Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / uml-patch-2.4.24-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    2004-01-16 03:45:20.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       2004-01-10 05:55:04.000000000 -0500
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       2004-01-10 05:56:22.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 2004-02-12 05:46:22.000000000 -0500
3712 @@ -0,0 +1,352 @@
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/init.h"
3721 +#include "linux/slab.h"
3722 +#include "linux/fs.h"
3723 +#include "linux/sound.h"
3724 +#include "linux/soundcard.h"
3725 +#include "asm/uaccess.h"
3726 +#include "kern_util.h"
3727 +#include "init.h"
3728 +#include "os.h"
3729 +
3730 +struct hostaudio_state {
3731 +       int fd;
3732 +};
3733 +
3734 +struct hostmixer_state {
3735 +       int fd;
3736 +};
3737 +
3738 +#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
3739 +#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
3740 +
3741 +/* Only changed from linux_main at boot time */
3742 +char *dsp = HOSTAUDIO_DEV_DSP;
3743 +char *mixer = HOSTAUDIO_DEV_MIXER;
3744 +
3745 +#define DSP_HELP \
3746 +"    This is used to specify the host dsp device to the hostaudio driver.\n" \
3747 +"    The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
3748 +
3749 +#define MIXER_HELP \
3750 +"    This is used to specify the host mixer device to the hostaudio driver.\n" \
3751 +"    The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
3752 +
3753 +#ifndef MODULE
3754 +static int set_dsp(char *name, int *add)
3755 +{
3756 +       dsp = name;
3757 +       return(0);
3758 +}
3759 +
3760 +__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
3761 +
3762 +static int set_mixer(char *name, int *add)
3763 +{
3764 +       mixer = name;
3765 +       return(0);
3766 +}
3767 +
3768 +__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
3769 +
3770 +#else /*MODULE*/
3771 +
3772 +MODULE_PARM(dsp, "s");
3773 +MODULE_PARM_DESC(dsp, DSP_HELP);
3774 +
3775 +MODULE_PARM(mixer, "s");
3776 +MODULE_PARM_DESC(mixer, MIXER_HELP);
3777 +
3778 +#endif
3779 +
3780 +/* /dev/dsp file operations */
3781 +
3782 +static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count, 
3783 +                             loff_t *ppos)
3784 +{
3785 +        struct hostaudio_state *state = file->private_data;
3786 +       void *kbuf;
3787 +       int err;
3788 +
3789 +#ifdef DEBUG
3790 +        printk("hostaudio: read called, count = %d\n", count);
3791 +#endif
3792 +
3793 +       kbuf = kmalloc(count, GFP_KERNEL);
3794 +       if(kbuf == NULL)
3795 +               return(-ENOMEM);
3796 +
3797 +       err = os_read_file(state->fd, kbuf, count);
3798 +       if(err < 0)
3799 +               goto out;
3800 +
3801 +       if(copy_to_user(buffer, kbuf, err))
3802 +               err = -EFAULT;
3803 +
3804 + out:
3805 +       kfree(kbuf);
3806 +       return(err);
3807 +}
3808 +
3809 +static ssize_t hostaudio_write(struct file *file, const char *buffer, 
3810 +                              size_t count, loff_t *ppos)
3811 +{
3812 +        struct hostaudio_state *state = file->private_data;
3813 +       void *kbuf;
3814 +       int err;
3815 +
3816 +#ifdef DEBUG
3817 +        printk("hostaudio: write called, count = %d\n", count);
3818 +#endif
3819 +
3820 +       kbuf = kmalloc(count, GFP_KERNEL);
3821 +       if(kbuf == NULL)
3822 +               return(-ENOMEM);
3823 +
3824 +       err = -EFAULT;
3825 +       if(copy_from_user(kbuf, buffer, count))
3826 +               goto out;
3827 +
3828 +       err = os_write_file(state->fd, kbuf, count);
3829 +       if(err < 0)
3830 +               goto out;
3831 +       *ppos += err;
3832 +
3833 + out:
3834 +       kfree(kbuf);
3835 +       return(err);
3836 +}
3837 +
3838 +static unsigned int hostaudio_poll(struct file *file, 
3839 +                                  struct poll_table_struct *wait)
3840 +{
3841 +        unsigned int mask = 0;
3842 +
3843 +#ifdef DEBUG
3844 +        printk("hostaudio: poll called (unimplemented)\n");
3845 +#endif
3846 +
3847 +        return(mask);
3848 +}
3849 +
3850 +static int hostaudio_ioctl(struct inode *inode, struct file *file, 
3851 +                          unsigned int cmd, unsigned long arg)
3852 +{
3853 +        struct hostaudio_state *state = file->private_data;
3854 +       unsigned long data = 0;
3855 +       int err;
3856 +
3857 +#ifdef DEBUG
3858 +        printk("hostaudio: ioctl called, cmd = %u\n", cmd);
3859 +#endif
3860 +       switch(cmd){
3861 +       case SNDCTL_DSP_SPEED:
3862 +       case SNDCTL_DSP_STEREO:
3863 +       case SNDCTL_DSP_GETBLKSIZE:
3864 +       case SNDCTL_DSP_CHANNELS:
3865 +       case SNDCTL_DSP_SUBDIVIDE:
3866 +       case SNDCTL_DSP_SETFRAGMENT:
3867 +               if(get_user(data, (int *) arg))
3868 +                       return(-EFAULT);
3869 +               break;
3870 +       default:
3871 +               break;
3872 +       }
3873 +
3874 +       err = os_ioctl_generic(state->fd, cmd, (unsigned long) &data);
3875 +
3876 +       switch(cmd){
3877 +       case SNDCTL_DSP_SPEED:
3878 +       case SNDCTL_DSP_STEREO:
3879 +       case SNDCTL_DSP_GETBLKSIZE:
3880 +       case SNDCTL_DSP_CHANNELS:
3881 +       case SNDCTL_DSP_SUBDIVIDE:
3882 +       case SNDCTL_DSP_SETFRAGMENT:
3883 +               if(put_user(data, (int *) arg))
3884 +                       return(-EFAULT);
3885 +               break;
3886 +       default:
3887 +               break;
3888 +       }
3889 +
3890 +       return(err);
3891 +}
3892 +
3893 +static int hostaudio_open(struct inode *inode, struct file *file)
3894 +{
3895 +        struct hostaudio_state *state;
3896 +        int r = 0, w = 0;
3897 +        int ret;
3898 +
3899 +#ifdef DEBUG
3900 +        printk("hostaudio: open called (host: %s)\n", dsp);
3901 +#endif
3902 +
3903 +        state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
3904 +        if(state == NULL) 
3905 +               return(-ENOMEM);
3906 +
3907 +        if(file->f_mode & FMODE_READ) r = 1;
3908 +        if(file->f_mode & FMODE_WRITE) w = 1;
3909 +
3910 +       ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
3911 +        if(ret < 0){
3912 +               kfree(state);
3913 +               return(ret);
3914 +        }
3915 +
3916 +       state->fd = ret;
3917 +        file->private_data = state;
3918 +        return(0);
3919 +}
3920 +
3921 +static int hostaudio_release(struct inode *inode, struct file *file)
3922 +{
3923 +        struct hostaudio_state *state = file->private_data;
3924 +
3925 +#ifdef DEBUG
3926 +        printk("hostaudio: release called\n");
3927 +#endif
3928 +
3929 +       os_close_file(state->fd);
3930 +        kfree(state);
3931 +
3932 +        return(0);
3933 +}
3934 +
3935 +/* /dev/mixer file operations */
3936 +
3937 +static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file, 
3938 +                                 unsigned int cmd, unsigned long arg)
3939 +{
3940 +        struct hostmixer_state *state = file->private_data;
3941 +
3942 +#ifdef DEBUG
3943 +        printk("hostmixer: ioctl called\n");
3944 +#endif
3945 +
3946 +       return(os_ioctl_generic(state->fd, cmd, arg));
3947 +}
3948 +
3949 +static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
3950 +{
3951 +        struct hostmixer_state *state;
3952 +        int r = 0, w = 0;
3953 +        int ret;
3954 +
3955 +#ifdef DEBUG
3956 +        printk("hostmixer: open called (host: %s)\n", mixer);
3957 +#endif
3958 +
3959 +        state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL);
3960 +        if(state == NULL) return(-ENOMEM);
3961 +
3962 +        if(file->f_mode & FMODE_READ) r = 1;
3963 +        if(file->f_mode & FMODE_WRITE) w = 1;
3964 +
3965 +       ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
3966 +        
3967 +        if(ret < 0){
3968 +               printk("hostaudio_open_mixdev failed to open '%s', err = %d\n",
3969 +                      dsp, -ret);
3970 +               kfree(state);
3971 +               return(ret);
3972 +        }
3973 +
3974 +        file->private_data = state;
3975 +        return(0);
3976 +}
3977 +
3978 +static int hostmixer_release(struct inode *inode, struct file *file)
3979 +{
3980 +        struct hostmixer_state *state = file->private_data;
3981 +
3982 +#ifdef DEBUG
3983 +        printk("hostmixer: release called\n");
3984 +#endif
3985 +
3986 +       os_close_file(state->fd);
3987 +        kfree(state);
3988 +
3989 +        return(0);
3990 +}
3991 +
3992 +
3993 +/* kernel module operations */
3994 +
3995 +static struct file_operations hostaudio_fops = {
3996 +        .owner          = THIS_MODULE,
3997 +        .llseek         = no_llseek,
3998 +        .read           = hostaudio_read,
3999 +        .write          = hostaudio_write,
4000 +        .poll           = hostaudio_poll,
4001 +        .ioctl          = hostaudio_ioctl,
4002 +        .mmap           = NULL,
4003 +        .open           = hostaudio_open,
4004 +        .release        = hostaudio_release,
4005 +};
4006 +
4007 +static struct file_operations hostmixer_fops = {
4008 +        .owner          = THIS_MODULE,
4009 +        .llseek         = no_llseek,
4010 +        .ioctl          = hostmixer_ioctl_mixdev,
4011 +        .open           = hostmixer_open_mixdev,
4012 +        .release        = hostmixer_release,
4013 +};
4014 +
4015 +struct {
4016 +       int dev_audio;
4017 +       int dev_mixer;
4018 +} module_data;
4019 +
4020 +MODULE_AUTHOR("Steve Schmidtke");
4021 +MODULE_DESCRIPTION("UML Audio Relay");
4022 +MODULE_LICENSE("GPL");
4023 +
4024 +static int __init hostaudio_init_module(void)
4025 +{
4026 +        printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
4027 +              dsp, mixer);
4028 +
4029 +       module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
4030 +        if(module_data.dev_audio < 0){
4031 +                printk(KERN_ERR "hostaudio: couldn't register DSP device!\n");
4032 +                return -ENODEV;
4033 +        }
4034 +
4035 +       module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1);
4036 +        if(module_data.dev_mixer < 0){
4037 +                printk(KERN_ERR "hostmixer: couldn't register mixer "
4038 +                      "device!\n");
4039 +                unregister_sound_dsp(module_data.dev_audio);
4040 +                return -ENODEV;
4041 +        }
4042 +
4043 +        return 0;
4044 +}
4045 +
4046 +static void __exit hostaudio_cleanup_module (void)
4047 +{
4048 +       unregister_sound_mixer(module_data.dev_mixer);
4049 +       unregister_sound_dsp(module_data.dev_audio);
4050 +}
4051 +
4052 +module_init(hostaudio_init_module);
4053 +module_exit(hostaudio_cleanup_module);
4054 +
4055 +/*
4056 + * Overrides for Emacs so that we follow Linus's tabbing style.
4057 + * Emacs will notice this stuff at the end of the file and automatically
4058 + * adjust the settings for this buffer only.  This must remain at the end
4059 + * of the file.
4060 + * ---------------------------------------------------------------------------
4061 + * Local variables:
4062 + * c-file-style: "linux"
4063 + * End:
4064 + */
4065 diff -Naur -X ../exclude-files orig/arch/um/drivers/line.c um/arch/um/drivers/line.c
4066 --- orig/arch/um/drivers/line.c 1969-12-31 19:00:00.000000000 -0500
4067 +++ um/arch/um/drivers/line.c   2003-11-07 03:03:57.000000000 -0500
4068 @@ -0,0 +1,610 @@
4069 +/* 
4070 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4071 + * Licensed under the GPL
4072 + */
4073 +
4074 +#include "linux/sched.h"
4075 +#include "linux/slab.h"
4076 +#include "linux/list.h"
4077 +#include "linux/devfs_fs_kernel.h"
4078 +#include "asm/irq.h"
4079 +#include "asm/uaccess.h"
4080 +#include "chan_kern.h"
4081 +#include "irq_user.h"
4082 +#include "line.h"
4083 +#include "kern.h"
4084 +#include "user_util.h"
4085 +#include "kern_util.h"
4086 +#include "os.h"
4087 +#include "irq_kern.h"
4088 +
4089 +#define LINE_BUFSIZE 4096
4090 +
4091 +static void line_interrupt(int irq, void *data, struct pt_regs *unused)
4092 +{
4093 +       struct line *dev = data;
4094 +
4095 +       if(dev->count > 0) 
4096 +               chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, 
4097 +                              dev);
4098 +}
4099 +
4100 +static void line_timer_cb(void *arg)
4101 +{
4102 +       struct line *dev = arg;
4103 +
4104 +       line_interrupt(dev->driver->read_irq, dev, NULL);
4105 +}
4106 +
4107 +static int write_room(struct line *dev)
4108 +{
4109 +       int n;
4110 +
4111 +       if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
4112 +
4113 +       n = dev->head - dev->tail;
4114 +       if(n <= 0) n = LINE_BUFSIZE + n;
4115 +       return(n - 1);
4116 +}
4117 +
4118 +static int buffer_data(struct line *line, const char *buf, int len)
4119 +{
4120 +       int end, room;
4121 +
4122 +       if(line->buffer == NULL){
4123 +               line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
4124 +               if(line->buffer == NULL){
4125 +                       printk("buffer_data - atomic allocation failed\n");
4126 +                       return(0);
4127 +               }
4128 +               line->head = line->buffer;
4129 +               line->tail = line->buffer;
4130 +       }
4131 +
4132 +       room = write_room(line);
4133 +       len = (len > room) ? room : len;
4134 +
4135 +       end = line->buffer + LINE_BUFSIZE - line->tail;
4136 +       if(len < end){
4137 +               memcpy(line->tail, buf, len);
4138 +               line->tail += len;
4139 +       }
4140 +       else {
4141 +               memcpy(line->tail, buf, end);
4142 +               buf += end;
4143 +               len -= end;
4144 +               memcpy(line->buffer, buf, len);
4145 +               line->tail = line->buffer + len;
4146 +       }
4147 +
4148 +       return(len);
4149 +}
4150 +
4151 +static int flush_buffer(struct line *line)
4152 +{
4153 +       int n, count;
4154 +
4155 +       if((line->buffer == NULL) || (line->head == line->tail)) return(1);
4156 +
4157 +       if(line->tail < line->head){
4158 +               count = line->buffer + LINE_BUFSIZE - line->head;
4159 +               n = write_chan(&line->chan_list, line->head, count,
4160 +                              line->driver->write_irq);
4161 +               if(n < 0) return(n);
4162 +               if(n == count) line->head = line->buffer;
4163 +               else {
4164 +                       line->head += n;
4165 +                       return(0);
4166 +               }
4167 +       }
4168 +
4169 +       count = line->tail - line->head;
4170 +       n = write_chan(&line->chan_list, line->head, count, 
4171 +                      line->driver->write_irq);
4172 +       if(n < 0) return(n);
4173 +
4174 +       line->head += n;
4175 +       return(line->head == line->tail);
4176 +}
4177 +
4178 +int line_write(struct line *lines, struct tty_struct *tty, int from_user,
4179 +              const char *buf, int len)
4180 +{
4181 +       struct line *line;
4182 +       char *new;
4183 +       unsigned long flags;
4184 +       int n, err, i, ret = 0;
4185 +
4186 +       if(tty->stopped) return 0;
4187 +
4188 +       if(from_user){
4189 +               new = kmalloc(len, GFP_KERNEL);
4190 +               if(new == NULL)
4191 +                       return(0);
4192 +               n = copy_from_user(new, buf, len);
4193 +               buf = new;
4194 +               if(n == len){
4195 +                       len = -EFAULT;
4196 +                       goto out_free;
4197 +               }
4198 +
4199 +               len -= n;
4200 +       }
4201 +
4202 +       i = minor(tty->device) - tty->driver.minor_start;
4203 +       line = &lines[i];
4204 +
4205 +       down(&line->sem);
4206 +       if(line->head != line->tail){
4207 +               local_irq_save(flags);
4208 +               ret += buffer_data(line, buf, len);
4209 +               err = flush_buffer(line);
4210 +               local_irq_restore(flags);
4211 +               if(err <= 0)
4212 +                       goto out_up;
4213 +       }
4214 +       else {
4215 +               n = write_chan(&line->chan_list, buf, len, 
4216 +                              line->driver->write_irq);
4217 +               if(n < 0){
4218 +                       ret = n;
4219 +                       goto out_up;
4220 +               }
4221 +
4222 +               len -= n;
4223 +               ret += n;
4224 +               if(len > 0)
4225 +                       ret += buffer_data(line, buf + n, len);
4226 +       }
4227 + out_up:
4228 +       up(&line->sem);
4229 +
4230 + out_free:
4231 +       if(from_user)
4232 +               kfree(buf);
4233 +       return(ret);
4234 +}
4235 +
4236 +static void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
4237 +{
4238 +       struct line *dev = data;
4239 +       struct tty_struct *tty = dev->tty;
4240 +       int err;
4241 +
4242 +       err = flush_buffer(dev);
4243 +       if(err == 0) return;
4244 +       else if(err < 0){
4245 +               dev->head = dev->buffer;
4246 +               dev->tail = dev->buffer;
4247 +       }
4248 +
4249 +       if(tty == NULL) return;
4250 +
4251 +       if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
4252 +          (tty->ldisc.write_wakeup != NULL))
4253 +               (tty->ldisc.write_wakeup)(tty);
4254 +       
4255 +       /* BLOCKING mode
4256 +        * In blocking mode, everything sleeps on tty->write_wait.
4257 +        * Sleeping in the console driver would break non-blocking
4258 +        * writes.
4259 +        */
4260 +
4261 +       if (waitqueue_active(&tty->write_wait))
4262 +               wake_up_interruptible(&tty->write_wait);
4263 +
4264 +}
4265 +
4266 +int line_setup_irq(int fd, int input, int output, void *data)
4267 +{
4268 +       struct line *line = data;
4269 +       struct line_driver *driver = line->driver;
4270 +       int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
4271 +
4272 +       if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ, 
4273 +                                      line_interrupt, flags, 
4274 +                                      driver->read_irq_name, line);
4275 +       if(err) return(err);
4276 +       if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, 
4277 +                                       line_write_interrupt, flags, 
4278 +                                       driver->write_irq_name, line);
4279 +       line->have_irq = 1;
4280 +       return(err);
4281 +}
4282 +
4283 +void line_disable(struct line *line, int current_irq)
4284 +{
4285 +       if(!line->have_irq) return;
4286 +
4287 +       if(line->driver->read_irq == current_irq)
4288 +               free_irq_later(line->driver->read_irq, line);
4289 +       else
4290 +               free_irq(line->driver->read_irq, line);
4291 +
4292 +       if(line->driver->write_irq == current_irq)
4293 +               free_irq_later(line->driver->write_irq, line);
4294 +       else
4295 +               free_irq(line->driver->write_irq, line);
4296 +
4297 +       line->have_irq = 0;
4298 +}
4299 +
4300 +int line_open(struct line *lines, struct tty_struct *tty,
4301 +             struct chan_opts *opts)
4302 +{
4303 +       struct line *line;
4304 +       int n, err = 0;
4305 +
4306 +       if(tty == NULL) n = 0;
4307 +       else n = minor(tty->device) - tty->driver.minor_start;
4308 +       line = &lines[n];
4309 +
4310 +       down(&line->sem);
4311 +       if(line->count == 0){
4312 +               if(!line->valid){
4313 +                       err = -ENODEV;
4314 +                       goto out;
4315 +               }
4316 +               if(list_empty(&line->chan_list)){
4317 +                       err = parse_chan_pair(line->init_str, &line->chan_list,
4318 +                                             line->init_pri, n, opts);
4319 +                       if(err) goto out;
4320 +                       err = open_chan(&line->chan_list);
4321 +                       if(err) goto out;
4322 +               }
4323 +               enable_chan(&line->chan_list, line);
4324 +               INIT_TQUEUE(&line->task, line_timer_cb, line);
4325 +       }
4326 +
4327 +       if(!line->sigio){
4328 +               chan_enable_winch(&line->chan_list, line);
4329 +               line->sigio = 1;
4330 +       }
4331 +
4332 +       /* This is outside the if because the initial console is opened
4333 +        * with tty == NULL
4334 +        */
4335 +       line->tty = tty;
4336 +
4337 +       if(tty != NULL){
4338 +               tty->driver_data = line;
4339 +               chan_window_size(&line->chan_list, &tty->winsize.ws_row, 
4340 +                                &tty->winsize.ws_col);
4341 +       }
4342 +
4343 +       line->count++;
4344 + out:
4345 +       up(&line->sem);
4346 +       return(err);
4347 +}
4348 +
4349 +void line_close(struct line *lines, struct tty_struct *tty)
4350 +{
4351 +       struct line *line;
4352 +       int n;
4353 +
4354 +       if(tty == NULL) n = 0;
4355 +       else n = minor(tty->device) - tty->driver.minor_start;
4356 +       line = &lines[n];
4357 +
4358 +       down(&line->sem);
4359 +       line->count--;
4360 +
4361 +       /* I don't like this, but I can't think of anything better.  What's
4362 +        * going on is that the tty is in the process of being closed for
4363 +        * the last time.  Its count hasn't been dropped yet, so it's still
4364 +        * at 1.  This may happen when line->count != 0 because of the initial
4365 +        * console open (without a tty) bumping it up to 1.
4366 +        */
4367 +       if((line->tty != NULL) && (line->tty->count == 1))
4368 +               line->tty = NULL;
4369 +       if(line->count == 0)
4370 +               line_disable(line, -1);
4371 +       up(&line->sem);
4372 +}
4373 +
4374 +void close_lines(struct line *lines, int nlines)
4375 +{
4376 +       int i;
4377 +
4378 +       for(i = 0; i < nlines; i++)
4379 +               close_chan(&lines[i].chan_list);
4380 +}
4381 +
4382 +int line_setup(struct line *lines, int num, char *init, int all_allowed)
4383 +{
4384 +       int i, n;
4385 +       char *end;
4386 +
4387 +       if(*init == '=') n = -1;
4388 +       else {
4389 +               n = simple_strtoul(init, &end, 0);
4390 +               if(*end != '='){
4391 +                       printk(KERN_ERR "line_setup failed to parse \"%s\"\n", 
4392 +                              init);
4393 +                       return(0);
4394 +               }
4395 +               init = end;
4396 +       }
4397 +       init++;
4398 +       if((n >= 0) && (n >= num)){
4399 +               printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
4400 +                      n, num);
4401 +               return(0);
4402 +       }
4403 +       else if(n >= 0){
4404 +               if(lines[n].count > 0){
4405 +                       printk("line_setup - device %d is open\n", n);
4406 +                       return(0);
4407 +               }
4408 +               if(lines[n].init_pri <= INIT_ONE){
4409 +                       lines[n].init_pri = INIT_ONE;
4410 +                       if(!strcmp(init, "none")) lines[n].valid = 0;
4411 +                       else {
4412 +                               lines[n].init_str = init;
4413 +                               lines[n].valid = 1;
4414 +                       }       
4415 +               }
4416 +       }
4417 +       else if(!all_allowed){
4418 +               printk("line_setup - can't configure all devices from "
4419 +                      "mconsole\n");
4420 +               return(0);
4421 +       }
4422 +       else {
4423 +               for(i = 0; i < num; i++){
4424 +                       if(lines[i].init_pri <= INIT_ALL){
4425 +                               lines[i].init_pri = INIT_ALL;
4426 +                               if(!strcmp(init, "none")) lines[i].valid = 0;
4427 +                               else {
4428 +                                       lines[i].init_str = init;
4429 +                                       lines[i].valid = 1;
4430 +                               }
4431 +                       }
4432 +               }
4433 +       }
4434 +       return(1);
4435 +}
4436 +
4437 +int line_config(struct line *lines, int num, char *str)
4438 +{
4439 +       char *new = uml_strdup(str);
4440 +
4441 +       if(new == NULL){
4442 +               printk("line_config - uml_strdup failed\n");
4443 +               return(-ENOMEM);
4444 +       }
4445 +       return(!line_setup(lines, num, new, 0));
4446 +}
4447 +
4448 +int line_get_config(char *name, struct line *lines, int num, char *str, 
4449 +                   int size, char **error_out)
4450 +{
4451 +       struct line *line;
4452 +       char *end;
4453 +       int dev, n = 0;
4454 +
4455 +       dev = simple_strtoul(name, &end, 0);
4456 +       if((*end != '\0') || (end == name)){
4457 +               *error_out = "line_get_config failed to parse device number";
4458 +               return(0);
4459 +       }
4460 +
4461 +       if((dev < 0) || (dev >= num)){
4462 +               *error_out = "device number of of range";
4463 +               return(0);
4464 +       }
4465 +
4466 +       line = &lines[dev];
4467 +
4468 +       down(&line->sem);
4469 +       if(!line->valid)
4470 +               CONFIG_CHUNK(str, size, n, "none", 1);
4471 +       else if(line->count == 0)
4472 +               CONFIG_CHUNK(str, size, n, line->init_str, 1);
4473 +       else n = chan_config_string(&line->chan_list, str, size, error_out);
4474 +       up(&line->sem);
4475 +
4476 +       return(n);
4477 +}
4478 +
4479 +int line_remove(struct line *lines, int num, char *str)
4480 +{
4481 +       char config[sizeof("conxxxx=none\0")];
4482 +
4483 +       sprintf(config, "%s=none", str);
4484 +       return(!line_setup(lines, num, config, 0));
4485 +}
4486 +
4487 +static int line_write_room(struct tty_struct *tty)
4488 +{
4489 +       struct line *dev = tty->driver_data;
4490 +
4491 +       return(write_room(dev));
4492 +}
4493 +
4494 +void line_register_devfs(struct lines *set, struct line_driver *line_driver, 
4495 +                        struct tty_driver *driver, struct line *lines,
4496 +                        int nlines)
4497 +{
4498 +       int err, i, n;
4499 +       char *from, *to;
4500 +
4501 +       driver->driver_name = line_driver->name;
4502 +       driver->name = line_driver->devfs_name;
4503 +       driver->major = line_driver->major;
4504 +       driver->minor_start = line_driver->minor_start;
4505 +       driver->type = line_driver->type;
4506 +       driver->subtype = line_driver->subtype;
4507 +       driver->magic = TTY_DRIVER_MAGIC;
4508 +       driver->flags = TTY_DRIVER_REAL_RAW;
4509 +
4510 +       n = set->num;
4511 +       driver->num = n;
4512 +       driver->table = kmalloc(n * sizeof(driver->table[0]), GFP_KERNEL);
4513 +       driver->termios = kmalloc(n * sizeof(driver->termios[0]), GFP_KERNEL);
4514 +       driver->termios_locked = kmalloc(n * sizeof(driver->termios_locked[0]),
4515 +                                        GFP_KERNEL);
4516 +       if((driver->table == NULL) || (driver->termios == NULL) ||
4517 +          (driver->termios_locked == NULL))
4518 +               panic("Failed to allocate driver table");
4519 +
4520 +       memset(driver->table, 0, n * sizeof(driver->table[0]));
4521 +       memset(driver->termios, 0, n * sizeof(driver->termios[0]));
4522 +       memset(driver->termios_locked, 0, 
4523 +              n * sizeof(driver->termios_locked[0]));
4524 +
4525 +       driver->write_room = line_write_room;
4526 +       driver->init_termios = tty_std_termios;
4527 +
4528 +       if (tty_register_driver(driver))
4529 +               panic("line_register_devfs : Couldn't register driver\n");
4530 +
4531 +       from = line_driver->symlink_from;
4532 +       to = line_driver->symlink_to;
4533 +       err = devfs_mk_symlink(NULL, from, 0, to, NULL, NULL);
4534 +       if(err) printk("Symlink creation from /dev/%s to /dev/%s "
4535 +                      "returned %d\n", from, to, err);
4536 +
4537 +       for(i = 0; i < nlines; i++){
4538 +               if(!lines[i].valid) 
4539 +                       tty_unregister_devfs(driver, driver->minor_start + i);
4540 +       }
4541 +
4542 +       mconsole_register_dev(&line_driver->mc);
4543 +}
4544 +
4545 +void lines_init(struct line *lines, int nlines)
4546 +{
4547 +       struct line *line;
4548 +       int i;
4549 +
4550 +       for(i = 0; i < nlines; i++){
4551 +               line = &lines[i];
4552 +               INIT_LIST_HEAD(&line->chan_list);
4553 +               sema_init(&line->sem, 1);
4554 +               if(line->init_str != NULL){
4555 +                       line->init_str = uml_strdup(line->init_str);
4556 +                       if(line->init_str == NULL)
4557 +                               printk("lines_init - uml_strdup returned "
4558 +                                      "NULL\n");
4559 +               }
4560 +       }
4561 +}
4562 +
4563 +struct winch {
4564 +       struct list_head list;
4565 +       int fd;
4566 +       int tty_fd;
4567 +       int pid;
4568 +       struct line *line;
4569 +};
4570 +
4571 +void winch_interrupt(int irq, void *data, struct pt_regs *unused)
4572 +{
4573 +       struct winch *winch = data;
4574 +       struct tty_struct *tty;
4575 +       int err;
4576 +       char c;
4577 +
4578 +       if(winch->fd != -1){
4579 +               err = generic_read(winch->fd, &c, NULL);
4580 +               if(err < 0){
4581 +                       if(err != -EAGAIN){
4582 +                               printk("winch_interrupt : read failed, "
4583 +                                      "errno = %d\n", -err);
4584 +                               printk("fd %d is losing SIGWINCH support\n", 
4585 +                                      winch->tty_fd);
4586 +                               return;
4587 +                       }
4588 +                       goto out;
4589 +               }
4590 +       }
4591 +       tty = winch->line->tty;
4592 +       if(tty != NULL){
4593 +               chan_window_size(&winch->line->chan_list, 
4594 +                                &tty->winsize.ws_row, 
4595 +                                &tty->winsize.ws_col);
4596 +               kill_pg(tty->pgrp, SIGWINCH, 1);
4597 +       }
4598 + out:
4599 +       if(winch->fd != -1)
4600 +               reactivate_fd(winch->fd, WINCH_IRQ);
4601 +}
4602 +
4603 +DECLARE_MUTEX(winch_handler_sem);
4604 +LIST_HEAD(winch_handlers);
4605 +
4606 +void register_winch_irq(int fd, int tty_fd, int pid, void *line)
4607 +{
4608 +       struct winch *winch;
4609 +
4610 +       down(&winch_handler_sem);
4611 +       winch = kmalloc(sizeof(*winch), GFP_KERNEL);
4612 +       if(winch == NULL){
4613 +               printk("register_winch_irq - kmalloc failed\n");
4614 +               goto out;
4615 +       }
4616 +       *winch = ((struct winch) { .list        = LIST_HEAD_INIT(winch->list),
4617 +                                  .fd          = fd,
4618 +                                  .tty_fd      = tty_fd,
4619 +                                  .pid         = pid,
4620 +                                  .line        = line });
4621 +       list_add(&winch->list, &winch_handlers);
4622 +       if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 
4623 +                         SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
4624 +                         "winch", winch) < 0)
4625 +               printk("register_winch_irq - failed to register IRQ\n");
4626 + out:
4627 +       up(&winch_handler_sem);
4628 +}
4629 +
4630 +static void winch_cleanup(void)
4631 +{
4632 +       struct list_head *ele;
4633 +       struct winch *winch;
4634 +
4635 +       list_for_each(ele, &winch_handlers){
4636 +               winch = list_entry(ele, struct winch, list);
4637 +               if(winch->fd != -1){
4638 +                       deactivate_fd(winch->fd, WINCH_IRQ);
4639 +                       os_close_file(winch->fd);
4640 +               }
4641 +               if(winch->pid != -1) 
4642 +                       os_kill_process(winch->pid, 1);
4643 +       }
4644 +}
4645 +
4646 +__uml_exitcall(winch_cleanup);
4647 +
4648 +char *add_xterm_umid(char *base)
4649 +{
4650 +       char *umid, *title;
4651 +       int len;
4652 +
4653 +       umid = get_umid(1);
4654 +       if(umid == NULL) return(base);
4655 +       
4656 +       len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
4657 +       title = kmalloc(len, GFP_KERNEL);
4658 +       if(title == NULL){
4659 +               printk("Failed to allocate buffer for xterm title\n");
4660 +               return(base);
4661 +       }
4662 +
4663 +       strncpy(title, base, len);
4664 +       len -= strlen(title);
4665 +       snprintf(&title[strlen(title)], len, " (%s)", umid);
4666 +       return(title);
4667 +}
4668 +
4669 +/*
4670 + * Overrides for Emacs so that we follow Linus's tabbing style.
4671 + * Emacs will notice this stuff at the end of the file and automatically
4672 + * adjust the settings for this buffer only.  This must remain at the end
4673 + * of the file.
4674 + * ---------------------------------------------------------------------------
4675 + * Local variables:
4676 + * c-file-style: "linux"
4677 + * End:
4678 + */
4679 diff -Naur -X ../exclude-files orig/arch/um/drivers/Makefile um/arch/um/drivers/Makefile
4680 --- orig/arch/um/drivers/Makefile       1969-12-31 19:00:00.000000000 -0500
4681 +++ um/arch/um/drivers/Makefile 2004-02-12 03:55:08.000000000 -0500
4682 @@ -0,0 +1,97 @@
4683 +# 
4684 +# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
4685 +# Licensed under the GPL
4686 +#
4687 +
4688 +O_TARGET := built-in.o 
4689 +
4690 +CHAN_OBJS := chan_kern.o chan_user.o line.o 
4691 +
4692 +list-multi := slip.o slirp.o daemon.o mcast.o mconsole.o net.o ubd.o \
4693 +       hostaudio.o pcap.o port.o harddog.o
4694 +
4695 +slip-objs := slip_kern.o slip_user.o
4696 +slirp-objs := slirp_kern.o slirp_user.o
4697 +daemon-objs := daemon_kern.o daemon_user.o
4698 +mcast-objs := mcast_kern.o mcast_user.o
4699 +pcap-objs := pcap_kern.o pcap_user.o
4700 +pcap-libs := -lpcap -L/usr/lib
4701 +net-objs := net_kern.o net_user.o
4702 +mconsole-objs := mconsole_kern.o mconsole_user.o
4703 +hostaudio-objs := hostaudio_kern.o
4704 +ubd-objs := ubd_kern.o ubd_user.o
4705 +port-objs := port_kern.o port_user.o
4706 +harddog-objs := harddog_kern.o harddog_user.o
4707 +
4708 +export-objs := mconsole_kern.o
4709 +
4710 +obj-y = 
4711 +obj-$(CONFIG_SSL) += ssl.o 
4712 +obj-$(CONFIG_UML_NET_SLIP) += slip.o
4713 +obj-$(CONFIG_UML_NET_SLIRP) += slirp.o
4714 +obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 
4715 +obj-$(CONFIG_UML_NET_MCAST) += mcast.o 
4716 +obj-$(CONFIG_UML_NET_PCAP) += pcap.o 
4717 +obj-$(CONFIG_UML_NET) += net.o 
4718 +obj-$(CONFIG_MCONSOLE) += mconsole.o
4719 +obj-$(CONFIG_MMAPPER) += mmapper_kern.o 
4720 +obj-$(CONFIG_BLK_DEV_UBD) += ubd.o 
4721 +obj-$(CONFIG_HOSTAUDIO) += hostaudio.o
4722 +obj-$(CONFIG_FD_CHAN) += fd.o 
4723 +obj-$(CONFIG_NULL_CHAN) += null.o 
4724 +obj-$(CONFIG_PORT_CHAN) += port.o
4725 +obj-$(CONFIG_PTY_CHAN) += pty.o
4726 +obj-$(CONFIG_TTY_CHAN) += tty.o 
4727 +obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
4728 +obj-$(CONFIG_UML_WATCHDOG) += harddog.o
4729 +obj-$(CONFIG_COW) += cow_kern.o
4730 +obj-$(CONFIG_COW_COMMON) += cow_user.o
4731 +
4732 +CFLAGS_pcap_user.o = -I/usr/include/pcap
4733 +
4734 +obj-y += stdio_console.o $(CHAN_OBJS)
4735 +
4736 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
4737 +
4738 +USER_OBJS = $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
4739 +       null.o pty.o tty.o xterm.o
4740 +
4741 +include $(TOPDIR)/Rules.make
4742 +
4743 +$(USER_OBJS) : %.o: %.c
4744 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
4745 +
4746 +clean:
4747 +
4748 +modules:
4749 +
4750 +fastdep:
4751 +
4752 +dep:
4753 +
4754 +archmrproper:
4755 +
4756 +daemon.o : $(daemon-objs)
4757 +
4758 +slip.o : $(slip-objs)
4759 +
4760 +slirp.o : $(slirp-objs)
4761 +
4762 +mcast.o : $(mcast-objs)
4763 +
4764 +pcap.o : $(pcap-objs)
4765 +
4766 +mconsole.o : $(mconsole-objs)
4767 +
4768 +net.o : $(net-objs)
4769 +
4770 +hostaudio.o : $(hostaudio-objs)
4771 +
4772 +ubd.o : $(ubd-objs)
4773 +
4774 +port.o : $(port-objs)
4775 +
4776 +harddog.o : $(harddog-objs)
4777 +
4778 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
4779 +       $(LD) -r -o $@ $($(patsubst %.o,%,$@)-objs) $($(patsubst %.o,%,$@)-libs)
4780 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast.h um/arch/um/drivers/mcast.h
4781 --- orig/arch/um/drivers/mcast.h        1969-12-31 19:00:00.000000000 -0500
4782 +++ um/arch/um/drivers/mcast.h  2003-10-21 03:26:06.000000000 -0400
4783 @@ -0,0 +1,30 @@
4784 +/* 
4785 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
4786 + * Licensed under the GPL
4787 + */
4788 +
4789 +#include "net_user.h"
4790 +
4791 +struct mcast_data {
4792 +       char *addr;
4793 +       unsigned short port;
4794 +       void *mcast_addr;
4795 +       int ttl;
4796 +       void *dev;
4797 +};
4798 +
4799 +extern struct net_user_info mcast_user_info;
4800 +
4801 +extern int mcast_user_write(int fd, void *buf, int len, 
4802 +                           struct mcast_data *pri);
4803 +
4804 +/*
4805 + * Overrides for Emacs so that we follow Linus's tabbing style.
4806 + * Emacs will notice this stuff at the end of the file and automatically
4807 + * adjust the settings for this buffer only.  This must remain at the end
4808 + * of the file.
4809 + * ---------------------------------------------------------------------------
4810 + * Local variables:
4811 + * c-file-style: "linux"
4812 + * End:
4813 + */
4814 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_kern.c um/arch/um/drivers/mcast_kern.c
4815 --- orig/arch/um/drivers/mcast_kern.c   1969-12-31 19:00:00.000000000 -0500
4816 +++ um/arch/um/drivers/mcast_kern.c     2003-10-21 03:26:06.000000000 -0400
4817 @@ -0,0 +1,145 @@
4818 +/*
4819 + * user-mode-linux networking multicast transport
4820 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4821 + *
4822 + * based on the existing uml-networking code, which is
4823 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
4824 + * James Leu (jleu@mindspring.net).
4825 + * Copyright (C) 2001 by various other people who didn't put their name here.
4826 + *
4827 + * Licensed under the GPL.
4828 + */
4829 +
4830 +#include "linux/kernel.h"
4831 +#include "linux/init.h"
4832 +#include "linux/netdevice.h"
4833 +#include "linux/etherdevice.h"
4834 +#include "linux/in.h"
4835 +#include "linux/inet.h"
4836 +#include "net_kern.h"
4837 +#include "net_user.h"
4838 +#include "mcast.h"
4839 +
4840 +struct mcast_init {
4841 +       char *addr;
4842 +       int port;
4843 +       int ttl;
4844 +};
4845 +
4846 +void mcast_init(struct net_device *dev, void *data)
4847 +{
4848 +       struct uml_net_private *pri;
4849 +       struct mcast_data *dpri;
4850 +       struct mcast_init *init = data;
4851 +
4852 +       init_etherdev(dev, 0);
4853 +       pri = dev->priv;
4854 +       dpri = (struct mcast_data *) pri->user;
4855 +       *dpri = ((struct mcast_data)
4856 +               { .addr         = init->addr,
4857 +                 .port         = init->port,
4858 +                 .ttl          = init->ttl,
4859 +                 .mcast_addr   = NULL,
4860 +                 .dev          = dev });
4861 +       printk("mcast backend ");
4862 +       printk("multicast adddress: %s:%u, TTL:%u ",
4863 +              dpri->addr, dpri->port, dpri->ttl);
4864 +
4865 +       printk("\n");
4866 +}
4867 +
4868 +static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
4869 +{
4870 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
4871 +       if(*skb == NULL) return(-ENOMEM);
4872 +       return(net_recvfrom(fd, (*skb)->mac.raw, 
4873 +                           (*skb)->dev->mtu + ETH_HEADER_OTHER));
4874 +}
4875 +
4876 +static int mcast_write(int fd, struct sk_buff **skb,
4877 +                       struct uml_net_private *lp)
4878 +{
4879 +       return mcast_user_write(fd, (*skb)->data, (*skb)->len, 
4880 +                                (struct mcast_data *) &lp->user);
4881 +}
4882 +
4883 +static struct net_kern_info mcast_kern_info = {
4884 +       .init                   = mcast_init,
4885 +       .protocol               = eth_protocol,
4886 +       .read                   = mcast_read,
4887 +       .write                  = mcast_write,
4888 +};
4889 +
4890 +int mcast_setup(char *str, char **mac_out, void *data)
4891 +{
4892 +       struct mcast_init *init = data;
4893 +       char *port_str = NULL, *ttl_str = NULL, *remain;
4894 +       char *last;
4895 +       int n;
4896 +
4897 +       *init = ((struct mcast_init)
4898 +               { .addr         = "239.192.168.1",
4899 +                 .port         = 1102,
4900 +                 .ttl          = 1 });
4901 +
4902 +       remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
4903 +                              NULL);
4904 +       if(remain != NULL){
4905 +               printk(KERN_ERR "mcast_setup - Extra garbage on "
4906 +                      "specification : '%s'\n", remain);
4907 +               return(0);
4908 +       }
4909 +       
4910 +       if(port_str != NULL){
4911 +               n = simple_strtoul(port_str, &last, 10);
4912 +               if((*last != '\0') || (last == port_str)){
4913 +                       printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", 
4914 +                              port_str);
4915 +                       return(0);
4916 +               }
4917 +               init->port = htons(n);
4918 +       }
4919 +
4920 +       if(ttl_str != NULL){
4921 +               init->ttl = simple_strtoul(ttl_str, &last, 10);
4922 +               if((*last != '\0') || (last == ttl_str)){
4923 +                       printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n", 
4924 +                              ttl_str);
4925 +                       return(0);
4926 +               }
4927 +       }
4928 +
4929 +       printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
4930 +              init->port, init->ttl);
4931 +
4932 +       return(1);
4933 +}
4934 +
4935 +static struct transport mcast_transport = {
4936 +       .list           = LIST_HEAD_INIT(mcast_transport.list),
4937 +       .name           = "mcast",
4938 +       .setup          = mcast_setup,
4939 +       .user           = &mcast_user_info,
4940 +       .kern           = &mcast_kern_info,
4941 +       .private_size   = sizeof(struct mcast_data),
4942 +       .setup_size     = sizeof(struct mcast_init),
4943 +};
4944 +
4945 +static int register_mcast(void)
4946 +{
4947 +       register_transport(&mcast_transport);
4948 +       return(1);
4949 +}
4950 +
4951 +__initcall(register_mcast);
4952 +
4953 +/*
4954 + * Overrides for Emacs so that we follow Linus's tabbing style.
4955 + * Emacs will notice this stuff at the end of the file and automatically
4956 + * adjust the settings for this buffer only.  This must remain at the end
4957 + * of the file.
4958 + * ---------------------------------------------------------------------------
4959 + * Local variables:
4960 + * c-file-style: "linux"
4961 + * End:
4962 + */
4963 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_user.c um/arch/um/drivers/mcast_user.c
4964 --- orig/arch/um/drivers/mcast_user.c   1969-12-31 19:00:00.000000000 -0500
4965 +++ um/arch/um/drivers/mcast_user.c     2003-10-21 03:26:06.000000000 -0400
4966 @@ -0,0 +1,177 @@
4967 +/*
4968 + * user-mode-linux networking multicast transport
4969 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4970 + *
4971 + * based on the existing uml-networking code, which is
4972 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
4973 + * James Leu (jleu@mindspring.net).
4974 + * Copyright (C) 2001 by various other people who didn't put their name here.
4975 + *
4976 + * Licensed under the GPL.
4977 + *
4978 + */
4979 +
4980 +#include <errno.h>
4981 +#include <unistd.h>
4982 +#include <linux/inet.h>
4983 +#include <sys/socket.h>
4984 +#include <sys/un.h>
4985 +#include <sys/time.h>
4986 +#include <netinet/in.h>
4987 +#include "net_user.h"
4988 +#include "mcast.h"
4989 +#include "kern_util.h"
4990 +#include "user_util.h"
4991 +#include "user.h"
4992 +#include "os.h"
4993 +
4994 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
4995 +
4996 +static struct sockaddr_in *new_addr(char *addr, unsigned short port)
4997 +{
4998 +       struct sockaddr_in *sin;
4999 +
5000 +       sin = um_kmalloc(sizeof(struct sockaddr_in));
5001 +       if(sin == NULL){
5002 +               printk("new_addr: allocation of sockaddr_in failed\n");
5003 +               return(NULL);
5004 +       }
5005 +       sin->sin_family = AF_INET;
5006 +       sin->sin_addr.s_addr = in_aton(addr);
5007 +       sin->sin_port = port;
5008 +       return(sin);
5009 +}
5010 +
5011 +static void mcast_user_init(void *data, void *dev)
5012 +{
5013 +       struct mcast_data *pri = data;
5014 +
5015 +       pri->mcast_addr = new_addr(pri->addr, pri->port);
5016 +       pri->dev = dev;
5017 +}
5018 +
5019 +static int mcast_open(void *data)
5020 +{
5021 +       struct mcast_data *pri = data;
5022 +       struct sockaddr_in *sin = pri->mcast_addr;
5023 +       struct ip_mreq mreq;
5024 +       int fd, yes = 1;
5025 +
5026 +
5027 +       if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) {
5028 +               fd = -EINVAL;
5029 +               goto out;
5030 +       }
5031 +
5032 +       fd = socket(AF_INET, SOCK_DGRAM, 0);
5033 +       if (fd < 0){
5034 +               printk("mcast_open : data socket failed, errno = %d\n", 
5035 +                      errno);
5036 +               fd = -ENOMEM;
5037 +               goto out;
5038 +       }
5039 +
5040 +       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
5041 +               printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
5042 +                       errno);
5043 +               os_close_file(fd);
5044 +               fd = -EINVAL;
5045 +               goto out;
5046 +       }
5047 +
5048 +       /* set ttl according to config */
5049 +       if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
5050 +                      sizeof(pri->ttl)) < 0) {
5051 +               printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
5052 +                       errno);
5053 +               os_close_file(fd);
5054 +               fd = -EINVAL;
5055 +               goto out;
5056 +       }
5057 +
5058 +       /* set LOOP, so data does get fed back to local sockets */
5059 +       if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
5060 +               printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
5061 +                       errno);
5062 +               os_close_file(fd);
5063 +               fd = -EINVAL;
5064 +               goto out;
5065 +       }
5066 +
5067 +       /* bind socket to mcast address */
5068 +       if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
5069 +               printk("mcast_open : data bind failed, errno = %d\n", errno);
5070 +               os_close_file(fd);
5071 +               fd = -EINVAL;
5072 +               goto out;
5073 +       }               
5074 +       
5075 +       /* subscribe to the multicast group */
5076 +       mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
5077 +       mreq.imr_interface.s_addr = 0;
5078 +       if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, 
5079 +                      &mreq, sizeof(mreq)) < 0) {
5080 +               printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n",
5081 +                       errno);
5082 +               printk("There appears not to be a multicast-capable network "
5083 +                      "interface on the host.\n");
5084 +               printk("eth0 should be configured in order to use the "
5085 +                      "multicast transport.\n");
5086 +               os_close_file(fd);
5087 +               fd = -EINVAL;
5088 +       }
5089 +
5090 + out:
5091 +       return(fd);
5092 +}
5093 +
5094 +static void mcast_close(int fd, void *data)
5095 +{
5096 +       struct ip_mreq mreq;
5097 +       struct mcast_data *pri = data;
5098 +       struct sockaddr_in *sin = pri->mcast_addr;
5099 +
5100 +       mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
5101 +       mreq.imr_interface.s_addr = 0;
5102 +       if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
5103 +                      &mreq, sizeof(mreq)) < 0) {
5104 +               printk("mcast_open: IP_DROP_MEMBERSHIP failed, error = %d\n",
5105 +                       errno);
5106 +       }
5107 +
5108 +       os_close_file(fd);
5109 +}
5110 +
5111 +int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
5112 +{
5113 +       struct sockaddr_in *data_addr = pri->mcast_addr;
5114 +
5115 +       return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
5116 +}
5117 +
5118 +static int mcast_set_mtu(int mtu, void *data)
5119 +{
5120 +       return(mtu);
5121 +}
5122 +
5123 +struct net_user_info mcast_user_info = {
5124 +       .init           = mcast_user_init,
5125 +       .open           = mcast_open,
5126 +       .close          = mcast_close,
5127 +       .remove         = NULL,
5128 +       .set_mtu        = mcast_set_mtu,
5129 +       .add_address    = NULL,
5130 +       .delete_address = NULL,
5131 +       .max_packet     = MAX_PACKET - ETH_HEADER_OTHER
5132 +};
5133 +
5134 +/*
5135 + * Overrides for Emacs so that we follow Linus's tabbing style.
5136 + * Emacs will notice this stuff at the end of the file and automatically
5137 + * adjust the settings for this buffer only.  This must remain at the end
5138 + * of the file.
5139 + * ---------------------------------------------------------------------------
5140 + * Local variables:
5141 + * c-file-style: "linux"
5142 + * End:
5143 + */
5144 diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_kern.c um/arch/um/drivers/mconsole_kern.c
5145 --- orig/arch/um/drivers/mconsole_kern.c        1969-12-31 19:00:00.000000000 -0500
5146 +++ um/arch/um/drivers/mconsole_kern.c  2004-02-12 03:09:12.000000000 -0500
5147 @@ -0,0 +1,560 @@
5148 +/*
5149 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
5150 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
5151 + * Licensed under the GPL
5152 + */
5153 +
5154 +#include "linux/kernel.h"
5155 +#include "linux/slab.h"
5156 +#include "linux/init.h"
5157 +#include "linux/notifier.h"
5158 +#include "linux/reboot.h"
5159 +#include "linux/utsname.h"
5160 +#include "linux/ctype.h"
5161 +#include "linux/interrupt.h"
5162 +#include "linux/sysrq.h"
5163 +#include "linux/tqueue.h"
5164 +#include "linux/module.h"
5165 +#include "linux/file.h"
5166 +#include "linux/fs.h"
5167 +#include "linux/proc_fs.h"
5168 +#include "asm/irq.h"
5169 +#include "asm/uaccess.h"
5170 +#include "user_util.h"
5171 +#include "kern_util.h"
5172 +#include "kern.h"
5173 +#include "mconsole.h"
5174 +#include "mconsole_kern.h"
5175 +#include "irq_user.h"
5176 +#include "init.h"
5177 +#include "os.h"
5178 +#include "umid.h"
5179 +#include "irq_kern.h"
5180 +
5181 +static int do_unlink_socket(struct notifier_block *notifier, 
5182 +                           unsigned long what, void *data)
5183 +{
5184 +       return(mconsole_unlink_socket());
5185 +}
5186 +
5187 +
5188 +static struct notifier_block reboot_notifier = {
5189 +       .notifier_call          = do_unlink_socket,
5190 +       .priority               = 0,
5191 +};
5192 +
5193 +/* Safe without explicit locking for now.  Tasklets provide their own 
5194 + * locking, and the interrupt handler is safe because it can't interrupt
5195 + * itself and it can only happen on CPU 0.
5196 + */
5197 +
5198 +LIST_HEAD(mc_requests);
5199 +
5200 +void mc_task_proc(void *unused)
5201 +{
5202 +       struct mconsole_entry *req;
5203 +       unsigned long flags;
5204 +       int done;
5205 +
5206 +       do {
5207 +               save_flags(flags);
5208 +               req = list_entry(mc_requests.next, struct mconsole_entry, 
5209 +                                list);
5210 +               list_del(&req->list);
5211 +               done = list_empty(&mc_requests);
5212 +               restore_flags(flags);
5213 +               req->request.cmd->handler(&req->request);
5214 +               kfree(req);
5215 +       } while(!done);
5216 +}
5217 +
5218 +struct tq_struct mconsole_task = {
5219 +       .routine        = mc_task_proc,
5220 +       .data           = NULL
5221 +};
5222 +
5223 +void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
5224 +{
5225 +       int fd;
5226 +       struct mconsole_entry *new;
5227 +       struct mc_request req;
5228 +
5229 +       fd = (int) dev_id;
5230 +       while (mconsole_get_request(fd, &req)){
5231 +               if(req.cmd->context == MCONSOLE_INTR) 
5232 +                       (*req.cmd->handler)(&req);
5233 +               else {
5234 +                       new = kmalloc(sizeof(*new), GFP_ATOMIC);
5235 +                       if(new == NULL)
5236 +                               mconsole_reply(&req, "Out of memory", 1, 0);
5237 +                       else {
5238 +                               new->request = req;
5239 +                               list_add(&new->list, &mc_requests);
5240 +                       }
5241 +               }
5242 +       }
5243 +       if(!list_empty(&mc_requests)) schedule_task(&mconsole_task);
5244 +       reactivate_fd(fd, MCONSOLE_IRQ);
5245 +}
5246 +
5247 +void mconsole_version(struct mc_request *req)
5248 +{
5249 +       char version[256];
5250 +
5251 +       sprintf(version, "%s %s %s %s %s", system_utsname.sysname, 
5252 +               system_utsname.nodename, system_utsname.release, 
5253 +               system_utsname.version, system_utsname.machine);
5254 +       mconsole_reply(req, version, 0, 0);
5255 +}
5256 +
5257 +void mconsole_log(struct mc_request *req)
5258 +{
5259 +       int len;
5260 +       char *ptr = req->request.data;
5261 +       
5262 +       ptr += strlen("log ");
5263 +
5264 +       len = req->len - (ptr - req->request.data);
5265 +       printk("%.*s", len, ptr);
5266 +       mconsole_reply(req, "", 0, 0);
5267 +}
5268 +
5269 +void mconsole_proc(struct mc_request *req)
5270 +{
5271 +       struct nameidata nd;
5272 +       struct file_system_type *proc;
5273 +       struct super_block *super;
5274 +       struct file *file;
5275 +       int n, err;
5276 +       char *ptr = req->request.data, *buf;
5277 +       
5278 +       ptr += strlen("proc");
5279 +       while(isspace(*ptr)) ptr++;
5280 +
5281 +       proc = get_fs_type("proc");
5282 +       if(proc == NULL){
5283 +               mconsole_reply(req, "procfs not registered", 1, 0);
5284 +               goto out;
5285 +       }
5286 +
5287 +       super = get_anon_super(proc, NULL, NULL);
5288 +       if(super == NULL){
5289 +               mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
5290 +               goto out_put;
5291 +       }
5292 +
5293 +       if(super->s_root == NULL){
5294 +               super = (*proc->read_super)(super, NULL, 0);
5295 +               if(super == NULL){
5296 +                       mconsole_reply(req, "Failed to read superblock", 1, 0);
5297 +                       goto out_put;
5298 +               }
5299 +       }
5300 +       up_write(&super->s_umount);
5301 +
5302 +       nd.dentry = super->s_root;
5303 +       nd.mnt = NULL;
5304 +       nd.flags = O_RDONLY + 1;
5305 +       nd.last_type = LAST_ROOT;
5306 +
5307 +       err = link_path_walk(ptr, &nd);
5308 +       if(err){
5309 +               mconsole_reply(req, "Failed to look up file", 1, 0);
5310 +               goto out_kill;
5311 +       }
5312 +
5313 +       file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
5314 +       if(IS_ERR(file)){
5315 +               mconsole_reply(req, "Failed to open file", 1, 0);
5316 +               goto out_kill;
5317 +       }
5318 +
5319 +       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
5320 +       if(buf == NULL){
5321 +               mconsole_reply(req, "Failed to allocate buffer", 1, 0);
5322 +               goto out_fput;
5323 +       }
5324 +
5325 +       if((file->f_op != NULL) && (file->f_op->read != NULL)){
5326 +               do {
5327 +                       n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, 
5328 +                                               &file->f_pos);
5329 +                       if(n >= 0){
5330 +                               buf[n] = '\0';
5331 +                               mconsole_reply(req, buf, 0, (n > 0));
5332 +                       }
5333 +                       else {
5334 +                               mconsole_reply(req, "Read of file failed", 
5335 +                                              1, 0);
5336 +                               goto out_free;
5337 +                       }
5338 +               } while(n > 0);
5339 +       }
5340 +       else mconsole_reply(req, "", 0, 0);
5341 +
5342 + out_free:
5343 +       kfree(buf);
5344 + out_fput:
5345 +       fput(file);
5346 + out_kill:
5347 +       kill_super(super);
5348 + out_put:
5349 +       /* put_filesystem(proc); */
5350 + out: ;
5351 +}
5352 +
5353 +#define UML_MCONSOLE_HELPTEXT \
5354 +"Commands: \n\
5355 +    version - Get kernel version \n\
5356 +    help - Print this message \n\
5357 +    halt - Halt UML \n\
5358 +    reboot - Reboot UML \n\
5359 +    config <dev>=<config> - Add a new device to UML;  \n\
5360 +       same syntax as command line \n\
5361 +    config <dev> - Query the configuration of a device \n\
5362 +    remove <dev> - Remove a device from UML \n\
5363 +    sysrq <letter> - Performs the SysRq action controlled by the letter \n\
5364 +    cad - invoke the Ctl-Alt-Del handler \n\
5365 +    stop - pause the UML; it will do nothing until it receives a 'go' \n\
5366 +    go - continue the UML after a 'stop' \n\
5367 +    log <string> - make UML enter <string> into the kernel log\n\
5368 +    proc <file> - returns the contents of the UML's /proc/<file>\n\
5369 +"
5370 +
5371 +void mconsole_help(struct mc_request *req)
5372 +{
5373 +       mconsole_reply(req, UML_MCONSOLE_HELPTEXT, 0, 0);
5374 +}
5375 +
5376 +void mconsole_halt(struct mc_request *req)
5377 +{
5378 +       mconsole_reply(req, "", 0, 0);
5379 +       machine_halt();
5380 +}
5381 +
5382 +void mconsole_reboot(struct mc_request *req)
5383 +{
5384 +       mconsole_reply(req, "", 0, 0);
5385 +       machine_restart(NULL);
5386 +}
5387 +
5388 +extern void ctrl_alt_del(void);
5389 +
5390 +void mconsole_cad(struct mc_request *req)
5391 +{
5392 +       mconsole_reply(req, "", 0, 0);
5393 +       ctrl_alt_del();
5394 +}
5395 +
5396 +void mconsole_go(struct mc_request *req)
5397 +{
5398 +       mconsole_reply(req, "Not stopped", 1, 0);
5399 +}
5400 +
5401 +void mconsole_stop(struct mc_request *req)
5402 +{
5403 +       deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
5404 +       os_set_fd_block(req->originating_fd, 1);
5405 +       mconsole_reply(req, "", 0, 0);
5406 +       while(mconsole_get_request(req->originating_fd, req)){
5407 +               if(req->cmd->handler == mconsole_go) break;
5408 +               (*req->cmd->handler)(req);
5409 +       }
5410 +       os_set_fd_block(req->originating_fd, 0);
5411 +       reactivate_fd(req->originating_fd, MCONSOLE_IRQ);
5412 +       mconsole_reply(req, "", 0, 0);
5413 +}
5414 +
5415 +/* This list is populated by __initcall routines. */
5416 +
5417 +LIST_HEAD(mconsole_devices);
5418 +
5419 +void mconsole_register_dev(struct mc_device *new)
5420 +{
5421 +       list_add(&new->list, &mconsole_devices);
5422 +}
5423 +
5424 +static struct mc_device *mconsole_find_dev(char *name)
5425 +{
5426 +       struct list_head *ele;
5427 +       struct mc_device *dev;
5428 +
5429 +       list_for_each(ele, &mconsole_devices){
5430 +               dev = list_entry(ele, struct mc_device, list);
5431 +               if(!strncmp(name, dev->name, strlen(dev->name)))
5432 +                       return(dev);
5433 +       }
5434 +       return(NULL);
5435 +}
5436 +
5437 +#define CONFIG_BUF_SIZE 64
5438 +
5439 +static void mconsole_get_config(int (*get_config)(char *, char *, int, 
5440 +                                                 char **),
5441 +                               struct mc_request *req, char *name)
5442 +{
5443 +       char default_buf[CONFIG_BUF_SIZE], *error, *buf;
5444 +       int n, size;
5445 +
5446 +       if(get_config == NULL){
5447 +               mconsole_reply(req, "No get_config routine defined", 1, 0);
5448 +               return;
5449 +       }
5450 +
5451 +       error = NULL;
5452 +       size = sizeof(default_buf)/sizeof(default_buf[0]);
5453 +       buf = default_buf;
5454 +
5455 +       while(1){
5456 +               n = (*get_config)(name, buf, size, &error);
5457 +               if(error != NULL){
5458 +                       mconsole_reply(req, error, 1, 0);
5459 +                       goto out;
5460 +               }
5461 +
5462 +               if(n <= size){
5463 +                       mconsole_reply(req, buf, 0, 0);
5464 +                       goto out;
5465 +               }
5466 +
5467 +               if(buf != default_buf)
5468 +                       kfree(buf);
5469 +
5470 +               size = n;
5471 +               buf = kmalloc(size, GFP_KERNEL);
5472 +               if(buf == NULL){
5473 +                       mconsole_reply(req, "Failed to allocate buffer", 1, 0);
5474 +                       return;
5475 +               }
5476 +       }
5477 + out:
5478 +       if(buf != default_buf)
5479 +               kfree(buf);
5480 +       
5481 +}
5482 +
5483 +void mconsole_config(struct mc_request *req)
5484 +{
5485 +       struct mc_device *dev;
5486 +       char *ptr = req->request.data, *name;
5487 +       int err;
5488 +
5489 +       ptr += strlen("config");
5490 +       while(isspace(*ptr)) ptr++;
5491 +       dev = mconsole_find_dev(ptr);
5492 +       if(dev == NULL){
5493 +               mconsole_reply(req, "Bad configuration option", 1, 0);
5494 +               return;
5495 +       }
5496 +
5497 +       name = &ptr[strlen(dev->name)];
5498 +       ptr = name;
5499 +       while((*ptr != '=') && (*ptr != '\0'))
5500 +               ptr++;
5501 +
5502 +       if(*ptr == '='){
5503 +               err = (*dev->config)(name);
5504 +               mconsole_reply(req, "", err, 0);
5505 +       }
5506 +       else mconsole_get_config(dev->get_config, req, name);
5507 +}
5508 +
5509 +void mconsole_remove(struct mc_request *req)
5510 +{
5511 +       struct mc_device *dev;  
5512 +       char *ptr = req->request.data;
5513 +       int err;
5514 +
5515 +       ptr += strlen("remove");
5516 +       while(isspace(*ptr)) ptr++;
5517 +       dev = mconsole_find_dev(ptr);
5518 +       if(dev == NULL){
5519 +               mconsole_reply(req, "Bad remove option", 1, 0);
5520 +               return;
5521 +       }
5522 +       err = (*dev->remove)(&ptr[strlen(dev->name)]);
5523 +       mconsole_reply(req, "", err, 0);
5524 +}
5525 +
5526 +#ifdef CONFIG_MAGIC_SYSRQ
5527 +void mconsole_sysrq(struct mc_request *req)
5528 +{
5529 +       char *ptr = req->request.data;
5530 +
5531 +       ptr += strlen("sysrq");
5532 +       while(isspace(*ptr)) ptr++;
5533 +
5534 +       mconsole_reply(req, "", 0, 0);
5535 +       handle_sysrq(*ptr, &current->thread.regs, NULL, NULL);
5536 +}
5537 +#else
5538 +void mconsole_sysrq(struct mc_request *req)
5539 +{
5540 +       mconsole_reply(req, "Sysrq not compiled in", 1, 0);
5541 +}
5542 +#endif
5543 +
5544 +/* Changed by mconsole_setup, which is __setup, and called before SMP is
5545 + * active.
5546 + */
5547 +static char *notify_socket = NULL; 
5548 +
5549 +int mconsole_init(void)
5550 +{
5551 +       int err, sock;
5552 +       char file[256];
5553 +
5554 +       if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
5555 +       snprintf(mconsole_socket_name, sizeof(file), "%s", file);
5556 +
5557 +       sock = os_create_unix_socket(file, sizeof(file), 1);
5558 +       if (sock < 0){
5559 +               printk("Failed to initialize management console\n");
5560 +               return(1);
5561 +       }
5562 +
5563 +       register_reboot_notifier(&reboot_notifier);
5564 +
5565 +       err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
5566 +                            SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
5567 +                            "mconsole", (void *)sock);
5568 +       if (err){
5569 +               printk("Failed to get IRQ for management console\n");
5570 +               return(1);
5571 +       }
5572 +
5573 +       if(notify_socket != NULL){
5574 +               notify_socket = uml_strdup(notify_socket);
5575 +               if(notify_socket != NULL)
5576 +                       mconsole_notify(notify_socket, MCONSOLE_SOCKET,
5577 +                                       mconsole_socket_name, 
5578 +                                       strlen(mconsole_socket_name) + 1);
5579 +               else printk(KERN_ERR "mconsole_setup failed to strdup "
5580 +                           "string\n");
5581 +       }
5582 +
5583 +       printk("mconsole (version %d) initialized on %s\n", 
5584 +              MCONSOLE_VERSION, mconsole_socket_name);
5585 +       return(0);
5586 +}
5587 +
5588 +__initcall(mconsole_init);
5589 +
5590 +static int write_proc_mconsole(struct file *file, const char *buffer,
5591 +                              unsigned long count, void *data)
5592 +{
5593 +       char *buf;
5594 +
5595 +       buf = kmalloc(count + 1, GFP_KERNEL);
5596 +       if(buf == NULL) 
5597 +               return(-ENOMEM);
5598 +
5599 +       if(copy_from_user(buf, buffer, count)){
5600 +               count = -EFAULT;
5601 +               goto out;
5602 +       }
5603 +
5604 +       buf[count] = '\0';
5605 +
5606 +       mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
5607 + out:
5608 +       kfree(buf);
5609 +       return(count);
5610 +}
5611 +
5612 +static int create_proc_mconsole(void)
5613 +{
5614 +       struct proc_dir_entry *ent;
5615 +
5616 +       if(notify_socket == NULL) return(0);
5617 +
5618 +       ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
5619 +       if(ent == NULL){
5620 +               printk("create_proc_mconsole : create_proc_entry failed\n");
5621 +               return(0);
5622 +       }
5623 +
5624 +       ent->read_proc = NULL;
5625 +       ent->write_proc = write_proc_mconsole;
5626 +       return(0);
5627 +}
5628 +
5629 +static spinlock_t notify_spinlock = SPIN_LOCK_UNLOCKED;
5630 +
5631 +void lock_notify(void)
5632 +{
5633 +       spin_lock(&notify_spinlock);
5634 +}
5635 +
5636 +void unlock_notify(void)
5637 +{
5638 +       spin_unlock(&notify_spinlock);
5639 +}
5640 +
5641 +__initcall(create_proc_mconsole);
5642 +
5643 +#define NOTIFY "=notify:"
5644 +
5645 +static int mconsole_setup(char *str)
5646 +{
5647 +       if(!strncmp(str, NOTIFY, strlen(NOTIFY))){
5648 +               str += strlen(NOTIFY);
5649 +               notify_socket = str;
5650 +       }
5651 +       else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str);
5652 +       return(1);
5653 +}
5654 +
5655 +__setup("mconsole", mconsole_setup);
5656 +
5657 +__uml_help(mconsole_setup,
5658 +"mconsole=notify:<socket>\n"
5659 +"    Requests that the mconsole driver send a message to the named Unix\n"
5660 +"    socket containing the name of the mconsole socket.  This also serves\n"
5661 +"    to notify outside processes when UML has booted far enough to respond\n"
5662 +"    to mconsole requests.\n\n"
5663 +);
5664 +
5665 +static int notify_panic(struct notifier_block *self, unsigned long unused1,
5666 +                       void *ptr)
5667 +{
5668 +       char *message = ptr;
5669 +
5670 +       if(notify_socket == NULL) return(0);
5671 +
5672 +       mconsole_notify(notify_socket, MCONSOLE_PANIC, message, 
5673 +                       strlen(message) + 1);
5674 +       return(0);
5675 +}
5676 +
5677 +static struct notifier_block panic_exit_notifier = {
5678 +       .notifier_call          = notify_panic,
5679 +       .next                   = NULL,
5680 +       .priority               = 1
5681 +};
5682 +
5683 +static int add_notifier(void)
5684 +{
5685 +       notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
5686 +       return(0);
5687 +}
5688 +
5689 +__initcall(add_notifier);
5690 +
5691 +char *mconsole_notify_socket(void)
5692 +{
5693 +       return(notify_socket);
5694 +}
5695 +
5696 +EXPORT_SYMBOL(mconsole_notify_socket);
5697 +
5698 +/*
5699 + * Overrides for Emacs so that we follow Linus's tabbing style.
5700 + * Emacs will notice this stuff at the end of the file and automatically
5701 + * adjust the settings for this buffer only.  This must remain at the end
5702 + * of the file.
5703 + * ---------------------------------------------------------------------------
5704 + * Local variables:
5705 + * c-file-style: "linux"
5706 + * End:
5707 + */
5708 diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_user.c um/arch/um/drivers/mconsole_user.c
5709 --- orig/arch/um/drivers/mconsole_user.c        1969-12-31 19:00:00.000000000 -0500
5710 +++ um/arch/um/drivers/mconsole_user.c  2003-10-21 03:26:06.000000000 -0400
5711 @@ -0,0 +1,215 @@
5712 +/*
5713 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
5714 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
5715 + * Licensed under the GPL
5716 + */
5717 +
5718 +#include <stdio.h>
5719 +#include <stdlib.h>
5720 +#include <errno.h>
5721 +#include <signal.h>
5722 +#include <sys/socket.h>
5723 +#include <sys/types.h>
5724 +#include <sys/uio.h>
5725 +#include <sys/un.h>
5726 +#include <unistd.h>
5727 +#include "user.h"
5728 +#include "mconsole.h"
5729 +#include "umid.h"
5730 +
5731 +static struct mconsole_command commands[] = {
5732 +       { "version", mconsole_version, MCONSOLE_INTR },
5733 +       { "halt", mconsole_halt, MCONSOLE_PROC },
5734 +       { "reboot", mconsole_reboot, MCONSOLE_PROC },
5735 +       { "config", mconsole_config, MCONSOLE_PROC },
5736 +       { "remove", mconsole_remove, MCONSOLE_PROC },
5737 +       { "sysrq", mconsole_sysrq, MCONSOLE_INTR },
5738 +       { "help", mconsole_help, MCONSOLE_INTR },
5739 +       { "cad", mconsole_cad, MCONSOLE_INTR },
5740 +       { "stop", mconsole_stop, MCONSOLE_PROC },
5741 +       { "go", mconsole_go, MCONSOLE_INTR },
5742 +       { "log", mconsole_log, MCONSOLE_INTR },
5743 +       { "proc", mconsole_proc, MCONSOLE_PROC },
5744 +};
5745 +
5746 +/* Initialized in mconsole_init, which is an initcall */
5747 +char mconsole_socket_name[256];
5748 +
5749 +int mconsole_reply_v0(struct mc_request *req, char *reply)
5750 +{
5751 +        struct iovec iov;
5752 +        struct msghdr msg;
5753 +
5754 +        iov.iov_base = reply;
5755 +        iov.iov_len = strlen(reply);
5756 +
5757 +        msg.msg_name = &(req->origin);
5758 +        msg.msg_namelen = req->originlen;
5759 +        msg.msg_iov = &iov;
5760 +        msg.msg_iovlen = 1;
5761 +        msg.msg_control = NULL;
5762 +        msg.msg_controllen = 0;
5763 +        msg.msg_flags = 0;
5764 +
5765 +        return sendmsg(req->originating_fd, &msg, 0);
5766 +}
5767 +
5768 +static struct mconsole_command *mconsole_parse(struct mc_request *req)
5769 +{
5770 +       struct mconsole_command *cmd;
5771 +       int i;
5772 +
5773 +       for(i=0;i<sizeof(commands)/sizeof(commands[0]);i++){
5774 +               cmd = &commands[i];
5775 +               if(!strncmp(req->request.data, cmd->command, 
5776 +                           strlen(cmd->command))){
5777 +                       return(cmd);
5778 +               }
5779 +       }
5780 +       return(NULL);
5781 +}
5782 +
5783 +#define MIN(a,b) ((a)<(b) ? (a):(b))
5784 +
5785 +#define STRINGX(x) #x
5786 +#define STRING(x) STRINGX(x)
5787 +
5788 +int mconsole_get_request(int fd, struct mc_request *req)
5789 +{
5790 +       int len;
5791 +
5792 +       req->originlen = sizeof(req->origin);
5793 +       req->len = recvfrom(fd, &req->request, sizeof(req->request), 0,
5794 +                           (struct sockaddr *) req->origin, &req->originlen);
5795 +       if (req->len < 0)
5796 +               return 0;
5797 +
5798 +       req->originating_fd = fd;
5799 +
5800 +       if(req->request.magic != MCONSOLE_MAGIC){
5801 +               /* Unversioned request */
5802 +               len = MIN(sizeof(req->request.data) - 1, 
5803 +                         strlen((char *) &req->request));
5804 +               memmove(req->request.data, &req->request, len);
5805 +               req->request.data[len] = '\0';
5806 +
5807 +               req->request.magic = MCONSOLE_MAGIC;
5808 +               req->request.version = 0;
5809 +               req->request.len = len;
5810 +
5811 +               mconsole_reply_v0(req, "ERR Version 0 mconsole clients are "
5812 +                                 "not supported by this driver");
5813 +               return(0);
5814 +       }
5815 +
5816 +       if(req->request.len >= MCONSOLE_MAX_DATA){
5817 +               mconsole_reply(req, "Request too large", 1, 0);
5818 +               return(0);
5819 +       }
5820 +       if(req->request.version != MCONSOLE_VERSION){
5821 +               mconsole_reply(req, "This driver only supports version " 
5822 +                               STRING(MCONSOLE_VERSION) " clients", 1, 0);
5823 +       }
5824 +       
5825 +       req->request.data[req->request.len] = '\0';
5826 +       req->cmd = mconsole_parse(req);
5827 +       if(req->cmd == NULL){
5828 +               mconsole_reply(req, "Unknown command", 1, 0);
5829 +               return(0);
5830 +       }
5831 +
5832 +       return(1);
5833 +}
5834 +
5835 +int mconsole_reply(struct mc_request *req, char *str, int err, int more)
5836 +{
5837 +       struct mconsole_reply reply;
5838 +       int total, len, n;
5839 +
5840 +       total = strlen(str);
5841 +       do {
5842 +               reply.err = err;
5843 +
5844 +               /* err can only be true on the first packet */
5845 +               err = 0;
5846 +
5847 +               len = MIN(total, MCONSOLE_MAX_DATA - 1);
5848 +
5849 +               if(len == total) reply.more = more;
5850 +               else reply.more = 1;
5851 +
5852 +               memcpy(reply.data, str, len);
5853 +               reply.data[len] = '\0';
5854 +               total -= len;
5855 +               str += len;
5856 +               reply.len = len + 1;
5857 +
5858 +               len = sizeof(reply) + reply.len - sizeof(reply.data);
5859 +
5860 +               n = sendto(req->originating_fd, &reply, len, 0,
5861 +                          (struct sockaddr *) req->origin, req->originlen);
5862 +
5863 +               if(n < 0) return(-errno);
5864 +       } while(total > 0);
5865 +       return(0);
5866 +}
5867 +
5868 +int mconsole_unlink_socket(void)
5869 +{
5870 +       unlink(mconsole_socket_name);
5871 +       return 0;
5872 +}
5873 +
5874 +static int notify_sock = -1;
5875 +
5876 +int mconsole_notify(char *sock_name, int type, const void *data, int len)
5877 +{
5878 +       struct sockaddr_un target;
5879 +       struct mconsole_notify packet;
5880 +       int n, err = 0;
5881 +
5882 +       lock_notify();
5883 +       if(notify_sock < 0){
5884 +               notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0);
5885 +               if(notify_sock < 0){
5886 +                       printk("mconsole_notify - socket failed, errno = %d\n",
5887 +                              errno);
5888 +                       err = -errno;
5889 +               }
5890 +       }
5891 +       unlock_notify();
5892 +       
5893 +       if(err)
5894 +               return(err);
5895 +
5896 +       target.sun_family = AF_UNIX;
5897 +       strcpy(target.sun_path, sock_name);
5898 +
5899 +       packet.magic = MCONSOLE_MAGIC;
5900 +       packet.version = MCONSOLE_VERSION;
5901 +       packet.type = type;
5902 +       len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len;
5903 +       packet.len = len;
5904 +       memcpy(packet.data, data, len);
5905 +
5906 +       err = 0;
5907 +       len = sizeof(packet) + packet.len - sizeof(packet.data);
5908 +       n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target, 
5909 +                  sizeof(target));
5910 +       if(n < 0){
5911 +               printk("mconsole_notify - sendto failed, errno = %d\n", errno);
5912 +               err = -errno;
5913 +       }
5914 +       return(err);
5915 +}
5916 +
5917 +/*
5918 + * Overrides for Emacs so that we follow Linus's tabbing style.
5919 + * Emacs will notice this stuff at the end of the file and automatically
5920 + * adjust the settings for this buffer only.  This must remain at the end
5921 + * of the file.
5922 + * ---------------------------------------------------------------------------
5923 + * Local variables:
5924 + * c-file-style: "linux"
5925 + * End:
5926 + */
5927 diff -Naur -X ../exclude-files orig/arch/um/drivers/mmapper_kern.c um/arch/um/drivers/mmapper_kern.c
5928 --- orig/arch/um/drivers/mmapper_kern.c 1969-12-31 19:00:00.000000000 -0500
5929 +++ um/arch/um/drivers/mmapper_kern.c   2003-10-21 03:26:06.000000000 -0400
5930 @@ -0,0 +1,151 @@
5931 +/*
5932 + * arch/um/drivers/mmapper_kern.c
5933 + *
5934 + * BRIEF MODULE DESCRIPTION
5935 + *
5936 + * Copyright (C) 2000 RidgeRun, Inc.
5937 + * Author: RidgeRun, Inc.
5938 + *         Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
5939 + *
5940 + */
5941 +#include <linux/kdev_t.h>
5942 +#include <linux/time.h>
5943 +#include <linux/devfs_fs_kernel.h>
5944 +#include <linux/module.h>
5945 +#include <linux/mm.h> 
5946 +#include <linux/slab.h>
5947 +#include <linux/init.h> 
5948 +#include <asm/uaccess.h>
5949 +#include <asm/irq.h>
5950 +#include <asm/smplock.h>
5951 +#include <asm/pgtable.h>
5952 +#include "mem_user.h"
5953 +#include "user_util.h"
5954
5955 +/* These are set in mmapper_init, which is called at boot time */
5956 +static unsigned long mmapper_size;
5957 +static unsigned long p_buf = 0;
5958 +static char *v_buf = NULL;
5959 +
5960 +static ssize_t
5961 +mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos)
5962 +{
5963 +       if(*ppos > mmapper_size)
5964 +               return -EINVAL;
5965 +
5966 +       if(count + *ppos > mmapper_size)
5967 +               count = count + *ppos - mmapper_size;
5968 +
5969 +       if(count < 0)
5970 +               return -EINVAL;
5971
5972 +       copy_to_user(buf,&v_buf[*ppos],count);
5973 +       
5974 +       return count;
5975 +}
5976 +
5977 +static ssize_t
5978 +mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
5979 +{
5980 +       if(*ppos > mmapper_size)
5981 +               return -EINVAL;
5982 +
5983 +       if(count + *ppos > mmapper_size)
5984 +               count = count + *ppos - mmapper_size;
5985 +
5986 +       if(count < 0)
5987 +               return -EINVAL;
5988 +
5989 +       copy_from_user(&v_buf[*ppos],buf,count);
5990 +       
5991 +       return count;
5992 +}
5993 +
5994 +static int 
5995 +mmapper_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
5996 +        unsigned long arg)
5997 +{
5998 +       return(-ENOIOCTLCMD);
5999 +}
6000 +
6001 +static int 
6002 +mmapper_mmap(struct file *file, struct vm_area_struct * vma)
6003 +{
6004 +       int ret = -EINVAL;
6005 +       int size;
6006 +
6007 +       lock_kernel();
6008 +       if (vma->vm_pgoff != 0)
6009 +               goto out;
6010 +       
6011 +       size = vma->vm_end - vma->vm_start;
6012 +       if(size > mmapper_size) return(-EFAULT);
6013 +
6014 +       /* XXX A comment above remap_page_range says it should only be
6015 +        * called when the mm semaphore is held
6016 +        */
6017 +       if (remap_page_range(vma->vm_start, p_buf, size, vma->vm_page_prot))
6018 +               goto out;
6019 +       ret = 0;
6020 +out:
6021 +       unlock_kernel();
6022 +       return ret;
6023 +}
6024 +
6025 +static int
6026 +mmapper_open(struct inode *inode, struct file *file)
6027 +{
6028 +       return 0;
6029 +}
6030 +
6031 +static int 
6032 +mmapper_release(struct inode *inode, struct file *file)
6033 +{
6034 +       return 0;
6035 +}
6036 +
6037 +static struct file_operations mmapper_fops = {
6038 +       .owner          = THIS_MODULE,
6039 +       .read           = mmapper_read,
6040 +       .write          = mmapper_write,
6041 +       .ioctl          = mmapper_ioctl,
6042 +       .mmap           = mmapper_mmap,
6043 +       .open           = mmapper_open,
6044 +       .release        = mmapper_release,
6045 +};
6046 +
6047 +static int __init mmapper_init(void)
6048 +{
6049 +       printk(KERN_INFO "Mapper v0.1\n");
6050 +
6051 +       v_buf = (char *) find_iomem("mmapper", &mmapper_size);
6052 +       if(mmapper_size == 0){
6053 +               printk(KERN_ERR "mmapper_init - find_iomem failed\n");
6054 +               return(0);
6055 +       }
6056 +
6057 +       p_buf = __pa(v_buf);
6058 +
6059 +       devfs_register (NULL, "mmapper", DEVFS_FL_DEFAULT, 
6060 +                       30, 0, S_IFCHR | S_IRUGO | S_IWUGO, 
6061 +                       &mmapper_fops, NULL); 
6062 +       devfs_mk_symlink(NULL, "mmapper0", DEVFS_FL_DEFAULT, "mmapper",
6063 +                        NULL, NULL);
6064 +       return(0);
6065 +}
6066 +
6067 +static void mmapper_exit(void)
6068 +{
6069 +}
6070 +
6071 +module_init(mmapper_init);
6072 +module_exit(mmapper_exit);
6073 +
6074 +MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>");
6075 +MODULE_DESCRIPTION("DSPLinux simulator mmapper driver");
6076 +/*
6077 + * ---------------------------------------------------------------------------
6078 + * Local variables:
6079 + * c-file-style: "linux"
6080 + * End:
6081 + */
6082 diff -Naur -X ../exclude-files orig/arch/um/drivers/net_kern.c um/arch/um/drivers/net_kern.c
6083 --- orig/arch/um/drivers/net_kern.c     1969-12-31 19:00:00.000000000 -0500
6084 +++ um/arch/um/drivers/net_kern.c       2003-10-21 03:26:06.000000000 -0400
6085 @@ -0,0 +1,872 @@
6086 +/*
6087 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
6088 + * James Leu (jleu@mindspring.net).
6089 + * Copyright (C) 2001 by various other people who didn't put their name here.
6090 + * Licensed under the GPL.
6091 + */
6092 +
6093 +#include "linux/config.h"
6094 +#include "linux/kernel.h"
6095 +#include "linux/netdevice.h"
6096 +#include "linux/rtnetlink.h"
6097 +#include "linux/skbuff.h"
6098 +#include "linux/socket.h"
6099 +#include "linux/spinlock.h"
6100 +#include "linux/module.h"
6101 +#include "linux/init.h"
6102 +#include "linux/etherdevice.h"
6103 +#include "linux/list.h"
6104 +#include "linux/inetdevice.h"
6105 +#include "linux/ctype.h"
6106 +#include "linux/bootmem.h"
6107 +#include "user_util.h"
6108 +#include "kern_util.h"
6109 +#include "net_kern.h"
6110 +#include "net_user.h"
6111 +#include "mconsole_kern.h"
6112 +#include "init.h"
6113 +#include "irq_user.h"
6114 +#include "irq_kern.h"
6115 +
6116 +static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
6117 +LIST_HEAD(opened);
6118 +
6119 +static int uml_net_rx(struct net_device *dev)
6120 +{
6121 +       struct uml_net_private *lp = dev->priv;
6122 +       int pkt_len;
6123 +       struct sk_buff *skb;
6124 +
6125 +       /* If we can't allocate memory, try again next round. */
6126 +       skb = dev_alloc_skb(dev->mtu);
6127 +       if (skb == NULL) {
6128 +               lp->stats.rx_dropped++;
6129 +               return 0;
6130 +       }
6131 +
6132 +       skb->dev = dev;
6133 +       skb_put(skb, dev->mtu);
6134 +       skb->mac.raw = skb->data;
6135 +       pkt_len = (*lp->read)(lp->fd, &skb, lp);
6136 +
6137 +       if (pkt_len > 0) {
6138 +               skb_trim(skb, pkt_len);
6139 +               skb->protocol = (*lp->protocol)(skb);
6140 +               netif_rx(skb);
6141 +
6142 +               lp->stats.rx_bytes += skb->len;
6143 +               lp->stats.rx_packets++;
6144 +               return pkt_len;
6145 +       }
6146 +
6147 +       kfree_skb(skb);
6148 +       return pkt_len;
6149 +}
6150 +
6151 +void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6152 +{
6153 +       struct net_device *dev = dev_id;
6154 +       struct uml_net_private *lp = dev->priv;
6155 +       int err;
6156 +
6157 +       if(!netif_running(dev))
6158 +               return;
6159 +
6160 +       spin_lock(&lp->lock);
6161 +       while((err = uml_net_rx(dev)) > 0) ;
6162 +       if(err < 0) {
6163 +               printk(KERN_ERR 
6164 +                      "Device '%s' read returned %d, shutting it down\n", 
6165 +                      dev->name, err);
6166 +               dev_close(dev);
6167 +               goto out;
6168 +       }
6169 +       reactivate_fd(lp->fd, UM_ETH_IRQ);
6170 +
6171 + out:
6172 +       spin_unlock(&lp->lock);
6173 +}
6174 +
6175 +static int uml_net_open(struct net_device *dev)
6176 +{
6177 +       struct uml_net_private *lp = dev->priv;
6178 +       char addr[sizeof("255.255.255.255\0")];
6179 +       int err;
6180 +
6181 +       spin_lock(&lp->lock);
6182 +
6183 +       if(lp->fd >= 0){
6184 +               err = -ENXIO;
6185 +               goto out;
6186 +       }
6187 +
6188 +       if(!lp->have_mac){
6189 +               dev_ip_addr(dev, addr, &lp->mac[2]);
6190 +               set_ether_mac(dev, lp->mac);
6191 +       }
6192 +
6193 +       lp->fd = (*lp->open)(&lp->user);
6194 +       if(lp->fd < 0){
6195 +               err = lp->fd;
6196 +               goto out;
6197 +       }
6198 +
6199 +       err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
6200 +                            SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
6201 +       if(err != 0){
6202 +               printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
6203 +               if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6204 +               lp->fd = -1;
6205 +               err = -ENETUNREACH;
6206 +       }
6207 +
6208 +       lp->tl.data = (unsigned long) &lp->user;
6209 +       netif_start_queue(dev);
6210 +
6211 +       spin_lock(&opened_lock);
6212 +       list_add(&lp->list, &opened);
6213 +       spin_unlock(&opened_lock);
6214 +       MOD_INC_USE_COUNT;
6215 + out:
6216 +       spin_unlock(&lp->lock);
6217 +       return(err);
6218 +}
6219 +
6220 +static int uml_net_close(struct net_device *dev)
6221 +{
6222 +       struct uml_net_private *lp = dev->priv;
6223 +       
6224 +       netif_stop_queue(dev);
6225 +       spin_lock(&lp->lock);
6226 +
6227 +       free_irq(dev->irq, dev);
6228 +       if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6229 +       lp->fd = -1;
6230 +       spin_lock(&opened_lock);
6231 +       list_del(&lp->list);
6232 +       spin_unlock(&opened_lock);
6233 +
6234 +       MOD_DEC_USE_COUNT;
6235 +       spin_unlock(&lp->lock);
6236 +       return 0;
6237 +}
6238 +
6239 +static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
6240 +{
6241 +       struct uml_net_private *lp = dev->priv;
6242 +       unsigned long flags;
6243 +       int len;
6244 +
6245 +       netif_stop_queue(dev);
6246 +
6247 +       spin_lock_irqsave(&lp->lock, flags);
6248 +
6249 +       len = (*lp->write)(lp->fd, &skb, lp);
6250 +
6251 +       if(len == skb->len) {
6252 +               lp->stats.tx_packets++;
6253 +               lp->stats.tx_bytes += skb->len;
6254 +               dev->trans_start = jiffies;
6255 +               netif_start_queue(dev);
6256 +
6257 +               /* this is normally done in the interrupt when tx finishes */
6258 +               netif_wake_queue(dev);
6259 +       } 
6260 +       else if(len == 0){
6261 +               netif_start_queue(dev);
6262 +               lp->stats.tx_dropped++;
6263 +       }
6264 +       else {
6265 +               netif_start_queue(dev);
6266 +               printk(KERN_ERR "uml_net_start_xmit: failed(%d)\n", len);
6267 +       }
6268 +
6269 +       spin_unlock_irqrestore(&lp->lock, flags);
6270 +
6271 +       dev_kfree_skb(skb);
6272 +
6273 +       return 0;
6274 +}
6275 +
6276 +static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
6277 +{
6278 +       struct uml_net_private *lp = dev->priv;
6279 +       return &lp->stats;
6280 +}
6281 +
6282 +static void uml_net_set_multicast_list(struct net_device *dev)
6283 +{
6284 +       if (dev->flags & IFF_PROMISC) return;
6285 +       else if (dev->mc_count) dev->flags |= IFF_ALLMULTI;
6286 +       else dev->flags &= ~IFF_ALLMULTI;
6287 +}
6288 +
6289 +static void uml_net_tx_timeout(struct net_device *dev)
6290 +{
6291 +       dev->trans_start = jiffies;
6292 +       netif_wake_queue(dev);
6293 +}
6294 +
6295 +static int uml_net_set_mac(struct net_device *dev, void *addr)
6296 +{
6297 +       struct uml_net_private *lp = dev->priv;
6298 +       struct sockaddr *hwaddr = addr;
6299 +
6300 +       spin_lock(&lp->lock);
6301 +       memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
6302 +       spin_unlock(&lp->lock);
6303 +
6304 +       return(0);
6305 +}
6306 +
6307 +static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
6308 +{
6309 +       struct uml_net_private *lp = dev->priv;
6310 +       int err = 0;
6311 +
6312 +       spin_lock(&lp->lock);
6313 +
6314 +       new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
6315 +       if(new_mtu < 0){
6316 +               err = new_mtu;
6317 +               goto out;
6318 +       }
6319 +
6320 +       dev->mtu = new_mtu;
6321 +
6322 + out:
6323 +       spin_unlock(&lp->lock);
6324 +       return err;
6325 +}
6326 +
6327 +static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6328 +{
6329 +       return(-EINVAL);
6330 +}
6331 +
6332 +void uml_net_user_timer_expire(unsigned long _conn)
6333 +{
6334 +#ifdef undef
6335 +       struct connection *conn = (struct connection *)_conn;
6336 +
6337 +       dprintk(KERN_INFO "uml_net_user_timer_expire [%p]\n", conn);
6338 +       do_connect(conn);
6339 +#endif
6340 +}
6341 +
6342 +/*
6343 + * default do nothing hard header packet routines for struct net_device init.
6344 + * real ethernet transports will overwrite with real routines.
6345 + */
6346 +static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
6347 +                 unsigned short type, void *daddr, void *saddr, unsigned len)
6348 +{
6349 +       return(0); /* no change */
6350 +}
6351 +
6352 +static int uml_net_rebuild_header(struct sk_buff *skb)
6353 +{
6354 +       return(0); /* ignore */ 
6355 +}
6356 +
6357 +static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
6358 +{
6359 +       return(-1); /* fail */
6360 +}
6361 +
6362 +static void uml_net_header_cache_update(struct hh_cache *hh,
6363 +                 struct net_device *dev, unsigned char * haddr)
6364 +{
6365 +       /* ignore */
6366 +}
6367 +
6368 +static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
6369 +{
6370 +       return(0); /* nothing */
6371 +}
6372 +
6373 +static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
6374 +static struct list_head devices = LIST_HEAD_INIT(devices);
6375 +
6376 +static int eth_configure(int n, void *init, char *mac,
6377 +                        struct transport *transport)
6378 +{
6379 +       struct uml_net *device;
6380 +       struct net_device *dev;
6381 +       struct uml_net_private *lp;
6382 +       int save, err, size;
6383 +
6384 +       size = transport->private_size + sizeof(struct uml_net_private) + 
6385 +               sizeof(((struct uml_net_private *) 0)->user);
6386 +
6387 +       device = kmalloc(sizeof(*device), GFP_KERNEL);
6388 +       if(device == NULL){
6389 +               printk(KERN_ERR "eth_configure failed to allocate uml_net\n");
6390 +               return(1);
6391 +       }
6392 +
6393 +       *device = ((struct uml_net) { .list     = LIST_HEAD_INIT(device->list),
6394 +                                     .dev      = NULL,
6395 +                                     .index    = n,
6396 +                                     .mac      = { [ 0 ... 5 ] = 0 },
6397 +                                     .have_mac = 0 });
6398 +
6399 +       spin_lock(&devices_lock);
6400 +       list_add(&device->list, &devices);
6401 +       spin_unlock(&devices_lock);
6402 +
6403 +       if(setup_etheraddr(mac, device->mac))
6404 +               device->have_mac = 1;
6405 +
6406 +       printk(KERN_INFO "Netdevice %d ", n);
6407 +       if(device->have_mac) printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
6408 +                                   device->mac[0], device->mac[1], 
6409 +                                   device->mac[2], device->mac[3], 
6410 +                                   device->mac[4], device->mac[5]);
6411 +       printk(": ");
6412 +       dev = kmalloc(sizeof(*dev) + size, GFP_KERNEL);
6413 +       if(dev == NULL){
6414 +               printk(KERN_ERR "eth_configure: failed to allocate device\n");
6415 +               return(1);
6416 +       }
6417 +       memset(dev, 0, sizeof(*dev) + size);
6418 +
6419 +       snprintf(dev->name, sizeof(dev->name), "eth%d", n);
6420 +       dev->priv = (void *) &dev[1];
6421 +       device->dev = dev;
6422 +
6423 +        dev->hard_header = uml_net_hard_header;
6424 +        dev->rebuild_header = uml_net_rebuild_header;
6425 +        dev->hard_header_cache = uml_net_header_cache;
6426 +        dev->header_cache_update= uml_net_header_cache_update;
6427 +        dev->hard_header_parse = uml_net_header_parse;
6428 +
6429 +       (*transport->kern->init)(dev, init);
6430 +
6431 +       dev->mtu = transport->user->max_packet;
6432 +       dev->open = uml_net_open;
6433 +       dev->hard_start_xmit = uml_net_start_xmit;
6434 +       dev->stop = uml_net_close;
6435 +       dev->get_stats = uml_net_get_stats;
6436 +       dev->set_multicast_list = uml_net_set_multicast_list;
6437 +       dev->tx_timeout = uml_net_tx_timeout;
6438 +       dev->set_mac_address = uml_net_set_mac;
6439 +       dev->change_mtu = uml_net_change_mtu;
6440 +       dev->do_ioctl = uml_net_ioctl;
6441 +       dev->watchdog_timeo = (HZ >> 1);
6442 +       dev->irq = UM_ETH_IRQ;
6443 +
6444 +       rtnl_lock();
6445 +       err = register_netdevice(dev);
6446 +       rtnl_unlock();
6447 +       if(err)
6448 +               return(1);
6449 +       lp = dev->priv;
6450 +
6451 +       /* lp.user is the first four bytes of the transport data, which
6452 +        * has already been initialized.  This structure assignment will
6453 +        * overwrite that, so we make sure that .user gets overwritten with
6454 +        * what it already has.
6455 +        */
6456 +       save = lp->user[0];
6457 +       *lp = ((struct uml_net_private) 
6458 +               { .list                 = LIST_HEAD_INIT(lp->list),
6459 +                 .lock                 = SPIN_LOCK_UNLOCKED,
6460 +                 .dev                  = dev,
6461 +                 .fd                   = -1,
6462 +                 .mac                  = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
6463 +                 .have_mac             = device->have_mac,
6464 +                 .protocol             = transport->kern->protocol,
6465 +                 .open                 = transport->user->open,
6466 +                 .close                = transport->user->close,
6467 +                 .remove               = transport->user->remove,
6468 +                 .read                 = transport->kern->read,
6469 +                 .write                = transport->kern->write,
6470 +                 .add_address          = transport->user->add_address,
6471 +                 .delete_address       = transport->user->delete_address,
6472 +                 .set_mtu              = transport->user->set_mtu,
6473 +                 .user                 = { save } });
6474 +       init_timer(&lp->tl);
6475 +       lp->tl.function = uml_net_user_timer_expire;
6476 +       memset(&lp->stats, 0, sizeof(lp->stats));
6477 +       if(lp->have_mac) memcpy(lp->mac, device->mac, sizeof(lp->mac));
6478 +
6479 +       if(transport->user->init) 
6480 +               (*transport->user->init)(&lp->user, dev);
6481 +
6482 +       if(device->have_mac)
6483 +               set_ether_mac(dev, device->mac);
6484 +       return(0);
6485 +}
6486 +
6487 +static struct uml_net *find_device(int n)
6488 +{
6489 +       struct uml_net *device;
6490 +       struct list_head *ele;
6491 +
6492 +       spin_lock(&devices_lock);
6493 +       list_for_each(ele, &devices){
6494 +               device = list_entry(ele, struct uml_net, list);
6495 +               if(device->index == n)
6496 +                       goto out;
6497 +       }
6498 +       device = NULL;
6499 + out:
6500 +       spin_unlock(&devices_lock);
6501 +       return(device);
6502 +}
6503 +
6504 +static int eth_parse(char *str, int *index_out, char **str_out)
6505 +{
6506 +       char *end;
6507 +       int n;
6508 +
6509 +       n = simple_strtoul(str, &end, 0);
6510 +       if(end == str){
6511 +               printk(KERN_ERR "eth_setup: Failed to parse '%s'\n", str);
6512 +               return(1);
6513 +       }
6514 +       if(n < 0){
6515 +               printk(KERN_ERR "eth_setup: device %d is negative\n", n);
6516 +               return(1);
6517 +       }
6518 +       str = end;
6519 +       if(*str != '='){
6520 +               printk(KERN_ERR 
6521 +                      "eth_setup: expected '=' after device number\n");
6522 +               return(1);
6523 +       }
6524 +       str++;
6525 +       if(find_device(n)){
6526 +               printk(KERN_ERR "eth_setup: Device %d already configured\n",
6527 +                      n);
6528 +               return(1);
6529 +       }
6530 +       if(index_out) *index_out = n;
6531 +       *str_out = str;
6532 +       return(0);
6533 +}
6534 +
6535 +struct eth_init {
6536 +       struct list_head list;
6537 +       char *init;
6538 +       int index;
6539 +};
6540 +
6541 +/* Filled in at boot time.  Will need locking if the transports become
6542 + * modular.
6543 + */
6544 +struct list_head transports = LIST_HEAD_INIT(transports);
6545 +
6546 +/* Filled in during early boot */
6547 +struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
6548 +
6549 +static int check_transport(struct transport *transport, char *eth, int n,
6550 +                          void **init_out, char **mac_out)
6551 +{
6552 +       int len;
6553 +
6554 +       len = strlen(transport->name);
6555 +       if(strncmp(eth, transport->name, len))
6556 +               return(0);
6557 +
6558 +       eth += len;
6559 +       if(*eth == ',')
6560 +               eth++;
6561 +       else if(*eth != '\0')
6562 +               return(0);
6563 +
6564 +       *init_out = kmalloc(transport->setup_size, GFP_KERNEL);
6565 +       if(*init_out == NULL)
6566 +               return(1);
6567 +
6568 +       if(!transport->setup(eth, mac_out, *init_out)){
6569 +               kfree(*init_out);
6570 +               *init_out = NULL;
6571 +       }
6572 +       return(1);
6573 +}
6574 +
6575 +void register_transport(struct transport *new)
6576 +{
6577 +       struct list_head *ele, *next;
6578 +       struct eth_init *eth;
6579 +       void *init;
6580 +       char *mac = NULL;
6581 +       int match;
6582 +
6583 +       list_add(&new->list, &transports);
6584 +
6585 +       list_for_each_safe(ele, next, &eth_cmd_line){
6586 +               eth = list_entry(ele, struct eth_init, list);
6587 +               match = check_transport(new, eth->init, eth->index, &init,
6588 +                                       &mac);
6589 +               if(!match)
6590 +                       continue;
6591 +               else if(init != NULL){
6592 +                       eth_configure(eth->index, init, mac, new);
6593 +                       kfree(init);
6594 +               }
6595 +               list_del(&eth->list);
6596 +       }
6597 +}
6598 +
6599 +static int eth_setup_common(char *str, int index)
6600 +{
6601 +       struct list_head *ele;
6602 +       struct transport *transport;
6603 +       void *init;
6604 +       char *mac = NULL;
6605 +
6606 +       list_for_each(ele, &transports){
6607 +               transport = list_entry(ele, struct transport, list);
6608 +               if(!check_transport(transport, str, index, &init, &mac))
6609 +                       continue;
6610 +               if(init != NULL){
6611 +                       eth_configure(index, init, mac, transport);
6612 +                       kfree(init);
6613 +               }
6614 +               return(1);
6615 +       }
6616 +       return(0);
6617 +}
6618 +
6619 +static int eth_setup(char *str)
6620 +{
6621 +       struct eth_init *new;
6622 +       int n, err;
6623 +
6624 +       err = eth_parse(str, &n, &str);
6625 +       if(err) return(1);
6626 +
6627 +       new = alloc_bootmem(sizeof(new));
6628 +       if(new == NULL){
6629 +               printk("eth_init : alloc_bootmem failed\n");
6630 +               return(1);
6631 +       }
6632 +       *new = ((struct eth_init) { .list       = LIST_HEAD_INIT(new->list),
6633 +                                   .index      = n,
6634 +                                   .init       = str });
6635 +       list_add_tail(&new->list, &eth_cmd_line);
6636 +       return(1);
6637 +}
6638 +
6639 +__setup("eth", eth_setup);
6640 +__uml_help(eth_setup,
6641 +"eth[0-9]+=<transport>,<options>\n"
6642 +"    Configure a network device.\n\n"
6643 +);
6644 +
6645 +static int eth_init(void)
6646 +{
6647 +       struct list_head *ele, *next;
6648 +       struct eth_init *eth;
6649 +
6650 +       list_for_each_safe(ele, next, &eth_cmd_line){
6651 +               eth = list_entry(ele, struct eth_init, list);
6652 +
6653 +               if(eth_setup_common(eth->init, eth->index))
6654 +                       list_del(&eth->list);
6655 +       }
6656 +       
6657 +       return(1);
6658 +}
6659 +
6660 +__initcall(eth_init);
6661 +
6662 +static int net_config(char *str)
6663 +{
6664 +       int n, err;
6665 +
6666 +       err = eth_parse(str, &n, &str);
6667 +       if(err) return(err);
6668 +
6669 +       str = uml_strdup(str);
6670 +       if(str == NULL){
6671 +               printk(KERN_ERR "net_config failed to strdup string\n");
6672 +               return(-1);
6673 +       }
6674 +       err = !eth_setup_common(str, n);
6675 +       if(err) 
6676 +               kfree(str);
6677 +       return(err);
6678 +}
6679 +
6680 +static int net_remove(char *str)
6681 +{
6682 +       struct uml_net *device;
6683 +       struct net_device *dev;
6684 +       struct uml_net_private *lp;
6685 +       char *end;
6686 +       int n;
6687 +
6688 +       n = simple_strtoul(str, &end, 0);
6689 +       if((*end != '\0') || (end == str))
6690 +               return(-1);
6691 +
6692 +       device = find_device(n);
6693 +       if(device == NULL)
6694 +               return(0);
6695 +
6696 +       dev = device->dev;
6697 +       lp = dev->priv;
6698 +       if(lp->fd > 0) return(-1);
6699 +       if(lp->remove != NULL) (*lp->remove)(&lp->user);
6700 +       unregister_netdev(dev);
6701 +
6702 +       list_del(&device->list);
6703 +       kfree(device);
6704 +       return(0);
6705 +}
6706 +
6707 +static struct mc_device net_mc = {
6708 +       .name           = "eth",
6709 +       .config         = net_config,
6710 +       .get_config     = NULL,
6711 +       .remove         = net_remove,
6712 +};
6713 +
6714 +static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
6715 +                             void *ptr)
6716 +{
6717 +       struct in_ifaddr *ifa = ptr;
6718 +       u32 addr = ifa->ifa_address;
6719 +       u32 netmask = ifa->ifa_mask;
6720 +       struct net_device *dev = ifa->ifa_dev->dev;
6721 +       struct uml_net_private *lp;
6722 +       void (*proc)(unsigned char *, unsigned char *, void *);
6723 +       unsigned char addr_buf[4], netmask_buf[4];
6724 +
6725 +       if(dev->open != uml_net_open) return(NOTIFY_DONE);
6726 +
6727 +       lp = dev->priv;
6728 +
6729 +       proc = NULL;
6730 +       switch (event){
6731 +       case NETDEV_UP:
6732 +               proc = lp->add_address;
6733 +               break;
6734 +       case NETDEV_DOWN:
6735 +               proc = lp->delete_address;
6736 +               break;
6737 +       }
6738 +       if(proc != NULL){
6739 +               addr_buf[0] = addr & 0xff;
6740 +               addr_buf[1] = (addr >> 8) & 0xff;
6741 +               addr_buf[2] = (addr >> 16) & 0xff;
6742 +               addr_buf[3] = addr >> 24;
6743 +               netmask_buf[0] = netmask & 0xff;
6744 +               netmask_buf[1] = (netmask >> 8) & 0xff;
6745 +               netmask_buf[2] = (netmask >> 16) & 0xff;
6746 +               netmask_buf[3] = netmask >> 24;
6747 +               (*proc)(addr_buf, netmask_buf, &lp->user);
6748 +       }
6749 +       return(NOTIFY_DONE);
6750 +}
6751 +
6752 +struct notifier_block uml_inetaddr_notifier = {
6753 +       .notifier_call          = uml_inetaddr_event,
6754 +};
6755 +
6756 +static int uml_net_init(void)
6757 +{
6758 +       struct list_head *ele;
6759 +       struct uml_net_private *lp;     
6760 +       struct in_device *ip;
6761 +       struct in_ifaddr *in;
6762 +
6763 +       mconsole_register_dev(&net_mc);
6764 +       register_inetaddr_notifier(&uml_inetaddr_notifier);
6765 +
6766 +       /* Devices may have been opened already, so the uml_inetaddr_notifier
6767 +        * didn't get a chance to run for them.  This fakes it so that
6768 +        * addresses which have already been set up get handled properly.
6769 +        */
6770 +       list_for_each(ele, &opened){
6771 +               lp = list_entry(ele, struct uml_net_private, list);
6772 +               ip = lp->dev->ip_ptr;
6773 +               if(ip == NULL) continue;
6774 +               in = ip->ifa_list;
6775 +               while(in != NULL){
6776 +                       uml_inetaddr_event(NULL, NETDEV_UP, in);
6777 +                       in = in->ifa_next;
6778 +               }
6779 +       }       
6780 +
6781 +       return(0);
6782 +}
6783 +
6784 +__initcall(uml_net_init);
6785 +
6786 +static void close_devices(void)
6787 +{
6788 +       struct list_head *ele;
6789 +       struct uml_net_private *lp;     
6790 +
6791 +       list_for_each(ele, &opened){
6792 +               lp = list_entry(ele, struct uml_net_private, list);
6793 +               if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6794 +               if(lp->remove != NULL) (*lp->remove)(&lp->user);
6795 +       }
6796 +}
6797 +
6798 +__uml_exitcall(close_devices);
6799 +
6800 +int setup_etheraddr(char *str, unsigned char *addr)
6801 +{
6802 +       char *end;
6803 +       int i;
6804 +
6805 +       if(str == NULL)
6806 +               return(0);
6807 +       for(i=0;i<6;i++){
6808 +               addr[i] = simple_strtoul(str, &end, 16);
6809 +               if((end == str) ||
6810 +                  ((*end != ':') && (*end != ',') && (*end != '\0'))){
6811 +                       printk(KERN_ERR 
6812 +                              "setup_etheraddr: failed to parse '%s' "
6813 +                              "as an ethernet address\n", str);
6814 +                       return(0);
6815 +               }
6816 +               str = end + 1;
6817 +       }
6818 +       if(addr[0] & 1){
6819 +               printk(KERN_ERR 
6820 +                      "Attempt to assign a broadcast ethernet address to a "
6821 +                      "device disallowed\n");
6822 +               return(0);
6823 +       }
6824 +       return(1);
6825 +}
6826 +
6827 +void dev_ip_addr(void *d, char *buf, char *bin_buf)
6828 +{
6829 +       struct net_device *dev = d;
6830 +       struct in_device *ip = dev->ip_ptr;
6831 +       struct in_ifaddr *in;
6832 +       u32 addr;
6833 +
6834 +       if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
6835 +               printk(KERN_WARNING "dev_ip_addr - device not assigned an "
6836 +                      "IP address\n");
6837 +               return;
6838 +       }
6839 +       addr = in->ifa_address;
6840 +       sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff, 
6841 +               (addr >> 16) & 0xff, addr >> 24);
6842 +       if(bin_buf){
6843 +               bin_buf[0] = addr & 0xff;
6844 +               bin_buf[1] = (addr >> 8) & 0xff;
6845 +               bin_buf[2] = (addr >> 16) & 0xff;
6846 +               bin_buf[3] = addr >> 24;
6847 +       }
6848 +}
6849 +
6850 +void set_ether_mac(void *d, unsigned char *addr)
6851 +{
6852 +       struct net_device *dev = d;
6853 +
6854 +       memcpy(dev->dev_addr, addr, ETH_ALEN);  
6855 +}
6856 +
6857 +struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
6858 +{
6859 +       if((skb != NULL) && (skb_tailroom(skb) < extra)){
6860 +               struct sk_buff *skb2;
6861 +
6862 +               skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
6863 +               dev_kfree_skb(skb);
6864 +               skb = skb2;
6865 +       }
6866 +       if(skb != NULL) skb_put(skb, extra);
6867 +       return(skb);
6868 +}
6869 +
6870 +void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *, 
6871 +                                       void *), 
6872 +                   void *arg)
6873 +{
6874 +       struct net_device *dev = d;
6875 +       struct in_device *ip = dev->ip_ptr;
6876 +       struct in_ifaddr *in;
6877 +       unsigned char address[4], netmask[4];
6878 +
6879 +       if(ip == NULL) return;
6880 +       in = ip->ifa_list;
6881 +       while(in != NULL){
6882 +               address[0] = in->ifa_address & 0xff;
6883 +               address[1] = (in->ifa_address >> 8) & 0xff;
6884 +               address[2] = (in->ifa_address >> 16) & 0xff;
6885 +               address[3] = in->ifa_address >> 24;
6886 +               netmask[0] = in->ifa_mask & 0xff;
6887 +               netmask[1] = (in->ifa_mask >> 8) & 0xff;
6888 +               netmask[2] = (in->ifa_mask >> 16) & 0xff;
6889 +               netmask[3] = in->ifa_mask >> 24;
6890 +               (*cb)(address, netmask, arg);
6891 +               in = in->ifa_next;
6892 +       }
6893 +}
6894 +
6895 +int dev_netmask(void *d, void *m)
6896 +{
6897 +       struct net_device *dev = d;
6898 +       struct in_device *ip = dev->ip_ptr;
6899 +       struct in_ifaddr *in;
6900 +       __u32 *mask_out = m;
6901 +
6902 +       if(ip == NULL) 
6903 +               return(1);
6904 +
6905 +       in = ip->ifa_list;
6906 +       if(in == NULL) 
6907 +               return(1);
6908 +
6909 +       *mask_out = in->ifa_mask;
6910 +       return(0);
6911 +}
6912 +
6913 +void *get_output_buffer(int *len_out)
6914 +{
6915 +       void *ret;
6916 +
6917 +       ret = (void *) __get_free_pages(GFP_KERNEL, 0);
6918 +       if(ret) *len_out = PAGE_SIZE;
6919 +       else *len_out = 0;
6920 +       return(ret);
6921 +}
6922 +
6923 +void free_output_buffer(void *buffer)
6924 +{
6925 +       free_pages((unsigned long) buffer, 0);
6926 +}
6927 +
6928 +int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out, 
6929 +                    char **gate_addr)
6930 +{
6931 +       char *remain;
6932 +
6933 +       remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL);
6934 +       if(remain != NULL){
6935 +               printk("tap_setup_common - Extra garbage on specification : "
6936 +                      "'%s'\n", remain);
6937 +               return(1);
6938 +       }
6939 +
6940 +       return(0);
6941 +}
6942 +
6943 +unsigned short eth_protocol(struct sk_buff *skb)
6944 +{
6945 +       return(eth_type_trans(skb, skb->dev));
6946 +}
6947 +
6948 +/*
6949 + * Overrides for Emacs so that we follow Linus's tabbing style.
6950 + * Emacs will notice this stuff at the end of the file and automatically
6951 + * adjust the settings for this buffer only.  This must remain at the end
6952 + * of the file.
6953 + * ---------------------------------------------------------------------------
6954 + * Local variables:
6955 + * c-file-style: "linux"
6956 + * End:
6957 + */
6958 diff -Naur -X ../exclude-files orig/arch/um/drivers/net_user.c um/arch/um/drivers/net_user.c
6959 --- orig/arch/um/drivers/net_user.c     1969-12-31 19:00:00.000000000 -0500
6960 +++ um/arch/um/drivers/net_user.c       2003-10-21 03:26:06.000000000 -0400
6961 @@ -0,0 +1,252 @@
6962 +/* 
6963 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
6964 + * Licensed under the GPL
6965 + */
6966 +
6967 +#include <stddef.h>
6968 +#include <stdarg.h>
6969 +#include <unistd.h>
6970 +#include <stdio.h>
6971 +#include <errno.h>
6972 +#include <stdlib.h>
6973 +#include <string.h>
6974 +#include <sys/socket.h>
6975 +#include <sys/wait.h>
6976 +#include "user.h"
6977 +#include "user_util.h"
6978 +#include "kern_util.h"
6979 +#include "net_user.h"
6980 +#include "helper.h"
6981 +#include "os.h"
6982 +
6983 +int tap_open_common(void *dev, char *gate_addr)
6984 +{
6985 +       int tap_addr[4];
6986 +
6987 +       if(gate_addr == NULL) return(0);
6988 +       if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], 
6989 +                 &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
6990 +               printk("Invalid tap IP address - '%s'\n", gate_addr);
6991 +               return(-EINVAL);
6992 +       }
6993 +       return(0);
6994 +}
6995 +
6996 +void tap_check_ips(char *gate_addr, char *eth_addr)
6997 +{
6998 +       int tap_addr[4];
6999 +
7000 +       if((gate_addr != NULL) && 
7001 +          (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], 
7002 +                  &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
7003 +          (eth_addr[0] == tap_addr[0]) && 
7004 +          (eth_addr[1] == tap_addr[1]) && 
7005 +          (eth_addr[2] == tap_addr[2]) && 
7006 +          (eth_addr[3] == tap_addr[3])){
7007 +               printk("The tap IP address and the UML eth IP address"
7008 +                      " must be different\n");
7009 +       }
7010 +}
7011 +
7012 +void read_output(int fd, char *output, int len)
7013 +{
7014 +       int remain, n, actual;
7015 +       char c;
7016 +
7017 +       if(output == NULL){
7018 +               output = &c;
7019 +               len = sizeof(c);
7020 +       }
7021 +               
7022 +       *output = '\0';
7023 +       n = os_read_file(fd, &remain, sizeof(remain));
7024 +       if(n != sizeof(remain)){
7025 +               printk("read_output - read of length failed, err = %d\n", -n);
7026 +               return;
7027 +       }
7028 +
7029 +       while(remain != 0){
7030 +               n = (remain < len) ? remain : len;
7031 +               actual = os_read_file(fd, output, n);
7032 +               if(actual != n){
7033 +                       printk("read_output - read of data failed, "
7034 +                              "err = %d\n", -actual);
7035 +                       return;
7036 +               }
7037 +               remain -= actual;
7038 +       }
7039 +       return;
7040 +}
7041 +
7042 +int net_read(int fd, void *buf, int len)
7043 +{
7044 +       int n;
7045 +
7046 +       n = os_read_file(fd,  buf,  len);
7047 +
7048 +       if(n == -EAGAIN) 
7049 +               return(0);
7050 +       else if(n == 0) 
7051 +               return(-ENOTCONN);
7052 +       return(n);
7053 +}
7054 +
7055 +int net_recvfrom(int fd, void *buf, int len)
7056 +{
7057 +       int n;
7058 +
7059 +       while(((n = recvfrom(fd,  buf,  len, 0, NULL, NULL)) < 0) && 
7060 +             (errno == EINTR)) ;
7061 +
7062 +       if(n < 0){
7063 +               if(errno == EAGAIN) return(0);
7064 +               return(-errno);
7065 +       }
7066 +       else if(n == 0) return(-ENOTCONN);
7067 +       return(n);
7068 +}
7069 +
7070 +int net_write(int fd, void *buf, int len)
7071 +{
7072 +       int n;
7073 +
7074 +       n = os_write_file(fd, buf, len);
7075 +
7076 +       if(n == -EAGAIN) 
7077 +               return(0);
7078 +       else if(n == 0) 
7079 +               return(-ENOTCONN);
7080 +       return(n);
7081 +}
7082 +
7083 +int net_send(int fd, void *buf, int len)
7084 +{
7085 +       int n;
7086 +
7087 +       while(((n = send(fd, buf, len, 0)) < 0) && (errno == EINTR)) ;
7088 +       if(n < 0){
7089 +               if(errno == EAGAIN) return(0);
7090 +               return(-errno);
7091 +       }
7092 +       else if(n == 0) return(-ENOTCONN);
7093 +       return(n);      
7094 +}
7095 +
7096 +int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
7097 +{
7098 +       int n;
7099 +
7100 +       while(((n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
7101 +                          sock_len)) < 0) && (errno == EINTR)) ;
7102 +       if(n < 0){
7103 +               if(errno == EAGAIN) return(0);
7104 +               return(-errno);
7105 +       }
7106 +       else if(n == 0) return(-ENOTCONN);
7107 +       return(n);      
7108 +}
7109 +
7110 +struct change_pre_exec_data {
7111 +       int close_me;
7112 +       int stdout;
7113 +};
7114 +
7115 +static void change_pre_exec(void *arg)
7116 +{
7117 +       struct change_pre_exec_data *data = arg;
7118 +
7119 +       os_close_file(data->close_me);
7120 +       dup2(data->stdout, 1);
7121 +}
7122 +
7123 +static int change_tramp(char **argv, char *output, int output_len)
7124 +{
7125 +       int pid, fds[2], err;
7126 +       struct change_pre_exec_data pe_data;
7127 +
7128 +       err = os_pipe(fds, 1, 0);
7129 +       if(err < 0){
7130 +               printk("change_tramp - pipe failed, err = %d\n", -err);
7131 +               return(err);
7132 +       }
7133 +       pe_data.close_me = fds[0];
7134 +       pe_data.stdout = fds[1];
7135 +       pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
7136 +
7137 +       os_close_file(fds[1]);
7138 +       read_output(fds[0], output, output_len);
7139 +       waitpid(pid, NULL, 0);  
7140 +       return(pid);
7141 +}
7142 +
7143 +static void change(char *dev, char *what, unsigned char *addr,
7144 +                  unsigned char *netmask)
7145 +{
7146 +       char addr_buf[sizeof("255.255.255.255\0")];
7147 +       char netmask_buf[sizeof("255.255.255.255\0")];
7148 +       char version[sizeof("nnnnn\0")];
7149 +       char *argv[] = { "uml_net", version, what, dev, addr_buf, 
7150 +                        netmask_buf, NULL };
7151 +       char *output;
7152 +       int output_len, pid;
7153 +
7154 +       sprintf(version, "%d", UML_NET_VERSION);
7155 +       sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
7156 +       sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1], 
7157 +               netmask[2], netmask[3]);
7158 +
7159 +       output_len = page_size();
7160 +       output = um_kmalloc(output_len);
7161 +       if(output == NULL)
7162 +               printk("change : failed to allocate output buffer\n");
7163 +
7164 +       pid = change_tramp(argv, output, output_len);
7165 +       if(pid < 0) return;
7166 +
7167 +       if(output != NULL){
7168 +               printk("%s", output);
7169 +               kfree(output);
7170 +       }
7171 +}
7172 +
7173 +void open_addr(unsigned char *addr, unsigned char *netmask, void *arg)
7174 +{
7175 +       change(arg, "add", addr, netmask);
7176 +}
7177 +
7178 +void close_addr(unsigned char *addr, unsigned char *netmask, void *arg)
7179 +{
7180 +       change(arg, "del", addr, netmask);
7181 +}
7182 +
7183 +char *split_if_spec(char *str, ...)
7184 +{
7185 +       char **arg, *end;
7186 +       va_list ap;
7187 +
7188 +       va_start(ap, str);
7189 +       while((arg = va_arg(ap, char **)) != NULL){
7190 +               if(*str == '\0')
7191 +                       return(NULL);
7192 +               end = strchr(str, ',');
7193 +               if(end != str)
7194 +                       *arg = str;
7195 +               if(end == NULL)
7196 +                       return(NULL);
7197 +               *end++ = '\0';
7198 +               str = end;
7199 +       }
7200 +       va_end(ap);
7201 +       return(str);
7202 +}
7203 +
7204 +/*
7205 + * Overrides for Emacs so that we follow Linus's tabbing style.
7206 + * Emacs will notice this stuff at the end of the file and automatically
7207 + * adjust the settings for this buffer only.  This must remain at the end
7208 + * of the file.
7209 + * ---------------------------------------------------------------------------
7210 + * Local variables:
7211 + * c-file-style: "linux"
7212 + * End:
7213 + */
7214 diff -Naur -X ../exclude-files orig/arch/um/drivers/null.c um/arch/um/drivers/null.c
7215 --- orig/arch/um/drivers/null.c 1969-12-31 19:00:00.000000000 -0500
7216 +++ um/arch/um/drivers/null.c   2003-10-21 03:26:06.000000000 -0400
7217 @@ -0,0 +1,55 @@
7218 +/* 
7219 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7220 + * Licensed under the GPL
7221 + */
7222 +
7223 +#include <stdlib.h>
7224 +#include <errno.h>
7225 +#include "chan_user.h"
7226 +#include "os.h"
7227 +
7228 +static int null_chan;
7229 +
7230 +void *null_init(char *str, int device, struct chan_opts *opts)
7231 +{
7232 +       return(&null_chan);
7233 +}
7234 +
7235 +int null_open(int input, int output, int primary, void *d, char **dev_out)
7236 +{
7237 +       *dev_out = NULL;
7238 +       return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0));
7239 +}
7240 +
7241 +int null_read(int fd, char *c_out, void *unused)
7242 +{
7243 +       return(-ENODEV);
7244 +}
7245 +
7246 +void null_free(void *data)
7247 +{
7248 +}
7249 +
7250 +struct chan_ops null_ops = {
7251 +       .type           = "null",
7252 +       .init           = null_init,
7253 +       .open           = null_open,
7254 +       .close          = generic_close,
7255 +       .read           = null_read,
7256 +       .write          = generic_write,
7257 +       .console_write  = generic_console_write,
7258 +       .window_size    = generic_window_size,
7259 +       .free           = null_free,
7260 +       .winch          = 0,
7261 +};
7262 +
7263 +/*
7264 + * Overrides for Emacs so that we follow Linus's tabbing style.
7265 + * Emacs will notice this stuff at the end of the file and automatically
7266 + * adjust the settings for this buffer only.  This must remain at the end
7267 + * of the file.
7268 + * ---------------------------------------------------------------------------
7269 + * Local variables:
7270 + * c-file-style: "linux"
7271 + * End:
7272 + */
7273 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_kern.c um/arch/um/drivers/pcap_kern.c
7274 --- orig/arch/um/drivers/pcap_kern.c    1969-12-31 19:00:00.000000000 -0500
7275 +++ um/arch/um/drivers/pcap_kern.c      2003-10-21 03:26:06.000000000 -0400
7276 @@ -0,0 +1,127 @@
7277 +/*
7278 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
7279 + * Licensed under the GPL.
7280 + */
7281 +
7282 +#include "linux/init.h"
7283 +#include "linux/netdevice.h"
7284 +#include "linux/etherdevice.h"
7285 +#include "net_kern.h"
7286 +#include "net_user.h"
7287 +#include "pcap_user.h"
7288 +
7289 +struct pcap_init {
7290 +       char *host_if;
7291 +       int promisc;
7292 +       int optimize;
7293 +       char *filter;
7294 +};
7295 +
7296 +void pcap_init(struct net_device *dev, void *data)
7297 +{
7298 +       struct uml_net_private *pri;
7299 +       struct pcap_data *ppri;
7300 +       struct pcap_init *init = data;
7301 +
7302 +       init_etherdev(dev, 0);
7303 +       pri = dev->priv;
7304 +       ppri = (struct pcap_data *) pri->user;
7305 +       *ppri = ((struct pcap_data)
7306 +               { .host_if      = init->host_if,
7307 +                 .promisc      = init->promisc,
7308 +                 .optimize     = init->optimize,
7309 +                 .filter       = init->filter,
7310 +                 .compiled     = NULL,
7311 +                 .pcap         = NULL });
7312 +}
7313 +
7314 +static int pcap_read(int fd, struct sk_buff **skb, 
7315 +                      struct uml_net_private *lp)
7316 +{
7317 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
7318 +       if(*skb == NULL) return(-ENOMEM);
7319 +       return(pcap_user_read(fd, (*skb)->mac.raw, 
7320 +                             (*skb)->dev->mtu + ETH_HEADER_OTHER,
7321 +                             (struct pcap_data *) &lp->user));
7322 +}
7323 +
7324 +static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
7325 +{
7326 +       return(-EPERM);
7327 +}
7328 +
7329 +static struct net_kern_info pcap_kern_info = {
7330 +       .init                   = pcap_init,
7331 +       .protocol               = eth_protocol,
7332 +       .read                   = pcap_read,
7333 +       .write                  = pcap_write,
7334 +};
7335 +
7336 +int pcap_setup(char *str, char **mac_out, void *data)
7337 +{
7338 +       struct pcap_init *init = data;
7339 +       char *remain, *host_if = NULL, *options[2] = { NULL, NULL };
7340 +       int i;
7341 +
7342 +       *init = ((struct pcap_init)
7343 +               { .host_if      = "eth0",
7344 +                 .promisc      = 1,
7345 +                 .optimize     = 0,
7346 +                 .filter       = NULL });
7347 +
7348 +       remain = split_if_spec(str, &host_if, &init->filter, 
7349 +                              &options[0], &options[1], NULL);
7350 +       if(remain != NULL){
7351 +               printk(KERN_ERR "pcap_setup - Extra garbage on "
7352 +                      "specification : '%s'\n", remain);
7353 +               return(0);
7354 +       }
7355 +
7356 +       if(host_if != NULL)
7357 +               init->host_if = host_if;
7358 +
7359 +       for(i = 0; i < sizeof(options)/sizeof(options[0]); i++){
7360 +               if(options[i] == NULL)
7361 +                       continue;
7362 +               if(!strcmp(options[i], "promisc"))
7363 +                       init->promisc = 1;
7364 +               else if(!strcmp(options[i], "nopromisc"))
7365 +                       init->promisc = 0;
7366 +               else if(!strcmp(options[i], "optimize"))
7367 +                       init->optimize = 1;
7368 +               else if(!strcmp(options[i], "nooptimize"))
7369 +                       init->optimize = 0;
7370 +               else printk("pcap_setup : bad option - '%s'\n", options[i]);
7371 +       }
7372 +
7373 +       return(1);
7374 +}
7375 +
7376 +static struct transport pcap_transport = {
7377 +       .list           = LIST_HEAD_INIT(pcap_transport.list),
7378 +       .name           = "pcap",
7379 +       .setup          = pcap_setup,
7380 +       .user           = &pcap_user_info,
7381 +       .kern           = &pcap_kern_info,
7382 +       .private_size   = sizeof(struct pcap_data),
7383 +       .setup_size     = sizeof(struct pcap_init),
7384 +};
7385 +
7386 +static int register_pcap(void)
7387 +{
7388 +       register_transport(&pcap_transport);
7389 +       return(1);
7390 +}
7391 +
7392 +__initcall(register_pcap);
7393 +
7394 +/*
7395 + * Overrides for Emacs so that we follow Linus's tabbing style.
7396 + * Emacs will notice this stuff at the end of the file and automatically
7397 + * adjust the settings for this buffer only.  This must remain at the end
7398 + * of the file.
7399 + * ---------------------------------------------------------------------------
7400 + * Local variables:
7401 + * c-file-style: "linux"
7402 + * End:
7403 + */
7404 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.c um/arch/um/drivers/pcap_user.c
7405 --- orig/arch/um/drivers/pcap_user.c    1969-12-31 19:00:00.000000000 -0500
7406 +++ um/arch/um/drivers/pcap_user.c      2003-10-21 03:26:06.000000000 -0400
7407 @@ -0,0 +1,143 @@
7408 +/*
7409 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
7410 + * Licensed under the GPL.
7411 + */
7412 +
7413 +#include <unistd.h>
7414 +#include <stdlib.h>
7415 +#include <string.h>
7416 +#include <errno.h>
7417 +#include <pcap.h>
7418 +#include <asm/types.h>
7419 +#include "net_user.h"
7420 +#include "pcap_user.h"
7421 +#include "user.h"
7422 +
7423 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
7424 +
7425 +#define PCAP_FD(p) (*(int *)(p))
7426 +
7427 +static void pcap_user_init(void *data, void *dev)
7428 +{
7429 +       struct pcap_data *pri = data;
7430 +       pcap_t *p;
7431 +       char errors[PCAP_ERRBUF_SIZE];
7432 +
7433 +       p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors);
7434 +       if(p == NULL){
7435 +               printk("pcap_user_init : pcap_open_live failed - '%s'\n", 
7436 +                      errors);
7437 +               return;
7438 +       }
7439 +
7440 +       pri->dev = dev;
7441 +       pri->pcap = p;
7442 +}
7443 +
7444 +static int pcap_open(void *data)
7445 +{
7446 +       struct pcap_data *pri = data;
7447 +       __u32 netmask;
7448 +       int err;
7449 +
7450 +       if(pri->pcap == NULL)
7451 +               return(-ENODEV);
7452 +
7453 +       if(pri->filter != NULL){
7454 +               err = dev_netmask(pri->dev, &netmask);
7455 +               if(err < 0){
7456 +                       printk("pcap_open : dev_netmask failed\n");
7457 +                       return(-EIO);
7458 +               }
7459 +
7460 +               pri->compiled = um_kmalloc(sizeof(struct bpf_program));
7461 +               if(pri->compiled == NULL){
7462 +                       printk("pcap_open : kmalloc failed\n");
7463 +                       return(-ENOMEM);
7464 +               }
7465 +               
7466 +               err = pcap_compile(pri->pcap, 
7467 +                                  (struct bpf_program *) pri->compiled, 
7468 +                                  pri->filter, pri->optimize, netmask);
7469 +               if(err < 0){
7470 +                       printk("pcap_open : pcap_compile failed - '%s'\n", 
7471 +                              pcap_geterr(pri->pcap));
7472 +                       return(-EIO);
7473 +               }
7474 +
7475 +               err = pcap_setfilter(pri->pcap, pri->compiled);
7476 +               if(err < 0){
7477 +                       printk("pcap_open : pcap_setfilter failed - '%s'\n", 
7478 +                              pcap_geterr(pri->pcap));
7479 +                       return(-EIO);
7480 +               }
7481 +       }
7482 +       
7483 +       return(PCAP_FD(pri->pcap));
7484 +}
7485 +
7486 +static void pcap_remove(void *data)
7487 +{
7488 +       struct pcap_data *pri = data;
7489 +
7490 +       if(pri->compiled != NULL)
7491 +               pcap_freecode(pri->compiled);
7492 +
7493 +       pcap_close(pri->pcap);
7494 +}
7495 +
7496 +struct pcap_handler_data {
7497 +       char *buffer;
7498 +       int len;
7499 +};
7500 +
7501 +static void handler(u_char *data, const struct pcap_pkthdr *header, 
7502 +                   const u_char *packet)
7503 +{
7504 +       int len;
7505 +
7506 +       struct pcap_handler_data *hdata = (struct pcap_handler_data *) data;
7507 +
7508 +       len = hdata->len < header->caplen ? hdata->len : header->caplen;
7509 +       memcpy(hdata->buffer, packet, len);
7510 +       hdata->len = len;
7511 +}
7512 +
7513 +int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
7514 +{
7515 +       struct pcap_handler_data hdata = ((struct pcap_handler_data)
7516 +                                         { .buffer     = buffer,
7517 +                                           .len        = len });
7518 +       int n;
7519 +
7520 +       n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
7521 +       if(n < 0){
7522 +               printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap));
7523 +               return(-EIO);
7524 +       }
7525 +       else if(n == 0) 
7526 +               return(0);
7527 +       return(hdata.len);
7528 +}
7529 +
7530 +struct net_user_info pcap_user_info = {
7531 +       .init           = pcap_user_init,
7532 +       .open           = pcap_open,
7533 +       .close          = NULL,
7534 +       .remove         = pcap_remove,
7535 +       .set_mtu        = NULL,
7536 +       .add_address    = NULL,
7537 +       .delete_address = NULL,
7538 +       .max_packet     = MAX_PACKET - ETH_HEADER_OTHER
7539 +};
7540 +
7541 +/*
7542 + * Overrides for Emacs so that we follow Linus's tabbing style.
7543 + * Emacs will notice this stuff at the end of the file and automatically
7544 + * adjust the settings for this buffer only.  This must remain at the end
7545 + * of the file.
7546 + * ---------------------------------------------------------------------------
7547 + * Local variables:
7548 + * c-file-style: "linux"
7549 + * End:
7550 + */
7551 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.h um/arch/um/drivers/pcap_user.h
7552 --- orig/arch/um/drivers/pcap_user.h    1969-12-31 19:00:00.000000000 -0500
7553 +++ um/arch/um/drivers/pcap_user.h      2003-10-21 03:26:06.000000000 -0400
7554 @@ -0,0 +1,31 @@
7555 +/* 
7556 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7557 + * Licensed under the GPL
7558 + */
7559 +
7560 +#include "net_user.h"
7561 +
7562 +struct pcap_data {
7563 +       char *host_if;
7564 +       int promisc;
7565 +       int optimize;
7566 +       char *filter;
7567 +       void *compiled;
7568 +       void *pcap;
7569 +       void *dev;
7570 +};
7571 +
7572 +extern struct net_user_info pcap_user_info;
7573 +
7574 +extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
7575 +
7576 +/*
7577 + * Overrides for Emacs so that we follow Linus's tabbing style.
7578 + * Emacs will notice this stuff at the end of the file and automatically
7579 + * adjust the settings for this buffer only.  This must remain at the end
7580 + * of the file.
7581 + * ---------------------------------------------------------------------------
7582 + * Local variables:
7583 + * c-file-style: "linux"
7584 + * End:
7585 + */
7586 diff -Naur -X ../exclude-files orig/arch/um/drivers/port.h um/arch/um/drivers/port.h
7587 --- orig/arch/um/drivers/port.h 1969-12-31 19:00:00.000000000 -0500
7588 +++ um/arch/um/drivers/port.h   2003-10-21 03:26:06.000000000 -0400
7589 @@ -0,0 +1,30 @@
7590 +/* 
7591 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
7592 + * Licensed under the GPL
7593 + */
7594 +
7595 +#ifndef __PORT_H__
7596 +#define __PORT_H__
7597 +
7598 +extern void *port_data(int port);
7599 +extern int port_wait(void *data);
7600 +extern void port_kern_close(void *d);
7601 +extern int port_connection(int fd, int *socket_out, int *pid_out);
7602 +extern int port_listen_fd(int port);
7603 +extern void port_read(int fd, void *data);
7604 +extern void port_kern_free(void *d);
7605 +extern int port_rcv_fd(int fd);
7606 +extern void port_remove_dev(void *d);
7607 +
7608 +#endif
7609 +
7610 +/*
7611 + * Overrides for Emacs so that we follow Linus's tabbing style.
7612 + * Emacs will notice this stuff at the end of the file and automatically
7613 + * adjust the settings for this buffer only.  This must remain at the end
7614 + * of the file.
7615 + * ---------------------------------------------------------------------------
7616 + * Local variables:
7617 + * c-file-style: "linux"
7618 + * End:
7619 + */
7620 diff -Naur -X ../exclude-files orig/arch/um/drivers/port_kern.c um/arch/um/drivers/port_kern.c
7621 --- orig/arch/um/drivers/port_kern.c    1969-12-31 19:00:00.000000000 -0500
7622 +++ um/arch/um/drivers/port_kern.c      2004-01-10 06:18:49.000000000 -0500
7623 @@ -0,0 +1,303 @@
7624 +/* 
7625 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7626 + * Licensed under the GPL
7627 + */
7628 +
7629 +#include "linux/list.h"
7630 +#include "linux/sched.h"
7631 +#include "linux/slab.h"
7632 +#include "linux/irq.h"
7633 +#include "linux/spinlock.h"
7634 +#include "linux/errno.h"
7635 +#include "asm/semaphore.h"
7636 +#include "asm/errno.h"
7637 +#include "kern_util.h"
7638 +#include "kern.h"
7639 +#include "irq_user.h"
7640 +#include "irq_kern.h"
7641 +#include "port.h"
7642 +#include "init.h"
7643 +#include "os.h"
7644 +
7645 +struct port_list {
7646 +       struct list_head list;
7647 +       int has_connection;
7648 +       struct semaphore sem;
7649 +       int port;
7650 +       int fd;
7651 +       spinlock_t lock;
7652 +       struct list_head pending;
7653 +       struct list_head connections;
7654 +};
7655 +
7656 +struct port_dev {
7657 +       struct port_list *port;
7658 +       int helper_pid;
7659 +       int telnetd_pid;
7660 +};
7661 +
7662 +struct connection {
7663 +       struct list_head list;
7664 +       int fd;
7665 +       int helper_pid;
7666 +       int socket[2];
7667 +       int telnetd_pid;
7668 +       struct port_list *port;
7669 +};
7670 +
7671 +static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
7672 +{
7673 +       struct connection *conn = data;
7674 +       int fd;
7675 +
7676 +       fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
7677 +       if(fd < 0){
7678 +               if(fd == -EAGAIN)
7679 +                       return;
7680 +
7681 +               printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 
7682 +                      -fd);
7683 +               os_close_file(conn->fd);
7684 +       }
7685 +
7686 +       list_del(&conn->list);
7687 +
7688 +       conn->fd = fd;
7689 +       list_add(&conn->list, &conn->port->connections);
7690 +
7691 +       up(&conn->port->sem);
7692 +}
7693 +
7694 +static int port_accept(struct port_list *port)
7695 +{
7696 +       struct connection *conn;
7697 +       int fd, socket[2], pid, ret = 0;
7698 +
7699 +       fd = port_connection(port->fd, socket, &pid);
7700 +       if(fd < 0){
7701 +               if(fd != -EAGAIN)
7702 +                       printk(KERN_ERR "port_accept : port_connection "
7703 +                              "returned %d\n", -fd);
7704 +               goto out;
7705 +       }
7706 +
7707 +       conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
7708 +       if(conn == NULL){
7709 +               printk(KERN_ERR "port_accept : failed to allocate "
7710 +                      "connection\n");
7711 +               goto out_close;
7712 +       }
7713 +       *conn = ((struct connection) 
7714 +               { .list         = LIST_HEAD_INIT(conn->list),
7715 +                 .fd           = fd,
7716 +                 .socket       = { socket[0], socket[1] },
7717 +                 .telnetd_pid  = pid,
7718 +                 .port         = port });
7719 +
7720 +       if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, 
7721 +                         SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
7722 +                         "telnetd", conn)){
7723 +               printk(KERN_ERR "port_accept : failed to get IRQ for "
7724 +                      "telnetd\n");
7725 +               goto out_free;
7726 +       }
7727 +
7728 +       list_add(&conn->list, &port->pending);
7729 +       return(1);
7730 +
7731 + out_free:
7732 +       kfree(conn);
7733 + out_close:
7734 +       os_close_file(fd);
7735 +       if(pid != -1) 
7736 +               os_kill_process(pid, 1);
7737 + out:
7738 +       return(ret);
7739 +} 
7740 +
7741 +DECLARE_MUTEX(ports_sem);
7742 +struct list_head ports = LIST_HEAD_INIT(ports);
7743 +
7744 +void port_task_proc(void *unused)
7745 +{
7746 +       struct port_list *port;
7747 +       struct list_head *ele;
7748 +       unsigned long flags;
7749 +
7750 +       save_flags(flags);
7751 +       list_for_each(ele, &ports){
7752 +               port = list_entry(ele, struct port_list, list);
7753 +               if(!port->has_connection)
7754 +                       continue;
7755 +               reactivate_fd(port->fd, ACCEPT_IRQ);
7756 +               while(port_accept(port)) ;
7757 +               port->has_connection = 0;
7758 +       }
7759 +       restore_flags(flags);
7760 +}
7761 +
7762 +struct tq_struct port_task = {
7763 +       .routine        = port_task_proc,
7764 +       .data           = NULL
7765 +};
7766 +
7767 +static void port_interrupt(int irq, void *data, struct pt_regs *regs)
7768 +{
7769 +       struct port_list *port = data;
7770 +
7771 +       port->has_connection = 1;
7772 +       schedule_task(&port_task);
7773 +} 
7774 +
7775 +void *port_data(int port_num)
7776 +{
7777 +       struct list_head *ele;
7778 +       struct port_list *port;
7779 +       struct port_dev *dev = NULL;
7780 +       int fd;
7781 +
7782 +       down(&ports_sem);
7783 +       list_for_each(ele, &ports){
7784 +               port = list_entry(ele, struct port_list, list);
7785 +               if(port->port == port_num) goto found;
7786 +       }
7787 +       port = kmalloc(sizeof(struct port_list), GFP_KERNEL);
7788 +       if(port == NULL){
7789 +               printk(KERN_ERR "Allocation of port list failed\n");
7790 +               goto out;
7791 +       }
7792 +
7793 +       fd = port_listen_fd(port_num);
7794 +       if(fd < 0){
7795 +               printk(KERN_ERR "binding to port %d failed, errno = %d\n",
7796 +                      port_num, -fd);
7797 +               goto out_free;
7798 +       }
7799 +       if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, 
7800 +                         SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "port",
7801 +                         port)){
7802 +               printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
7803 +               goto out_close;
7804 +       }
7805 +
7806 +       *port = ((struct port_list) 
7807 +               { .list                 = LIST_HEAD_INIT(port->list),
7808 +                 .has_connection       = 0,
7809 +                 .sem                  = __SEMAPHORE_INITIALIZER(port->sem, 
7810 +                                                                 0),
7811 +                 .lock                 = SPIN_LOCK_UNLOCKED,
7812 +                 .port                 = port_num,
7813 +                 .fd                   = fd,
7814 +                 .pending              = LIST_HEAD_INIT(port->pending),
7815 +                 .connections          = LIST_HEAD_INIT(port->connections) });
7816 +       list_add(&port->list, &ports);
7817 +
7818 + found:
7819 +       dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL);
7820 +       if(dev == NULL){
7821 +               printk(KERN_ERR "Allocation of port device entry failed\n");
7822 +               goto out;
7823 +       }
7824 +
7825 +       *dev = ((struct port_dev) { .port               = port,
7826 +                                   .helper_pid         = -1,
7827 +                                   .telnetd_pid        = -1 });
7828 +       goto out;
7829 +
7830 + out_free:
7831 +       kfree(port);
7832 + out_close:
7833 +       os_close_file(fd);
7834 + out:
7835 +       up(&ports_sem);
7836 +       return(dev);
7837 +}
7838 +
7839 +int port_wait(void *data)
7840 +{
7841 +       struct port_dev *dev = data;
7842 +       struct connection *conn;
7843 +       struct port_list *port = dev->port;
7844 +       int fd;
7845 +
7846 +       while(1){
7847 +               if(down_interruptible(&port->sem))
7848 +                       return(-ERESTARTSYS);
7849 +
7850 +               spin_lock(&port->lock);
7851 +
7852 +               conn = list_entry(port->connections.next, struct connection, 
7853 +                                 list);
7854 +               list_del(&conn->list);
7855 +               spin_unlock(&port->lock);
7856 +
7857 +               os_shutdown_socket(conn->socket[0], 1, 1);
7858 +               os_close_file(conn->socket[0]);
7859 +               os_shutdown_socket(conn->socket[1], 1, 1);
7860 +               os_close_file(conn->socket[1]); 
7861 +
7862 +               /* This is done here because freeing an IRQ can't be done
7863 +                * within the IRQ handler.  So, pipe_interrupt always ups
7864 +                * the semaphore regardless of whether it got a successful
7865 +                * connection.  Then we loop here throwing out failed 
7866 +                * connections until a good one is found.
7867 +                */
7868 +               free_irq(TELNETD_IRQ, conn);
7869 +
7870 +               if(conn->fd >= 0) break;
7871 +               os_close_file(conn->fd);
7872 +               kfree(conn);
7873 +       }
7874 +
7875 +       fd = conn->fd;
7876 +       dev->helper_pid = conn->helper_pid;
7877 +       dev->telnetd_pid = conn->telnetd_pid;
7878 +       kfree(conn);
7879 +
7880 +       return(fd);
7881 +}
7882 +
7883 +void port_remove_dev(void *d)
7884 +{
7885 +       struct port_dev *dev = d;
7886 +
7887 +       if(dev->helper_pid != -1)
7888 +               os_kill_process(dev->helper_pid, 0);
7889 +       if(dev->telnetd_pid != -1)
7890 +               os_kill_process(dev->telnetd_pid, 1);
7891 +       dev->helper_pid = -1;
7892 +       dev->telnetd_pid = -1;
7893 +}
7894 +
7895 +void port_kern_free(void *d)
7896 +{
7897 +       struct port_dev *dev = d;
7898 +
7899 +       port_remove_dev(dev);
7900 +       kfree(dev);
7901 +}
7902 +
7903 +static void free_port(void)
7904 +{
7905 +       struct list_head *ele;
7906 +       struct port_list *port;
7907 +
7908 +       list_for_each(ele, &ports){
7909 +               port = list_entry(ele, struct port_list, list);
7910 +               free_irq_by_fd(port->fd);
7911 +               os_close_file(port->fd);
7912 +       }
7913 +}
7914 +
7915 +__uml_exitcall(free_port);
7916 +
7917 +/*
7918 + * Overrides for Emacs so that we follow Linus's tabbing style.
7919 + * Emacs will notice this stuff at the end of the file and automatically
7920 + * adjust the settings for this buffer only.  This must remain at the end
7921 + * of the file.
7922 + * ---------------------------------------------------------------------------
7923 + * Local variables:
7924 + * c-file-style: "linux"
7925 + * End:
7926 + */
7927 diff -Naur -X ../exclude-files orig/arch/um/drivers/port_user.c um/arch/um/drivers/port_user.c
7928 --- orig/arch/um/drivers/port_user.c    1969-12-31 19:00:00.000000000 -0500
7929 +++ um/arch/um/drivers/port_user.c      2003-10-21 03:26:06.000000000 -0400
7930 @@ -0,0 +1,213 @@
7931 +/* 
7932 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
7933 + * Licensed under the GPL
7934 + */
7935 +
7936 +#include <stdio.h>
7937 +#include <stddef.h>
7938 +#include <stdlib.h>
7939 +#include <string.h>
7940 +#include <errno.h>
7941 +#include <unistd.h>
7942 +#include <termios.h>
7943 +#include <sys/socket.h>
7944 +#include <sys/un.h>
7945 +#include <netinet/in.h>
7946 +#include "user_util.h"
7947 +#include "kern_util.h"
7948 +#include "user.h"
7949 +#include "chan_user.h"
7950 +#include "port.h"
7951 +#include "helper.h"
7952 +#include "os.h"
7953 +
7954 +struct port_chan {
7955 +       int raw;
7956 +       struct termios tt;
7957 +       void *kernel_data;
7958 +       char dev[sizeof("32768\0")];
7959 +};
7960 +
7961 +void *port_init(char *str, int device, struct chan_opts *opts)
7962 +{
7963 +       struct port_chan *data;
7964 +       void *kern_data;
7965 +       char *end;
7966 +       int port;
7967 +
7968 +       if(*str != ':'){
7969 +               printk("port_init : channel type 'port' must specify a "
7970 +                      "port number\n");
7971 +               return(NULL);
7972 +       }
7973 +       str++;
7974 +       port = strtoul(str, &end, 0);
7975 +       if((*end != '\0') || (end == str)){
7976 +               printk("port_init : couldn't parse port '%s'\n", str);
7977 +               return(NULL);
7978 +       }
7979 +
7980 +       kern_data = port_data(port);
7981 +       if(kern_data == NULL) 
7982 +               return(NULL);
7983 +
7984 +       data = um_kmalloc(sizeof(*data));
7985 +       if(data == NULL) 
7986 +               goto err;
7987 +
7988 +       *data = ((struct port_chan) { .raw              = opts->raw,
7989 +                                     .kernel_data      = kern_data });
7990 +       sprintf(data->dev, "%d", port);
7991 +
7992 +       return(data);
7993 + err:
7994 +       port_kern_free(kern_data);
7995 +       return(NULL);
7996 +}
7997 +
7998 +void port_free(void *d)
7999 +{
8000 +       struct port_chan *data = d;
8001 +
8002 +       port_kern_free(data->kernel_data);
8003 +       kfree(data);
8004 +}
8005 +
8006 +int port_open(int input, int output, int primary, void *d, char **dev_out)
8007 +{
8008 +       struct port_chan *data = d;
8009 +       int fd;
8010 +
8011 +       fd = port_wait(data->kernel_data);
8012 +       if((fd >= 0) && data->raw){
8013 +               tcgetattr(fd, &data->tt);
8014 +               raw(fd, 0);
8015 +       }
8016 +       *dev_out = data->dev;
8017 +       return(fd);
8018 +}
8019 +
8020 +void port_close(int fd, void *d)
8021 +{
8022 +       struct port_chan *data = d;
8023 +
8024 +       port_remove_dev(data->kernel_data);
8025 +       os_close_file(fd);
8026 +}
8027 +
8028 +int port_console_write(int fd, const char *buf, int n, void *d)
8029 +{
8030 +       struct port_chan *data = d;
8031 +
8032 +       return(generic_console_write(fd, buf, n, &data->tt));
8033 +}
8034 +
8035 +struct chan_ops port_ops = {
8036 +       .type           = "port",
8037 +       .init           = port_init,
8038 +       .open           = port_open,
8039 +       .close          = port_close,
8040 +       .read           = generic_read,
8041 +       .write          = generic_write,
8042 +       .console_write  = port_console_write,
8043 +       .window_size    = generic_window_size,
8044 +       .free           = port_free,
8045 +       .winch          = 1,
8046 +};
8047 +
8048 +int port_listen_fd(int port)
8049 +{
8050 +       struct sockaddr_in addr;
8051 +       int fd, err;
8052 +
8053 +       fd = socket(PF_INET, SOCK_STREAM, 0);
8054 +       if(fd == -1) 
8055 +               return(-errno);
8056 +
8057 +       addr.sin_family = AF_INET;
8058 +       addr.sin_port = htons(port);
8059 +       addr.sin_addr.s_addr = htonl(INADDR_ANY);
8060 +       if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){
8061 +               err = -errno;
8062 +               goto out;
8063 +       }
8064 +  
8065 +       if(listen(fd, 1) < 0){
8066 +               err = -errno;
8067 +               goto out;
8068 +       }
8069 +
8070 +       err = os_set_fd_block(fd, 0);
8071 +       if(err < 0)
8072 +               goto out;
8073 +
8074 +       return(fd);
8075 + out:
8076 +       os_close_file(fd);
8077 +       return(err);
8078 +}
8079 +
8080 +struct port_pre_exec_data {
8081 +       int sock_fd;
8082 +       int pipe_fd;
8083 +};
8084 +
8085 +void port_pre_exec(void *arg)
8086 +{
8087 +       struct port_pre_exec_data *data = arg;
8088 +
8089 +       dup2(data->sock_fd, 0);
8090 +       dup2(data->sock_fd, 1);
8091 +       dup2(data->sock_fd, 2);
8092 +       os_close_file(data->sock_fd);
8093 +       dup2(data->pipe_fd, 3);
8094 +       os_shutdown_socket(3, 1, 0);
8095 +       os_close_file(data->pipe_fd);
8096 +}
8097 +
8098 +int port_connection(int fd, int *socket, int *pid_out)
8099 +{
8100 +       int new, err;
8101 +       char *argv[] = { "/usr/sbin/in.telnetd", "-L", 
8102 +                        "/usr/lib/uml/port-helper", NULL };
8103 +       struct port_pre_exec_data data;
8104 +
8105 +       new = os_accept_connection(fd);
8106 +       if(new < 0)
8107 +               return(new);
8108 +
8109 +       err = os_pipe(socket, 0, 0);
8110 +       if(err < 0) 
8111 +               goto out_close;
8112 +
8113 +       data = ((struct port_pre_exec_data)
8114 +               { .sock_fd              = new,
8115 +                 .pipe_fd              = socket[1] });
8116 +
8117 +       err = run_helper(port_pre_exec, &data, argv, NULL);
8118 +       if(err < 0) 
8119 +               goto out_shutdown;
8120 +
8121 +       *pid_out = err;
8122 +       return(new);
8123 +
8124 + out_shutdown:
8125 +       os_shutdown_socket(socket[0], 1, 1);
8126 +       os_close_file(socket[0]);
8127 +       os_shutdown_socket(socket[1], 1, 1);    
8128 +       os_close_file(socket[1]);
8129 + out_close:
8130 +       os_close_file(new);
8131 +       return(err);
8132 +}
8133 +
8134 +/*
8135 + * Overrides for Emacs so that we follow Linus's tabbing style.
8136 + * Emacs will notice this stuff at the end of the file and automatically
8137 + * adjust the settings for this buffer only.  This must remain at the end
8138 + * of the file.
8139 + * ---------------------------------------------------------------------------
8140 + * Local variables:
8141 + * c-file-style: "linux"
8142 + * End:
8143 + */
8144 diff -Naur -X ../exclude-files orig/arch/um/drivers/pty.c um/arch/um/drivers/pty.c
8145 --- orig/arch/um/drivers/pty.c  1969-12-31 19:00:00.000000000 -0500
8146 +++ um/arch/um/drivers/pty.c    2003-10-21 03:26:06.000000000 -0400
8147 @@ -0,0 +1,148 @@
8148 +/* 
8149 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
8150 + * Licensed under the GPL
8151 + */
8152 +
8153 +#include <stdio.h>
8154 +#include <unistd.h>
8155 +#include <string.h>
8156 +#include <errno.h>
8157 +#include <termios.h>
8158 +#include "chan_user.h"
8159 +#include "user.h"
8160 +#include "user_util.h"
8161 +#include "kern_util.h"
8162 +#include "os.h"
8163 +
8164 +struct pty_chan {
8165 +       void (*announce)(char *dev_name, int dev);
8166 +       int dev;
8167 +       int raw;
8168 +       struct termios tt;
8169 +       char dev_name[sizeof("/dev/pts/0123456\0")];
8170 +};
8171 +
8172 +void *pty_chan_init(char *str, int device, struct chan_opts *opts)
8173 +{
8174 +       struct pty_chan *data;
8175 +
8176 +       data = um_kmalloc(sizeof(*data));
8177 +       if(data == NULL) return(NULL);
8178 +       *data = ((struct pty_chan) { .announce          = opts->announce, 
8179 +                                    .dev               = device,
8180 +                                    .raw               = opts->raw });
8181 +       return(data);
8182 +}
8183 +
8184 +int pts_open(int input, int output, int primary, void *d, char **dev_out)
8185 +{
8186 +       struct pty_chan *data = d;
8187 +       char *dev;
8188 +       int fd;
8189 +
8190 +       fd = get_pty();
8191 +       if(fd < 0){
8192 +               printk("open_pts : Failed to open pts\n");
8193 +               return(-errno);
8194 +       }
8195 +       if(data->raw){
8196 +               tcgetattr(fd, &data->tt);
8197 +               raw(fd, 0);
8198 +       }
8199 +
8200 +       dev = ptsname(fd);
8201 +       sprintf(data->dev_name, "%s", dev);
8202 +       *dev_out = data->dev_name;
8203 +       if(data->announce) (*data->announce)(dev, data->dev);
8204 +       return(fd);
8205 +}
8206 +
8207 +int getmaster(char *line)
8208 +{
8209 +       char *pty, *bank, *cp;
8210 +       int master, err;
8211 +
8212 +       pty = &line[strlen("/dev/ptyp")];
8213 +       for (bank = "pqrs"; *bank; bank++) {
8214 +               line[strlen("/dev/pty")] = *bank;
8215 +               *pty = '0';
8216 +               if (os_stat_file(line, NULL) < 0)
8217 +                       break;
8218 +               for (cp = "0123456789abcdef"; *cp; cp++) {
8219 +                       *pty = *cp;
8220 +                       master = os_open_file(line, of_rdwr(OPENFLAGS()), 0);
8221 +                       if (master >= 0) {
8222 +                               char *tp = &line[strlen("/dev/")];
8223 +
8224 +                               /* verify slave side is usable */
8225 +                               *tp = 't';
8226 +                               err = os_access(line, OS_ACC_RW_OK);
8227 +                               *tp = 'p';
8228 +                               if(err == 0) return(master);
8229 +                               (void) os_close_file(master);
8230 +                       }
8231 +               }
8232 +       }
8233 +       return(-1);
8234 +}
8235 +
8236 +int pty_open(int input, int output, int primary, void *d, char **dev_out)
8237 +{
8238 +       struct pty_chan *data = d;
8239 +       int fd;
8240 +       char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
8241 +
8242 +       fd = getmaster(dev);
8243 +       if(fd < 0) return(-errno);
8244 +       
8245 +       if(data->raw) raw(fd, 0);
8246 +       if(data->announce) (*data->announce)(dev, data->dev);
8247 +
8248 +       sprintf(data->dev_name, "%s", dev);
8249 +       *dev_out = data->dev_name;
8250 +       return(fd);
8251 +}
8252 +
8253 +int pty_console_write(int fd, const char *buf, int n, void *d)
8254 +{
8255 +       struct pty_chan *data = d;
8256 +
8257 +       return(generic_console_write(fd, buf, n, &data->tt));
8258 +}
8259 +
8260 +struct chan_ops pty_ops = {
8261 +       .type           = "pty",
8262 +       .init           = pty_chan_init,
8263 +       .open           = pty_open,
8264 +       .close          = generic_close,
8265 +       .read           = generic_read,
8266 +       .write          = generic_write,
8267 +       .console_write  = pty_console_write,
8268 +       .window_size    = generic_window_size,
8269 +       .free           = generic_free,
8270 +       .winch          = 0,
8271 +};
8272 +
8273 +struct chan_ops pts_ops = {
8274 +       .type           = "pts",
8275 +       .init           = pty_chan_init,
8276 +       .open           = pts_open,
8277 +       .close          = generic_close,
8278 +       .read           = generic_read,
8279 +       .write          = generic_write,
8280 +       .console_write  = pty_console_write,
8281 +       .window_size    = generic_window_size,
8282 +       .free           = generic_free,
8283 +       .winch          = 0,
8284 +};
8285 +
8286 +/*
8287 + * Overrides for Emacs so that we follow Linus's tabbing style.
8288 + * Emacs will notice this stuff at the end of the file and automatically
8289 + * adjust the settings for this buffer only.  This must remain at the end
8290 + * of the file.
8291 + * ---------------------------------------------------------------------------
8292 + * Local variables:
8293 + * c-file-style: "linux"
8294 + * End:
8295 + */
8296 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip.h um/arch/um/drivers/slip.h
8297 --- orig/arch/um/drivers/slip.h 1969-12-31 19:00:00.000000000 -0500
8298 +++ um/arch/um/drivers/slip.h   2003-10-21 03:26:06.000000000 -0400
8299 @@ -0,0 +1,39 @@
8300 +#ifndef __UM_SLIP_H
8301 +#define __UM_SLIP_H
8302 +
8303 +#define BUF_SIZE 1500
8304 + /* two bytes each for a (pathological) max packet of escaped chars +  * 
8305 +  * terminating END char + initial END char                            */
8306 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8307 +
8308 +struct slip_data {
8309 +       void *dev;
8310 +       char name[sizeof("slnnnnn\0")];
8311 +       char *addr;
8312 +       char *gate_addr;
8313 +       int slave;
8314 +       char ibuf[ENC_BUF_SIZE];
8315 +       char obuf[ENC_BUF_SIZE];
8316 +       int more; /* more data: do not read fd until ibuf has been drained */
8317 +       int pos;
8318 +       int esc;
8319 +};
8320 +
8321 +extern struct net_user_info slip_user_info;
8322 +
8323 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
8324 +extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri);
8325 +extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri);
8326 +
8327 +#endif
8328 +
8329 +/*
8330 + * Overrides for Emacs so that we follow Linus's tabbing style.
8331 + * Emacs will notice this stuff at the end of the file and automatically
8332 + * adjust the settings for this buffer only.  This must remain at the end
8333 + * of the file.
8334 + * ---------------------------------------------------------------------------
8335 + * Local variables:
8336 + * c-file-style: "linux"
8337 + * End:
8338 + */
8339 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_kern.c um/arch/um/drivers/slip_kern.c
8340 --- orig/arch/um/drivers/slip_kern.c    1969-12-31 19:00:00.000000000 -0500
8341 +++ um/arch/um/drivers/slip_kern.c      2003-10-21 03:26:06.000000000 -0400
8342 @@ -0,0 +1,109 @@
8343 +#include "linux/config.h"
8344 +#include "linux/kernel.h"
8345 +#include "linux/stddef.h"
8346 +#include "linux/init.h"
8347 +#include "linux/netdevice.h"
8348 +#include "linux/if_arp.h"
8349 +#include "net_kern.h"
8350 +#include "net_user.h"
8351 +#include "kern.h"
8352 +#include "slip.h"
8353 +
8354 +struct slip_init {
8355 +       char *gate_addr;
8356 +};
8357 +
8358 +void slip_init(struct net_device *dev, void *data)
8359 +{
8360 +       struct uml_net_private *private;
8361 +       struct slip_data *spri;
8362 +       struct slip_init *init = data;
8363 +
8364 +       private = dev->priv;
8365 +       spri = (struct slip_data *) private->user;
8366 +       *spri = ((struct slip_data)
8367 +               { .name         = { '\0' },
8368 +                 .addr         = NULL,
8369 +                 .gate_addr    = init->gate_addr,
8370 +                 .slave        = -1,
8371 +                 .ibuf         = { '\0' },
8372 +                 .obuf         = { '\0' },
8373 +                 .pos          = 0,
8374 +                 .esc          = 0,
8375 +                 .dev          = dev });
8376 +
8377 +       dev->init = NULL;
8378 +       dev->hard_header_len = 0;
8379 +       dev->addr_len = 4;
8380 +       dev->type = ARPHRD_ETHER;
8381 +       dev->tx_queue_len = 256;
8382 +       dev->flags = IFF_NOARP;
8383 +       printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr);
8384 +}
8385 +
8386 +static unsigned short slip_protocol(struct sk_buff *skbuff)
8387 +{
8388 +       return(htons(ETH_P_IP));
8389 +}
8390 +
8391 +static int slip_read(int fd, struct sk_buff **skb, 
8392 +                      struct uml_net_private *lp)
8393 +{
8394 +       return(slip_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, 
8395 +                             (struct slip_data *) &lp->user));
8396 +}
8397 +
8398 +static int slip_write(int fd, struct sk_buff **skb,
8399 +                     struct uml_net_private *lp)
8400 +{
8401 +       return(slip_user_write(fd, (*skb)->data, (*skb)->len, 
8402 +                              (struct slip_data *) &lp->user));
8403 +}
8404 +
8405 +struct net_kern_info slip_kern_info = {
8406 +       .init                   = slip_init,
8407 +       .protocol               = slip_protocol,
8408 +       .read                   = slip_read,
8409 +       .write                  = slip_write,
8410 +};
8411 +
8412 +static int slip_setup(char *str, char **mac_out, void *data)
8413 +{
8414 +       struct slip_init *init = data;
8415 +
8416 +       *init = ((struct slip_init)
8417 +               { .gate_addr            = NULL });
8418 +
8419 +       if(str[0] != '\0') 
8420 +               init->gate_addr = str;
8421 +       return(1);
8422 +}
8423 +
8424 +static struct transport slip_transport = {
8425 +       .list           = LIST_HEAD_INIT(slip_transport.list),
8426 +       .name           = "slip",
8427 +       .setup          = slip_setup,
8428 +       .user           = &slip_user_info,
8429 +       .kern           = &slip_kern_info,
8430 +       .private_size   = sizeof(struct slip_data),
8431 +       .setup_size     = sizeof(struct slip_init),
8432 +};
8433 +
8434 +static int register_slip(void)
8435 +{
8436 +       register_transport(&slip_transport);
8437 +       return(1);
8438 +}
8439 +
8440 +__initcall(register_slip);
8441 +
8442 +/*
8443 + * Overrides for Emacs so that we follow Linus's tabbing style.
8444 + * Emacs will notice this stuff at the end of the file and automatically
8445 + * adjust the settings for this buffer only.  This must remain at the end
8446 + * of the file.
8447 + * ---------------------------------------------------------------------------
8448 + * Local variables:
8449 + * c-file-style: "linux"
8450 + * End:
8451 + */
8452 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_proto.h um/arch/um/drivers/slip_proto.h
8453 --- orig/arch/um/drivers/slip_proto.h   1969-12-31 19:00:00.000000000 -0500
8454 +++ um/arch/um/drivers/slip_proto.h     2003-10-21 03:26:06.000000000 -0400
8455 @@ -0,0 +1,93 @@
8456 +/* 
8457 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
8458 + * Licensed under the GPL
8459 + */
8460 +
8461 +#ifndef __UM_SLIP_PROTO_H__
8462 +#define __UM_SLIP_PROTO_H__
8463 +
8464 +/* SLIP protocol characters. */
8465 +#define SLIP_END             0300      /* indicates end of frame       */
8466 +#define SLIP_ESC             0333      /* indicates byte stuffing      */
8467 +#define SLIP_ESC_END         0334      /* ESC ESC_END means END 'data' */
8468 +#define SLIP_ESC_ESC         0335      /* ESC ESC_ESC means ESC 'data' */
8469 +
8470 +static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc)
8471 +{
8472 +       int ret;
8473 +
8474 +       switch(c){
8475 +       case SLIP_END:
8476 +               *esc = 0;
8477 +               ret=*pos;
8478 +               *pos=0;
8479 +               return(ret);
8480 +       case SLIP_ESC:
8481 +               *esc = 1;
8482 +               return(0);
8483 +       case SLIP_ESC_ESC:
8484 +               if(*esc){
8485 +                       *esc = 0;
8486 +                       c = SLIP_ESC;
8487 +               }
8488 +               break;
8489 +       case SLIP_ESC_END:
8490 +               if(*esc){
8491 +                       *esc = 0;
8492 +                       c = SLIP_END;
8493 +               }
8494 +               break;
8495 +       }
8496 +       buf[(*pos)++] = c;
8497 +       return(0);
8498 +}
8499 +
8500 +static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
8501 +{
8502 +       unsigned char *ptr = d;
8503 +       unsigned char c;
8504 +
8505 +       /*
8506 +        * Send an initial END character to flush out any
8507 +        * data that may have accumulated in the receiver
8508 +        * due to line noise.
8509 +        */
8510 +
8511 +       *ptr++ = SLIP_END;
8512 +
8513 +       /*
8514 +        * For each byte in the packet, send the appropriate
8515 +        * character sequence, according to the SLIP protocol.
8516 +        */
8517 +
8518 +       while (len-- > 0) {
8519 +               switch(c = *s++) {
8520 +               case SLIP_END:
8521 +                       *ptr++ = SLIP_ESC;
8522 +                       *ptr++ = SLIP_ESC_END;
8523 +                       break;
8524 +               case SLIP_ESC:
8525 +                       *ptr++ = SLIP_ESC;
8526 +                       *ptr++ = SLIP_ESC_ESC;
8527 +                       break;
8528 +               default:
8529 +                       *ptr++ = c;
8530 +                       break;
8531 +               }
8532 +       }
8533 +       *ptr++ = SLIP_END;
8534 +       return (ptr - d);
8535 +}
8536 +
8537 +#endif
8538 +
8539 +/*
8540 + * Overrides for Emacs so that we follow Linus's tabbing style.
8541 + * Emacs will notice this stuff at the end of the file and automatically
8542 + * adjust the settings for this buffer only.  This must remain at the end
8543 + * of the file.
8544 + * ---------------------------------------------------------------------------
8545 + * Local variables:
8546 + * c-file-style: "linux"
8547 + * End:
8548 + */
8549 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_user.c um/arch/um/drivers/slip_user.c
8550 --- orig/arch/um/drivers/slip_user.c    1969-12-31 19:00:00.000000000 -0500
8551 +++ um/arch/um/drivers/slip_user.c      2003-10-21 03:26:06.000000000 -0400
8552 @@ -0,0 +1,274 @@
8553 +#include <stdio.h>
8554 +#include <stdlib.h>
8555 +#include <unistd.h>
8556 +#include <stddef.h>
8557 +#include <sched.h>
8558 +#include <string.h>
8559 +#include <sys/errno.h>
8560 +#include <sys/termios.h>
8561 +#include <sys/wait.h>
8562 +#include <sys/signal.h>
8563 +#include "user_util.h"
8564 +#include "kern_util.h"
8565 +#include "user.h"
8566 +#include "net_user.h"
8567 +#include "slip.h"
8568 +#include "slip_proto.h"
8569 +#include "helper.h"
8570 +#include "os.h"
8571 +
8572 +void slip_user_init(void *data, void *dev)
8573 +{
8574 +       struct slip_data *pri = data;
8575 +
8576 +       pri->dev = dev;
8577 +}
8578 +
8579 +static int set_up_tty(int fd)
8580 +{
8581 +       int i;
8582 +       struct termios tios;
8583 +
8584 +       if (tcgetattr(fd, &tios) < 0) {
8585 +               printk("could not get initial terminal attributes\n");
8586 +               return(-1);
8587 +       }
8588 +
8589 +       tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
8590 +       tios.c_iflag = IGNBRK | IGNPAR;
8591 +       tios.c_oflag = 0;
8592 +       tios.c_lflag = 0;
8593 +       for (i = 0; i < NCCS; i++)
8594 +               tios.c_cc[i] = 0;
8595 +       tios.c_cc[VMIN] = 1;
8596 +       tios.c_cc[VTIME] = 0;
8597 +
8598 +       cfsetospeed(&tios, B38400);
8599 +       cfsetispeed(&tios, B38400);
8600 +
8601 +       if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
8602 +               printk("failed to set terminal attributes\n");
8603 +               return(-1);
8604 +       }
8605 +       return(0);
8606 +}
8607 +
8608 +struct slip_pre_exec_data {
8609 +       int stdin;
8610 +       int stdout;
8611 +       int close_me;
8612 +};
8613 +
8614 +static void slip_pre_exec(void *arg)
8615 +{
8616 +       struct slip_pre_exec_data *data = arg;
8617 +
8618 +       if(data->stdin >= 0) dup2(data->stdin, 0);
8619 +       dup2(data->stdout, 1);
8620 +       if(data->close_me >= 0) os_close_file(data->close_me);
8621 +}
8622 +
8623 +static int slip_tramp(char **argv, int fd)
8624 +{
8625 +       struct slip_pre_exec_data pe_data;
8626 +       char *output;
8627 +       int status, pid, fds[2], err, output_len;
8628 +
8629 +       err = os_pipe(fds, 1, 0);
8630 +       if(err < 0){
8631 +               printk("slip_tramp : pipe failed, err = %d\n", -err);
8632 +               return(err);
8633 +       }
8634 +
8635 +       err = 0;
8636 +       pe_data.stdin = fd;
8637 +       pe_data.stdout = fds[1];
8638 +       pe_data.close_me = fds[0];
8639 +       pid = run_helper(slip_pre_exec, &pe_data, argv, NULL);
8640 +
8641 +       if(pid < 0) err = pid;
8642 +       else {
8643 +               output_len = page_size();
8644 +               output = um_kmalloc(output_len);
8645 +               if(output == NULL)
8646 +                       printk("slip_tramp : failed to allocate output "
8647 +                              "buffer\n");
8648 +
8649 +               os_close_file(fds[1]);
8650 +               read_output(fds[0], output, output_len);
8651 +               if(output != NULL){
8652 +                       printk("%s", output);
8653 +                       kfree(output);
8654 +               }
8655 +               if(waitpid(pid, &status, 0) < 0) err = errno;
8656 +               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
8657 +                       printk("'%s' didn't exit with status 0\n", argv[0]);
8658 +                       err = -EINVAL;
8659 +               }
8660 +       }
8661 +       return(err);
8662 +}
8663 +
8664 +static int slip_open(void *data)
8665 +{
8666 +       struct slip_data *pri = data;
8667 +       char version_buf[sizeof("nnnnn\0")];
8668 +       char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
8669 +       char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf, 
8670 +                        NULL };
8671 +       int sfd, mfd, err;
8672 +
8673 +       mfd = get_pty();
8674 +       if(mfd < 0){
8675 +               printk("umn : Failed to open pty, err = %d\n", -mfd);
8676 +               return(mfd);
8677 +       }
8678 +       sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
8679 +       if(sfd < 0){
8680 +               printk("Couldn't open tty for slip line, err = %d\n", -sfd);
8681 +               return(sfd);
8682 +       }
8683 +       if(set_up_tty(sfd)) return(-1);
8684 +       pri->slave = sfd;
8685 +       pri->pos = 0;
8686 +       pri->esc = 0;
8687 +       if(pri->gate_addr != NULL){
8688 +               sprintf(version_buf, "%d", UML_NET_VERSION);
8689 +               strcpy(gate_buf, pri->gate_addr);
8690 +
8691 +               err = slip_tramp(argv, sfd);
8692 +
8693 +               if(err < 0){
8694 +                       printk("slip_tramp failed - err = %d\n", -err);
8695 +                       return(err);
8696 +               }
8697 +               err = os_get_ifname(pri->slave, pri->name);
8698 +               if(err < 0){
8699 +                       printk("get_ifname failed, err = %d\n", -err);
8700 +                       return(err);
8701 +               }
8702 +               iter_addresses(pri->dev, open_addr, pri->name);
8703 +       }
8704 +       else {
8705 +               err = os_set_slip(sfd);
8706 +               if(err < 0){
8707 +                       printk("Failed to set slip discipline encapsulation - "
8708 +                              "err = %d\n", -err);
8709 +                       return(err);
8710 +               }
8711 +       }
8712 +       return(mfd);
8713 +}
8714 +
8715 +static void slip_close(int fd, void *data)
8716 +{
8717 +       struct slip_data *pri = data;
8718 +       char version_buf[sizeof("nnnnn\0")];
8719 +       char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name, 
8720 +                        NULL };
8721 +       int err;
8722 +
8723 +       if(pri->gate_addr != NULL)
8724 +               iter_addresses(pri->dev, close_addr, pri->name);
8725 +
8726 +       sprintf(version_buf, "%d", UML_NET_VERSION);
8727 +
8728 +       err = slip_tramp(argv, -1);
8729 +
8730 +       if(err != 0)
8731 +               printk("slip_tramp failed - errno = %d\n", -err);
8732 +       os_close_file(fd);
8733 +       os_close_file(pri->slave);
8734 +       pri->slave = -1;
8735 +}
8736 +
8737 +int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
8738 +{
8739 +       int i, n, size, start;
8740 +
8741 +       if(pri->more>0) {
8742 +               i = 0;
8743 +               while(i < pri->more) {
8744 +                       size = slip_unesc(pri->ibuf[i++],
8745 +                                       pri->ibuf, &pri->pos, &pri->esc);
8746 +                       if(size){
8747 +                               memcpy(buf, pri->ibuf, size);
8748 +                               memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
8749 +                               pri->more=pri->more-i; 
8750 +                               return(size);
8751 +                       }
8752 +               }
8753 +               pri->more=0;
8754 +       }
8755 +
8756 +       n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
8757 +       if(n <= 0) return(n);
8758 +
8759 +       start = pri->pos;
8760 +       for(i = 0; i < n; i++){
8761 +               size = slip_unesc(pri->ibuf[start + i],
8762 +                               pri->ibuf, &pri->pos, &pri->esc);
8763 +               if(size){
8764 +                       memcpy(buf, pri->ibuf, size);
8765 +                       memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
8766 +                       pri->more=n-(i+1); 
8767 +                       return(size);
8768 +               }
8769 +       }
8770 +       return(0);
8771 +}
8772 +
8773 +int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
8774 +{
8775 +       int actual, n;
8776 +
8777 +       actual = slip_esc(buf, pri->obuf, len);
8778 +       n = net_write(fd, pri->obuf, actual);
8779 +       if(n < 0) return(n);
8780 +       else return(len);
8781 +}
8782 +
8783 +static int slip_set_mtu(int mtu, void *data)
8784 +{
8785 +       return(mtu);
8786 +}
8787 +
8788 +static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
8789 +                         void *data)
8790 +{
8791 +       struct slip_data *pri = data;
8792 +
8793 +       if(pri->slave < 0) return;
8794 +       open_addr(addr, netmask, pri->name);
8795 +}
8796 +
8797 +static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
8798 +                           void *data)
8799 +{
8800 +       struct slip_data *pri = data;
8801 +
8802 +       if(pri->slave < 0) return;
8803 +       close_addr(addr, netmask, pri->name);
8804 +}
8805 +
8806 +struct net_user_info slip_user_info = {
8807 +       .init           = slip_user_init,
8808 +       .open           = slip_open,
8809 +       .close          = slip_close,
8810 +       .remove         = NULL,
8811 +       .set_mtu        = slip_set_mtu,
8812 +       .add_address    = slip_add_addr,
8813 +       .delete_address = slip_del_addr,
8814 +       .max_packet     = BUF_SIZE
8815 +};
8816 +
8817 +/*
8818 + * Overrides for Emacs so that we follow Linus's tabbing style.
8819 + * Emacs will notice this stuff at the end of the file and automatically
8820 + * adjust the settings for this buffer only.  This must remain at the end
8821 + * of the file.
8822 + * ---------------------------------------------------------------------------
8823 + * Local variables:
8824 + * c-file-style: "linux"
8825 + * End:
8826 + */
8827 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp.h um/arch/um/drivers/slirp.h
8828 --- orig/arch/um/drivers/slirp.h        1969-12-31 19:00:00.000000000 -0500
8829 +++ um/arch/um/drivers/slirp.h  2003-10-21 03:26:06.000000000 -0400
8830 @@ -0,0 +1,51 @@
8831 +#ifndef __UM_SLIRP_H
8832 +#define __UM_SLIRP_H
8833 +
8834 +#define BUF_SIZE 1500
8835 + /* two bytes each for a (pathological) max packet of escaped chars +  * 
8836 +  * terminating END char + initial END char                            */
8837 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8838 +
8839 +#define SLIRP_MAX_ARGS 100
8840 +/*
8841 + * XXX this next definition is here because I don't understand why this
8842 + * initializer doesn't work in slirp_kern.c:
8843 + *
8844 + *   argv :  { init->argv[ 0 ... SLIRP_MAX_ARGS-1 ] },
8845 + *
8846 + * or why I can't typecast like this:
8847 + *
8848 + *   argv :  (char* [SLIRP_MAX_ARGS])(init->argv), 
8849 + */
8850 +struct arg_list_dummy_wrapper { char *argv[SLIRP_MAX_ARGS]; };
8851 +
8852 +struct slirp_data {
8853 +       void *dev;
8854 +       struct arg_list_dummy_wrapper argw;
8855 +       int pid;
8856 +       int slave;
8857 +       char ibuf[ENC_BUF_SIZE];
8858 +       char obuf[ENC_BUF_SIZE];
8859 +       int more; /* more data: do not read fd until ibuf has been drained */
8860 +       int pos;
8861 +       int esc;
8862 +};
8863 +
8864 +extern struct net_user_info slirp_user_info;
8865 +
8866 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
8867 +extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri);
8868 +extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri);
8869 +
8870 +#endif
8871 +
8872 +/*
8873 + * Overrides for Emacs so that we follow Linus's tabbing style.
8874 + * Emacs will notice this stuff at the end of the file and automatically
8875 + * adjust the settings for this buffer only.  This must remain at the end
8876 + * of the file.
8877 + * ---------------------------------------------------------------------------
8878 + * Local variables:
8879 + * c-file-style: "linux"
8880 + * End:
8881 + */
8882 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_kern.c um/arch/um/drivers/slirp_kern.c
8883 --- orig/arch/um/drivers/slirp_kern.c   1969-12-31 19:00:00.000000000 -0500
8884 +++ um/arch/um/drivers/slirp_kern.c     2003-10-21 03:26:06.000000000 -0400
8885 @@ -0,0 +1,132 @@
8886 +#include "linux/kernel.h"
8887 +#include "linux/stddef.h"
8888 +#include "linux/init.h"
8889 +#include "linux/netdevice.h"
8890 +#include "linux/if_arp.h"
8891 +#include "net_kern.h"
8892 +#include "net_user.h"
8893 +#include "kern.h"
8894 +#include "slirp.h"
8895 +
8896 +struct slirp_init {
8897 +       struct arg_list_dummy_wrapper argw;  /* XXX should be simpler... */
8898 +};
8899 +
8900 +void slirp_init(struct net_device *dev, void *data)
8901 +{
8902 +       struct uml_net_private *private;
8903 +       struct slirp_data *spri;
8904 +       struct slirp_init *init = data;
8905 +       int i;
8906 +
8907 +       private = dev->priv;
8908 +       spri = (struct slirp_data *) private->user;
8909 +       *spri = ((struct slirp_data)
8910 +               { .argw         = init->argw,
8911 +                 .pid          = -1,
8912 +                 .slave        = -1,
8913 +                 .ibuf         = { '\0' },
8914 +                 .obuf         = { '\0' },
8915 +                 .pos          = 0,
8916 +                 .esc          = 0,
8917 +                 .dev          = dev });
8918 +
8919 +       dev->init = NULL;
8920 +       dev->hard_header_len = 0;
8921 +       dev->addr_len = 4;
8922 +       dev->type = ARPHRD_ETHER;
8923 +       dev->tx_queue_len = 256;
8924 +       dev->flags = IFF_NOARP;
8925 +       printk("SLIRP backend - command line:");
8926 +       for(i=0;spri->argw.argv[i]!=NULL;i++) {
8927 +               printk(" '%s'",spri->argw.argv[i]);
8928 +       }
8929 +       printk("\n");
8930 +}
8931 +
8932 +static unsigned short slirp_protocol(struct sk_buff *skbuff)
8933 +{
8934 +       return(htons(ETH_P_IP));
8935 +}
8936 +
8937 +static int slirp_read(int fd, struct sk_buff **skb, 
8938 +                      struct uml_net_private *lp)
8939 +{
8940 +       return(slirp_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, 
8941 +                             (struct slirp_data *) &lp->user));
8942 +}
8943 +
8944 +static int slirp_write(int fd, struct sk_buff **skb,
8945 +                     struct uml_net_private *lp)
8946 +{
8947 +       return(slirp_user_write(fd, (*skb)->data, (*skb)->len, 
8948 +                              (struct slirp_data *) &lp->user));
8949 +}
8950 +
8951 +struct net_kern_info slirp_kern_info = {
8952 +       .init                   = slirp_init,
8953 +       .protocol               = slirp_protocol,
8954 +       .read                   = slirp_read,
8955 +       .write                  = slirp_write,
8956 +};
8957 +
8958 +static int slirp_setup(char *str, char **mac_out, void *data)
8959 +{
8960 +       struct slirp_init *init = data;
8961 +       int i=0;
8962 +
8963 +       *init = ((struct slirp_init)
8964 +               { argw :                { { "slirp", NULL  } } });
8965 +
8966 +       str = split_if_spec(str, mac_out, NULL);
8967 +
8968 +       if(str == NULL) { /* no command line given after MAC addr */
8969 +               return(1);
8970 +       }
8971 +
8972 +       do {
8973 +               if(i>=SLIRP_MAX_ARGS-1) {
8974 +                       printk("slirp_setup: truncating slirp arguments\n");
8975 +                       break;
8976 +               }
8977 +               init->argw.argv[i++] = str;
8978 +               while(*str && *str!=',') {
8979 +                       if(*str=='_') *str=' ';
8980 +                       str++;
8981 +               }
8982 +               if(*str!=',')
8983 +                       break;
8984 +               *str++='\0';
8985 +       } while(1);
8986 +       init->argw.argv[i]=NULL;
8987 +       return(1);
8988 +}
8989 +
8990 +static struct transport slirp_transport = {
8991 +       .list           = LIST_HEAD_INIT(slirp_transport.list),
8992 +       .name           = "slirp",
8993 +       .setup          = slirp_setup,
8994 +       .user           = &slirp_user_info,
8995 +       .kern           = &slirp_kern_info,
8996 +       .private_size   = sizeof(struct slirp_data),
8997 +       .setup_size     = sizeof(struct slirp_init),
8998 +};
8999 +
9000 +static int register_slirp(void)
9001 +{
9002 +       register_transport(&slirp_transport);
9003 +       return(1);
9004 +}
9005 +
9006 +__initcall(register_slirp);
9007 +
9008 +/*
9009 + * Overrides for Emacs so that we follow Linus's tabbing style.
9010 + * Emacs will notice this stuff at the end of the file and automatically
9011 + * adjust the settings for this buffer only.  This must remain at the end
9012 + * of the file.
9013 + * ---------------------------------------------------------------------------
9014 + * Local variables:
9015 + * c-file-style: "linux"
9016 + * End:
9017 + */
9018 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_user.c um/arch/um/drivers/slirp_user.c
9019 --- orig/arch/um/drivers/slirp_user.c   1969-12-31 19:00:00.000000000 -0500
9020 +++ um/arch/um/drivers/slirp_user.c     2003-10-21 03:26:06.000000000 -0400
9021 @@ -0,0 +1,201 @@
9022 +#include <stdio.h>
9023 +#include <stdlib.h>
9024 +#include <unistd.h>
9025 +#include <stddef.h>
9026 +#include <sched.h>
9027 +#include <string.h>
9028 +#include <sys/errno.h>
9029 +#include <sys/wait.h>
9030 +#include <sys/signal.h>
9031 +#include "user_util.h"
9032 +#include "kern_util.h"
9033 +#include "user.h"
9034 +#include "net_user.h"
9035 +#include "slirp.h"
9036 +#include "slip_proto.h"
9037 +#include "helper.h"
9038 +#include "os.h"
9039 +
9040 +void slirp_user_init(void *data, void *dev)
9041 +{
9042 +       struct slirp_data *pri = data;
9043 +
9044 +       pri->dev = dev;
9045 +}
9046 +
9047 +struct slirp_pre_exec_data {
9048 +       int stdin;
9049 +       int stdout;
9050 +};
9051 +
9052 +static void slirp_pre_exec(void *arg)
9053 +{
9054 +       struct slirp_pre_exec_data *data = arg;
9055 +
9056 +       if(data->stdin != -1) dup2(data->stdin, 0);
9057 +       if(data->stdout != -1) dup2(data->stdout, 1);
9058 +}
9059 +
9060 +static int slirp_tramp(char **argv, int fd)
9061 +{
9062 +       struct slirp_pre_exec_data pe_data;
9063 +       int pid;
9064 +
9065 +       pe_data.stdin = fd;
9066 +       pe_data.stdout = fd;
9067 +       pid = run_helper(slirp_pre_exec, &pe_data, argv, NULL);
9068 +
9069 +       return(pid);
9070 +}
9071 +
9072 +/* XXX This is just a trivial wrapper around os_pipe */ 
9073 +static int slirp_datachan(int *mfd, int *sfd)
9074 +{
9075 +       int fds[2], err;
9076 +
9077 +       err = os_pipe(fds, 1, 1);
9078 +       if(err < 0){
9079 +               printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
9080 +               return(err);
9081 +       }
9082 +
9083 +       *mfd = fds[0];
9084 +       *sfd = fds[1];
9085 +       return(0);
9086 +}
9087 +
9088 +static int slirp_open(void *data)
9089 +{
9090 +       struct slirp_data *pri = data;
9091 +       int sfd, mfd, pid, err;
9092 +
9093 +       err = slirp_datachan(&mfd, &sfd);
9094 +       if(err)
9095 +               return(err);
9096 +
9097 +       pid = slirp_tramp(pri->argw.argv, sfd);
9098 +
9099 +       if(pid < 0){
9100 +               printk("slirp_tramp failed - errno = %d\n", -pid);
9101 +               os_close_file(sfd);     
9102 +               os_close_file(mfd);     
9103 +               return(pid);
9104 +       }
9105 +
9106 +       pri->slave = sfd;
9107 +       pri->pos = 0;
9108 +       pri->esc = 0;
9109 +
9110 +       pri->pid = pid;
9111 +
9112 +       return(mfd);
9113 +}
9114 +
9115 +static void slirp_close(int fd, void *data)
9116 +{
9117 +       struct slirp_data *pri = data;
9118 +       int status,err;
9119 +
9120 +       os_close_file(fd);
9121 +       os_close_file(pri->slave);
9122 +
9123 +       pri->slave = -1;
9124 +
9125 +       if(pri->pid<1) {
9126 +               printk("slirp_close: no child process to shut down\n");
9127 +               return;
9128 +       }
9129 +
9130 +#if 0
9131 +       if(kill(pri->pid, SIGHUP)<0) {
9132 +               printk("slirp_close: sending hangup to %d failed (%d)\n",
9133 +                       pri->pid, errno);
9134 +       }
9135 +#endif
9136 +
9137 +       err = waitpid(pri->pid, &status, WNOHANG);
9138 +       if(err<0) {
9139 +               printk("slirp_close: waitpid returned %d\n", errno);
9140 +               return;
9141 +       }
9142 +
9143 +       if(err==0) {
9144 +               printk("slirp_close: process %d has not exited\n");
9145 +               return;
9146 +       }
9147 +
9148 +       pri->pid = -1;
9149 +}
9150 +
9151 +int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
9152 +{
9153 +       int i, n, size, start;
9154 +
9155 +       if(pri->more>0) {
9156 +               i = 0;
9157 +               while(i < pri->more) {
9158 +                       size = slip_unesc(pri->ibuf[i++],
9159 +                                       pri->ibuf,&pri->pos,&pri->esc);
9160 +                       if(size){
9161 +                               memcpy(buf, pri->ibuf, size);
9162 +                               memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
9163 +                               pri->more=pri->more-i; 
9164 +                               return(size);
9165 +                       }
9166 +               }
9167 +               pri->more=0;
9168 +       }
9169 +
9170 +       n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
9171 +       if(n <= 0) return(n);
9172 +
9173 +       start = pri->pos;
9174 +       for(i = 0; i < n; i++){
9175 +               size = slip_unesc(pri->ibuf[start + i],
9176 +                               pri->ibuf,&pri->pos,&pri->esc);
9177 +               if(size){
9178 +                       memcpy(buf, pri->ibuf, size);
9179 +                       memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
9180 +                       pri->more=n-(i+1); 
9181 +                       return(size);
9182 +               }
9183 +       }
9184 +       return(0);
9185 +}
9186 +
9187 +int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
9188 +{
9189 +       int actual, n;
9190 +
9191 +       actual = slip_esc(buf, pri->obuf, len);
9192 +       n = net_write(fd, pri->obuf, actual);
9193 +       if(n < 0) return(n);
9194 +       else return(len);
9195 +}
9196 +
9197 +static int slirp_set_mtu(int mtu, void *data)
9198 +{
9199 +       return(mtu);
9200 +}
9201 +
9202 +struct net_user_info slirp_user_info = {
9203 +       .init           = slirp_user_init,
9204 +       .open           = slirp_open,
9205 +       .close          = slirp_close,
9206 +       .remove         = NULL,
9207 +       .set_mtu        = slirp_set_mtu,
9208 +       .add_address    = NULL,
9209 +       .delete_address = NULL,
9210 +       .max_packet     = BUF_SIZE
9211 +};
9212 +
9213 +/*
9214 + * Overrides for Emacs so that we follow Linus's tabbing style.
9215 + * Emacs will notice this stuff at the end of the file and automatically
9216 + * adjust the settings for this buffer only.  This must remain at the end
9217 + * of the file.
9218 + * ---------------------------------------------------------------------------
9219 + * Local variables:
9220 + * c-file-style: "linux"
9221 + * End:
9222 + */
9223 diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.c um/arch/um/drivers/ssl.c
9224 --- orig/arch/um/drivers/ssl.c  1969-12-31 19:00:00.000000000 -0500
9225 +++ um/arch/um/drivers/ssl.c    2004-01-10 06:20:17.000000000 -0500
9226 @@ -0,0 +1,300 @@
9227 +/* 
9228 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
9229 + * Licensed under the GPL
9230 + */
9231 +
9232 +#include "linux/config.h"
9233 +#include "linux/fs.h"
9234 +#include "linux/tty.h"
9235 +#include "linux/tty_driver.h"
9236 +#include "linux/major.h"
9237 +#include "linux/mm.h"
9238 +#include "linux/init.h"
9239 +#include "linux/console.h"
9240 +#include "asm/termbits.h"
9241 +#include "asm/irq.h"
9242 +#include "line.h"
9243 +#include "ssl.h"
9244 +#include "chan_kern.h"
9245 +#include "user_util.h"
9246 +#include "kern_util.h"
9247 +#include "kern.h"
9248 +#include "init.h"
9249 +#include "irq_user.h"
9250 +#include "mconsole_kern.h"
9251 +#include "2_5compat.h"
9252 +
9253 +static int ssl_version = 1;
9254 +
9255 +/* Referenced only by tty_driver below - presumably it's locked correctly
9256 + * by the tty driver.
9257 + */
9258 +static int ssl_refcount = 0;
9259 +
9260 +static struct tty_driver ssl_driver;
9261 +
9262 +#define NR_PORTS 64
9263 +
9264 +void ssl_announce(char *dev_name, int dev)
9265 +{
9266 +       printk(KERN_INFO "Serial line %d assigned device '%s'\n", dev,
9267 +              dev_name);
9268 +}
9269 +
9270 +static struct chan_opts opts = {
9271 +       .announce       = ssl_announce,
9272 +       .xterm_title    = "Serial Line #%d",
9273 +       .raw            = 1,
9274 +       .tramp_stack    = 0,
9275 +       .in_kernel      = 1,
9276 +};
9277 +
9278 +static int ssl_config(char *str);
9279 +static int ssl_get_config(char *dev, char *str, int size, char **error_out);
9280 +static int ssl_remove(char *str);
9281 +
9282 +static struct line_driver driver = {
9283 +       .name                   = "UML serial line",
9284 +       .devfs_name             = "tts/%d",
9285 +       .major                  = TTY_MAJOR,
9286 +       .minor_start            = 64,
9287 +       .type                   = TTY_DRIVER_TYPE_SERIAL,
9288 +       .subtype                = 0,
9289 +       .read_irq               = SSL_IRQ,
9290 +       .read_irq_name          = "ssl",
9291 +       .write_irq              = SSL_WRITE_IRQ,
9292 +       .write_irq_name         = "ssl-write",
9293 +       .symlink_from           = "serial",
9294 +       .symlink_to             = "tts",
9295 +       .mc  = {
9296 +               .name           = "ssl",
9297 +               .config         = ssl_config,
9298 +               .get_config     = ssl_get_config,
9299 +               .remove         = ssl_remove,
9300 +       },
9301 +};
9302 +
9303 +/* The array is initialized by line_init, which is an initcall.  The 
9304 + * individual elements are protected by individual semaphores.
9305 + */
9306 +static struct line serial_lines[NR_PORTS] =
9307 +       { [0 ... NR_PORTS - 1] = LINE_INIT(CONFIG_SSL_CHAN, &driver) };
9308 +
9309 +static struct lines lines = LINES_INIT(NR_PORTS);
9310 +
9311 +static int ssl_config(char *str)
9312 +{
9313 +       return(line_config(serial_lines, 
9314 +                          sizeof(serial_lines)/sizeof(serial_lines[0]), str));
9315 +}
9316 +
9317 +static int ssl_get_config(char *dev, char *str, int size, char **error_out)
9318 +{
9319 +       return(line_get_config(dev, serial_lines, 
9320 +                              sizeof(serial_lines)/sizeof(serial_lines[0]), 
9321 +                              str, size, error_out));
9322 +}
9323 +
9324 +static int ssl_remove(char *str)
9325 +{
9326 +       return(line_remove(serial_lines, 
9327 +                          sizeof(serial_lines)/sizeof(serial_lines[0]), str));
9328 +}
9329 +
9330 +int ssl_open(struct tty_struct *tty, struct file *filp)
9331 +{
9332 +       return(line_open(serial_lines, tty, &opts));
9333 +}
9334 +
9335 +static void ssl_close(struct tty_struct *tty, struct file * filp)
9336 +{
9337 +       line_close(serial_lines, tty);
9338 +}
9339 +
9340 +static int ssl_write(struct tty_struct * tty, int from_user,
9341 +                    const unsigned char *buf, int count)
9342 +{
9343 +       return(line_write(serial_lines, tty, from_user, buf, count));
9344 +}
9345 +
9346 +static void ssl_put_char(struct tty_struct *tty, unsigned char ch)
9347 +{
9348 +       line_write(serial_lines, tty, 0, &ch, sizeof(ch));
9349 +}
9350 +
9351 +static void ssl_flush_chars(struct tty_struct *tty)
9352 +{
9353 +       return;
9354 +}
9355 +
9356 +static int ssl_chars_in_buffer(struct tty_struct *tty)
9357 +{
9358 +       return(0);
9359 +}
9360 +
9361 +static void ssl_flush_buffer(struct tty_struct *tty)
9362 +{
9363 +       return;
9364 +}
9365 +
9366 +static int ssl_ioctl(struct tty_struct *tty, struct file * file,
9367 +                    unsigned int cmd, unsigned long arg)
9368 +{
9369 +       int ret;
9370 +
9371 +       ret = 0;
9372 +       switch(cmd){
9373 +       case TCGETS:
9374 +       case TCSETS:
9375 +       case TCFLSH:
9376 +       case TCSETSF:
9377 +       case TCSETSW:
9378 +       case TCGETA:
9379 +       case TIOCMGET:
9380 +       case TCSBRK:
9381 +       case TCSBRKP:
9382 +       case TIOCMSET:
9383 +               ret = -ENOIOCTLCMD;
9384 +               break;
9385 +       default:
9386 +               printk(KERN_ERR 
9387 +                      "Unimplemented ioctl in ssl_ioctl : 0x%x\n", cmd);
9388 +               ret = -ENOIOCTLCMD;
9389 +               break;
9390 +       }
9391 +       return(ret);
9392 +}
9393 +
9394 +static void ssl_throttle(struct tty_struct * tty)
9395 +{
9396 +       printk(KERN_ERR "Someone should implement ssl_throttle\n");
9397 +}
9398 +
9399 +static void ssl_unthrottle(struct tty_struct * tty)
9400 +{
9401 +       printk(KERN_ERR "Someone should implement ssl_unthrottle\n");
9402 +}
9403 +
9404 +static void ssl_set_termios(struct tty_struct *tty, 
9405 +                           struct termios *old_termios)
9406 +{
9407 +}
9408 +
9409 +static void ssl_stop(struct tty_struct *tty)
9410 +{
9411 +       printk(KERN_ERR "Someone should implement ssl_stop\n");
9412 +}
9413 +
9414 +static void ssl_start(struct tty_struct *tty)
9415 +{
9416 +       printk(KERN_ERR "Someone should implement ssl_start\n");
9417 +}
9418 +
9419 +void ssl_hangup(struct tty_struct *tty)
9420 +{
9421 +}
9422 +
9423 +static struct tty_driver ssl_driver = {
9424 +       .refcount               = &ssl_refcount,
9425 +       .open                   = ssl_open,
9426 +       .close                  = ssl_close,
9427 +       .write                  = ssl_write,
9428 +       .put_char               = ssl_put_char,
9429 +       .flush_chars            = ssl_flush_chars,
9430 +       .chars_in_buffer        = ssl_chars_in_buffer,
9431 +       .flush_buffer           = ssl_flush_buffer,
9432 +       .ioctl                  = ssl_ioctl,
9433 +       .throttle               = ssl_throttle,
9434 +       .unthrottle             = ssl_unthrottle,
9435 +       .set_termios            = ssl_set_termios,
9436 +       .stop                   = ssl_stop,
9437 +       .start                  = ssl_start,
9438 +       .hangup                 = ssl_hangup
9439 +};
9440 +
9441 +/* Changed by ssl_init and referenced by ssl_exit, which are both serialized
9442 + * by being an initcall and exitcall, respectively.
9443 + */
9444 +static int ssl_init_done = 0;
9445 +
9446 +static void ssl_console_write(struct console *c, const char *string, 
9447 +                             unsigned len)
9448 +{
9449 +       struct line *line = &serial_lines[c->index];
9450 +       if(ssl_init_done)
9451 +               down(&line->sem);
9452 +       console_write_chan(&line->chan_list, string, len);
9453 +       if(ssl_init_done)
9454 +               up(&line->sem);
9455 +}
9456 +
9457 +static kdev_t ssl_console_device(struct console *c)
9458 +{
9459 +       return mk_kdev(TTY_MAJOR, c->index);
9460 +}
9461 +
9462 +static int ssl_console_setup(struct console *co, char *options)
9463 +{
9464 +       return(0);
9465 +}
9466 +
9467 +static struct console ssl_cons = {
9468 +       name:           "ttyS",
9469 +       write:          ssl_console_write,
9470 +       device:         ssl_console_device,
9471 +       setup:          ssl_console_setup,
9472 +       flags:          CON_PRINTBUFFER,
9473 +       index:          -1,
9474 +};
9475 +
9476 +int ssl_init(void)
9477 +{
9478 +       char *new_title;
9479 +
9480 +       printk(KERN_INFO "Initializing software serial port version %d\n", 
9481 +              ssl_version);
9482 +
9483 +       line_register_devfs(&lines, &driver, &ssl_driver, serial_lines, 
9484 +                           sizeof(serial_lines)/sizeof(serial_lines[0]));
9485 +
9486 +       lines_init(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]));
9487 +
9488 +       new_title = add_xterm_umid(opts.xterm_title);
9489 +       if(new_title != NULL) opts.xterm_title = new_title;
9490 +
9491 +       register_console(&ssl_cons);
9492 +       ssl_init_done = 1;
9493 +       return(0);
9494 +}
9495 +
9496 +__initcall(ssl_init);
9497 +
9498 +static int ssl_chan_setup(char *str)
9499 +{
9500 +       return(line_setup(serial_lines, 
9501 +                         sizeof(serial_lines)/sizeof(serial_lines[0]), 
9502 +                         str, 1));
9503 +}
9504 +
9505 +__setup("ssl", ssl_chan_setup);
9506 +__channel_help(ssl_chan_setup, "ssl");
9507 +
9508 +static void ssl_exit(void)
9509 +{
9510 +       if(!ssl_init_done) return;
9511 +       close_lines(serial_lines, 
9512 +                   sizeof(serial_lines)/sizeof(serial_lines[0]));
9513 +}
9514 +
9515 +__uml_exitcall(ssl_exit);
9516 +
9517 +/*
9518 + * Overrides for Emacs so that we follow Linus's tabbing style.
9519 + * Emacs will notice this stuff at the end of the file and automatically
9520 + * adjust the settings for this buffer only.  This must remain at the end
9521 + * of the file.
9522 + * ---------------------------------------------------------------------------
9523 + * Local variables:
9524 + * c-file-style: "linux"
9525 + * End:
9526 + */
9527 diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.h um/arch/um/drivers/ssl.h
9528 --- orig/arch/um/drivers/ssl.h  1969-12-31 19:00:00.000000000 -0500
9529 +++ um/arch/um/drivers/ssl.h    2003-10-21 03:26:06.000000000 -0400
9530 @@ -0,0 +1,23 @@
9531 +/* 
9532 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9533 + * Licensed under the GPL
9534 + */
9535 +
9536 +#ifndef __SSL_H__
9537 +#define __SSL_H__
9538 +
9539 +extern int ssl_read(int fd, int line);
9540 +extern void ssl_receive_char(int line, char ch);
9541 +
9542 +#endif
9543 +
9544 +/*
9545 + * Overrides for Emacs so that we follow Linus's tabbing style.
9546 + * Emacs will notice this stuff at the end of the file and automatically
9547 + * adjust the settings for this buffer only.  This must remain at the end
9548 + * of the file.
9549 + * ---------------------------------------------------------------------------
9550 + * Local variables:
9551 + * c-file-style: "linux"
9552 + * End:
9553 + */
9554 diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.c um/arch/um/drivers/stdio_console.c
9555 --- orig/arch/um/drivers/stdio_console.c        1969-12-31 19:00:00.000000000 -0500
9556 +++ um/arch/um/drivers/stdio_console.c  2003-11-07 03:03:03.000000000 -0500
9557 @@ -0,0 +1,258 @@
9558 +/* 
9559 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
9560 + * Licensed under the GPL
9561 + */
9562 +
9563 +#include "linux/config.h"
9564 +#include "linux/posix_types.h"
9565 +#include "linux/tty.h"
9566 +#include "linux/tty_flip.h"
9567 +#include "linux/types.h"
9568 +#include "linux/major.h"
9569 +#include "linux/kdev_t.h"
9570 +#include "linux/console.h"
9571 +#include "linux/string.h"
9572 +#include "linux/sched.h"
9573 +#include "linux/list.h"
9574 +#include "linux/init.h"
9575 +#include "linux/interrupt.h"
9576 +#include "linux/slab.h"
9577 +#include "asm/current.h"
9578 +#include "asm/softirq.h"
9579 +#include "asm/hardirq.h"
9580 +#include "asm/irq.h"
9581 +#include "stdio_console.h"
9582 +#include "line.h"
9583 +#include "chan_kern.h"
9584 +#include "user_util.h"
9585 +#include "kern_util.h"
9586 +#include "irq_user.h"
9587 +#include "mconsole_kern.h"
9588 +#include "init.h"
9589 +#include "2_5compat.h"
9590 +
9591 +#define MAX_TTYS (8)
9592 +
9593 +/* Referenced only by tty_driver below - presumably it's locked correctly
9594 + * by the tty driver.
9595 + */
9596 +
9597 +static struct tty_driver console_driver;
9598 +
9599 +static int console_refcount = 0;
9600 +
9601 +static struct chan_ops init_console_ops = {
9602 +       .type           = "you shouldn't see this",
9603 +       .init           = NULL,
9604 +       .open           = NULL,
9605 +       .close          = NULL,
9606 +       .read           = NULL,
9607 +       .write          = NULL,
9608 +       .console_write  = generic_write,
9609 +       .window_size    = NULL,
9610 +       .free           = NULL,
9611 +       .winch          = 0,
9612 +};
9613 +
9614 +static struct chan init_console_chan = {
9615 +       .list           = { },
9616 +       .primary        = 1,
9617 +       .input          = 0,
9618 +       .output         = 1,
9619 +       .opened         = 1,
9620 +       .fd             = 1,
9621 +       .pri            = INIT_STATIC,
9622 +       .ops            = &init_console_ops,
9623 +       .data           = NULL
9624 +};
9625 +
9626 +void stdio_announce(char *dev_name, int dev)
9627 +{
9628 +       printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
9629 +              dev_name);
9630 +}
9631 +
9632 +static struct chan_opts opts = {
9633 +       .announce       = stdio_announce,
9634 +       .xterm_title    = "Virtual Console #%d",
9635 +       .raw            = 1,
9636 +       .tramp_stack    = 0,
9637 +       .in_kernel      = 1,
9638 +};
9639 +
9640 +static int con_config(char *str);
9641 +static int con_get_config(char *dev, char *str, int size, char **error_out);
9642 +static int con_remove(char *str);
9643 +
9644 +static struct line_driver driver = {
9645 +       .name                   = "UML console",
9646 +       .devfs_name             = "vc/%d",
9647 +       .major                  = TTY_MAJOR,
9648 +       .minor_start            = 0,
9649 +       .type                   = TTY_DRIVER_TYPE_CONSOLE,
9650 +       .subtype                = SYSTEM_TYPE_CONSOLE,
9651 +       .read_irq               = CONSOLE_IRQ,
9652 +       .read_irq_name          = "console",
9653 +       .write_irq              = CONSOLE_WRITE_IRQ,
9654 +       .write_irq_name         = "console-write",
9655 +       .symlink_from           = "ttys",
9656 +       .symlink_to             = "vc",
9657 +       .mc  = {
9658 +               .name           = "con",
9659 +               .config         = con_config,
9660 +               .get_config     = con_get_config,
9661 +               .remove         = con_remove,
9662 +       },
9663 +};
9664 +
9665 +static struct lines console_lines = LINES_INIT(MAX_TTYS);
9666 +
9667 +/* The array is initialized by line_init, which is an initcall.  The 
9668 + * individual elements are protected by individual semaphores.
9669 + */
9670 +struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
9671 +                             [ 1 ... MAX_TTYS - 1 ] = 
9672 +                             LINE_INIT(CONFIG_CON_CHAN, &driver) };
9673 +
9674 +static int con_config(char *str)
9675 +{
9676 +       return(line_config(vts, sizeof(vts)/sizeof(vts[0]), str));
9677 +}
9678 +
9679 +static int con_get_config(char *dev, char *str, int size, char **error_out)
9680 +{
9681 +       return(line_get_config(dev, vts, sizeof(vts)/sizeof(vts[0]), str, 
9682 +                              size, error_out));
9683 +}
9684 +
9685 +static int con_remove(char *str)
9686 +{
9687 +       return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str));
9688 +}
9689 +
9690 +static int open_console(struct tty_struct *tty)
9691 +{
9692 +       return(line_open(vts, tty, &opts));
9693 +}
9694 +
9695 +static int con_open(struct tty_struct *tty, struct file *filp)
9696 +{
9697 +       return(open_console(tty));
9698 +}
9699 +
9700 +static void con_close(struct tty_struct *tty, struct file *filp)
9701 +{
9702 +       line_close(vts, tty);
9703 +}
9704 +
9705 +static int con_write(struct tty_struct *tty, int from_user, 
9706 +                    const unsigned char *buf, int count)
9707 +{
9708 +        return(line_write(vts, tty, from_user, buf, count));
9709 +}
9710 +
9711 +static void set_termios(struct tty_struct *tty, struct termios * old)
9712 +{
9713 +}
9714 +
9715 +static int chars_in_buffer(struct tty_struct *tty)
9716 +{
9717 +       return(0);
9718 +}
9719 +
9720 +static int con_init_done = 0;
9721 +
9722 +int stdio_init(void)
9723 +{
9724 +       char *new_title;
9725 +
9726 +       printk(KERN_INFO "Initializing stdio console driver\n");
9727 +
9728 +       line_register_devfs(&console_lines, &driver, &console_driver, vts, 
9729 +                           sizeof(vts)/sizeof(vts[0]));
9730 +
9731 +       lines_init(vts, sizeof(vts)/sizeof(vts[0]));
9732 +
9733 +       new_title = add_xterm_umid(opts.xterm_title);
9734 +       if(new_title != NULL) opts.xterm_title = new_title;
9735 +
9736 +       open_console(NULL);
9737 +       con_init_done = 1;
9738 +       return(0);
9739 +}
9740 +
9741 +__initcall(stdio_init);
9742 +
9743 +static void console_write(struct console *console, const char *string, 
9744 +                         unsigned len)
9745 +{
9746 +       struct line *line = &vts[console->index];
9747 +
9748 +       if(con_init_done)
9749 +               down(&line->sem);
9750 +       console_write_chan(&line->chan_list, string, len);
9751 +       if(con_init_done)
9752 +               up(&line->sem);
9753 +}
9754 +
9755 +static struct tty_driver console_driver = {
9756 +       .refcount               = &console_refcount,
9757 +       .open                   = con_open,
9758 +       .close                  = con_close,
9759 +       .write                  = con_write,
9760 +       .chars_in_buffer        = chars_in_buffer,
9761 +       .set_termios            = set_termios
9762 +};
9763 +
9764 +static kdev_t console_device(struct console *c)
9765 +{
9766 +       return mk_kdev(TTY_MAJOR, c->index);
9767 +}
9768 +
9769 +static int console_setup(struct console *co, char *options)
9770 +{
9771 +       return(0);
9772 +}
9773 +
9774 +static struct console stdiocons = {
9775 +       name:           "tty",
9776 +       write:          console_write,
9777 +       device:         console_device,
9778 +       setup:          console_setup,
9779 +       flags:          CON_PRINTBUFFER,
9780 +       index:          -1,
9781 +};
9782 +
9783 +void stdio_console_init(void)
9784 +{
9785 +       INIT_LIST_HEAD(&vts[0].chan_list);
9786 +       list_add(&init_console_chan.list, &vts[0].chan_list);
9787 +       register_console(&stdiocons);
9788 +}
9789 +
9790 +static int console_chan_setup(char *str)
9791 +{
9792 +       return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
9793 +}
9794 +
9795 +__setup("con", console_chan_setup);
9796 +__channel_help(console_chan_setup, "con");
9797 +
9798 +static void console_exit(void)
9799 +{
9800 +       if(!con_init_done) return;
9801 +       close_lines(vts, sizeof(vts)/sizeof(vts[0]));
9802 +}
9803 +
9804 +__uml_exitcall(console_exit);
9805 +
9806 +/*
9807 + * Overrides for Emacs so that we follow Linus's tabbing style.
9808 + * Emacs will notice this stuff at the end of the file and automatically
9809 + * adjust the settings for this buffer only.  This must remain at the end
9810 + * of the file.
9811 + * ---------------------------------------------------------------------------
9812 + * Local variables:
9813 + * c-file-style: "linux"
9814 + * End:
9815 + */
9816 diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.h um/arch/um/drivers/stdio_console.h
9817 --- orig/arch/um/drivers/stdio_console.h        1969-12-31 19:00:00.000000000 -0500
9818 +++ um/arch/um/drivers/stdio_console.h  2003-10-21 03:26:06.000000000 -0400
9819 @@ -0,0 +1,21 @@
9820 +/* 
9821 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9822 + * Licensed under the GPL
9823 + */
9824 +
9825 +#ifndef __STDIO_CONSOLE_H
9826 +#define __STDIO_CONSOLE_H
9827 +
9828 +extern void save_console_flags(void);
9829 +#endif
9830 +
9831 +/*
9832 + * Overrides for Emacs so that we follow Linus's tabbing style.
9833 + * Emacs will notice this stuff at the end of the file and automatically
9834 + * adjust the settings for this buffer only.  This must remain at the end
9835 + * of the file.
9836 + * ---------------------------------------------------------------------------
9837 + * Local variables:
9838 + * c-file-style: "linux"
9839 + * End:
9840 + */
9841 diff -Naur -X ../exclude-files orig/arch/um/drivers/tty.c um/arch/um/drivers/tty.c
9842 --- orig/arch/um/drivers/tty.c  1969-12-31 19:00:00.000000000 -0500
9843 +++ um/arch/um/drivers/tty.c    2003-10-21 03:26:06.000000000 -0400
9844 @@ -0,0 +1,86 @@
9845 +/* 
9846 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
9847 + * Licensed under the GPL
9848 + */
9849 +
9850 +#include <stdio.h>
9851 +#include <termios.h>
9852 +#include <errno.h>
9853 +#include <unistd.h>
9854 +#include "chan_user.h"
9855 +#include "user_util.h"
9856 +#include "user.h"
9857 +#include "os.h"
9858 +
9859 +struct tty_chan {
9860 +       char *dev;
9861 +       int raw;
9862 +       struct termios tt;
9863 +};
9864 +
9865 +void *tty_chan_init(char *str, int device, struct chan_opts *opts)
9866 +{
9867 +       struct tty_chan *data;
9868 +
9869 +       if(*str != ':'){
9870 +               printk("tty_init : channel type 'tty' must specify "
9871 +                      "a device\n");
9872 +               return(NULL);
9873 +       }
9874 +       str++;
9875 +
9876 +       data = um_kmalloc(sizeof(*data)); 
9877 +       if(data == NULL) 
9878 +               return(NULL);
9879 +       *data = ((struct tty_chan) { .dev       = str,
9880 +                                    .raw       = opts->raw });
9881 +                                    
9882 +       return(data);
9883 +}
9884 +
9885 +int tty_open(int input, int output, int primary, void *d, char **dev_out)
9886 +{
9887 +       struct tty_chan *data = d;
9888 +       int fd;
9889 +
9890 +       fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0);
9891 +       if(fd < 0) return(fd);
9892 +       if(data->raw){
9893 +               tcgetattr(fd, &data->tt);
9894 +               raw(fd, 0);
9895 +       }
9896 +
9897 +       *dev_out = data->dev;
9898 +       return(fd);
9899 +}
9900 +
9901 +int tty_console_write(int fd, const char *buf, int n, void *d)
9902 +{
9903 +       struct tty_chan *data = d;
9904 +
9905 +       return(generic_console_write(fd, buf, n, &data->tt));
9906 +}
9907 +
9908 +struct chan_ops tty_ops = {
9909 +       .type           = "tty",
9910 +       .init           = tty_chan_init,
9911 +       .open           = tty_open,
9912 +       .close          = generic_close,
9913 +       .read           = generic_read,
9914 +       .write          = generic_write,
9915 +       .console_write  = tty_console_write,
9916 +       .window_size    = generic_window_size,
9917 +       .free           = generic_free,
9918 +       .winch          = 0,
9919 +};
9920 +
9921 +/*
9922 + * Overrides for Emacs so that we follow Linus's tabbing style.
9923 + * Emacs will notice this stuff at the end of the file and automatically
9924 + * adjust the settings for this buffer only.  This must remain at the end
9925 + * of the file.
9926 + * ---------------------------------------------------------------------------
9927 + * Local variables:
9928 + * c-file-style: "linux"
9929 + * End:
9930 + */
9931 diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_kern.c um/arch/um/drivers/ubd_kern.c
9932 --- orig/arch/um/drivers/ubd_kern.c     1969-12-31 19:00:00.000000000 -0500
9933 +++ um/arch/um/drivers/ubd_kern.c       2004-01-21 01:28:43.000000000 -0500
9934 @@ -0,0 +1,1396 @@
9935 +/* 
9936 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9937 + * Licensed under the GPL
9938 + */
9939 +
9940 +/* 2001-09-28...2002-04-17
9941 + * Partition stuff by James_McMechan@hotmail.com
9942 + * old style ubd by setting UBD_SHIFT to 0
9943 + */
9944 +
9945 +#define MAJOR_NR UBD_MAJOR
9946 +#define UBD_SHIFT 4
9947 +
9948 +#include "linux/config.h"
9949 +#include "linux/blk.h"
9950 +#include "linux/blkdev.h"
9951 +#include "linux/hdreg.h"
9952 +#include "linux/init.h"
9953 +#include "linux/devfs_fs_kernel.h"
9954 +#include "linux/cdrom.h"
9955 +#include "linux/proc_fs.h"
9956 +#include "linux/ctype.h"
9957 +#include "linux/capability.h"
9958 +#include "linux/mm.h"
9959 +#include "linux/vmalloc.h"
9960 +#include "linux/blkpg.h"
9961 +#include "linux/genhd.h"
9962 +#include "linux/spinlock.h"
9963 +#include "asm/segment.h"
9964 +#include "asm/uaccess.h"
9965 +#include "asm/irq.h"
9966 +#include "asm/types.h"
9967 +#include "user_util.h"
9968 +#include "mem_user.h"
9969 +#include "kern_util.h"
9970 +#include "kern.h"
9971 +#include "mconsole_kern.h"
9972 +#include "init.h"
9973 +#include "irq_user.h"
9974 +#include "irq_kern.h"
9975 +#include "ubd_user.h"
9976 +#include "2_5compat.h"
9977 +#include "os.h"
9978 +#include "mem.h"
9979 +#include "mem_kern.h"
9980 +
9981 +static int ubd_open(struct inode * inode, struct file * filp);
9982 +static int ubd_release(struct inode * inode, struct file * file);
9983 +static int ubd_ioctl(struct inode * inode, struct file * file,
9984 +                    unsigned int cmd, unsigned long arg);
9985 +static int ubd_revalidate(kdev_t rdev);
9986 +static int ubd_revalidate1(kdev_t rdev);
9987 +
9988 +#define MAX_DEV (8)
9989 +#define MAX_MINOR (MAX_DEV << UBD_SHIFT)
9990 +
9991 +/* Changed in early boot */
9992 +static int ubd_do_mmap = 0;
9993 +#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
9994 +
9995 +/* Not modified by this driver */
9996 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
9997 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
9998 +
9999 +/* Protected by ubd_lock */
10000 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
10001 +
10002 +static struct block_device_operations ubd_blops = {
10003 +        .open          = ubd_open,
10004 +        .release       = ubd_release,
10005 +        .ioctl         = ubd_ioctl,
10006 +        .revalidate    = ubd_revalidate,
10007 +};
10008 +
10009 +/* Protected by ubd_lock, except in prepare_request and ubd_ioctl because 
10010 + * the block layer should ensure that the device is idle before closing it.
10011 + */
10012 +static struct hd_struct        ubd_part[MAX_MINOR] =
10013 +       { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
10014 +
10015 +/* Protected by io_request_lock */
10016 +static request_queue_t *ubd_queue;
10017 +
10018 +/* Protected by ubd_lock */
10019 +static int fake_major = MAJOR_NR;
10020 +
10021 +static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
10022 +
10023 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
10024 +{ \
10025 +       .major          = maj, \
10026 +       .major_name     = name, \
10027 +       .minor_shift    = shift, \
10028 +       .max_p          = 1 << shift, \
10029 +       .part           = parts, \
10030 +       .sizes          = bsizes, \
10031 +       .nr_real        = max, \
10032 +       .real_devices   = NULL, \
10033 +       .next           = NULL, \
10034 +       .fops           = blops, \
10035 +       .de_arr         = NULL, \
10036 +       .flags          = 0 \
10037 +}
10038 +
10039 +static struct gendisk ubd_gendisk = INIT_GENDISK(MAJOR_NR, "ubd", ubd_part,
10040 +                                                UBD_SHIFT, sizes, MAX_DEV, 
10041 +                                                &ubd_blops);
10042 +static struct gendisk fake_gendisk = INIT_GENDISK(0, "ubd", ubd_part, 
10043 +                                                 UBD_SHIFT, sizes, MAX_DEV, 
10044 +                                                 &ubd_blops);
10045 +
10046 +#ifdef CONFIG_BLK_DEV_UBD_SYNC
10047 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
10048 +                                        .cl = 1 })
10049 +#else
10050 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \
10051 +                                        .cl = 1 })
10052 +#endif
10053 +
10054 +/* Not protected - changed only in ubd_setup_common and then only to
10055 + * to enable O_SYNC.
10056 + */
10057 +static struct openflags global_openflags = OPEN_FLAGS;
10058 +
10059 +struct cow {
10060 +       char *file;
10061 +       int fd;
10062 +       unsigned long *bitmap;
10063 +       unsigned long bitmap_len;
10064 +       int bitmap_offset;
10065 +        int data_offset;
10066 +};
10067 +
10068 +struct ubd {
10069 +       char *file;
10070 +       int count;
10071 +       int fd;
10072 +       __u64 size;
10073 +       struct openflags boot_openflags;
10074 +       struct openflags openflags;
10075 +       devfs_handle_t devfs;
10076 +       int no_cow;
10077 +       struct cow cow;
10078 +
10079 +       int map_writes;
10080 +       int map_reads;
10081 +       int nomap_writes;
10082 +       int nomap_reads;
10083 +       int write_maps;
10084 +};
10085 +
10086 +#define DEFAULT_COW { \
10087 +       .file                   = NULL, \
10088 +        .fd                    = -1, \
10089 +        .bitmap                        = NULL, \
10090 +       .bitmap_offset          = 0, \
10091 +        .data_offset           = 0, \
10092 +}
10093 +
10094 +#define DEFAULT_UBD { \
10095 +       .file                   = NULL, \
10096 +       .count                  = 0, \
10097 +       .fd                     = -1, \
10098 +       .size                   = -1, \
10099 +       .boot_openflags         = OPEN_FLAGS, \
10100 +       .openflags              = OPEN_FLAGS, \
10101 +       .devfs                  = NULL, \
10102 +       .no_cow                 = 0, \
10103 +        .cow                   = DEFAULT_COW, \
10104 +       .map_writes             = 0, \
10105 +       .map_reads              = 0, \
10106 +       .nomap_writes           = 0, \
10107 +       .nomap_reads            = 0, \
10108 +       .write_maps             = 0, \
10109 +}
10110 +
10111 +struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
10112 +
10113 +static int ubd0_init(void)
10114 +{
10115 +       struct ubd *dev = &ubd_dev[0];
10116 +
10117 +       if(dev->file == NULL)
10118 +               dev->file = "root_fs";
10119 +       return(0);
10120 +}
10121 +
10122 +__initcall(ubd0_init);
10123 +
10124 +/* Only changed by fake_ide_setup which is a setup */
10125 +static int fake_ide = 0;
10126 +static struct proc_dir_entry *proc_ide_root = NULL;
10127 +static struct proc_dir_entry *proc_ide = NULL;
10128 +
10129 +static void make_proc_ide(void)
10130 +{
10131 +       proc_ide_root = proc_mkdir("ide", 0);
10132 +       proc_ide = proc_mkdir("ide0", proc_ide_root);
10133 +}
10134 +
10135 +static int proc_ide_read_media(char *page, char **start, off_t off, int count,
10136 +                              int *eof, void *data)
10137 +{
10138 +       int len;
10139 +
10140 +       strcpy(page, "disk\n");
10141 +       len = strlen("disk\n");
10142 +       len -= off;
10143 +       if (len < count){
10144 +               *eof = 1;
10145 +               if (len <= 0) return 0;
10146 +       }
10147 +       else len = count;
10148 +       *start = page + off;
10149 +       return len;
10150 +}
10151 +
10152 +static void make_ide_entries(char *dev_name)
10153 +{
10154 +       struct proc_dir_entry *dir, *ent;
10155 +       char name[64];
10156 +
10157 +       if(!fake_ide) return;
10158 +
10159 +       /* Without locking this could race if a UML was booted with no 
10160 +        * disks and then two mconsole requests which add disks came in 
10161 +        * at the same time.
10162 +        */
10163 +       spin_lock(&ubd_lock);
10164 +       if(proc_ide_root == NULL) make_proc_ide();
10165 +       spin_unlock(&ubd_lock);
10166 +
10167 +       dir = proc_mkdir(dev_name, proc_ide);
10168 +       if(!dir) return;
10169 +
10170 +       ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir);
10171 +       if(!ent) return;
10172 +       ent->nlink = 1;
10173 +       ent->data = NULL;
10174 +       ent->read_proc = proc_ide_read_media;
10175 +       ent->write_proc = NULL;
10176 +       sprintf(name,"ide0/%s", dev_name);
10177 +       proc_symlink(dev_name, proc_ide_root, name);
10178 +}
10179 +
10180 +static int fake_ide_setup(char *str)
10181 +{
10182 +       fake_ide = 1;
10183 +       return(1);
10184 +}
10185 +
10186 +__setup("fake_ide", fake_ide_setup);
10187 +
10188 +__uml_help(fake_ide_setup,
10189 +"fake_ide\n"
10190 +"    Create ide0 entries that map onto ubd devices.\n\n"
10191 +);
10192 +
10193 +static int parse_unit(char **ptr)
10194 +{
10195 +       char *str = *ptr, *end;
10196 +       int n = -1;
10197 +
10198 +       if(isdigit(*str)) {
10199 +               n = simple_strtoul(str, &end, 0);
10200 +               if(end == str)
10201 +                       return(-1);
10202 +               *ptr = end;
10203 +       }
10204 +       else if (('a' <= *str) && (*str <= 'h')) {
10205 +               n = *str - 'a';
10206 +               str++;
10207 +               *ptr = str;
10208 +       }
10209 +       return(n);
10210 +}
10211 +
10212 +static int ubd_setup_common(char *str, int *index_out)
10213 +{
10214 +       struct openflags flags = global_openflags;
10215 +       struct ubd *dev;
10216 +       char *backing_file;
10217 +       int n, err;
10218 +
10219 +       if(index_out) *index_out = -1;
10220 +       n = *str;
10221 +       if(n == '='){
10222 +               char *end;
10223 +               int major;
10224 +
10225 +               str++;
10226 +               if(!strcmp(str, "mmap")){
10227 +                       CHOOSE_MODE(printk("mmap not supported by the ubd "
10228 +                                          "driver in tt mode\n"),
10229 +                                   ubd_do_mmap = 1);
10230 +                       return(0);
10231 +               }
10232 +
10233 +               if(!strcmp(str, "sync")){
10234 +                       global_openflags.s = 1;
10235 +                       return(0);
10236 +               }
10237 +               major = simple_strtoul(str, &end, 0);
10238 +               if((*end != '\0') || (end == str)){
10239 +                       printk(KERN_ERR 
10240 +                              "ubd_setup : didn't parse major number\n");
10241 +                       return(1);
10242 +               }
10243 +
10244 +               err = 1;
10245 +               spin_lock(&ubd_lock);
10246 +               if(fake_major != MAJOR_NR){
10247 +                       printk(KERN_ERR "Can't assign a fake major twice\n");
10248 +                       goto out1;
10249 +               }
10250 +
10251 +               fake_gendisk.major = major;
10252 +               fake_major = major;
10253 +       
10254 +               printk(KERN_INFO "Setting extra ubd major number to %d\n",
10255 +                      major);
10256 +               err = 0;
10257 +       out1:
10258 +               spin_unlock(&ubd_lock);
10259 +               return(err);
10260 +       }
10261 +
10262 +       n = parse_unit(&str);
10263 +       if(n < 0){
10264 +               printk(KERN_ERR "ubd_setup : couldn't parse unit number "
10265 +                      "'%s'\n", str);
10266 +               return(1);
10267 +       }
10268 +
10269 +       if(n >= MAX_DEV){
10270 +               printk(KERN_ERR "ubd_setup : index %d out of range "
10271 +                      "(%d devices)\n", n, MAX_DEV);   
10272 +               return(1);
10273 +       }
10274 +
10275 +       err = 1;
10276 +       spin_lock(&ubd_lock);
10277 +
10278 +       dev = &ubd_dev[n];
10279 +       if(dev->file != NULL){
10280 +               printk(KERN_ERR "ubd_setup : device already configured\n");
10281 +               goto out2;
10282 +       }
10283 +
10284 +       if(index_out) *index_out = n;
10285 +
10286 +       if(*str == 'r'){
10287 +               flags.w = 0;
10288 +               str++;
10289 +       }
10290 +       if(*str == 's'){
10291 +               flags.s = 1;
10292 +               str++;
10293 +       }
10294 +       if(*str == 'd'){
10295 +               dev->no_cow = 1;
10296 +               str++;
10297 +       }
10298 +
10299 +       if(*str++ != '='){
10300 +               printk(KERN_ERR "ubd_setup : Expected '='\n");
10301 +               goto out2;
10302 +       }
10303 +
10304 +       err = 0;
10305 +       backing_file = strchr(str, ',');
10306 +       if(backing_file){
10307 +               if(dev->no_cow)
10308 +                       printk(KERN_ERR "Can't specify both 'd' and a "
10309 +                              "cow file\n");
10310 +               else {
10311 +                       *backing_file = '\0';
10312 +                       backing_file++;
10313 +               }
10314 +       }
10315 +       dev->file = str;
10316 +       dev->cow.file = backing_file;
10317 +       dev->boot_openflags = flags;
10318 + out2:
10319 +       spin_unlock(&ubd_lock);
10320 +       return(err);
10321 +}
10322 +
10323 +static int ubd_setup(char *str)
10324 +{
10325 +       ubd_setup_common(str, NULL);
10326 +       return(1);
10327 +}
10328 +
10329 +__setup("ubd", ubd_setup);
10330 +__uml_help(ubd_setup,
10331 +"ubd<n>=<filename>\n"
10332 +"    This is used to associate a device with a file in the underlying\n"
10333 +"    filesystem. Usually, there is a filesystem in the file, but \n"
10334 +"    that's not required. Swap devices containing swap files can be\n"
10335 +"    specified like this. Also, a file which doesn't contain a\n"
10336 +"    filesystem can have its contents read in the virtual \n"
10337 +"    machine by running dd on the device. n must be in the range\n"
10338 +"    0 to 7. Appending an 'r' to the number will cause that device\n"
10339 +"    to be mounted read-only. For example ubd1r=./ext_fs. Appending\n"
10340 +"    an 's' (has to be _after_ 'r', if there is one) will cause data\n"
10341 +"    to be written to disk on the host immediately.\n\n"
10342 +);
10343 +
10344 +static int fakehd(char *str)
10345 +{
10346 +       printk(KERN_INFO 
10347 +              "fakehd : Changing ubd_gendisk.major_name to \"hd\".\n");
10348 +       ubd_gendisk.major_name = "hd";
10349 +       return(1);
10350 +}
10351 +
10352 +__setup("fakehd", fakehd);
10353 +__uml_help(fakehd,
10354 +"fakehd\n"
10355 +"    Change the ubd device name to \"hd\".\n\n"
10356 +);
10357 +
10358 +static void do_ubd_request(request_queue_t * q);
10359 +
10360 +/* Only changed by ubd_init, which is an initcall. */
10361 +int thread_fd = -1;
10362 +
10363 +/* Changed by ubd_handler, which is serialized because interrupts only
10364 + * happen on CPU 0.
10365 + */
10366 +int intr_count = 0;
10367 +
10368 +static void ubd_finish(int error)
10369 +{
10370 +       int nsect;
10371 +
10372 +       if(error){
10373 +               end_request(0);
10374 +               return;
10375 +       }
10376 +       nsect = CURRENT->current_nr_sectors;
10377 +       CURRENT->sector += nsect;
10378 +       CURRENT->buffer += nsect << 9;
10379 +       CURRENT->errors = 0;
10380 +       CURRENT->nr_sectors -= nsect;
10381 +       CURRENT->current_nr_sectors = 0;
10382 +       end_request(1);
10383 +}
10384 +
10385 +static void ubd_handler(void)
10386 +{
10387 +       struct io_thread_req req;
10388 +       int n, err;
10389 +
10390 +       DEVICE_INTR = NULL;
10391 +       intr_count++;
10392 +       n = read_ubd_fs(thread_fd, &req, sizeof(req));
10393 +       if(n != sizeof(req)){
10394 +               printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
10395 +                      "err = %d\n", os_getpid(), -n);
10396 +               spin_lock(&io_request_lock);
10397 +               end_request(0);
10398 +               spin_unlock(&io_request_lock);
10399 +               return;
10400 +       }
10401 +        
10402 +        if((req.op != UBD_MMAP) && 
10403 +          ((req.offset != ((__u64) (CURRENT->sector)) << 9) ||
10404 +           (req.length != (CURRENT->current_nr_sectors) << 9)))
10405 +               panic("I/O op mismatch");
10406 +
10407 +       if(req.map_fd != -1){
10408 +               err = physmem_subst_mapping(req.buffer, req.map_fd, 
10409 +                                           req.map_offset, 1);
10410 +               if(err)
10411 +                       printk("ubd_handler - physmem_subst_mapping failed, "
10412 +                              "err = %d\n", -err);
10413 +       }
10414 +
10415 +       spin_lock(&io_request_lock);
10416 +       ubd_finish(req.error);
10417 +       reactivate_fd(thread_fd, UBD_IRQ);      
10418 +       do_ubd_request(ubd_queue);
10419 +       spin_unlock(&io_request_lock);
10420 +}
10421 +
10422 +static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
10423 +{
10424 +       ubd_handler();
10425 +}
10426 +
10427 +/* Only changed by ubd_init, which is an initcall. */
10428 +static int io_pid = -1;
10429 +
10430 +void kill_io_thread(void)
10431 +{
10432 +       if(io_pid != -1)
10433 +               os_kill_process(io_pid, 1);
10434 +}
10435 +
10436 +__uml_exitcall(kill_io_thread);
10437 +
10438 +/* Initialized in an initcall, and unchanged thereafter */
10439 +devfs_handle_t ubd_dir_handle;
10440 +
10441 +static int ubd_add(int n)
10442 +{
10443 +       struct ubd *dev = &ubd_dev[n];
10444 +       char name[sizeof("nnnnnn\0")], dev_name[sizeof("ubd0x")];
10445 +       int err = -EISDIR;
10446 +
10447 +       if(dev->file == NULL)
10448 +               goto out;
10449 +
10450 +       err = ubd_revalidate1(MKDEV(MAJOR_NR, n << UBD_SHIFT));
10451 +       if(err)
10452 +               goto out;
10453 +
10454 +       if(dev->cow.file == NULL)
10455 +               blk_sizes[n] = UBD_MMAP_BLOCK_SIZE;
10456 +
10457 +       sprintf(name, "%d", n);
10458 +       dev->devfs = devfs_register(ubd_dir_handle, name, DEVFS_FL_REMOVABLE,
10459 +                                   MAJOR_NR, n << UBD_SHIFT, S_IFBLK | 
10460 +                                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
10461 +                                   &ubd_blops, NULL);
10462 +
10463 +#if 0 /* 2.5 ... */
10464 +       sprintf(disk->disk_name, "ubd%c", 'a' + unit);
10465 +#endif
10466 +
10467 +       sprintf(dev_name, "%s%c", ubd_gendisk.major_name, 
10468 +                    n + 'a');
10469 +
10470 +       make_ide_entries(dev_name);
10471 +       return(0);
10472 +
10473 + out:
10474 +       return(err);
10475 +}
10476 +
10477 +static int ubd_config(char *str)
10478 +{
10479 +       int n, err;
10480 +
10481 +       str = uml_strdup(str);
10482 +       if(str == NULL){
10483 +               printk(KERN_ERR "ubd_config failed to strdup string\n");
10484 +               return(1);
10485 +       }
10486 +       err = ubd_setup_common(str, &n);
10487 +       if(err){
10488 +               kfree(str);
10489 +               return(-1);
10490 +       }
10491 +       if(n == -1) return(0);
10492 +
10493 +       spin_lock(&ubd_lock);
10494 +       err = ubd_add(n);
10495 +       if(err)
10496 +               ubd_dev[n].file = NULL;
10497 +       spin_unlock(&ubd_lock);
10498 +
10499 +       return(err);
10500 +}
10501 +
10502 +static int ubd_get_config(char *name, char *str, int size, char **error_out)
10503 +{
10504 +       struct ubd *dev;
10505 +       char *end;
10506 +       int n, len = 0;
10507 +
10508 +       n = simple_strtoul(name, &end, 0);
10509 +       if((*end != '\0') || (end == name)){
10510 +               *error_out = "ubd_get_config : didn't parse device number";
10511 +               return(-1);
10512 +       }
10513 +
10514 +       if((n >= MAX_DEV) || (n < 0)){
10515 +               *error_out = "ubd_get_config : device number out of range";
10516 +               return(-1);
10517 +       }
10518 +
10519 +       dev = &ubd_dev[n];
10520 +       spin_lock(&ubd_lock);
10521 +
10522 +       if(dev->file == NULL){
10523 +               CONFIG_CHUNK(str, size, len, "", 1);
10524 +               goto out;
10525 +       }
10526 +
10527 +       CONFIG_CHUNK(str, size, len, dev->file, 0);
10528 +
10529 +       if(dev->cow.file != NULL){
10530 +               CONFIG_CHUNK(str, size, len, ",", 0);
10531 +               CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
10532 +       }
10533 +       else CONFIG_CHUNK(str, size, len, "", 1);
10534 +
10535 + out:
10536 +       spin_unlock(&ubd_lock);
10537 +       return(len);
10538 +}
10539 +
10540 +static int ubd_remove(char *str)
10541 +{
10542 +       struct ubd *dev;
10543 +       int n, err = -ENODEV;
10544 +
10545 +       if(isdigit(*str)){
10546 +               char *end;
10547 +               n = simple_strtoul(str, &end, 0);
10548 +               if ((*end != '\0') || (end == str)) 
10549 +                       return(err);
10550 +       }
10551 +       else if (('a' <= *str) && (*str <= 'h'))
10552 +               n = *str - 'a';
10553 +       else
10554 +               return(err);    /* it should be a number 0-7/a-h */
10555 +
10556 +       if((n < 0) || (n >= MAX_DEV))
10557 +               return(err);
10558 +
10559 +       dev = &ubd_dev[n];
10560 +
10561 +       spin_lock(&ubd_lock);
10562 +       err = 0;
10563 +       if(dev->file == NULL)
10564 +               goto out;
10565 +       err = -1;
10566 +       if(dev->count > 0)
10567 +               goto out;
10568 +       if(dev->devfs != NULL) 
10569 +               devfs_unregister(dev->devfs);
10570 +
10571 +       *dev = ((struct ubd) DEFAULT_UBD);
10572 +       err = 0;
10573 + out:
10574 +       spin_unlock(&ubd_lock);
10575 +       return(err);
10576 +}
10577 +
10578 +static struct mc_device ubd_mc = {
10579 +       .name           = "ubd",
10580 +       .config         = ubd_config,
10581 +       .get_config     = ubd_get_config,
10582 +       .remove         = ubd_remove,
10583 +};
10584 +
10585 +static int ubd_mc_init(void)
10586 +{
10587 +       mconsole_register_dev(&ubd_mc);
10588 +       return(0);
10589 +}
10590 +
10591 +__initcall(ubd_mc_init);
10592 +
10593 +static request_queue_t *ubd_get_queue(kdev_t device)
10594 +{
10595 +       return(ubd_queue);
10596 +}
10597 +
10598 +int ubd_init(void)
10599 +{
10600 +       unsigned long stack;
10601 +        int i, err;
10602 +
10603 +       ubd_dir_handle = devfs_mk_dir (NULL, "ubd", NULL);
10604 +       if (devfs_register_blkdev(MAJOR_NR, "ubd", &ubd_blops)) {
10605 +               printk(KERN_ERR "ubd: unable to get major %d\n", MAJOR_NR);
10606 +               return -1;
10607 +       }
10608 +       read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
10609 +       blksize_size[MAJOR_NR] = blk_sizes;
10610 +       blk_size[MAJOR_NR] = sizes;
10611 +       INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
10612 +
10613 +       ubd_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
10614 +       blk_init_queue(ubd_queue, DEVICE_REQUEST);
10615 +       INIT_ELV(ubd_queue, &ubd_queue->elevator);
10616 +
10617 +        add_gendisk(&ubd_gendisk);
10618 +       if (fake_major != MAJOR_NR){
10619 +               /* major number 0 is used to auto select */
10620 +               err = devfs_register_blkdev(fake_major, "fake", &ubd_blops);
10621 +               if(fake_major == 0){
10622 +               /* auto device number case */
10623 +                       fake_major = err;
10624 +                       if(err == 0)
10625 +                               return(-ENODEV);
10626 +               } 
10627 +               else if (err){
10628 +                       /* not auto so normal error */
10629 +                       printk(KERN_ERR "ubd: error %d getting major %d\n", 
10630 +                              -err, fake_major);
10631 +                       return(-ENODEV);
10632 +               }
10633 +
10634 +               blk_dev[fake_major].queue = ubd_get_queue;
10635 +               read_ahead[fake_major] = 8;     /* 8 sector (4kB) read-ahead */
10636 +               blksize_size[fake_major] = blk_sizes;
10637 +               blk_size[fake_major] = sizes;
10638 +               INIT_HARDSECT(hardsect_size, fake_major, hardsect_sizes);
10639 +                add_gendisk(&fake_gendisk);
10640 +       }
10641 +
10642 +       for(i=0;i<MAX_DEV;i++) 
10643 +               ubd_add(i);
10644 +
10645 +       if(global_openflags.s){
10646 +               printk(KERN_INFO "ubd : Synchronous mode\n");
10647 +               return(0);
10648 +       }
10649 +       stack = alloc_stack(0, 0);
10650 +       io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), 
10651 +                                &thread_fd);
10652 +       if(io_pid < 0){
10653 +               io_pid = -1;
10654 +               printk(KERN_ERR 
10655 +                      "ubd : Failed to start I/O thread (errno = %d) - "
10656 +                      "falling back to synchronous I/O\n", -io_pid);
10657 +               return(0);
10658 +       }
10659 +       err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 
10660 +                            SA_INTERRUPT, "ubd", ubd_dev);
10661 +       if(err != 0) 
10662 +               printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
10663 +       return(err);
10664 +}
10665 +
10666 +__initcall(ubd_init);
10667 +
10668 +static void ubd_close(struct ubd *dev)
10669 +{
10670 +       if(ubd_do_mmap)
10671 +               physmem_forget_descriptor(dev->fd);
10672 +       os_close_file(dev->fd);
10673 +       if(dev->cow.file != NULL)
10674 +               return;
10675 +
10676 +       if(ubd_do_mmap)
10677 +               physmem_forget_descriptor(dev->cow.fd);
10678 +       os_close_file(dev->cow.fd);
10679 +       vfree(dev->cow.bitmap);
10680 +       dev->cow.bitmap = NULL;
10681 +}
10682 +
10683 +static int ubd_open_dev(struct ubd *dev)
10684 +{
10685 +       struct openflags flags;
10686 +       char **back_ptr;
10687 +       int err, create_cow, *create_ptr;
10688 +
10689 +       dev->openflags = dev->boot_openflags;
10690 +       create_cow = 0;
10691 +       create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
10692 +       back_ptr = dev->no_cow ? NULL : &dev->cow.file;
10693 +       dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
10694 +                               &dev->cow.bitmap_offset, &dev->cow.bitmap_len, 
10695 +                               &dev->cow.data_offset, create_ptr);
10696 +
10697 +       if((dev->fd == -ENOENT) && create_cow){
10698 +               dev->fd = create_cow_file(dev->file, dev->cow.file, 
10699 +                                         dev->openflags, 1 << 9, PAGE_SIZE,
10700 +                                         &dev->cow.bitmap_offset, 
10701 +                                         &dev->cow.bitmap_len,
10702 +                                         &dev->cow.data_offset);
10703 +               if(dev->fd >= 0){
10704 +                       printk(KERN_INFO "Creating \"%s\" as COW file for "
10705 +                              "\"%s\"\n", dev->file, dev->cow.file);
10706 +               }
10707 +       }
10708 +
10709 +       if(dev->fd < 0) return(dev->fd);
10710 +
10711 +       if(dev->cow.file != NULL){
10712 +               err = -ENOMEM;
10713 +               dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
10714 +               if(dev->cow.bitmap == NULL){
10715 +                       printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
10716 +                       goto error;
10717 +               }
10718 +               flush_tlb_kernel_vm();
10719 +
10720 +               err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 
10721 +                                     dev->cow.bitmap_offset, 
10722 +                                     dev->cow.bitmap_len);
10723 +               if(err < 0) 
10724 +                       goto error;
10725 +
10726 +               flags = dev->openflags;
10727 +               flags.w = 0;
10728 +               err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL, 
10729 +                                   NULL, NULL);
10730 +               if(err < 0) goto error;
10731 +               dev->cow.fd = err;
10732 +       }
10733 +       return(0);
10734 + error:
10735 +       os_close_file(dev->fd);
10736 +       return(err);
10737 +}
10738 +
10739 +static int ubd_file_size(struct ubd *dev, __u64 *size_out)
10740 +{
10741 +       char *file;
10742 +
10743 +       file = dev->cow.file ? dev->cow.file : dev->file;
10744 +       return(os_file_size(file, size_out));
10745 +}
10746 +
10747 +static int ubd_open(struct inode *inode, struct file *filp)
10748 +{
10749 +       struct ubd *dev;
10750 +       int n, offset, err = 0;
10751 +
10752 +       n = DEVICE_NR(inode->i_rdev);
10753 +       dev = &ubd_dev[n];
10754 +       if(n >= MAX_DEV)
10755 +               return -ENODEV;
10756 +
10757 +       spin_lock(&ubd_lock);
10758 +       offset = n << UBD_SHIFT;
10759 +
10760 +       if(dev->count == 0){
10761 +               err = ubd_open_dev(dev);
10762 +               if(err){
10763 +                       printk(KERN_ERR "ubd%d: Can't open \"%s\": "
10764 +                              "errno = %d\n", n, dev->file, -err);
10765 +                       goto out;
10766 +               }
10767 +               err = ubd_file_size(dev, &dev->size);
10768 +               if(err < 0)
10769 +                       goto out;
10770 +               sizes[offset] = dev->size / BLOCK_SIZE;
10771 +               ubd_part[offset].nr_sects = dev->size / hardsect_sizes[offset];
10772 +       }
10773 +       dev->count++;
10774 +       if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
10775 +               if(--dev->count == 0) ubd_close(dev);
10776 +               err = -EROFS;
10777 +       }
10778 + out:
10779 +       spin_unlock(&ubd_lock);
10780 +       return(err);
10781 +}
10782 +
10783 +static int ubd_release(struct inode * inode, struct file * file)
10784 +{
10785 +        int n, offset;
10786 +
10787 +       n =  DEVICE_NR(inode->i_rdev);
10788 +       offset = n << UBD_SHIFT;
10789 +       if(n >= MAX_DEV)
10790 +               return -ENODEV;
10791 +
10792 +       spin_lock(&ubd_lock);
10793 +       if(--ubd_dev[n].count == 0)
10794 +               ubd_close(&ubd_dev[n]);
10795 +       spin_unlock(&ubd_lock);
10796 +
10797 +       return(0);
10798 +}
10799 +
10800 +static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, 
10801 +                         __u64 *cow_offset, unsigned long *bitmap, 
10802 +                         __u64 bitmap_offset, unsigned long *bitmap_words,
10803 +                         __u64 bitmap_len)
10804 +{
10805 +       __u64 sector = io_offset >> 9;
10806 +       int i, update_bitmap = 0;
10807 +
10808 +       for(i = 0; i < length >> 9; i++){
10809 +               if(cow_mask != NULL)
10810 +                       ubd_set_bit(i, (unsigned char *) cow_mask);
10811 +               if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
10812 +                       continue;
10813 +
10814 +               update_bitmap = 1;
10815 +               ubd_set_bit(sector + i, (unsigned char *) bitmap);
10816 +       }
10817 +
10818 +       if(!update_bitmap)
10819 +               return;
10820 +
10821 +       *cow_offset = sector / (sizeof(unsigned long) * 8);
10822 +
10823 +       /* This takes care of the case where we're exactly at the end of the
10824 +        * device, and *cow_offset + 1 is off the end.  So, just back it up
10825 +        * by one word.  Thanks to Lynn Kerby for the fix and James McMechan
10826 +        * for the original diagnosis.
10827 +        */
10828 +       if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) / 
10829 +                          sizeof(unsigned long) - 1))
10830 +               (*cow_offset)--;
10831 +
10832 +       bitmap_words[0] = bitmap[*cow_offset];
10833 +       bitmap_words[1] = bitmap[*cow_offset + 1];
10834 +
10835 +       *cow_offset *= sizeof(unsigned long);
10836 +       *cow_offset += bitmap_offset;
10837 +}
10838 +
10839 +static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, 
10840 +                      __u64 bitmap_offset, __u64 bitmap_len)
10841 +{
10842 +       __u64 sector = req->offset >> 9;
10843 +        int i;
10844 +
10845 +       if(req->length > (sizeof(req->sector_mask) * 8) << 9)
10846 +               panic("Operation too long");
10847 +
10848 +       if(req->op == UBD_READ) {
10849 +               for(i = 0; i < req->length >> 9; i++){
10850 +                       if(ubd_test_bit(sector + i, (unsigned char *) bitmap)){
10851 +                               ubd_set_bit(i, (unsigned char *) 
10852 +                                           &req->sector_mask);
10853 +                       }
10854 +                }
10855 +        } 
10856 +        else cowify_bitmap(req->offset, req->length, &req->sector_mask,
10857 +                          &req->cow_offset, bitmap, bitmap_offset, 
10858 +                          req->bitmap_words, bitmap_len);
10859 +}
10860 +
10861 +static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
10862 +{
10863 +       __u64 sector;
10864 +       unsigned char *bitmap;
10865 +       int bit, i;
10866 +
10867 +       /* mmap must have been requested on the command line */
10868 +       if(!ubd_do_mmap)
10869 +               return(-1);
10870 +
10871 +       /* The buffer must be page aligned */
10872 +       if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
10873 +               return(-1);
10874 +
10875 +       /* The request must be a page long */
10876 +       if((req->current_nr_sectors << 9) != PAGE_SIZE)
10877 +               return(-1);
10878 +
10879 +       if(dev->cow.file == NULL)
10880 +               return(dev->fd);
10881 +
10882 +       sector = offset >> 9;
10883 +       bitmap = (unsigned char *) dev->cow.bitmap;
10884 +       bit = ubd_test_bit(sector, bitmap);
10885 +
10886 +       for(i = 1; i < req->current_nr_sectors; i++){
10887 +               if(ubd_test_bit(sector + i, bitmap) != bit)
10888 +                       return(-1);
10889 +       }
10890 +
10891 +       if(bit || (req->cmd == WRITE))
10892 +               offset += dev->cow.data_offset;
10893 +
10894 +       /* The data on disk must be page aligned */
10895 +       if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
10896 +               return(-1);
10897 +
10898 +       return(bit ? dev->fd : dev->cow.fd);
10899 +}
10900 +
10901 +static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset, 
10902 +                               struct request *req, 
10903 +                               struct io_thread_req *io_req)
10904 +{
10905 +       int err;
10906 +
10907 +       if(req->cmd == WRITE){
10908 +               /* Writes are almost no-ops since the new data is already in the
10909 +                * host page cache
10910 +                */
10911 +               dev->map_writes++;
10912 +               if(dev->cow.file != NULL)
10913 +                       cowify_bitmap(io_req->offset, io_req->length, 
10914 +                                     &io_req->sector_mask, &io_req->cow_offset,
10915 +                                     dev->cow.bitmap, dev->cow.bitmap_offset,
10916 +                                     io_req->bitmap_words, 
10917 +                                     dev->cow.bitmap_len);
10918 +       }
10919 +       else {
10920 +               int w;
10921 +
10922 +               if((dev->cow.file != NULL) && (fd == dev->cow.fd))
10923 +                       w = 0;
10924 +               else w = dev->openflags.w;
10925 +
10926 +               if((dev->cow.file != NULL) && (fd == dev->fd))
10927 +                       offset += dev->cow.data_offset;
10928 +
10929 +               err = physmem_subst_mapping(req->buffer, fd, offset, w);
10930 +               if(err){
10931 +                       printk("physmem_subst_mapping failed, err = %d\n", 
10932 +                              -err);
10933 +                       return(1);
10934 +               }
10935 +               dev->map_reads++;
10936 +       }
10937 +       io_req->op = UBD_MMAP;
10938 +       io_req->buffer = req->buffer;
10939 +       return(0);
10940 +}
10941 +
10942 +static int prepare_request(struct request *req, struct io_thread_req *io_req)
10943 +{
10944 +       struct ubd *dev;
10945 +       __u64 offset;
10946 +       int minor, n, len, fd;
10947 +
10948 +       if(req->rq_status == RQ_INACTIVE) return(1);
10949 +
10950 +       minor = MINOR(req->rq_dev);
10951 +       n = minor >> UBD_SHIFT;
10952 +       dev = &ubd_dev[n];
10953 +
10954 +       if(IS_WRITE(req) && !dev->openflags.w){
10955 +               printk("Write attempted on readonly ubd device %d\n", n);
10956 +               end_request(0);
10957 +               return(1);
10958 +       }
10959 +
10960 +        req->sector += ubd_part[minor].start_sect;
10961 +       offset = ((__u64) req->sector) << 9;
10962 +       len = req->current_nr_sectors << 9;
10963 +
10964 +       io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
10965 +       io_req->fds[1] = dev->fd;
10966 +       io_req->map_fd = -1;
10967 +       io_req->cow_offset = -1;
10968 +       io_req->offset = offset;
10969 +       io_req->length = len;
10970 +       io_req->error = 0;
10971 +       io_req->sector_mask = 0;
10972 +
10973 +       fd = mmap_fd(req, dev, io_req->offset);
10974 +       if(fd > 0){
10975 +               /* If mmapping is otherwise OK, but the first access to the 
10976 +                * page is a write, then it's not mapped in yet.  So we have 
10977 +                * to write the data to disk first, then we can map the disk
10978 +                * page in and continue normally from there.
10979 +                */
10980 +               if((req->cmd == WRITE) && !is_remapped(req->buffer)){
10981 +                       io_req->map_fd = dev->fd;
10982 +                       io_req->map_offset = io_req->offset + 
10983 +                               dev->cow.data_offset;
10984 +                       dev->write_maps++;
10985 +               }
10986 +               else return(prepare_mmap_request(dev, fd, io_req->offset, req, 
10987 +                                                io_req));
10988 +       }
10989 +
10990 +       if(req->cmd == READ)
10991 +               dev->nomap_reads++;
10992 +       else dev->nomap_writes++;
10993 +
10994 +       io_req->op = (req->cmd == READ) ? UBD_READ : UBD_WRITE;
10995 +       io_req->offsets[0] = 0;
10996 +       io_req->offsets[1] = dev->cow.data_offset;
10997 +       io_req->buffer = req->buffer;
10998 +       io_req->sectorsize = 1 << 9;
10999 +
11000 +        if(dev->cow.file != NULL) 
11001 +               cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
11002 +                          dev->cow.bitmap_len);
11003 +       return(0);
11004 +}
11005 +
11006 +static void do_ubd_request(request_queue_t *q)
11007 +{
11008 +       struct io_thread_req io_req;
11009 +       struct request *req;
11010 +       int err, n;
11011 +
11012 +       if(thread_fd == -1){
11013 +               while(!list_empty(&q->queue_head)){
11014 +                       req = blkdev_entry_next_request(&q->queue_head);
11015 +                       err = prepare_request(req, &io_req);
11016 +                       if(!err){
11017 +                               do_io(&io_req);
11018 +                               ubd_finish(io_req.error);
11019 +                       }
11020 +               }
11021 +       }
11022 +       else {
11023 +               if(DEVICE_INTR || list_empty(&q->queue_head)) return;
11024 +               req = blkdev_entry_next_request(&q->queue_head);
11025 +               err = prepare_request(req, &io_req);
11026 +               if(!err){
11027 +                       SET_INTR(ubd_handler);
11028 +                       n = write_ubd_fs(thread_fd, (char *) &io_req, 
11029 +                                        sizeof(io_req));
11030 +                       if(n != sizeof(io_req))
11031 +                               printk("write to io thread failed, "
11032 +                                      "errno = %d\n", -n);
11033 +               }
11034 +       }
11035 +}
11036 +
11037 +static int ubd_ioctl(struct inode * inode, struct file * file,
11038 +                    unsigned int cmd, unsigned long arg)
11039 +{
11040 +       struct hd_geometry *loc = (struct hd_geometry *) arg;
11041 +       struct ubd *dev;
11042 +       int n, minor, err;
11043 +       struct hd_driveid ubd_id = {
11044 +               .cyls           = 0,
11045 +               .heads          = 128,
11046 +               .sectors        = 32,
11047 +       };
11048 +       
11049 +        if(!inode) return(-EINVAL);
11050 +       minor = MINOR(inode->i_rdev);
11051 +       n = minor >> UBD_SHIFT;
11052 +       if(n >= MAX_DEV)
11053 +               return(-EINVAL);
11054 +       dev = &ubd_dev[n];
11055 +       switch (cmd) {
11056 +               struct hd_geometry g;
11057 +               struct cdrom_volctrl volume;
11058 +       case HDIO_GETGEO:
11059 +               if(!loc) return(-EINVAL);
11060 +               g.heads = 128;
11061 +               g.sectors = 32;
11062 +               g.cylinders = dev->size / (128 * 32 * hardsect_sizes[minor]);
11063 +               g.start = ubd_part[minor].start_sect;
11064 +               return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
11065 +       case BLKGETSIZE:   /* Return device size */
11066 +               if(!arg) return(-EINVAL);
11067 +               err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
11068 +               if(err)
11069 +                       return(err);
11070 +               put_user(ubd_part[minor].nr_sects, (long *) arg);
11071 +               return(0);
11072 +       case BLKRRPART: /* Re-read partition tables */
11073 +               return(ubd_revalidate(inode->i_rdev));
11074 +
11075 +       case HDIO_SET_UNMASKINTR:
11076 +               if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
11077 +               if((arg > 1) || (minor & 0x3F)) return(-EINVAL);
11078 +               return(0);
11079 +
11080 +       case HDIO_GET_UNMASKINTR:
11081 +               if(!arg)  return(-EINVAL);
11082 +               err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
11083 +               if(err)
11084 +                       return(err);
11085 +               return(0);
11086 +
11087 +       case HDIO_GET_MULTCOUNT:
11088 +               if(!arg)  return(-EINVAL);
11089 +               err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
11090 +               if(err)
11091 +                       return(err);
11092 +               return(0);
11093 +
11094 +       case HDIO_SET_MULTCOUNT:
11095 +               if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
11096 +               if(MINOR(inode->i_rdev) & 0x3F) return(-EINVAL);
11097 +               return(0);
11098 +
11099 +       case HDIO_GET_IDENTITY:
11100 +               ubd_id.cyls = dev->size / (128 * 32 * hardsect_sizes[minor]);
11101 +               if(copy_to_user((char *) arg, (char *) &ubd_id, 
11102 +                                sizeof(ubd_id)))
11103 +                       return(-EFAULT);
11104 +               return(0);
11105 +               
11106 +       case CDROMVOLREAD:
11107 +               if(copy_from_user(&volume, (char *) arg, sizeof(volume)))
11108 +                       return(-EFAULT);
11109 +               volume.channel0 = 255;
11110 +               volume.channel1 = 255;
11111 +               volume.channel2 = 255;
11112 +               volume.channel3 = 255;
11113 +               if(copy_to_user((char *) arg, &volume, sizeof(volume)))
11114 +                       return(-EFAULT);
11115 +               return(0);
11116 +
11117 +       default:
11118 +               return blk_ioctl(inode->i_rdev, cmd, arg);
11119 +       }
11120 +}
11121 +
11122 +static int ubd_revalidate1(kdev_t rdev)
11123 +{
11124 +       int i, n, offset, err = 0, pcount = 1 << UBD_SHIFT;
11125 +       struct ubd *dev;
11126 +       struct hd_struct *part;
11127 +
11128 +       n = DEVICE_NR(rdev);
11129 +       offset = n << UBD_SHIFT;
11130 +       dev = &ubd_dev[n];
11131 +
11132 +       part = &ubd_part[offset];
11133 +
11134 +       /* clear all old partition counts */
11135 +       for(i = 1; i < pcount; i++) {
11136 +               part[i].start_sect = 0;
11137 +               part[i].nr_sects = 0;
11138 +       }
11139 +
11140 +       /* If it already has been opened we can check the partitions 
11141 +        * directly 
11142 +        */
11143 +       if(dev->count){
11144 +               part->start_sect = 0;
11145 +               register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount, 
11146 +                             &ubd_blops, part->nr_sects);
11147 +       } 
11148 +       else if(dev->file){
11149 +               err = ubd_open_dev(dev);
11150 +               if(err){
11151 +                       printk(KERN_ERR "unable to open %s for validation\n",
11152 +                              dev->file);
11153 +                       goto out;
11154 +               }
11155 +
11156 +               /* have to recompute sizes since we opened it */
11157 +               err = ubd_file_size(dev, &dev->size);
11158 +               if(err < 0) {
11159 +                       ubd_close(dev);
11160 +                       goto out;
11161 +               }
11162 +               part->start_sect = 0;
11163 +               part->nr_sects = dev->size / hardsect_sizes[offset];
11164 +               register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount, 
11165 +                             &ubd_blops, part->nr_sects);
11166 +
11167 +               /* we are done so close it */
11168 +               ubd_close(dev);
11169 +       } 
11170 +       else err = -ENODEV;
11171 + out:
11172 +       return(err);
11173 +}
11174 +
11175 +static int ubd_revalidate(kdev_t rdev)
11176 +{
11177 +       int err;
11178 +
11179 +       spin_lock(&ubd_lock);
11180 +       err = ubd_revalidate1(rdev);
11181 +       spin_unlock(&ubd_lock);
11182 +       return(err);
11183 +}
11184 +
11185 +static int ubd_check_remapped(int fd, unsigned long address, int is_write,
11186 +                             __u64 offset)
11187 +{
11188 +       __u64 bitmap_offset;
11189 +       unsigned long new_bitmap[2];
11190 +       int i, err, n;
11191 +
11192 +       /* If it's not a write access, we can't do anything about it */
11193 +       if(!is_write)
11194 +               return(0);
11195 +
11196 +       /* We have a write */
11197 +       for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
11198 +               struct ubd *dev = &ubd_dev[i];
11199 +
11200 +               if((dev->fd != fd) && (dev->cow.fd != fd))
11201 +                       continue;
11202 +
11203 +               /* It's a write to a ubd device */
11204 +
11205 +               if(!dev->openflags.w){
11206 +                       /* It's a write access on a read-only device - probably
11207 +                        * shouldn't happen.  If the kernel is trying to change
11208 +                        * something with no intention of writing it back out,
11209 +                        * then this message will clue us in that this needs
11210 +                        * fixing
11211 +                        */
11212 +                       printk("Write access to mapped page from readonly ubd "
11213 +                              "device %d\n", i);
11214 +                       return(0);
11215 +               }
11216 +
11217 +               /* It's a write to a writeable ubd device - it must be COWed
11218 +                * because, otherwise, the page would have been mapped in 
11219 +                * writeable
11220 +                */
11221 +
11222 +               if(!dev->cow.file)
11223 +                       panic("Write fault on writeable non-COW ubd device %d",
11224 +                             i);
11225 +
11226 +               /* It should also be an access to the backing file since the 
11227 +                * COW pages should be mapped in read-write
11228 +                */
11229 +
11230 +               if(fd == dev->fd)
11231 +                       panic("Write fault on a backing page of ubd "
11232 +                             "device %d\n", i);
11233 +
11234 +               /* So, we do the write, copying the backing data to the COW 
11235 +                * file... 
11236 +                */
11237 +
11238 +               err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
11239 +               if(err < 0)
11240 +                       panic("Couldn't seek to %lld in COW file of ubd "
11241 +                             "device %d, err = %d", 
11242 +                             offset + dev->cow.data_offset, i, -err);
11243 +
11244 +               n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
11245 +               if(n != PAGE_SIZE)
11246 +                       panic("Couldn't copy data to COW file of ubd "
11247 +                             "device %d, err = %d", i, -n);
11248 +
11249 +               /* ... updating the COW bitmap... */
11250 +
11251 +               cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset, 
11252 +                             dev->cow.bitmap, dev->cow.bitmap_offset, 
11253 +                             new_bitmap, dev->cow.bitmap_len);
11254 +
11255 +               err = os_seek_file(dev->fd, bitmap_offset);
11256 +               if(err < 0)
11257 +                       panic("Couldn't seek to %lld in COW file of ubd "
11258 +                             "device %d, err = %d", bitmap_offset, i, -err);
11259 +
11260 +               n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
11261 +               if(n != sizeof(new_bitmap))
11262 +                       panic("Couldn't update bitmap  of ubd device %d, "
11263 +                             "err = %d", i, -n);
11264 +               
11265 +               /* Maybe we can map the COW page in, and maybe we can't.  If
11266 +                * it is a pre-V3 COW file, we can't, since the alignment will 
11267 +                * be wrong.  If it is a V3 or later COW file which has been 
11268 +                * moved to a system with a larger page size, then maybe we 
11269 +                * can't, depending on the exact location of the page.
11270 +                */
11271 +
11272 +               offset += dev->cow.data_offset;
11273 +
11274 +               /* Remove the remapping, putting the original anonymous page
11275 +                * back.  If the COW file can be mapped in, that is done.
11276 +                * Otherwise, the COW page is read in.
11277 +                */
11278 +
11279 +               if(!physmem_remove_mapping((void *) address))
11280 +                       panic("Address 0x%lx not remapped by ubd device %d", 
11281 +                             address, i);
11282 +               if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
11283 +                       physmem_subst_mapping((void *) address, dev->fd, 
11284 +                                             offset, 1);
11285 +               else {
11286 +                       err = os_seek_file(dev->fd, offset);
11287 +                       if(err < 0)
11288 +                               panic("Couldn't seek to %lld in COW file of "
11289 +                                     "ubd device %d, err = %d", offset, i, 
11290 +                                     -err);
11291 +
11292 +                       n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
11293 +                       if(n != PAGE_SIZE)
11294 +                               panic("Failed to read page from offset %llx of "
11295 +                                     "COW file of ubd device %d, err = %d",
11296 +                                     offset, i, -n);
11297 +               }
11298 +
11299 +               return(1);
11300 +       }
11301 +
11302 +       /* It's not a write on a ubd device */
11303 +       return(0);
11304 +}
11305 +
11306 +static struct remapper ubd_remapper = {
11307 +       .list   = LIST_HEAD_INIT(ubd_remapper.list),
11308 +       .proc   = ubd_check_remapped,
11309 +};
11310 +
11311 +static int ubd_remapper_setup(void)
11312 +{
11313 +       if(ubd_do_mmap)
11314 +               register_remapper(&ubd_remapper);
11315 +
11316 +       return(0);
11317 +}
11318 +
11319 +__initcall(ubd_remapper_setup);
11320 +
11321 +/*
11322 + * Overrides for Emacs so that we follow Linus's tabbing style.
11323 + * Emacs will notice this stuff at the end of the file and automatically
11324 + * adjust the settings for this buffer only.  This must remain at the end
11325 + * of the file.
11326 + * ---------------------------------------------------------------------------
11327 + * Local variables:
11328 + * c-file-style: "linux"
11329 + * End:
11330 + */
11331 diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_user.c um/arch/um/drivers/ubd_user.c
11332 --- orig/arch/um/drivers/ubd_user.c     1969-12-31 19:00:00.000000000 -0500
11333 +++ um/arch/um/drivers/ubd_user.c       2004-01-10 06:24:52.000000000 -0500
11334 @@ -0,0 +1,377 @@
11335 +/* 
11336 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
11337 + * Copyright (C) 2001 Ridgerun,Inc (glonnon@ridgerun.com)
11338 + * Licensed under the GPL
11339 + */
11340 +
11341 +#include <stddef.h>
11342 +#include <unistd.h>
11343 +#include <errno.h>
11344 +#include <sched.h>
11345 +#include <signal.h>
11346 +#include <string.h>
11347 +#include <netinet/in.h>
11348 +#include <sys/time.h>
11349 +#include <sys/socket.h>
11350 +#include <sys/mman.h>
11351 +#include <sys/param.h>
11352 +#include "asm/types.h"
11353 +#include "user_util.h"
11354 +#include "kern_util.h"
11355 +#include "user.h"
11356 +#include "ubd_user.h"
11357 +#include "os.h"
11358 +#include "cow.h"
11359 +
11360 +#include <endian.h>
11361 +#include <byteswap.h>
11362 +
11363 +static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
11364 +{
11365 +       struct uml_stat buf1, buf2;
11366 +       int err;
11367 +
11368 +       if(from_cmdline == NULL) return(1);
11369 +       if(!strcmp(from_cmdline, from_cow)) return(1);
11370 +
11371 +       err = os_stat_file(from_cmdline, &buf1);
11372 +       if(err < 0){
11373 +               printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
11374 +               return(1);
11375 +       }
11376 +       err = os_stat_file(from_cow, &buf2);
11377 +       if(err < 0){
11378 +               printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
11379 +               return(1);
11380 +       }
11381 +       if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
11382 +               return(1);
11383 +
11384 +       printk("Backing file mismatch - \"%s\" requested,\n"
11385 +              "\"%s\" specified in COW header of \"%s\"\n",
11386 +              from_cmdline, from_cow, cow);
11387 +       return(0);
11388 +}
11389 +
11390 +static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
11391 +{
11392 +       unsigned long modtime;
11393 +       long long actual;
11394 +       int err;
11395 +
11396 +       err = os_file_modtime(file, &modtime);
11397 +       if(err < 0){
11398 +               printk("Failed to get modification time of backing file "
11399 +                      "\"%s\", err = %d\n", file, -err);
11400 +               return(err);
11401 +       }
11402 +
11403 +       err = os_file_size(file, &actual);
11404 +       if(err < 0){
11405 +               printk("Failed to get size of backing file \"%s\", "
11406 +                      "err = %d\n", file, -err);
11407 +               return(err);
11408 +       }
11409 +
11410 +       if(actual != size){
11411 +               printk("Size mismatch (%ld vs %ld) of COW header vs backing "
11412 +                      "file\n", size, actual);
11413 +               return(-EINVAL);
11414 +       }
11415 +       if(modtime != mtime){
11416 +               printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
11417 +                      "file\n", mtime, modtime);
11418 +               return(-EINVAL);
11419 +       }
11420 +       return(0);
11421 +}
11422 +
11423 +int read_cow_bitmap(int fd, void *buf, int offset, int len)
11424 +{
11425 +       int err;
11426 +
11427 +       err = os_seek_file(fd, offset);
11428 +       if(err < 0) 
11429 +               return(err);
11430 +
11431 +       err = os_read_file(fd, buf, len);
11432 +       if(err < 0) 
11433 +               return(err);
11434 +
11435 +       return(0);
11436 +}
11437 +
11438 +int open_ubd_file(char *file, struct openflags *openflags, 
11439 +                 char **backing_file_out, int *bitmap_offset_out, 
11440 +                 unsigned long *bitmap_len_out, int *data_offset_out, 
11441 +                 int *create_cow_out)
11442 +{
11443 +       time_t mtime;
11444 +       __u64 size;
11445 +       __u32 version, align;
11446 +       char *backing_file;
11447 +       int fd, err, sectorsize, same, mode = 0644;
11448 +
11449 +       fd = os_open_file(file, *openflags, mode);
11450 +       if(fd < 0){
11451 +               if((fd == -ENOENT) && (create_cow_out != NULL))
11452 +                       *create_cow_out = 1;
11453 +                if(!openflags->w ||
11454 +                   ((errno != EROFS) && (errno != EACCES))) return(-errno);
11455 +               openflags->w = 0;
11456 +               fd = os_open_file(file, *openflags, mode); 
11457 +               if(fd < 0) 
11458 +                       return(fd);
11459 +        }
11460 +
11461 +       err = os_lock_file(fd, openflags->w);
11462 +       if(err < 0){
11463 +               printk("Failed to lock '%s', err = %d\n", file, -err);
11464 +               goto out_close;
11465 +       }
11466 +       
11467 +       if(backing_file_out == NULL) return(fd);
11468 +
11469 +       err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
11470 +                             &size, &sectorsize, &align, bitmap_offset_out);
11471 +       if(err && (*backing_file_out != NULL)){
11472 +               printk("Failed to read COW header from COW file \"%s\", "
11473 +                      "errno = %d\n", file, -err);
11474 +               goto out_close;
11475 +       }
11476 +       if(err) return(fd);
11477 +
11478 +       if(backing_file_out == NULL) return(fd);
11479 +       
11480 +       same = same_backing_files(*backing_file_out, backing_file, file);
11481 +
11482 +       if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
11483 +               printk("Switching backing file to '%s'\n", *backing_file_out);
11484 +               err = write_cow_header(file, fd, *backing_file_out,
11485 +                                      sectorsize, align, &size);
11486 +               if(err){
11487 +                       printk("Switch failed, errno = %d\n", -err);
11488 +                       return(err);
11489 +               }
11490 +       }
11491 +       else {
11492 +               *backing_file_out = backing_file;
11493 +               err = backing_file_mismatch(*backing_file_out, size, mtime);
11494 +               if(err) goto out_close;
11495 +       }
11496 +
11497 +       cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, 
11498 +                 bitmap_len_out, data_offset_out);
11499 +
11500 +        return(fd);
11501 + out_close:
11502 +       os_close_file(fd);
11503 +       return(err);
11504 +}
11505 +
11506 +int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
11507 +                   int sectorsize, int alignment, int *bitmap_offset_out, 
11508 +                   unsigned long *bitmap_len_out, int *data_offset_out)
11509 +{
11510 +       int err, fd;
11511 +
11512 +       flags.c = 1;
11513 +       fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
11514 +       if(fd < 0){
11515 +               err = fd;
11516 +               printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
11517 +                      -err);
11518 +               goto out;
11519 +       }
11520 +
11521 +       err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
11522 +                           bitmap_offset_out, bitmap_len_out, 
11523 +                           data_offset_out);
11524 +       if(!err)
11525 +               return(fd);
11526 +
11527 +       os_close_file(fd);
11528 + out:
11529 +       return(err);
11530 +}
11531 +
11532 +/* XXX Just trivial wrappers around os_read_file and os_write_file */
11533 +int read_ubd_fs(int fd, void *buffer, int len)
11534 +{
11535 +       return(os_read_file(fd, buffer, len));
11536 +}
11537 +
11538 +int write_ubd_fs(int fd, char *buffer, int len)
11539 +{
11540 +       return(os_write_file(fd, buffer, len));
11541 +}
11542 +
11543 +static int update_bitmap(struct io_thread_req *req)
11544 +{
11545 +       int n;
11546 +
11547 +       if(req->cow_offset == -1)
11548 +               return(0);
11549 +
11550 +       n = os_seek_file(req->fds[1], req->cow_offset);
11551 +       if(n < 0){
11552 +               printk("do_io - bitmap lseek failed : err = %d\n", -n);
11553 +               return(1);
11554 +       }
11555 +
11556 +       n = os_write_file(req->fds[1], &req->bitmap_words,
11557 +                         sizeof(req->bitmap_words));
11558 +       if(n != sizeof(req->bitmap_words)){
11559 +               printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
11560 +                      req->fds[1]);
11561 +               return(1);
11562 +       }
11563 +
11564 +       return(0);
11565 +}
11566 +
11567 +void do_io(struct io_thread_req *req)
11568 +{
11569 +       char *buf;
11570 +       unsigned long len;
11571 +       int n, nsectors, start, end, bit;
11572 +       int err;
11573 +       __u64 off;
11574 +
11575 +       if(req->op == UBD_MMAP){
11576 +               /* Touch the page to force the host to do any necessary IO to 
11577 +                * get it into memory 
11578 +                */
11579 +               n = *((volatile int *) req->buffer);
11580 +               req->error = update_bitmap(req);
11581 +               return;
11582 +       }
11583 +
11584 +       nsectors = req->length / req->sectorsize;
11585 +       start = 0;
11586 +       do {
11587 +               bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
11588 +               end = start;
11589 +               while((end < nsectors) && 
11590 +                     (ubd_test_bit(end, (unsigned char *) 
11591 +                                   &req->sector_mask) == bit))
11592 +                       end++;
11593 +
11594 +               off = req->offset + req->offsets[bit] + 
11595 +                       start * req->sectorsize;
11596 +               len = (end - start) * req->sectorsize;
11597 +               buf = &req->buffer[start * req->sectorsize];
11598 +
11599 +               err = os_seek_file(req->fds[bit], off);
11600 +               if(err < 0){
11601 +                       printk("do_io - lseek failed : err = %d\n", -err);
11602 +                       req->error = 1;
11603 +                       return;
11604 +               }
11605 +               if(req->op == UBD_READ){
11606 +                       n = 0;
11607 +                       do {
11608 +                               buf = &buf[n];
11609 +                               len -= n;
11610 +                               n = os_read_file(req->fds[bit], buf, len);
11611 +                               if (n < 0) {
11612 +                                       printk("do_io - read failed, err = %d "
11613 +                                              "fd = %d\n", -n, req->fds[bit]);
11614 +                                       req->error = 1;
11615 +                                       return;
11616 +                               }
11617 +                       } while((n < len) && (n != 0));
11618 +                       if (n < len) memset(&buf[n], 0, len - n);
11619 +               }
11620 +               else {
11621 +                       n = os_write_file(req->fds[bit], buf, len);
11622 +                       if(n != len){
11623 +                               printk("do_io - write failed err = %d "
11624 +                                      "fd = %d\n", -n, req->fds[bit]);
11625 +                               req->error = 1;
11626 +                               return;
11627 +                       }
11628 +               }
11629 +
11630 +               start = end;
11631 +       } while(start < nsectors);
11632 +
11633 +       req->error = update_bitmap(req);
11634 +}
11635 +
11636 +/* Changed in start_io_thread, which is serialized by being called only
11637 + * from ubd_init, which is an initcall.
11638 + */
11639 +int kernel_fd = -1;
11640 +
11641 +/* Only changed by the io thread */
11642 +int io_count = 0;
11643 +
11644 +int io_thread(void *arg)
11645 +{
11646 +       struct io_thread_req req;
11647 +       int n;
11648 +
11649 +       signal(SIGWINCH, SIG_IGN);
11650 +       while(1){
11651 +               n = os_read_file(kernel_fd, &req, sizeof(req));
11652 +               if(n != sizeof(req)){
11653 +                       if(n < 0)
11654 +                               printk("io_thread - read failed, fd = %d, "
11655 +                                      "err = %d\n", kernel_fd, -n);
11656 +                       else {
11657 +                               printk("io_thread - short read, fd = %d, "
11658 +                                      "length = %d\n", kernel_fd, n);
11659 +                       }
11660 +                       continue;
11661 +               }
11662 +               io_count++;
11663 +               do_io(&req);
11664 +               n = os_write_file(kernel_fd, &req, sizeof(req));
11665 +               if(n != sizeof(req))
11666 +                       printk("io_thread - write failed, fd = %d, err = %d\n",
11667 +                              kernel_fd, -n);
11668 +       }
11669 +}
11670 +
11671 +int start_io_thread(unsigned long sp, int *fd_out)
11672 +{
11673 +       int pid, fds[2], err;
11674 +
11675 +       err = os_pipe(fds, 1, 1);
11676 +       if(err < 0){
11677 +               printk("start_io_thread - os_pipe failed, err = %d\n", -err);
11678 +               goto out;
11679 +       }
11680 +
11681 +       kernel_fd = fds[0];
11682 +       *fd_out = fds[1];
11683 +
11684 +       pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
11685 +                   NULL);
11686 +       if(pid < 0){
11687 +               printk("start_io_thread - clone failed : errno = %d\n", errno);
11688 +               goto out_close;
11689 +       }
11690 +
11691 +       return(pid);
11692 +
11693 + out_close:
11694 +       os_close_file(fds[0]);
11695 +       os_close_file(fds[1]);
11696 +       kernel_fd = -1;
11697 +       *fd_out = -1;
11698 + out:
11699 +       return(err);
11700 +}
11701 +
11702 +/*
11703 + * Overrides for Emacs so that we follow Linus's tabbing style.
11704 + * Emacs will notice this stuff at the end of the file and automatically
11705 + * adjust the settings for this buffer only.  This must remain at the end
11706 + * of the file.
11707 + * ---------------------------------------------------------------------------
11708 + * Local variables:
11709 + * c-file-style: "linux"
11710 + * End:
11711 + */
11712 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.c um/arch/um/drivers/xterm.c
11713 --- orig/arch/um/drivers/xterm.c        1969-12-31 19:00:00.000000000 -0500
11714 +++ um/arch/um/drivers/xterm.c  2003-10-21 03:26:06.000000000 -0400
11715 @@ -0,0 +1,201 @@
11716 +/* 
11717 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
11718 + * Licensed under the GPL
11719 + */
11720 +
11721 +#include <stdio.h>
11722 +#include <stdlib.h>
11723 +#include <unistd.h>
11724 +#include <string.h>
11725 +#include <errno.h>
11726 +#include <termios.h>
11727 +#include <signal.h>
11728 +#include <sched.h>
11729 +#include <sys/socket.h>
11730 +#include "kern_util.h"
11731 +#include "chan_user.h"
11732 +#include "helper.h"
11733 +#include "user_util.h"
11734 +#include "user.h"
11735 +#include "os.h"
11736 +#include "xterm.h"
11737 +
11738 +struct xterm_chan {
11739 +       int pid;
11740 +       int helper_pid;
11741 +       char *title;
11742 +       int device;
11743 +       int raw;
11744 +       struct termios tt;
11745 +       unsigned long stack;
11746 +       int direct_rcv;
11747 +};
11748 +
11749 +void *xterm_init(char *str, int device, struct chan_opts *opts)
11750 +{
11751 +       struct xterm_chan *data;
11752 +
11753 +       data = malloc(sizeof(*data));
11754 +       if(data == NULL) return(NULL);
11755 +       *data = ((struct xterm_chan) { .pid             = -1, 
11756 +                                      .helper_pid      = -1,
11757 +                                      .device          = device, 
11758 +                                      .title           = opts->xterm_title,
11759 +                                      .raw             = opts->raw,
11760 +                                      .stack           = opts->tramp_stack,
11761 +                                      .direct_rcv      = !opts->in_kernel } );
11762 +       return(data);
11763 +}
11764 +
11765 +/* Only changed by xterm_setup, which is a setup */
11766 +static char *terminal_emulator = "xterm";
11767 +static char *title_switch = "-T";
11768 +static char *exec_switch = "-e";
11769 +
11770 +static int __init xterm_setup(char *line, int *add)
11771 +{
11772 +       *add = 0;
11773 +       terminal_emulator = line;
11774 +
11775 +       line = strchr(line, ',');
11776 +       if(line == NULL) return(0);
11777 +       *line++ = '\0';
11778 +       if(*line) title_switch = line;
11779 +
11780 +       line = strchr(line, ',');
11781 +       if(line == NULL) return(0);
11782 +       *line++ = '\0';
11783 +       if(*line) exec_switch = line;
11784 +
11785 +       return(0);
11786 +}
11787 +
11788 +__uml_setup("xterm=", xterm_setup,
11789 +"xterm=<terminal emulator>,<title switch>,<exec switch>\n"
11790 +"    Specifies an alternate terminal emulator to use for the debugger,\n"
11791 +"    consoles, and serial lines when they are attached to the xterm channel.\n"
11792 +"    The values are the terminal emulator binary, the switch it uses to set\n"
11793 +"    its title, and the switch it uses to execute a subprocess,\n"
11794 +"    respectively.  The title switch must have the form '<switch> title',\n"
11795 +"    not '<switch>=title'.  Similarly, the exec switch must have the form\n"
11796 +"    '<switch> command arg1 arg2 ...'.\n"
11797 +"    The default values are 'xterm=xterm,-T,-e'.  Values for gnome-terminal\n"
11798 +"    are 'xterm=gnome-terminal,-t,-x'.\n\n"
11799 +);
11800 +
11801 +int xterm_open(int input, int output, int primary, void *d, char **dev_out)
11802 +{
11803 +       struct xterm_chan *data = d;
11804 +       unsigned long stack;
11805 +       int pid, fd, new, err;
11806 +       char title[256], file[] = "/tmp/xterm-pipeXXXXXX";
11807 +       char *argv[] = { terminal_emulator, title_switch, title, exec_switch, 
11808 +                        "/usr/lib/uml/port-helper", "-uml-socket",
11809 +                        file, NULL };
11810 +
11811 +       if(os_access(argv[4], OS_ACC_X_OK) < 0)
11812 +               argv[4] = "port-helper";
11813 +
11814 +       fd = mkstemp(file);
11815 +       if(fd < 0){
11816 +               printk("xterm_open : mkstemp failed, errno = %d\n", errno);
11817 +               return(-errno);
11818 +       }
11819 +
11820 +       if(unlink(file)){
11821 +               printk("xterm_open : unlink failed, errno = %d\n", errno);
11822 +               return(-errno);
11823 +       }
11824 +       os_close_file(fd);
11825 +
11826 +       fd = os_create_unix_socket(file, sizeof(file), 1);
11827 +       if(fd < 0){
11828 +               printk("xterm_open : create_unix_socket failed, errno = %d\n", 
11829 +                      -fd);
11830 +               return(fd);
11831 +       }
11832 +
11833 +       sprintf(title, data->title, data->device);
11834 +       stack = data->stack;
11835 +       pid = run_helper(NULL, NULL, argv, &stack);
11836 +       if(pid < 0){
11837 +               printk("xterm_open : run_helper failed, errno = %d\n", -pid);
11838 +               return(pid);
11839 +       }
11840 +
11841 +       if(data->stack == 0) free_stack(stack, 0);
11842 +
11843 +       if(data->direct_rcv)
11844 +               new = os_rcv_fd(fd, &data->helper_pid);
11845 +       else {
11846 +               err = os_set_fd_block(fd, 0);
11847 +               if(err < 0){
11848 +                       printk("xterm_open : failed to set descriptor "
11849 +                              "non-blocking, err = %d\n", -err);
11850 +                       return(err);
11851 +               }
11852 +               new = xterm_fd(fd, &data->helper_pid);
11853 +       }
11854 +       if(new < 0){
11855 +               printk("xterm_open : os_rcv_fd failed, err = %d\n", -new);
11856 +               goto out;
11857 +       }
11858 +
11859 +       tcgetattr(new, &data->tt);
11860 +       if(data->raw) raw(new, 0);
11861 +
11862 +       data->pid = pid;
11863 +       *dev_out = NULL;
11864 + out:
11865 +       unlink(file);
11866 +       return(new);
11867 +}
11868 +
11869 +void xterm_close(int fd, void *d)
11870 +{
11871 +       struct xterm_chan *data = d;
11872 +       
11873 +       if(data->pid != -1) 
11874 +               os_kill_process(data->pid, 1);
11875 +       data->pid = -1;
11876 +       if(data->helper_pid != -1) 
11877 +               os_kill_process(data->helper_pid, 0);
11878 +       data->helper_pid = -1;
11879 +       os_close_file(fd);
11880 +}
11881 +
11882 +void xterm_free(void *d)
11883 +{
11884 +       free(d);
11885 +}
11886 +
11887 +int xterm_console_write(int fd, const char *buf, int n, void *d)
11888 +{
11889 +       struct xterm_chan *data = d;
11890 +
11891 +       return(generic_console_write(fd, buf, n, &data->tt));
11892 +}
11893 +
11894 +struct chan_ops xterm_ops = {
11895 +       .type           = "xterm",
11896 +       .init           = xterm_init,
11897 +       .open           = xterm_open,
11898 +       .close          = xterm_close,
11899 +       .read           = generic_read,
11900 +       .write          = generic_write,
11901 +       .console_write  = xterm_console_write,
11902 +       .window_size    = generic_window_size,
11903 +       .free           = xterm_free,
11904 +       .winch          = 1,
11905 +};
11906 +
11907 +/*
11908 + * Overrides for Emacs so that we follow Linus's tabbing style.
11909 + * Emacs will notice this stuff at the end of the file and automatically
11910 + * adjust the settings for this buffer only.  This must remain at the end
11911 + * of the file.
11912 + * ---------------------------------------------------------------------------
11913 + * Local variables:
11914 + * c-file-style: "linux"
11915 + * End:
11916 + */
11917 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.h um/arch/um/drivers/xterm.h
11918 --- orig/arch/um/drivers/xterm.h        1969-12-31 19:00:00.000000000 -0500
11919 +++ um/arch/um/drivers/xterm.h  2003-10-21 03:26:06.000000000 -0400
11920 @@ -0,0 +1,22 @@
11921 +/* 
11922 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
11923 + * Licensed under the GPL
11924 + */
11925 +
11926 +#ifndef __XTERM_H__
11927 +#define __XTERM_H__
11928 +
11929 +extern int xterm_fd(int socket, int *pid_out);
11930 +
11931 +#endif
11932 +
11933 +/*
11934 + * Overrides for Emacs so that we follow Linus's tabbing style.
11935 + * Emacs will notice this stuff at the end of the file and automatically
11936 + * adjust the settings for this buffer only.  This must remain at the end
11937 + * of the file.
11938 + * ---------------------------------------------------------------------------
11939 + * Local variables:
11940 + * c-file-style: "linux"
11941 + * End:
11942 + */
11943 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm_kern.c um/arch/um/drivers/xterm_kern.c
11944 --- orig/arch/um/drivers/xterm_kern.c   1969-12-31 19:00:00.000000000 -0500
11945 +++ um/arch/um/drivers/xterm_kern.c     2003-10-21 03:26:06.000000000 -0400
11946 @@ -0,0 +1,82 @@
11947 +/* 
11948 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
11949 + * Licensed under the GPL
11950 + */
11951 +
11952 +#include "linux/errno.h"
11953 +#include "linux/slab.h"
11954 +#include "asm/semaphore.h"
11955 +#include "asm/irq.h"
11956 +#include "irq_user.h"
11957 +#include "irq_kern.h"
11958 +#include "kern_util.h"
11959 +#include "os.h"
11960 +#include "xterm.h"
11961 +
11962 +struct xterm_wait {
11963 +       struct semaphore sem;
11964 +       int fd;
11965 +       int pid;
11966 +       int new_fd;
11967 +};
11968 +
11969 +static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
11970 +{
11971 +       struct xterm_wait *xterm = data;
11972 +       int fd;
11973 +
11974 +       fd = os_rcv_fd(xterm->fd, &xterm->pid);
11975 +       if(fd == -EAGAIN)
11976 +               return;
11977 +
11978 +       xterm->new_fd = fd;
11979 +       up(&xterm->sem);
11980 +}
11981 +
11982 +int xterm_fd(int socket, int *pid_out)
11983 +{
11984 +       struct xterm_wait *data;
11985 +       int err, ret;
11986 +
11987 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
11988 +       if(data == NULL){
11989 +               printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
11990 +               return(-ENOMEM);
11991 +       }
11992 +       *data = ((struct xterm_wait) 
11993 +               { .sem          = __SEMAPHORE_INITIALIZER(data->sem, 0),
11994 +                 .fd           = socket,
11995 +                 .pid          = -1,
11996 +                 .new_fd       = -1 });
11997 +
11998 +       err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, 
11999 +                            SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
12000 +                            "xterm", data);
12001 +       if(err){
12002 +               printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
12003 +                      "err = %d\n",  err);
12004 +               ret = err;
12005 +               goto out;
12006 +       }
12007 +       down(&data->sem);
12008 +
12009 +       free_irq(XTERM_IRQ, data);
12010 +
12011 +       ret = data->new_fd;
12012 +       *pid_out = data->pid;
12013 + out:
12014 +       kfree(data);
12015 +
12016 +       return(ret);
12017 +}
12018 +
12019 +/*
12020 + * Overrides for Emacs so that we follow Linus's tabbing style.
12021 + * Emacs will notice this stuff at the end of the file and automatically
12022 + * adjust the settings for this buffer only.  This must remain at the end
12023 + * of the file.
12024 + * ---------------------------------------------------------------------------
12025 + * Local variables:
12026 + * c-file-style: "linux"
12027 + * End:
12028 + */
12029 diff -Naur -X ../exclude-files orig/arch/um/dyn_link.ld.in um/arch/um/dyn_link.ld.in
12030 --- orig/arch/um/dyn_link.ld.in 1969-12-31 19:00:00.000000000 -0500
12031 +++ um/arch/um/dyn_link.ld.in   2004-01-10 04:28:44.000000000 -0500
12032 @@ -0,0 +1,171 @@
12033 +OUTPUT_FORMAT("ELF_FORMAT")
12034 +OUTPUT_ARCH(ELF_ARCH)
12035 +ENTRY(_start)
12036 +SEARCH_DIR("/usr/local/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
12037 +/* Do we need any of these for elf?
12038 +   __DYNAMIC = 0;    */
12039 +SECTIONS
12040 +{
12041 +  . = START() + SIZEOF_HEADERS;
12042 +  .interp         : { *(.interp) }
12043 +  __binary_start = .;
12044 +  . = ALIGN(4096);             /* Init code and data */
12045 +  _stext = .;
12046 +  __init_begin = .;
12047 +  .text.init : { *(.text.init) }
12048 +
12049 +  . = ALIGN(4096);
12050 +
12051 +  /* Read-only sections, merged into text segment: */
12052 +  .hash           : { *(.hash) }
12053 +  .dynsym         : { *(.dynsym) }
12054 +  .dynstr         : { *(.dynstr) }
12055 +  .gnu.version    : { *(.gnu.version) }
12056 +  .gnu.version_d  : { *(.gnu.version_d) }
12057 +  .gnu.version_r  : { *(.gnu.version_r) }
12058 +  .rel.init       : { *(.rel.init) }
12059 +  .rela.init      : { *(.rela.init) }
12060 +  .rel.text       : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
12061 +  .rela.text      : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
12062 +  .rel.fini       : { *(.rel.fini) }
12063 +  .rela.fini      : { *(.rela.fini) }
12064 +  .rel.rodata     : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
12065 +  .rela.rodata    : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
12066 +  .rel.data       : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
12067 +  .rela.data      : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
12068 +  .rel.tdata     : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
12069 +  .rela.tdata    : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
12070 +  .rel.tbss      : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
12071 +  .rela.tbss     : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
12072 +  .rel.ctors      : { *(.rel.ctors) }
12073 +  .rela.ctors     : { *(.rela.ctors) }
12074 +  .rel.dtors      : { *(.rel.dtors) }
12075 +  .rela.dtors     : { *(.rela.dtors) }
12076 +  .rel.got        : { *(.rel.got) }
12077 +  .rela.got       : { *(.rela.got) }
12078 +  .rel.bss        : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
12079 +  .rela.bss       : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
12080 +  .rel.plt        : { *(.rel.plt) }
12081 +  .rela.plt       : { *(.rela.plt) }
12082 +  .init           : {
12083 +    KEEP (*(.init))
12084 +  } =0x90909090
12085 +  .plt            : { *(.plt) }
12086 +  .text           : {
12087 +    *(.text .stub .text.* .gnu.linkonce.t.*)
12088 +    /* .gnu.warning sections are handled specially by elf32.em.  */
12089 +    *(.gnu.warning)
12090 +  } =0x90909090
12091 +  .fini           : {
12092 +    KEEP (*(.fini))
12093 +  } =0x90909090
12094 +
12095 +  PROVIDE (__etext = .);
12096 +  PROVIDE (_etext = .);
12097 +  PROVIDE (etext = .);
12098 +  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
12099 +  .rodata1        : { *(.rodata1) }
12100 +  .eh_frame_hdr : { *(.eh_frame_hdr) }
12101 +
12102 +
12103 +  . = ALIGN(4096);
12104 +  PROVIDE (_sdata = .);
12105 +
12106 +include(`arch/um/common.ld.in')
12107 +
12108 +  /* Ensure the __preinit_array_start label is properly aligned.  We
12109 +     could instead move the label definition inside the section, but
12110 +     the linker would then create the section even if it turns out to
12111 +     be empty, which isn't pretty.  */
12112 +  . = ALIGN(32 / 8);
12113 +  .preinit_array     : { *(.preinit_array) }
12114 +  .init_array     : { *(.init_array) }
12115 +  .fini_array     : { *(.fini_array) }
12116 +  .data           : {
12117 +    . = ALIGN(KERNEL_STACK_SIZE);              /* init_task */
12118 +    *(.data.init_task)
12119 +    *(.data .data.* .gnu.linkonce.d.*)
12120 +    SORT(CONSTRUCTORS)
12121 +  }
12122 +  .data1          : { *(.data1) }
12123 +  .tdata         : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
12124 +  .tbss                  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
12125 +  .eh_frame       : { KEEP (*(.eh_frame)) }
12126 +  .gcc_except_table   : { *(.gcc_except_table) }
12127 +  .dynamic        : { *(.dynamic) }
12128 +  .ctors          : {
12129 +    /* gcc uses crtbegin.o to find the start of
12130 +       the constructors, so we make sure it is
12131 +       first.  Because this is a wildcard, it
12132 +       doesn't matter if the user does not
12133 +       actually link against crtbegin.o; the
12134 +       linker won't look for a file to match a
12135 +       wildcard.  The wildcard also means that it
12136 +       doesn't matter which directory crtbegin.o
12137 +       is in.  */
12138 +    KEEP (*crtbegin.o(.ctors))
12139 +    /* We don't want to include the .ctor section from
12140 +       from the crtend.o file until after the sorted ctors.
12141 +       The .ctor section from the crtend file contains the
12142 +       end of ctors marker and it must be last */
12143 +    KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
12144 +    KEEP (*(SORT(.ctors.*)))
12145 +    KEEP (*(.ctors))
12146 +  }
12147 +  .dtors          : {
12148 +    KEEP (*crtbegin.o(.dtors))
12149 +    KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
12150 +    KEEP (*(SORT(.dtors.*)))
12151 +    KEEP (*(.dtors))
12152 +  }
12153 +  .jcr            : { KEEP (*(.jcr)) }
12154 +  .got            : { *(.got.plt) *(.got) }
12155 +  _edata = .;
12156 +  PROVIDE (edata = .);
12157 +  __bss_start = .;
12158 +  .bss            : {
12159 +   *(.dynbss)
12160 +   *(.bss .bss.* .gnu.linkonce.b.*)
12161 +   *(COMMON)
12162 +   /* Align here to ensure that the .bss section occupies space up to
12163 +      _end.  Align after .bss to ensure correct alignment even if the
12164 +      .bss section disappears because there are no input sections.  */
12165 +   . = ALIGN(32 / 8);
12166 +  . = ALIGN(32 / 8);
12167 +  }
12168 +  _end = .;
12169 +  PROVIDE (end = .);
12170 +   /* Stabs debugging sections.  */
12171 +  .stab          0 : { *(.stab) }
12172 +  .stabstr       0 : { *(.stabstr) }
12173 +  .stab.excl     0 : { *(.stab.excl) }
12174 +  .stab.exclstr  0 : { *(.stab.exclstr) }
12175 +  .stab.index    0 : { *(.stab.index) }
12176 +  .stab.indexstr 0 : { *(.stab.indexstr) }
12177 +  .comment       0 : { *(.comment) }
12178 +  /* DWARF debug sections.
12179 +     Symbols in the DWARF debugging sections are relative to the beginning
12180 +     of the section so we begin them at 0.  */
12181 +  /* DWARF 1 */
12182 +  .debug          0 : { *(.debug) }
12183 +  .line           0 : { *(.line) }
12184 +  /* GNU DWARF 1 extensions */
12185 +  .debug_srcinfo  0 : { *(.debug_srcinfo) }
12186 +  .debug_sfnames  0 : { *(.debug_sfnames) }
12187 +  /* DWARF 1.1 and DWARF 2 */
12188 +  .debug_aranges  0 : { *(.debug_aranges) }
12189 +  .debug_pubnames 0 : { *(.debug_pubnames) }
12190 +  /* DWARF 2 */
12191 +  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
12192 +  .debug_abbrev   0 : { *(.debug_abbrev) }
12193 +  .debug_line     0 : { *(.debug_line) }
12194 +  .debug_frame    0 : { *(.debug_frame) }
12195 +  .debug_str      0 : { *(.debug_str) }
12196 +  .debug_loc      0 : { *(.debug_loc) }
12197 +  .debug_macinfo  0 : { *(.debug_macinfo) }
12198 +  /* SGI/MIPS DWARF 2 extensions */
12199 +  .debug_weaknames 0 : { *(.debug_weaknames) }
12200 +  .debug_funcnames 0 : { *(.debug_funcnames) }
12201 +  .debug_typenames 0 : { *(.debug_typenames) }
12202 +  .debug_varnames  0 : { *(.debug_varnames) }
12203 +}
12204 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs.h um/arch/um/fs/hostfs/hostfs.h
12205 --- orig/arch/um/fs/hostfs/hostfs.h     1969-12-31 19:00:00.000000000 -0500
12206 +++ um/arch/um/fs/hostfs/hostfs.h       2003-12-17 10:52:50.000000000 -0500
12207 @@ -0,0 +1,69 @@
12208 +#ifndef __UM_FS_HOSTFS
12209 +#define __UM_FS_HOSTFS
12210 +
12211 +#include "os.h"
12212 +
12213 +/* These are exactly the same definitions as in fs.h, but the names are 
12214 + * changed so that this file can be included in both kernel and user files.
12215 + */
12216 +
12217 +#define HOSTFS_ATTR_MODE       1
12218 +#define HOSTFS_ATTR_UID        2
12219 +#define HOSTFS_ATTR_GID        4
12220 +#define HOSTFS_ATTR_SIZE       8
12221 +#define HOSTFS_ATTR_ATIME      16
12222 +#define HOSTFS_ATTR_MTIME      32
12223 +#define HOSTFS_ATTR_CTIME      64
12224 +#define HOSTFS_ATTR_ATIME_SET  128
12225 +#define HOSTFS_ATTR_MTIME_SET  256
12226 +#define HOSTFS_ATTR_FORCE      512     /* Not a change, but a change it */
12227 +#define HOSTFS_ATTR_ATTR_FLAG  1024
12228 +
12229 +struct hostfs_iattr {
12230 +       unsigned int    ia_valid;
12231 +       mode_t          ia_mode;
12232 +       uid_t           ia_uid;
12233 +       gid_t           ia_gid;
12234 +       loff_t          ia_size;
12235 +       time_t          ia_atime;
12236 +       time_t          ia_mtime;
12237 +       time_t          ia_ctime;
12238 +       unsigned int    ia_attr_flags;
12239 +};
12240 +
12241 +extern int stat_file(const char *path, int *dev_out, 
12242 +                    unsigned long long *inode_out, int *mode_out, 
12243 +                    int *nlink_out, int *uid_out, int *gid_out, 
12244 +                    unsigned long long *size_out, unsigned long *atime_out, 
12245 +                    unsigned long *mtime_out, unsigned long *ctime_out, 
12246 +                    int *blksize_out, unsigned long long *blocks_out);
12247 +extern int access_file(char *path, int r, int w, int x);
12248 +extern int open_file(char *path, int r, int w, int append);
12249 +extern int file_type(const char *path, int *rdev);
12250 +extern void *open_dir(char *path, int *err_out);
12251 +extern char *read_dir(void *stream, unsigned long long *pos, 
12252 +                     unsigned long long *ino_out, int *len_out);
12253 +extern void close_file(void *stream);
12254 +extern void close_dir(void *stream);
12255 +extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
12256 +extern int write_file(int fd, unsigned long long *offset, const char *buf,
12257 +                     int len);
12258 +extern int lseek_file(int fd, long long offset, int whence);
12259 +extern int file_create(char *name, int ur, int uw, int ux, int gr, 
12260 +                      int gw, int gx, int or, int ow, int ox);
12261 +extern int set_attr(const char *file, struct hostfs_iattr *attrs);
12262 +extern int make_symlink(const char *from, const char *to);
12263 +extern int unlink_file(const char *file);
12264 +extern int do_mkdir(const char *file, int mode);
12265 +extern int do_rmdir(const char *file);
12266 +extern int do_mknod(const char *file, int mode, int dev);
12267 +extern int link_file(const char *from, const char *to);
12268 +extern int do_readlink(char *file, char *buf, int size);
12269 +extern int rename_file(char *from, char *to);
12270 +extern int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
12271 +                    long long *bfree_out, long long *bavail_out, 
12272 +                    long long *files_out, long long *ffree_out, 
12273 +                    void *fsid_out, int fsid_size, long *namelen_out, 
12274 +                    long *spare_out);
12275 +
12276 +#endif
12277 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_kern.c um/arch/um/fs/hostfs/hostfs_kern.c
12278 --- orig/arch/um/fs/hostfs/hostfs_kern.c        1969-12-31 19:00:00.000000000 -0500
12279 +++ um/arch/um/fs/hostfs/hostfs_kern.c  2003-10-21 03:26:06.000000000 -0400
12280 @@ -0,0 +1,965 @@
12281 +/* 
12282 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
12283 + * Licensed under the GPL
12284 + */
12285 +
12286 +#include <linux/stddef.h>
12287 +#include <linux/fs.h>
12288 +#include <linux/version.h>
12289 +#include <linux/module.h>
12290 +#include <linux/init.h>
12291 +#include <linux/slab.h>
12292 +#include <linux/pagemap.h>
12293 +#include <linux/blkdev.h>
12294 +#include <asm/uaccess.h>
12295 +#include "hostfs.h"
12296 +#include "kern_util.h"
12297 +#include "kern.h"
12298 +#include "user_util.h"
12299 +#include "2_5compat.h"
12300 +#include "init.h"
12301 +
12302 +#define file_hostfs_i(file) (&(file)->f_dentry->d_inode->u.hostfs_i)
12303 +
12304 +int hostfs_d_delete(struct dentry *dentry)
12305 +{
12306 +       return(1);
12307 +}
12308 +
12309 +struct dentry_operations hostfs_dentry_ops = {
12310 +       .d_delete               = hostfs_d_delete,
12311 +};
12312 +
12313 +#define DEFAULT_ROOT "/"
12314 +
12315 +/* Changed in hostfs_args before the kernel starts running */
12316 +static char *jail_dir = NULL;
12317 +static int append = 0;
12318 +
12319 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
12320 +
12321 +static struct inode_operations hostfs_iops;
12322 +static struct inode_operations hostfs_dir_iops;
12323 +static struct address_space_operations hostfs_link_aops;
12324 +
12325 +static int __init hostfs_args(char *options, int *add)
12326 +{
12327 +       char *ptr;
12328 +
12329 +       ptr = strchr(options, ',');
12330 +       if(ptr != NULL)
12331 +               *ptr++ = '\0';
12332 +       if(*options != '\0')
12333 +               jail_dir = options;
12334 +
12335 +       options = ptr;
12336 +       while(options){
12337 +               ptr = strchr(options, ',');
12338 +               if(ptr != NULL)
12339 +                       *ptr++ = '\0';
12340 +               if(*options != '\0'){
12341 +                       if(!strcmp(options, "append"))
12342 +                               append = 1;
12343 +                       else printf("hostfs_args - unsupported option - %s\n",
12344 +                                   options);
12345 +               }
12346 +               options = ptr;
12347 +       }
12348 +       return(0);
12349 +}
12350 +
12351 +__uml_setup("hostfs=", hostfs_args,
12352 +"hostfs=<root dir>,<flags>,...\n"
12353 +"    This is used to set hostfs parameters.  The root directory argument\n"
12354 +"    is used to confine all hostfs mounts to within the specified directory\n"
12355 +"    tree on the host.  If this isn't specified, then a user inside UML can\n"
12356 +"    mount anything on the host that's accessible to the user that's running\n"
12357 +"    it.\n"
12358 +"    The only flag currently supported is 'append', which specifies that all\n"
12359 +"    files opened by hostfs will be opened in append mode.\n\n"
12360 +);
12361 +
12362 +static char *dentry_name(struct dentry *dentry, int extra)
12363 +{
12364 +       struct dentry *parent;
12365 +       char *root, *name;
12366 +       int len;
12367 +
12368 +       len = 0;
12369 +       parent = dentry;
12370 +       while(parent->d_parent != parent){
12371 +               len += parent->d_name.len + 1;
12372 +               parent = parent->d_parent;
12373 +       }
12374 +       
12375 +       root = parent->d_inode->u.hostfs_i.host_filename;
12376 +       len += strlen(root);
12377 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
12378 +       if(name == NULL) return(NULL);
12379 +
12380 +       name[len] = '\0';
12381 +       parent = dentry;
12382 +       while(parent->d_parent != parent){
12383 +               len -= parent->d_name.len + 1;
12384 +               name[len] = '/';
12385 +               strncpy(&name[len + 1], parent->d_name.name, 
12386 +                       parent->d_name.len);
12387 +               parent = parent->d_parent;
12388 +       }
12389 +       strncpy(name, root, strlen(root));
12390 +       return(name);
12391 +}
12392 +
12393 +static char *inode_name(struct inode *ino, int extra)
12394 +{
12395 +       struct dentry *dentry;
12396 +
12397 +       dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
12398 +       return(dentry_name(dentry, extra));
12399 +}
12400 +
12401 +static int read_name(struct inode *ino, char *name)
12402 +{
12403 +       /* The non-int inode fields are copied into ints by stat_file and
12404 +        * then copied into the inode because passing the actual pointers
12405 +        * in and having them treated as int * breaks on big-endian machines
12406 +        */
12407 +       int err;
12408 +       int i_dev, i_mode, i_nlink, i_blksize;
12409 +       unsigned long long i_size;
12410 +       unsigned long long i_ino;
12411 +       unsigned long long i_blocks;
12412 +       err = stat_file(name, &i_dev, &i_ino, &i_mode, &i_nlink, 
12413 +                       &ino->i_uid, &ino->i_gid, &i_size, &ino->i_atime, 
12414 +                       &ino->i_mtime, &ino->i_ctime, &i_blksize, &i_blocks);
12415 +       if(err) return(err);
12416 +       ino->i_ino = i_ino;
12417 +       ino->i_dev = i_dev;
12418 +       ino->i_mode = i_mode;
12419 +       ino->i_nlink = i_nlink;
12420 +       ino->i_size = i_size;
12421 +       ino->i_blksize = i_blksize;
12422 +       ino->i_blocks = i_blocks;
12423 +       if(kdev_same(ino->i_sb->s_dev, ROOT_DEV) && (ino->i_uid == getuid()))
12424 +               ino->i_uid = 0;
12425 +       return(0);
12426 +}
12427 +
12428 +static char *follow_link(char *link)
12429 +{
12430 +       int len, n;
12431 +       char *name, *resolved, *end;
12432 +
12433 +       len = 64;
12434 +       while(1){
12435 +               n = -ENOMEM;
12436 +               name = kmalloc(len, GFP_KERNEL);
12437 +               if(name == NULL)
12438 +                       goto out;
12439 +
12440 +               n = do_readlink(link, name, len);
12441 +               if(n < len)
12442 +                       break;
12443 +               len *= 2;
12444 +               kfree(name);
12445 +       }
12446 +       if(n < 0)
12447 +               goto out_free;
12448 +
12449 +       if(*name == '/')
12450 +               return(name);
12451 +
12452 +       end = strrchr(link, '/');
12453 +       if(end == NULL)
12454 +               return(name);
12455 +
12456 +       *(end + 1) = '\0';
12457 +       len = strlen(link) + strlen(name) + 1;
12458 +
12459 +       resolved = kmalloc(len, GFP_KERNEL);
12460 +       if(resolved == NULL){
12461 +               n = -ENOMEM;
12462 +               goto out_free;
12463 +       }
12464 +
12465 +       sprintf(resolved, "%s%s", link, name);
12466 +       kfree(name);
12467 +       kfree(link);
12468 +       return(resolved);
12469 +
12470 + out_free:
12471 +       kfree(name);
12472 + out:
12473 +       return(ERR_PTR(n));
12474 +}
12475 +
12476 +static int read_inode(struct inode *ino)
12477 +{
12478 +       char *name;
12479 +       int err;
12480 +
12481 +       err = -ENOMEM;
12482 +       name = inode_name(ino, 0);
12483 +       if(name == NULL) 
12484 +               goto out;
12485 +
12486 +       if(file_type(name, NULL) == OS_TYPE_SYMLINK){
12487 +               name = follow_link(name);
12488 +               if(IS_ERR(name)){
12489 +                       err = PTR_ERR(name);
12490 +                       goto out;
12491 +               }
12492 +       }
12493 +       
12494 +       err = read_name(ino, name);
12495 +       kfree(name);
12496 + out:
12497 +       return(err);
12498 +}
12499 +
12500 +void hostfs_delete_inode(struct inode *ino)
12501 +{
12502 +       if(ino->u.hostfs_i.host_filename) 
12503 +               kfree(ino->u.hostfs_i.host_filename);
12504 +       ino->u.hostfs_i.host_filename = NULL;
12505 +
12506 +       if(ino->u.hostfs_i.fd != -1) 
12507 +               close_file(&ino->u.hostfs_i.fd);
12508 +
12509 +       ino->u.hostfs_i.mode = 0;
12510 +       clear_inode(ino);
12511 +}
12512 +
12513 +int hostfs_statfs(struct super_block *sb, struct statfs *sf)
12514 +{
12515 +       /* do_statfs uses struct statfs64 internally, but the linux kernel
12516 +        * struct statfs still has 32-bit versions for most of these fields,
12517 +        * so we convert them here
12518 +        */
12519 +       int err;
12520 +       long long f_blocks;
12521 +       long long f_bfree;
12522 +       long long f_bavail;
12523 +       long long f_files;
12524 +       long long f_ffree;
12525 +
12526 +       err = do_statfs(sb->s_root->d_inode->u.hostfs_i.host_filename,
12527 +                       &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
12528 +                       &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), 
12529 +                       &sf->f_namelen, sf->f_spare);
12530 +       if(err) return(err);
12531 +       sf->f_blocks = f_blocks;
12532 +       sf->f_bfree = f_bfree;
12533 +       sf->f_bavail = f_bavail;
12534 +       sf->f_files = f_files;
12535 +       sf->f_ffree = f_ffree;
12536 +       sf->f_type = HOSTFS_SUPER_MAGIC;
12537 +       return(0);
12538 +}
12539 +
12540 +static struct super_operations hostfs_sbops = { 
12541 +       .put_inode      = force_delete,
12542 +       .delete_inode   = hostfs_delete_inode,
12543 +       .statfs         = hostfs_statfs,
12544 +};
12545 +
12546 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
12547 +{
12548 +       void *dir;
12549 +       char *name;
12550 +       unsigned long long next, ino;
12551 +       int error, len;
12552 +
12553 +       name = dentry_name(file->f_dentry, 0);
12554 +       if(name == NULL) return(-ENOMEM);
12555 +       dir = open_dir(name, &error);
12556 +       kfree(name);
12557 +       if(dir == NULL) return(-error);
12558 +       next = file->f_pos;
12559 +       while((name = read_dir(dir, &next, &ino, &len)) != NULL){
12560 +               error = (*filldir)(ent, name, len, file->f_pos, 
12561 +                                  ino, DT_UNKNOWN);
12562 +               if(error) break;
12563 +               file->f_pos = next;
12564 +       }
12565 +       close_dir(dir);
12566 +       return(0);
12567 +}
12568 +
12569 +int hostfs_file_open(struct inode *ino, struct file *file)
12570 +{
12571 +       char *name;
12572 +       int mode = 0, r = 0, w = 0, fd;
12573 +
12574 +       mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
12575 +       if((mode & ino->u.hostfs_i.mode) == mode)
12576 +               return(0);
12577 +
12578 +       /* The file may already have been opened, but with the wrong access,
12579 +        * so this resets things and reopens the file with the new access.
12580 +        */
12581 +       if(ino->u.hostfs_i.fd != -1){
12582 +               close_file(&ino->u.hostfs_i.fd);
12583 +               ino->u.hostfs_i.fd = -1;
12584 +       }
12585 +
12586 +       ino->u.hostfs_i.mode |= mode;
12587 +       if(ino->u.hostfs_i.mode & FMODE_READ) 
12588 +               r = 1;
12589 +       if(ino->u.hostfs_i.mode & FMODE_WRITE) 
12590 +               w = 1;
12591 +       if(w) 
12592 +               r = 1;
12593 +
12594 +       name = dentry_name(file->f_dentry, 0);
12595 +       if(name == NULL) 
12596 +               return(-ENOMEM);
12597 +
12598 +       fd = open_file(name, r, w, append);
12599 +       kfree(name);
12600 +       if(fd < 0) return(fd);
12601 +       file_hostfs_i(file)->fd = fd;
12602 +
12603 +       return(0);
12604 +}
12605 +
12606 +int hostfs_dir_open(struct inode *ino, struct file *file)
12607 +{
12608 +       return(0);      
12609 +}
12610 +
12611 +int hostfs_dir_release(struct inode *ino, struct file *file)
12612 +{
12613 +       return(0);
12614 +}
12615 +
12616 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
12617 +{
12618 +       return(0);
12619 +}
12620 +
12621 +static struct file_operations hostfs_file_fops = {
12622 +       .owner          = NULL,
12623 +       .read           = generic_file_read,
12624 +       .write          = generic_file_write,
12625 +       .mmap           = generic_file_mmap,
12626 +       .open           = hostfs_file_open,
12627 +       .release        = NULL,
12628 +       .fsync          = hostfs_fsync,
12629 +};
12630 +
12631 +static struct file_operations hostfs_dir_fops = {
12632 +       .owner          = NULL,
12633 +       .readdir        = hostfs_readdir,
12634 +       .open           = hostfs_dir_open,
12635 +       .release        = hostfs_dir_release,
12636 +       .fsync          = hostfs_fsync,
12637 +};
12638 +
12639 +int hostfs_writepage(struct page *page)
12640 +{
12641 +       struct address_space *mapping = page->mapping;
12642 +       struct inode *inode = mapping->host;
12643 +       char *buffer;
12644 +       unsigned long long base;
12645 +       int count = PAGE_CACHE_SIZE;
12646 +       int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
12647 +       int err;
12648 +
12649 +       if (page->index >= end_index)
12650 +               count = inode->i_size & (PAGE_CACHE_SIZE-1);
12651 +
12652 +       buffer = kmap(page);
12653 +       base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
12654 +
12655 +       err = write_file(inode->u.hostfs_i.fd, &base, buffer, count);
12656 +       if(err != count){
12657 +               ClearPageUptodate(page);
12658 +               goto out;
12659 +       }
12660 +
12661 +       if (base > inode->i_size)
12662 +               inode->i_size = base;
12663 +
12664 +       if (PageError(page))
12665 +               ClearPageError(page);   
12666 +       err = 0;
12667 +
12668 + out:  
12669 +       kunmap(page);
12670 +
12671 +       UnlockPage(page);
12672 +       return err; 
12673 +}
12674 +
12675 +int hostfs_readpage(struct file *file, struct page *page)
12676 +{
12677 +       char *buffer;
12678 +       long long start;
12679 +       int err = 0;
12680 +
12681 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
12682 +       buffer = kmap(page);
12683 +       err = read_file(file_hostfs_i(file)->fd, &start, buffer,
12684 +                       PAGE_CACHE_SIZE);
12685 +       if(err < 0) goto out;
12686 +
12687 +       memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
12688 +
12689 +       flush_dcache_page(page);
12690 +       SetPageUptodate(page);
12691 +       if (PageError(page)) ClearPageError(page);
12692 +       err = 0;
12693 + out:
12694 +       kunmap(page);
12695 +       UnlockPage(page);
12696 +       return(err);
12697 +}
12698 +
12699 +int hostfs_prepare_write(struct file *file, struct page *page, 
12700 +                        unsigned int from, unsigned int to)
12701 +{
12702 +       char *buffer;
12703 +       long long start, tmp;
12704 +       int err;
12705 +
12706 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
12707 +       buffer = kmap(page);
12708 +       if(from != 0){
12709 +               tmp = start;
12710 +               err = read_file(file_hostfs_i(file)->fd, &tmp, buffer,
12711 +                               from);
12712 +               if(err < 0) goto out;
12713 +       }
12714 +       if(to != PAGE_CACHE_SIZE){
12715 +               start += to;
12716 +               err = read_file(file_hostfs_i(file)->fd, &start, buffer + to,
12717 +                               PAGE_CACHE_SIZE - to);
12718 +               if(err < 0) goto out;           
12719 +       }
12720 +       err = 0;
12721 + out:
12722 +       kunmap(page);
12723 +       return(err);
12724 +}
12725 +
12726 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
12727 +                unsigned to)
12728 +{
12729 +       struct address_space *mapping = page->mapping;
12730 +       struct inode *inode = mapping->host;
12731 +       char *buffer;
12732 +       long long start;
12733 +       int err = 0;
12734 +
12735 +       start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
12736 +       buffer = kmap(page);
12737 +       err = write_file(file_hostfs_i(file)->fd, &start, buffer + from, 
12738 +                        to - from);
12739 +       if(err > 0) err = 0;
12740 +       if(!err && (start > inode->i_size))
12741 +               inode->i_size = start;
12742 +
12743 +       kunmap(page);
12744 +       return(err);
12745 +}
12746 +
12747 +static struct address_space_operations hostfs_aops = {
12748 +       .writepage      = hostfs_writepage,
12749 +       .readpage       = hostfs_readpage,
12750 +/*     .set_page_dirty = __set_page_dirty_nobuffers, */
12751 +       .prepare_write  = hostfs_prepare_write,
12752 +       .commit_write   = hostfs_commit_write
12753 +};
12754 +
12755 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
12756 +                              int *error)
12757 +{
12758 +       struct inode *inode;
12759 +       char *name;
12760 +       int type, err = -ENOMEM, rdev;
12761 +
12762 +       inode = new_inode(sb);
12763 +       if(inode == NULL) 
12764 +               goto out;
12765 +
12766 +       inode->u.hostfs_i.host_filename = NULL;
12767 +       inode->u.hostfs_i.fd = -1;
12768 +       inode->u.hostfs_i.mode = 0;
12769 +       insert_inode_hash(inode);
12770 +       if(dentry){
12771 +               name = dentry_name(dentry, 0);
12772 +               if(name == NULL){
12773 +                       err = -ENOMEM;
12774 +                       goto out_put;
12775 +               }
12776 +               type = file_type(name, &rdev);
12777 +               kfree(name);
12778 +       }
12779 +       else type = OS_TYPE_DIR;
12780 +       inode->i_sb = sb;
12781 +
12782 +       err = 0;
12783 +       if(type == OS_TYPE_SYMLINK)
12784 +               inode->i_op = &page_symlink_inode_operations;
12785 +       else if(type == OS_TYPE_DIR)
12786 +               inode->i_op = &hostfs_dir_iops;
12787 +       else inode->i_op = &hostfs_iops;
12788 +
12789 +       if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
12790 +       else inode->i_fop = &hostfs_file_fops;
12791 +
12792 +       if(type == OS_TYPE_SYMLINK) 
12793 +               inode->i_mapping->a_ops = &hostfs_link_aops;
12794 +       else inode->i_mapping->a_ops = &hostfs_aops;
12795 +
12796 +       switch (type) {
12797 +       case OS_TYPE_CHARDEV:
12798 +               init_special_inode(inode, S_IFCHR, rdev);
12799 +               break;
12800 +       case OS_TYPE_BLOCKDEV:
12801 +               init_special_inode(inode, S_IFBLK, rdev);
12802 +               break;
12803 +       case OS_TYPE_FIFO:
12804 +               init_special_inode(inode, S_IFIFO, 0);
12805 +               break;
12806 +       case OS_TYPE_SOCK:
12807 +               init_special_inode(inode, S_IFSOCK, 0);
12808 +               break;
12809 +       }
12810 +       
12811 +       if(error) *error = err;
12812 +       return(inode);
12813 + out_put:
12814 +       make_bad_inode(inode);
12815 +       iput(inode);
12816 + out:
12817 +       if(error) *error = err;
12818 +       return(NULL);
12819 +}
12820 +
12821 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode)
12822 +{
12823 +       struct inode *inode;
12824 +       char *name;
12825 +       int error, fd;
12826 +
12827 +       inode = get_inode(dir->i_sb, dentry, &error);
12828 +       if(error) return(error);
12829 +       name = dentry_name(dentry, 0);
12830 +       if(name == NULL){
12831 +               iput(inode);
12832 +               return(-ENOMEM);
12833 +       }
12834 +       fd = file_create(name, 
12835 +                        mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, 
12836 +                        mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, 
12837 +                        mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
12838 +       if(fd < 0) 
12839 +               error = fd;
12840 +       else error = read_name(inode, name);
12841 +
12842 +       kfree(name);
12843 +       if(error){
12844 +               iput(inode);
12845 +               return(error);
12846 +       }
12847 +       inode->u.hostfs_i.fd = fd;
12848 +       inode->u.hostfs_i.mode = FMODE_READ | FMODE_WRITE;
12849 +       d_instantiate(dentry, inode);
12850 +       return(0);
12851 +}
12852
12853 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry)
12854 +{
12855 +       struct inode *inode;
12856 +       char *name;
12857 +       int error;
12858 +
12859 +       inode = get_inode(ino->i_sb, dentry, &error);
12860 +       if(error != 0) return(ERR_PTR(error));
12861 +       name = dentry_name(dentry, 0);
12862 +       if(name == NULL) return(ERR_PTR(-ENOMEM));
12863 +       error = read_name(inode, name);
12864 +       kfree(name);
12865 +       if(error){
12866 +               iput(inode);
12867 +               if(error == -ENOENT) inode = NULL;
12868 +               else return(ERR_PTR(error));
12869 +       }
12870 +       d_add(dentry, inode);
12871 +       dentry->d_op = &hostfs_dentry_ops;
12872 +       return(NULL);
12873 +}
12874 +
12875 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
12876 +{
12877 +        char *file;
12878 +       int len;
12879 +
12880 +       file = inode_name(ino, dentry->d_name.len + 1);
12881 +       if(file == NULL) return(NULL);
12882 +        strcat(file, "/");
12883 +       len = strlen(file);
12884 +        strncat(file, dentry->d_name.name, dentry->d_name.len);
12885 +       file[len + dentry->d_name.len] = '\0';
12886 +        return(file);
12887 +}
12888 +
12889 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
12890 +{
12891 +        char *from_name, *to_name;
12892 +        int err;
12893 +
12894 +        from_name = inode_dentry_name(ino, from); 
12895 +        if(from_name == NULL) 
12896 +                return(-ENOMEM);
12897 +        to_name = dentry_name(to, 0);
12898 +       if(to_name == NULL){
12899 +               kfree(from_name);
12900 +               return(-ENOMEM);
12901 +       }
12902 +        err = link_file(to_name, from_name);
12903 +        kfree(from_name);
12904 +        kfree(to_name);
12905 +        return(err);
12906 +}
12907 +
12908 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
12909 +{
12910 +       char *file;
12911 +       int err;
12912 +
12913 +       file = inode_dentry_name(ino, dentry);
12914 +       if(file == NULL) return(-ENOMEM);
12915 +       if(append)
12916 +               return(-EPERM);
12917 +
12918 +       err = unlink_file(file);
12919 +       kfree(file);
12920 +       return(err);
12921 +}
12922 +
12923 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
12924 +{
12925 +       char *file;
12926 +       int err;
12927 +
12928 +       file = inode_dentry_name(ino, dentry);
12929 +       if(file == NULL) return(-ENOMEM);
12930 +       err = make_symlink(file, to);
12931 +       kfree(file);
12932 +       return(err);
12933 +}
12934 +
12935 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
12936 +{
12937 +       char *file;
12938 +       int err;
12939 +
12940 +       file = inode_dentry_name(ino, dentry);
12941 +       if(file == NULL) return(-ENOMEM);
12942 +       err = do_mkdir(file, mode);
12943 +       kfree(file);
12944 +       return(err);
12945 +}
12946 +
12947 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
12948 +{
12949 +       char *file;
12950 +       int err;
12951 +
12952 +       file = inode_dentry_name(ino, dentry);
12953 +       if(file == NULL) return(-ENOMEM);
12954 +       err = do_rmdir(file);
12955 +       kfree(file);
12956 +       return(err);
12957 +}
12958 +
12959 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
12960 +{
12961 +       struct inode *inode;
12962 +       char *name;
12963 +       int error;
12964
12965 +       inode = get_inode(dir->i_sb, dentry, &error);
12966 +       if(error) return(error);
12967 +       name = dentry_name(dentry, 0);
12968 +       if(name == NULL){
12969 +               iput(inode);
12970 +               return(-ENOMEM);
12971 +       }
12972 +       init_special_inode(inode, mode, dev);
12973 +       error = do_mknod(name, mode, dev);
12974 +       if(!error) error = read_name(inode, name);
12975 +       kfree(name);
12976 +       if(error){
12977 +               iput(inode);
12978 +               return(error);
12979 +       }
12980 +       d_instantiate(dentry, inode);
12981 +       return(0);
12982 +}
12983 +
12984 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
12985 +                 struct inode *to_ino, struct dentry *to)
12986 +{
12987 +       char *from_name, *to_name;
12988 +       int err;
12989 +
12990 +       from_name = inode_dentry_name(from_ino, from);
12991 +       if(from_name == NULL)
12992 +               return(-ENOMEM);
12993 +       to_name = inode_dentry_name(to_ino, to);
12994 +       if(to_name == NULL){
12995 +               kfree(from_name);
12996 +               return(-ENOMEM);
12997 +       }
12998 +       err = rename_file(from_name, to_name);
12999 +       kfree(from_name);
13000 +       kfree(to_name);
13001 +       return(err);
13002 +}
13003 +
13004 +void hostfs_truncate(struct inode *ino)
13005 +{
13006 +       not_implemented();
13007 +}
13008 +
13009 +int hostfs_permission(struct inode *ino, int desired)
13010 +{
13011 +       char *name;
13012 +       int r = 0, w = 0, x = 0, err;
13013 +
13014 +       if(desired & MAY_READ) r = 1;
13015 +       if(desired & MAY_WRITE) w = 1;
13016 +       if(desired & MAY_EXEC) x = 1;
13017 +       name = inode_name(ino, 0);
13018 +       if(name == NULL) return(-ENOMEM);
13019 +       err = access_file(name, r, w, x);
13020 +       kfree(name);
13021 +       if(!err) err = vfs_permission(ino, desired);
13022 +       return(err);
13023 +}
13024 +
13025 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
13026 +{
13027 +       struct hostfs_iattr attrs;
13028 +       char *name;
13029 +       int err;
13030 +       
13031 +       if(append) 
13032 +               attr->ia_valid &= ~ATTR_SIZE;
13033 +
13034 +       attrs.ia_valid = 0;
13035 +       if(attr->ia_valid & ATTR_MODE){
13036 +               attrs.ia_valid |= HOSTFS_ATTR_MODE;
13037 +               attrs.ia_mode = attr->ia_mode;
13038 +       }
13039 +       if(attr->ia_valid & ATTR_UID){
13040 +               if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) && 
13041 +                  (attr->ia_uid == 0))
13042 +                       attr->ia_uid = getuid();
13043 +               attrs.ia_valid |= HOSTFS_ATTR_UID;
13044 +               attrs.ia_uid = attr->ia_uid;
13045 +       }
13046 +       if(attr->ia_valid & ATTR_GID){
13047 +               if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) && 
13048 +                  (attr->ia_gid == 0))
13049 +                       attr->ia_gid = getuid();
13050 +               attrs.ia_valid |= HOSTFS_ATTR_GID;
13051 +               attrs.ia_gid = attr->ia_gid;
13052 +       }
13053 +       if(attr->ia_valid & ATTR_SIZE){
13054 +               attrs.ia_valid |= HOSTFS_ATTR_SIZE;
13055 +               attrs.ia_size = attr->ia_size;
13056 +       }
13057 +       if(attr->ia_valid & ATTR_ATIME){
13058 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME;
13059 +               attrs.ia_atime = attr->ia_atime;
13060 +       }
13061 +       if(attr->ia_valid & ATTR_MTIME){
13062 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME;
13063 +               attrs.ia_mtime = attr->ia_mtime;
13064 +       }
13065 +       if(attr->ia_valid & ATTR_CTIME){
13066 +               attrs.ia_valid |= HOSTFS_ATTR_CTIME;
13067 +               attrs.ia_ctime = attr->ia_ctime;
13068 +       }
13069 +       if(attr->ia_valid & ATTR_ATIME_SET){
13070 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
13071 +       }
13072 +       if(attr->ia_valid & ATTR_MTIME_SET){
13073 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
13074 +       }
13075 +       name = dentry_name(dentry, 0);
13076 +       if(name == NULL) return(-ENOMEM);
13077 +       err = set_attr(name, &attrs);
13078 +       kfree(name);
13079 +       if(err)
13080 +               return(err);
13081 +
13082 +       return(inode_setattr(dentry->d_inode, attr));
13083 +}
13084 +
13085 +int hostfs_getattr(struct dentry *dentry, struct iattr *attr)
13086 +{
13087 +       not_implemented();
13088 +       return(-EINVAL);
13089 +}
13090 +
13091 +static struct inode_operations hostfs_iops = {
13092 +       .create         = hostfs_create,
13093 +       .link           = hostfs_link,
13094 +       .unlink         = hostfs_unlink,
13095 +       .symlink        = hostfs_symlink,
13096 +       .mkdir          = hostfs_mkdir,
13097 +       .rmdir          = hostfs_rmdir,
13098 +       .mknod          = hostfs_mknod,
13099 +       .rename         = hostfs_rename,
13100 +       .truncate       = hostfs_truncate,
13101 +       .permission     = hostfs_permission,
13102 +       .setattr        = hostfs_setattr,
13103 +       .getattr        = hostfs_getattr,
13104 +};
13105 +
13106 +static struct inode_operations hostfs_dir_iops = {
13107 +       .create         = hostfs_create,
13108 +       .lookup         = hostfs_lookup,
13109 +       .link           = hostfs_link,
13110 +       .unlink         = hostfs_unlink,
13111 +       .symlink        = hostfs_symlink,
13112 +       .mkdir          = hostfs_mkdir,
13113 +       .rmdir          = hostfs_rmdir,
13114 +       .mknod          = hostfs_mknod,
13115 +       .rename         = hostfs_rename,
13116 +       .truncate       = hostfs_truncate,
13117 +       .permission     = hostfs_permission,
13118 +       .setattr        = hostfs_setattr,
13119 +       .getattr        = hostfs_getattr,
13120 +};
13121 +
13122 +int hostfs_link_readpage(struct file *file, struct page *page)
13123 +{
13124 +       char *buffer, *name;
13125 +       long long start;
13126 +       int err;
13127 +
13128 +       start = page->index << PAGE_CACHE_SHIFT;
13129 +       buffer = kmap(page);
13130 +       name = inode_name(page->mapping->host, 0);
13131 +       if(name == NULL) return(-ENOMEM);
13132 +       err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
13133 +       kfree(name);
13134 +       if(err == PAGE_CACHE_SIZE)
13135 +               err = -E2BIG;
13136 +       else if(err > 0){
13137 +               flush_dcache_page(page);
13138 +               SetPageUptodate(page);
13139 +               if (PageError(page)) ClearPageError(page);
13140 +               err = 0;
13141 +       }
13142 +       kunmap(page);
13143 +       UnlockPage(page);
13144 +       return(err);
13145 +}
13146 +
13147 +static struct address_space_operations hostfs_link_aops = {
13148 +       .readpage       = hostfs_link_readpage,
13149 +};
13150 +
13151 +static char *get_root(char *mount_arg)
13152 +{
13153 +       char *root, *slash = "";
13154 +       int len = 0;
13155 +
13156 +       if(jail_dir != NULL){
13157 +               len += strlen(jail_dir);
13158 +               if((*jail_dir == '\0') || 
13159 +                  (jail_dir[strlen(jail_dir) - 1] != '/'))
13160 +                       slash = "/";
13161 +               len += strlen(slash);
13162 +       }
13163 +
13164 +       if((mount_arg == NULL) || (*mount_arg == '\0'))
13165 +               mount_arg = DEFAULT_ROOT;
13166 +
13167 +       len += strlen(mount_arg) + 1;
13168 +
13169 +       root = kmalloc(len, GFP_KERNEL);
13170 +       if(root == NULL)
13171 +               return(NULL);
13172 +
13173 +       if(jail_dir != NULL)
13174 +               sprintf(root, "%s%s%s", jail_dir, slash, mount_arg);
13175 +       else
13176 +               strcpy(root, mount_arg);
13177 +
13178 +       return(root);
13179 +}
13180 +
13181 +struct super_block *hostfs_read_super(struct super_block *sb, void *data, 
13182 +                                     int silent)
13183 +{
13184 +       struct inode *root_inode;
13185 +       char *root_dir;
13186 +
13187 +       sb->s_blocksize = 1024;
13188 +       sb->s_blocksize_bits = 10;
13189 +       sb->s_magic = HOSTFS_SUPER_MAGIC;
13190 +       sb->s_op = &hostfs_sbops;
13191 +
13192 +       root_inode = get_inode(sb, NULL, NULL);
13193 +       if(root_inode == NULL)
13194 +               goto out;
13195 +
13196 +       root_dir = get_root(data);
13197 +       if(root_dir == NULL)
13198 +               goto out_put;
13199 +
13200 +       root_inode->u.hostfs_i.host_filename = root_dir;
13201 +       sb->s_root = d_alloc_root(root_inode);
13202 +       if(sb->s_root == NULL)
13203 +               goto out_free;
13204 +
13205 +       if(read_inode(root_inode))
13206 +               goto out_dput;
13207 +       return(sb);
13208 +
13209 + out_dput:
13210 +       dput(sb->s_root);
13211 + out_free:
13212 +       kfree(root_dir);
13213 + out_put:
13214 +       make_bad_inode(root_inode);
13215 +       iput(root_inode);
13216 + out:
13217 +       return(NULL);
13218 +}
13219 +
13220 +DECLARE_FSTYPE(hostfs_type, "hostfs", hostfs_read_super, 0);
13221 +
13222 +static int __init init_hostfs(void)
13223 +{
13224 +       return(register_filesystem(&hostfs_type));
13225 +}
13226 +
13227 +static void __exit exit_hostfs(void)
13228 +{
13229 +       unregister_filesystem(&hostfs_type);
13230 +}
13231 +
13232 +module_init(init_hostfs)
13233 +module_exit(exit_hostfs)
13234 +MODULE_LICENSE("GPL");
13235 +
13236 +/*
13237 + * Overrides for Emacs so that we follow Linus's tabbing style.
13238 + * Emacs will notice this stuff at the end of the file and automatically
13239 + * adjust the settings for this buffer only.  This must remain at the end
13240 + * of the file.
13241 + * ---------------------------------------------------------------------------
13242 + * Local variables:
13243 + * c-file-style: "linux"
13244 + * End:
13245 + */
13246 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_user.c um/arch/um/fs/hostfs/hostfs_user.c
13247 --- orig/arch/um/fs/hostfs/hostfs_user.c        1969-12-31 19:00:00.000000000 -0500
13248 +++ um/arch/um/fs/hostfs/hostfs_user.c  2003-11-14 08:51:20.000000000 -0500
13249 @@ -0,0 +1,359 @@
13250 +/* 
13251 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13252 + * Licensed under the GPL
13253 + */
13254 +
13255 +#include <unistd.h>
13256 +#include <stdio.h>
13257 +#include <fcntl.h>
13258 +#include <dirent.h>
13259 +#include <errno.h>
13260 +#include <utime.h>
13261 +#include <string.h>
13262 +#include <sys/stat.h>
13263 +#include <sys/time.h>
13264 +#include <sys/vfs.h>
13265 +#include "hostfs.h"
13266 +#include "kern_util.h"
13267 +#include "user.h"
13268 +
13269 +int stat_file(const char *path, int *dev_out, unsigned long long *inode_out,
13270 +             int *mode_out, int *nlink_out, int *uid_out, int *gid_out, 
13271 +             unsigned long long *size_out, unsigned long *atime_out,
13272 +             unsigned long *mtime_out, unsigned long *ctime_out,
13273 +             int *blksize_out, unsigned long long *blocks_out)
13274 +{
13275 +       struct stat64 buf;
13276 +
13277 +       if(lstat64(path, &buf) < 0) 
13278 +               return(-errno);
13279 +       if(dev_out != NULL) *dev_out = buf.st_dev;
13280 +
13281 +       /* See the Makefile for why STAT64_INO_FIELD is passed in
13282 +        * by the build
13283 +        */
13284 +       if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
13285 +       if(mode_out != NULL) *mode_out = buf.st_mode;
13286 +       if(nlink_out != NULL) *nlink_out = buf.st_nlink;
13287 +       if(uid_out != NULL) *uid_out = buf.st_uid;
13288 +       if(gid_out != NULL) *gid_out = buf.st_gid;
13289 +       if(size_out != NULL) *size_out = buf.st_size;
13290 +       if(atime_out != NULL) *atime_out = buf.st_atime;
13291 +       if(mtime_out != NULL) *mtime_out = buf.st_mtime;
13292 +       if(ctime_out != NULL) *ctime_out = buf.st_ctime;
13293 +       if(blksize_out != NULL) *blksize_out = buf.st_blksize;
13294 +       if(blocks_out != NULL) *blocks_out = buf.st_blocks;
13295 +       return(0);
13296 +}
13297 +
13298 +int file_type(const char *path, int *rdev)
13299 +{
13300 +       struct stat64 buf;
13301 +
13302 +       if(lstat64(path, &buf) < 0) 
13303 +               return(-errno);
13304 +       if(rdev != NULL) 
13305 +               *rdev = buf.st_rdev;
13306 +
13307 +       if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
13308 +       else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
13309 +       else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
13310 +       else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
13311 +       else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
13312 +       else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
13313 +       else return(OS_TYPE_FILE);
13314 +}
13315 +
13316 +int access_file(char *path, int r, int w, int x)
13317 +{
13318 +       int mode = 0;
13319 +
13320 +       if(r) mode = R_OK;
13321 +       if(w) mode |= W_OK;
13322 +       if(x) mode |= X_OK;
13323 +       if(access(path, mode) != 0) return(-errno);
13324 +       else return(0);
13325 +}
13326 +
13327 +int open_file(char *path, int r, int w, int append)
13328 +{
13329 +       int mode = 0, fd;
13330 +
13331 +       if(r && !w) 
13332 +               mode = O_RDONLY;
13333 +       else if(!r && w) 
13334 +               mode = O_WRONLY;
13335 +       else if(r && w) 
13336 +               mode = O_RDWR;
13337 +       else panic("Impossible mode in open_file");
13338 +
13339 +       if(append)
13340 +               mode |= O_APPEND;
13341 +       fd = open64(path, mode);
13342 +       if(fd < 0) return(-errno);
13343 +       else return(fd);
13344 +}
13345 +
13346 +void *open_dir(char *path, int *err_out)
13347 +{
13348 +       DIR *dir;
13349 +
13350 +       dir = opendir(path);
13351 +       *err_out = errno;
13352 +       if(dir == NULL) return(NULL);
13353 +       return(dir);
13354 +}
13355 +
13356 +char *read_dir(void *stream, unsigned long long *pos, 
13357 +              unsigned long long *ino_out, int *len_out)
13358 +{
13359 +       DIR *dir = stream;
13360 +       struct dirent *ent;
13361 +
13362 +       seekdir(dir, *pos);
13363 +       ent = readdir(dir);
13364 +       if(ent == NULL) return(NULL);
13365 +       *len_out = strlen(ent->d_name);
13366 +       *ino_out = ent->d_ino;
13367 +       *pos = telldir(dir);
13368 +       return(ent->d_name);
13369 +}
13370 +
13371 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
13372 +{
13373 +       int n, err;
13374 +
13375 +       err = os_seek_file(fd, *offset);
13376 +       if(err)
13377 +               return(err);
13378 +
13379 +       n = os_read_file(fd, buf, len);
13380 +       if(n < 0) 
13381 +               return(n);
13382 +
13383 +       *offset += n;
13384 +       return(n);
13385 +}
13386 +
13387 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
13388 +{
13389 +       int n, err;
13390 +
13391 +       err = os_seek_file(fd, *offset);
13392 +       if(err)
13393 +               return(err);
13394 +
13395 +       n = os_write_file(fd, buf, len);
13396 +       if(n < 0) 
13397 +               return(n);
13398 +
13399 +       *offset += n;
13400 +       return(n);
13401 +}
13402 +
13403 +int lseek_file(int fd, long long offset, int whence)
13404 +{
13405 +       int ret;
13406 +
13407 +       ret = lseek64(fd, offset, whence);
13408 +       if(ret < 0) return(-errno);
13409 +       return(0);
13410 +}
13411 +
13412 +void close_file(void *stream)
13413 +{
13414 +       close(*((int *) stream));
13415 +}
13416 +
13417 +void close_dir(void *stream)
13418 +{
13419 +       closedir(stream);
13420 +}
13421 +
13422 +int file_create(char *name, int ur, int uw, int ux, int gr, 
13423 +               int gw, int gx, int or, int ow, int ox)
13424 +{
13425 +       int mode, fd;
13426 +
13427 +       mode = 0;
13428 +       mode |= ur ? S_IRUSR : 0;
13429 +       mode |= uw ? S_IWUSR : 0;
13430 +       mode |= ux ? S_IXUSR : 0;
13431 +       mode |= gr ? S_IRGRP : 0;
13432 +       mode |= gw ? S_IWGRP : 0;
13433 +       mode |= gx ? S_IXGRP : 0;
13434 +       mode |= or ? S_IROTH : 0;
13435 +       mode |= ow ? S_IWOTH : 0;
13436 +       mode |= ox ? S_IXOTH : 0;
13437 +       fd = open64(name, O_CREAT | O_RDWR, mode);
13438 +       if(fd < 0) 
13439 +               return(-errno);
13440 +       return(fd);
13441 +}
13442 +
13443 +int set_attr(const char *file, struct hostfs_iattr *attrs)
13444 +{
13445 +       struct utimbuf buf;
13446 +       int err, ma;
13447 +
13448 +       if(attrs->ia_valid & HOSTFS_ATTR_MODE){
13449 +               if(chmod(file, attrs->ia_mode) != 0) return(-errno);
13450 +       }
13451 +       if(attrs->ia_valid & HOSTFS_ATTR_UID){
13452 +               if(chown(file, attrs->ia_uid, -1)) return(-errno);
13453 +       }
13454 +       if(attrs->ia_valid & HOSTFS_ATTR_GID){
13455 +               if(chown(file, -1, attrs->ia_gid)) return(-errno);
13456 +       }
13457 +       if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
13458 +               if(truncate64(file, attrs->ia_size)) return(-errno);
13459 +       }
13460 +       ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
13461 +       if((attrs->ia_valid & ma) == ma){
13462 +               buf.actime = attrs->ia_atime;
13463 +               buf.modtime = attrs->ia_mtime;
13464 +               if(utime(file, &buf) != 0) return(-errno);
13465 +       }
13466 +       else {
13467 +               if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
13468 +                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
13469 +                                       NULL, NULL, NULL, &buf.modtime, NULL,
13470 +                                       NULL, NULL);
13471 +                       if(err != 0) return(err);
13472 +                       buf.actime = attrs->ia_atime;
13473 +                       if(utime(file, &buf) != 0) return(-errno);
13474 +               }
13475 +               if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
13476 +                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
13477 +                                       NULL, NULL, &buf.actime, NULL, NULL, 
13478 +                                       NULL, NULL);
13479 +                       if(err != 0) return(err);
13480 +                       buf.modtime = attrs->ia_mtime;
13481 +                       if(utime(file, &buf) != 0) return(-errno);
13482 +               }
13483 +       }
13484 +       if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
13485 +       if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
13486 +               err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
13487 +                               NULL, NULL, &attrs->ia_atime, &attrs->ia_mtime,
13488 +                               NULL, NULL, NULL);
13489 +               if(err != 0) return(err);
13490 +       }
13491 +       return(0);
13492 +}
13493 +
13494 +int make_symlink(const char *from, const char *to)
13495 +{
13496 +       int err;
13497 +
13498 +       err = symlink(to, from);
13499 +       if(err) return(-errno);
13500 +       return(0);
13501 +}
13502 +
13503 +int unlink_file(const char *file)
13504 +{
13505 +       int err;
13506 +
13507 +       err = unlink(file);
13508 +       if(err) return(-errno);
13509 +       return(0);
13510 +}
13511 +
13512 +int do_mkdir(const char *file, int mode)
13513 +{
13514 +       int err;
13515 +
13516 +       err = mkdir(file, mode);
13517 +       if(err) return(-errno);
13518 +       return(0);
13519 +}
13520 +
13521 +int do_rmdir(const char *file)
13522 +{
13523 +       int err;
13524 +
13525 +       err = rmdir(file);
13526 +       if(err) return(-errno);
13527 +       return(0);
13528 +}
13529 +
13530 +int do_mknod(const char *file, int mode, int dev)
13531 +{
13532 +       int err;
13533 +
13534 +       err = mknod(file, mode, dev);
13535 +       if(err) return(-errno);
13536 +       return(0);
13537 +}
13538 +
13539 +int link_file(const char *to, const char *from)
13540 +{
13541 +       int err;
13542 +
13543 +       err = link(to, from);
13544 +       if(err) return(-errno);
13545 +       return(0);
13546 +}
13547 +
13548 +int do_readlink(char *file, char *buf, int size)
13549 +{
13550 +       int n;
13551 +
13552 +       n = readlink(file, buf, size);
13553 +       if(n < 0) 
13554 +               return(-errno);
13555 +       if(n < size) 
13556 +               buf[n] = '\0';
13557 +       return(n);
13558 +}
13559 +
13560 +int rename_file(char *from, char *to)
13561 +{
13562 +       int err;
13563 +
13564 +       err = rename(from, to);
13565 +       if(err < 0) return(-errno);
13566 +       return(0);      
13567 +}
13568 +
13569 +int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
13570 +             long long *bfree_out, long long *bavail_out, 
13571 +             long long *files_out, long long *ffree_out,
13572 +             void *fsid_out, int fsid_size, long *namelen_out, 
13573 +             long *spare_out)
13574 +{
13575 +       struct statfs64 buf;
13576 +       int err;
13577 +
13578 +       err = statfs64(root, &buf);
13579 +       if(err < 0) return(-errno);
13580 +       *bsize_out = buf.f_bsize;
13581 +       *blocks_out = buf.f_blocks;
13582 +       *bfree_out = buf.f_bfree;
13583 +       *bavail_out = buf.f_bavail;
13584 +       *files_out = buf.f_files;
13585 +       *ffree_out = buf.f_ffree;
13586 +       memcpy(fsid_out, &buf.f_fsid, 
13587 +              sizeof(buf.f_fsid) > fsid_size ? fsid_size : 
13588 +              sizeof(buf.f_fsid));
13589 +       *namelen_out = buf.f_namelen;
13590 +       spare_out[0] = buf.f_spare[0];
13591 +       spare_out[1] = buf.f_spare[1];
13592 +       spare_out[2] = buf.f_spare[2];
13593 +       spare_out[3] = buf.f_spare[3];
13594 +       spare_out[4] = buf.f_spare[4];
13595 +       spare_out[5] = buf.f_spare[5];
13596 +       return(0);
13597 +}
13598 +
13599 +/*
13600 + * Overrides for Emacs so that we follow Linus's tabbing style.
13601 + * Emacs will notice this stuff at the end of the file and automatically
13602 + * adjust the settings for this buffer only.  This must remain at the end
13603 + * of the file.
13604 + * ---------------------------------------------------------------------------
13605 + * Local variables:
13606 + * c-file-style: "linux"
13607 + * End:
13608 + */
13609 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/Makefile um/arch/um/fs/hostfs/Makefile
13610 --- orig/arch/um/fs/hostfs/Makefile     1969-12-31 19:00:00.000000000 -0500
13611 +++ um/arch/um/fs/hostfs/Makefile       2003-10-21 03:26:06.000000000 -0400
13612 @@ -0,0 +1,24 @@
13613 +# 
13614 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13615 +# Licensed under the GPL
13616 +#
13617 +
13618 +# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino
13619 +# to __st_ino.  It stayed in the same place, so as long as the correct name
13620 +# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa.
13621 +
13622 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
13623 +                               echo __)st_ino
13624 +
13625 +USER_CFLAGS := $(USER_CFLAGS) -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
13626 +
13627 +O_TARGET := hostfs.o
13628 +obj-y = hostfs_kern.o hostfs_user.o
13629 +obj-m = $(O_TARGET)
13630 +
13631 +USER_OBJS = $(filter %_user.o,$(obj-y))
13632 +
13633 +include $(TOPDIR)/Rules.make
13634 +
13635 +$(USER_OBJS) : %.o: %.c
13636 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
13637 diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/hppfs_kern.c um/arch/um/fs/hppfs/hppfs_kern.c
13638 --- orig/arch/um/fs/hppfs/hppfs_kern.c  1969-12-31 19:00:00.000000000 -0500
13639 +++ um/arch/um/fs/hppfs/hppfs_kern.c    2004-01-08 23:35:58.000000000 -0500
13640 @@ -0,0 +1,737 @@
13641 +/* 
13642 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13643 + * Licensed under the GPL
13644 + */
13645 +
13646 +#include <linux/fs.h>
13647 +#include <linux/module.h>
13648 +#include <linux/slab.h>
13649 +#include <linux/list.h>
13650 +#include <linux/kernel.h>
13651 +#include <linux/ctype.h>
13652 +#include <asm/uaccess.h>
13653 +#include "os.h"
13654 +
13655 +struct hppfs_data {
13656 +       struct list_head list;
13657 +       char contents[PAGE_SIZE - sizeof(struct list_head)];
13658 +};
13659 +
13660 +struct hppfs_private {
13661 +       struct file proc_file;
13662 +       int host_fd;
13663 +       loff_t len;
13664 +       struct hppfs_data *contents;
13665 +};
13666 +
13667 +#define HPPFS_SUPER_MAGIC 0xb00000ee
13668 +
13669 +static struct super_operations hppfs_sbops;
13670 +
13671 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
13672 +                              int *error);
13673 +
13674 +static int is_pid(struct dentry *dentry)
13675 +{
13676 +       struct super_block *sb;
13677 +       int i;
13678 +
13679 +       sb = dentry->d_sb;
13680 +       if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
13681 +               return(0);
13682 +
13683 +       for(i = 0; i < dentry->d_name.len; i++){
13684 +               if(!isdigit(dentry->d_name.name[i]))
13685 +                       return(0);
13686 +       }
13687 +       return(1);
13688 +}
13689 +
13690 +static char *dentry_name(struct dentry *dentry, int extra)
13691 +{
13692 +       struct dentry *parent;
13693 +       char *root, *name;
13694 +       const char *seg_name;
13695 +       int len, seg_len;
13696 +
13697 +       len = 0;
13698 +       parent = dentry;
13699 +       while(parent->d_parent != parent){
13700 +               if(is_pid(parent))
13701 +                       len += strlen("pid") + 1;
13702 +               else len += parent->d_name.len + 1;
13703 +               parent = parent->d_parent;
13704 +       }
13705 +       
13706 +       root = "proc";
13707 +       len += strlen(root);
13708 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
13709 +       if(name == NULL) return(NULL);
13710 +
13711 +       name[len] = '\0';
13712 +       parent = dentry;
13713 +       while(parent->d_parent != parent){
13714 +               if(is_pid(parent)){
13715 +                       seg_name = "pid";
13716 +                       seg_len = strlen("pid");
13717 +               }
13718 +               else {
13719 +                       seg_name = parent->d_name.name;
13720 +                       seg_len = parent->d_name.len;
13721 +               }
13722 +
13723 +               len -= seg_len + 1;
13724 +               name[len] = '/';
13725 +               strncpy(&name[len + 1], seg_name, seg_len);
13726 +               parent = parent->d_parent;
13727 +       }
13728 +       strncpy(name, root, strlen(root));
13729 +       return(name);
13730 +}
13731 +
13732 +struct dentry_operations hppfs_dentry_ops = {
13733 +};
13734 +
13735 +static int file_removed(struct dentry *dentry, const char *file)
13736 +{
13737 +       char *host_file;
13738 +       int extra, fd;
13739 +
13740 +       extra = 0;
13741 +       if(file != NULL) extra += strlen(file) + 1;
13742 +
13743 +       host_file = dentry_name(dentry, extra + strlen("/remove"));
13744 +       if(host_file == NULL){
13745 +               printk("file_removed : allocation failed\n");
13746 +               return(-ENOMEM);
13747 +       }
13748 +
13749 +       if(file != NULL){
13750 +               strcat(host_file, "/");
13751 +               strcat(host_file, file);
13752 +       }
13753 +       strcat(host_file, "/remove");
13754 +
13755 +       fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
13756 +       kfree(host_file);
13757 +       if(fd >= 0){
13758 +               os_close_file(fd);
13759 +               return(1);
13760 +       }
13761 +       return(0);
13762 +}
13763 +
13764 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry)
13765 +{
13766 +       struct dentry *proc_dentry;
13767 +       struct inode *inode;
13768 +       int err, deleted;
13769 +
13770 +       deleted = file_removed(dentry, NULL);
13771 +       if(deleted < 0)
13772 +               return(ERR_PTR(deleted));
13773 +       else if(deleted)
13774 +               return(ERR_PTR(-ENOENT));
13775 +
13776 +       proc_dentry = lookup_hash(&dentry->d_name, ino->u.hppfs_i.proc_dentry);
13777 +       if(IS_ERR(proc_dentry))
13778 +               return(proc_dentry);
13779 +
13780 +       inode = get_inode(ino->i_sb, proc_dentry, &err);
13781 +       if(err != 0) 
13782 +               return(ERR_PTR(err));
13783 +
13784 +       d_add(dentry, inode);
13785 +       dentry->d_op = &hppfs_dentry_ops;
13786 +       return(NULL);
13787 +}
13788 +
13789 +static struct inode_operations hppfs_file_iops = {
13790 +};
13791 +
13792 +static struct inode_operations hppfs_dir_iops = {
13793 +       .lookup         = hppfs_lookup,
13794 +};
13795 +
13796 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count, 
13797 +                        loff_t *ppos, int is_user)
13798 +{
13799 +       ssize_t (*read)(struct file *, char *, size_t, loff_t *);
13800 +       ssize_t n;
13801 +
13802 +       read = file->f_dentry->d_inode->i_fop->read;
13803 +       if(read == NULL)
13804 +               return(-EOPNOTSUPP);
13805 +
13806 +       if(!is_user)
13807 +               set_fs(KERNEL_DS);
13808 +               
13809 +       n = (*read)(file, buf, count, &file->f_pos);
13810 +
13811 +       if(!is_user)
13812 +               set_fs(USER_DS);
13813 +
13814 +       if(ppos) *ppos = file->f_pos;
13815 +       return(n);
13816 +}
13817 +
13818 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
13819 +{
13820 +       ssize_t n;
13821 +       int cur, err;
13822 +       char *new_buf;
13823 +
13824 +       n = -ENOMEM;
13825 +       new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
13826 +       if(new_buf == NULL){
13827 +               printk("hppfs_read_file : kmalloc failed\n");
13828 +               goto out;
13829 +       }
13830 +       n = 0;
13831 +       while(count > 0){
13832 +               cur = min_t(ssize_t, count, PAGE_SIZE);
13833 +               err = os_read_file(fd, new_buf, cur);
13834 +               if(err < 0){
13835 +                       printk("hppfs_read : read failed, err = %d\n", -err);
13836 +                       n = err;
13837 +                       goto out_free;
13838 +               }
13839 +               else if(err == 0)
13840 +                       break;
13841 +
13842 +               if(copy_to_user(buf, new_buf, err)){
13843 +                       n = -EFAULT;
13844 +                       goto out_free;
13845 +               }
13846 +               n += err;
13847 +               count -= err;
13848 +       }
13849 + out_free:
13850 +       kfree(new_buf);
13851 + out:
13852 +       return(n);
13853 +}
13854 +
13855 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count, 
13856 +                         loff_t *ppos)
13857 +{
13858 +       struct hppfs_private *hppfs = file->private_data;
13859 +       struct hppfs_data *data;
13860 +       loff_t off;
13861 +       int err;
13862 +
13863 +       if(hppfs->contents != NULL){
13864 +               if(*ppos >= hppfs->len) return(0);
13865 +
13866 +               data = hppfs->contents;
13867 +               off = *ppos;
13868 +               while(off >= sizeof(data->contents)){
13869 +                       data = list_entry(data->list.next, struct hppfs_data,
13870 +                                         list);
13871 +                       off -= sizeof(data->contents);
13872 +               }
13873 +
13874 +               if(off + count > hppfs->len)
13875 +                       count = hppfs->len - off;
13876 +               copy_to_user(buf, &data->contents[off], count);
13877 +               *ppos += count;
13878 +       }
13879 +       else if(hppfs->host_fd != -1){
13880 +               err = os_seek_file(hppfs->host_fd, *ppos);
13881 +               if(err < 0){
13882 +                       printk("hppfs_read : seek failed, err = %d\n", -err);
13883 +                       return(err);
13884 +               }
13885 +               count = hppfs_read_file(hppfs->host_fd, buf, count);
13886 +               if(count > 0)
13887 +                       *ppos += count;
13888 +       }
13889 +       else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
13890 +
13891 +       return(count);
13892 +}
13893 +
13894 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, 
13895 +                          loff_t *ppos)
13896 +{
13897 +       struct hppfs_private *data = file->private_data;
13898 +       struct file *proc_file = &data->proc_file;
13899 +       ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
13900 +       int err;
13901 +
13902 +       write = proc_file->f_dentry->d_inode->i_fop->write;
13903 +       if(write == NULL)
13904 +               return(-EOPNOTSUPP);
13905 +
13906 +       proc_file->f_pos = file->f_pos;
13907 +       err = (*write)(proc_file, buf, len, &proc_file->f_pos);
13908 +       file->f_pos = proc_file->f_pos;
13909 +
13910 +       return(err);
13911 +}
13912 +
13913 +static int open_host_sock(char *host_file, int *filter_out)
13914 +{
13915 +       char *end;
13916 +       int fd;
13917 +
13918 +       end = &host_file[strlen(host_file)];
13919 +       strcpy(end, "/rw");
13920 +       *filter_out = 1;
13921 +       fd = os_connect_socket(host_file);
13922 +       if(fd >= 0)
13923 +               return(fd);
13924 +
13925 +       strcpy(end, "/r");
13926 +       *filter_out = 0;
13927 +       fd = os_connect_socket(host_file);
13928 +       return(fd);
13929 +}
13930 +
13931 +static void free_contents(struct hppfs_data *head)
13932 +{
13933 +       struct hppfs_data *data;
13934 +       struct list_head *ele, *next;
13935 +
13936 +       if(head == NULL) return;
13937 +
13938 +       list_for_each_safe(ele, next, &head->list){
13939 +               data = list_entry(ele, struct hppfs_data, list);
13940 +               kfree(data);
13941 +       }
13942 +       kfree(head);
13943 +}
13944 +
13945 +static struct hppfs_data *hppfs_get_data(int fd, int filter, 
13946 +                                        struct file *proc_file, 
13947 +                                        struct file *hppfs_file, 
13948 +                                        loff_t *size_out)
13949 +{
13950 +       struct hppfs_data *data, *new, *head;
13951 +       int n, err;
13952 +
13953 +       err = -ENOMEM;
13954 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
13955 +       if(data == NULL){
13956 +               printk("hppfs_get_data : head allocation failed\n");
13957 +               goto failed;
13958 +       }
13959 +
13960 +       INIT_LIST_HEAD(&data->list);
13961 +
13962 +       head = data;
13963 +       *size_out = 0;
13964 +
13965 +       if(filter){
13966 +               while((n = read_proc(proc_file, data->contents,
13967 +                                    sizeof(data->contents), NULL, 0)) > 0) {
13968 +                       err = os_write_file(fd, data->contents, n);
13969 +                       if(err != n)
13970 +                               printk("hppfs_get_data : failed to write out "
13971 +                                      "%d bytes, err = %d\n", n, -err);
13972 +               }
13973 +               err = os_shutdown_socket(fd, 0, 1);
13974 +               if(err < 0){
13975 +                       printk("hppfs_get_data : failed to shut down "
13976 +                              "socket\n");
13977 +                       goto failed_free;
13978 +               }
13979 +       }
13980 +       while(1){
13981 +               n = os_read_file(fd, data->contents, sizeof(data->contents));
13982 +               if(n < 0){
13983 +                       err = n;
13984 +                       printk("hppfs_get_data : read failed, err = %d\n", -n);
13985 +                       goto failed_free;
13986 +               }
13987 +               else if(n == 0)
13988 +                       break;
13989 +
13990 +               *size_out += n;
13991 +
13992 +               if(n < sizeof(data->contents))
13993 +                       break;
13994 +
13995 +               new = kmalloc(sizeof(*data), GFP_KERNEL);
13996 +               if(new == 0){
13997 +                       printk("hppfs_get_data : data allocation failed\n");
13998 +                       err = -ENOMEM;
13999 +                       goto failed_free;
14000 +               }
14001 +       
14002 +               INIT_LIST_HEAD(&new->list);
14003 +               list_add(&new->list, &data->list);
14004 +               data = new;
14005 +       }
14006 +       return(head);
14007 +
14008 + failed_free:
14009 +       free_contents(head);
14010 + failed:               
14011 +       return(ERR_PTR(err));
14012 +}
14013 +
14014 +static struct hppfs_private *hppfs_data(void)
14015 +{
14016 +       struct hppfs_private *data;
14017 +
14018 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
14019 +       if(data == NULL)
14020 +               return(data);
14021 +
14022 +       *data = ((struct hppfs_private ) { .host_fd             = -1,
14023 +                                          .len                 = -1,
14024 +                                          .contents            = NULL } );
14025 +       return(data);
14026 +}
14027 +
14028 +static int hppfs_open(struct inode *inode, struct file *file)
14029 +{
14030 +       struct hppfs_private *data;
14031 +       struct dentry *proc_dentry;
14032 +       char *host_file;
14033 +       int err, fd, type, filter;
14034 +
14035 +       err = -ENOMEM;
14036 +       data = hppfs_data();
14037 +       if(data == NULL)
14038 +               goto out;
14039 +
14040 +       host_file = dentry_name(file->f_dentry, strlen("/rw"));
14041 +       if(host_file == NULL)
14042 +               goto out_free2;
14043 +
14044 +       proc_dentry = inode->u.hppfs_i.proc_dentry;
14045 +       err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
14046 +       if(err)
14047 +               goto out_free1;
14048 +
14049 +       type = os_file_type(host_file);
14050 +       if(type == OS_TYPE_FILE){
14051 +               fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
14052 +               if(fd >= 0) 
14053 +                       data->host_fd = fd;
14054 +               else printk("hppfs_open : failed to open '%s', err = %d\n",
14055 +                           host_file, -fd);
14056 +
14057 +               data->contents = NULL;
14058 +       }
14059 +       else if(type == OS_TYPE_DIR){
14060 +               fd = open_host_sock(host_file, &filter);
14061 +               if(fd >= 0){
14062 +                       data->contents = hppfs_get_data(fd, filter, 
14063 +                                                       &data->proc_file, 
14064 +                                                       file, &data->len);
14065 +                       if(!IS_ERR(data->contents))
14066 +                               data->host_fd = fd;
14067 +               }
14068 +               else printk("hppfs_open : failed to open a socket in "
14069 +                           "'%s', err = %d\n", host_file, -fd);
14070 +       }
14071 +       kfree(host_file);
14072 +
14073 +       file->private_data = data;
14074 +       return(0);
14075 +
14076 + out_free1:
14077 +       kfree(host_file);
14078 + out_free2:
14079 +       free_contents(data->contents);
14080 +       kfree(data);
14081 + out:
14082 +       return(err);
14083 +}
14084 +
14085 +static int hppfs_dir_open(struct inode *inode, struct file *file)
14086 +{
14087 +       struct hppfs_private *data;
14088 +       struct dentry *proc_dentry;
14089 +       int err;
14090 +
14091 +       err = -ENOMEM;
14092 +       data = hppfs_data();
14093 +       if(data == NULL)
14094 +               goto out;
14095 +
14096 +       proc_dentry = inode->u.hppfs_i.proc_dentry;
14097 +       err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
14098 +       if(err)
14099 +               goto out_free;
14100 +
14101 +       file->private_data = data;
14102 +       return(0);
14103 +
14104 + out_free:
14105 +       kfree(data);
14106 + out:
14107 +       return(err);
14108 +}
14109 +
14110 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
14111 +{
14112 +       struct hppfs_private *data = file->private_data;
14113 +       struct file *proc_file = &data->proc_file;
14114 +       loff_t (*llseek)(struct file *, loff_t, int);
14115 +       loff_t ret;
14116 +
14117 +       llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
14118 +       if(llseek != NULL){
14119 +               ret = (*llseek)(proc_file, off, where);
14120 +               if(ret < 0)
14121 +                       return(ret);
14122 +       }
14123 +
14124 +       return(default_llseek(file, off, where));
14125 +}
14126 +
14127 +struct hppfs_dirent {
14128 +       void *vfs_dirent;
14129 +       filldir_t filldir;
14130 +       struct dentry *dentry;
14131 +};
14132 +
14133 +static int hppfs_filldir(void *d, const char *name, int size, 
14134 +                        loff_t offset, ino_t inode, unsigned int type)
14135 +{
14136 +       struct hppfs_dirent *dirent = d;
14137 +
14138 +       if(file_removed(dirent->dentry, name))
14139 +               return(0);
14140 +
14141 +       return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset, 
14142 +                                 inode, type));
14143 +}
14144 +
14145 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
14146 +{
14147 +       struct hppfs_private *data = file->private_data;
14148 +       struct file *proc_file = &data->proc_file;
14149 +       int (*readdir)(struct file *, void *, filldir_t);
14150 +       struct hppfs_dirent dirent = ((struct hppfs_dirent)
14151 +                                     { .vfs_dirent     = ent,
14152 +                                       .filldir        = filldir,
14153 +                                       .dentry         = file->f_dentry } );
14154 +       int err;
14155 +
14156 +       readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
14157 +       if(readdir == NULL)
14158 +               return(-EOPNOTSUPP);
14159 +
14160 +       proc_file->f_pos = file->f_pos;
14161 +       err = (*readdir)(proc_file, &dirent, hppfs_filldir);
14162 +       file->f_pos = proc_file->f_pos;
14163 +
14164 +       return(err);
14165 +}
14166 +
14167 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
14168 +{
14169 +       return(0);
14170 +}
14171 +
14172 +static struct file_operations hppfs_file_fops = {
14173 +       .owner          = NULL,
14174 +       .llseek         = hppfs_llseek,
14175 +       .read           = hppfs_read,
14176 +       .write          = hppfs_write,
14177 +       .open           = hppfs_open,
14178 +};
14179 +
14180 +static struct file_operations hppfs_dir_fops = {
14181 +       .owner          = NULL,
14182 +       .readdir        = hppfs_readdir,
14183 +       .open           = hppfs_dir_open,
14184 +       .fsync          = hppfs_fsync,
14185 +};
14186 +
14187 +static int hppfs_statfs(struct super_block *sb, struct statfs *sf)
14188 +{
14189 +       sf->f_blocks = 0;
14190 +       sf->f_bfree = 0;
14191 +       sf->f_bavail = 0;
14192 +       sf->f_files = 0;
14193 +       sf->f_ffree = 0;
14194 +       sf->f_type = HPPFS_SUPER_MAGIC;
14195 +       return(0);
14196 +}
14197 +
14198 +static struct super_operations hppfs_sbops = { 
14199 +       .put_inode      = force_delete,
14200 +       .delete_inode   = NULL,
14201 +       .statfs         = hppfs_statfs,
14202 +};
14203 +
14204 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
14205 +{
14206 +       struct file proc_file;
14207 +       struct dentry *proc_dentry;
14208 +       int (*readlink)(struct dentry *, char *, int);
14209 +       int err, n;
14210 +
14211 +       proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
14212 +       err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
14213 +       if(err) 
14214 +               return(err);
14215 +
14216 +       readlink = proc_dentry->d_inode->i_op->readlink;
14217 +       if(readlink == NULL)
14218 +               return(-EOPNOTSUPP);
14219 +       n = (*readlink)(proc_dentry, buffer, buflen);
14220 +
14221 +       if(proc_file.f_op->release)
14222 +               (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
14223 +       
14224 +       return(n);
14225 +}
14226 +
14227 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
14228 +{
14229 +       struct file proc_file;
14230 +       struct dentry *proc_dentry;
14231 +       int (*follow_link)(struct dentry *, struct nameidata *);
14232 +       int err, n;
14233 +
14234 +       proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
14235 +       err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
14236 +       if(err) 
14237 +               return(err);
14238 +
14239 +       follow_link = proc_dentry->d_inode->i_op->follow_link;
14240 +       if(follow_link == NULL)
14241 +               return(-EOPNOTSUPP);
14242 +       n = (*follow_link)(proc_dentry, nd);
14243 +
14244 +       if(proc_file.f_op->release)
14245 +               (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
14246 +       
14247 +       return(n);
14248 +}
14249 +
14250 +static struct inode_operations hppfs_link_iops = {
14251 +       .readlink       = hppfs_readlink,
14252 +       .follow_link    = hppfs_follow_link,
14253 +};
14254 +
14255 +static void read_inode(struct inode *ino)
14256 +{
14257 +       struct inode *proc_ino;
14258 +
14259 +       proc_ino = ino->u.hppfs_i.proc_dentry->d_inode;
14260 +       ino->i_uid = proc_ino->i_uid;
14261 +       ino->i_gid = proc_ino->i_gid;
14262 +       ino->i_atime = proc_ino->i_atime;
14263 +       ino->i_mtime = proc_ino->i_mtime;
14264 +       ino->i_ctime = proc_ino->i_ctime;
14265 +       ino->i_ino = proc_ino->i_ino;
14266 +       ino->i_dev = proc_ino->i_dev;
14267 +       ino->i_mode = proc_ino->i_mode;
14268 +       ino->i_nlink = proc_ino->i_nlink;
14269 +       ino->i_size = proc_ino->i_size;
14270 +       ino->i_blksize = proc_ino->i_blksize;
14271 +       ino->i_blocks = proc_ino->i_blocks;
14272 +}
14273 +
14274 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
14275 +                              int *error)
14276 +{
14277 +       struct inode *inode;
14278 +       int err = -ENOMEM;
14279 +
14280 +       inode = new_inode(sb);
14281 +       if(inode == NULL) 
14282 +               goto out;
14283 +
14284 +       insert_inode_hash(inode);
14285 +       if(S_ISDIR(dentry->d_inode->i_mode)){
14286 +               inode->i_op = &hppfs_dir_iops;
14287 +               inode->i_fop = &hppfs_dir_fops;
14288 +       }
14289 +       else if(S_ISLNK(dentry->d_inode->i_mode)){
14290 +               inode->i_op = &hppfs_link_iops;
14291 +               inode->i_fop = &hppfs_file_fops;
14292 +       }
14293 +       else {
14294 +               inode->i_op = &hppfs_file_iops;
14295 +               inode->i_fop = &hppfs_file_fops;
14296 +       }
14297 +
14298 +       inode->i_sb = sb;
14299 +       inode->u.hppfs_i.proc_dentry = dentry;
14300 +
14301 +       read_inode(inode);
14302 +       err = 0;
14303 +
14304 +       if(error) *error = err;
14305 +       return(inode);
14306 + out:
14307 +       if(error) *error = err;
14308 +       return(NULL);
14309 +}
14310 +
14311 +static struct super_block *hppfs_read_super(struct super_block *sb, void *d, 
14312 +                                           int silent)
14313 +{
14314 +       struct inode *root_inode;
14315 +       struct file_system_type *procfs;
14316 +       struct super_block *proc_sb;
14317 +
14318 +       procfs = get_fs_type("proc");
14319 +       if(procfs == NULL) 
14320 +               goto out;
14321 +
14322 +       if(list_empty(&procfs->fs_supers))
14323 +               goto out;
14324 +
14325 +       proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
14326 +                            s_instances);
14327 +       
14328 +       sb->s_blocksize = 1024;
14329 +       sb->s_blocksize_bits = 10;
14330 +       sb->s_magic = HPPFS_SUPER_MAGIC;
14331 +       sb->s_op = &hppfs_sbops;
14332 +
14333 +       dget(proc_sb->s_root);
14334 +       root_inode = get_inode(sb, proc_sb->s_root, NULL);
14335 +       if(root_inode == NULL)
14336 +               goto out_dput;
14337 +
14338 +       sb->s_root = d_alloc_root(root_inode);
14339 +       if(sb->s_root == NULL)
14340 +               goto out_put;
14341 +
14342 +       return(sb);
14343 +
14344 + out_put:
14345 +       iput(root_inode);
14346 + out_dput:
14347 +       dput(proc_sb->s_root);
14348 + out:
14349 +       return(NULL);
14350 +}
14351 +
14352 +DECLARE_FSTYPE(hppfs_type, "hppfs", hppfs_read_super, 0);
14353 +
14354 +static int __init init_hppfs(void)
14355 +{
14356 +       return(register_filesystem(&hppfs_type));
14357 +}
14358 +
14359 +static void __exit exit_hppfs(void)
14360 +{
14361 +       unregister_filesystem(&hppfs_type);
14362 +}
14363 +
14364 +module_init(init_hppfs)
14365 +module_exit(exit_hppfs)
14366 +MODULE_LICENSE("GPL");
14367 +
14368 +/*
14369 + * Overrides for Emacs so that we follow Linus's tabbing style.
14370 + * Emacs will notice this stuff at the end of the file and automatically
14371 + * adjust the settings for this buffer only.  This must remain at the end
14372 + * of the file.
14373 + * ---------------------------------------------------------------------------
14374 + * Local variables:
14375 + * c-file-style: "linux"
14376 + * End:
14377 + */
14378 diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/Makefile um/arch/um/fs/hppfs/Makefile
14379 --- orig/arch/um/fs/hppfs/Makefile      1969-12-31 19:00:00.000000000 -0500
14380 +++ um/arch/um/fs/hppfs/Makefile        2003-10-21 03:26:06.000000000 -0400
14381 @@ -0,0 +1,10 @@
14382 +O_TARGET := hppfs.o
14383 +obj-y = hppfs_kern.o #hppfs_user.o
14384 +obj-m = $(O_TARGET)
14385 +
14386 +CFLAGS_hppfs_kern.o := $(CFLAGS)
14387 +#CFLAGS_hppfs_user.o := $(USER_CFLAGS)
14388 +
14389 +override CFLAGS =  
14390 +
14391 +include $(TOPDIR)/Rules.make
14392 diff -Naur -X ../exclude-files orig/arch/um/fs/Makefile um/arch/um/fs/Makefile
14393 --- orig/arch/um/fs/Makefile    1969-12-31 19:00:00.000000000 -0500
14394 +++ um/arch/um/fs/Makefile      2003-10-21 03:26:06.000000000 -0400
14395 @@ -0,0 +1,23 @@
14396 +# 
14397 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
14398 +# Licensed under the GPL
14399 +#
14400 +
14401 +O_TARGET := built-in.o
14402 +
14403 +subdir-y =
14404 +subdir-m =
14405 +
14406 +subdir-$(CONFIG_HOSTFS) += hostfs
14407 +subdir-$(CONFIG_HPPFS) += hppfs
14408 +
14409 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
14410 +obj-m += $(join $(subdir-m),$(subdir-m:%=/%.o))
14411 +
14412 +include $(TOPDIR)/Rules.make
14413 +
14414 +dep:
14415 +
14416 +clean:
14417 +
14418 +archmrproper:
14419 diff -Naur -X ../exclude-files orig/arch/um/include/2_5compat.h um/arch/um/include/2_5compat.h
14420 --- orig/arch/um/include/2_5compat.h    1969-12-31 19:00:00.000000000 -0500
14421 +++ um/arch/um/include/2_5compat.h      2003-11-07 02:49:26.000000000 -0500
14422 @@ -0,0 +1,33 @@
14423 +/* 
14424 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
14425 + * Licensed under the GPL
14426 + */
14427 +
14428 +#ifndef __2_5_COMPAT_H__
14429 +#define __2_5_COMPAT_H__
14430 +
14431 +#include "linux/version.h"
14432 +
14433 +#define INIT_ELV(queue, elv) elevator_init(elv, ELV_NOOP)
14434 +
14435 +#define ELV_NOOP ELEVATOR_NOOP
14436 +
14437 +#define INIT_HARDSECT(arr, maj, sizes) arr[maj] = sizes
14438 +
14439 +#define IS_WRITE(req) ((req)->cmd == WRITE)
14440 +
14441 +#define SET_PRI(task) \
14442 +       do { (task)->nice = 20; (task)->counter = -100; } while(0);
14443 +
14444 +#endif
14445 +
14446 +/*
14447 + * Overrides for Emacs so that we follow Linus's tabbing style.
14448 + * Emacs will notice this stuff at the end of the file and automatically
14449 + * adjust the settings for this buffer only.  This must remain at the end
14450 + * of the file.
14451 + * ---------------------------------------------------------------------------
14452 + * Local variables:
14453 + * c-file-style: "linux"
14454 + * End:
14455 + */
14456 diff -Naur -X ../exclude-files orig/arch/um/include/chan_kern.h um/arch/um/include/chan_kern.h
14457 --- orig/arch/um/include/chan_kern.h    1969-12-31 19:00:00.000000000 -0500
14458 +++ um/arch/um/include/chan_kern.h      2003-10-21 03:26:06.000000000 -0400
14459 @@ -0,0 +1,56 @@
14460 +/* 
14461 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
14462 + * Licensed under the GPL
14463 + */
14464 +
14465 +#ifndef __CHAN_KERN_H__
14466 +#define __CHAN_KERN_H__
14467 +
14468 +#include "linux/tty.h"
14469 +#include "linux/list.h"
14470 +#include "chan_user.h"
14471 +
14472 +struct chan {
14473 +       struct list_head list;
14474 +       char *dev;
14475 +       unsigned int primary:1;
14476 +       unsigned int input:1;
14477 +       unsigned int output:1;
14478 +       unsigned int opened:1;
14479 +       int fd;
14480 +       enum chan_init_pri pri;
14481 +       struct chan_ops *ops;
14482 +       void *data;
14483 +};
14484 +
14485 +extern void chan_interrupt(struct list_head *chans, struct tq_struct *task,
14486 +                          struct tty_struct *tty, int irq, void *dev);
14487 +extern int parse_chan_pair(char *str, struct list_head *chans, int pri, 
14488 +                          int device, struct chan_opts *opts);
14489 +extern int open_chan(struct list_head *chans);
14490 +extern int write_chan(struct list_head *chans, const char *buf, int len,
14491 +                            int write_irq);
14492 +extern int console_write_chan(struct list_head *chans, const char *buf, 
14493 +                             int len);
14494 +extern void close_chan(struct list_head *chans);
14495 +extern void chan_enable_winch(struct list_head *chans, void *line);
14496 +extern void enable_chan(struct list_head *chans, void *data);
14497 +extern int chan_window_size(struct list_head *chans, 
14498 +                            unsigned short *rows_out, 
14499 +                            unsigned short *cols_out);
14500 +extern int chan_out_fd(struct list_head *chans);
14501 +extern int chan_config_string(struct list_head *chans, char *str, int size,
14502 +                             char **error_out);
14503 +
14504 +#endif
14505 +
14506 +/*
14507 + * Overrides for Emacs so that we follow Linus's tabbing style.
14508 + * Emacs will notice this stuff at the end of the file and automatically
14509 + * adjust the settings for this buffer only.  This must remain at the end
14510 + * of the file.
14511 + * ---------------------------------------------------------------------------
14512 + * Local variables:
14513 + * c-file-style: "linux"
14514 + * End:
14515 + */
14516 diff -Naur -X ../exclude-files orig/arch/um/include/chan_user.h um/arch/um/include/chan_user.h
14517 --- orig/arch/um/include/chan_user.h    1969-12-31 19:00:00.000000000 -0500
14518 +++ um/arch/um/include/chan_user.h      2003-10-21 03:26:06.000000000 -0400
14519 @@ -0,0 +1,66 @@
14520 +/* 
14521 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
14522 + * Licensed under the GPL
14523 + */
14524 +
14525 +#ifndef __CHAN_USER_H__
14526 +#define __CHAN_USER_H__
14527 +
14528 +#include "init.h"
14529 +
14530 +struct chan_opts {
14531 +       void (*announce)(char *dev_name, int dev);
14532 +       char *xterm_title;
14533 +       int raw;
14534 +       unsigned long tramp_stack;
14535 +       int in_kernel;
14536 +};
14537 +
14538 +enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE };
14539 +
14540 +struct chan_ops {
14541 +       char *type;
14542 +       void *(*init)(char *, int, struct chan_opts *);
14543 +       int (*open)(int, int, int, void *, char **);
14544 +       void (*close)(int, void *);
14545 +       int (*read)(int, char *, void *);
14546 +       int (*write)(int, const char *, int, void *);
14547 +       int (*console_write)(int, const char *, int, void *);
14548 +       int (*window_size)(int, void *, unsigned short *, unsigned short *);
14549 +       void (*free)(void *);
14550 +       int winch;
14551 +};
14552 +
14553 +extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops,
14554 +       xterm_ops;
14555 +
14556 +extern void generic_close(int fd, void *unused);
14557 +extern int generic_read(int fd, char *c_out, void *unused);
14558 +extern int generic_write(int fd, const char *buf, int n, void *unused);
14559 +extern int generic_console_write(int fd, const char *buf, int n, void *state);
14560 +extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
14561 +                              unsigned short *cols_out);
14562 +extern void generic_free(void *data);
14563 +
14564 +extern void register_winch(int fd, void *device_data);
14565 +extern void register_winch_irq(int fd, int tty_fd, int pid, void *line);
14566 +
14567 +#define __channel_help(fn, prefix) \
14568 +__uml_help(fn, prefix "[0-9]*=<channel description>\n" \
14569 +"    Attach a console or serial line to a host channel.  See\n" \
14570 +"    http://user-mode-linux.sourceforge.net/input.html for a complete\n" \
14571 +"    description of this switch.\n\n" \
14572 +);
14573 +
14574 +#endif
14575 +
14576 +/*
14577 + * Overrides for Emacs so that we follow Linus's tabbing style.
14578 + * Emacs will notice this stuff at the end of the file and automatically
14579 + * adjust the settings for this buffer only.  This must remain at the end
14580 + * of the file.
14581 + * ---------------------------------------------------------------------------
14582 + * Local variables:
14583 + * c-file-style: "linux"
14584 + * End:
14585 + */
14586 diff -Naur -X ../exclude-files orig/arch/um/include/choose-mode.h um/arch/um/include/choose-mode.h
14587 --- orig/arch/um/include/choose-mode.h  1969-12-31 19:00:00.000000000 -0500
14588 +++ um/arch/um/include/choose-mode.h    2003-10-21 03:26:06.000000000 -0400
14589 @@ -0,0 +1,35 @@
14590 +/* 
14591 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14592 + * Licensed under the GPL
14593 + */
14594 +
14595 +#ifndef __CHOOSE_MODE_H__
14596 +#define __CHOOSE_MODE_H__
14597 +
14598 +#include "uml-config.h"
14599 +
14600 +#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS)
14601 +#define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas))
14602 +
14603 +#elif defined(UML_CONFIG_MODE_SKAS)
14604 +#define CHOOSE_MODE(tt, skas) (skas)
14605 +
14606 +#elif defined(UML_CONFIG_MODE_TT)
14607 +#define CHOOSE_MODE(tt, skas) (tt)
14608 +#endif
14609 +
14610 +#define CHOOSE_MODE_PROC(tt, skas, args...) \
14611 +       CHOOSE_MODE(tt(args), skas(args))
14612 +
14613 +#endif
14614 +
14615 +/*
14616 + * Overrides for Emacs so that we follow Linus's tabbing style.
14617 + * Emacs will notice this stuff at the end of the file and automatically
14618 + * adjust the settings for this buffer only.  This must remain at the end
14619 + * of the file.
14620 + * ---------------------------------------------------------------------------
14621 + * Local variables:
14622 + * c-file-style: "linux"
14623 + * End:
14624 + */
14625 diff -Naur -X ../exclude-files orig/arch/um/include/frame.h um/arch/um/include/frame.h
14626 --- orig/arch/um/include/frame.h        1969-12-31 19:00:00.000000000 -0500
14627 +++ um/arch/um/include/frame.h  2003-10-21 03:26:06.000000000 -0400
14628 @@ -0,0 +1,53 @@
14629 +/* 
14630 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14631 + * Licensed under the GPL
14632 + */
14633 +
14634 +#ifndef __FRAME_H_
14635 +#define __FRAME_H_
14636 +
14637 +#include "sysdep/frame.h"
14638 +
14639 +struct frame_common {
14640 +       void *data;
14641 +       int len;
14642 +       int sig_index;
14643 +       int sr_index;
14644 +       int sr_relative;
14645 +       int sp_index;
14646 +       struct arch_frame_data arch;
14647 +};
14648 +
14649 +struct sc_frame {
14650 +       struct frame_common common;
14651 +       int sc_index;
14652 +};
14653 +
14654 +extern struct sc_frame signal_frame_sc;
14655 +
14656 +extern struct sc_frame signal_frame_sc_sr;
14657 +
14658 +struct si_frame {
14659 +       struct frame_common common;
14660 +       int sip_index;
14661 +       int si_index;
14662 +       int ucp_index;
14663 +       int uc_index;
14664 +};
14665 +
14666 +extern struct si_frame signal_frame_si;
14667 +
14668 +extern void capture_signal_stack(void);
14669 +
14670 +#endif
14671 +
14672 +/*
14673 + * Overrides for Emacs so that we follow Linus's tabbing style.
14674 + * Emacs will notice this stuff at the end of the file and automatically
14675 + * adjust the settings for this buffer only.  This must remain at the end
14676 + * of the file.
14677 + * ---------------------------------------------------------------------------
14678 + * Local variables:
14679 + * c-file-style: "linux"
14680 + * End:
14681 + */
14682 diff -Naur -X ../exclude-files orig/arch/um/include/frame_kern.h um/arch/um/include/frame_kern.h
14683 --- orig/arch/um/include/frame_kern.h   1969-12-31 19:00:00.000000000 -0500
14684 +++ um/arch/um/include/frame_kern.h     2003-10-21 03:26:06.000000000 -0400
14685 @@ -0,0 +1,34 @@
14686 +/* 
14687 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14688 + * Licensed under the GPL
14689 + */
14690 +
14691 +#ifndef __FRAME_KERN_H_
14692 +#define __FRAME_KERN_H_
14693 +
14694 +#include "frame.h"
14695 +#include "sysdep/frame_kern.h"
14696 +
14697 +extern int setup_signal_stack_sc(unsigned long stack_top, int sig, 
14698 +                                unsigned long handler,
14699 +                                void (*restorer)(void), 
14700 +                                struct pt_regs *regs, 
14701 +                                sigset_t *mask);
14702 +extern int setup_signal_stack_si(unsigned long stack_top, int sig, 
14703 +                                unsigned long handler, 
14704 +                                void (*restorer)(void), 
14705 +                                struct pt_regs *regs, siginfo_t *info, 
14706 +                                sigset_t *mask);
14707 +
14708 +#endif
14709 +
14710 +/*
14711 + * Overrides for Emacs so that we follow Linus's tabbing style.
14712 + * Emacs will notice this stuff at the end of the file and automatically
14713 + * adjust the settings for this buffer only.  This must remain at the end
14714 + * of the file.
14715 + * ---------------------------------------------------------------------------
14716 + * Local variables:
14717 + * c-file-style: "linux"
14718 + * End:
14719 + */
14720 diff -Naur -X ../exclude-files orig/arch/um/include/frame_user.h um/arch/um/include/frame_user.h
14721 --- orig/arch/um/include/frame_user.h   1969-12-31 19:00:00.000000000 -0500
14722 +++ um/arch/um/include/frame_user.h     2003-10-21 03:26:06.000000000 -0400
14723 @@ -0,0 +1,23 @@
14724 +/* 
14725 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14726 + * Licensed under the GPL
14727 + */
14728 +
14729 +#ifndef __FRAME_USER_H_
14730 +#define __FRAME_USER_H_
14731 +
14732 +#include "sysdep/frame_user.h"
14733 +#include "frame.h"
14734 +
14735 +#endif
14736 +
14737 +/*
14738 + * Overrides for Emacs so that we follow Linus's tabbing style.
14739 + * Emacs will notice this stuff at the end of the file and automatically
14740 + * adjust the settings for this buffer only.  This must remain at the end
14741 + * of the file.
14742 + * ---------------------------------------------------------------------------
14743 + * Local variables:
14744 + * c-file-style: "linux"
14745 + * End:
14746 + */
14747 diff -Naur -X ../exclude-files orig/arch/um/include/helper.h um/arch/um/include/helper.h
14748 --- orig/arch/um/include/helper.h       1969-12-31 19:00:00.000000000 -0500
14749 +++ um/arch/um/include/helper.h 2003-10-21 03:26:06.000000000 -0400
14750 @@ -0,0 +1,27 @@
14751 +/* 
14752 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14753 + * Licensed under the GPL
14754 + */
14755 +
14756 +#ifndef __HELPER_H__
14757 +#define __HELPER_H__
14758 +
14759 +extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
14760 +                     unsigned long *stack_out);
14761 +extern int run_helper_thread(int (*proc)(void *), void *arg, 
14762 +                            unsigned int flags, unsigned long *stack_out,
14763 +                            int stack_order);
14764 +extern int helper_wait(int pid);
14765 +
14766 +#endif
14767 +
14768 +/*
14769 + * Overrides for Emacs so that we follow Linus's tabbing style.
14770 + * Emacs will notice this stuff at the end of the file and automatically
14771 + * adjust the settings for this buffer only.  This must remain at the end
14772 + * of the file.
14773 + * ---------------------------------------------------------------------------
14774 + * Local variables:
14775 + * c-file-style: "linux"
14776 + * End:
14777 + */
14778 diff -Naur -X ../exclude-files orig/arch/um/include/init.h um/arch/um/include/init.h
14779 --- orig/arch/um/include/init.h 1969-12-31 19:00:00.000000000 -0500
14780 +++ um/arch/um/include/init.h   2003-10-21 03:26:06.000000000 -0400
14781 @@ -0,0 +1,114 @@
14782 +#ifndef _LINUX_UML_INIT_H
14783 +#define _LINUX_UML_INIT_H
14784 +
14785 +/* These macros are used to mark some functions or
14786 + * initialized data (doesn't apply to uninitialized data)
14787 + * as `initialization' functions. The kernel can take this
14788 + * as hint that the function is used only during the initialization
14789 + * phase and free up used memory resources after
14790 + *
14791 + * Usage:
14792 + * For functions:
14793 + *
14794 + * You should add __init immediately before the function name, like:
14795 + *
14796 + * static void __init initme(int x, int y)
14797 + * {
14798 + *    extern int z; z = x * y;
14799 + * }
14800 + *
14801 + * If the function has a prototype somewhere, you can also add
14802 + * __init between closing brace of the prototype and semicolon:
14803 + *
14804 + * extern int initialize_foobar_device(int, int, int) __init;
14805 + *
14806 + * For initialized data:
14807 + * You should insert __initdata between the variable name and equal
14808 + * sign followed by value, e.g.:
14809 + *
14810 + * static int init_variable __initdata = 0;
14811 + * static char linux_logo[] __initdata = { 0x32, 0x36, ... };
14812 + *
14813 + * Don't forget to initialize data not at file scope, i.e. within a function,
14814 + * as gcc otherwise puts the data into the bss section and not into the init
14815 + * section.
14816 + *
14817 + * Also note, that this data cannot be "const".
14818 + */
14819 +
14820 +#ifndef _LINUX_INIT_H
14821 +typedef int (*initcall_t)(void);
14822 +typedef void (*exitcall_t)(void);
14823 +
14824 +#define __init          __attribute__ ((__section__ (".text.init")))
14825 +#define __exit          __attribute__ ((unused, __section__(".text.exit")))
14826 +#define __initdata      __attribute__ ((__section__ (".data.init")))
14827 +
14828 +#endif
14829 +
14830 +#ifndef MODULE
14831 +struct uml_param {
14832 +        const char *str;
14833 +        int (*setup_func)(char *, int *);
14834 +};
14835 +
14836 +extern initcall_t __uml_initcall_start, __uml_initcall_end;
14837 +extern initcall_t __uml_postsetup_start, __uml_postsetup_end;
14838 +extern const char *__uml_help_start, *__uml_help_end;
14839 +#endif
14840 +
14841 +#define __uml_initcall(fn)                                             \
14842 +       static initcall_t __uml_initcall_##fn __uml_init_call = fn
14843 +
14844 +#define __uml_exitcall(fn)                                             \
14845 +       static exitcall_t __uml_exitcall_##fn __uml_exit_call = fn
14846 +
14847 +extern struct uml_param __uml_setup_start, __uml_setup_end;
14848 +
14849 +#define __uml_postsetup(fn)                                            \
14850 +       static initcall_t __uml_postsetup_##fn __uml_postsetup_call = fn
14851 +
14852 +#define __non_empty_string(dummyname,string)                           \
14853 +       struct __uml_non_empty_string_struct_##dummyname                \
14854 +       {                                                               \
14855 +               char _string[sizeof(string)-2];                         \
14856 +       }
14857 +
14858 +#ifndef MODULE
14859 +#define __uml_setup(str, fn, help...)                                  \
14860 +       __non_empty_string(fn ##_setup, str);                           \
14861 +       __uml_help(fn, help);                                           \
14862 +       static char __uml_setup_str_##fn[] __initdata = str;            \
14863 +       static struct uml_param __uml_setup_##fn __uml_init_setup = { __uml_setup_str_##fn, fn }
14864 +#else
14865 +#define __uml_setup(str, fn, help...)                                  \
14866 +
14867 +#endif
14868 +
14869 +#define __uml_help(fn, help...)                                                \
14870 +       __non_empty_string(fn ##__help, help);                          \
14871 +       static char __uml_help_str_##fn[] __initdata = help;            \
14872 +       static const char *__uml_help_##fn __uml_setup_help = __uml_help_str_##fn
14873 +
14874 +/*
14875 + * Mark functions and data as being only used at initialization
14876 + * or exit time.
14877 + */
14878 +#define __uml_init_setup       __attribute__ ((unused,__section__ (".uml.setup.init")))
14879 +#define __uml_setup_help       __attribute__ ((unused,__section__ (".uml.help.init")))
14880 +#define __uml_init_call                __attribute__ ((unused,__section__ (".uml.initcall.init")))
14881 +#define __uml_postsetup_call   __attribute__ ((unused,__section__ (".uml.postsetup.init")))
14882 +#define __uml_exit_call                __attribute__ ((unused,__section__ (".uml.exitcall.exit")))
14883 +
14884 +#endif /* _LINUX_UML_INIT_H */
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/initrd.h um/arch/um/include/initrd.h
14897 --- orig/arch/um/include/initrd.h       1969-12-31 19:00:00.000000000 -0500
14898 +++ um/arch/um/include/initrd.h 2003-10-21 03:26:06.000000000 -0400
14899 @@ -0,0 +1,22 @@
14900 +/*
14901 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
14902 + * Licensed under the GPL
14903 + */
14904 +
14905 +#ifndef __INITRD_USER_H__
14906 +#define __INITRD_USER_H__
14907 +
14908 +extern int load_initrd(char *filename, void *buf, int size);
14909 +
14910 +#endif
14911 +
14912 +/*
14913 + * Overrides for Emacs so that we follow Linus's tabbing style.
14914 + * Emacs will notice this stuff at the end of the file and automatically
14915 + * adjust the settings for this buffer only.  This must remain at the end
14916 + * of the file.
14917 + * ---------------------------------------------------------------------------
14918 + * Local variables:
14919 + * c-file-style: "linux"
14920 + * End:
14921 + */
14922 diff -Naur -X ../exclude-files orig/arch/um/include/irq_kern.h um/arch/um/include/irq_kern.h
14923 --- orig/arch/um/include/irq_kern.h     1969-12-31 19:00:00.000000000 -0500
14924 +++ um/arch/um/include/irq_kern.h       2003-10-21 03:26:06.000000000 -0400
14925 @@ -0,0 +1,27 @@
14926 +/* 
14927 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14928 + * Licensed under the GPL
14929 + */
14930 +
14931 +#ifndef __IRQ_KERN_H__
14932 +#define __IRQ_KERN_H__
14933 +
14934 +#include "linux/interrupt.h"
14935 +
14936 +extern int um_request_irq(unsigned int irq, int fd, int type,
14937 +                         void (*handler)(int, void *, struct pt_regs *),
14938 +                         unsigned long irqflags,  const char * devname,
14939 +                         void *dev_id);
14940 +
14941 +#endif
14942 +
14943 +/*
14944 + * Overrides for Emacs so that we follow Linus's tabbing style.
14945 + * Emacs will notice this stuff at the end of the file and automatically
14946 + * adjust the settings for this buffer only.  This must remain at the end
14947 + * of the file.
14948 + * ---------------------------------------------------------------------------
14949 + * Local variables:
14950 + * c-file-style: "linux"
14951 + * End:
14952 + */
14953 diff -Naur -X ../exclude-files orig/arch/um/include/irq_user.h um/arch/um/include/irq_user.h
14954 --- orig/arch/um/include/irq_user.h     1969-12-31 19:00:00.000000000 -0500
14955 +++ um/arch/um/include/irq_user.h       2003-10-21 03:26:06.000000000 -0400
14956 @@ -0,0 +1,35 @@
14957 +/* 
14958 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14959 + * Licensed under the GPL
14960 + */
14961 +
14962 +#ifndef __IRQ_USER_H__
14963 +#define __IRQ_USER_H__
14964 +
14965 +enum { IRQ_READ, IRQ_WRITE };
14966 +
14967 +extern void sigio_handler(int sig, union uml_pt_regs *regs);
14968 +extern int activate_fd(int irq, int fd, int type, void *dev_id);
14969 +extern void free_irq_by_irq_and_dev(int irq, void *dev_id);
14970 +extern void free_irq_by_fd(int fd);
14971 +extern void reactivate_fd(int fd, int irqnum);
14972 +extern void deactivate_fd(int fd, int irqnum);
14973 +extern void forward_interrupts(int pid);
14974 +extern void init_irq_signals(int on_sigstack);
14975 +extern void forward_ipi(int fd, int pid);
14976 +extern void free_irq_later(int irq, void *dev_id);
14977 +extern int activate_ipi(int fd, int pid);
14978 +extern unsigned long irq_lock(void);
14979 +extern void irq_unlock(unsigned long flags);
14980 +#endif
14981 +
14982 +/*
14983 + * Overrides for Emacs so that we follow Linus's tabbing style.
14984 + * Emacs will notice this stuff at the end of the file and automatically
14985 + * adjust the settings for this buffer only.  This must remain at the end
14986 + * of the file.
14987 + * ---------------------------------------------------------------------------
14988 + * Local variables:
14989 + * c-file-style: "linux"
14990 + * End:
14991 + */
14992 diff -Naur -X ../exclude-files orig/arch/um/include/kern.h um/arch/um/include/kern.h
14993 --- orig/arch/um/include/kern.h 1969-12-31 19:00:00.000000000 -0500
14994 +++ um/arch/um/include/kern.h   2003-10-21 03:26:06.000000000 -0400
14995 @@ -0,0 +1,48 @@
14996 +/* 
14997 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
14998 + * Licensed under the GPL
14999 + */
15000 +
15001 +#ifndef __KERN_H__
15002 +#define __KERN_H__
15003 +
15004 +/* These are all user-mode things which are convenient to call directly
15005 + * from kernel code and for which writing a wrapper is too much of a pain.
15006 + * The regular include files can't be included because this file is included
15007 + * only into kernel code, and user-space includes conflict with kernel
15008 + * includes.
15009 + */
15010 +
15011 +extern int errno;
15012 +
15013 +extern int clone(int (*proc)(void *), void *sp, int flags, void *data);
15014 +extern int sleep(int);
15015 +extern int printf(char *fmt, ...);
15016 +extern char *strerror(int errnum);
15017 +extern char *ptsname(int __fd);
15018 +extern int munmap(void *, int);
15019 +extern void *sbrk(int increment);
15020 +extern void *malloc(int size);
15021 +extern void perror(char *err);
15022 +extern int kill(int pid, int sig);
15023 +extern int getuid(void);
15024 +extern int pause(void);
15025 +extern int write(int, const void *, int);
15026 +extern int exit(int);
15027 +extern int close(int);
15028 +extern int read(unsigned int, char *, int);
15029 +extern int pipe(int *);
15030 +extern int sched_yield(void);
15031 +extern int ptrace(int op, int pid, long addr, long data);
15032 +#endif
15033 +
15034 +/*
15035 + * Overrides for Emacs so that we follow Linus's tabbing style.
15036 + * Emacs will notice this stuff at the end of the file and automatically
15037 + * adjust the settings for this buffer only.  This must remain at the end
15038 + * of the file.
15039 + * ---------------------------------------------------------------------------
15040 + * Local variables:
15041 + * c-file-style: "linux"
15042 + * End:
15043 + */
15044 diff -Naur -X ../exclude-files orig/arch/um/include/kern_util.h um/arch/um/include/kern_util.h
15045 --- orig/arch/um/include/kern_util.h    1969-12-31 19:00:00.000000000 -0500
15046 +++ um/arch/um/include/kern_util.h      2003-11-10 00:58:10.000000000 -0500
15047 @@ -0,0 +1,123 @@
15048 +/* 
15049 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
15050 + * Licensed under the GPL
15051 + */
15052 +
15053 +#ifndef __KERN_UTIL_H__
15054 +#define __KERN_UTIL_H__
15055 +
15056 +#include "sysdep/ptrace.h"
15057 +
15058 +extern int ncpus;
15059 +extern char *linux_prog;
15060 +extern char *gdb_init;
15061 +extern int kmalloc_ok;
15062 +extern int timer_irq_inited;
15063 +extern int jail;
15064 +extern int nsyscalls;
15065 +
15066 +#define UML_ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK))
15067 +#define UML_ROUND_UP(addr) \
15068 +       UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
15069 +
15070 +extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg);
15071 +extern unsigned long stack_sp(unsigned long page);
15072 +extern int kernel_thread_proc(void *data);
15073 +extern void syscall_segv(int sig);
15074 +extern int current_pid(void);
15075 +extern unsigned long alloc_stack(int order, int atomic);
15076 +extern int do_signal(int error);
15077 +extern int is_stack_fault(unsigned long sp);
15078 +extern unsigned long segv(unsigned long address, unsigned long ip, 
15079 +                         int is_write, int is_user, void *sc);
15080 +extern unsigned long handle_page_fault(unsigned long address, unsigned long ip,
15081 +                                      int is_write, int is_user, 
15082 +                                      int *code_out);
15083 +extern void syscall_ready(void);
15084 +extern int segv_syscall(void);
15085 +extern void kern_finish_exec(void *task, int new_pid, unsigned long stack);
15086 +extern int page_size(void);
15087 +extern int page_mask(void);
15088 +extern int need_finish_fork(void);
15089 +extern void free_stack(unsigned long stack, int order);
15090 +extern void add_input_request(int op, void (*proc)(int), void *arg);
15091 +extern int sys_execve(char *file, char **argv, char **env);
15092 +extern char *current_cmd(void);
15093 +extern void timer_handler(int sig, union uml_pt_regs *regs);
15094 +extern int set_signals(int enable);
15095 +extern void force_sigbus(void);
15096 +extern int pid_to_processor_id(int pid);
15097 +extern void block_signals(void);
15098 +extern void unblock_signals(void);
15099 +extern void deliver_signals(void *t);
15100 +extern int next_syscall_index(int max);
15101 +extern int next_trap_index(int max);
15102 +extern void cpu_idle(void);
15103 +extern void finish_fork(void);
15104 +extern void paging_init(void);
15105 +extern void init_flush_vm(void);
15106 +extern void *syscall_sp(void *t);
15107 +extern void syscall_trace(void);
15108 +extern int hz(void);
15109 +extern void idle_timer(void);
15110 +extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
15111 +extern int external_pid(void *t);
15112 +extern void boot_timer_handler(int sig);
15113 +extern void interrupt_end(void);
15114 +extern void initial_thread_cb(void (*proc)(void *), void *arg);
15115 +extern int debugger_signal(int status, int pid);
15116 +extern void debugger_parent_signal(int status, int pid);
15117 +extern void child_signal(int pid, int status);
15118 +extern int init_ptrace_proxy(int idle_pid, int startup, int stop);
15119 +extern int init_parent_proxy(int pid);
15120 +extern void check_stack_overflow(void *ptr);
15121 +extern void relay_signal(int sig, union uml_pt_regs *regs);
15122 +extern void not_implemented(void);
15123 +extern int user_context(unsigned long sp);
15124 +extern void timer_irq(union uml_pt_regs *regs);
15125 +extern void unprotect_stack(unsigned long stack);
15126 +extern void do_uml_exitcalls(void);
15127 +extern int attach_debugger(int idle_pid, int pid, int stop);
15128 +extern void bad_segv(unsigned long address, unsigned long ip, int is_write);
15129 +extern int config_gdb(char *str);
15130 +extern int remove_gdb(void);
15131 +extern char *uml_strdup(char *string);
15132 +extern void unprotect_kernel_mem(void);
15133 +extern void protect_kernel_mem(void);
15134 +extern void set_kmem_end(unsigned long);
15135 +extern void uml_cleanup(void);
15136 +extern void set_current(void *t);
15137 +extern void lock_signalled_task(void *t);
15138 +extern void IPI_handler(int cpu);
15139 +extern int jail_setup(char *line, int *add);
15140 +extern void *get_init_task(void);
15141 +extern int clear_user_proc(void *buf, int size);
15142 +extern int copy_to_user_proc(void *to, void *from, int size);
15143 +extern int copy_from_user_proc(void *to, void *from, int size);
15144 +extern int strlen_user_proc(char *str);
15145 +extern void bus_handler(int sig, union uml_pt_regs *regs);
15146 +extern void winch(int sig, union uml_pt_regs *regs);
15147 +extern long execute_syscall(void *r);
15148 +extern int smp_sigio_handler(void);
15149 +extern void *get_current(void);
15150 +extern struct task_struct *get_task(int pid, int require);
15151 +extern void machine_halt(void);
15152 +extern int is_syscall(unsigned long addr);
15153 +extern void arch_switch(void);
15154 +extern void free_irq(unsigned int, void *);
15155 +extern int um_in_interrupt(void);
15156 +extern int cpu(void);
15157 +extern unsigned long long time_stamp(void);
15158 +
15159 +#endif
15160 +
15161 +/*
15162 + * Overrides for Emacs so that we follow Linus's tabbing style.
15163 + * Emacs will notice this stuff at the end of the file and automatically
15164 + * adjust the settings for this buffer only.  This must remain at the end
15165 + * of the file.
15166 + * ---------------------------------------------------------------------------
15167 + * Local variables:
15168 + * c-file-style: "linux"
15169 + * End:
15170 + */
15171 diff -Naur -X ../exclude-files orig/arch/um/include/line.h um/arch/um/include/line.h
15172 --- orig/arch/um/include/line.h 1969-12-31 19:00:00.000000000 -0500
15173 +++ um/arch/um/include/line.h   2003-11-07 02:25:37.000000000 -0500
15174 @@ -0,0 +1,103 @@
15175 +/* 
15176 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15177 + * Licensed under the GPL
15178 + */
15179 +
15180 +#ifndef __LINE_H__
15181 +#define __LINE_H__
15182 +
15183 +#include "linux/list.h"
15184 +#include "linux/tqueue.h"
15185 +#include "linux/tty.h"
15186 +#include "asm/semaphore.h"
15187 +#include "chan_user.h"
15188 +#include "mconsole_kern.h"
15189 +
15190 +struct line_driver {
15191 +       char *name;
15192 +       char *devfs_name;
15193 +       short major;
15194 +       short minor_start;
15195 +       short type;
15196 +       short subtype;
15197 +       int read_irq;
15198 +       char *read_irq_name;
15199 +       int write_irq;
15200 +       char *write_irq_name;
15201 +       char *symlink_from;
15202 +       char *symlink_to;
15203 +       struct mc_device mc;
15204 +};
15205 +
15206 +struct line {
15207 +       char *init_str;
15208 +       int init_pri;
15209 +       struct list_head chan_list;
15210 +       int valid;
15211 +       int count;
15212 +       struct tty_struct *tty;
15213 +       struct semaphore sem;
15214 +       char *buffer;
15215 +       char *head;
15216 +       char *tail;
15217 +       int sigio;
15218 +       struct tq_struct task;
15219 +       struct line_driver *driver;
15220 +       int have_irq;
15221 +};
15222 +
15223 +#define LINE_INIT(str, d) \
15224 +       { init_str :    str, \
15225 +         init_pri :    INIT_STATIC, \
15226 +         chan_list :   { }, \
15227 +         valid :       1, \
15228 +         count :       0, \
15229 +         tty :         NULL, \
15230 +         sem :         { }, \
15231 +         buffer :      NULL, \
15232 +         head :        NULL, \
15233 +         tail :        NULL, \
15234 +         sigio :       0, \
15235 +         driver :      d, \
15236 +          have_irq :   0 }
15237 +
15238 +struct lines {
15239 +       int num;
15240 +};
15241 +
15242 +#define LINES_INIT(n) {  num :         n }
15243 +
15244 +extern void line_close(struct line *lines, struct tty_struct *tty);
15245 +extern int line_open(struct line *lines, struct tty_struct *tty, 
15246 +                    struct chan_opts *opts);
15247 +extern int line_setup(struct line *lines, int num, char *init, 
15248 +                     int all_allowed);
15249 +extern int line_write(struct line *line, struct tty_struct *tty, int from_user,
15250 +                     const char *buf, int len);
15251 +extern char *add_xterm_umid(char *base);
15252 +extern int line_setup_irq(int fd, int input, int output, void *data);
15253 +extern void line_close_chan(struct line *line);
15254 +extern void line_disable(struct line *line, int current_irq);
15255 +extern void line_register_devfs(struct lines *set, 
15256 +                               struct line_driver *line_driver, 
15257 +                               struct tty_driver *driver, struct line *lines,
15258 +                               int nlines);
15259 +extern void lines_init(struct line *lines, int nlines);
15260 +extern void close_lines(struct line *lines, int nlines);
15261 +extern int line_config(struct line *lines, int num, char *str);
15262 +extern int line_remove(struct line *lines, int num, char *str);
15263 +extern int line_get_config(char *dev, struct line *lines, int num, char *str, 
15264 +                          int size, char **error_out);
15265 +
15266 +#endif
15267 +
15268 +/*
15269 + * Overrides for Emacs so that we follow Linus's tabbing style.
15270 + * Emacs will notice this stuff at the end of the file and automatically
15271 + * adjust the settings for this buffer only.  This must remain at the end
15272 + * of the file.
15273 + * ---------------------------------------------------------------------------
15274 + * Local variables:
15275 + * c-file-style: "linux"
15276 + * End:
15277 + */
15278 diff -Naur -X ../exclude-files orig/arch/um/include/Makefile um/arch/um/include/Makefile
15279 --- orig/arch/um/include/Makefile       1969-12-31 19:00:00.000000000 -0500
15280 +++ um/arch/um/include/Makefile 2003-10-21 03:26:06.000000000 -0400
15281 @@ -0,0 +1,7 @@
15282 +all : sc.h
15283 +
15284 +sc.h : ../util/mk_sc
15285 +       ../util/mk_sc > $@
15286 +
15287 +../util/mk_sc :
15288 +       $(MAKE) -C ../util mk_sc
15289 diff -Naur -X ../exclude-files orig/arch/um/include/mconsole.h um/arch/um/include/mconsole.h
15290 --- orig/arch/um/include/mconsole.h     1969-12-31 19:00:00.000000000 -0500
15291 +++ um/arch/um/include/mconsole.h       2003-10-21 03:26:06.000000000 -0400
15292 @@ -0,0 +1,103 @@
15293 +/*
15294 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
15295 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15296 + * Licensed under the GPL
15297 + */
15298 +
15299 +#ifndef __MCONSOLE_H__
15300 +#define __MCONSOLE_H__
15301 +
15302 +#ifndef __KERNEL__
15303 +#include <stdint.h>
15304 +#define u32 uint32_t
15305 +#endif
15306 +
15307 +#define MCONSOLE_MAGIC (0xcafebabe)
15308 +#define MCONSOLE_MAX_DATA (512)
15309 +#define MCONSOLE_VERSION 2
15310 +
15311 +struct mconsole_request {
15312 +       u32 magic;
15313 +       u32 version;
15314 +       u32 len;
15315 +       char data[MCONSOLE_MAX_DATA];
15316 +};
15317 +
15318 +struct mconsole_reply {
15319 +       u32 err;
15320 +       u32 more;
15321 +       u32 len;
15322 +       char data[MCONSOLE_MAX_DATA];
15323 +};
15324 +
15325 +struct mconsole_notify {
15326 +       u32 magic;
15327 +       u32 version;    
15328 +       enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
15329 +              MCONSOLE_USER_NOTIFY } type;
15330 +       u32 len;
15331 +       char data[MCONSOLE_MAX_DATA];
15332 +};
15333 +
15334 +struct mc_request;
15335 +
15336 +enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
15337 +
15338 +struct mconsole_command
15339 +{
15340 +       char *command;
15341 +       void (*handler)(struct mc_request *req);
15342 +       enum mc_context context;
15343 +};
15344 +
15345 +struct mc_request
15346 +{
15347 +       int len;
15348 +       int as_interrupt;
15349 +
15350 +       int originating_fd;
15351 +       int originlen;
15352 +       unsigned char origin[128];                      /* sockaddr_un */
15353 +
15354 +       struct mconsole_request request;
15355 +       struct mconsole_command *cmd;
15356 +};
15357 +
15358 +extern char mconsole_socket_name[];
15359 +
15360 +extern int mconsole_unlink_socket(void);
15361 +extern int mconsole_reply(struct mc_request *req, char *reply, int err,
15362 +                         int more);
15363 +
15364 +extern void mconsole_version(struct mc_request *req);
15365 +extern void mconsole_help(struct mc_request *req);
15366 +extern void mconsole_halt(struct mc_request *req);
15367 +extern void mconsole_reboot(struct mc_request *req);
15368 +extern void mconsole_config(struct mc_request *req);
15369 +extern void mconsole_remove(struct mc_request *req);
15370 +extern void mconsole_sysrq(struct mc_request *req);
15371 +extern void mconsole_cad(struct mc_request *req);
15372 +extern void mconsole_stop(struct mc_request *req);
15373 +extern void mconsole_go(struct mc_request *req);
15374 +extern void mconsole_log(struct mc_request *req);
15375 +extern void mconsole_proc(struct mc_request *req);
15376 +
15377 +extern int mconsole_get_request(int fd, struct mc_request *req);
15378 +extern int mconsole_notify(char *sock_name, int type, const void *data, 
15379 +                          int len);
15380 +extern char *mconsole_notify_socket(void);
15381 +extern void lock_notify(void);
15382 +extern void unlock_notify(void);
15383 +
15384 +#endif
15385 +
15386 +/*
15387 + * Overrides for Emacs so that we follow Linus's tabbing style.
15388 + * Emacs will notice this stuff at the end of the file and automatically
15389 + * adjust the settings for this buffer only.  This must remain at the end
15390 + * of the file.
15391 + * ---------------------------------------------------------------------------
15392 + * Local variables:
15393 + * c-file-style: "linux"
15394 + * End:
15395 + */
15396 diff -Naur -X ../exclude-files orig/arch/um/include/mconsole_kern.h um/arch/um/include/mconsole_kern.h
15397 --- orig/arch/um/include/mconsole_kern.h        1969-12-31 19:00:00.000000000 -0500
15398 +++ um/arch/um/include/mconsole_kern.h  2003-10-21 03:26:06.000000000 -0400
15399 @@ -0,0 +1,62 @@
15400 +/*
15401 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15402 + * Licensed under the GPL
15403 + */
15404 +
15405 +#ifndef __MCONSOLE_KERN_H__
15406 +#define __MCONSOLE_KERN_H__
15407 +
15408 +#include "linux/config.h"
15409 +#include "linux/list.h"
15410 +#include "mconsole.h"
15411 +
15412 +struct mconsole_entry {
15413 +       struct list_head list;
15414 +       struct mc_request request;
15415 +};
15416 +
15417 +struct mc_device {
15418 +       struct list_head list;
15419 +       char *name;
15420 +       int (*config)(char *);
15421 +       int (*get_config)(char *, char *, int, char **);
15422 +       int (*remove)(char *);
15423 +};
15424 +
15425 +#define CONFIG_CHUNK(str, size, current, chunk, end) \
15426 +do { \
15427 +       current += strlen(chunk); \
15428 +       if(current >= size) \
15429 +               str = NULL; \
15430 +       if(str != NULL){ \
15431 +               strcpy(str, chunk); \
15432 +               str += strlen(chunk); \
15433 +       } \
15434 +       if(end) \
15435 +               current++; \
15436 +} while(0)
15437 +
15438 +#ifdef CONFIG_MCONSOLE
15439 +
15440 +extern void mconsole_register_dev(struct mc_device *new);
15441 +
15442 +#else
15443 +
15444 +static inline void mconsole_register_dev(struct mc_device *new)
15445 +{
15446 +}
15447 +
15448 +#endif
15449 +
15450 +#endif
15451 +
15452 +/*
15453 + * Overrides for Emacs so that we follow Linus's tabbing style.
15454 + * Emacs will notice this stuff at the end of the file and automatically
15455 + * adjust the settings for this buffer only.  This must remain at the end
15456 + * of the file.
15457 + * ---------------------------------------------------------------------------
15458 + * Local variables:
15459 + * c-file-style: "linux"
15460 + * End:
15461 + */
15462 diff -Naur -X ../exclude-files orig/arch/um/include/mem.h um/arch/um/include/mem.h
15463 --- orig/arch/um/include/mem.h  1969-12-31 19:00:00.000000000 -0500
15464 +++ um/arch/um/include/mem.h    2004-01-16 11:14:38.000000000 -0500
15465 @@ -0,0 +1,29 @@
15466 +/* 
15467 + * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com)
15468 + * Licensed under the GPL
15469 + */
15470 +
15471 +#ifndef __MEM_H__
15472 +#define __MEM_H__
15473 +
15474 +#include "linux/types.h"
15475 +
15476 +extern void set_kmem_end(unsigned long new);
15477 +extern int phys_mapping(unsigned long phys, __u64 *offset_out);
15478 +extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
15479 +extern int is_remapped(void *virt);
15480 +extern int physmem_remove_mapping(void *virt);
15481 +extern void physmem_forget_descriptor(int fd);
15482 +
15483 +#endif
15484 +
15485 +/*
15486 + * Overrides for Emacs so that we follow Linus's tabbing style.
15487 + * Emacs will notice this stuff at the end of the file and automatically
15488 + * adjust the settings for this buffer only.  This must remain at the end
15489 + * of the file.
15490 + * ---------------------------------------------------------------------------
15491 + * Local variables:
15492 + * c-file-style: "linux"
15493 + * End:
15494 + */
15495 diff -Naur -X ../exclude-files orig/arch/um/include/mem_kern.h um/arch/um/include/mem_kern.h
15496 --- orig/arch/um/include/mem_kern.h     1969-12-31 19:00:00.000000000 -0500
15497 +++ um/arch/um/include/mem_kern.h       2003-10-21 03:26:06.000000000 -0400
15498 @@ -0,0 +1,30 @@
15499 +/* 
15500 + * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com)
15501 + * Licensed under the GPL
15502 + */
15503 +
15504 +#ifndef __MEM_KERN_H__
15505 +#define __MEM_KERN_H__
15506 +
15507 +#include "linux/list.h"
15508 +#include "linux/types.h"
15509 +
15510 +struct remapper {
15511 +       struct list_head list;
15512 +       int (*proc)(int, unsigned long, int, __u64);
15513 +};
15514 +
15515 +extern void register_remapper(struct remapper *info);
15516 +
15517 +#endif
15518 +
15519 +/*
15520 + * Overrides for Emacs so that we follow Linus's tabbing style.
15521 + * Emacs will notice this stuff at the end of the file and automatically
15522 + * adjust the settings for this buffer only.  This must remain at the end
15523 + * of the file.
15524 + * ---------------------------------------------------------------------------
15525 + * Local variables:
15526 + * c-file-style: "linux"
15527 + * End:
15528 + */
15529 diff -Naur -X ../exclude-files orig/arch/um/include/mem_user.h um/arch/um/include/mem_user.h
15530 --- orig/arch/um/include/mem_user.h     1969-12-31 19:00:00.000000000 -0500
15531 +++ um/arch/um/include/mem_user.h       2004-01-10 00:11:06.000000000 -0500
15532 @@ -0,0 +1,81 @@
15533 +/*
15534 + * arch/um/include/mem_user.h
15535 + *
15536 + * BRIEF MODULE DESCRIPTION
15537 + * user side memory interface for support IO memory inside user mode linux
15538 + *
15539 + * Copyright (C) 2001 RidgeRun, Inc.
15540 + * Author: RidgeRun, Inc.
15541 + *         Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
15542 + *
15543 + *  This program is free software; you can redistribute  it and/or modify it
15544 + *  under  the terms of  the GNU General  Public License as published by the
15545 + *  Free Software Foundation;  either version 2 of the  License, or (at your
15546 + *  option) any later version.
15547 + *
15548 + *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
15549 + *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
15550 + *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
15551 + *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
15552 + *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15553 + *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
15554 + *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
15555 + *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
15556 + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
15557 + *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15558 + *
15559 + *  You should have received a copy of the  GNU General Public License along
15560 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
15561 + *  675 Mass Ave, Cambridge, MA 02139, USA.
15562 + */
15563 +
15564 +#ifndef _MEM_USER_H
15565 +#define _MEM_USER_H
15566 +
15567 +struct iomem_region {
15568 +       struct iomem_region *next;
15569 +       char *driver;
15570 +       int fd;
15571 +       int size;
15572 +       unsigned long phys;
15573 +       unsigned long virt;
15574 +};
15575 +
15576 +extern struct iomem_region *iomem_regions;
15577 +extern int iomem_size;
15578 +
15579 +#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
15580 +
15581 +extern unsigned long host_task_size;
15582 +extern unsigned long task_size;
15583 +
15584 +extern int init_mem_user(void);
15585 +extern int create_mem_file(unsigned long len);
15586 +extern void setup_memory(void *entry);
15587 +extern unsigned long find_iomem(char *driver, unsigned long *len_out);
15588 +extern int init_maps(unsigned long physmem, unsigned long iomem, 
15589 +                    unsigned long highmem);
15590 +extern unsigned long get_vm(unsigned long len);
15591 +extern void setup_physmem(unsigned long start, unsigned long usable,
15592 +                         unsigned long len, unsigned long highmem);
15593 +extern void add_iomem(char *name, int fd, unsigned long size);
15594 +extern unsigned long phys_offset(unsigned long phys);
15595 +extern void unmap_physmem(void);
15596 +extern void map_memory(unsigned long virt, unsigned long phys, 
15597 +                      unsigned long len, int r, int w, int x);
15598 +extern int protect_memory(unsigned long addr, unsigned long len, 
15599 +                         int r, int w, int x, int must_succeed);
15600 +extern unsigned long get_kmem_end(void);
15601 +
15602 +#endif
15603 +
15604 +/*
15605 + * Overrides for Emacs so that we follow Linus's tabbing style.
15606 + * Emacs will notice this stuff at the end of the file and automatically
15607 + * adjust the settings for this buffer only.  This must remain at the end
15608 + * of the file.
15609 + * ---------------------------------------------------------------------------
15610 + * Local variables:
15611 + * c-file-style: "linux"
15612 + * End:
15613 + */
15614 diff -Naur -X ../exclude-files orig/arch/um/include/mode.h um/arch/um/include/mode.h
15615 --- orig/arch/um/include/mode.h 1969-12-31 19:00:00.000000000 -0500
15616 +++ um/arch/um/include/mode.h   2003-10-21 03:26:06.000000000 -0400
15617 @@ -0,0 +1,30 @@
15618 +/* 
15619 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15620 + * Licensed under the GPL
15621 + */
15622 +
15623 +#ifndef __MODE_H__
15624 +#define __MODE_H__
15625 +
15626 +#include "uml-config.h"
15627 +
15628 +#ifdef UML_CONFIG_MODE_TT
15629 +#include "../kernel/tt/include/mode.h"
15630 +#endif
15631 +
15632 +#ifdef UML_CONFIG_MODE_SKAS
15633 +#include "../kernel/skas/include/mode.h"
15634 +#endif
15635 +
15636 +#endif
15637 +
15638 +/*
15639 + * Overrides for Emacs so that we follow Linus's tabbing style.
15640 + * Emacs will notice this stuff at the end of the file and automatically
15641 + * adjust the settings for this buffer only.  This must remain at the end
15642 + * of the file.
15643 + * ---------------------------------------------------------------------------
15644 + * Local variables:
15645 + * c-file-style: "linux"
15646 + * End:
15647 + */
15648 diff -Naur -X ../exclude-files orig/arch/um/include/mode_kern.h um/arch/um/include/mode_kern.h
15649 --- orig/arch/um/include/mode_kern.h    1969-12-31 19:00:00.000000000 -0500
15650 +++ um/arch/um/include/mode_kern.h      2003-10-21 03:26:06.000000000 -0400
15651 @@ -0,0 +1,30 @@
15652 +/* 
15653 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15654 + * Licensed under the GPL
15655 + */
15656 +
15657 +#ifndef __MODE_KERN_H__
15658 +#define __MODE_KERN_H__
15659 +
15660 +#include "linux/config.h"
15661 +
15662 +#ifdef CONFIG_MODE_TT
15663 +#include "../kernel/tt/include/mode_kern.h"
15664 +#endif
15665 +
15666 +#ifdef CONFIG_MODE_SKAS
15667 +#include "../kernel/skas/include/mode_kern.h"
15668 +#endif
15669 +
15670 +#endif
15671 +
15672 +/*
15673 + * Overrides for Emacs so that we follow Linus's tabbing style.
15674 + * Emacs will notice this stuff at the end of the file and automatically
15675 + * adjust the settings for this buffer only.  This must remain at the end
15676 + * of the file.
15677 + * ---------------------------------------------------------------------------
15678 + * Local variables:
15679 + * c-file-style: "linux"
15680 + * End:
15681 + */
15682 diff -Naur -X ../exclude-files orig/arch/um/include/net_kern.h um/arch/um/include/net_kern.h
15683 --- orig/arch/um/include/net_kern.h     1969-12-31 19:00:00.000000000 -0500
15684 +++ um/arch/um/include/net_kern.h       2003-10-21 03:26:06.000000000 -0400
15685 @@ -0,0 +1,81 @@
15686 +/* 
15687 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15688 + * Licensed under the GPL
15689 + */
15690 +
15691 +#ifndef __UM_NET_KERN_H
15692 +#define __UM_NET_KERN_H
15693 +
15694 +#include "linux/netdevice.h"
15695 +#include "linux/skbuff.h"
15696 +#include "linux/socket.h"
15697 +#include "linux/list.h"
15698 +
15699 +struct uml_net {
15700 +       struct list_head list;
15701 +       struct net_device *dev;
15702 +       int index;
15703 +       unsigned char mac[ETH_ALEN];
15704 +       int have_mac;
15705 +};
15706 +
15707 +struct uml_net_private {
15708 +       struct list_head list;
15709 +       spinlock_t lock;
15710 +       struct net_device *dev;
15711 +       struct timer_list tl;
15712 +       struct net_device_stats stats;
15713 +       int fd;
15714 +       unsigned char mac[ETH_ALEN];
15715 +       int have_mac;
15716 +       unsigned short (*protocol)(struct sk_buff *);
15717 +       int (*open)(void *);
15718 +       void (*close)(int, void *);
15719 +       void (*remove)(void *);
15720 +       int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
15721 +       int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
15722 +       
15723 +       void (*add_address)(unsigned char *, unsigned char *, void *);
15724 +       void (*delete_address)(unsigned char *, unsigned char *, void *);
15725 +       int (*set_mtu)(int mtu, void *);
15726 +       int user[1];
15727 +};
15728 +
15729 +struct net_kern_info {
15730 +       void (*init)(struct net_device *, void *);
15731 +       unsigned short (*protocol)(struct sk_buff *);
15732 +       int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
15733 +       int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
15734 +};
15735 +
15736 +struct transport {
15737 +       struct list_head list;
15738 +       char *name;
15739 +       int (*setup)(char *, char **, void *);
15740 +       struct net_user_info *user;
15741 +       struct net_kern_info *kern;
15742 +       int private_size;
15743 +       int setup_size;
15744 +};
15745 +
15746 +extern struct net_device *ether_init(int);
15747 +extern unsigned short ether_protocol(struct sk_buff *);
15748 +extern int setup_etheraddr(char *str, unsigned char *addr);
15749 +extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
15750 +extern int tap_setup_common(char *str, char *type, char **dev_name, 
15751 +                           char **mac_out, char **gate_addr);
15752 +extern void register_transport(struct transport *new);
15753 +extern unsigned short eth_protocol(struct sk_buff *skb);
15754 +
15755 +#endif
15756 +
15757 +/*
15758 + * Overrides for Emacs so that we follow Linus's tabbing style.
15759 + * Emacs will notice this stuff at the end of the file and automatically
15760 + * adjust the settings for this buffer only.  This must remain at the end
15761 + * of the file.
15762 + * ---------------------------------------------------------------------------
15763 + * Local variables:
15764 + * c-file-style: "linux"
15765 + * End:
15766 + */
15767 diff -Naur -X ../exclude-files orig/arch/um/include/net_user.h um/arch/um/include/net_user.h
15768 --- orig/arch/um/include/net_user.h     1969-12-31 19:00:00.000000000 -0500
15769 +++ um/arch/um/include/net_user.h       2003-10-21 03:26:06.000000000 -0400
15770 @@ -0,0 +1,66 @@
15771 +/* 
15772 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15773 + * Licensed under the GPL
15774 + */
15775 +
15776 +#ifndef __UM_NET_USER_H__
15777 +#define __UM_NET_USER_H__
15778 +
15779 +#define ETH_ADDR_LEN (6)
15780 +#define ETH_HEADER_ETHERTAP (16)
15781 +#define ETH_HEADER_OTHER (14)
15782 +#define ETH_MAX_PACKET (1500)
15783 +
15784 +#define UML_NET_VERSION (4)
15785 +
15786 +struct net_user_info {
15787 +       void (*init)(void *, void *);
15788 +       int (*open)(void *);
15789 +       void (*close)(int, void *);
15790 +       void (*remove)(void *);
15791 +       int (*set_mtu)(int mtu, void *);
15792 +       void (*add_address)(unsigned char *, unsigned char *, void *);
15793 +       void (*delete_address)(unsigned char *, unsigned char *, void *);
15794 +       int max_packet;
15795 +};
15796 +
15797 +extern void ether_user_init(void *data, void *dev);
15798 +extern void dev_ip_addr(void *d, char *buf, char *bin_buf);
15799 +extern void set_ether_mac(void *d, unsigned char *addr);
15800 +extern void iter_addresses(void *d, void (*cb)(unsigned char *, 
15801 +                                              unsigned char *, void *), 
15802 +                          void *arg);
15803 +
15804 +extern void *get_output_buffer(int *len_out);
15805 +extern void free_output_buffer(void *buffer);
15806 +
15807 +extern int tap_open_common(void *dev, char *gate_addr);
15808 +extern void tap_check_ips(char *gate_addr, char *eth_addr);
15809 +
15810 +extern void read_output(int fd, char *output_out, int len);
15811 +
15812 +extern int net_read(int fd, void *buf, int len);
15813 +extern int net_recvfrom(int fd, void *buf, int len);
15814 +extern int net_write(int fd, void *buf, int len);
15815 +extern int net_send(int fd, void *buf, int len);
15816 +extern int net_sendto(int fd, void *buf, int len, void *to, int sock_len);
15817 +
15818 +extern void open_addr(unsigned char *addr, unsigned char *netmask, void *arg);
15819 +extern void close_addr(unsigned char *addr, unsigned char *netmask, void *arg);
15820 +
15821 +extern char *split_if_spec(char *str, ...);
15822 +
15823 +extern int dev_netmask(void *d, void *m);
15824 +
15825 +#endif
15826 +
15827 +/*
15828 + * Overrides for Emacs so that we follow Linus's tabbing style.
15829 + * Emacs will notice this stuff at the end of the file and automatically
15830 + * adjust the settings for this buffer only.  This must remain at the end
15831 + * of the file.
15832 + * ---------------------------------------------------------------------------
15833 + * Local variables:
15834 + * c-file-style: "linux"
15835 + * End:
15836 + */
15837 diff -Naur -X ../exclude-files orig/arch/um/include/os.h um/arch/um/include/os.h
15838 --- orig/arch/um/include/os.h   1969-12-31 19:00:00.000000000 -0500
15839 +++ um/arch/um/include/os.h     2003-12-17 10:48:12.000000000 -0500
15840 @@ -0,0 +1,180 @@
15841 +/* 
15842 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15843 + * Licensed under the GPL
15844 + */
15845 +
15846 +#ifndef __OS_H__
15847 +#define __OS_H__
15848 +
15849 +#include "asm/types.h"
15850 +#include "../os/include/file.h"
15851 +
15852 +#define OS_TYPE_FILE 1 
15853 +#define OS_TYPE_DIR 2 
15854 +#define OS_TYPE_SYMLINK 3 
15855 +#define OS_TYPE_CHARDEV 4
15856 +#define OS_TYPE_BLOCKDEV 5
15857 +#define OS_TYPE_FIFO 6
15858 +#define OS_TYPE_SOCK 7
15859 +
15860 +/* os_access() flags */
15861 +#define OS_ACC_F_OK    0       /* Test for existence.  */
15862 +#define OS_ACC_X_OK    1       /* Test for execute permission.  */
15863 +#define OS_ACC_W_OK    2       /* Test for write permission.  */
15864 +#define OS_ACC_R_OK    4       /* Test for read permission.  */
15865 +#define OS_ACC_RW_OK   (OS_ACC_W_OK | OS_ACC_R_OK) /* Test for RW permission */
15866 +
15867 +/*
15868 + * types taken from stat_file() in hostfs_user.c
15869 + * (if they are wrong here, they are wrong there...).
15870 + */
15871 +struct uml_stat {
15872 +       int                ust_dev;        /* device */
15873 +       unsigned long long ust_ino;        /* inode */
15874 +       int                ust_mode;       /* protection */
15875 +       int                ust_nlink;      /* number of hard links */
15876 +       int                ust_uid;        /* user ID of owner */
15877 +       int                ust_gid;        /* group ID of owner */
15878 +       unsigned long long ust_size;       /* total size, in bytes */
15879 +       int                ust_blksize;    /* blocksize for filesystem I/O */
15880 +       unsigned long long ust_blocks;     /* number of blocks allocated */
15881 +       unsigned long      ust_atime;      /* time of last access */
15882 +       unsigned long      ust_mtime;      /* time of last modification */
15883 +       unsigned long      ust_ctime;      /* time of last change */
15884 +};
15885 +
15886 +struct openflags {
15887 +       unsigned int r : 1;
15888 +       unsigned int w : 1;
15889 +       unsigned int s : 1;     /* O_SYNC */
15890 +       unsigned int c : 1;     /* O_CREAT */
15891 +       unsigned int t : 1;     /* O_TRUNC */
15892 +       unsigned int a : 1;     /* O_APPEND */
15893 +       unsigned int e : 1;     /* O_EXCL */
15894 +       unsigned int cl : 1;    /* FD_CLOEXEC */
15895 +};
15896 +
15897 +#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
15898 +                                         .t = 0, .a = 0, .e = 0, .cl = 0 })
15899 +
15900 +static inline struct openflags of_read(struct openflags flags)
15901 +{
15902 +       flags.r = 1; 
15903 +       return(flags);
15904 +}
15905 +
15906 +static inline struct openflags of_write(struct openflags flags)
15907 +{
15908 +       flags.w = 1; 
15909 +       return(flags); 
15910 +}
15911 +
15912 +static inline struct openflags of_rdwr(struct openflags flags)
15913 +{
15914 +       return(of_read(of_write(flags)));
15915 +}
15916 +
15917 +static inline struct openflags of_set_rw(struct openflags flags, int r, int w)
15918 +{
15919 +       flags.r = r;
15920 +       flags.w = w;
15921 +       return(flags);
15922 +}
15923 +
15924 +static inline struct openflags of_sync(struct openflags flags)
15925 +{ 
15926 +       flags.s = 1; 
15927 +       return(flags); 
15928 +}
15929 +
15930 +static inline struct openflags of_create(struct openflags flags)
15931 +{ 
15932 +       flags.c = 1; 
15933 +       return(flags); 
15934 +}
15935
15936 +static inline struct openflags of_trunc(struct openflags flags)
15937 +{ 
15938 +       flags.t = 1; 
15939 +       return(flags); 
15940 +}
15941
15942 +static inline struct openflags of_append(struct openflags flags)
15943 +{ 
15944 +       flags.a = 1; 
15945 +       return(flags); 
15946 +}
15947
15948 +static inline struct openflags of_excl(struct openflags flags)
15949 +{ 
15950 +       flags.e = 1; 
15951 +       return(flags); 
15952 +}
15953 +
15954 +static inline struct openflags of_cloexec(struct openflags flags)
15955 +{ 
15956 +       flags.cl = 1; 
15957 +       return(flags); 
15958 +}
15959
15960 +extern int os_stat_file(const char *file_name, struct uml_stat *buf);
15961 +extern int os_stat_fd(const int fd, struct uml_stat *buf);
15962 +extern int os_access(const char *file, int mode);
15963 +extern void os_print_error(int error, const char* str);
15964 +extern int os_get_exec_close(int fd, int *close_on_exec);
15965 +extern int os_set_exec_close(int fd, int close_on_exec);
15966 +extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
15967 +extern int os_window_size(int fd, int *rows, int *cols);
15968 +extern int os_new_tty_pgrp(int fd, int pid);
15969 +extern int os_get_ifname(int fd, char *namebuf);
15970 +extern int os_set_slip(int fd);
15971 +extern int os_set_owner(int fd, int pid);
15972 +extern int os_sigio_async(int master, int slave);
15973 +extern int os_mode_fd(int fd, int mode);
15974 +
15975 +extern int os_seek_file(int fd, __u64 offset);
15976 +extern int os_open_file(char *file, struct openflags flags, int mode);
15977 +extern int os_read_file(int fd, void *buf, int len);
15978 +extern int os_write_file(int fd, const void *buf, int count);
15979 +extern int os_file_size(char *file, long long *size_out);
15980 +extern int os_file_modtime(char *file, unsigned long *modtime);
15981 +extern int os_pipe(int *fd, int stream, int close_on_exec);
15982 +extern int os_set_fd_async(int fd, int owner);
15983 +extern int os_set_fd_block(int fd, int blocking);
15984 +extern int os_accept_connection(int fd);
15985 +extern int os_create_unix_socket(char *file, int len, int close_on_exec);
15986 +extern int os_shutdown_socket(int fd, int r, int w);
15987 +extern void os_close_file(int fd);
15988 +extern int os_rcv_fd(int fd, int *helper_pid_out);
15989 +extern int create_unix_socket(char *file, int len, int close_on_exec);
15990 +extern int os_connect_socket(char *name);
15991 +extern int os_file_type(char *file);
15992 +extern int os_file_mode(char *file, struct openflags *mode_out);
15993 +extern int os_lock_file(int fd, int excl);
15994 +
15995 +extern unsigned long os_process_pc(int pid);
15996 +extern int os_process_parent(int pid);
15997 +extern void os_stop_process(int pid);
15998 +extern void os_kill_process(int pid, int reap_child);
15999 +extern void os_usr1_process(int pid);
16000 +extern int os_getpid(void);
16001 +
16002 +extern int os_map_memory(void *virt, int fd, unsigned long long off, 
16003 +                        unsigned long len, int r, int w, int x);
16004 +extern int os_protect_memory(void *addr, unsigned long len, 
16005 +                            int r, int w, int x);
16006 +extern int os_unmap_memory(void *addr, int len);
16007 +extern void os_flush_stdout(void);
16008 +
16009 +#endif
16010 +
16011 +/*
16012 + * Overrides for Emacs so that we follow Linus's tabbing style.
16013 + * Emacs will notice this stuff at the end of the file and automatically
16014 + * adjust the settings for this buffer only.  This must remain at the end
16015 + * of the file.
16016 + * ---------------------------------------------------------------------------
16017 + * Local variables:
16018 + * c-file-style: "linux"
16019 + * End:
16020 + */
16021 diff -Naur -X ../exclude-files orig/arch/um/include/process.h um/arch/um/include/process.h
16022 --- orig/arch/um/include/process.h      1969-12-31 19:00:00.000000000 -0500
16023 +++ um/arch/um/include/process.h        2003-10-21 03:26:06.000000000 -0400
16024 @@ -0,0 +1,25 @@
16025 +/* 
16026 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16027 + * Licensed under the GPL
16028 + */
16029 +
16030 +#ifndef __PROCESS_H__
16031 +#define __PROCESS_H__
16032 +
16033 +#include <asm/sigcontext.h>
16034 +
16035 +extern void sig_handler(int sig, struct sigcontext sc);
16036 +extern void alarm_handler(int sig, struct sigcontext sc);
16037 +
16038 +#endif
16039 +
16040 +/*
16041 + * Overrides for Emacs so that we follow Linus's tabbing style.
16042 + * Emacs will notice this stuff at the end of the file and automatically
16043 + * adjust the settings for this buffer only.  This must remain at the end
16044 + * of the file.
16045 + * ---------------------------------------------------------------------------
16046 + * Local variables:
16047 + * c-file-style: "linux"
16048 + * End:
16049 + */
16050 diff -Naur -X ../exclude-files orig/arch/um/include/ptrace_user.h um/arch/um/include/ptrace_user.h
16051 --- orig/arch/um/include/ptrace_user.h  1969-12-31 19:00:00.000000000 -0500
16052 +++ um/arch/um/include/ptrace_user.h    2003-10-21 03:26:06.000000000 -0400
16053 @@ -0,0 +1,18 @@
16054 +/* 
16055 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16056 + * Licensed under the GPL
16057 + */
16058 +
16059 +#ifndef __PTRACE_USER_H__
16060 +#define __PTRACE_USER_H__
16061 +
16062 +#include "sysdep/ptrace_user.h"
16063 +
16064 +extern int ptrace_getregs(long pid, unsigned long *regs_out);
16065 +extern int ptrace_setregs(long pid, unsigned long *regs_in);
16066 +extern int ptrace_getfpregs(long pid, unsigned long *regs_out);
16067 +extern void arch_enter_kernel(void *task, int pid);
16068 +extern void arch_leave_kernel(void *task, int pid);
16069 +extern void ptrace_pokeuser(unsigned long addr, unsigned long data);
16070 +
16071 +#endif
16072 diff -Naur -X ../exclude-files orig/arch/um/include/sigcontext.h um/arch/um/include/sigcontext.h
16073 --- orig/arch/um/include/sigcontext.h   1969-12-31 19:00:00.000000000 -0500
16074 +++ um/arch/um/include/sigcontext.h     2003-10-21 03:26:06.000000000 -0400
16075 @@ -0,0 +1,25 @@
16076 +/* 
16077 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
16078 + * Licensed under the GPL
16079 + */
16080 +
16081 +#ifndef __UML_SIGCONTEXT_H__
16082 +#define __UML_SIGCONTEXT_H__
16083 +
16084 +#include "sysdep/sigcontext.h"
16085 +
16086 +extern int sc_size(void *data);
16087 +extern void sc_to_sc(void *to_ptr, void *from_ptr);
16088 +
16089 +#endif
16090 +
16091 +/*
16092 + * Overrides for Emacs so that we follow Linus's tabbing style.
16093 + * Emacs will notice this stuff at the end of the file and automatically
16094 + * adjust the settings for this buffer only.  This must remain at the end
16095 + * of the file.
16096 + * ---------------------------------------------------------------------------
16097 + * Local variables:
16098 + * c-file-style: "linux"
16099 + * End:
16100 + */
16101 diff -Naur -X ../exclude-files orig/arch/um/include/sigio.h um/arch/um/include/sigio.h
16102 --- orig/arch/um/include/sigio.h        1969-12-31 19:00:00.000000000 -0500
16103 +++ um/arch/um/include/sigio.h  2003-10-21 03:26:06.000000000 -0400
16104 @@ -0,0 +1,28 @@
16105 +/* 
16106 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16107 + * Licensed under the GPL
16108 + */
16109 +
16110 +#ifndef __SIGIO_H__
16111 +#define __SIGIO_H__
16112 +
16113 +extern int write_sigio_irq(int fd);
16114 +extern int register_sigio_fd(int fd);
16115 +extern int read_sigio_fd(int fd);
16116 +extern int add_sigio_fd(int fd, int read);
16117 +extern int ignore_sigio_fd(int fd);
16118 +extern void sigio_lock(void);
16119 +extern void sigio_unlock(void);
16120 +
16121 +#endif
16122 +
16123 +/*
16124 + * Overrides for Emacs so that we follow Linus's tabbing style.
16125 + * Emacs will notice this stuff at the end of the file and automatically
16126 + * adjust the settings for this buffer only.  This must remain at the end
16127 + * of the file.
16128 + * ---------------------------------------------------------------------------
16129 + * Local variables:
16130 + * c-file-style: "linux"
16131 + * End:
16132 + */
16133 diff -Naur -X ../exclude-files orig/arch/um/include/signal_kern.h um/arch/um/include/signal_kern.h
16134 --- orig/arch/um/include/signal_kern.h  1969-12-31 19:00:00.000000000 -0500
16135 +++ um/arch/um/include/signal_kern.h    2003-10-21 03:26:06.000000000 -0400
16136 @@ -0,0 +1,22 @@
16137 +/* 
16138 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
16139 + * Licensed under the GPL
16140 + */
16141 +
16142 +#ifndef __SIGNAL_KERN_H__
16143 +#define __SIGNAL_KERN_H__
16144 +
16145 +extern int have_signals(void *t);
16146 +
16147 +#endif
16148 +
16149 +/*
16150 + * Overrides for Emacs so that we follow Linus's tabbing style.
16151 + * Emacs will notice this stuff at the end of the file and automatically
16152 + * adjust the settings for this buffer only.  This must remain at the end
16153 + * of the file.
16154 + * ---------------------------------------------------------------------------
16155 + * Local variables:
16156 + * c-file-style: "linux"
16157 + * End:
16158 + */
16159 diff -Naur -X ../exclude-files orig/arch/um/include/signal_user.h um/arch/um/include/signal_user.h
16160 --- orig/arch/um/include/signal_user.h  1969-12-31 19:00:00.000000000 -0500
16161 +++ um/arch/um/include/signal_user.h    2003-10-21 03:26:06.000000000 -0400
16162 @@ -0,0 +1,26 @@
16163 +/* 
16164 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
16165 + * Licensed under the GPL
16166 + */
16167 +
16168 +#ifndef __SIGNAL_USER_H__
16169 +#define __SIGNAL_USER_H__
16170 +
16171 +extern int signal_stack_size;
16172 +
16173 +extern int change_sig(int signal, int on);
16174 +extern void set_sigstack(void *stack, int size);
16175 +extern void set_handler(int sig, void (*handler)(int), int flags, ...);
16176 +
16177 +#endif
16178 +
16179 +/*
16180 + * Overrides for Emacs so that we follow Linus's tabbing style.
16181 + * Emacs will notice this stuff at the end of the file and automatically
16182 + * adjust the settings for this buffer only.  This must remain at the end
16183 + * of the file.
16184 + * ---------------------------------------------------------------------------
16185 + * Local variables:
16186 + * c-file-style: "linux"
16187 + * End:
16188 + */
16189 diff -Naur -X ../exclude-files orig/arch/um/include/skas_ptrace.h um/arch/um/include/skas_ptrace.h
16190 --- orig/arch/um/include/skas_ptrace.h  1969-12-31 19:00:00.000000000 -0500
16191 +++ um/arch/um/include/skas_ptrace.h    2003-10-21 03:26:06.000000000 -0400
16192 @@ -0,0 +1,36 @@
16193 +/* 
16194 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16195 + * Licensed under the GPL
16196 + */
16197 +
16198 +#ifndef __SKAS_PTRACE_H
16199 +#define __SKAS_PTRACE_H
16200 +
16201 +struct ptrace_faultinfo {
16202 +       int is_write;
16203 +       unsigned long addr;
16204 +};
16205 +
16206 +struct ptrace_ldt {
16207 +       int func;
16208 +       void *ptr;
16209 +       unsigned long bytecount;
16210 +};
16211 +
16212 +#define PTRACE_FAULTINFO 52
16213 +#define PTRACE_SIGPENDING 53
16214 +#define PTRACE_LDT 54
16215 +#define PTRACE_SWITCH_MM 55
16216 +
16217 +#endif
16218 +
16219 +/*
16220 + * Overrides for Emacs so that we follow Linus's tabbing style.
16221 + * Emacs will notice this stuff at the end of the file and automatically
16222 + * adjust the settings for this buffer only.  This must remain at the end
16223 + * of the file.
16224 + * ---------------------------------------------------------------------------
16225 + * Local variables:
16226 + * c-file-style: "linux"
16227 + * End:
16228 + */
16229 diff -Naur -X ../exclude-files orig/arch/um/include/syscall_user.h um/arch/um/include/syscall_user.h
16230 --- orig/arch/um/include/syscall_user.h 1969-12-31 19:00:00.000000000 -0500
16231 +++ um/arch/um/include/syscall_user.h   2003-10-21 03:26:06.000000000 -0400
16232 @@ -0,0 +1,23 @@
16233 +/* 
16234 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16235 + * Licensed under the GPL
16236 + */
16237 +
16238 +#ifndef __SYSCALL_USER_H
16239 +#define __SYSCALL_USER_H
16240 +
16241 +extern int record_syscall_start(int syscall);
16242 +extern void record_syscall_end(int index, int result);
16243 +
16244 +#endif
16245 +
16246 +/*
16247 + * Overrides for Emacs so that we follow Linus's tabbing style.
16248 + * Emacs will notice this stuff at the end of the file and automatically
16249 + * adjust the settings for this buffer only.  This must remain at the end
16250 + * of the file.
16251 + * ---------------------------------------------------------------------------
16252 + * Local variables:
16253 + * c-file-style: "linux"
16254 + * End:
16255 + */
16256 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/checksum.h um/arch/um/include/sysdep-i386/checksum.h
16257 --- orig/arch/um/include/sysdep-i386/checksum.h 1969-12-31 19:00:00.000000000 -0500
16258 +++ um/arch/um/include/sysdep-i386/checksum.h   2004-01-13 23:40:05.000000000 -0500
16259 @@ -0,0 +1,218 @@
16260 +/* 
16261 + * Licensed under the GPL
16262 + */
16263 +
16264 +#ifndef __UM_SYSDEP_CHECKSUM_H
16265 +#define __UM_SYSDEP_CHECKSUM_H
16266 +
16267 +#include "linux/string.h"
16268 +#include "asm/uaccess.h"
16269 +
16270 +/*
16271 + * computes the checksum of a memory block at buff, length len,
16272 + * and adds in "sum" (32-bit)
16273 + *
16274 + * returns a 32-bit number suitable for feeding into itself
16275 + * or csum_tcpudp_magic
16276 + *
16277 + * this function must be called with even lengths, except
16278 + * for the last fragment, which may be odd
16279 + *
16280 + * it's best to have buff aligned on a 32-bit boundary
16281 + */
16282 +unsigned int csum_partial(const unsigned char * buff, int len, 
16283 +                         unsigned int sum);
16284 +
16285 +/*
16286 + * the same as csum_partial, but copies from src while it
16287 + * checksums, and handles user-space pointer exceptions correctly, when needed.
16288 + *
16289 + * here even more important to align src and dst on a 32-bit (or even
16290 + * better 64-bit) boundary
16291 + */
16292 +
16293 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len, 
16294 +                                 int sum, int *err_ptr);
16295 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len, 
16296 +                                   int sum, int *err_ptr);
16297 +
16298 +/*
16299 + *     Note: when you get a NULL pointer exception here this means someone
16300 + *     passed in an incorrect kernel address to one of these functions.
16301 + *
16302 + *     If you use these functions directly please don't forget the
16303 + *     verify_area().
16304 + */
16305 +
16306 +static __inline__
16307 +unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
16308 +                                      int len, int sum)
16309 +{
16310 +       memcpy(dst, src, len);
16311 +       return(csum_partial(dst, len, sum));
16312 +}
16313 +
16314 +static __inline__
16315 +unsigned int csum_partial_copy_from_user(const char *src, char *dst,
16316 +                                        int len, int sum, int *err_ptr)
16317 +{
16318 +       return csum_partial_copy_from(src, dst, len, sum, err_ptr);
16319 +}
16320 +
16321 +/*
16322 + * These are the old (and unsafe) way of doing checksums, a warning message 
16323 + * will be printed if they are used and an exception occurs.
16324 + *
16325 + * these functions should go away after some time.
16326 + */
16327 +
16328 +#define csum_partial_copy_fromuser csum_partial_copy_from_user
16329 +unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
16330 +
16331 +/*
16332 + *     This is a version of ip_compute_csum() optimized for IP headers,
16333 + *     which always checksum on 4 octet boundaries.
16334 + *
16335 + *     By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
16336 + *     Arnt Gulbrandsen.
16337 + */
16338 +static inline unsigned short ip_fast_csum(unsigned char * iph,
16339 +                                         unsigned int ihl)
16340 +{
16341 +       unsigned int sum;
16342 +
16343 +       __asm__ __volatile__(
16344 +           "movl (%1), %0      ;\n"
16345 +           "subl $4, %2        ;\n"
16346 +           "jbe 2f             ;\n"
16347 +           "addl 4(%1), %0     ;\n"
16348 +           "adcl 8(%1), %0     ;\n"
16349 +           "adcl 12(%1), %0    ;\n"
16350 +"1:        adcl 16(%1), %0     ;\n"
16351 +           "lea 4(%1), %1      ;\n"
16352 +           "decl %2            ;\n"
16353 +           "jne 1b             ;\n"
16354 +           "adcl $0, %0        ;\n"
16355 +           "movl %0, %2        ;\n"
16356 +           "shrl $16, %0       ;\n"
16357 +           "addw %w2, %w0      ;\n"
16358 +           "adcl $0, %0        ;\n"
16359 +           "notl %0            ;\n"
16360 +"2:                            ;\n"
16361 +       /* Since the input registers which are loaded with iph and ipl
16362 +          are modified, we must also specify them as outputs, or gcc
16363 +          will assume they contain their original values. */
16364 +       : "=r" (sum), "=r" (iph), "=r" (ihl)
16365 +       : "1" (iph), "2" (ihl));
16366 +       return(sum);
16367 +}
16368 +
16369 +/*
16370 + *     Fold a partial checksum
16371 + */
16372 +
16373 +static inline unsigned int csum_fold(unsigned int sum)
16374 +{
16375 +       __asm__(
16376 +               "addl %1, %0            ;\n"
16377 +               "adcl $0xffff, %0       ;\n"
16378 +               : "=r" (sum)
16379 +               : "r" (sum << 16), "0" (sum & 0xffff0000)
16380 +       );
16381 +       return (~sum) >> 16;
16382 +}
16383 +
16384 +static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
16385 +                                                  unsigned long daddr,
16386 +                                                  unsigned short len,
16387 +                                                  unsigned short proto,
16388 +                                                  unsigned int sum)
16389 +{
16390 +    __asm__(
16391 +       "addl %1, %0    ;\n"
16392 +       "adcl %2, %0    ;\n"
16393 +       "adcl %3, %0    ;\n"
16394 +       "adcl $0, %0    ;\n"
16395 +       : "=r" (sum)
16396 +       : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum));
16397 +    return sum;
16398 +}
16399 +
16400 +/*
16401 + * computes the checksum of the TCP/UDP pseudo-header
16402 + * returns a 16-bit checksum, already complemented
16403 + */
16404 +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
16405 +                                                  unsigned long daddr,
16406 +                                                  unsigned short len,
16407 +                                                  unsigned short proto,
16408 +                                                  unsigned int sum)
16409 +{
16410 +       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
16411 +}
16412 +
16413 +/*
16414 + * this routine is used for miscellaneous IP-like checksums, mainly
16415 + * in icmp.c
16416 + */
16417 +
16418 +static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
16419 +{
16420 +    return csum_fold (csum_partial(buff, len, 0));
16421 +}
16422 +
16423 +#define _HAVE_ARCH_IPV6_CSUM
16424 +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
16425 +                                                    struct in6_addr *daddr,
16426 +                                                    __u32 len,
16427 +                                                    unsigned short proto,
16428 +                                                    unsigned int sum)
16429 +{
16430 +       __asm__(
16431 +               "addl 0(%1), %0         ;\n"
16432 +               "adcl 4(%1), %0         ;\n"
16433 +               "adcl 8(%1), %0         ;\n"
16434 +               "adcl 12(%1), %0        ;\n"
16435 +               "adcl 0(%2), %0         ;\n"
16436 +               "adcl 4(%2), %0         ;\n"
16437 +               "adcl 8(%2), %0         ;\n"
16438 +               "adcl 12(%2), %0        ;\n"
16439 +               "adcl %3, %0            ;\n"
16440 +               "adcl %4, %0            ;\n"
16441 +               "adcl $0, %0            ;\n"
16442 +               : "=&r" (sum)
16443 +               : "r" (saddr), "r" (daddr),
16444 +                 "r"(htonl(len)), "r"(htonl(proto)), "0"(sum));
16445 +
16446 +       return csum_fold(sum);
16447 +}
16448 +
16449 +/*
16450 + *     Copy and checksum to user
16451 + */
16452 +#define HAVE_CSUM_COPY_USER
16453 +static __inline__ unsigned int csum_and_copy_to_user(const char *src, 
16454 +                                                    char *dst, int len,
16455 +                                                    int sum, int *err_ptr)
16456 +{
16457 +       if (access_ok(VERIFY_WRITE, dst, len))
16458 +               return(csum_partial_copy_to(src, dst, len, sum, err_ptr));
16459 +
16460 +       if (len)
16461 +               *err_ptr = -EFAULT;
16462 +
16463 +       return -1; /* invalid checksum */
16464 +}
16465 +
16466 +#endif
16467 +
16468 +/*
16469 + * Overrides for Emacs so that we follow Linus's tabbing style.
16470 + * Emacs will notice this stuff at the end of the file and automatically
16471 + * adjust the settings for this buffer only.  This must remain at the end
16472 + * of the file.
16473 + * ---------------------------------------------------------------------------
16474 + * Local variables:
16475 + * c-file-style: "linux"
16476 + * End:
16477 + */
16478 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame.h um/arch/um/include/sysdep-i386/frame.h
16479 --- orig/arch/um/include/sysdep-i386/frame.h    1969-12-31 19:00:00.000000000 -0500
16480 +++ um/arch/um/include/sysdep-i386/frame.h      2003-10-21 03:26:06.000000000 -0400
16481 @@ -0,0 +1,29 @@
16482 +/* 
16483 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16484 + * Licensed under the GPL
16485 + */
16486 +
16487 +#ifndef __FRAME_I386_H
16488 +#define __FRAME_I386_H
16489 +
16490 +struct arch_frame_data_raw {
16491 +       unsigned long fp_start;
16492 +       unsigned long sr;
16493 +};
16494 +
16495 +struct arch_frame_data {
16496 +       int fpstate_size;
16497 +};
16498 +
16499 +#endif
16500 +
16501 +/*
16502 + * Overrides for Emacs so that we follow Linus's tabbing style.
16503 + * Emacs will notice this stuff at the end of the file and automatically
16504 + * adjust the settings for this buffer only.  This must remain at the end
16505 + * of the file.
16506 + * ---------------------------------------------------------------------------
16507 + * Local variables:
16508 + * c-file-style: "linux"
16509 + * End:
16510 + */
16511 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_kern.h um/arch/um/include/sysdep-i386/frame_kern.h
16512 --- orig/arch/um/include/sysdep-i386/frame_kern.h       1969-12-31 19:00:00.000000000 -0500
16513 +++ um/arch/um/include/sysdep-i386/frame_kern.h 2003-10-21 03:26:06.000000000 -0400
16514 @@ -0,0 +1,69 @@
16515 +/* 
16516 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16517 + * Licensed under the GPL
16518 + */
16519 +
16520 +#ifndef __FRAME_KERN_I386_H
16521 +#define __FRAME_KERN_I386_H
16522 +
16523 +/* This is called from sys_sigreturn.  It takes the sp at the point of the
16524 + * sigreturn system call and returns the address of the sigcontext struct
16525 + * on the stack.
16526 + */
16527 +
16528 +static inline void *sp_to_sc(unsigned long sp)
16529 +{
16530 +       return((void *) sp);
16531 +}
16532 +
16533 +static inline void *sp_to_uc(unsigned long sp)
16534 +{
16535 +       unsigned long uc;
16536 +
16537 +       uc = sp + signal_frame_si.uc_index - 
16538 +               signal_frame_si.common.sp_index - 4;
16539 +       return((void *) uc);
16540 +}
16541 +
16542 +static inline void *sp_to_rt_sc(unsigned long sp)
16543 +{
16544 +       unsigned long sc;
16545 +
16546 +       sc = sp - signal_frame_si.common.sp_index + 
16547 +               signal_frame_si.common.len - 4;
16548 +       return((void *) sc);
16549 +}
16550 +
16551 +static inline void *sp_to_mask(unsigned long sp)
16552 +{
16553 +       unsigned long mask;
16554 +
16555 +       mask = sp - signal_frame_sc.common.sp_index + 
16556 +               signal_frame_sc.common.len - 8;
16557 +       return((void *) mask);
16558 +}
16559 +
16560 +extern int sc_size(void *data);
16561 +
16562 +static inline void *sp_to_rt_mask(unsigned long sp)
16563 +{
16564 +       unsigned long mask;
16565 +
16566 +       mask = sp - signal_frame_si.common.sp_index + 
16567 +               signal_frame_si.common.len + 
16568 +               sc_size(&signal_frame_si.common.arch) - 4;
16569 +       return((void *) mask);
16570 +}
16571 +
16572 +#endif
16573 +
16574 +/*
16575 + * Overrides for Emacs so that we follow Linus's tabbing style.
16576 + * Emacs will notice this stuff at the end of the file and automatically
16577 + * adjust the settings for this buffer only.  This must remain at the end
16578 + * of the file.
16579 + * ---------------------------------------------------------------------------
16580 + * Local variables:
16581 + * c-file-style: "linux"
16582 + * End:
16583 + */
16584 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_user.h um/arch/um/include/sysdep-i386/frame_user.h
16585 --- orig/arch/um/include/sysdep-i386/frame_user.h       1969-12-31 19:00:00.000000000 -0500
16586 +++ um/arch/um/include/sysdep-i386/frame_user.h 2004-01-14 03:54:47.000000000 -0500
16587 @@ -0,0 +1,91 @@
16588 +/* 
16589 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16590 + * Licensed under the GPL
16591 + */
16592 +
16593 +#ifndef __FRAME_USER_I386_H
16594 +#define __FRAME_USER_I386_H
16595 +
16596 +#include <asm/page.h>
16597 +#include "sysdep/frame.h"
16598 +
16599 +/* This stuff is to calculate the size of the fp state struct at runtime
16600 + * because it has changed between 2.2 and 2.4 and it would be good for a
16601 + * UML compiled on one to work on the other.
16602 + * So, setup_arch_frame_raw fills in the arch struct with the raw data, which
16603 + * just contains the address of the end of the sigcontext.  This is invoked
16604 + * from the signal handler.
16605 + * setup_arch_frame uses that data to figure out what 
16606 + * arch_frame_data.fpstate_size should be.  It really has no idea, since it's
16607 + * not allowed to do sizeof(struct fpstate) but it's safe to consider that it's
16608 + * everything from the end of the sigcontext up to the top of the stack.  So,
16609 + * it masks off the page number to get the offset within the page and subtracts
16610 + * that from the page size, and that's how big the fpstate struct will be
16611 + * considered to be.
16612 + */
16613 +
16614 +static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data,
16615 +                                       void *end, unsigned long srp)
16616 +{
16617 +       unsigned long sr = *((unsigned long *) srp);
16618 +
16619 +       data->fp_start = (unsigned long) end;
16620 +       if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK))
16621 +               data->sr = sr;
16622 +       else data->sr = 0;
16623 +}
16624 +
16625 +static inline void setup_arch_frame(struct arch_frame_data_raw *in, 
16626 +                                   struct arch_frame_data *out)
16627 +{
16628 +       unsigned long fpstate_start = in->fp_start;
16629 +
16630 +       if(in->sr == 0){
16631 +               fpstate_start &= ~PAGE_MASK;
16632 +               out->fpstate_size = PAGE_SIZE - fpstate_start;
16633 +       }
16634 +       else {
16635 +               out->fpstate_size = in->sr - fpstate_start;
16636 +       }
16637 +}
16638 +
16639 +/* This figures out where on the stack the SA_RESTORER function address
16640 + * is stored.  For i386, it's the signal handler return address, so it's
16641 + * located next to the frame pointer.
16642 + * This is inlined, so __builtin_frame_address(0) is correct.  Otherwise,
16643 + * it would have to be __builtin_frame_address(1).
16644 + */
16645 +
16646 +#define frame_restorer() \
16647 +({ \
16648 +       unsigned long *fp; \
16649 +\
16650 +       fp = __builtin_frame_address(0); \
16651 +       ((unsigned long) (fp + 1)); \
16652 +})
16653 +
16654 +/* Similarly, this returns the value of sp when the handler was first
16655 + * entered.  This is used to calculate the proper sp when delivering
16656 + * signals.
16657 + */
16658 +
16659 +#define frame_sp() \
16660 +({ \
16661 +       unsigned long *fp; \
16662 +\
16663 +       fp = __builtin_frame_address(0); \
16664 +       ((unsigned long) (fp + 1)); \
16665 +})
16666 +
16667 +#endif
16668 +
16669 +/*
16670 + * Overrides for Emacs so that we follow Linus's tabbing style.
16671 + * Emacs will notice this stuff at the end of the file and automatically
16672 + * adjust the settings for this buffer only.  This must remain at the end
16673 + * of the file.
16674 + * ---------------------------------------------------------------------------
16675 + * Local variables:
16676 + * c-file-style: "linux"
16677 + * End:
16678 + */
16679 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace.h um/arch/um/include/sysdep-i386/ptrace.h
16680 --- orig/arch/um/include/sysdep-i386/ptrace.h   1969-12-31 19:00:00.000000000 -0500
16681 +++ um/arch/um/include/sysdep-i386/ptrace.h     2003-10-21 03:26:06.000000000 -0400
16682 @@ -0,0 +1,193 @@
16683 +/* 
16684 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16685 + * Licensed under the GPL
16686 + */
16687 +
16688 +#ifndef __SYSDEP_I386_PTRACE_H
16689 +#define __SYSDEP_I386_PTRACE_H
16690 +
16691 +#include "uml-config.h"
16692 +
16693 +#ifdef UML_CONFIG_MODE_TT
16694 +#include "ptrace-tt.h"
16695 +#endif
16696 +
16697 +#ifdef UML_CONFIG_MODE_SKAS
16698 +#include "ptrace-skas.h"
16699 +#endif
16700 +
16701 +#include "choose-mode.h"
16702 +
16703 +union uml_pt_regs {
16704 +#ifdef UML_CONFIG_MODE_TT
16705 +       struct tt_regs {
16706 +               long syscall;
16707 +               void *sc;
16708 +       } tt;
16709 +#endif
16710 +#ifdef UML_CONFIG_MODE_SKAS
16711 +       struct skas_regs {
16712 +               unsigned long regs[HOST_FRAME_SIZE];
16713 +               unsigned long fp[HOST_FP_SIZE];
16714 +               unsigned long xfp[HOST_XFP_SIZE];
16715 +               unsigned long fault_addr;
16716 +               unsigned long fault_type;
16717 +               unsigned long trap_type;
16718 +               long syscall;
16719 +               int is_user;
16720 +       } skas;
16721 +#endif
16722 +};
16723 +
16724 +#define EMPTY_UML_PT_REGS { }
16725 +
16726 +extern int mode_tt;
16727 +
16728 +#define UPT_SC(r) ((r)->tt.sc)
16729 +#define UPT_IP(r) \
16730 +       CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
16731 +#define UPT_SP(r) \
16732 +       CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
16733 +#define UPT_EFLAGS(r) \
16734 +       CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
16735 +#define UPT_EAX(r) \
16736 +       CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs))
16737 +#define UPT_EBX(r) \
16738 +       CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs))
16739 +#define UPT_ECX(r) \
16740 +       CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs))
16741 +#define UPT_EDX(r) \
16742 +       CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs))
16743 +#define UPT_ESI(r) \
16744 +       CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs))
16745 +#define UPT_EDI(r) \
16746 +       CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs))
16747 +#define UPT_EBP(r) \
16748 +       CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs))
16749 +#define UPT_ORIG_EAX(r) \
16750 +       CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
16751 +#define UPT_CS(r) \
16752 +       CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
16753 +#define UPT_SS(r) \
16754 +       CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs))
16755 +#define UPT_DS(r) \
16756 +       CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
16757 +#define UPT_ES(r) \
16758 +       CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
16759 +#define UPT_FS(r) \
16760 +       CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
16761 +#define UPT_GS(r) \
16762 +       CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
16763 +
16764 +#define UPT_SYSCALL_ARG1(r) UPT_EBX(r)
16765 +#define UPT_SYSCALL_ARG2(r) UPT_ECX(r)
16766 +#define UPT_SYSCALL_ARG3(r) UPT_EDX(r)
16767 +#define UPT_SYSCALL_ARG4(r) UPT_ESI(r)
16768 +#define UPT_SYSCALL_ARG5(r) UPT_EDI(r)
16769 +#define UPT_SYSCALL_ARG6(r) UPT_EBP(r)
16770 +
16771 +extern int user_context(unsigned long sp);
16772 +
16773 +#define UPT_IS_USER(r) \
16774 +       CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
16775 +
16776 +struct syscall_args {
16777 +       unsigned long args[6];
16778 +};
16779 +
16780 +#define SYSCALL_ARGS(r) ((struct syscall_args) \
16781 +                        { .args = { UPT_SYSCALL_ARG1(r), \
16782 +                                    UPT_SYSCALL_ARG2(r), \
16783 +                                   UPT_SYSCALL_ARG3(r), \
16784 +                                    UPT_SYSCALL_ARG4(r), \
16785 +                                   UPT_SYSCALL_ARG5(r), \
16786 +                                    UPT_SYSCALL_ARG6(r) } } )
16787 +
16788 +#define UPT_REG(regs, reg) \
16789 +       ({      unsigned long val; \
16790 +               switch(reg){ \
16791 +               case EIP: val = UPT_IP(regs); break; \
16792 +               case UESP: val = UPT_SP(regs); break; \
16793 +               case EAX: val = UPT_EAX(regs); break; \
16794 +               case EBX: val = UPT_EBX(regs); break; \
16795 +               case ECX: val = UPT_ECX(regs); break; \
16796 +               case EDX: val = UPT_EDX(regs); break; \
16797 +               case ESI: val = UPT_ESI(regs); break; \
16798 +               case EDI: val = UPT_EDI(regs); break; \
16799 +               case EBP: val = UPT_EBP(regs); break; \
16800 +               case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \
16801 +               case CS: val = UPT_CS(regs); break; \
16802 +               case SS: val = UPT_SS(regs); break; \
16803 +               case DS: val = UPT_DS(regs); break; \
16804 +               case ES: val = UPT_ES(regs); break; \
16805 +               case FS: val = UPT_FS(regs); break; \
16806 +               case GS: val = UPT_GS(regs); break; \
16807 +               case EFL: val = UPT_EFLAGS(regs); break; \
16808 +               default :  \
16809 +                       panic("Bad register in UPT_REG : %d\n", reg);  \
16810 +                       val = -1; \
16811 +               } \
16812 +               val; \
16813 +       })
16814 +       
16815 +
16816 +#define UPT_SET(regs, reg, val) \
16817 +       do { \
16818 +               switch(reg){ \
16819 +               case EIP: UPT_IP(regs) = val; break; \
16820 +               case UESP: UPT_SP(regs) = val; break; \
16821 +               case EAX: UPT_EAX(regs) = val; break; \
16822 +               case EBX: UPT_EBX(regs) = val; break; \
16823 +               case ECX: UPT_ECX(regs) = val; break; \
16824 +               case EDX: UPT_EDX(regs) = val; break; \
16825 +               case ESI: UPT_ESI(regs) = val; break; \
16826 +               case EDI: UPT_EDI(regs) = val; break; \
16827 +               case EBP: UPT_EBP(regs) = val; break; \
16828 +               case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \
16829 +               case CS: UPT_CS(regs) = val; break; \
16830 +               case SS: UPT_SS(regs) = val; break; \
16831 +               case DS: UPT_DS(regs) = val; break; \
16832 +               case ES: UPT_ES(regs) = val; break; \
16833 +               case FS: UPT_FS(regs) = val; break; \
16834 +               case GS: UPT_GS(regs) = val; break; \
16835 +               case EFL: UPT_EFLAGS(regs) = val; break; \
16836 +               default :  \
16837 +                       panic("Bad register in UPT_SET : %d\n", reg);  \
16838 +                       break; \
16839 +               } \
16840 +       } while (0)
16841 +
16842 +#define UPT_SET_SYSCALL_RETURN(r, res) \
16843 +       CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \
16844 +                    REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
16845 +
16846 +#define UPT_RESTART_SYSCALL(r) \
16847 +       CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
16848 +                   REGS_RESTART_SYSCALL((r)->skas.regs))
16849 +
16850 +#define UPT_ORIG_SYSCALL(r) UPT_EAX(r)
16851 +#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
16852 +#define UPT_SYSCALL_RET(r) UPT_EAX(r)
16853 +
16854 +#define UPT_SEGV_IS_FIXABLE(r) \
16855 +       CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
16856 +                    REGS_SEGV_IS_FIXABLE(&r->skas))
16857 +
16858 +#define UPT_FAULT_ADDR(r) \
16859 +       CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
16860 +
16861 +#define UPT_FAULT_WRITE(r) \
16862 +       CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
16863 +
16864 +#endif
16865 +
16866 +/*
16867 + * Overrides for Emacs so that we follow Linus's tabbing style.
16868 + * Emacs will notice this stuff at the end of the file and automatically
16869 + * adjust the settings for this buffer only.  This must remain at the end
16870 + * of the file.
16871 + * ---------------------------------------------------------------------------
16872 + * Local variables:
16873 + * c-file-style: "linux"
16874 + * End:
16875 + */
16876 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace_user.h um/arch/um/include/sysdep-i386/ptrace_user.h
16877 --- orig/arch/um/include/sysdep-i386/ptrace_user.h      1969-12-31 19:00:00.000000000 -0500
16878 +++ um/arch/um/include/sysdep-i386/ptrace_user.h        2003-10-21 03:26:06.000000000 -0400
16879 @@ -0,0 +1,62 @@
16880 +/* 
16881 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16882 + * Licensed under the GPL
16883 + */
16884 +
16885 +#ifndef __SYSDEP_I386_PTRACE_USER_H__
16886 +#define __SYSDEP_I386_PTRACE_USER_H__
16887 +
16888 +#include <asm/ptrace.h>
16889 +
16890 +#define PT_OFFSET(r) ((r) * sizeof(long))
16891 +
16892 +#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX])
16893 +#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX)
16894 +
16895 +#define PT_SYSCALL_ARG1_OFFSET PT_OFFSET(EBX)
16896 +#define PT_SYSCALL_ARG2_OFFSET PT_OFFSET(ECX)
16897 +#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX)
16898 +#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI)
16899 +#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI)
16900 +
16901 +#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX)
16902 +
16903 +#define PT_IP_OFFSET PT_OFFSET(EIP)
16904 +#define PT_IP(regs) ((regs)[EIP])
16905 +#define PT_SP(regs) ((regs)[UESP])
16906 +
16907 +#ifndef FRAME_SIZE
16908 +#define FRAME_SIZE (17)
16909 +#endif
16910 +#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long))
16911 +
16912 +#define FP_FRAME_SIZE (27)
16913 +#define FPX_FRAME_SIZE (128)
16914 +
16915 +#ifdef PTRACE_GETREGS
16916 +#define UM_HAVE_GETREGS
16917 +#endif
16918 +
16919 +#ifdef PTRACE_SETREGS
16920 +#define UM_HAVE_SETREGS
16921 +#endif
16922 +
16923 +#ifdef PTRACE_GETFPREGS
16924 +#define UM_HAVE_GETFPREGS
16925 +#endif
16926 +
16927 +#ifdef PTRACE_SETFPREGS
16928 +#define UM_HAVE_SETFPREGS
16929 +#endif
16930 +
16931 +#ifdef PTRACE_GETFPXREGS
16932 +#define UM_HAVE_GETFPXREGS
16933 +#endif
16934 +
16935 +#ifdef PTRACE_SETFPXREGS
16936 +#define UM_HAVE_SETFPXREGS
16937 +#endif
16938 +
16939 +extern void update_debugregs(int seq);
16940 +
16941 +#endif
16942 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/sigcontext.h um/arch/um/include/sysdep-i386/sigcontext.h
16943 --- orig/arch/um/include/sysdep-i386/sigcontext.h       1969-12-31 19:00:00.000000000 -0500
16944 +++ um/arch/um/include/sysdep-i386/sigcontext.h 2003-10-21 03:26:06.000000000 -0400
16945 @@ -0,0 +1,49 @@
16946 +/* 
16947 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16948 + * Licensed under the GPL
16949 + */
16950 +
16951 +#ifndef __SYS_SIGCONTEXT_I386_H
16952 +#define __SYS_SIGCONTEXT_I386_H
16953 +
16954 +#include "sc.h"
16955 +
16956 +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
16957 +
16958 +#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
16959 +#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
16960 +
16961 +#define SC_FAULT_ADDR(sc) SC_CR2(sc)
16962 +#define SC_FAULT_TYPE(sc) SC_ERR(sc)
16963 +
16964 +#define FAULT_WRITE(err) (err & 2)
16965 +#define TO_SC_ERR(is_write) ((is_write) ? 2 : 0)
16966 +
16967 +#define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc)))
16968 +
16969 +#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
16970 +
16971 +/* ptrace expects that, at the start of a system call, %eax contains
16972 + * -ENOSYS, so this makes it so.
16973 + */
16974 +#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
16975 +
16976 +/* This is Page Fault */
16977 +#define SEGV_IS_FIXABLE(trap) (trap == 14)
16978 +
16979 +#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
16980 +
16981 +extern unsigned long *sc_sigmask(void *sc_ptr);
16982 +extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
16983 +
16984 +#endif
16985 +/*
16986 + * Overrides for Emacs so that we follow Linus's tabbing style.
16987 + * Emacs will notice this stuff at the end of the file and automatically
16988 + * adjust the settings for this buffer only.  This must remain at the end
16989 + * of the file.
16990 + * ---------------------------------------------------------------------------
16991 + * Local variables:
16992 + * c-file-style: "linux"
16993 + * End:
16994 + */
16995 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/syscalls.h um/arch/um/include/sysdep-i386/syscalls.h
16996 --- orig/arch/um/include/sysdep-i386/syscalls.h 1969-12-31 19:00:00.000000000 -0500
16997 +++ um/arch/um/include/sysdep-i386/syscalls.h   2003-10-21 03:26:06.000000000 -0400
16998 @@ -0,0 +1,61 @@
16999 +/* 
17000 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17001 + * Licensed under the GPL
17002 + */
17003 +
17004 +#include "asm/unistd.h"
17005 +#include "sysdep/ptrace.h"
17006 +
17007 +typedef long syscall_handler_t(struct pt_regs);
17008 +
17009 +#define EXECUTE_SYSCALL(syscall, regs) \
17010 +       ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
17011 +
17012 +extern syscall_handler_t sys_modify_ldt;
17013 +extern syscall_handler_t old_mmap_i386;
17014 +extern syscall_handler_t old_select;
17015 +extern syscall_handler_t sys_ni_syscall;
17016 +
17017 +#define ARCH_SYSCALLS \
17018 +       [ __NR_mmap ] = old_mmap_i386, \
17019 +       [ __NR_select ] = old_select, \
17020 +       [ __NR_vm86old ] = sys_ni_syscall, \
17021 +        [ __NR_modify_ldt ] = sys_modify_ldt, \
17022 +       [ __NR_lchown32 ] = sys_lchown, \
17023 +       [ __NR_getuid32 ] = sys_getuid, \
17024 +       [ __NR_getgid32 ] = sys_getgid, \
17025 +       [ __NR_geteuid32 ] = sys_geteuid, \
17026 +       [ __NR_getegid32 ] = sys_getegid, \
17027 +       [ __NR_setreuid32 ] = sys_setreuid, \
17028 +       [ __NR_setregid32 ] = sys_setregid, \
17029 +       [ __NR_getgroups32 ] = sys_getgroups, \
17030 +       [ __NR_setgroups32 ] = sys_setgroups, \
17031 +       [ __NR_fchown32 ] = sys_fchown, \
17032 +       [ __NR_setresuid32 ] = sys_setresuid, \
17033 +       [ __NR_getresuid32 ] = sys_getresuid, \
17034 +       [ __NR_setresgid32 ] = sys_setresgid, \
17035 +       [ __NR_getresgid32 ] = sys_getresgid, \
17036 +       [ __NR_chown32 ] = sys_chown, \
17037 +       [ __NR_setuid32 ] = sys_setuid, \
17038 +       [ __NR_setgid32 ] = sys_setgid, \
17039 +       [ __NR_setfsuid32 ] = sys_setfsuid, \
17040 +       [ __NR_setfsgid32 ] = sys_setfsgid, \
17041 +       [ __NR_pivot_root ] = sys_pivot_root, \
17042 +       [ __NR_mincore ] = sys_mincore, \
17043 +       [ __NR_madvise ] = sys_madvise, \
17044 +        [ 222 ] = sys_ni_syscall, 
17045 +        
17046 +/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
17047 +
17048 +#define LAST_ARCH_SYSCALL 222
17049 +
17050 +/*
17051 + * Overrides for Emacs so that we follow Linus's tabbing style.
17052 + * Emacs will notice this stuff at the end of the file and automatically
17053 + * adjust the settings for this buffer only.  This must remain at the end
17054 + * of the file.
17055 + * ---------------------------------------------------------------------------
17056 + * Local variables:
17057 + * c-file-style: "linux"
17058 + * End:
17059 + */
17060 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/ptrace.h um/arch/um/include/sysdep-ia64/ptrace.h
17061 --- orig/arch/um/include/sysdep-ia64/ptrace.h   1969-12-31 19:00:00.000000000 -0500
17062 +++ um/arch/um/include/sysdep-ia64/ptrace.h     2003-10-21 03:26:06.000000000 -0400
17063 @@ -0,0 +1,26 @@
17064 +/* 
17065 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17066 + * Licensed under the GPL
17067 + */
17068 +
17069 +#ifndef __SYSDEP_IA64_PTRACE_H
17070 +#define __SYSDEP_IA64_PTRACE_H
17071 +
17072 +struct sys_pt_regs {
17073 +  int foo;
17074 +};
17075 +
17076 +#define EMPTY_REGS { 0 }
17077 +
17078 +#endif
17079 +
17080 +/*
17081 + * Overrides for Emacs so that we follow Linus's tabbing style.
17082 + * Emacs will notice this stuff at the end of the file and automatically
17083 + * adjust the settings for this buffer only.  This must remain at the end
17084 + * of the file.
17085 + * ---------------------------------------------------------------------------
17086 + * Local variables:
17087 + * c-file-style: "linux"
17088 + * End:
17089 + */
17090 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/sigcontext.h um/arch/um/include/sysdep-ia64/sigcontext.h
17091 --- orig/arch/um/include/sysdep-ia64/sigcontext.h       1969-12-31 19:00:00.000000000 -0500
17092 +++ um/arch/um/include/sysdep-ia64/sigcontext.h 2003-10-21 03:26:06.000000000 -0400
17093 @@ -0,0 +1,20 @@
17094 +/* 
17095 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17096 + * Licensed under the GPL
17097 + */
17098 +
17099 +#ifndef __SYSDEP_IA64_SIGCONTEXT_H
17100 +#define __SYSDEP_IA64_SIGCONTEXT_H
17101 +
17102 +#endif
17103 +
17104 +/*
17105 + * Overrides for Emacs so that we follow Linus's tabbing style.
17106 + * Emacs will notice this stuff at the end of the file and automatically
17107 + * adjust the settings for this buffer only.  This must remain at the end
17108 + * of the file.
17109 + * ---------------------------------------------------------------------------
17110 + * Local variables:
17111 + * c-file-style: "linux"
17112 + * End:
17113 + */
17114 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/syscalls.h um/arch/um/include/sysdep-ia64/syscalls.h
17115 --- orig/arch/um/include/sysdep-ia64/syscalls.h 1969-12-31 19:00:00.000000000 -0500
17116 +++ um/arch/um/include/sysdep-ia64/syscalls.h   2003-10-21 03:26:06.000000000 -0400
17117 @@ -0,0 +1,20 @@
17118 +/* 
17119 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17120 + * Licensed under the GPL
17121 + */
17122 +
17123 +#ifndef __SYSDEP_IA64_SYSCALLS_H
17124 +#define __SYSDEP_IA64_SYSCALLS_H
17125 +
17126 +#endif
17127 +
17128 +/*
17129 + * Overrides for Emacs so that we follow Linus's tabbing style.
17130 + * Emacs will notice this stuff at the end of the file and automatically
17131 + * adjust the settings for this buffer only.  This must remain at the end
17132 + * of the file.
17133 + * ---------------------------------------------------------------------------
17134 + * Local variables:
17135 + * c-file-style: "linux"
17136 + * End:
17137 + */
17138 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/ptrace.h um/arch/um/include/sysdep-ppc/ptrace.h
17139 --- orig/arch/um/include/sysdep-ppc/ptrace.h    1969-12-31 19:00:00.000000000 -0500
17140 +++ um/arch/um/include/sysdep-ppc/ptrace.h      2003-10-21 03:26:06.000000000 -0400
17141 @@ -0,0 +1,104 @@
17142 +/* 
17143 + * Licensed under the GPL
17144 + */
17145 +
17146 +#ifndef __SYS_PTRACE_PPC_H
17147 +#define __SYS_PTRACE_PPC_H
17148 +
17149 +#include "linux/config.h"
17150 +#include "linux/types.h"
17151 +
17152 +/* the following taken from <asm-ppc/ptrace.h> */
17153 +
17154 +#ifdef CONFIG_PPC64
17155 +#define PPC_REG unsigned long /*long*/
17156 +#else
17157 +#define PPC_REG unsigned long
17158 +#endif
17159 +struct sys_pt_regs_s {
17160 +       PPC_REG gpr[32];
17161 +       PPC_REG nip;
17162 +       PPC_REG msr;
17163 +       PPC_REG orig_gpr3;      /* Used for restarting system calls */
17164 +       PPC_REG ctr;
17165 +       PPC_REG link;
17166 +       PPC_REG xer;
17167 +       PPC_REG ccr;
17168 +       PPC_REG mq;             /* 601 only (not used at present) */
17169 +                               /* Used on APUS to hold IPL value. */
17170 +       PPC_REG trap;           /* Reason for being here */
17171 +       PPC_REG dar;            /* Fault registers */
17172 +       PPC_REG dsisr;
17173 +       PPC_REG result;         /* Result of a system call */
17174 +};
17175 +
17176 +#define NUM_REGS (sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG))
17177 +
17178 +struct sys_pt_regs {
17179 +    PPC_REG regs[sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG)];
17180 +};
17181 +
17182 +#define UM_MAX_REG (PT_FPR0)
17183 +#define UM_MAX_REG_OFFSET (UM_MAX_REG * sizeof(PPC_REG))
17184 +
17185 +#define EMPTY_REGS { { [ 0 ... NUM_REGS - 1] = 0 } }
17186 +
17187 +#define UM_REG(r, n) ((r)->regs[n])
17188 +
17189 +#define UM_SYSCALL_RET(r) UM_REG(r, PT_R3)
17190 +#define UM_SP(r) UM_REG(r, PT_R1)
17191 +#define UM_IP(r) UM_REG(r, PT_NIP)
17192 +#define UM_ELF_ZERO(r) UM_REG(r, PT_FPSCR)
17193 +#define UM_SYSCALL_NR(r) UM_REG(r, PT_R0)
17194 +#define UM_SYSCALL_ARG1(r) UM_REG(r, PT_ORIG_R3)
17195 +#define UM_SYSCALL_ARG2(r) UM_REG(r, PT_R4)
17196 +#define UM_SYSCALL_ARG3(r) UM_REG(r, PT_R5)
17197 +#define UM_SYSCALL_ARG4(r) UM_REG(r, PT_R6)
17198 +#define UM_SYSCALL_ARG5(r) UM_REG(r, PT_R7)
17199 +#define UM_SYSCALL_ARG6(r) UM_REG(r, PT_R8)
17200 +
17201 +#define UM_SYSCALL_NR_OFFSET (PT_R0 * sizeof(PPC_REG))
17202 +#define UM_SYSCALL_RET_OFFSET (PT_R3 * sizeof(PPC_REG))
17203 +#define UM_SYSCALL_ARG1_OFFSET (PT_R3 * sizeof(PPC_REG))
17204 +#define UM_SYSCALL_ARG2_OFFSET (PT_R4 * sizeof(PPC_REG))
17205 +#define UM_SYSCALL_ARG3_OFFSET (PT_R5 * sizeof(PPC_REG))
17206 +#define UM_SYSCALL_ARG4_OFFSET (PT_R6 * sizeof(PPC_REG))
17207 +#define UM_SYSCALL_ARG5_OFFSET (PT_R7 * sizeof(PPC_REG))
17208 +#define UM_SYSCALL_ARG6_OFFSET (PT_R8 * sizeof(PPC_REG))
17209 +#define UM_SP_OFFSET (PT_R1 * sizeof(PPC_REG))
17210 +#define UM_IP_OFFSET (PT_NIP * sizeof(PPC_REG))
17211 +#define UM_ELF_ZERO_OFFSET (PT_R3 * sizeof(PPC_REG))
17212 +
17213 +#define UM_SET_SYSCALL_RETURN(_regs, result)           \
17214 +do {                                                    \
17215 +        if (result < 0) {                              \
17216 +               (_regs)->regs[PT_CCR] |= 0x10000000;    \
17217 +               UM_SYSCALL_RET((_regs)) = -result;      \
17218 +        } else {                                       \
17219 +               UM_SYSCALL_RET((_regs)) = result;       \
17220 +        }                                               \
17221 +} while(0)
17222 +
17223 +extern void shove_aux_table(unsigned long sp);
17224 +#define UM_FIX_EXEC_STACK(sp) shove_aux_table(sp);
17225 +
17226 +/* These aren't actually defined.  The undefs are just to make sure
17227 + * everyone's clear on the concept.
17228 + */
17229 +#undef UML_HAVE_GETREGS
17230 +#undef UML_HAVE_GETFPREGS
17231 +#undef UML_HAVE_SETREGS
17232 +#undef UML_HAVE_SETFPREGS
17233 +
17234 +#endif
17235 +
17236 +/*
17237 + * Overrides for Emacs so that we follow Linus's tabbing style.
17238 + * Emacs will notice this stuff at the end of the file and automatically
17239 + * adjust the settings for this buffer only.  This must remain at the end
17240 + * of the file.
17241 + * ---------------------------------------------------------------------------
17242 + * Local variables:
17243 + * c-file-style: "linux"
17244 + * End:
17245 + */
17246 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/sigcontext.h um/arch/um/include/sysdep-ppc/sigcontext.h
17247 --- orig/arch/um/include/sysdep-ppc/sigcontext.h        1969-12-31 19:00:00.000000000 -0500
17248 +++ um/arch/um/include/sysdep-ppc/sigcontext.h  2003-10-21 03:26:06.000000000 -0400
17249 @@ -0,0 +1,62 @@
17250 +/* 
17251 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17252 + * Licensed under the GPL
17253 + */
17254 +
17255 +#ifndef __SYS_SIGCONTEXT_PPC_H
17256 +#define __SYS_SIGCONTEXT_PPC_H
17257 +
17258 +#define DSISR_WRITE 0x02000000
17259 +
17260 +#define SC_FAULT_ADDR(sc) ({ \
17261 +               struct sigcontext *_sc = (sc); \
17262 +               long retval = -1; \
17263 +               switch (_sc->regs->trap) { \
17264 +               case 0x300: \
17265 +                       /* data exception */ \
17266 +                       retval = _sc->regs->dar; \
17267 +                       break; \
17268 +               case 0x400: \
17269 +                       /* instruction exception */ \
17270 +                       retval = _sc->regs->nip; \
17271 +                       break; \
17272 +               default: \
17273 +                       panic("SC_FAULT_ADDR: unhandled trap type\n"); \
17274 +               } \
17275 +               retval; \
17276 +       })
17277 +
17278 +#define SC_FAULT_WRITE(sc) ({ \
17279 +               struct sigcontext *_sc = (sc); \
17280 +               long retval = -1; \
17281 +               switch (_sc->regs->trap) { \
17282 +               case 0x300: \
17283 +                       /* data exception */ \
17284 +                       retval = !!(_sc->regs->dsisr & DSISR_WRITE); \
17285 +                       break; \
17286 +               case 0x400: \
17287 +                       /* instruction exception: not a write */ \
17288 +                       retval = 0; \
17289 +                       break; \
17290 +               default: \
17291 +                       panic("SC_FAULT_ADDR: unhandled trap type\n"); \
17292 +               } \
17293 +               retval; \
17294 +       })
17295 +
17296 +#define SC_IP(sc) ((sc)->regs->nip)
17297 +#define SC_SP(sc) ((sc)->regs->gpr[1])
17298 +#define SEGV_IS_FIXABLE(sc) (1)
17299 +
17300 +#endif
17301 +
17302 +/*
17303 + * Overrides for Emacs so that we follow Linus's tabbing style.
17304 + * Emacs will notice this stuff at the end of the file and automatically
17305 + * adjust the settings for this buffer only.  This must remain at the end
17306 + * of the file.
17307 + * ---------------------------------------------------------------------------
17308 + * Local variables:
17309 + * c-file-style: "linux"
17310 + * End:
17311 + */
17312 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/syscalls.h um/arch/um/include/sysdep-ppc/syscalls.h
17313 --- orig/arch/um/include/sysdep-ppc/syscalls.h  1969-12-31 19:00:00.000000000 -0500
17314 +++ um/arch/um/include/sysdep-ppc/syscalls.h    2003-10-21 03:26:06.000000000 -0400
17315 @@ -0,0 +1,50 @@
17316 +/* 
17317 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17318 + * Licensed under the GPL
17319 + */
17320 +
17321 +typedef long syscall_handler_t(unsigned long arg1, unsigned long arg2,
17322 +                              unsigned long arg3, unsigned long arg4,
17323 +                              unsigned long arg5, unsigned long arg6);
17324 +
17325 +#define EXECUTE_SYSCALL(syscall, regs) \
17326 +        (*sys_call_table[syscall])(UM_SYSCALL_ARG1(&regs), \
17327 +                                  UM_SYSCALL_ARG2(&regs), \
17328 +                                  UM_SYSCALL_ARG3(&regs), \
17329 +                                  UM_SYSCALL_ARG4(&regs), \
17330 +                                  UM_SYSCALL_ARG5(&regs), \
17331 +                                  UM_SYSCALL_ARG6(&regs))
17332 +
17333 +extern syscall_handler_t sys_mincore;
17334 +extern syscall_handler_t sys_madvise;
17335 +
17336 +/* old_mmap needs the correct prototype since syscall_kern.c includes
17337 + * this file.
17338 + */
17339 +int old_mmap(unsigned long addr, unsigned long len,
17340 +            unsigned long prot, unsigned long flags,
17341 +            unsigned long fd, unsigned long offset);
17342 +
17343 +#define ARCH_SYSCALLS \
17344 +       [ __NR_modify_ldt ] = sys_ni_syscall, \
17345 +       [ __NR_pciconfig_read ] = sys_ni_syscall, \
17346 +       [ __NR_pciconfig_write ] = sys_ni_syscall, \
17347 +       [ __NR_pciconfig_iobase ] = sys_ni_syscall, \
17348 +       [ __NR_pivot_root ] = sys_ni_syscall, \
17349 +       [ __NR_multiplexer ] = sys_ni_syscall, \
17350 +       [ __NR_mmap ] = old_mmap, \
17351 +       [ __NR_madvise ] = sys_madvise, \
17352 +       [ __NR_mincore ] = sys_mincore, 
17353 +
17354 +#define LAST_ARCH_SYSCALL __NR_mincore
17355 +
17356 +/*
17357 + * Overrides for Emacs so that we follow Linus's tabbing style.
17358 + * Emacs will notice this stuff at the end of the file and automatically
17359 + * adjust the settings for this buffer only.  This must remain at the end
17360 + * of the file.
17361 + * ---------------------------------------------------------------------------
17362 + * Local variables:
17363 + * c-file-style: "linux"
17364 + * End:
17365 + */
17366 diff -Naur -X ../exclude-files orig/arch/um/include/sysrq.h um/arch/um/include/sysrq.h
17367 --- orig/arch/um/include/sysrq.h        1969-12-31 19:00:00.000000000 -0500
17368 +++ um/arch/um/include/sysrq.h  2003-10-21 03:26:06.000000000 -0400
17369 @@ -0,0 +1,6 @@
17370 +#ifndef __UM_SYSRQ_H
17371 +#define __UM_SYSRQ_H
17372 +
17373 +extern void show_trace(unsigned long *stack);
17374 +
17375 +#endif
17376 diff -Naur -X ../exclude-files orig/arch/um/include/tempfile.h um/arch/um/include/tempfile.h
17377 --- orig/arch/um/include/tempfile.h     1969-12-31 19:00:00.000000000 -0500
17378 +++ um/arch/um/include/tempfile.h       2003-10-21 03:26:06.000000000 -0400
17379 @@ -0,0 +1,21 @@
17380 +/* 
17381 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
17382 + * Licensed under the GPL
17383 + */
17384 +
17385 +#ifndef __TEMPFILE_H__
17386 +#define __TEMPFILE_H__
17387 +
17388 +extern int make_tempfile(const char *template, char **tempname, int do_unlink);
17389 +
17390 +#endif
17391 +/*
17392 + * Overrides for Emacs so that we follow Linus's tabbing style.
17393 + * Emacs will notice this stuff at the end of the file and automatically
17394 + * adjust the settings for this buffer only.  This must remain at the end
17395 + * of the file.
17396 + * ---------------------------------------------------------------------------
17397 + * Local variables:
17398 + * c-file-style: "linux"
17399 + * End:
17400 + */
17401 diff -Naur -X ../exclude-files orig/arch/um/include/time_user.h um/arch/um/include/time_user.h
17402 --- orig/arch/um/include/time_user.h    1969-12-31 19:00:00.000000000 -0500
17403 +++ um/arch/um/include/time_user.h      2003-10-21 03:26:06.000000000 -0400
17404 @@ -0,0 +1,17 @@
17405 +/* 
17406 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17407 + * Licensed under the GPL
17408 + */
17409 +
17410 +#ifndef __TIME_USER_H__
17411 +#define __TIME_USER_H__
17412 +
17413 +extern void timer(void);
17414 +extern void switch_timers(int to_real);
17415 +extern void set_interval(int timer_type);
17416 +extern void idle_sleep(int secs);
17417 +extern void enable_timer(void);
17418 +extern unsigned long time_lock(void);
17419 +extern void time_unlock(unsigned long);
17420 +
17421 +#endif
17422 diff -Naur -X ../exclude-files orig/arch/um/include/tlb.h um/arch/um/include/tlb.h
17423 --- orig/arch/um/include/tlb.h  1969-12-31 19:00:00.000000000 -0500
17424 +++ um/arch/um/include/tlb.h    2003-10-21 03:26:06.000000000 -0400
17425 @@ -0,0 +1,23 @@
17426 +/* 
17427 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17428 + * Licensed under the GPL
17429 + */
17430 +
17431 +#ifndef __TLB_H__
17432 +#define __TLB_H__
17433 +
17434 +extern void mprotect_kernel_vm(int w);
17435 +extern void force_flush_all(void);
17436 +
17437 +#endif
17438 +
17439 +/*
17440 + * Overrides for Emacs so that we follow Linus's tabbing style.
17441 + * Emacs will notice this stuff at the end of the file and automatically
17442 + * adjust the settings for this buffer only.  This must remain at the end
17443 + * of the file.
17444 + * ---------------------------------------------------------------------------
17445 + * Local variables:
17446 + * c-file-style: "linux"
17447 + * End:
17448 + */
17449 diff -Naur -X ../exclude-files orig/arch/um/include/ubd_user.h um/arch/um/include/ubd_user.h
17450 --- orig/arch/um/include/ubd_user.h     1969-12-31 19:00:00.000000000 -0500
17451 +++ um/arch/um/include/ubd_user.h       2003-10-21 03:26:06.000000000 -0400
17452 @@ -0,0 +1,79 @@
17453 +/* 
17454 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17455 + * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com)
17456 + * Licensed under the GPL
17457 + */
17458 +
17459 +#ifndef __UM_UBD_USER_H
17460 +#define __UM_UBD_USER_H
17461 +
17462 +#include "os.h"
17463 +
17464 +enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
17465 +
17466 +struct io_thread_req {
17467 +       enum ubd_req op;
17468 +       int fds[2];
17469 +       unsigned long offsets[2];
17470 +       unsigned long long offset;
17471 +       unsigned long length;
17472 +       char *buffer;
17473 +       int sectorsize;
17474 +       unsigned long sector_mask;
17475 +       unsigned long long cow_offset;
17476 +       unsigned long bitmap_words[2];
17477 +       int map_fd;
17478 +       unsigned long long map_offset;
17479 +       int error;
17480 +};
17481 +
17482 +extern int open_ubd_file(char *file, struct openflags *openflags, 
17483 +                        char **backing_file_out, int *bitmap_offset_out, 
17484 +                        unsigned long *bitmap_len_out, int *data_offset_out,
17485 +                        int *create_cow_out);
17486 +extern int create_cow_file(char *cow_file, char *backing_file, 
17487 +                          struct openflags flags, int sectorsize, 
17488 +                          int alignment, int *bitmap_offset_out, 
17489 +                          unsigned long *bitmap_len_out,
17490 +                          int *data_offset_out);
17491 +extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
17492 +extern int read_ubd_fs(int fd, void *buffer, int len);
17493 +extern int write_ubd_fs(int fd, char *buffer, int len);
17494 +extern int start_io_thread(unsigned long sp, int *fds_out);
17495 +extern void do_io(struct io_thread_req *req);
17496 +
17497 +static inline int ubd_test_bit(__u64 bit, unsigned char *data)
17498 +{
17499 +       __u64 n;
17500 +       int bits, off;
17501 +
17502 +       bits = sizeof(data[0]) * 8;
17503 +       n = bit / bits;
17504 +       off = bit % bits;
17505 +       return((data[n] & (1 << off)) != 0);
17506 +}
17507 +
17508 +static inline void ubd_set_bit(__u64 bit, unsigned char *data)
17509 +{
17510 +       __u64 n;
17511 +       int bits, off;
17512 +
17513 +       bits = sizeof(data[0]) * 8;
17514 +       n = bit / bits;
17515 +       off = bit % bits;
17516 +       data[n] |= (1 << off);
17517 +}
17518 +
17519 +
17520 +#endif
17521 +
17522 +/*
17523 + * Overrides for Emacs so that we follow Linus's tabbing style.
17524 + * Emacs will notice this stuff at the end of the file and automatically
17525 + * adjust the settings for this buffer only.  This must remain at the end
17526 + * of the file.
17527 + * ---------------------------------------------------------------------------
17528 + * Local variables:
17529 + * c-file-style: "linux"
17530 + * End:
17531 + */
17532 diff -Naur -X ../exclude-files orig/arch/um/include/umid.h um/arch/um/include/umid.h
17533 --- orig/arch/um/include/umid.h 1969-12-31 19:00:00.000000000 -0500
17534 +++ um/arch/um/include/umid.h   2003-10-21 03:26:06.000000000 -0400
17535 @@ -0,0 +1,22 @@
17536 +/*
17537 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
17538 + * Licensed under the GPL
17539 + */
17540 +
17541 +#ifndef __UMID_H__
17542 +#define __UMID_H__
17543 +
17544 +extern int umid_file_name(char *name, char *buf, int len);
17545 +
17546 +#endif
17547 +
17548 +/*
17549 + * Overrides for Emacs so that we follow Linus's tabbing style.
17550 + * Emacs will notice this stuff at the end of the file and automatically
17551 + * adjust the settings for this buffer only.  This must remain at the end
17552 + * of the file.
17553 + * ---------------------------------------------------------------------------
17554 + * Local variables:
17555 + * c-file-style: "linux"
17556 + * End:
17557 + */
17558 diff -Naur -X ../exclude-files orig/arch/um/include/uml_uaccess.h um/arch/um/include/uml_uaccess.h
17559 --- orig/arch/um/include/uml_uaccess.h  1969-12-31 19:00:00.000000000 -0500
17560 +++ um/arch/um/include/uml_uaccess.h    2003-10-21 03:26:06.000000000 -0400
17561 @@ -0,0 +1,28 @@
17562 +/*
17563 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
17564 + * Licensed under the GPL
17565 + */
17566 +
17567 +#ifndef __UML_UACCESS_H__
17568 +#define __UML_UACCESS_H__
17569 +
17570 +extern int __do_copy_to_user(void *to, const void *from, int n,
17571 +                                 void **fault_addr, void **fault_catcher);
17572 +extern unsigned long __do_user_copy(void *to, const void *from, int n,
17573 +                                   void **fault_addr, void **fault_catcher,
17574 +                                   void (*op)(void *to, const void *from,
17575 +                                              int n), int *faulted_out);
17576 +void __do_copy(void *to, const void *from, int n);
17577 +
17578 +#endif
17579 +
17580 +/*
17581 + * Overrides for Emacs so that we follow Linus's tabbing style.
17582 + * Emacs will notice this stuff at the end of the file and automatically
17583 + * adjust the settings for this buffer only.  This must remain at the end
17584 + * of the file.
17585 + * ---------------------------------------------------------------------------
17586 + * Local variables:
17587 + * c-file-style: "linux"
17588 + * End:
17589 + */
17590 diff -Naur -X ../exclude-files orig/arch/um/include/um_mmu.h um/arch/um/include/um_mmu.h
17591 --- orig/arch/um/include/um_mmu.h       1969-12-31 19:00:00.000000000 -0500
17592 +++ um/arch/um/include/um_mmu.h 2003-10-21 03:26:06.000000000 -0400
17593 @@ -0,0 +1,40 @@
17594 +/* 
17595 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17596 + * Licensed under the GPL
17597 + */
17598 +
17599 +#ifndef __ARCH_UM_MMU_H
17600 +#define __ARCH_UM_MMU_H
17601 +
17602 +#include "linux/config.h"
17603 +#include "choose-mode.h"
17604 +
17605 +#ifdef CONFIG_MODE_TT
17606 +#include "../kernel/tt/include/mmu.h"
17607 +#endif
17608 +
17609 +#ifdef CONFIG_MODE_SKAS
17610 +#include "../kernel/skas/include/mmu.h"
17611 +#endif
17612 +
17613 +typedef union {
17614 +#ifdef CONFIG_MODE_TT
17615 +       struct mmu_context_tt tt;
17616 +#endif
17617 +#ifdef CONFIG_MODE_SKAS
17618 +       struct mmu_context_skas skas;
17619 +#endif
17620 +} mm_context_t;
17621 +
17622 +#endif
17623 +
17624 +/*
17625 + * Overrides for Emacs so that we follow Linus's tabbing style.
17626 + * Emacs will notice this stuff at the end of the file and automatically
17627 + * adjust the settings for this buffer only.  This must remain at the end
17628 + * of the file.
17629 + * ---------------------------------------------------------------------------
17630 + * Local variables:
17631 + * c-file-style: "linux"
17632 + * End:
17633 + */
17634 diff -Naur -X ../exclude-files orig/arch/um/include/umn.h um/arch/um/include/umn.h
17635 --- orig/arch/um/include/umn.h  1969-12-31 19:00:00.000000000 -0500
17636 +++ um/arch/um/include/umn.h    2003-10-21 03:26:06.000000000 -0400
17637 @@ -0,0 +1,27 @@
17638 +/* 
17639 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17640 + * Licensed under the GPL
17641 + */
17642 +
17643 +#ifndef __UMN_H
17644 +#define __UMN_H
17645 +
17646 +extern int open_umn_tty(int *slave_out, int *slipno_out);
17647 +extern void close_umn_tty(int master, int slave);
17648 +extern int umn_send_packet(int fd, void *data, int len);
17649 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
17650 +extern void slip_unesc(unsigned char s);
17651 +extern void umn_read(int fd);
17652 +
17653 +#endif
17654 +
17655 +/*
17656 + * Overrides for Emacs so that we follow Linus's tabbing style.
17657 + * Emacs will notice this stuff at the end of the file and automatically
17658 + * adjust the settings for this buffer only.  This must remain at the end
17659 + * of the file.
17660 + * ---------------------------------------------------------------------------
17661 + * Local variables:
17662 + * c-file-style: "linux"
17663 + * End:
17664 + */
17665 diff -Naur -X ../exclude-files orig/arch/um/include/um_uaccess.h um/arch/um/include/um_uaccess.h
17666 --- orig/arch/um/include/um_uaccess.h   1969-12-31 19:00:00.000000000 -0500
17667 +++ um/arch/um/include/um_uaccess.h     2003-10-21 03:26:06.000000000 -0400
17668 @@ -0,0 +1,124 @@
17669 +/* 
17670 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17671 + * Licensed under the GPL
17672 + */
17673 +
17674 +#ifndef __ARCH_UM_UACCESS_H
17675 +#define __ARCH_UM_UACCESS_H
17676 +
17677 +#include "linux/config.h"
17678 +#include "choose-mode.h"
17679 +
17680 +#ifdef CONFIG_MODE_TT
17681 +#include "../kernel/tt/include/uaccess.h"
17682 +#endif
17683 +
17684 +#ifdef CONFIG_MODE_SKAS
17685 +#include "../kernel/skas/include/uaccess.h"
17686 +#endif
17687 +
17688 +#define access_ok(type, addr, size) \
17689 +       CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
17690 +
17691 +static inline int verify_area(int type, const void * addr, unsigned long size)
17692 +{
17693 +       return(CHOOSE_MODE_PROC(verify_area_tt, verify_area_skas, type, addr,
17694 +                               size));
17695 +}
17696 +
17697 +static inline int copy_from_user(void *to, const void *from, int n)
17698 +{
17699 +       return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to,
17700 +                               from, n));
17701 +}
17702 +
17703 +static inline int copy_to_user(void *to, const void *from, int n)
17704 +{
17705 +       return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to, 
17706 +                               from, n));
17707 +}
17708 +
17709 +/*
17710 + * strncpy_from_user: - Copy a NUL terminated string from userspace.
17711 + * @dst:   Destination address, in kernel space.  This buffer must be at
17712 + *         least @count bytes long.
17713 + * @src:   Source address, in user space.
17714 + * @count: Maximum number of bytes to copy, including the trailing NUL.
17715 + * 
17716 + * Copies a NUL-terminated string from userspace to kernel space.
17717 + *
17718 + * On success, returns the length of the string (not including the trailing
17719 + * NUL).
17720 + *
17721 + * If access to userspace fails, returns -EFAULT (some data may have been
17722 + * copied).
17723 + *
17724 + * If @count is smaller than the length of the string, copies @count bytes
17725 + * and returns @count.
17726 + */
17727 +
17728 +static inline int strncpy_from_user(char *dst, const char *src, int count)
17729 +{
17730 +       return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
17731 +                               dst, src, count));
17732 +}
17733 +
17734 +/*
17735 + * __clear_user: - Zero a block of memory in user space, with less checking.
17736 + * @to:   Destination address, in user space.
17737 + * @n:    Number of bytes to zero.
17738 + *
17739 + * Zero a block of memory in user space.  Caller must check
17740 + * the specified block with access_ok() before calling this function.
17741 + *
17742 + * Returns number of bytes that could not be cleared.
17743 + * On success, this will be zero.
17744 + */
17745 +static inline int __clear_user(void *mem, int len)
17746 +{
17747 +       return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
17748 +}
17749 +
17750 +/*
17751 + * clear_user: - Zero a block of memory in user space.
17752 + * @to:   Destination address, in user space.
17753 + * @n:    Number of bytes to zero.
17754 + *
17755 + * Zero a block of memory in user space.
17756 + *
17757 + * Returns number of bytes that could not be cleared.
17758 + * On success, this will be zero.
17759 + */
17760 +static inline int clear_user(void *mem, int len)
17761 +{
17762 +       return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
17763 +}
17764 +
17765 +/*
17766 + * strlen_user: - Get the size of a string in user space.
17767 + * @str: The string to measure.
17768 + * @n:   The maximum valid length
17769 + *
17770 + * Get the size of a NUL-terminated string in user space.
17771 + *
17772 + * Returns the size of the string INCLUDING the terminating NUL.
17773 + * On exception, returns 0.
17774 + * If the string is too long, returns a value greater than @n.
17775 + */
17776 +static inline int strnlen_user(const void *str, int len)
17777 +{
17778 +       return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
17779 +}
17780 +
17781 +#endif
17782 +
17783 +/*
17784 + * Overrides for Emacs so that we follow Linus's tabbing style.
17785 + * Emacs will notice this stuff at the end of the file and automatically
17786 + * adjust the settings for this buffer only.  This must remain at the end
17787 + * of the file.
17788 + * ---------------------------------------------------------------------------
17789 + * Local variables:
17790 + * c-file-style: "linux"
17791 + * End:
17792 + */
17793 diff -Naur -X ../exclude-files orig/arch/um/include/user.h um/arch/um/include/user.h
17794 --- orig/arch/um/include/user.h 1969-12-31 19:00:00.000000000 -0500
17795 +++ um/arch/um/include/user.h   2003-10-21 03:26:06.000000000 -0400
17796 @@ -0,0 +1,29 @@
17797 +/* 
17798 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17799 + * Licensed under the GPL
17800 + */
17801 +
17802 +#ifndef __USER_H__
17803 +#define __USER_H__
17804 +
17805 +extern void panic(const char *fmt, ...);
17806 +extern int printk(const char *fmt, ...);
17807 +extern void schedule(void);
17808 +extern void *um_kmalloc(int size);
17809 +extern void *um_kmalloc_atomic(int size);
17810 +extern void kfree(void *ptr);
17811 +extern int in_aton(char *str);
17812 +extern int open_gdb_chan(void);
17813 +
17814 +#endif
17815 +
17816 +/*
17817 + * Overrides for Emacs so that we follow Linus's tabbing style.
17818 + * Emacs will notice this stuff at the end of the file and automatically
17819 + * adjust the settings for this buffer only.  This must remain at the end
17820 + * of the file.
17821 + * ---------------------------------------------------------------------------
17822 + * Local variables:
17823 + * c-file-style: "linux"
17824 + * End:
17825 + */
17826 diff -Naur -X ../exclude-files orig/arch/um/include/user_util.h um/arch/um/include/user_util.h
17827 --- orig/arch/um/include/user_util.h    1969-12-31 19:00:00.000000000 -0500
17828 +++ um/arch/um/include/user_util.h      2003-11-09 11:36:31.000000000 -0500
17829 @@ -0,0 +1,103 @@
17830 +/* 
17831 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
17832 + * Licensed under the GPL
17833 + */
17834 +
17835 +#ifndef __USER_UTIL_H__
17836 +#define __USER_UTIL_H__
17837 +
17838 +#include "sysdep/ptrace.h"
17839 +
17840 +extern int mode_tt;
17841 +
17842 +extern int grantpt(int __fd);
17843 +extern int unlockpt(int __fd);
17844 +extern char *ptsname(int __fd);
17845 +
17846 +struct cpu_task {
17847 +       int pid;
17848 +       void *task;
17849 +};
17850 +
17851 +extern struct cpu_task cpu_tasks[];
17852 +
17853 +struct signal_info {
17854 +       void (*handler)(int, union uml_pt_regs *);
17855 +       int is_irq;
17856 +};
17857 +
17858 +extern struct signal_info sig_info[];
17859 +
17860 +extern unsigned long low_physmem;
17861 +extern unsigned long high_physmem;
17862 +extern unsigned long uml_physmem;
17863 +extern unsigned long uml_reserved;
17864 +extern unsigned long end_vm;
17865 +extern unsigned long start_vm;
17866 +extern unsigned long highmem;
17867 +
17868 +extern char host_info[];
17869 +
17870 +extern char saved_command_line[];
17871 +extern char command_line[];
17872 +
17873 +extern char *tempdir;
17874 +
17875 +extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
17876 +extern unsigned long _unprotected_end;
17877 +extern unsigned long brk_start;
17878 +
17879 +extern int pty_output_sigio;
17880 +extern int pty_close_sigio;
17881 +
17882 +extern void stop(void);
17883 +extern void stack_protections(unsigned long address);
17884 +extern void task_protections(unsigned long address);
17885 +extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
17886 +extern void *add_signal_handler(int sig, void (*handler)(int));
17887 +extern int start_fork_tramp(void *arg, unsigned long temp_stack, 
17888 +                           int clone_flags, int (*tramp)(void *));
17889 +extern int linux_main(int argc, char **argv);
17890 +extern void set_cmdline(char *cmd);
17891 +extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
17892 +extern int get_pty(void);
17893 +extern void *um_kmalloc(int size);
17894 +extern int raw(int fd, int complain);
17895 +extern int switcheroo(int fd, int prot, void *from, void *to, int size);
17896 +extern void setup_machinename(char *machine_out);
17897 +extern void setup_hostinfo(void);
17898 +extern void add_arg(char *cmd_line, char *arg);
17899 +extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
17900 +extern void init_new_thread_signals(int altstack);
17901 +extern void do_exec(int old_pid, int new_pid);
17902 +extern void tracer_panic(char *msg, ...);
17903 +extern char *get_umid(int only_if_set);
17904 +extern void do_longjmp(void *p, int val);
17905 +extern void suspend_new_thread(int fd);
17906 +extern int detach(int pid, int sig);
17907 +extern int attach(int pid);
17908 +extern void kill_child_dead(int pid);
17909 +extern int cont(int pid);
17910 +extern void check_ptrace(void);
17911 +extern void check_sigio(void);
17912 +extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
17913 +extern void write_sigio_workaround(void);
17914 +extern void arch_check_bugs(void);
17915 +extern int cpu_feature(char *what, char *buf, int len);
17916 +extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
17917 +extern int arch_fixup(unsigned long address, void *sc_ptr);
17918 +extern int can_do_skas(void);
17919 +extern void arch_init_thread(void);
17920 +
17921 +#endif
17922 +
17923 +/*
17924 + * Overrides for Emacs so that we follow Linus's tabbing style.
17925 + * Emacs will notice this stuff at the end of the file and automatically
17926 + * adjust the settings for this buffer only.  This must remain at the end
17927 + * of the file.
17928 + * ---------------------------------------------------------------------------
17929 + * Local variables:
17930 + * c-file-style: "linux"
17931 + * End:
17932 + */
17933 diff -Naur -X ../exclude-files orig/arch/um/kernel/checksum.c um/arch/um/kernel/checksum.c
17934 --- orig/arch/um/kernel/checksum.c      1969-12-31 19:00:00.000000000 -0500
17935 +++ um/arch/um/kernel/checksum.c        2003-10-21 03:26:06.000000000 -0400
17936 @@ -0,0 +1,42 @@
17937 +#include "asm/uaccess.h"
17938 +#include "linux/errno.h"
17939 +
17940 +extern unsigned int arch_csum_partial(const char *buff, int len, int sum);
17941 +
17942 +extern unsigned int csum_partial(char *buff, int len, int sum)
17943 +{
17944 +       return(arch_csum_partial(buff, len, sum));
17945 +}
17946 +
17947 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len, 
17948 +                                 int sum, int *err_ptr)
17949 +{
17950 +       if(copy_to_user(dst, src, len)){
17951 +               *err_ptr = -EFAULT;
17952 +               return(-1);
17953 +       }
17954 +
17955 +       return(arch_csum_partial(src, len, sum));
17956 +}
17957 +
17958 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len, 
17959 +                                   int sum, int *err_ptr)
17960 +{
17961 +       if(copy_from_user(dst, src, len)){
17962 +               *err_ptr = -EFAULT;
17963 +               return(-1);
17964 +       }
17965 +
17966 +       return(arch_csum_partial(dst, len, sum));
17967 +}
17968 +
17969 +/*
17970 + * Overrides for Emacs so that we follow Linus's tabbing style.
17971 + * Emacs will notice this stuff at the end of the file and automatically
17972 + * adjust the settings for this buffer only.  This must remain at the end
17973 + * of the file.
17974 + * ---------------------------------------------------------------------------
17975 + * Local variables:
17976 + * c-file-style: "linux"
17977 + * End:
17978 + */
17979 diff -Naur -X ../exclude-files orig/arch/um/kernel/config.c.in um/arch/um/kernel/config.c.in
17980 --- orig/arch/um/kernel/config.c.in     1969-12-31 19:00:00.000000000 -0500
17981 +++ um/arch/um/kernel/config.c.in       2003-10-21 03:26:06.000000000 -0400
17982 @@ -0,0 +1,32 @@
17983 +/* 
17984 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17985 + * Licensed under the GPL
17986 + */
17987 +
17988 +#include <stdio.h>
17989 +#include <stdlib.h>
17990 +#include "init.h"
17991 +
17992 +static __initdata char *config = "CONFIG";
17993 +
17994 +static int __init print_config(char *line, int *add)
17995 +{
17996 +       printf("%s", config);
17997 +       exit(0);
17998 +}
17999 +
18000 +__uml_setup("--showconfig", print_config,
18001 +"--showconfig\n"
18002 +"    Prints the config file that this UML binary was generated from.\n\n"
18003 +);
18004 +
18005 +/*
18006 + * Overrides for Emacs so that we follow Linus's tabbing style.
18007 + * Emacs will notice this stuff at the end of the file and automatically
18008 + * adjust the settings for this buffer only.  This must remain at the end
18009 + * of the file.
18010 + * ---------------------------------------------------------------------------
18011 + * Local variables:
18012 + * c-file-style: "linux"
18013 + * End:
18014 + */
18015 diff -Naur -X ../exclude-files orig/arch/um/kernel/exec_kern.c um/arch/um/kernel/exec_kern.c
18016 --- orig/arch/um/kernel/exec_kern.c     1969-12-31 19:00:00.000000000 -0500
18017 +++ um/arch/um/kernel/exec_kern.c       2003-10-21 03:26:06.000000000 -0400
18018 @@ -0,0 +1,86 @@
18019 +/* 
18020 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
18021 + * Licensed under the GPL
18022 + */
18023 +
18024 +#include "linux/slab.h"
18025 +#include "linux/smp_lock.h"
18026 +#include "asm/ptrace.h"
18027 +#include "asm/pgtable.h"
18028 +#include "asm/pgalloc.h"
18029 +#include "asm/uaccess.h"
18030 +#include "user_util.h"
18031 +#include "kern_util.h"
18032 +#include "mem_user.h"
18033 +#include "kern.h"
18034 +#include "irq_user.h"
18035 +#include "tlb.h"
18036 +#include "2_5compat.h"
18037 +#include "os.h"
18038 +#include "time_user.h"
18039 +#include "choose-mode.h"
18040 +#include "mode_kern.h"
18041 +
18042 +void flush_thread(void)
18043 +{
18044 +       CHOOSE_MODE(flush_thread_tt(), flush_thread_skas());
18045 +}
18046 +
18047 +void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
18048 +{
18049 +       CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
18050 +}
18051 +
18052 +extern void log_exec(char **argv, void *tty);
18053 +
18054 +static int execve1(char *file, char **argv, char **env)
18055 +{
18056 +        int error;
18057 +
18058 +#ifdef CONFIG_TTY_LOG
18059 +       log_exec(argv, current->tty);
18060 +#endif
18061 +        error = do_execve(file, argv, env, &current->thread.regs);
18062 +        if (error == 0){
18063 +                current->ptrace &= ~PT_DTRACE;
18064 +                set_cmdline(current_cmd());
18065 +        }
18066 +        return(error);
18067 +}
18068 +
18069 +int um_execve(char *file, char **argv, char **env)
18070 +{
18071 +       int err;
18072 +
18073 +       err = execve1(file, argv, env);
18074 +       if(!err) 
18075 +               do_longjmp(current->thread.exec_buf, 1);
18076 +       return(err);
18077 +}
18078 +
18079 +int sys_execve(char *file, char **argv, char **env)
18080 +{
18081 +       int error;
18082 +       char *filename;
18083 +
18084 +       lock_kernel();
18085 +       filename = getname((char *) file);
18086 +       error = PTR_ERR(filename);
18087 +       if (IS_ERR(filename)) goto out;
18088 +       error = execve1(filename, argv, env);
18089 +       putname(filename);
18090 + out:
18091 +       unlock_kernel();
18092 +       return(error);
18093 +}
18094 +
18095 +/*
18096 + * Overrides for Emacs so that we follow Linus's tabbing style.
18097 + * Emacs will notice this stuff at the end of the file and automatically
18098 + * adjust the settings for this buffer only.  This must remain at the end
18099 + * of the file.
18100 + * ---------------------------------------------------------------------------
18101 + * Local variables:
18102 + * c-file-style: "linux"
18103 + * End:
18104 + */
18105 diff -Naur -X ../exclude-files orig/arch/um/kernel/exitcode.c um/arch/um/kernel/exitcode.c
18106 --- orig/arch/um/kernel/exitcode.c      1969-12-31 19:00:00.000000000 -0500
18107 +++ um/arch/um/kernel/exitcode.c        2003-10-21 03:26:06.000000000 -0400
18108 @@ -0,0 +1,73 @@
18109 +/* 
18110 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18111 + * Licensed under the GPL
18112 + */
18113 +
18114 +#include "linux/init.h"
18115 +#include "linux/ctype.h"
18116 +#include "linux/proc_fs.h"
18117 +#include "asm/uaccess.h"
18118 +
18119 +/* If read and write race, the read will still atomically read a valid
18120 + * value.
18121 + */
18122 +int uml_exitcode = 0;
18123 +
18124 +static int read_proc_exitcode(char *page, char **start, off_t off,
18125 +                             int count, int *eof, void *data)
18126 +{
18127 +       int len;
18128 +
18129 +       len = sprintf(page, "%d\n", uml_exitcode);
18130 +       len -= off;
18131 +       if(len <= off+count) *eof = 1;
18132 +       *start = page + off;
18133 +       if(len > count) len = count;
18134 +       if(len < 0) len = 0;
18135 +       return(len);
18136 +}
18137 +
18138 +static int write_proc_exitcode(struct file *file, const char *buffer,
18139 +                              unsigned long count, void *data)
18140 +{
18141 +       char *end, buf[sizeof("nnnnn\0")];
18142 +       int tmp;
18143 +
18144 +       if(copy_from_user(buf, buffer, count))
18145 +               return(-EFAULT);
18146 +       tmp = simple_strtol(buf, &end, 0);
18147 +       if((*end != '\0') && !isspace(*end))
18148 +               return(-EINVAL);
18149 +       uml_exitcode = tmp;
18150 +       return(count);
18151 +}
18152 +
18153 +static int make_proc_exitcode(void)
18154 +{
18155 +       struct proc_dir_entry *ent;
18156 +
18157 +       ent = create_proc_entry("exitcode", 0600, &proc_root);
18158 +       if(ent == NULL){
18159 +               printk("make_proc_exitcode : Failed to register "
18160 +                      "/proc/exitcode\n");
18161 +               return(0);
18162 +       }
18163 +
18164 +       ent->read_proc = read_proc_exitcode;
18165 +       ent->write_proc = write_proc_exitcode;
18166 +       
18167 +       return(0);
18168 +}
18169 +
18170 +__initcall(make_proc_exitcode);
18171 +
18172 +/*
18173 + * Overrides for Emacs so that we follow Linus's tabbing style.
18174 + * Emacs will notice this stuff at the end of the file and automatically
18175 + * adjust the settings for this buffer only.  This must remain at the end
18176 + * of the file.
18177 + * ---------------------------------------------------------------------------
18178 + * Local variables:
18179 + * c-file-style: "linux"
18180 + * End:
18181 + */
18182 diff -Naur -X ../exclude-files orig/arch/um/kernel/frame.c um/arch/um/kernel/frame.c
18183 --- orig/arch/um/kernel/frame.c 1969-12-31 19:00:00.000000000 -0500
18184 +++ um/arch/um/kernel/frame.c   2003-10-21 03:26:06.000000000 -0400
18185 @@ -0,0 +1,341 @@
18186 +/* 
18187 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18188 + * Licensed under the GPL
18189 + */
18190 +
18191 +#include <stdio.h>
18192 +#include <stdlib.h>
18193 +#include <unistd.h>
18194 +#include <string.h>
18195 +#include <signal.h>
18196 +#include <wait.h>
18197 +#include <sched.h>
18198 +#include <errno.h>
18199 +#include <sys/ptrace.h>
18200 +#include <sys/syscall.h>
18201 +#include <sys/mman.h>
18202 +#include <asm/page.h>
18203 +#include <asm/ptrace.h>
18204 +#include <asm/sigcontext.h>
18205 +#include "sysdep/ptrace.h"
18206 +#include "sysdep/sigcontext.h"
18207 +#include "frame_user.h"
18208 +#include "kern_util.h"
18209 +#include "ptrace_user.h"
18210 +#include "os.h"
18211 +
18212 +static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
18213 +                        unsigned long top, void **data_out)
18214 +{
18215 +       unsigned long regs[FRAME_SIZE];
18216 +       int pid, status, n, len;
18217 +
18218 +       /* Start the child as a thread */
18219 +       pid = clone(child, sp, CLONE_VM | SIGCHLD, arg);
18220 +       if(pid < 0){
18221 +               printf("capture_stack : clone failed - errno = %d\n", errno);
18222 +               exit(1);
18223 +       }
18224 +
18225 +       /* Wait for it to stop itself and continue it with a SIGUSR1 to force 
18226 +        * it into the signal handler.
18227 +        */
18228 +       n = waitpid(pid, &status, WUNTRACED);
18229 +       if(n < 0){
18230 +               printf("capture_stack : waitpid failed - errno = %d\n", errno);
18231 +               exit(1);
18232 +       }
18233 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
18234 +               fprintf(stderr, "capture_stack : Expected SIGSTOP, "
18235 +                       "got status = 0x%x\n", status);
18236 +               exit(1);
18237 +       }
18238 +       if(ptrace(PTRACE_CONT, pid, 0, SIGUSR1) < 0){
18239 +               printf("capture_stack : PTRACE_CONT failed - errno = %d\n", 
18240 +                      errno);
18241 +               exit(1);
18242 +       }
18243 +
18244 +       /* Wait for it to stop itself again and grab its registers again.  
18245 +        * At this point, the handler has stuffed the addresses of
18246 +        * sig, sc, and SA_RESTORER in raw.
18247 +        */
18248 +       n = waitpid(pid, &status, WUNTRACED);
18249 +       if(n < 0){
18250 +               printf("capture_stack : waitpid failed - errno = %d\n", errno);
18251 +               exit(1);
18252 +       }
18253 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
18254 +               fprintf(stderr, "capture_stack : Expected SIGSTOP, "
18255 +                       "got status = 0x%x\n", status);
18256 +               exit(1);
18257 +       }
18258 +       if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0){
18259 +               printf("capture_stack : PTRACE_GETREGS failed - errno = %d\n", 
18260 +                      errno);
18261 +               exit(1);
18262 +       }
18263 +
18264 +       /* It has outlived its usefulness, so continue it so it can exit */
18265 +       if(ptrace(PTRACE_CONT, pid, 0, 0) < 0){
18266 +               printf("capture_stack : PTRACE_CONT failed - errno = %d\n", 
18267 +                      errno);
18268 +               exit(1);
18269 +       }
18270 +       if(waitpid(pid, &status, 0) < 0){
18271 +               printf("capture_stack : waitpid failed - errno = %d\n", errno);
18272 +               exit(1);
18273 +       }
18274 +       if(!WIFSIGNALED(status) || (WTERMSIG(status) != 9)){
18275 +               printf("capture_stack : Expected exit signal 9, "
18276 +                      "got status = 0x%x\n", status);
18277 +               exit(1);
18278 +       }
18279 +
18280 +       /* The frame that we want is the top of the signal stack */
18281 +
18282 +       len = top - PT_SP(regs);
18283 +       *data_out = malloc(len);
18284 +       if(*data_out == NULL){
18285 +               printf("capture_stack : malloc failed - errno = %d\n", errno);
18286 +               exit(1);
18287 +       }
18288 +       memcpy(*data_out, (void *) PT_SP(regs), len);
18289 +
18290 +       return(len);
18291 +}
18292 +
18293 +struct common_raw {
18294 +       void *stack;
18295 +       int size;
18296 +       unsigned long sig;
18297 +       unsigned long sr;
18298 +       unsigned long sp;       
18299 +       struct arch_frame_data_raw arch;
18300 +};
18301 +
18302 +#define SA_RESTORER (0x04000000)
18303 +
18304 +typedef unsigned long old_sigset_t;
18305 +
18306 +struct old_sigaction {
18307 +       __sighandler_t handler;
18308 +       old_sigset_t sa_mask;
18309 +       unsigned long sa_flags;
18310 +       void (*sa_restorer)(void);
18311 +};
18312 +
18313 +static void child_common(struct common_raw *common, sighandler_t handler,
18314 +                        int restorer, int flags)
18315 +{
18316 +       stack_t ss = ((stack_t) { .ss_sp        = common->stack,
18317 +                                 .ss_flags     = 0,
18318 +                                 .ss_size      = common->size });
18319 +       int err;
18320 +
18321 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
18322 +               printf("PTRACE_TRACEME failed, errno = %d\n", errno);
18323 +       }
18324 +       if(sigaltstack(&ss, NULL) < 0){
18325 +               printf("sigaltstack failed - errno = %d\n", errno);
18326 +               kill(getpid(), SIGKILL);
18327 +       }
18328 +
18329 +       if(restorer){
18330 +               struct sigaction sa;
18331 +
18332 +               sa.sa_handler = handler;
18333 +               sigemptyset(&sa.sa_mask);
18334 +               sa.sa_flags = SA_ONSTACK | flags;
18335 +               err = sigaction(SIGUSR1, &sa, NULL);
18336 +       }
18337 +       else {
18338 +               struct old_sigaction sa;
18339 +
18340 +               sa.handler = handler;
18341 +               sa.sa_mask = 0;
18342 +               sa.sa_flags = (SA_ONSTACK | flags) & ~SA_RESTORER;
18343 +               err = syscall(__NR_sigaction, SIGUSR1, &sa, NULL);
18344 +       }
18345 +       
18346 +       if(err < 0){
18347 +               printf("sigaction failed - errno = %d\n", errno);
18348 +               kill(getpid(), SIGKILL);
18349 +       }
18350 +
18351 +       os_stop_process(os_getpid());
18352 +}
18353 +
18354 +/* Changed only during early boot */
18355 +struct sc_frame signal_frame_sc;
18356 +
18357 +struct sc_frame signal_frame_sc_sr;
18358 +
18359 +struct sc_frame_raw {
18360 +       struct common_raw common;
18361 +       unsigned long sc;
18362 +       int restorer;
18363 +};
18364 +
18365 +/* Changed only during early boot */
18366 +static struct sc_frame_raw *raw_sc = NULL;
18367 +
18368 +static void sc_handler(int sig, struct sigcontext sc)
18369 +{
18370 +       raw_sc->common.sig = (unsigned long) &sig;
18371 +       raw_sc->common.sr = frame_restorer();
18372 +       raw_sc->common.sp = frame_sp();
18373 +       raw_sc->sc = (unsigned long) &sc;
18374 +       setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr);
18375 +
18376 +       os_stop_process(os_getpid());
18377 +       kill(getpid(), SIGKILL);
18378 +}
18379 +
18380 +static int sc_child(void *arg)
18381 +{
18382 +       raw_sc = arg;
18383 +       child_common(&raw_sc->common, (sighandler_t) sc_handler, 
18384 +                    raw_sc->restorer, 0);
18385 +       return(-1);
18386 +}
18387 +
18388 +/* Changed only during early boot */
18389 +struct si_frame signal_frame_si;
18390 +
18391 +struct si_frame_raw {
18392 +       struct common_raw common;
18393 +       unsigned long sip;
18394 +       unsigned long si;
18395 +       unsigned long ucp;
18396 +       unsigned long uc;
18397 +};
18398 +
18399 +/* Changed only during early boot */
18400 +static struct si_frame_raw *raw_si = NULL;
18401 +
18402 +static void si_handler(int sig, siginfo_t *si, struct ucontext *ucontext)
18403 +{
18404 +       raw_si->common.sig = (unsigned long) &sig;
18405 +       raw_si->common.sr = frame_restorer();
18406 +       raw_si->common.sp = frame_sp();
18407 +       raw_si->sip = (unsigned long) &si;
18408 +       raw_si->si = (unsigned long) si;
18409 +       raw_si->ucp = (unsigned long) &ucontext;
18410 +       raw_si->uc = (unsigned long) ucontext;
18411 +       setup_arch_frame_raw(&raw_si->common.arch, 
18412 +                            ucontext->uc_mcontext.fpregs, raw_si->common.sr);
18413 +       
18414 +       os_stop_process(os_getpid());
18415 +       kill(getpid(), SIGKILL);
18416 +}
18417 +
18418 +static int si_child(void *arg)
18419 +{
18420 +       raw_si = arg;
18421 +       child_common(&raw_si->common, (sighandler_t) si_handler, 1, 
18422 +                    SA_SIGINFO);
18423 +       return(-1);
18424 +}
18425 +
18426 +static int relative_sr(unsigned long sr, int sr_index, void *stack, 
18427 +                      void *framep)
18428 +{
18429 +       unsigned long *srp = (unsigned long *) sr;
18430 +       unsigned long frame = (unsigned long) framep;
18431 +
18432 +       if((*srp & PAGE_MASK) == (unsigned long) stack){
18433 +               *srp -= sr;
18434 +               *((unsigned long *) (frame + sr_index)) = *srp;
18435 +               return(1);
18436 +       }
18437 +       else return(0);
18438 +}
18439 +
18440 +static unsigned long capture_stack_common(int (*proc)(void *), void *arg, 
18441 +                                         struct common_raw *common_in, 
18442 +                                         void *top, void *sigstack, 
18443 +                                         int stack_len, 
18444 +                                         struct frame_common *common_out)
18445 +{
18446 +       unsigned long sig_top = (unsigned long) sigstack + stack_len, base;
18447 +
18448 +       common_in->stack = (void *) sigstack;
18449 +       common_in->size = stack_len;
18450 +       common_out->len = capture_stack(proc, arg, top, sig_top, 
18451 +                                       &common_out->data);
18452 +       base = sig_top - common_out->len;
18453 +       common_out->sig_index = common_in->sig - base;
18454 +       common_out->sp_index = common_in->sp - base;
18455 +       common_out->sr_index = common_in->sr - base;
18456 +       common_out->sr_relative = relative_sr(common_in->sr, 
18457 +                                             common_out->sr_index, sigstack, 
18458 +                                             common_out->data);
18459 +       return(base);
18460 +}
18461 +
18462 +void capture_signal_stack(void)
18463 +{
18464 +       struct sc_frame_raw raw_sc;
18465 +       struct si_frame_raw raw_si;
18466 +       void *stack, *sigstack;
18467 +       unsigned long top, base;
18468 +
18469 +       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
18470 +                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
18471 +       sigstack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
18472 +                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
18473 +       if((stack == MAP_FAILED) || (sigstack == MAP_FAILED)){
18474 +               printf("capture_signal_stack : mmap failed - errno = %d\n", 
18475 +                      errno);
18476 +               exit(1);
18477 +       }
18478 +
18479 +       top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
18480 +
18481 +       /* Get the sigcontext, no sigrestorer layout */
18482 +       raw_sc.restorer = 0;
18483 +       base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common, 
18484 +                                   (void *) top, sigstack, PAGE_SIZE, 
18485 +                                   &signal_frame_sc.common);
18486 +
18487 +       signal_frame_sc.sc_index = raw_sc.sc - base;
18488 +       setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc.common.arch);
18489 +
18490 +       /* Ditto for the sigcontext, sigrestorer layout */
18491 +       raw_sc.restorer = 1;
18492 +       base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common, 
18493 +                                   (void *) top, sigstack, PAGE_SIZE, 
18494 +                                   &signal_frame_sc_sr.common);
18495 +       signal_frame_sc_sr.sc_index = raw_sc.sc - base;
18496 +       setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc_sr.common.arch);
18497 +
18498 +       /* And the siginfo layout */
18499 +
18500 +       base = capture_stack_common(si_child, &raw_si, &raw_si.common, 
18501 +                                   (void *) top, sigstack, PAGE_SIZE, 
18502 +                                   &signal_frame_si.common);
18503 +       signal_frame_si.sip_index = raw_si.sip - base;
18504 +       signal_frame_si.si_index = raw_si.si - base;
18505 +       signal_frame_si.ucp_index = raw_si.ucp - base;
18506 +       signal_frame_si.uc_index = raw_si.uc - base;
18507 +       setup_arch_frame(&raw_si.common.arch, &signal_frame_si.common.arch);
18508 +
18509 +       if((munmap(stack, PAGE_SIZE) < 0) || 
18510 +          (munmap(sigstack, PAGE_SIZE) < 0)){
18511 +               printf("capture_signal_stack : munmap failed - errno = %d\n", 
18512 +                      errno);
18513 +               exit(1);
18514 +       }
18515 +}
18516 +
18517 +/*
18518 + * Overrides for Emacs so that we follow Linus's tabbing style.
18519 + * Emacs will notice this stuff at the end of the file and automatically
18520 + * adjust the settings for this buffer only.  This must remain at the end
18521 + * of the file.
18522 + * ---------------------------------------------------------------------------
18523 + * Local variables:
18524 + * c-file-style: "linux"
18525 + * End:
18526 + */
18527 diff -Naur -X ../exclude-files orig/arch/um/kernel/frame_kern.c um/arch/um/kernel/frame_kern.c
18528 --- orig/arch/um/kernel/frame_kern.c    1969-12-31 19:00:00.000000000 -0500
18529 +++ um/arch/um/kernel/frame_kern.c      2003-11-19 03:32:43.000000000 -0500
18530 @@ -0,0 +1,174 @@
18531 +/* 
18532 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18533 + * Licensed under the GPL
18534 + */
18535 +
18536 +#include "asm/ptrace.h"
18537 +#include "asm/uaccess.h"
18538 +#include "asm/signal.h"
18539 +#include "asm/uaccess.h"
18540 +#include "asm/ucontext.h"
18541 +#include "frame_kern.h"
18542 +#include "sigcontext.h"
18543 +#include "sysdep/ptrace.h"
18544 +#include "choose-mode.h"
18545 +#include "mode.h"
18546 +
18547 +int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
18548 +{
18549 +       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
18550 +               return -EFAULT;
18551 +       if (from->si_code < 0)
18552 +               return __copy_to_user(to, from, sizeof(siginfo_t));
18553 +       else {
18554 +               int err;
18555 +
18556 +               /* If you change siginfo_t structure, please be sure
18557 +                  this code is fixed accordingly.
18558 +                  It should never copy any pad contained in the structure
18559 +                  to avoid security leaks, but must copy the generic
18560 +                  3 ints plus the relevant union member.  */
18561 +               err = __put_user(from->si_signo, &to->si_signo);
18562 +               err |= __put_user(from->si_errno, &to->si_errno);
18563 +               err |= __put_user((short)from->si_code, &to->si_code);
18564 +               /* First 32bits of unions are always present.  */
18565 +               err |= __put_user(from->si_pid, &to->si_pid);
18566 +               switch (from->si_code >> 16) {
18567 +               case __SI_FAULT >> 16:
18568 +                       break;
18569 +               case __SI_CHLD >> 16:
18570 +                       err |= __put_user(from->si_utime, &to->si_utime);
18571 +                       err |= __put_user(from->si_stime, &to->si_stime);
18572 +                       err |= __put_user(from->si_status, &to->si_status);
18573 +               default:
18574 +                       err |= __put_user(from->si_uid, &to->si_uid);
18575 +                       break;
18576 +               }
18577 +               return err;
18578 +       }
18579 +}
18580 +
18581 +static int copy_restorer(void (*restorer)(void), unsigned long start, 
18582 +                        unsigned long sr_index, int sr_relative)
18583 +{
18584 +       unsigned long sr;
18585 +
18586 +       if(sr_relative){
18587 +               sr = (unsigned long) restorer;
18588 +               sr += start + sr_index;
18589 +               restorer = (void (*)(void)) sr;
18590 +       }
18591 +
18592 +       return(copy_to_user((void *) (start + sr_index), &restorer, 
18593 +                           sizeof(restorer)));
18594 +}
18595 +
18596 +extern int userspace_pid[];
18597 +
18598 +static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from, 
18599 +                          struct arch_frame_data *arch)
18600 +{
18601 +       return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 
18602 +                                             arch),
18603 +                          copy_sc_to_user_skas(userspace_pid[0], to, fp, 
18604 +                                               &from->regs,
18605 +                                               current->thread.cr2,
18606 +                                               current->thread.err)));
18607 +}
18608 +
18609 +static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set,
18610 +                                unsigned long sp)
18611 +{
18612 +       int err = 0;
18613 +
18614 +       err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
18615 +       err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
18616 +       err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
18617 +       err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs,
18618 +                              &signal_frame_si.common.arch);
18619 +       err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
18620 +       return(err);
18621 +}
18622 +
18623 +int setup_signal_stack_si(unsigned long stack_top, int sig, 
18624 +                         unsigned long handler, void (*restorer)(void), 
18625 +                         struct pt_regs *regs, siginfo_t *info, 
18626 +                         sigset_t *mask)
18627 +{
18628 +       unsigned long start;
18629 +       void *sip, *ucp, *fp;
18630 +
18631 +       start = stack_top - signal_frame_si.common.len;
18632 +       sip = (void *) (start + signal_frame_si.si_index);
18633 +       ucp = (void *) (start + signal_frame_si.uc_index);
18634 +       fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext));
18635 +
18636 +       if(restorer == NULL)
18637 +               panic("setup_signal_stack_si - no restorer");
18638 +
18639 +       if(copy_to_user((void *) start, signal_frame_si.common.data,
18640 +                       signal_frame_si.common.len) ||
18641 +          copy_to_user((void *) (start + signal_frame_si.common.sig_index), 
18642 +                       &sig, sizeof(sig)) ||
18643 +          copy_siginfo_to_user(sip, info) ||
18644 +          copy_to_user((void *) (start + signal_frame_si.sip_index), &sip,
18645 +                       sizeof(sip)) ||
18646 +          copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) ||
18647 +          copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp,
18648 +                       sizeof(ucp)) ||
18649 +          copy_restorer(restorer, start, signal_frame_si.common.sr_index,
18650 +                        signal_frame_si.common.sr_relative))
18651 +               return(1);
18652 +       
18653 +       PT_REGS_IP(regs) = handler;
18654 +       PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
18655 +       return(0);
18656 +}
18657 +
18658 +int setup_signal_stack_sc(unsigned long stack_top, int sig, 
18659 +                         unsigned long handler, void (*restorer)(void), 
18660 +                         struct pt_regs *regs, sigset_t *mask)
18661 +{
18662 +       struct frame_common *frame = &signal_frame_sc_sr.common;
18663 +       void *user_sc;
18664 +       int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
18665 +       unsigned long sigs, sr;
18666 +       unsigned long start = stack_top - frame->len - sig_size;
18667 +
18668 +       user_sc = (void *) (start + signal_frame_sc_sr.sc_index);
18669 +       if(restorer == NULL){
18670 +               frame = &signal_frame_sc.common;
18671 +               user_sc = (void *) (start + signal_frame_sc.sc_index);
18672 +               sr = (unsigned long) frame->data;
18673 +               sr += frame->sr_index;
18674 +               sr = *((unsigned long *) sr);
18675 +               restorer = ((void (*)(void)) sr);
18676 +       }
18677 +
18678 +       sigs = start + frame->len;
18679 +       if(copy_to_user((void *) start, frame->data, frame->len) ||
18680 +          copy_to_user((void *) (start + frame->sig_index), &sig, 
18681 +                       sizeof(sig)) ||
18682 +          copy_sc_to_user(user_sc, NULL, regs, 
18683 +                          &signal_frame_sc.common.arch) ||
18684 +          copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) ||
18685 +          copy_to_user((void *) sigs, &mask->sig[1], sig_size) ||
18686 +          copy_restorer(restorer, start, frame->sr_index, frame->sr_relative))
18687 +               return(1);
18688 +
18689 +       PT_REGS_IP(regs) = handler;
18690 +       PT_REGS_SP(regs) = start + frame->sp_index;
18691 +
18692 +       return(0);
18693 +}
18694 +
18695 +/*
18696 + * Overrides for Emacs so that we follow Linus's tabbing style.
18697 + * Emacs will notice this stuff at the end of the file and automatically
18698 + * adjust the settings for this buffer only.  This must remain at the end
18699 + * of the file.
18700 + * ---------------------------------------------------------------------------
18701 + * Local variables:
18702 + * c-file-style: "linux"
18703 + * End:
18704 + */
18705 diff -Naur -X ../exclude-files orig/arch/um/kernel/gmon_syms.c um/arch/um/kernel/gmon_syms.c
18706 --- orig/arch/um/kernel/gmon_syms.c     1969-12-31 19:00:00.000000000 -0500
18707 +++ um/arch/um/kernel/gmon_syms.c       2003-10-21 03:26:06.000000000 -0400
18708 @@ -0,0 +1,20 @@
18709 +/* 
18710 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
18711 + * Licensed under the GPL
18712 + */
18713 +
18714 +#include "linux/module.h"
18715 +
18716 +extern void __bb_init_func(void *);
18717 +EXPORT_SYMBOL(__bb_init_func);
18718 +
18719 +/*
18720 + * Overrides for Emacs so that we follow Linus's tabbing style.
18721 + * Emacs will notice this stuff at the end of the file and automatically
18722 + * adjust the settings for this buffer only.  This must remain at the end
18723 + * of the file.
18724 + * ---------------------------------------------------------------------------
18725 + * Local variables:
18726 + * c-file-style: "linux"
18727 + * End:
18728 + */
18729 diff -Naur -X ../exclude-files orig/arch/um/kernel/gprof_syms.c um/arch/um/kernel/gprof_syms.c
18730 --- orig/arch/um/kernel/gprof_syms.c    1969-12-31 19:00:00.000000000 -0500
18731 +++ um/arch/um/kernel/gprof_syms.c      2003-10-21 03:26:06.000000000 -0400
18732 @@ -0,0 +1,20 @@
18733 +/* 
18734 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
18735 + * Licensed under the GPL
18736 + */
18737 +
18738 +#include "linux/module.h"
18739 +
18740 +extern void mcount(void);
18741 +EXPORT_SYMBOL(mcount);
18742 +
18743 +/*
18744 + * Overrides for Emacs so that we follow Linus's tabbing style.
18745 + * Emacs will notice this stuff at the end of the file and automatically
18746 + * adjust the settings for this buffer only.  This must remain at the end
18747 + * of the file.
18748 + * ---------------------------------------------------------------------------
18749 + * Local variables:
18750 + * c-file-style: "linux"
18751 + * End:
18752 + */
18753 diff -Naur -X ../exclude-files orig/arch/um/kernel/helper.c um/arch/um/kernel/helper.c
18754 --- orig/arch/um/kernel/helper.c        1969-12-31 19:00:00.000000000 -0500
18755 +++ um/arch/um/kernel/helper.c  2003-11-08 07:41:30.000000000 -0500
18756 @@ -0,0 +1,170 @@
18757 +/* 
18758 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18759 + * Licensed under the GPL
18760 + */
18761 +
18762 +#include <stdio.h>
18763 +#include <stdlib.h>
18764 +#include <unistd.h>
18765 +#include <errno.h>
18766 +#include <sched.h>
18767 +#include <sys/signal.h>
18768 +#include <sys/wait.h>
18769 +#include "user.h"
18770 +#include "kern_util.h"
18771 +#include "os.h"
18772 +
18773 +struct helper_data {
18774 +       void (*pre_exec)(void*);
18775 +       void *pre_data;
18776 +       char **argv;
18777 +       int fd;
18778 +};
18779 +
18780 +/* Debugging aid, changed only from gdb */
18781 +int helper_pause = 0;
18782 +
18783 +static void helper_hup(int sig)
18784 +{
18785 +}
18786 +
18787 +static int helper_child(void *arg)
18788 +{
18789 +       struct helper_data *data = arg;
18790 +       char **argv = data->argv;
18791 +       int errval;
18792 +
18793 +       if(helper_pause){
18794 +               signal(SIGHUP, helper_hup);
18795 +               pause();
18796 +       }
18797 +       if(data->pre_exec != NULL)
18798 +               (*data->pre_exec)(data->pre_data);
18799 +       execvp(argv[0], argv);
18800 +       errval = errno;
18801 +       printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
18802 +       os_write_file(data->fd, &errval, sizeof(errval));
18803 +       os_kill_process(os_getpid(), 0);
18804 +       return(0);
18805 +}
18806 +
18807 +/* XXX The alloc_stack here breaks if this is called in the tracing thread */
18808 +
18809 +int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
18810 +              unsigned long *stack_out)
18811 +{
18812 +       struct helper_data data;
18813 +       unsigned long stack, sp;
18814 +       int pid, fds[2], err, n;
18815 +
18816 +       if((stack_out != NULL) && (*stack_out != 0))
18817 +               stack = *stack_out;
18818 +       else stack = alloc_stack(0, um_in_interrupt());
18819 +       if(stack == 0) 
18820 +               return(-ENOMEM);
18821 +
18822 +       err = os_pipe(fds, 1, 0);
18823 +       if(err < 0){
18824 +               printk("run_helper : pipe failed, err = %d\n", -err);
18825 +               goto out_free;
18826 +       }
18827 +
18828 +       err = os_set_exec_close(fds[1], 1);
18829 +       if(err < 0){
18830 +               printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
18831 +                      -err);
18832 +               goto out_close;
18833 +       }
18834 +
18835 +       sp = stack + page_size() - sizeof(void *);
18836 +       data.pre_exec = pre_exec;
18837 +       data.pre_data = pre_data;
18838 +       data.argv = argv;
18839 +       data.fd = fds[1];
18840 +       pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
18841 +       if(pid < 0){
18842 +               printk("run_helper : clone failed, errno = %d\n", errno);
18843 +               err = -errno;
18844 +               goto out_close;
18845 +       }
18846 +
18847 +       os_close_file(fds[1]);
18848 +       n = os_read_file(fds[0], &err, sizeof(err));
18849 +       if(n < 0){
18850 +               printk("run_helper : read on pipe failed, err = %d\n", -n);
18851 +               err = n;
18852 +               goto out_kill;
18853 +       }
18854 +       else if(n != 0){
18855 +               waitpid(pid, NULL, 0);
18856 +               pid = -errno;
18857 +       }
18858 +
18859 +       if(stack_out == NULL) free_stack(stack, 0);
18860 +        else *stack_out = stack;
18861 +       return(pid);
18862 +
18863 + out_kill:
18864 +       os_kill_process(pid, 1);
18865 + out_close:
18866 +       os_close_file(fds[0]);
18867 +       os_close_file(fds[1]);
18868 + out_free:
18869 +       free_stack(stack, 0);
18870 +       return(err);
18871 +}
18872 +
18873 +int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, 
18874 +                     unsigned long *stack_out, int stack_order)
18875 +{
18876 +       unsigned long stack, sp;
18877 +       int pid, status;
18878 +
18879 +       stack = alloc_stack(stack_order, um_in_interrupt());
18880 +       if(stack == 0) return(-ENOMEM);
18881 +
18882 +       sp = stack + (page_size() << stack_order) - sizeof(void *);
18883 +       pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
18884 +       if(pid < 0){
18885 +               printk("run_helper_thread : clone failed, errno = %d\n", 
18886 +                      errno);
18887 +               return(-errno);
18888 +       }
18889 +       if(stack_out == NULL){
18890 +               pid = waitpid(pid, &status, 0);
18891 +               if(pid < 0){
18892 +                       printk("run_helper_thread - wait failed, errno = %d\n",
18893 +                              errno);
18894 +                       pid = -errno;
18895 +               }
18896 +               if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
18897 +                       printk("run_helper_thread - thread returned status "
18898 +                              "0x%x\n", status);
18899 +               free_stack(stack, stack_order);
18900 +       }
18901 +        else *stack_out = stack;
18902 +       return(pid);
18903 +}
18904 +
18905 +int helper_wait(int pid, int block)
18906 +{
18907 +       int ret;
18908 +
18909 +       ret = waitpid(pid, NULL, WNOHANG);
18910 +       if(ret < 0){
18911 +               printk("helper_wait : waitpid failed, errno = %d\n", errno);
18912 +               return(-errno);
18913 +       }
18914 +       return(ret);
18915 +}
18916 +
18917 +/*
18918 + * Overrides for Emacs so that we follow Linus's tabbing style.
18919 + * Emacs will notice this stuff at the end of the file and automatically
18920 + * adjust the settings for this buffer only.  This must remain at the end
18921 + * of the file.
18922 + * ---------------------------------------------------------------------------
18923 + * Local variables:
18924 + * c-file-style: "linux"
18925 + * End:
18926 + */
18927 diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_kern.c um/arch/um/kernel/initrd_kern.c
18928 --- orig/arch/um/kernel/initrd_kern.c   1969-12-31 19:00:00.000000000 -0500
18929 +++ um/arch/um/kernel/initrd_kern.c     2003-10-21 03:26:06.000000000 -0400
18930 @@ -0,0 +1,59 @@
18931 +/*
18932 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
18933 + * Licensed under the GPL
18934 + */
18935 +
18936 +#include "linux/init.h"
18937 +#include "linux/bootmem.h"
18938 +#include "linux/blk.h"
18939 +#include "asm/types.h"
18940 +#include "user_util.h"
18941 +#include "kern_util.h"
18942 +#include "initrd.h"
18943 +#include "init.h"
18944 +#include "os.h"
18945 +
18946 +/* Changed by uml_initrd_setup, which is a setup */
18947 +static char *initrd __initdata = NULL;
18948 +
18949 +static int __init read_initrd(void)
18950 +{
18951 +       void *area;
18952 +       long long size;
18953 +       int err;
18954 +
18955 +       if(initrd == NULL) return 0;
18956 +       err = os_file_size(initrd, &size);
18957 +       if(err) return 0;
18958 +       area = alloc_bootmem(size);
18959 +       if(area == NULL) return 0;
18960 +       if(load_initrd(initrd, area, size) == -1) return 0;
18961 +       initrd_start = (unsigned long) area;
18962 +       initrd_end = initrd_start + size;
18963 +       return 0;
18964 +}
18965 +
18966 +__uml_postsetup(read_initrd);
18967 +
18968 +static int __init uml_initrd_setup(char *line, int *add)
18969 +{
18970 +       initrd = line;
18971 +       return 0;
18972 +}
18973 +
18974 +__uml_setup("initrd=", uml_initrd_setup, 
18975 +"initrd=<initrd image>\n"
18976 +"    This is used to boot UML from an initrd image.  The argument is the\n"
18977 +"    name of the file containing the image.\n\n"
18978 +);
18979 +
18980 +/*
18981 + * Overrides for Emacs so that we follow Linus's tabbing style.
18982 + * Emacs will notice this stuff at the end of the file and automatically
18983 + * adjust the settings for this buffer only.  This must remain at the end
18984 + * of the file.
18985 + * ---------------------------------------------------------------------------
18986 + * Local variables:
18987 + * c-file-style: "linux"
18988 + * End:
18989 + */
18990 diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_user.c um/arch/um/kernel/initrd_user.c
18991 --- orig/arch/um/kernel/initrd_user.c   1969-12-31 19:00:00.000000000 -0500
18992 +++ um/arch/um/kernel/initrd_user.c     2003-10-21 03:26:06.000000000 -0400
18993 @@ -0,0 +1,44 @@
18994 +/*
18995 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
18996 + * Licensed under the GPL
18997 + */
18998 +
18999 +#include <unistd.h>
19000 +#include <sys/types.h>
19001 +#include <sys/stat.h>
19002 +#include <errno.h>
19003 +
19004 +#include "user_util.h"
19005 +#include "kern_util.h"
19006 +#include "user.h"
19007 +#include "initrd.h"
19008 +#include "os.h"
19009 +
19010 +int load_initrd(char *filename, void *buf, int size)
19011 +{
19012 +       int fd, n;
19013 +
19014 +       fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
19015 +       if(fd < 0){
19016 +               printk("Opening '%s' failed - err = %d\n", filename, -fd);
19017 +               return(-1);
19018 +       }
19019 +       n = os_read_file(fd, buf, size);
19020 +       if(n != size){
19021 +               printk("Read of %d bytes from '%s' failed, err = %d\n", size, 
19022 +                      filename, -n);
19023 +               return(-1);
19024 +       }
19025 +       return(0);
19026 +}
19027 +
19028 +/*
19029 + * Overrides for Emacs so that we follow Linus's tabbing style.
19030 + * Emacs will notice this stuff at the end of the file and automatically
19031 + * adjust the settings for this buffer only.  This must remain at the end
19032 + * of the file.
19033 + * ---------------------------------------------------------------------------
19034 + * Local variables:
19035 + * c-file-style: "linux"
19036 + * End:
19037 + */
19038 diff -Naur -X ../exclude-files orig/arch/um/kernel/init_task.c um/arch/um/kernel/init_task.c
19039 --- orig/arch/um/kernel/init_task.c     1969-12-31 19:00:00.000000000 -0500
19040 +++ um/arch/um/kernel/init_task.c       2003-10-21 03:26:06.000000000 -0400
19041 @@ -0,0 +1,61 @@
19042 +/* 
19043 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19044 + * Licensed under the GPL
19045 + */
19046 +
19047 +#include "linux/config.h"
19048 +#include "linux/mm.h"
19049 +#include "linux/sched.h"
19050 +#include "linux/version.h"
19051 +#include "asm/uaccess.h"
19052 +#include "asm/pgtable.h"
19053 +#include "user_util.h"
19054 +#include "mem_user.h"
19055 +
19056 +static struct fs_struct init_fs = INIT_FS;
19057 +static struct files_struct init_files = INIT_FILES;
19058 +static struct signal_struct init_signals = INIT_SIGNALS;
19059 +struct mm_struct init_mm = INIT_MM(init_mm);
19060 +
19061 +/*
19062 + * Initial task structure.
19063 + *
19064 + * We need to make sure that this is 16384-byte aligned due to the
19065 + * way process stacks are handled. This is done by having a special
19066 + * "init_task" linker map entry..
19067 + */
19068 +
19069 +union task_union init_task_union 
19070 +__attribute__((__section__(".data.init_task"))) = 
19071 +{ INIT_TASK(init_task_union.task) };
19072 +
19073 +struct task_struct *alloc_task_struct(void)
19074 +{
19075 +       return((struct task_struct *) 
19076 +              __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
19077 +}
19078 +
19079 +void unprotect_stack(unsigned long stack)
19080 +{
19081 +       protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, 
19082 +                      1, 1, 0, 1);
19083 +}
19084 +
19085 +void free_task_struct(struct task_struct *task)
19086 +{
19087 +       /* free_pages decrements the page counter and only actually frees
19088 +        * the pages if they are now not accessed by anything.
19089 +        */
19090 +       free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
19091 +}
19092 +
19093 +/*
19094 + * Overrides for Emacs so that we follow Linus's tabbing style.
19095 + * Emacs will notice this stuff at the end of the file and automatically
19096 + * adjust the settings for this buffer only.  This must remain at the end
19097 + * of the file.
19098 + * ---------------------------------------------------------------------------
19099 + * Local variables:
19100 + * c-file-style: "linux"
19101 + * End:
19102 + */
19103 diff -Naur -X ../exclude-files orig/arch/um/kernel/irq.c um/arch/um/kernel/irq.c
19104 --- orig/arch/um/kernel/irq.c   1969-12-31 19:00:00.000000000 -0500
19105 +++ um/arch/um/kernel/irq.c     2003-12-16 22:45:27.000000000 -0500
19106 @@ -0,0 +1,840 @@
19107 +/* 
19108 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19109 + * Licensed under the GPL
19110 + * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
19111 + *     Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
19112 + */
19113 +
19114 +#include "linux/config.h"
19115 +#include "linux/kernel.h"
19116 +#include "linux/smp.h"
19117 +#include "linux/irq.h"
19118 +#include "linux/kernel_stat.h"
19119 +#include "linux/interrupt.h"
19120 +#include "linux/random.h"
19121 +#include "linux/slab.h"
19122 +#include "linux/file.h"
19123 +#include "linux/proc_fs.h"
19124 +#include "linux/init.h"
19125 +#include "linux/seq_file.h"
19126 +#include "asm/irq.h"
19127 +#include "asm/hw_irq.h"
19128 +#include "asm/hardirq.h"
19129 +#include "asm/atomic.h"
19130 +#include "asm/signal.h"
19131 +#include "asm/system.h"
19132 +#include "asm/errno.h"
19133 +#include "asm/uaccess.h"
19134 +#include "user_util.h"
19135 +#include "kern_util.h"
19136 +#include "irq_user.h"
19137 +#include "irq_kern.h"
19138 +
19139 +static void register_irq_proc (unsigned int irq);
19140 +
19141 +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
19142 +        { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
19143 +
19144 +/*
19145 + * Generic no controller code
19146 + */
19147 +
19148 +static void enable_none(unsigned int irq) { }
19149 +static unsigned int startup_none(unsigned int irq) { return 0; }
19150 +static void disable_none(unsigned int irq) { }
19151 +static void ack_none(unsigned int irq)
19152 +{
19153 +/*
19154 + * 'what should we do if we get a hw irq event on an illegal vector'.
19155 + * each architecture has to answer this themselves, it doesnt deserve
19156 + * a generic callback i think.
19157 + */
19158 +#if CONFIG_X86
19159 +       printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
19160 +#ifdef CONFIG_X86_LOCAL_APIC
19161 +       /*
19162 +        * Currently unexpected vectors happen only on SMP and APIC.
19163 +        * We _must_ ack these because every local APIC has only N
19164 +        * irq slots per priority level, and a 'hanging, unacked' IRQ
19165 +        * holds up an irq slot - in excessive cases (when multiple
19166 +        * unexpected vectors occur) that might lock up the APIC
19167 +        * completely.
19168 +        */
19169 +       ack_APIC_irq();
19170 +#endif
19171 +#endif
19172 +}
19173 +
19174 +/* startup is the same as "enable", shutdown is same as "disable" */
19175 +#define shutdown_none  disable_none
19176 +#define end_none       enable_none
19177 +
19178 +struct hw_interrupt_type no_irq_type = {
19179 +       "none",
19180 +       startup_none,
19181 +       shutdown_none,
19182 +       enable_none,
19183 +       disable_none,
19184 +       ack_none,
19185 +       end_none
19186 +};
19187 +
19188 +/*
19189 + * Generic, controller-independent functions:
19190 + */
19191 +
19192 +int get_irq_list(char *buf)
19193 +{
19194 +       int i, j;
19195 +       unsigned long flags;
19196 +       struct irqaction * action;
19197 +       char *p = buf;
19198 +
19199 +       p += sprintf(p, "           ");
19200 +       for (j=0; j<smp_num_cpus; j++)
19201 +               p += sprintf(p, "CPU%d       ",j);
19202 +       *p++ = '\n';
19203 +
19204 +       for (i = 0 ; i < NR_IRQS ; i++) {
19205 +               spin_lock_irqsave(&irq_desc[i].lock, flags);
19206 +               action = irq_desc[i].action;
19207 +               if (!action) 
19208 +                       goto end;
19209 +               p += sprintf(p, "%3d: ",i);
19210 +#ifndef CONFIG_SMP
19211 +               p += sprintf(p, "%10u ", kstat_irqs(i));
19212 +#else
19213 +               for (j = 0; j < smp_num_cpus; j++)
19214 +                       p += sprintf(p, "%10u ",
19215 +                               kstat.irqs[cpu_logical_map(j)][i]);
19216 +#endif
19217 +               p += sprintf(p, " %14s", irq_desc[i].handler->typename);
19218 +               p += sprintf(p, "  %s", action->name);
19219 +
19220 +               for (action=action->next; action; action = action->next)
19221 +                       p += sprintf(p, ", %s", action->name);
19222 +               *p++ = '\n';
19223 +       end:
19224 +               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
19225 +       }
19226 +       p += sprintf(p, "\n");
19227 +#ifdef notdef
19228 +#if CONFIG_SMP
19229 +       p += sprintf(p, "LOC: ");
19230 +       for (j = 0; j < smp_num_cpus; j++)
19231 +               p += sprintf(p, "%10u ",
19232 +                       apic_timer_irqs[cpu_logical_map(j)]);
19233 +       p += sprintf(p, "\n");
19234 +#endif
19235 +#endif
19236 +       p += sprintf(p, "ERR: %10lu\n", 0L);
19237 +       return p - buf;
19238 +}
19239 +
19240 +/*
19241 + * This should really return information about whether
19242 + * we should do bottom half handling etc. Right now we
19243 + * end up _always_ checking the bottom half, which is a
19244 + * waste of time and is not what some drivers would
19245 + * prefer.
19246 + */
19247 +int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, 
19248 +                    struct irqaction * action)
19249 +{
19250 +       int status;
19251 +       int cpu = smp_processor_id();
19252 +
19253 +       irq_enter(cpu, irq);
19254 +
19255 +       status = 1;     /* Force the "do bottom halves" bit */
19256 +
19257 +       if (!(action->flags & SA_INTERRUPT))
19258 +               __sti();
19259 +
19260 +       do {
19261 +               status |= action->flags;
19262 +               action->handler(irq, action->dev_id, regs);
19263 +               action = action->next;
19264 +       } while (action);
19265 +       if (status & SA_SAMPLE_RANDOM)
19266 +               add_interrupt_randomness(irq);
19267 +       __cli();
19268 +
19269 +       irq_exit(cpu, irq);
19270 +
19271 +       return status;
19272 +}
19273 +
19274 +/*
19275 + * Generic enable/disable code: this just calls
19276 + * down into the PIC-specific version for the actual
19277 + * hardware disable after having gotten the irq
19278 + * controller lock. 
19279 + */
19280
19281 +/**
19282 + *     disable_irq_nosync - disable an irq without waiting
19283 + *     @irq: Interrupt to disable
19284 + *
19285 + *     Disable the selected interrupt line. Disables of an interrupt
19286 + *     stack. Unlike disable_irq(), this function does not ensure existing
19287 + *     instances of the IRQ handler have completed before returning.
19288 + *
19289 + *     This function may be called from IRQ context.
19290 + */
19291
19292 +void inline disable_irq_nosync(unsigned int irq)
19293 +{
19294 +       irq_desc_t *desc = irq_desc + irq;
19295 +       unsigned long flags;
19296 +
19297 +       spin_lock_irqsave(&desc->lock, flags);
19298 +       if (!desc->depth++) {
19299 +               desc->status |= IRQ_DISABLED;
19300 +               desc->handler->disable(irq);
19301 +       }
19302 +       spin_unlock_irqrestore(&desc->lock, flags);
19303 +}
19304 +
19305 +/**
19306 + *     disable_irq - disable an irq and wait for completion
19307 + *     @irq: Interrupt to disable
19308 + *
19309 + *     Disable the selected interrupt line. Disables of an interrupt
19310 + *     stack. That is for two disables you need two enables. This
19311 + *     function waits for any pending IRQ handlers for this interrupt
19312 + *     to complete before returning. If you use this function while
19313 + *     holding a resource the IRQ handler may need you will deadlock.
19314 + *
19315 + *     This function may be called - with care - from IRQ context.
19316 + */
19317
19318 +void disable_irq(unsigned int irq)
19319 +{
19320 +       disable_irq_nosync(irq);
19321 +
19322 +       if (!local_irq_count(smp_processor_id())) {
19323 +               do {
19324 +                       barrier();
19325 +               } while (irq_desc[irq].status & IRQ_INPROGRESS);
19326 +       }
19327 +}
19328 +
19329 +/**
19330 + *     enable_irq - enable interrupt handling on an irq
19331 + *     @irq: Interrupt to enable
19332 + *
19333 + *     Re-enables the processing of interrupts on this IRQ line
19334 + *     providing no disable_irq calls are now in effect.
19335 + *
19336 + *     This function may be called from IRQ context.
19337 + */
19338
19339 +void enable_irq(unsigned int irq)
19340 +{
19341 +       irq_desc_t *desc = irq_desc + irq;
19342 +       unsigned long flags;
19343 +
19344 +       spin_lock_irqsave(&desc->lock, flags);
19345 +       switch (desc->depth) {
19346 +       case 1: {
19347 +               unsigned int status = desc->status & ~IRQ_DISABLED;
19348 +               desc->status = status;
19349 +               if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
19350 +                       desc->status = status | IRQ_REPLAY;
19351 +                       hw_resend_irq(desc->handler,irq);
19352 +               }
19353 +               desc->handler->enable(irq);
19354 +               /* fall-through */
19355 +       }
19356 +       default:
19357 +               desc->depth--;
19358 +               break;
19359 +       case 0:
19360 +               printk(KERN_ERR "enable_irq() unbalanced from %p\n",
19361 +                      __builtin_return_address(0));
19362 +       }
19363 +       spin_unlock_irqrestore(&desc->lock, flags);
19364 +}
19365 +
19366 +/*
19367 + * do_IRQ handles all normal device IRQ's (the special
19368 + * SMP cross-CPU interrupts have their own specific
19369 + * handlers).
19370 + */
19371 +unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
19372 +{      
19373 +       /* 
19374 +        * 0 return value means that this irq is already being
19375 +        * handled by some other CPU. (or is disabled)
19376 +        */
19377 +       int cpu = smp_processor_id();
19378 +       irq_desc_t *desc = irq_desc + irq;
19379 +       struct irqaction * action;
19380 +       unsigned int status;
19381 +
19382 +       kstat.irqs[cpu][irq]++;
19383 +       spin_lock(&desc->lock);
19384 +       desc->handler->ack(irq);
19385 +       /*
19386 +          REPLAY is when Linux resends an IRQ that was dropped earlier
19387 +          WAITING is used by probe to mark irqs that are being tested
19388 +          */
19389 +       status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
19390 +       status |= IRQ_PENDING; /* we _want_ to handle it */
19391 +
19392 +       /*
19393 +        * If the IRQ is disabled for whatever reason, we cannot
19394 +        * use the action we have.
19395 +        */
19396 +       action = NULL;
19397 +       if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
19398 +               action = desc->action;
19399 +               status &= ~IRQ_PENDING; /* we commit to handling */
19400 +               status |= IRQ_INPROGRESS; /* we are handling it */
19401 +       }
19402 +       desc->status = status;
19403 +
19404 +       /*
19405 +        * If there is no IRQ handler or it was disabled, exit early.
19406 +          Since we set PENDING, if another processor is handling
19407 +          a different instance of this same irq, the other processor
19408 +          will take care of it.
19409 +        */
19410 +       if (!action)
19411 +               goto out;
19412 +
19413 +       /*
19414 +        * Edge triggered interrupts need to remember
19415 +        * pending events.
19416 +        * This applies to any hw interrupts that allow a second
19417 +        * instance of the same irq to arrive while we are in do_IRQ
19418 +        * or in the handler. But the code here only handles the _second_
19419 +        * instance of the irq, not the third or fourth. So it is mostly
19420 +        * useful for irq hardware that does not mask cleanly in an
19421 +        * SMP environment.
19422 +        */
19423 +       for (;;) {
19424 +               spin_unlock(&desc->lock);
19425 +               handle_IRQ_event(irq, (struct pt_regs *) regs, action);
19426 +               spin_lock(&desc->lock);
19427 +               
19428 +               if (!(desc->status & IRQ_PENDING))
19429 +                       break;
19430 +               desc->status &= ~IRQ_PENDING;
19431 +       }
19432 +       desc->status &= ~IRQ_INPROGRESS;
19433 +out:
19434 +       /*
19435 +        * The ->end() handler has to deal with interrupts which got
19436 +        * disabled while the handler was running.
19437 +        */
19438 +       desc->handler->end(irq);
19439 +       spin_unlock(&desc->lock);
19440 +
19441 +       if (softirq_pending(cpu))
19442 +               do_softirq();
19443 +       return 1;
19444 +}
19445 +
19446 +/**
19447 + *     request_irq - allocate an interrupt line
19448 + *     @irq: Interrupt line to allocate
19449 + *     @handler: Function to be called when the IRQ occurs
19450 + *     @irqflags: Interrupt type flags
19451 + *     @devname: An ascii name for the claiming device
19452 + *     @dev_id: A cookie passed back to the handler function
19453 + *
19454 + *     This call allocates interrupt resources and enables the
19455 + *     interrupt line and IRQ handling. From the point this
19456 + *     call is made your handler function may be invoked. Since
19457 + *     your handler function must clear any interrupt the board 
19458 + *     raises, you must take care both to initialise your hardware
19459 + *     and to set up the interrupt handler in the right order.
19460 + *
19461 + *     Dev_id must be globally unique. Normally the address of the
19462 + *     device data structure is used as the cookie. Since the handler
19463 + *     receives this value it makes sense to use it.
19464 + *
19465 + *     If your interrupt is shared you must pass a non NULL dev_id
19466 + *     as this is required when freeing the interrupt.
19467 + *
19468 + *     Flags:
19469 + *
19470 + *     SA_SHIRQ                Interrupt is shared
19471 + *
19472 + *     SA_INTERRUPT            Disable local interrupts while processing
19473 + *
19474 + *     SA_SAMPLE_RANDOM        The interrupt can be used for entropy
19475 + *
19476 + */
19477
19478 +int request_irq(unsigned int irq,
19479 +               void (*handler)(int, void *, struct pt_regs *),
19480 +               unsigned long irqflags, 
19481 +               const char * devname,
19482 +               void *dev_id)
19483 +{
19484 +       int retval;
19485 +       struct irqaction * action;
19486 +
19487 +#if 1
19488 +       /*
19489 +        * Sanity-check: shared interrupts should REALLY pass in
19490 +        * a real dev-ID, otherwise we'll have trouble later trying
19491 +        * to figure out which interrupt is which (messes up the
19492 +        * interrupt freeing logic etc).
19493 +        */
19494 +       if (irqflags & SA_SHIRQ) {
19495 +               if (!dev_id)
19496 +                       printk(KERN_ERR "Bad boy: %s (at 0x%x) called us "
19497 +                              "without a dev_id!\n", devname, (&irq)[-1]);
19498 +       }
19499 +#endif
19500 +
19501 +       if (irq >= NR_IRQS)
19502 +               return -EINVAL;
19503 +       if (!handler)
19504 +               return -EINVAL;
19505 +
19506 +       action = (struct irqaction *)
19507 +                       kmalloc(sizeof(struct irqaction), GFP_KERNEL);
19508 +       if (!action)
19509 +               return -ENOMEM;
19510 +
19511 +       action->handler = handler;
19512 +       action->flags = irqflags;
19513 +       action->mask = 0;
19514 +       action->name = devname;
19515 +       action->next = NULL;
19516 +       action->dev_id = dev_id;
19517 +
19518 +       retval = setup_irq(irq, action);
19519 +       if (retval)
19520 +               kfree(action);
19521 +       return retval;
19522 +}
19523 +
19524 +int um_request_irq(unsigned int irq, int fd, int type,
19525 +                  void (*handler)(int, void *, struct pt_regs *),
19526 +                  unsigned long irqflags, const char * devname,
19527 +                  void *dev_id)
19528 +{
19529 +       int err;
19530 +
19531 +       err = request_irq(irq, handler, irqflags, devname, dev_id);
19532 +       if(err) 
19533 +               return(err);
19534 +
19535 +       if(fd != -1)
19536 +               err = activate_fd(irq, fd, type, dev_id);
19537 +       return(err);
19538 +}
19539 +
19540 +/* this was setup_x86_irq but it seems pretty generic */
19541 +int setup_irq(unsigned int irq, struct irqaction * new)
19542 +{
19543 +       int shared = 0;
19544 +       unsigned long flags;
19545 +       struct irqaction *old, **p;
19546 +       irq_desc_t *desc = irq_desc + irq;
19547 +
19548 +       /*
19549 +        * Some drivers like serial.c use request_irq() heavily,
19550 +        * so we have to be careful not to interfere with a
19551 +        * running system.
19552 +        */
19553 +       if (new->flags & SA_SAMPLE_RANDOM) {
19554 +               /*
19555 +                * This function might sleep, we want to call it first,
19556 +                * outside of the atomic block.
19557 +                * Yes, this might clear the entropy pool if the wrong
19558 +                * driver is attempted to be loaded, without actually
19559 +                * installing a new handler, but is this really a problem,
19560 +                * only the sysadmin is able to do this.
19561 +                */
19562 +               rand_initialize_irq(irq);
19563 +       }
19564 +
19565 +       /*
19566 +        * The following block of code has to be executed atomically
19567 +        */
19568 +       spin_lock_irqsave(&desc->lock,flags);
19569 +       p = &desc->action;
19570 +       old = *p;
19571 +       if (old != NULL) {
19572 +               /* Can't share interrupts unless both agree to */
19573 +               if (!(old->flags & new->flags & SA_SHIRQ)) {
19574 +                       spin_unlock_irqrestore(&desc->lock,flags);
19575 +                       return -EBUSY;
19576 +               }
19577 +
19578 +               /* add new interrupt at end of irq queue */
19579 +               do {
19580 +                       p = &old->next;
19581 +                       old = *p;
19582 +               } while (old);
19583 +               shared = 1;
19584 +       }
19585 +
19586 +       *p = new;
19587 +
19588 +       if (!shared) {
19589 +               desc->depth = 0;
19590 +               desc->status &= ~IRQ_DISABLED;
19591 +               desc->handler->startup(irq);
19592 +       }
19593 +       spin_unlock_irqrestore(&desc->lock,flags);
19594 +
19595 +       register_irq_proc(irq);
19596 +       return 0;
19597 +}
19598 +
19599 +/**
19600 + *     free_irq - free an interrupt
19601 + *     @irq: Interrupt line to free
19602 + *     @dev_id: Device identity to free
19603 + *
19604 + *     Remove an interrupt handler. The handler is removed and if the
19605 + *     interrupt line is no longer in use by any driver it is disabled.
19606 + *     On a shared IRQ the caller must ensure the interrupt is disabled
19607 + *     on the card it drives before calling this function. The function
19608 + *     does not return until any executing interrupts for this IRQ
19609 + *     have completed.
19610 + *
19611 + *     This function may be called from interrupt context. 
19612 + *
19613 + *     Bugs: Attempting to free an irq in a handler for the same irq hangs
19614 + *           the machine.
19615 + */
19616
19617 +void free_irq(unsigned int irq, void *dev_id)
19618 +{
19619 +       irq_desc_t *desc;
19620 +       struct irqaction **p;
19621 +       unsigned long flags;
19622 +
19623 +       if (irq >= NR_IRQS)
19624 +               return;
19625 +
19626 +       desc = irq_desc + irq;
19627 +       spin_lock_irqsave(&desc->lock,flags);
19628 +       p = &desc->action;
19629 +       for (;;) {
19630 +               struct irqaction * action = *p;
19631 +               if (action) {
19632 +                       struct irqaction **pp = p;
19633 +                       p = &action->next;
19634 +                       if (action->dev_id != dev_id)
19635 +                               continue;
19636 +
19637 +                       /* Found it - now remove it from the list of entries */
19638 +                       *pp = action->next;
19639 +                       if (!desc->action) {
19640 +                               desc->status |= IRQ_DISABLED;
19641 +                               desc->handler->shutdown(irq);
19642 +                       }
19643 +                       free_irq_by_irq_and_dev(irq, dev_id);
19644 +                       spin_unlock_irqrestore(&desc->lock,flags);
19645 +
19646 +#ifdef CONFIG_SMP
19647 +                       /* Wait to make sure it's not being used on another CPU */
19648 +                       while (desc->status & IRQ_INPROGRESS)
19649 +                               barrier();
19650 +#endif
19651 +                       kfree(action);
19652 +                       return;
19653 +               }
19654 +               printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
19655 +               spin_unlock_irqrestore(&desc->lock,flags);
19656 +               return;
19657 +       }
19658 +}
19659 +
19660 +/* These are initialized by sysctl_init, which is called from init/main.c */
19661 +static struct proc_dir_entry * root_irq_dir;
19662 +static struct proc_dir_entry * irq_dir [NR_IRQS];
19663 +static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
19664 +
19665 +/* These are read and written as longs, so a read won't see a partial write
19666 + * even during a race.
19667 + */
19668 +static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
19669 +
19670 +#define HEX_DIGITS 8
19671 +
19672 +static int irq_affinity_read_proc (char *page, char **start, off_t off,
19673 +                       int count, int *eof, void *data)
19674 +{
19675 +       if (count < HEX_DIGITS+1)
19676 +               return -EINVAL;
19677 +       return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
19678 +}
19679 +
19680 +static unsigned int parse_hex_value (const char *buffer,
19681 +               unsigned long count, unsigned long *ret)
19682 +{
19683 +       unsigned char hexnum [HEX_DIGITS];
19684 +       unsigned long value;
19685 +       int i;
19686 +
19687 +       if (!count)
19688 +               return -EINVAL;
19689 +       if (count > HEX_DIGITS)
19690 +               count = HEX_DIGITS;
19691 +       if (copy_from_user(hexnum, buffer, count))
19692 +               return -EFAULT;
19693 +
19694 +       /*
19695 +        * Parse the first HEX_DIGITS characters as a hex string, any non-hex
19696 +        * char is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
19697 +        */
19698 +       value = 0;
19699 +
19700 +       for (i = 0; i < count; i++) {
19701 +               unsigned int c = hexnum[i];
19702 +
19703 +               switch (c) {
19704 +                       case '0' ... '9': c -= '0'; break;
19705 +                       case 'a' ... 'f': c -= 'a'-10; break;
19706 +                       case 'A' ... 'F': c -= 'A'-10; break;
19707 +               default:
19708 +                       goto out;
19709 +               }
19710 +               value = (value << 4) | c;
19711 +       }
19712 +out:
19713 +       *ret = value;
19714 +       return 0;
19715 +}
19716 +
19717 +static int irq_affinity_write_proc (struct file *file, const char *buffer,
19718 +                                       unsigned long count, void *data)
19719 +{
19720 +       int irq = (long) data, full_count = count, err;
19721 +       unsigned long new_value;
19722 +
19723 +       if (!irq_desc[irq].handler->set_affinity)
19724 +               return -EIO;
19725 +
19726 +       err = parse_hex_value(buffer, count, &new_value);
19727 +
19728 +#if CONFIG_SMP
19729 +       /*
19730 +        * Do not allow disabling IRQs completely - it's a too easy
19731 +        * way to make the system unusable accidentally :-) At least
19732 +        * one online CPU still has to be targeted.
19733 +        */
19734 +       if (!(new_value & cpu_online_map))
19735 +               return -EINVAL;
19736 +#endif
19737 +
19738 +       irq_affinity[irq] = new_value;
19739 +       irq_desc[irq].handler->set_affinity(irq, new_value);
19740 +
19741 +       return full_count;
19742 +}
19743 +
19744 +static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
19745 +                       int count, int *eof, void *data)
19746 +{
19747 +       unsigned long *mask = (unsigned long *) data;
19748 +       if (count < HEX_DIGITS+1)
19749 +               return -EINVAL;
19750 +       return sprintf (page, "%08lx\n", *mask);
19751 +}
19752 +
19753 +static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
19754 +                                       unsigned long count, void *data)
19755 +{
19756 +       unsigned long *mask = (unsigned long *) data, full_count = count, err;
19757 +       unsigned long new_value;
19758 +
19759 +       err = parse_hex_value(buffer, count, &new_value);
19760 +       if (err)
19761 +               return err;
19762 +
19763 +       *mask = new_value;
19764 +       return full_count;
19765 +}
19766 +
19767 +#define MAX_NAMELEN 10
19768 +
19769 +static void register_irq_proc (unsigned int irq)
19770 +{
19771 +       struct proc_dir_entry *entry;
19772 +       char name [MAX_NAMELEN];
19773 +
19774 +       if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
19775 +           irq_dir[irq])
19776 +               return;
19777 +
19778 +       memset(name, 0, MAX_NAMELEN);
19779 +       sprintf(name, "%d", irq);
19780 +
19781 +       /* create /proc/irq/1234 */
19782 +       irq_dir[irq] = proc_mkdir(name, root_irq_dir);
19783 +
19784 +       /* create /proc/irq/1234/smp_affinity */
19785 +       entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
19786 +
19787 +       entry->nlink = 1;
19788 +       entry->data = (void *)(long)irq;
19789 +       entry->read_proc = irq_affinity_read_proc;
19790 +       entry->write_proc = irq_affinity_write_proc;
19791 +
19792 +       smp_affinity_entry[irq] = entry;
19793 +}
19794 +
19795 +/* Read and written as a long */
19796 +unsigned long prof_cpu_mask = -1;
19797 +
19798 +void __init init_irq_proc (void)
19799 +{
19800 +       struct proc_dir_entry *entry;
19801 +       int i;
19802 +
19803 +       /* create /proc/irq */
19804 +       root_irq_dir = proc_mkdir("irq", 0);
19805 +
19806 +       /* create /proc/irq/prof_cpu_mask */
19807 +       entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
19808 +
19809 +       entry->nlink = 1;
19810 +       entry->data = (void *)&prof_cpu_mask;
19811 +       entry->read_proc = prof_cpu_mask_read_proc;
19812 +       entry->write_proc = prof_cpu_mask_write_proc;
19813 +
19814 +       /*
19815 +        * Create entries for all existing IRQs.
19816 +        */
19817 +       for (i = 0; i < NR_IRQS; i++)
19818 +               register_irq_proc(i);
19819 +}
19820 +
19821 +static spinlock_t irq_spinlock = SPIN_LOCK_UNLOCKED;
19822 +
19823 +unsigned long irq_lock(void)
19824 +{
19825 +       unsigned long flags;
19826 +
19827 +       spin_lock_irqsave(&irq_spinlock, flags);
19828 +       return(flags);
19829 +}
19830 +
19831 +void irq_unlock(unsigned long flags)
19832 +{
19833 +       spin_unlock_irqrestore(&irq_spinlock, flags);
19834 +}
19835 +
19836 +unsigned long probe_irq_on(void)
19837 +{
19838 +       return(0);
19839 +}
19840 +
19841 +int probe_irq_off(unsigned long val)
19842 +{
19843 +       return(0);
19844 +}
19845 +
19846 +static unsigned int startup_SIGIO_irq(unsigned int irq)
19847 +{
19848 +       return(0);
19849 +}
19850 +
19851 +static void shutdown_SIGIO_irq(unsigned int irq)
19852 +{
19853 +}
19854 +
19855 +static void enable_SIGIO_irq(unsigned int irq)
19856 +{
19857 +}
19858 +
19859 +static void disable_SIGIO_irq(unsigned int irq)
19860 +{
19861 +}
19862 +
19863 +static void mask_and_ack_SIGIO(unsigned int irq)
19864 +{
19865 +}
19866 +
19867 +static void end_SIGIO_irq(unsigned int irq)
19868 +{
19869 +}
19870 +
19871 +static unsigned int startup_SIGVTALRM_irq(unsigned int irq)
19872 +{
19873 +       return(0);
19874 +}
19875 +
19876 +static void shutdown_SIGVTALRM_irq(unsigned int irq)
19877 +{
19878 +}
19879 +
19880 +static void enable_SIGVTALRM_irq(unsigned int irq)
19881 +{
19882 +}
19883 +
19884 +static void disable_SIGVTALRM_irq(unsigned int irq)
19885 +{
19886 +}
19887 +
19888 +static void mask_and_ack_SIGVTALRM(unsigned int irq)
19889 +{
19890 +}
19891 +
19892 +static void end_SIGVTALRM_irq(unsigned int irq)
19893 +{
19894 +}
19895 +
19896 +static struct hw_interrupt_type SIGIO_irq_type = {
19897 +       "SIGIO",
19898 +       startup_SIGIO_irq,
19899 +       shutdown_SIGIO_irq,
19900 +       enable_SIGIO_irq,
19901 +       disable_SIGIO_irq,
19902 +       mask_and_ack_SIGIO,
19903 +       end_SIGIO_irq,
19904 +       NULL
19905 +};
19906 +
19907 +static struct hw_interrupt_type SIGVTALRM_irq_type = {
19908 +       "SIGVTALRM",
19909 +       startup_SIGVTALRM_irq,
19910 +       shutdown_SIGVTALRM_irq,
19911 +       enable_SIGVTALRM_irq,
19912 +       disable_SIGVTALRM_irq,
19913 +       mask_and_ack_SIGVTALRM,
19914 +       end_SIGVTALRM_irq,
19915 +       NULL
19916 +};
19917 +
19918 +void __init init_IRQ(void)
19919 +{
19920 +       int i;
19921 +
19922 +       irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
19923 +       irq_desc[TIMER_IRQ].action = 0;
19924 +       irq_desc[TIMER_IRQ].depth = 1;
19925 +       irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type;
19926 +       enable_irq(TIMER_IRQ);
19927 +       for(i=1;i<NR_IRQS;i++){
19928 +               irq_desc[i].status = IRQ_DISABLED;
19929 +               irq_desc[i].action = 0;
19930 +               irq_desc[i].depth = 1;
19931 +               irq_desc[i].handler = &SIGIO_irq_type;
19932 +               enable_irq(i);
19933 +       }
19934 +       init_irq_signals(0);
19935 +}
19936 +
19937 +/*
19938 + * Overrides for Emacs so that we follow Linus's tabbing style.
19939 + * Emacs will notice this stuff at the end of the file and automatically
19940 + * adjust the settings for this buffer only.  This must remain at the end
19941 + * of the file.
19942 + * ---------------------------------------------------------------------------
19943 + * Local variables:
19944 + * c-file-style: "linux"
19945 + * End:
19946 + */
19947 diff -Naur -X ../exclude-files orig/arch/um/kernel/irq_user.c um/arch/um/kernel/irq_user.c
19948 --- orig/arch/um/kernel/irq_user.c      1969-12-31 19:00:00.000000000 -0500
19949 +++ um/arch/um/kernel/irq_user.c        2003-10-21 03:26:06.000000000 -0400
19950 @@ -0,0 +1,424 @@
19951 +/* 
19952 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19953 + * Licensed under the GPL
19954 + */
19955 +
19956 +#include <stdlib.h>
19957 +#include <unistd.h>
19958 +#include <errno.h>
19959 +#include <signal.h>
19960 +#include <string.h>
19961 +#include <sys/poll.h>
19962 +#include <sys/types.h>
19963 +#include <sys/time.h>
19964 +#include "user_util.h"
19965 +#include "kern_util.h"
19966 +#include "user.h"
19967 +#include "process.h"
19968 +#include "signal_user.h"
19969 +#include "sigio.h"
19970 +#include "irq_user.h"
19971 +#include "os.h"
19972 +
19973 +struct irq_fd {
19974 +       struct irq_fd *next;
19975 +       void *id;
19976 +       int fd;
19977 +       int type;
19978 +       int irq;
19979 +       int pid;
19980 +       int events;
19981 +       int current_events;
19982 +       int freed;
19983 +};
19984 +
19985 +static struct irq_fd *active_fds = NULL;
19986 +static struct irq_fd **last_irq_ptr = &active_fds;
19987 +
19988 +static struct pollfd *pollfds = NULL;
19989 +static int pollfds_num = 0;
19990 +static int pollfds_size = 0;
19991 +
19992 +extern int io_count, intr_count;
19993 +
19994 +void sigio_handler(int sig, union uml_pt_regs *regs)
19995 +{
19996 +       struct irq_fd *irq_fd, *next;
19997 +       int i, n;
19998 +
19999 +       if(smp_sigio_handler()) return;
20000 +       while(1){
20001 +               n = poll(pollfds, pollfds_num, 0);
20002 +               if(n < 0){
20003 +                       if(errno == EINTR) continue;
20004 +                       printk("sigio_handler : poll returned %d, "
20005 +                              "errno = %d\n", n, errno);
20006 +                       break;
20007 +               }
20008 +               if(n == 0) break;
20009 +
20010 +               irq_fd = active_fds;
20011 +               for(i = 0; i < pollfds_num; i++){
20012 +                       if(pollfds[i].revents != 0){
20013 +                               irq_fd->current_events = pollfds[i].revents;
20014 +                               pollfds[i].fd = -1;
20015 +                       }
20016 +                       irq_fd = irq_fd->next;
20017 +               }
20018 +
20019 +               for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){
20020 +                       next = irq_fd->next;
20021 +                       if(irq_fd->current_events != 0){
20022 +                               irq_fd->current_events = 0;
20023 +                               do_IRQ(irq_fd->irq, regs);
20024 +
20025 +                               /* This is here because the next irq may be
20026 +                                * freed in the handler.  If a console goes
20027 +                                * away, both the read and write irqs will be
20028 +                                * freed.  After do_IRQ, ->next will point to
20029 +                                * a good IRQ.
20030 +                                * Irqs can't be freed inside their handlers,
20031 +                                * so the next best thing is to have them
20032 +                                * marked as needing freeing, so that they
20033 +                                * can be freed here.
20034 +                                */
20035 +                               next = irq_fd->next;
20036 +                               if(irq_fd->freed)
20037 +                                       free_irq(irq_fd->irq, irq_fd->id);
20038 +                       }
20039 +               }
20040 +       }
20041 +}
20042 +
20043 +int activate_ipi(int fd, int pid)
20044 +{
20045 +       return(os_set_fd_async(fd, pid));
20046 +}
20047 +
20048 +static void maybe_sigio_broken(int fd, int type)
20049 +{
20050 +       if(isatty(fd)){
20051 +               if((type == IRQ_WRITE) && !pty_output_sigio){
20052 +                       write_sigio_workaround();
20053 +                       add_sigio_fd(fd, 0);
20054 +               }
20055 +               else if((type == IRQ_READ) && !pty_close_sigio){
20056 +                       write_sigio_workaround();
20057 +                       add_sigio_fd(fd, 1);                    
20058 +               }
20059 +       }
20060 +}
20061 +
20062 +int activate_fd(int irq, int fd, int type, void *dev_id)
20063 +{
20064 +       struct pollfd *tmp_pfd;
20065 +       struct irq_fd *new_fd, *irq_fd;
20066 +       unsigned long flags;
20067 +       int pid, events, err, n, size;
20068 +
20069 +       pid = os_getpid();
20070 +       err = os_set_fd_async(fd, pid);
20071 +       if(err < 0)
20072 +               goto out;
20073 +
20074 +       new_fd = um_kmalloc(sizeof(*new_fd));
20075 +       err = -ENOMEM;
20076 +       if(new_fd == NULL)
20077 +               goto out;
20078 +
20079 +       if(type == IRQ_READ) events = POLLIN | POLLPRI;
20080 +       else events = POLLOUT;
20081 +       *new_fd = ((struct irq_fd) { .next              = NULL,
20082 +                                    .id                = dev_id,
20083 +                                    .fd                = fd,
20084 +                                    .type              = type,
20085 +                                    .irq               = irq,
20086 +                                    .pid               = pid,
20087 +                                    .events            = events,
20088 +                                    .current_events    = 0,
20089 +                                    .freed             = 0  } );
20090 +
20091 +       /* Critical section - locked by a spinlock because this stuff can
20092 +        * be changed from interrupt handlers.  The stuff above is done 
20093 +        * outside the lock because it allocates memory.
20094 +        */
20095 +
20096 +       /* Actually, it only looks like it can be called from interrupt
20097 +        * context.  The culprit is reactivate_fd, which calls 
20098 +        * maybe_sigio_broken, which calls write_sigio_workaround,
20099 +        * which calls activate_fd.  However, write_sigio_workaround should
20100 +        * only be called once, at boot time.  That would make it clear that
20101 +        * this is called only from process context, and can be locked with
20102 +        * a semaphore.
20103 +        */
20104 +       flags = irq_lock();
20105 +       for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
20106 +               if((irq_fd->fd == fd) && (irq_fd->type == type)){
20107 +                       printk("Registering fd %d twice\n", fd);
20108 +                       printk("Irqs : %d, %d\n", irq_fd->irq, irq);
20109 +                       printk("Ids : 0x%x, 0x%x\n", irq_fd->id, dev_id);
20110 +                       goto out_unlock;
20111 +               }
20112 +       }
20113 +
20114 +       n = pollfds_num;
20115 +       if(n == pollfds_size){
20116 +               while(1){
20117 +                       /* Here we have to drop the lock in order to call 
20118 +                        * kmalloc, which might sleep.  If something else
20119 +                        * came in and changed the pollfds array, we free
20120 +                        * the buffer and try again.
20121 +                        */
20122 +                       irq_unlock(flags);
20123 +                       size = (pollfds_num + 1) * sizeof(pollfds[0]);
20124 +                       tmp_pfd = um_kmalloc(size);
20125 +                       flags = irq_lock();
20126 +                       if(tmp_pfd == NULL)
20127 +                               goto out_unlock;
20128 +                       if(n == pollfds_size)
20129 +                               break;
20130 +                       kfree(tmp_pfd);
20131 +               }
20132 +               if(pollfds != NULL){
20133 +                       memcpy(tmp_pfd, pollfds,
20134 +                              sizeof(pollfds[0]) * pollfds_size);
20135 +                       kfree(pollfds);
20136 +               }
20137 +               pollfds = tmp_pfd;
20138 +               pollfds_size++;
20139 +       }
20140 +
20141 +       if(type == IRQ_WRITE) 
20142 +               fd = -1;
20143 +
20144 +       pollfds[pollfds_num] = ((struct pollfd) { .fd   = fd,
20145 +                                                 .events       = events,
20146 +                                                 .revents      = 0 });
20147 +       pollfds_num++;
20148 +
20149 +       *last_irq_ptr = new_fd;
20150 +       last_irq_ptr = &new_fd->next;
20151 +
20152 +       irq_unlock(flags);
20153 +
20154 +       /* This calls activate_fd, so it has to be outside the critical
20155 +        * section.
20156 +        */
20157 +       maybe_sigio_broken(fd, type);
20158 +
20159 +       return(0);
20160 +
20161 + out_unlock:
20162 +       irq_unlock(flags);
20163 +       kfree(new_fd);
20164 + out:
20165 +       return(err);
20166 +}
20167 +
20168 +static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
20169 +{
20170 +       struct irq_fd **prev;
20171 +       unsigned long flags;
20172 +       int i = 0;
20173 +
20174 +       flags = irq_lock();
20175 +       prev = &active_fds;
20176 +       while(*prev != NULL){
20177 +               if((*test)(*prev, arg)){
20178 +                       struct irq_fd *old_fd = *prev;
20179 +                       if((pollfds[i].fd != -1) && 
20180 +                          (pollfds[i].fd != (*prev)->fd)){
20181 +                               printk("free_irq_by_cb - mismatch between "
20182 +                                      "active_fds and pollfds, fd %d vs %d\n",
20183 +                                      (*prev)->fd, pollfds[i].fd);
20184 +                               goto out;
20185 +                       }
20186 +                       memcpy(&pollfds[i], &pollfds[i + 1],
20187 +                              (pollfds_num - i - 1) * sizeof(pollfds[0]));
20188 +                       pollfds_num--;
20189 +                       if(last_irq_ptr == &old_fd->next) 
20190 +                               last_irq_ptr = prev;
20191 +                       *prev = (*prev)->next;
20192 +                       if(old_fd->type == IRQ_WRITE) 
20193 +                               ignore_sigio_fd(old_fd->fd);
20194 +                       kfree(old_fd);
20195 +                       continue;
20196 +               }
20197 +               prev = &(*prev)->next;
20198 +               i++;
20199 +       }
20200 + out:
20201 +       irq_unlock(flags);
20202 +}
20203 +
20204 +struct irq_and_dev {
20205 +       int irq;
20206 +       void *dev;
20207 +};
20208 +
20209 +static int same_irq_and_dev(struct irq_fd *irq, void *d)
20210 +{
20211 +       struct irq_and_dev *data = d;
20212 +
20213 +       return((irq->irq == data->irq) && (irq->id == data->dev));
20214 +}
20215 +
20216 +void free_irq_by_irq_and_dev(int irq, void *dev)
20217 +{
20218 +       struct irq_and_dev data = ((struct irq_and_dev) { .irq  = irq,
20219 +                                                         .dev  = dev });
20220 +
20221 +       free_irq_by_cb(same_irq_and_dev, &data);
20222 +}
20223 +
20224 +static int same_fd(struct irq_fd *irq, void *fd)
20225 +{
20226 +       return(irq->fd == *((int *) fd));
20227 +}
20228 +
20229 +void free_irq_by_fd(int fd)
20230 +{
20231 +       free_irq_by_cb(same_fd, &fd);
20232 +}
20233 +
20234 +static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
20235 +{
20236 +       struct irq_fd *irq;
20237 +       int i = 0;
20238 +
20239 +       for(irq=active_fds; irq != NULL; irq = irq->next){
20240 +               if((irq->fd == fd) && (irq->irq == irqnum)) break;
20241 +               i++;
20242 +       }
20243 +       if(irq == NULL){
20244 +               printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
20245 +               goto out;
20246 +       }
20247 +       if((pollfds[i].fd != -1) && (pollfds[i].fd != fd)){
20248 +               printk("find_irq_by_fd - mismatch between active_fds and "
20249 +                      "pollfds, fd %d vs %d, need %d\n", irq->fd, 
20250 +                      pollfds[i].fd, fd);
20251 +               irq = NULL;
20252 +               goto out;
20253 +       }
20254 +       *index_out = i;
20255 + out:
20256 +       return(irq);
20257 +}
20258 +
20259 +void free_irq_later(int irq, void *dev_id)
20260 +{
20261 +       struct irq_fd *irq_fd;
20262 +       unsigned long flags;
20263 +
20264 +       flags = irq_lock();
20265 +       for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
20266 +               if((irq_fd->irq == irq) && (irq_fd->id == dev_id))
20267 +                       break;
20268 +       }
20269 +       if(irq_fd == NULL){
20270 +               printk("free_irq_later found no irq, irq = %d, "
20271 +                      "dev_id = 0x%p\n", irq, dev_id);
20272 +               goto out;
20273 +       }
20274 +       irq_fd->freed = 1;
20275 + out:
20276 +       irq_unlock(flags);
20277 +}
20278 +
20279 +void reactivate_fd(int fd, int irqnum)
20280 +{
20281 +       struct irq_fd *irq;
20282 +       unsigned long flags;
20283 +       int i;
20284 +
20285 +       flags = irq_lock();
20286 +       irq = find_irq_by_fd(fd, irqnum, &i);
20287 +       if(irq == NULL){
20288 +               irq_unlock(flags);
20289 +               return;
20290 +       }
20291 +
20292 +       pollfds[i].fd = irq->fd;
20293 +
20294 +       irq_unlock(flags);
20295 +
20296 +       /* This calls activate_fd, so it has to be outside the critical
20297 +        * section.
20298 +        */
20299 +       maybe_sigio_broken(fd, irq->type);
20300 +}
20301 +
20302 +void deactivate_fd(int fd, int irqnum)
20303 +{
20304 +       struct irq_fd *irq;
20305 +       unsigned long flags;
20306 +       int i;
20307 +
20308 +       flags = irq_lock();
20309 +       irq = find_irq_by_fd(fd, irqnum, &i);
20310 +       if(irq == NULL)
20311 +               goto out;
20312 +       pollfds[i].fd = -1;
20313 + out:
20314 +       irq_unlock(flags);
20315 +}
20316 +
20317 +void forward_ipi(int fd, int pid)
20318 +{
20319 +       int err;
20320 +
20321 +       err = os_set_owner(fd, pid);
20322 +       if(err < 0)
20323 +               printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
20324 +                      "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
20325 +}
20326 +
20327 +void forward_interrupts(int pid)
20328 +{
20329 +       struct irq_fd *irq;
20330 +       unsigned long flags;
20331 +       int err;
20332 +
20333 +       flags = irq_lock();
20334 +       for(irq=active_fds;irq != NULL;irq = irq->next){
20335 +               err = os_set_owner(irq->fd, pid);
20336 +               if(err < 0){
20337 +                       /* XXX Just remove the irq rather than
20338 +                        * print out an infinite stream of these
20339 +                        */
20340 +                       printk("Failed to forward %d to pid %d, err = %d\n",
20341 +                              irq->fd, pid, -err);
20342 +               }
20343 +
20344 +               irq->pid = pid;
20345 +       }
20346 +       irq_unlock(flags);
20347 +}
20348 +
20349 +void init_irq_signals(int on_sigstack)
20350 +{
20351 +       __sighandler_t h;
20352 +       int flags;
20353 +
20354 +       flags = on_sigstack ? SA_ONSTACK : 0;
20355 +       if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
20356 +       else h = boot_timer_handler;
20357 +
20358 +       set_handler(SIGVTALRM, h, flags | SA_RESTART, 
20359 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
20360 +       set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
20361 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20362 +       signal(SIGWINCH, SIG_IGN);
20363 +}
20364 +
20365 +/*
20366 + * Overrides for Emacs so that we follow Linus's tabbing style.
20367 + * Emacs will notice this stuff at the end of the file and automatically
20368 + * adjust the settings for this buffer only.  This must remain at the end
20369 + * of the file.
20370 + * ---------------------------------------------------------------------------
20371 + * Local variables:
20372 + * c-file-style: "linux"
20373 + * End:
20374 + */
20375 diff -Naur -X ../exclude-files orig/arch/um/kernel/ksyms.c um/arch/um/kernel/ksyms.c
20376 --- orig/arch/um/kernel/ksyms.c 1969-12-31 19:00:00.000000000 -0500
20377 +++ um/arch/um/kernel/ksyms.c   2004-01-23 00:44:09.000000000 -0500
20378 @@ -0,0 +1,120 @@
20379 +/* 
20380 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
20381 + * Licensed under the GPL
20382 + */
20383 +
20384 +#include "linux/config.h"
20385 +#include "linux/module.h"
20386 +#include "linux/string.h"
20387 +#include "linux/smp_lock.h"
20388 +#include "linux/spinlock.h"
20389 +#include "asm/current.h"
20390 +#include "asm/delay.h"
20391 +#include "asm/processor.h"
20392 +#include "asm/unistd.h"
20393 +#include "asm/pgalloc.h"
20394 +#include "asm/pgtable.h"
20395 +#include "asm/page.h"
20396 +#include "kern_util.h"
20397 +#include "user_util.h"
20398 +#include "os.h"
20399 +#include "helper.h"
20400 +
20401 +EXPORT_SYMBOL(stop);
20402 +EXPORT_SYMBOL(strtok);
20403 +EXPORT_SYMBOL(uml_physmem);
20404 +EXPORT_SYMBOL(set_signals);
20405 +EXPORT_SYMBOL(get_signals);
20406 +EXPORT_SYMBOL(kernel_thread);
20407 +EXPORT_SYMBOL(__const_udelay);
20408 +EXPORT_SYMBOL(__udelay);
20409 +EXPORT_SYMBOL(sys_waitpid);
20410 +EXPORT_SYMBOL(task_size);
20411 +EXPORT_SYMBOL(flush_tlb_range);
20412 +EXPORT_SYMBOL(host_task_size);
20413 +EXPORT_SYMBOL(arch_validate);
20414 +EXPORT_SYMBOL(get_kmem_end);
20415 +
20416 +EXPORT_SYMBOL(high_physmem);
20417 +EXPORT_SYMBOL(empty_zero_page);
20418 +EXPORT_SYMBOL(um_virt_to_phys);
20419 +EXPORT_SYMBOL(__virt_to_page);
20420 +EXPORT_SYMBOL(to_phys);
20421 +EXPORT_SYMBOL(to_virt);
20422 +EXPORT_SYMBOL(mode_tt);
20423 +EXPORT_SYMBOL(handle_page_fault);
20424 +
20425 +#ifdef CONFIG_MODE_TT
20426 +EXPORT_SYMBOL(copy_from_user_tt);
20427 +EXPORT_SYMBOL(copy_to_user_tt);
20428 +#endif
20429 +
20430 +#ifdef CONFIG_MODE_SKAS
20431 +EXPORT_SYMBOL(copy_to_user_skas);
20432 +EXPORT_SYMBOL(copy_from_user_skas);
20433 +#endif
20434 +
20435 +EXPORT_SYMBOL(os_stat_fd);
20436 +EXPORT_SYMBOL(os_stat_file);
20437 +EXPORT_SYMBOL(os_access);
20438 +EXPORT_SYMBOL(os_print_error);
20439 +EXPORT_SYMBOL(os_get_exec_close);
20440 +EXPORT_SYMBOL(os_set_exec_close);
20441 +EXPORT_SYMBOL(os_getpid);
20442 +EXPORT_SYMBOL(os_open_file);
20443 +EXPORT_SYMBOL(os_read_file);
20444 +EXPORT_SYMBOL(os_write_file);
20445 +EXPORT_SYMBOL(os_seek_file);
20446 +EXPORT_SYMBOL(os_lock_file);
20447 +EXPORT_SYMBOL(os_pipe);
20448 +EXPORT_SYMBOL(os_file_type);
20449 +EXPORT_SYMBOL(os_file_mode);
20450 +EXPORT_SYMBOL(os_file_size);
20451 +EXPORT_SYMBOL(os_flush_stdout);
20452 +EXPORT_SYMBOL(os_close_file);
20453 +EXPORT_SYMBOL(os_set_fd_async);
20454 +EXPORT_SYMBOL(os_set_fd_block);
20455 +EXPORT_SYMBOL(helper_wait);
20456 +EXPORT_SYMBOL(os_shutdown_socket);
20457 +EXPORT_SYMBOL(os_create_unix_socket);
20458 +EXPORT_SYMBOL(os_connect_socket);
20459 +EXPORT_SYMBOL(os_accept_connection);
20460 +EXPORT_SYMBOL(os_ioctl_generic);
20461 +EXPORT_SYMBOL(os_rcv_fd);
20462 +EXPORT_SYMBOL(run_helper);
20463 +EXPORT_SYMBOL(start_thread);
20464 +EXPORT_SYMBOL(dump_thread);
20465 +
20466 +/* This is here because UML expands open to sys_open, not to a system
20467 + * call instruction.
20468 + */
20469 +EXPORT_SYMBOL(sys_open);
20470 +EXPORT_SYMBOL(sys_lseek);
20471 +EXPORT_SYMBOL(sys_read);
20472 +EXPORT_SYMBOL(sys_wait4);
20473 +
20474 +#ifdef CONFIG_SMP
20475 +
20476 +/* required for SMP */
20477 +
20478 +extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
20479 +EXPORT_SYMBOL_NOVERS(__write_lock_failed);
20480 +
20481 +extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
20482 +EXPORT_SYMBOL_NOVERS(__read_lock_failed);
20483 +
20484 +EXPORT_SYMBOL(kernel_flag_cacheline);
20485 +EXPORT_SYMBOL(smp_num_cpus);
20486 +
20487 +#endif
20488 +
20489 +/*
20490 + * Overrides for Emacs so that we follow Linus's tabbing style.
20491 + * Emacs will notice this stuff at the end of the file and automatically
20492 + * adjust the settings for this buffer only.  This must remain at the end
20493 + * of the file.
20494 + * ---------------------------------------------------------------------------
20495 + * Local variables:
20496 + * c-file-style: "linux"
20497 + * End:
20498 + */
20499 diff -Naur -X ../exclude-files orig/arch/um/kernel/Makefile um/arch/um/kernel/Makefile
20500 --- orig/arch/um/kernel/Makefile        1969-12-31 19:00:00.000000000 -0500
20501 +++ um/arch/um/kernel/Makefile  2003-10-21 03:26:06.000000000 -0400
20502 @@ -0,0 +1,73 @@
20503 +# 
20504 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
20505 +# Licensed under the GPL
20506 +#
20507 +
20508 +O_TARGET = built-in.o
20509 +
20510 +obj-y = config.o checksum.o exec_kern.o exitcode.o frame_kern.o frame.o \
20511 +       helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \
20512 +       physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
20513 +       sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
20514 +       syscall_kern.o syscall_user.o sysrq.o sys_call_table.o tempfile.o \
20515 +       time.o time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o \
20516 +       um_arch.o umid.o user_syms.o user_util.o
20517 +
20518 +obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
20519 +obj-$(CONFIG_GPROF) += gprof_syms.o
20520 +obj-$(CONFIG_GCOV) += gmon_syms.o
20521 +obj-$(CONFIG_TTY_LOG) += tty_log.o
20522 +
20523 +subdir-$(CONFIG_MODE_TT) += tt
20524 +subdir-$(CONFIG_MODE_SKAS) += skas
20525 +
20526 +user-objs-$(CONFIG_TTY_LOG) += tty_log.o
20527 +
20528 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
20529 +
20530 +# user_syms.o not included here because Rules.make has its own ideas about
20531 +# building anything in export-objs
20532 +
20533 +USER_OBJS = $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
20534 +       process.o tempfile.o time.o umid.o user_util.o 
20535 +
20536 +DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__
20537 +DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__
20538 +
20539 +export-objs-$(CONFIG_GPROF) += gprof_syms.o
20540 +export-objs-$(CONFIG_GCOV) += gmon_syms.o
20541 +
20542 +export-objs = ksyms.o process_kern.o signal_kern.o user_syms.o $(export-objs-y)
20543 +
20544 +CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \
20545 +       -I/usr/include -I../include
20546 +
20547 +CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
20548 +
20549 +include $(TOPDIR)/Rules.make
20550 +
20551 +$(USER_OBJS) : %.o: %.c
20552 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
20553 +
20554 +# This has to be separate because it needs be compiled with frame pointers
20555 +# regardless of how the rest of the kernel is built.
20556 +
20557 +frame.o: frame.c
20558 +       $(CC) $(CFLAGS_$@) -c -o $@ $<
20559 +
20560 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
20561 +
20562 +config.c : config.c.in $(TOPDIR)/.config
20563 +       $(PERL) -e $(QUOTE) < config.c.in > $@
20564 +
20565 +clean:
20566 +       $(RM) config.c
20567 +       for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
20568 +
20569 +modules:
20570 +
20571 +fastdep:
20572 +
20573 +dep:
20574 +
20575 +archmrproper: clean
20576 diff -Naur -X ../exclude-files orig/arch/um/kernel/mem.c um/arch/um/kernel/mem.c
20577 --- orig/arch/um/kernel/mem.c   1969-12-31 19:00:00.000000000 -0500
20578 +++ um/arch/um/kernel/mem.c     2003-12-22 01:25:00.000000000 -0500
20579 @@ -0,0 +1,336 @@
20580 +/* 
20581 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
20582 + * Licensed under the GPL
20583 + */
20584 +
20585 +#include "linux/stddef.h"
20586 +#include "linux/kernel.h"
20587 +#include "linux/mm.h"
20588 +#include "linux/bootmem.h"
20589 +#include "linux/highmem.h"
20590 +#include "asm/page.h"
20591 +#include "asm/fixmap.h"
20592 +#include "asm/pgalloc.h"
20593 +#include "user_util.h"
20594 +#include "kern_util.h"
20595 +#include "kern.h"
20596 +#include "mem_user.h"
20597 +#include "uml_uaccess.h"
20598 +#include "os.h"
20599 +
20600 +extern char __binary_start;
20601 +
20602 +/* Changed during early boot */
20603 +unsigned long *empty_zero_page = NULL;
20604 +unsigned long *empty_bad_page = NULL;
20605 +pgd_t swapper_pg_dir[1024];
20606 +unsigned long highmem;
20607 +int kmalloc_ok = 0;
20608 +
20609 +static unsigned long brk_end;
20610 +static unsigned long totalram_pages = 0;
20611 +
20612 +void unmap_physmem(void)
20613 +{
20614 +       os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
20615 +}
20616 +
20617 +static void map_cb(void *unused)
20618 +{
20619 +       map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
20620 +}
20621 +
20622 +#ifdef CONFIG_HIGHMEM
20623 +static void setup_highmem(unsigned long highmem_start, 
20624 +                         unsigned long highmem_len)
20625 +{
20626 +       struct page *page;
20627 +       unsigned long highmem_pfn;
20628 +       int i;
20629 +
20630 +       highmem_start_page = virt_to_page(highmem_start);
20631 +
20632 +       highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT;
20633 +       for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
20634 +               page = &mem_map[highmem_pfn + i];
20635 +               ClearPageReserved(page);
20636 +               set_bit(PG_highmem, &page->flags);
20637 +               atomic_set(&page->count, 1);
20638 +               __free_page(page);
20639 +       }
20640 +}
20641 +#endif
20642 +
20643 +void mem_init(void)
20644 +{
20645 +       unsigned long start;
20646 +
20647 +        /* clear the zero-page */
20648 +        memset((void *) empty_zero_page, 0, PAGE_SIZE);
20649 +
20650 +       /* Map in the area just after the brk now that kmalloc is about
20651 +        * to be turned on.
20652 +        */
20653 +       brk_end = (unsigned long) UML_ROUND_UP(sbrk(0));
20654 +       map_cb(NULL);
20655 +       initial_thread_cb(map_cb, NULL);
20656 +       free_bootmem(__pa(brk_end), uml_reserved - brk_end);
20657 +       uml_reserved = brk_end;
20658 +
20659 +       /* Fill in any hole at the start of the binary */
20660 +       start = (unsigned long) &__binary_start;
20661 +       if(uml_physmem != start){
20662 +               map_memory(uml_physmem, __pa(uml_physmem), start - uml_physmem,
20663 +                          1, 1, 0);
20664 +       }
20665 +
20666 +       /* this will put all low memory onto the freelists */
20667 +       totalram_pages = free_all_bootmem();
20668 +       totalram_pages += highmem >> PAGE_SHIFT;
20669 +       num_physpages = totalram_pages;
20670 +       printk(KERN_INFO "Memory: %luk available\n", 
20671 +              (unsigned long) nr_free_pages() << (PAGE_SHIFT-10));
20672 +       kmalloc_ok = 1;
20673 +
20674 +#ifdef CONFIG_HIGHMEM
20675 +       setup_highmem(end_iomem, highmem);
20676 +#endif
20677 +}
20678 +
20679 +static void __init fixrange_init(unsigned long start, unsigned long end, 
20680 +                                pgd_t *pgd_base)
20681 +{
20682 +       pgd_t *pgd;
20683 +       pmd_t *pmd;
20684 +       pte_t *pte;
20685 +       int i, j;
20686 +       unsigned long vaddr;
20687 +
20688 +       vaddr = start;
20689 +       i = __pgd_offset(vaddr);
20690 +       j = __pmd_offset(vaddr);
20691 +       pgd = pgd_base + i;
20692 +
20693 +       for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
20694 +               pmd = (pmd_t *)pgd;
20695 +               for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
20696 +                       if (pmd_none(*pmd)) {
20697 +                               pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
20698 +                               set_pmd(pmd, __pmd(_KERNPG_TABLE + 
20699 +                                                  (unsigned long) __pa(pte)));
20700 +                               if (pte != pte_offset(pmd, 0))
20701 +                                       BUG();
20702 +                       }
20703 +                       vaddr += PMD_SIZE;
20704 +               }
20705 +               j = 0;
20706 +       }
20707 +}
20708 +
20709 +#ifdef CONFIG_HIGHMEM
20710 +pte_t *kmap_pte;
20711 +pgprot_t kmap_prot;
20712 +
20713 +#define kmap_get_fixmap_pte(vaddr)                                     \
20714 +       pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
20715 +
20716 +void __init kmap_init(void)
20717 +{
20718 +       unsigned long kmap_vstart;
20719 +
20720 +       /* cache the first kmap pte */
20721 +       kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
20722 +       kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
20723 +
20724 +       kmap_prot = PAGE_KERNEL;
20725 +}
20726 +
20727 +static void init_highmem(void)
20728 +{
20729 +       pgd_t *pgd;
20730 +       pmd_t *pmd;
20731 +       pte_t *pte;
20732 +       unsigned long vaddr;
20733 +
20734 +       /*
20735 +        * Permanent kmaps:
20736 +        */
20737 +       vaddr = PKMAP_BASE;
20738 +       fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, swapper_pg_dir);
20739 +
20740 +       pgd = swapper_pg_dir + __pgd_offset(vaddr);
20741 +       pmd = pmd_offset(pgd, vaddr);
20742 +       pte = pte_offset(pmd, vaddr);
20743 +       pkmap_page_table = pte;
20744 +
20745 +       kmap_init();
20746 +}
20747 +
20748 +#endif /* CONFIG_HIGHMEM */
20749 +
20750 +void paging_init(void)
20751 +{
20752 +       unsigned long zones_size[MAX_NR_ZONES], vaddr;
20753 +       int i;
20754 +
20755 +       empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
20756 +       empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
20757 +       for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++) 
20758 +               zones_size[i] = 0;
20759 +       zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
20760 +       zones_size[2] = highmem >> PAGE_SHIFT;
20761 +       free_area_init(zones_size);
20762 +
20763 +       /*
20764 +        * Fixed mappings, only the page table structure has to be
20765 +        * created - mappings will be set by set_fixmap():
20766 +        */
20767 +       vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
20768 +       fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir);
20769 +
20770 +#if CONFIG_HIGHMEM
20771 +       init_highmem();
20772 +#endif
20773 +}
20774 +
20775 +struct page *arch_validate(struct page *page, int mask, int order)
20776 +{
20777 +       unsigned long addr, zero = 0;
20778 +       int i;
20779 +
20780 + again:
20781 +       if(page == NULL) return(page);
20782 +       if(PageHighMem(page)) return(page);
20783 +
20784 +       addr = (unsigned long) page_address(page);
20785 +       for(i = 0; i < (1 << order); i++){
20786 +               current->thread.fault_addr = (void *) addr;
20787 +               if(__do_copy_to_user((void *) addr, &zero, 
20788 +                                    sizeof(zero),
20789 +                                    &current->thread.fault_addr,
20790 +                                    &current->thread.fault_catcher)){
20791 +                       if(!(mask & __GFP_WAIT)) return(NULL);
20792 +                       else break;
20793 +               }
20794 +               addr += PAGE_SIZE;
20795 +       }
20796 +       if(i == (1 << order)) return(page);
20797 +       page = _alloc_pages(mask, order);
20798 +       goto again;
20799 +}
20800 +
20801 +/* This can't do anything because nothing in the kernel image can be freed
20802 + * since it's not in kernel physical memory.
20803 + */
20804 +
20805 +void free_initmem(void)
20806 +{
20807 +}
20808 +
20809 +#ifdef CONFIG_BLK_DEV_INITRD
20810 +
20811 +void free_initrd_mem(unsigned long start, unsigned long end)
20812 +{
20813 +       if (start < end)
20814 +               printk ("Freeing initrd memory: %ldk freed\n", 
20815 +                       (end - start) >> 10);
20816 +       for (; start < end; start += PAGE_SIZE) {
20817 +               ClearPageReserved(virt_to_page(start));
20818 +               set_page_count(virt_to_page(start), 1);
20819 +               free_page(start);
20820 +               totalram_pages++;
20821 +       }
20822 +}
20823 +       
20824 +#endif
20825 +
20826 +int do_check_pgt_cache(int low, int high)
20827 +{
20828 +        int freed = 0;
20829 +        if(pgtable_cache_size > high) {
20830 +                do {
20831 +                        if (pgd_quicklist) {
20832 +                                free_pgd_slow(get_pgd_fast());
20833 +                                freed++;
20834 +                        }
20835 +                        if (pmd_quicklist) {
20836 +                                pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
20837 +                                freed++;
20838 +                        }
20839 +                        if (pte_quicklist) {
20840 +                                pte_free_slow(pte_alloc_one_fast(NULL, 0));
20841 +                                freed++;
20842 +                        }
20843 +                } while(pgtable_cache_size > low);
20844 +        }
20845 +        return freed;
20846 +}
20847 +
20848 +void show_mem(void)
20849 +{
20850 +        int i, total = 0, reserved = 0;
20851 +        int shared = 0, cached = 0;
20852 +        int highmem = 0;
20853 +
20854 +        printk("Mem-info:\n");
20855 +        show_free_areas();
20856 +        printk("Free swap:       %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
20857 +        i = max_mapnr;
20858 +        while(i-- > 0) {
20859 +                total++;
20860 +                if(PageHighMem(mem_map + i))
20861 +                        highmem++;
20862 +                if(PageReserved(mem_map + i))
20863 +                        reserved++;
20864 +                else if(PageSwapCache(mem_map + i))
20865 +                        cached++;
20866 +                else if(page_count(mem_map + i))
20867 +                        shared += page_count(mem_map + i) - 1;
20868 +        }
20869 +        printk("%d pages of RAM\n", total);
20870 +        printk("%d pages of HIGHMEM\n", highmem);
20871 +        printk("%d reserved pages\n", reserved);
20872 +        printk("%d pages shared\n", shared);
20873 +        printk("%d pages swap cached\n", cached);
20874 +        printk("%ld pages in page table cache\n", pgtable_cache_size);
20875 +        show_buffers();
20876 +}
20877 +
20878 +/* Changed by meminfo_compat, which is a setup */
20879 +static int meminfo_22 = 0;
20880 +
20881 +static int meminfo_compat(char *str)
20882 +{
20883 +       meminfo_22 = 1;
20884 +       return(1);
20885 +}
20886 +
20887 +__setup("22_meminfo", meminfo_compat);
20888 +
20889 +void si_meminfo(struct sysinfo *val)
20890 +{
20891 +       val->totalram = totalram_pages;
20892 +       val->sharedram = 0;
20893 +       val->freeram = nr_free_pages();
20894 +       val->bufferram = atomic_read(&buffermem_pages);
20895 +       val->totalhigh = highmem >> PAGE_SHIFT;
20896 +       val->freehigh = nr_free_highpages();
20897 +       val->mem_unit = PAGE_SIZE;
20898 +       if(meminfo_22){
20899 +               val->freeram <<= PAGE_SHIFT;
20900 +               val->bufferram <<= PAGE_SHIFT;
20901 +               val->totalram <<= PAGE_SHIFT;
20902 +               val->sharedram <<= PAGE_SHIFT;
20903 +       }
20904 +}
20905 +
20906 +/*
20907 + * Overrides for Emacs so that we follow Linus's tabbing style.
20908 + * Emacs will notice this stuff at the end of the file and automatically
20909 + * adjust the settings for this buffer only.  This must remain at the end
20910 + * of the file.
20911 + * ---------------------------------------------------------------------------
20912 + * Local variables:
20913 + * c-file-style: "linux"
20914 + * End:
20915 + */
20916 diff -Naur -X ../exclude-files orig/arch/um/kernel/mem_user.c um/arch/um/kernel/mem_user.c
20917 --- orig/arch/um/kernel/mem_user.c      1969-12-31 19:00:00.000000000 -0500
20918 +++ um/arch/um/kernel/mem_user.c        2004-01-10 00:19:09.000000000 -0500
20919 @@ -0,0 +1,216 @@
20920 +/*
20921 + * arch/um/kernel/mem_user.c
20922 + *
20923 + * BRIEF MODULE DESCRIPTION
20924 + * user side memory routines for supporting IO memory inside user mode linux
20925 + *
20926 + * Copyright (C) 2001 RidgeRun, Inc.
20927 + * Author: RidgeRun, Inc.
20928 + *         Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
20929 + *
20930 + *  This program is free software; you can redistribute  it and/or modify it
20931 + *  under  the terms of  the GNU General  Public License as published by the
20932 + *  Free Software Foundation;  either version 2 of the  License, or (at your
20933 + *  option) any later version.
20934 + *
20935 + *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
20936 + *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
20937 + *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
20938 + *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
20939 + *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20940 + *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
20941 + *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20942 + *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
20943 + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20944 + *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20945 + *
20946 + *  You should have received a copy of the  GNU General Public License along
20947 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
20948 + *  675 Mass Ave, Cambridge, MA 02139, USA.
20949 + */
20950 +
20951 +#include <stdio.h>
20952 +#include <stdlib.h>
20953 +#include <stddef.h>
20954 +#include <stdarg.h>
20955 +#include <unistd.h>
20956 +#include <errno.h>
20957 +#include <string.h>
20958 +#include <fcntl.h>
20959 +#include <sys/types.h>
20960 +#include <sys/mman.h>
20961 +#include "kern_util.h"
20962 +#include "user.h"
20963 +#include "user_util.h"
20964 +#include "mem_user.h"
20965 +#include "init.h"
20966 +#include "os.h"
20967 +#include "tempfile.h"
20968 +#include "kern_constants.h"
20969 +
20970 +extern struct mem_region physmem_region;
20971 +
20972 +#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
20973 +
20974 +static int create_tmp_file(unsigned long len)
20975 +{
20976 +       int fd, err;
20977 +       char zero;
20978 +
20979 +       fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
20980 +       if(fd < 0) {
20981 +               os_print_error(fd, "make_tempfile");
20982 +               exit(1);
20983 +       }
20984 +
20985 +       err = os_mode_fd(fd, 0777);
20986 +       if(err < 0){
20987 +               os_print_error(err, "os_mode_fd");
20988 +               exit(1);
20989 +       }
20990 +       err = os_seek_file(fd, len);
20991 +       if(err < 0){
20992 +               os_print_error(err, "os_seek_file");
20993 +               exit(1);
20994 +       }
20995 +       zero = 0;
20996 +       err = os_write_file(fd, &zero, 1);
20997 +       if(err != 1){
20998 +               os_print_error(err, "os_write_file");
20999 +               exit(1);
21000 +       }
21001 +
21002 +       return(fd);
21003 +}
21004 +
21005 +static int have_devanon(void)
21006 +{
21007 +       int fd;
21008 +
21009 +       printk("Checking for /dev/anon on the host...");
21010 +       fd = open("/dev/anon", O_RDWR);
21011 +       if(fd < 0){
21012 +               printk("Not available (open failed with errno %d)\n", errno);
21013 +               return(0);
21014 +       }
21015 +
21016 +       printk("OK\n");
21017 +       return(1);
21018 +}
21019 +
21020 +static int create_anon_file(unsigned long len)
21021 +{
21022 +       void *addr;
21023 +       int fd;
21024 +
21025 +       fd = open("/dev/anon", O_RDWR);
21026 +       if(fd < 0) {
21027 +               os_print_error(fd, "opening /dev/anon");
21028 +               exit(1);
21029 +       }
21030 +
21031 +       addr = mmap(NULL, len, PROT_READ | PROT_WRITE , MAP_PRIVATE, fd, 0);
21032 +       if(addr == MAP_FAILED){
21033 +               os_print_error((int) addr, "mapping physmem file");
21034 +               exit(1);
21035 +       }
21036 +       munmap(addr, len);
21037 +
21038 +       return(fd);
21039 +}
21040 +
21041 +int create_mem_file(unsigned long len)
21042 +{
21043 +       int err, fd;
21044 +
21045 +       if(have_devanon())
21046 +               fd = create_anon_file(len);
21047 +       else fd = create_tmp_file(len);
21048 +
21049 +       err = os_set_exec_close(fd, 1);
21050 +       if(err < 0)
21051 +               os_print_error(err, "exec_close");
21052 +       return(fd);
21053 +}
21054 +
21055 +struct iomem_region *iomem_regions = NULL;
21056 +int iomem_size = 0;
21057 +
21058 +static int __init parse_iomem(char *str, int *add)
21059 +{
21060 +       struct iomem_region *new;
21061 +       struct uml_stat buf;
21062 +       char *file, *driver;
21063 +       int fd, err;
21064 +
21065 +       driver = str;
21066 +       file = strchr(str,',');
21067 +       if(file == NULL){
21068 +               printf("parse_iomem : failed to parse iomem\n");
21069 +               goto out;
21070 +       }
21071 +       *file = '\0';
21072 +       file++;
21073 +       fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
21074 +       if(fd < 0){
21075 +               os_print_error(fd, "parse_iomem - Couldn't open io file");
21076 +               goto out;
21077 +       }
21078 +
21079 +       err = os_stat_fd(fd, &buf);
21080 +       if(err < 0){
21081 +               os_print_error(err, "parse_iomem - cannot stat_fd file");
21082 +               goto out_close;
21083 +       }
21084 +
21085 +       new = malloc(sizeof(*new));
21086 +       if(new == NULL){
21087 +               perror("Couldn't allocate iomem_region struct");
21088 +               goto out_close;
21089 +       }
21090 +
21091 +       *new = ((struct iomem_region) { .next           = iomem_regions,
21092 +                                       .driver         = driver,
21093 +                                       .fd             = fd,
21094 +                                       .size           = buf.ust_size,
21095 +                                       .phys           = 0,
21096 +                                       .virt           = 0 });
21097 +       iomem_regions = new;
21098 +       iomem_size += new->size + UM_KERN_PAGE_SIZE;
21099 +
21100 +       return(0);
21101 + out_close:
21102 +       os_close_file(fd);
21103 + out:
21104 +       return(1);
21105 +}
21106 +
21107 +__uml_setup("iomem=", parse_iomem,
21108 +"iomem=<name>,<file>\n"
21109 +"    Configure <file> as an IO memory region named <name>.\n\n"
21110 +);
21111 +
21112 +int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
21113 +                  int must_succeed)
21114 +{
21115 +       int err;
21116 +
21117 +       err = os_protect_memory((void *) addr, len, r, w, x);
21118 +       if(err < 0){
21119 +                if(must_succeed)
21120 +                        panic("protect failed, err = %d", -err);
21121 +                else return(err);
21122 +       }
21123 +       return(0);
21124 +}
21125 +
21126 +/*
21127 + * Overrides for Emacs so that we follow Linus's tabbing style.
21128 + * Emacs will notice this stuff at the end of the file and automatically
21129 + * adjust the settings for this buffer only.  This must remain at the end
21130 + * of the file.
21131 + * ---------------------------------------------------------------------------
21132 + * Local variables:
21133 + * c-file-style: "linux"
21134 + * End:
21135 + */
21136 diff -Naur -X ../exclude-files orig/arch/um/kernel/mprot.h um/arch/um/kernel/mprot.h
21137 --- orig/arch/um/kernel/mprot.h 1969-12-31 19:00:00.000000000 -0500
21138 +++ um/arch/um/kernel/mprot.h   2003-10-21 03:26:06.000000000 -0400
21139 @@ -0,0 +1,6 @@
21140 +#ifndef __MPROT_H__
21141 +#define __MPROT_H__
21142 +
21143 +extern void no_access(unsigned long addr, unsigned int len);
21144 +
21145 +#endif
21146 diff -Naur -X ../exclude-files orig/arch/um/kernel/physmem.c um/arch/um/kernel/physmem.c
21147 --- orig/arch/um/kernel/physmem.c       1969-12-31 19:00:00.000000000 -0500
21148 +++ um/arch/um/kernel/physmem.c 2004-01-16 23:38:02.000000000 -0500
21149 @@ -0,0 +1,446 @@
21150 +/* 
21151 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
21152 + * Licensed under the GPL
21153 + */
21154 +
21155 +#include "linux/mm.h"
21156 +#include "linux/ghash.h"
21157 +#include "linux/slab.h"
21158 +#include "linux/vmalloc.h"
21159 +#include "linux/bootmem.h"
21160 +#include "asm/types.h"
21161 +#include "asm/pgtable.h"
21162 +#include "kern_util.h"
21163 +#include "user_util.h"
21164 +#include "mode_kern.h"
21165 +#include "mem.h"
21166 +#include "mem_user.h"
21167 +#include "os.h"
21168 +#include "kern.h"
21169 +#include "init.h"
21170 +
21171 +#define PHYS_HASHSIZE (8192)
21172 +
21173 +struct phys_desc;
21174 +
21175 +DEF_HASH_STRUCTS(virtmem, PHYS_HASHSIZE, struct phys_desc);
21176 +
21177 +struct phys_desc {
21178 +       struct virtmem_ptrs virt_ptrs;
21179 +       int fd;
21180 +       __u64 offset;
21181 +       void *virt;
21182 +       unsigned long phys;
21183 +       struct list_head list;
21184 +};
21185 +
21186 +struct virtmem_table virtmem_hash;
21187 +
21188 +static int virt_cmp(void *virt1, void *virt2)
21189 +{
21190 +       return(virt1 != virt2);
21191 +}
21192 +
21193 +static int virt_hash(void *virt)
21194 +{
21195 +       unsigned long addr = ((unsigned long) virt) >> PAGE_SHIFT;
21196 +       return(addr % PHYS_HASHSIZE);
21197 +}
21198 +
21199 +DEF_HASH(static, virtmem, struct phys_desc, virt_ptrs, void *, virt, virt_cmp, 
21200 +        virt_hash);
21201 +
21202 +LIST_HEAD(descriptor_mappings);
21203 +
21204 +struct desc_mapping {
21205 +       int fd;
21206 +       struct list_head list;
21207 +       struct list_head pages;
21208 +};
21209 +
21210 +static struct desc_mapping *find_mapping(int fd)
21211 +{
21212 +       struct desc_mapping *desc;
21213 +       struct list_head *ele;
21214 +
21215 +       list_for_each(ele, &descriptor_mappings){
21216 +               desc = list_entry(ele, struct desc_mapping, list);
21217 +               if(desc->fd == fd)
21218 +                       return(desc);
21219 +       }
21220 +
21221 +       return(NULL);
21222 +}
21223 +
21224 +static struct desc_mapping *descriptor_mapping(int fd)
21225 +{
21226 +       struct desc_mapping *desc;
21227 +
21228 +       desc = find_mapping(fd);
21229 +       if(desc != NULL)
21230 +               return(desc);
21231 +
21232 +       desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
21233 +       if(desc == NULL)
21234 +               return(NULL);
21235 +
21236 +       *desc = ((struct desc_mapping) 
21237 +               { .fd =         fd,
21238 +                 .list =       LIST_HEAD_INIT(desc->list),
21239 +                 .pages =      LIST_HEAD_INIT(desc->pages) });
21240 +       list_add(&desc->list, &descriptor_mappings);
21241 +
21242 +       return(desc);
21243 +}
21244 +
21245 +int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
21246 +{
21247 +       struct desc_mapping *fd_maps;
21248 +       struct phys_desc *desc;
21249 +       unsigned long phys;
21250 +       int err;
21251 +
21252 +       fd_maps = descriptor_mapping(fd);
21253 +       if(fd_maps == NULL)
21254 +               return(-ENOMEM);
21255 +
21256 +       phys = __pa(virt);
21257 +       if(find_virtmem_hash(&virtmem_hash, virt) != NULL)
21258 +               panic("Address 0x%p is already substituted\n", virt);
21259 +
21260 +       err = -ENOMEM;
21261 +       desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
21262 +       if(desc == NULL)
21263 +               goto out;
21264 +
21265 +       *desc = ((struct phys_desc) 
21266 +               { .virt_ptrs =  { NULL, NULL },
21267 +                 .fd =         fd,
21268 +                 .offset =             offset,
21269 +                 .virt =               virt,
21270 +                 .phys =               __pa(virt),
21271 +                 .list =               LIST_HEAD_INIT(desc->list) });
21272 +       insert_virtmem_hash(&virtmem_hash, desc);
21273 +
21274 +       list_add(&desc->list, &fd_maps->pages);
21275 +
21276 +       virt = (void *) ((unsigned long) virt & PAGE_MASK);
21277 +       err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
21278 +       if(!err)
21279 +               goto out;
21280 +
21281 +       remove_virtmem_hash(&virtmem_hash, desc);
21282 +       kfree(desc);
21283 + out:
21284 +       return(err);
21285 +}
21286 +
21287 +static int physmem_fd = -1;
21288 +
21289 +static void remove_mapping(struct phys_desc *desc)
21290 +{
21291 +       void *virt = desc->virt;
21292 +       int err;
21293 +
21294 +       remove_virtmem_hash(&virtmem_hash, desc);
21295 +       list_del(&desc->list);
21296 +       kfree(desc);
21297 +
21298 +       err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
21299 +       if(err)
21300 +               panic("Failed to unmap block device page from physical memory, "
21301 +                     "errno = %d", -err);
21302 +}
21303 +
21304 +int physmem_remove_mapping(void *virt)
21305 +{
21306 +       struct phys_desc *desc;
21307 +
21308 +       virt = (void *) ((unsigned long) virt & PAGE_MASK);
21309 +       desc = find_virtmem_hash(&virtmem_hash, virt);
21310 +       if(desc == NULL)
21311 +               return(0);
21312 +
21313 +       remove_mapping(desc);
21314 +       return(1);
21315 +}
21316 +
21317 +void physmem_forget_descriptor(int fd)
21318 +{
21319 +       struct desc_mapping *desc;
21320 +       struct phys_desc *page;
21321 +       struct list_head *ele, *next;
21322 +       __u64 offset;
21323 +       void *addr;
21324 +       int err;
21325 +
21326 +       desc = find_mapping(fd);
21327 +       if(desc == NULL)
21328 +               return;
21329 +
21330 +       list_for_each_safe(ele, next, &desc->pages){
21331 +               page = list_entry(ele, struct phys_desc, list);
21332 +               offset = page->offset;
21333 +               addr = page->virt;
21334 +               remove_mapping(page);
21335 +               err = os_seek_file(fd, offset);
21336 +               if(err)
21337 +                       panic("physmem_forget_descriptor - failed to seek "
21338 +                             "to %lld in fd %d, error = %d\n",
21339 +                             offset, fd, -err);
21340 +               err = os_read_file(fd, addr, PAGE_SIZE);
21341 +               if(err < 0)
21342 +                       panic("physmem_forget_descriptor - failed to read "
21343 +                             "from fd %d to 0x%p, error = %d\n",
21344 +                             fd, addr, -err);
21345 +       }
21346 +
21347 +       list_del(&desc->list);
21348 +       kfree(desc);
21349 +}
21350 +
21351 +void arch_free_page(struct page *page, int order)
21352 +{
21353 +       void *virt;
21354 +       int i;
21355 +
21356 +       for(i = 0; i < (1 << order); i++){
21357 +               virt = __va(page_to_phys(page + i));
21358 +               physmem_remove_mapping(virt);
21359 +       }
21360 +}
21361 +
21362 +int is_remapped(void *virt)
21363 +{
21364 +       return(find_virtmem_hash(&virtmem_hash, virt) != NULL);
21365 +}
21366 +
21367 +/* Changed during early boot */
21368 +unsigned long high_physmem;
21369 +
21370 +extern unsigned long physmem_size;
21371 +
21372 +void *to_virt(unsigned long phys)
21373 +{
21374 +       return((void *) uml_physmem + phys);
21375 +}
21376 +
21377 +unsigned long to_phys(void *virt)
21378 +{
21379 +       return(((unsigned long) virt) - uml_physmem);
21380 +}
21381 +
21382 +int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
21383 +{
21384 +       struct page *p, *map;
21385 +       unsigned long phys_len, phys_pages, highmem_len, highmem_pages;
21386 +       unsigned long iomem_len, iomem_pages, total_len, total_pages;
21387 +       int i;
21388 +
21389 +       phys_pages = physmem >> PAGE_SHIFT;
21390 +       phys_len = phys_pages * sizeof(struct page);
21391 +
21392 +       iomem_pages = iomem >> PAGE_SHIFT;
21393 +       iomem_len = iomem_pages * sizeof(struct page);
21394 +
21395 +       highmem_pages = highmem >> PAGE_SHIFT;
21396 +       highmem_len = highmem_pages * sizeof(struct page);
21397 +
21398 +       total_pages = phys_pages + iomem_pages + highmem_pages;
21399 +       total_len = phys_len + iomem_pages + highmem_len;
21400 +
21401 +       if(kmalloc_ok){
21402 +               map = kmalloc(total_len, GFP_KERNEL);
21403 +               if(map == NULL) 
21404 +                       map = vmalloc(total_len);
21405 +       }
21406 +       else map = alloc_bootmem_low_pages(total_len);
21407 +
21408 +       if(map == NULL)
21409 +               return(-ENOMEM);
21410 +
21411 +       for(i = 0; i < total_pages; i++){
21412 +               p = &map[i];
21413 +               set_page_count(p, 0);
21414 +               SetPageReserved(p);
21415 +               INIT_LIST_HEAD(&p->list);
21416 +       }
21417 +
21418 +       mem_map = map;
21419 +       max_mapnr = total_pages;
21420 +       return(0);
21421 +}
21422 +
21423 +struct page *phys_to_page(const unsigned long phys)
21424 +{
21425 +       return(&mem_map[phys >> PAGE_SHIFT]);
21426 +}
21427 +
21428 +struct page *__virt_to_page(const unsigned long virt)
21429 +{
21430 +       return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
21431 +}
21432 +
21433 +unsigned long page_to_phys(struct page *page)
21434 +{
21435 +       return((page - mem_map) << PAGE_SHIFT);
21436 +}
21437 +
21438 +pte_t mk_pte(struct page *page, pgprot_t pgprot)
21439 +{
21440 +       pte_t pte;
21441 +
21442 +       pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot);
21443 +       if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte));
21444 +       return(pte);
21445 +}
21446 +
21447 +/* Changed during early boot */
21448 +static unsigned long kmem_top = 0;
21449 +
21450 +unsigned long get_kmem_end(void)
21451 +{
21452 +       if(kmem_top == 0) 
21453 +               kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
21454 +       return(kmem_top);
21455 +}
21456 +
21457 +void map_memory(unsigned long virt, unsigned long phys, unsigned long len, 
21458 +               int r, int w, int x)
21459 +{
21460 +       __u64 offset;
21461 +       int fd, err;
21462 +
21463 +       fd = phys_mapping(phys, &offset);
21464 +       err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
21465 +       if(err)
21466 +               panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, "
21467 +                     "err = %d\n", virt, fd, offset, len, r, w, x, err);
21468 +}
21469 +
21470 +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
21471 +
21472 +void setup_physmem(unsigned long start, unsigned long reserve_end,
21473 +                  unsigned long len, unsigned long highmem)
21474 +{
21475 +       unsigned long reserve = reserve_end - start;
21476 +       int pfn = PFN_UP(__pa(reserve_end));
21477 +       int delta = (len - reserve) >> PAGE_SHIFT;
21478 +       int err, offset, bootmap_size;
21479 +
21480 +       physmem_fd = create_mem_file(len + highmem);
21481 +
21482 +       offset = uml_reserved - uml_physmem;
21483 +       err = os_map_memory((void *) uml_reserved, physmem_fd, offset, 
21484 +                           len - offset, 1, 1, 0);
21485 +       if(err < 0){
21486 +               os_print_error(err, "Mapping memory");
21487 +               exit(1);
21488 +       }
21489 +
21490 +       bootmap_size = init_bootmem(pfn, pfn + delta);
21491 +       free_bootmem(__pa(reserve_end) + bootmap_size,
21492 +                    len - bootmap_size - reserve);
21493 +}
21494 +
21495 +int phys_mapping(unsigned long phys, __u64 *offset_out)
21496 +{
21497 +       struct phys_desc *desc = find_virtmem_hash(&virtmem_hash, 
21498 +                                                  __va(phys & PAGE_MASK));
21499 +       int fd = -1;
21500 +
21501 +       if(desc != NULL){
21502 +               fd = desc->fd;
21503 +               *offset_out = desc->offset;
21504 +       }
21505 +       else if(phys < physmem_size){
21506 +               fd = physmem_fd;
21507 +               *offset_out = phys;
21508 +       }
21509 +       else if(phys < __pa(end_iomem)){
21510 +               struct iomem_region *region = iomem_regions;
21511 +       
21512 +               while(region != NULL){
21513 +                       if((phys >= region->phys) && 
21514 +                          (phys < region->phys + region->size)){
21515 +                               fd = region->fd;
21516 +                               *offset_out = phys - region->phys;
21517 +                               break;
21518 +                       }
21519 +                       region = region->next;
21520 +               }
21521 +       }
21522 +       else if(phys < __pa(end_iomem) + highmem){
21523 +               fd = physmem_fd;
21524 +               *offset_out = phys - iomem_size;
21525 +       }
21526 +
21527 +       return(fd);
21528 +}
21529 +
21530 +static int __init uml_mem_setup(char *line, int *add)
21531 +{
21532 +       char *retptr;
21533 +       physmem_size = memparse(line,&retptr);
21534 +       return 0;
21535 +}
21536 +__uml_setup("mem=", uml_mem_setup,
21537 +"mem=<Amount of desired ram>\n"
21538 +"    This controls how much \"physical\" memory the kernel allocates\n"
21539 +"    for the system. The size is specified as a number followed by\n"
21540 +"    one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
21541 +"    This is not related to the amount of memory in the host.  It can\n"
21542 +"    be more, and the excess, if it's ever used, will just be swapped out.\n"
21543 +"      Example: mem=64M\n\n"
21544 +);
21545 +
21546 +unsigned long find_iomem(char *driver, unsigned long *len_out)
21547 +{
21548 +       struct iomem_region *region = iomem_regions;
21549 +       
21550 +       while(region != NULL){
21551 +               if(!strcmp(region->driver, driver)){
21552 +                       *len_out = region->size;
21553 +                       return(region->virt);
21554 +               }
21555 +       }
21556 +
21557 +       return(0);
21558 +}
21559 +
21560 +int setup_iomem(void)
21561 +{
21562 +       struct iomem_region *region = iomem_regions;
21563 +       unsigned long iomem_start = high_physmem + PAGE_SIZE;
21564 +       int err;
21565 +
21566 +       while(region != NULL){
21567 +               err = os_map_memory((void *) iomem_start, region->fd, 0, 
21568 +                                   region->size, 1, 1, 0);
21569 +               if(err)
21570 +                       printk("Mapping iomem region for driver '%s' failed, "
21571 +                              "errno = %d\n", region->driver, -err);
21572 +               else {
21573 +                       region->virt = iomem_start;
21574 +                       region->phys = __pa(region->virt);
21575 +               }
21576 +
21577 +               iomem_start += region->size + PAGE_SIZE;
21578 +               region = region->next;
21579 +       }
21580 +
21581 +       return(0);
21582 +}
21583 +
21584 +__initcall(setup_iomem);
21585 +
21586 +/*
21587 + * Overrides for Emacs so that we follow Linus's tabbing style.
21588 + * Emacs will notice this stuff at the end of the file and automatically
21589 + * adjust the settings for this buffer only.  This must remain at the end
21590 + * of the file.
21591 + * ---------------------------------------------------------------------------
21592 + * Local variables:
21593 + * c-file-style: "linux"
21594 + * End:
21595 + */
21596 diff -Naur -X ../exclude-files orig/arch/um/kernel/process.c um/arch/um/kernel/process.c
21597 --- orig/arch/um/kernel/process.c       1969-12-31 19:00:00.000000000 -0500
21598 +++ um/arch/um/kernel/process.c 2004-01-31 02:47:57.000000000 -0500
21599 @@ -0,0 +1,289 @@
21600 +/* 
21601 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
21602 + * Licensed under the GPL
21603 + */
21604 +
21605 +#include <stdio.h>
21606 +#include <unistd.h>
21607 +#include <signal.h>
21608 +#include <sched.h>
21609 +#include <errno.h>
21610 +#include <stdarg.h>
21611 +#include <stdlib.h>
21612 +#include <setjmp.h>
21613 +#include <sys/time.h>
21614 +#include <sys/ptrace.h>
21615 +#include <sys/wait.h>
21616 +#include <sys/mman.h>
21617 +#include <asm/ptrace.h>
21618 +#include <asm/sigcontext.h>
21619 +#include <asm/unistd.h>
21620 +#include <asm/page.h>
21621 +#include "user_util.h"
21622 +#include "kern_util.h"
21623 +#include "user.h"
21624 +#include "process.h"
21625 +#include "signal_kern.h"
21626 +#include "signal_user.h"
21627 +#include "sysdep/ptrace.h"
21628 +#include "sysdep/sigcontext.h"
21629 +#include "irq_user.h"
21630 +#include "ptrace_user.h"
21631 +#include "time_user.h"
21632 +#include "init.h"
21633 +#include "os.h"
21634 +#include "uml-config.h"
21635 +#include "choose-mode.h"
21636 +#include "mode.h"
21637 +#ifdef UML_CONFIG_MODE_SKAS
21638 +#include "skas.h"
21639 +#include "skas_ptrace.h"
21640 +#endif
21641 +
21642 +void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
21643 +{
21644 +       int flags = 0, pages;
21645 +
21646 +       if(sig_stack != NULL){
21647 +               pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
21648 +               set_sigstack(sig_stack, pages * page_size());
21649 +               flags = SA_ONSTACK;
21650 +       }
21651 +       if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
21652 +}
21653 +
21654 +void init_new_thread_signals(int altstack)
21655 +{
21656 +       int flags = altstack ? SA_ONSTACK : 0;
21657 +
21658 +       /* NODEFER is set here because SEGV isn't turned back on when the 
21659 +        * handler is ready to receive signals.  This causes any segfault
21660 +        * during a copy_user to kill the process because the fault is blocked.
21661 +        */
21662 +       set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags | SA_NODEFER,
21663 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21664 +       set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags, 
21665 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21666 +       set_handler(SIGFPE, (__sighandler_t) sig_handler, flags, 
21667 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21668 +       set_handler(SIGILL, (__sighandler_t) sig_handler, flags, 
21669 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21670 +       set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, 
21671 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21672 +       set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags, 
21673 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21674 +       set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
21675 +                   SA_NOMASK | flags, -1);
21676 +       signal(SIGHUP, SIG_IGN);
21677 +
21678 +       init_irq_signals(altstack);
21679 +}
21680 +
21681 +struct tramp {
21682 +       int (*tramp)(void *);
21683 +       void *tramp_data;
21684 +       unsigned long temp_stack;
21685 +       int flags;
21686 +       int pid;
21687 +};
21688 +
21689 +/* See above for why sigkill is here */
21690 +
21691 +int sigkill = SIGKILL;
21692 +
21693 +int outer_tramp(void *arg)
21694 +{
21695 +       struct tramp *t;
21696 +       int sig = sigkill;
21697 +
21698 +       t = arg;
21699 +       t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2,
21700 +                      t->flags, t->tramp_data);
21701 +       if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
21702 +       kill(os_getpid(), sig);
21703 +       _exit(0);
21704 +}
21705 +
21706 +int start_fork_tramp(void *thread_arg, unsigned long temp_stack, 
21707 +                    int clone_flags, int (*tramp)(void *))
21708 +{
21709 +       struct tramp arg;
21710 +       unsigned long sp;
21711 +       int new_pid, status, err;
21712 +
21713 +       /* The trampoline will run on the temporary stack */
21714 +       sp = stack_sp(temp_stack);
21715 +
21716 +       clone_flags |= CLONE_FILES | SIGCHLD;
21717 +
21718 +       arg.tramp = tramp;
21719 +       arg.tramp_data = thread_arg;
21720 +       arg.temp_stack = temp_stack;
21721 +       arg.flags = clone_flags;
21722 +
21723 +       /* Start the process and wait for it to kill itself */
21724 +       new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
21725 +       if(new_pid < 0) return(-errno);
21726 +       while(((err = waitpid(new_pid, &status, 0)) < 0) && (errno == EINTR)) ;
21727 +       if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", 
21728 +                         errno);
21729 +       if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
21730 +               panic("outer trampoline didn't exit with SIGKILL, "
21731 +                     "status = %d", status);
21732 +
21733 +       return(arg.pid);
21734 +}
21735 +
21736 +void suspend_new_thread(int fd)
21737 +{
21738 +       char c;
21739 +
21740 +       os_stop_process(os_getpid());
21741 +
21742 +       if(os_read_file(fd, &c, sizeof(c)) != sizeof(c))
21743 +               panic("read failed in suspend_new_thread");
21744 +}
21745 +
21746 +static int ptrace_child(void *arg)
21747 +{
21748 +       int pid = os_getpid();
21749 +
21750 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
21751 +               perror("ptrace");
21752 +               os_kill_process(pid, 0);
21753 +       }
21754 +       os_stop_process(pid);
21755 +       _exit(os_getpid() == pid);
21756 +}
21757 +
21758 +static int start_ptraced_child(void **stack_out)
21759 +{
21760 +       void *stack;
21761 +       unsigned long sp;
21762 +       int pid, n, status;
21763 +       
21764 +       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
21765 +                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
21766 +       if(stack == MAP_FAILED)
21767 +               panic("check_ptrace : mmap failed, errno = %d", errno);
21768 +       sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
21769 +       pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
21770 +       if(pid < 0)
21771 +               panic("check_ptrace : clone failed, errno = %d", errno);
21772 +       n = waitpid(pid, &status, WUNTRACED);
21773 +       if(n < 0)
21774 +               panic("check_ptrace : wait failed, errno = %d", errno);
21775 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
21776 +               panic("check_ptrace : expected SIGSTOP, got status = %d",
21777 +                     status);
21778 +
21779 +       *stack_out = stack;
21780 +       return(pid);
21781 +}
21782 +
21783 +static void stop_ptraced_child(int pid, void *stack, int exitcode)
21784 +{
21785 +       int status, n;
21786 +
21787 +       if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
21788 +               panic("check_ptrace : ptrace failed, errno = %d", errno);
21789 +       n = waitpid(pid, &status, 0);
21790 +       if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode))
21791 +               panic("check_ptrace : child exited with status 0x%x", status);
21792 +
21793 +       if(munmap(stack, PAGE_SIZE) < 0)
21794 +               panic("check_ptrace : munmap failed, errno = %d", errno);
21795 +}
21796 +
21797 +void __init check_ptrace(void)
21798 +{
21799 +       void *stack;
21800 +       int pid, syscall, n, status;
21801 +
21802 +       printk("Checking that ptrace can change system call numbers...");
21803 +       pid = start_ptraced_child(&stack);
21804 +
21805 +       while(1){
21806 +               if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
21807 +                       panic("check_ptrace : ptrace failed, errno = %d", 
21808 +                             errno);
21809 +               n = waitpid(pid, &status, WUNTRACED);
21810 +               if(n < 0)
21811 +                       panic("check_ptrace : wait failed, errno = %d", errno);
21812 +               if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
21813 +                       panic("check_ptrace : expected SIGTRAP, "
21814 +                             "got status = %d", status);
21815 +               
21816 +               syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET,
21817 +                                0);
21818 +               if(syscall == __NR_getpid){
21819 +                       n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
21820 +                                  __NR_getppid);
21821 +                       if(n < 0)
21822 +                               panic("check_ptrace : failed to modify system "
21823 +                                     "call, errno = %d", errno);
21824 +                       break;
21825 +               }
21826 +       }
21827 +       stop_ptraced_child(pid, stack, 0);
21828 +       printk("OK\n");
21829 +}
21830 +
21831 +int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
21832 +{
21833 +       sigjmp_buf buf;
21834 +       int n;
21835 +
21836 +       *jmp_ptr = &buf;
21837 +       n = sigsetjmp(buf, 1);
21838 +       if(n != 0)
21839 +               return(n);
21840 +       (*fn)(arg);
21841 +       return(0);
21842 +}
21843 +
21844 +int can_do_skas(void)
21845 +{
21846 +#ifdef UML_CONFIG_MODE_SKAS
21847 +       struct ptrace_faultinfo fi;
21848 +       void *stack;
21849 +       int pid, n, ret = 1;
21850 +
21851 +       printf("Checking for the skas3 patch in the host...");
21852 +       pid = start_ptraced_child(&stack);
21853 +
21854 +       n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
21855 +       if(n < 0){
21856 +               if(errno == EIO)
21857 +                       printf("not found\n");
21858 +               else printf("No (unexpected errno - %d)\n", errno);
21859 +               ret = 0;
21860 +       }
21861 +       else printf("found\n");
21862 +
21863 +       init_registers(pid);
21864 +       stop_ptraced_child(pid, stack, 1);
21865 +
21866 +       printf("Checking for /proc/mm...");
21867 +       if(os_access("/proc/mm", OS_ACC_W_OK) < 0){
21868 +               printf("not found\n");
21869 +               ret = 0;
21870 +       }
21871 +       else printf("found\n");
21872 +
21873 +       return(ret);
21874 +#else
21875 +       return(0);
21876 +#endif
21877 +}
21878 +
21879 +/*
21880 + * Overrides for Emacs so that we follow Linus's tabbing style.
21881 + * Emacs will notice this stuff at the end of the file and automatically
21882 + * adjust the settings for this buffer only.  This must remain at the end
21883 + * of the file.
21884 + * ---------------------------------------------------------------------------
21885 + * Local variables:
21886 + * c-file-style: "linux"
21887 + * End:
21888 + */
21889 diff -Naur -X ../exclude-files orig/arch/um/kernel/process_kern.c um/arch/um/kernel/process_kern.c
21890 --- orig/arch/um/kernel/process_kern.c  1969-12-31 19:00:00.000000000 -0500
21891 +++ um/arch/um/kernel/process_kern.c    2003-11-08 08:37:04.000000000 -0500
21892 @@ -0,0 +1,396 @@
21893 +/* 
21894 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
21895 + * Licensed under the GPL
21896 + */
21897 +
21898 +#include "linux/config.h"
21899 +#include "linux/kernel.h"
21900 +#include "linux/sched.h"
21901 +#include "linux/interrupt.h"
21902 +#include "linux/mm.h"
21903 +#include "linux/slab.h"
21904 +#include "linux/utsname.h"
21905 +#include "linux/fs.h"
21906 +#include "linux/utime.h"
21907 +#include "linux/smp_lock.h"
21908 +#include "linux/module.h"
21909 +#include "linux/init.h"
21910 +#include "linux/capability.h"
21911 +#include "asm/unistd.h"
21912 +#include "asm/mman.h"
21913 +#include "asm/segment.h"
21914 +#include "asm/stat.h"
21915 +#include "asm/pgtable.h"
21916 +#include "asm/processor.h"
21917 +#include "asm/pgalloc.h"
21918 +#include "asm/spinlock.h"
21919 +#include "asm/uaccess.h"
21920 +#include "asm/user.h"
21921 +#include "user_util.h"
21922 +#include "kern_util.h"
21923 +#include "kern.h"
21924 +#include "signal_kern.h"
21925 +#include "signal_user.h"
21926 +#include "init.h"
21927 +#include "irq_user.h"
21928 +#include "mem_user.h"
21929 +#include "time_user.h"
21930 +#include "tlb.h"
21931 +#include "frame_kern.h"
21932 +#include "sigcontext.h"
21933 +#include "2_5compat.h"
21934 +#include "os.h"
21935 +#include "mode.h"
21936 +#include "mode_kern.h"
21937 +#include "choose-mode.h"
21938 +
21939 +/* This is a per-cpu array.  A processor only modifies its entry and it only
21940 + * cares about its entry, so it's OK if another processor is modifying its
21941 + * entry.
21942 + */
21943 +struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
21944 +
21945 +struct task_struct *get_task(int pid, int require)
21946 +{
21947 +        struct task_struct *ret;
21948 +
21949 +        read_lock(&tasklist_lock);
21950 +       ret = find_task_by_pid(pid);
21951 +        read_unlock(&tasklist_lock);
21952 +
21953 +        if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
21954 +        return(ret);
21955 +}
21956 +
21957 +int external_pid(void *t)
21958 +{
21959 +       struct task_struct *task = t ? t : current;
21960 +
21961 +       return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
21962 +}
21963 +
21964 +int pid_to_processor_id(int pid)
21965 +{
21966 +       int i;
21967 +
21968 +       for(i = 0; i < smp_num_cpus; i++){
21969 +               if(cpu_tasks[i].pid == pid) return(i);
21970 +       }
21971 +       return(-1);
21972 +}
21973 +
21974 +void free_stack(unsigned long stack, int order)
21975 +{
21976 +       free_pages(stack, order);
21977 +}
21978 +
21979 +unsigned long alloc_stack(int order, int atomic)
21980 +{
21981 +       unsigned long page;
21982 +       int flags = GFP_KERNEL;
21983 +
21984 +       if(atomic) flags |= GFP_ATOMIC;
21985 +       page = __get_free_pages(flags, order);
21986 +       if(page == 0)
21987 +               return(0);
21988 +       stack_protections(page);
21989 +       return(page);
21990 +}
21991 +
21992 +int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
21993 +{
21994 +       int pid;
21995 +
21996 +       current->thread.request.u.thread.proc = fn;
21997 +       current->thread.request.u.thread.arg = arg;
21998 +       pid = do_fork(CLONE_VM | flags, 0, NULL, 0);
21999 +#if 0 /* CLONE_UNTRACED for 2.6 */
22000 +       pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0);
22001 +#endif
22002 +       if(pid < 0) 
22003 +               panic("do_fork failed in kernel_thread, errno = %d", pid);
22004 +       return(pid);
22005 +}
22006 +
22007 +void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
22008 +              struct task_struct *tsk, unsigned cpu)
22009 +{
22010 +       if (prev != next) 
22011 +               clear_bit(cpu, &prev->cpu_vm_mask);
22012 +       set_bit(cpu, &next->cpu_vm_mask);
22013 +}
22014 +
22015 +void set_current(void *t)
22016 +{
22017 +       struct task_struct *task = t;
22018 +
22019 +       cpu_tasks[task->processor] = ((struct cpu_task) 
22020 +               { external_pid(task), task });
22021 +}
22022 +
22023 +void *_switch_to(void *prev, void *next)
22024 +{
22025 +       return(CHOOSE_MODE(_switch_to_tt(prev, next), 
22026 +                          _switch_to_skas(prev, next)));
22027 +}
22028 +
22029 +void interrupt_end(void)
22030 +{
22031 +       if(current->need_resched) schedule();
22032 +       if(current->sigpending != 0) do_signal(0);
22033 +}
22034 +
22035 +void release_thread(struct task_struct *task)
22036 +{
22037 +       CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
22038 +}
22039 +
22040 +void exit_thread(void)
22041 +{
22042 +       CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
22043 +       unprotect_stack((unsigned long) current);
22044 +}
22045 +
22046 +void *get_current(void)
22047 +{
22048 +       return(current);
22049 +}
22050 +
22051 +int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
22052 +               unsigned long stack_top, struct task_struct * p, 
22053 +               struct pt_regs *regs)
22054 +{
22055 +       p->thread = (struct thread_struct) INIT_THREAD;
22056 +       p->thread.kernel_stack = (unsigned long) p + 2 * PAGE_SIZE;
22057 +
22058 +       return(CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr, 
22059 +                               clone_flags, sp, stack_top, p, regs));
22060 +}
22061 +
22062 +void initial_thread_cb(void (*proc)(void *), void *arg)
22063 +{
22064 +       int save_kmalloc_ok = kmalloc_ok;
22065 +
22066 +       kmalloc_ok = 0;
22067 +       CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc, 
22068 +                        arg);
22069 +       kmalloc_ok = save_kmalloc_ok;
22070 +}
22071 +
22072 +unsigned long stack_sp(unsigned long page)
22073 +{
22074 +       return(page + PAGE_SIZE - sizeof(void *));
22075 +}
22076 +
22077 +int current_pid(void)
22078 +{
22079 +       return(current->pid);
22080 +}
22081 +
22082 +void cpu_idle(void)
22083 +{
22084 +       CHOOSE_MODE(init_idle_tt(), init_idle_skas());
22085 +
22086 +       atomic_inc(&init_mm.mm_count);
22087 +       current->mm = &init_mm;
22088 +       current->active_mm = &init_mm;
22089 +
22090 +       while(1){
22091 +               /* endless idle loop with no priority at all */
22092 +               SET_PRI(current);
22093 +
22094 +               /*
22095 +                * although we are an idle CPU, we do not want to
22096 +                * get into the scheduler unnecessarily.
22097 +                */
22098 +               if (current->need_resched) {
22099 +                       schedule();
22100 +                       check_pgt_cache();
22101 +               }
22102 +               idle_sleep(10);
22103 +       }
22104 +}
22105 +
22106 +int page_size(void)
22107 +{
22108 +       return(PAGE_SIZE);
22109 +}
22110 +
22111 +int page_mask(void)
22112 +{
22113 +       return(PAGE_MASK);
22114 +}
22115 +
22116 +void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 
22117 +                     pte_t *pte_out)
22118 +{
22119 +       pgd_t *pgd;
22120 +       pmd_t *pmd;
22121 +       pte_t *pte;
22122 +
22123 +       if(task->mm == NULL) 
22124 +               return(ERR_PTR(-EINVAL));
22125 +       pgd = pgd_offset(task->mm, addr);
22126 +       pmd = pmd_offset(pgd, addr);
22127 +       if(!pmd_present(*pmd)) 
22128 +               return(ERR_PTR(-EINVAL));
22129 +       pte = pte_offset(pmd, addr);
22130 +       if(!pte_present(*pte)) 
22131 +               return(ERR_PTR(-EINVAL));
22132 +       if(pte_out != NULL)
22133 +               *pte_out = *pte;
22134 +       return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK));
22135 +}
22136 +
22137 +char *current_cmd(void)
22138 +{
22139 +#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
22140 +       return("(Unknown)");
22141 +#else
22142 +       void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
22143 +       return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
22144 +#endif
22145 +}
22146 +
22147 +void force_sigbus(void)
22148 +{
22149 +       printk(KERN_ERR "Killing pid %d because of a lack of memory\n", 
22150 +              current->pid);
22151 +       lock_kernel();
22152 +       sigaddset(&current->pending.signal, SIGBUS);
22153 +       recalc_sigpending(current);
22154 +       current->flags |= PF_SIGNALED;
22155 +       do_exit(SIGBUS | 0x80);
22156 +}
22157 +
22158 +void dump_thread(struct pt_regs *regs, struct user *u)
22159 +{
22160 +}
22161 +
22162 +void enable_hlt(void)
22163 +{
22164 +       panic("enable_hlt");
22165 +}
22166 +
22167 +void disable_hlt(void)
22168 +{
22169 +       panic("disable_hlt");
22170 +}
22171 +
22172 +extern int signal_frame_size;
22173 +
22174 +void *um_kmalloc(int size)
22175 +{
22176 +       return(kmalloc(size, GFP_KERNEL));
22177 +}
22178 +
22179 +void *um_kmalloc_atomic(int size)
22180 +{
22181 +       return(kmalloc(size, GFP_ATOMIC));
22182 +}
22183 +
22184 +unsigned long get_fault_addr(void)
22185 +{
22186 +       return((unsigned long) current->thread.fault_addr);
22187 +}
22188 +
22189 +EXPORT_SYMBOL(get_fault_addr);
22190 +
22191 +void not_implemented(void)
22192 +{
22193 +       printk(KERN_DEBUG "Something isn't implemented in here\n");
22194 +}
22195 +
22196 +EXPORT_SYMBOL(not_implemented);
22197 +
22198 +int user_context(unsigned long sp)
22199 +{
22200 +       unsigned long stack;
22201 +
22202 +       stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
22203 +       stack += 2 * PAGE_SIZE;
22204 +       return(stack != current->thread.kernel_stack);
22205 +}
22206 +
22207 +extern void remove_umid_dir(void);
22208 +
22209 +__uml_exitcall(remove_umid_dir);
22210 +
22211 +extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
22212 +
22213 +void do_uml_exitcalls(void)
22214 +{
22215 +       exitcall_t *call;
22216 +
22217 +       call = &__uml_exitcall_end;
22218 +       while (--call >= &__uml_exitcall_begin)
22219 +               (*call)();
22220 +}
22221 +
22222 +char *uml_strdup(char *string)
22223 +{
22224 +       char *new;
22225 +
22226 +       new = kmalloc(strlen(string) + 1, GFP_KERNEL);
22227 +       if(new == NULL) return(NULL);
22228 +       strcpy(new, string);
22229 +       return(new);
22230 +}
22231 +
22232 +void *get_init_task(void)
22233 +{
22234 +       return(&init_task_union.task);
22235 +}
22236 +
22237 +int copy_to_user_proc(void *to, void *from, int size)
22238 +{
22239 +       return(copy_to_user(to, from, size));
22240 +}
22241 +
22242 +int copy_from_user_proc(void *to, void *from, int size)
22243 +{
22244 +       return(copy_from_user(to, from, size));
22245 +}
22246 +
22247 +int clear_user_proc(void *buf, int size)
22248 +{
22249 +       return(clear_user(buf, size));
22250 +}
22251 +
22252 +int strlen_user_proc(char *str)
22253 +{
22254 +       return(strlen_user(str));
22255 +}
22256 +
22257 +int smp_sigio_handler(void)
22258 +{
22259 +#ifdef CONFIG_SMP
22260 +       int cpu = current->processor;
22261 +
22262 +       IPI_handler(cpu);
22263 +       if(cpu != 0)
22264 +               return(1);
22265 +#endif
22266 +       return(0);
22267 +}
22268 +
22269 +int um_in_interrupt(void)
22270 +{
22271 +       return(in_interrupt());
22272 +}
22273 +
22274 +int cpu(void)
22275 +{
22276 +        return(current->processor);
22277 +}
22278 +
22279 +/*
22280 + * Overrides for Emacs so that we follow Linus's tabbing style.
22281 + * Emacs will notice this stuff at the end of the file and automatically
22282 + * adjust the settings for this buffer only.  This must remain at the end
22283 + * of the file.
22284 + * ---------------------------------------------------------------------------
22285 + * Local variables:
22286 + * c-file-style: "linux"
22287 + * End:
22288 + */
22289 diff -Naur -X ../exclude-files orig/arch/um/kernel/ptrace.c um/arch/um/kernel/ptrace.c
22290 --- orig/arch/um/kernel/ptrace.c        1969-12-31 19:00:00.000000000 -0500
22291 +++ um/arch/um/kernel/ptrace.c  2003-10-21 03:26:06.000000000 -0400
22292 @@ -0,0 +1,325 @@
22293 +/* 
22294 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
22295 + * Licensed under the GPL
22296 + */
22297 +
22298 +#include "linux/sched.h"
22299 +#include "linux/mm.h"
22300 +#include "linux/errno.h"
22301 +#include "linux/smp_lock.h"
22302 +#ifdef CONFIG_PROC_MM
22303 +#include "linux/proc_mm.h"
22304 +#endif
22305 +#include "asm/ptrace.h"
22306 +#include "asm/uaccess.h"
22307 +#include "kern_util.h"
22308 +#include "ptrace_user.h"
22309 +
22310 +/*
22311 + * Called by kernel/ptrace.c when detaching..
22312 + */
22313 +void ptrace_disable(struct task_struct *child)
22314 +{ 
22315 +}
22316 +
22317 +extern long do_mmap2(struct task_struct *task, unsigned long addr, 
22318 +                    unsigned long len, unsigned long prot, 
22319 +                    unsigned long flags, unsigned long fd,
22320 +                    unsigned long pgoff);
22321 +
22322 +int sys_ptrace(long request, long pid, long addr, long data)
22323 +{
22324 +       struct task_struct *child;
22325 +       int i, ret;
22326 +
22327 +       lock_kernel();
22328 +       ret = -EPERM;
22329 +       if (request == PTRACE_TRACEME) {
22330 +               /* are we already being traced? */
22331 +               if (current->ptrace & PT_PTRACED)
22332 +                       goto out;
22333 +               /* set the ptrace bit in the process flags. */
22334 +               current->ptrace |= PT_PTRACED;
22335 +               ret = 0;
22336 +               goto out;
22337 +       }
22338 +       ret = -ESRCH;
22339 +       read_lock(&tasklist_lock);
22340 +       child = find_task_by_pid(pid);
22341 +       if (child)
22342 +               get_task_struct(child);
22343 +       read_unlock(&tasklist_lock);
22344 +       if (!child)
22345 +               goto out;
22346 +
22347 +       ret = -EPERM;
22348 +       if (pid == 1)           /* you may not mess with init */
22349 +               goto out_tsk;
22350 +
22351 +       if (request == PTRACE_ATTACH) {
22352 +               ret = ptrace_attach(child);
22353 +               goto out_tsk;
22354 +       }
22355 +
22356 +       ret = ptrace_check_attach(child, request == PTRACE_KILL);
22357 +       if (ret < 0)
22358 +               goto out_tsk;
22359 +
22360 +       switch (request) {
22361 +               /* when I and D space are separate, these will need to be fixed. */
22362 +       case PTRACE_PEEKTEXT: /* read word at location addr. */ 
22363 +       case PTRACE_PEEKDATA: {
22364 +               unsigned long tmp;
22365 +               int copied;
22366 +
22367 +               ret = -EIO;
22368 +               copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
22369 +               if (copied != sizeof(tmp))
22370 +                       break;
22371 +               ret = put_user(tmp,(unsigned long *) data);
22372 +               break;
22373 +       }
22374 +
22375 +       /* read the word at location addr in the USER area. */
22376 +       case PTRACE_PEEKUSR: {
22377 +               unsigned long tmp;
22378 +
22379 +               ret = -EIO;
22380 +               if ((addr & 3) || addr < 0) 
22381 +                       break;
22382 +
22383 +               tmp = 0;  /* Default return condition */
22384 +               if(addr < FRAME_SIZE_OFFSET){
22385 +                       tmp = getreg(child, addr);
22386 +               }
22387 +               else if((addr >= offsetof(struct user, u_debugreg[0])) &&
22388 +                       (addr <= offsetof(struct user, u_debugreg[7]))){
22389 +                       addr -= offsetof(struct user, u_debugreg[0]);
22390 +                       addr = addr >> 2;
22391 +                       tmp = child->thread.arch.debugregs[addr];
22392 +               }
22393 +               ret = put_user(tmp, (unsigned long *) data);
22394 +               break;
22395 +       }
22396 +
22397 +       /* when I and D space are separate, this will have to be fixed. */
22398 +       case PTRACE_POKETEXT: /* write the word at location addr. */
22399 +       case PTRACE_POKEDATA:
22400 +               ret = -EIO;
22401 +               if (access_process_vm(child, addr, &data, sizeof(data), 
22402 +                                     1) != sizeof(data))
22403 +                       break;
22404 +               ret = 0;
22405 +               break;
22406 +
22407 +       case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
22408 +               ret = -EIO;
22409 +               if ((addr & 3) || addr < 0)
22410 +                       break;
22411 +
22412 +               if (addr < FRAME_SIZE_OFFSET) {
22413 +                       ret = putreg(child, addr, data);
22414 +                       break;
22415 +               }
22416 +               else if((addr >= offsetof(struct user, u_debugreg[0])) &&
22417 +                       (addr <= offsetof(struct user, u_debugreg[7]))){
22418 +                         addr -= offsetof(struct user, u_debugreg[0]);
22419 +                         addr = addr >> 2;
22420 +                         if((addr == 4) || (addr == 5)) break;
22421 +                         child->thread.arch.debugregs[addr] = data;
22422 +                         ret = 0;
22423 +               }
22424 +
22425 +               break;
22426 +
22427 +       case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
22428 +       case PTRACE_CONT: { /* restart after signal. */
22429 +               ret = -EIO;
22430 +               if ((unsigned long) data > _NSIG)
22431 +                       break;
22432 +               if (request == PTRACE_SYSCALL)
22433 +                       child->ptrace |= PT_TRACESYS;
22434 +               else
22435 +                       child->ptrace &= ~PT_TRACESYS;
22436 +               child->exit_code = data;
22437 +               wake_up_process(child);
22438 +               ret = 0;
22439 +               break;
22440 +       }
22441 +
22442 +/*
22443 + * make the child exit.  Best I can do is send it a sigkill. 
22444 + * perhaps it should be put in the status that it wants to 
22445 + * exit.
22446 + */
22447 +       case PTRACE_KILL: {
22448 +               ret = 0;
22449 +               if (child->state == TASK_ZOMBIE)        /* already dead */
22450 +                       break;
22451 +               child->exit_code = SIGKILL;
22452 +               wake_up_process(child);
22453 +               break;
22454 +       }
22455 +
22456 +       case PTRACE_SINGLESTEP: {  /* set the trap flag. */
22457 +               ret = -EIO;
22458 +               if ((unsigned long) data > _NSIG)
22459 +                       break;
22460 +               child->ptrace &= ~PT_TRACESYS;
22461 +               child->ptrace |= PT_DTRACE;
22462 +               child->exit_code = data;
22463 +               /* give it a chance to run. */
22464 +               wake_up_process(child);
22465 +               ret = 0;
22466 +               break;
22467 +       }
22468 +
22469 +       case PTRACE_DETACH:
22470 +               /* detach a process that was attached. */
22471 +               ret = ptrace_detach(child, data);
22472 +               break;
22473 +
22474 +#ifdef PTRACE_GETREGS
22475 +       case PTRACE_GETREGS: { /* Get all gp regs from the child. */
22476 +               if (!access_ok(VERIFY_WRITE, (unsigned long *)data, 
22477 +                              FRAME_SIZE_OFFSET)) {
22478 +                       ret = -EIO;
22479 +                       break;
22480 +               }
22481 +               for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
22482 +                       __put_user(getreg(child, i), (unsigned long *) data);
22483 +                       data += sizeof(long);
22484 +               }
22485 +               ret = 0;
22486 +               break;
22487 +       }
22488 +#endif
22489 +#ifdef PTRACE_SETREGS
22490 +       case PTRACE_SETREGS: { /* Set all gp regs in the child. */
22491 +               unsigned long tmp = 0;
22492 +               if (!access_ok(VERIFY_READ, (unsigned *)data, 
22493 +                              FRAME_SIZE_OFFSET)) {
22494 +                       ret = -EIO;
22495 +                       break;
22496 +               }
22497 +               for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
22498 +                       __get_user(tmp, (unsigned long *) data);
22499 +                       putreg(child, i, tmp);
22500 +                       data += sizeof(long);
22501 +               }
22502 +               ret = 0;
22503 +               break;
22504 +       }
22505 +#endif
22506 +#ifdef PTRACE_GETFPREGS
22507 +       case PTRACE_GETFPREGS: /* Get the child FPU state. */
22508 +               ret = get_fpregs(data, child);
22509 +               break;
22510 +#endif
22511 +#ifdef PTRACE_SETFPREGS
22512 +       case PTRACE_SETFPREGS: /* Set the child FPU state. */
22513 +               ret = set_fpregs(data, child);
22514 +               break;
22515 +#endif
22516 +#ifdef PTRACE_GETFPXREGS
22517 +       case PTRACE_GETFPXREGS: /* Get the child FPU state. */
22518 +               ret = get_fpxregs(data, child);
22519 +               break;
22520 +#endif
22521 +#ifdef PTRACE_SETFPXREGS
22522 +       case PTRACE_SETFPXREGS: /* Set the child FPU state. */
22523 +               ret = set_fpxregs(data, child);
22524 +               break;
22525 +#endif
22526 +       case PTRACE_FAULTINFO: {
22527 +               struct ptrace_faultinfo fault;
22528 +
22529 +               fault = ((struct ptrace_faultinfo) 
22530 +                       { .is_write     = child->thread.err,
22531 +                         .addr         = child->thread.cr2 });
22532 +               ret = copy_to_user((unsigned long *) data, &fault, 
22533 +                                  sizeof(fault));
22534 +               if(ret)
22535 +                       break;
22536 +               break;
22537 +       }
22538 +       case PTRACE_SIGPENDING:
22539 +               ret = copy_to_user((unsigned long *) data, 
22540 +                                  &child->pending.signal,
22541 +                                  sizeof(child->pending.signal));
22542 +               break;
22543 +
22544 +       case PTRACE_LDT: {
22545 +               struct ptrace_ldt ldt;
22546 +
22547 +               if(copy_from_user(&ldt, (unsigned long *) data, 
22548 +                                 sizeof(ldt))){
22549 +                       ret = -EIO;
22550 +                       break;
22551 +               }
22552 +
22553 +               /* This one is confusing, so just punt and return -EIO for 
22554 +                * now
22555 +                */
22556 +               ret = -EIO;
22557 +               break;
22558 +       }
22559 +#ifdef CONFIG_PROC_MM
22560 +       case PTRACE_SWITCH_MM: {
22561 +               struct mm_struct *old = child->mm;
22562 +               struct mm_struct *new = proc_mm_get_mm(data);
22563 +
22564 +               if(IS_ERR(new)){
22565 +                       ret = PTR_ERR(new);
22566 +                       break;
22567 +               }
22568 +
22569 +               atomic_inc(&new->mm_users);
22570 +               child->mm = new;
22571 +               child->active_mm = new;
22572 +               mmput(old);
22573 +               ret = 0;
22574 +               break;
22575 +       }
22576 +#endif
22577 +       default:
22578 +               ret = -EIO;
22579 +               break;
22580 +       }
22581 + out_tsk:
22582 +       free_task_struct(child);
22583 + out:
22584 +       unlock_kernel();
22585 +       return ret;
22586 +}
22587 +
22588 +void syscall_trace(void)
22589 +{
22590 +       if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
22591 +           != (PT_PTRACED|PT_TRACESYS))
22592 +               return;
22593 +       current->exit_code = SIGTRAP;
22594 +       current->state = TASK_STOPPED;
22595 +       notify_parent(current, SIGCHLD);
22596 +       schedule();
22597 +       /*
22598 +        * this isn't the same as continuing with a signal, but it will do
22599 +        * for normal use.  strace only continues with a signal if the
22600 +        * stopping signal is not SIGTRAP.  -brl
22601 +        */
22602 +       if (current->exit_code) {
22603 +               send_sig(current->exit_code, current, 1);
22604 +               current->exit_code = 0;
22605 +       }
22606 +}
22607 +
22608 +/*
22609 + * Overrides for Emacs so that we follow Linus's tabbing style.
22610 + * Emacs will notice this stuff at the end of the file and automatically
22611 + * adjust the settings for this buffer only.  This must remain at the end
22612 + * of the file.
22613 + * ---------------------------------------------------------------------------
22614 + * Local variables:
22615 + * c-file-style: "linux"
22616 + * End:
22617 + */
22618 diff -Naur -X ../exclude-files orig/arch/um/kernel/reboot.c um/arch/um/kernel/reboot.c
22619 --- orig/arch/um/kernel/reboot.c        1969-12-31 19:00:00.000000000 -0500
22620 +++ um/arch/um/kernel/reboot.c  2003-10-21 03:26:06.000000000 -0400
22621 @@ -0,0 +1,73 @@
22622 +/* 
22623 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
22624 + * Licensed under the GPL
22625 + */
22626 +
22627 +#include "linux/sched.h"
22628 +#include "user_util.h"
22629 +#include "kern_util.h"
22630 +#include "kern.h"
22631 +#include "os.h"
22632 +#include "mode.h"
22633 +#include "choose-mode.h"
22634 +
22635 +#ifdef CONFIG_SMP
22636 +static void kill_idlers(int me)
22637 +{
22638 +#ifdef CONFIG_MODE_TT
22639 +       struct task_struct *p;
22640 +       int i;
22641 +
22642 +       for(i = 0; i < sizeof(init_tasks)/sizeof(init_tasks[0]); i++){
22643 +               p = init_tasks[i];
22644 +               if((p != NULL) && (p->thread.mode.tt.extern_pid != me) &&
22645 +                  (p->thread.mode.tt.extern_pid != -1))
22646 +                       os_kill_process(p->thread.mode.tt.extern_pid, 0);
22647 +       }
22648 +#endif
22649 +}
22650 +#endif
22651 +
22652 +static void kill_off_processes(void)
22653 +{
22654 +       CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas());
22655 +#ifdef CONFIG_SMP
22656 +       kill_idlers(os_getpid());
22657 +#endif
22658 +}
22659 +
22660 +void uml_cleanup(void)
22661 +{
22662 +       kill_off_processes();
22663 +       do_uml_exitcalls();
22664 +}
22665 +
22666 +void machine_restart(char * __unused)
22667 +{
22668 +       do_uml_exitcalls();
22669 +       kill_off_processes();
22670 +       CHOOSE_MODE(reboot_tt(), reboot_skas());
22671 +}
22672 +
22673 +void machine_power_off(void)
22674 +{
22675 +       do_uml_exitcalls();
22676 +       kill_off_processes();
22677 +       CHOOSE_MODE(halt_tt(), halt_skas());
22678 +}
22679 +
22680 +void machine_halt(void)
22681 +{
22682 +       machine_power_off();
22683 +}
22684 +
22685 +/*
22686 + * Overrides for Emacs so that we follow Linus's tabbing style.
22687 + * Emacs will notice this stuff at the end of the file and automatically
22688 + * adjust the settings for this buffer only.  This must remain at the end
22689 + * of the file.
22690 + * ---------------------------------------------------------------------------
22691 + * Local variables:
22692 + * c-file-style: "linux"
22693 + * End:
22694 + */
22695 diff -Naur -X ../exclude-files orig/arch/um/kernel/resource.c um/arch/um/kernel/resource.c
22696 --- orig/arch/um/kernel/resource.c      1969-12-31 19:00:00.000000000 -0500
22697 +++ um/arch/um/kernel/resource.c        2003-10-21 03:26:06.000000000 -0400
22698 @@ -0,0 +1,23 @@
22699 +/* 
22700 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
22701 + * Licensed under the GPL
22702 + */
22703 +
22704 +#include "linux/pci.h"
22705 +
22706 +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
22707 +                            unsigned long start, unsigned long size)
22708 +{
22709 +       return start;
22710 +}
22711 +
22712 +/*
22713 + * Overrides for Emacs so that we follow Linus's tabbing style.
22714 + * Emacs will notice this stuff at the end of the file and automatically
22715 + * adjust the settings for this buffer only.  This must remain at the end
22716 + * of the file.
22717 + * ---------------------------------------------------------------------------
22718 + * Local variables:
22719 + * c-file-style: "linux"
22720 + * End:
22721 + */
22722 diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_kern.c um/arch/um/kernel/sigio_kern.c
22723 --- orig/arch/um/kernel/sigio_kern.c    1969-12-31 19:00:00.000000000 -0500
22724 +++ um/arch/um/kernel/sigio_kern.c      2003-10-21 03:26:07.000000000 -0400
22725 @@ -0,0 +1,57 @@
22726 +/* 
22727 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22728 + * Licensed under the GPL
22729 + */
22730 +
22731 +#include "linux/kernel.h"
22732 +#include "linux/list.h"
22733 +#include "linux/slab.h"
22734 +#include "asm/irq.h"
22735 +#include "init.h"
22736 +#include "sigio.h"
22737 +#include "irq_user.h"
22738 +#include "irq_kern.h"
22739 +
22740 +/* Protected by sigio_lock() called from write_sigio_workaround */
22741 +static int sigio_irq_fd = -1;
22742 +
22743 +void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
22744 +{
22745 +       read_sigio_fd(sigio_irq_fd);
22746 +       reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
22747 +}
22748 +
22749 +int write_sigio_irq(int fd)
22750 +{
22751 +       if(um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
22752 +                         SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio", 
22753 +                         NULL)){
22754 +               printk("write_sigio_irq : um_request_irq failed\n");
22755 +               return(-1);
22756 +       }
22757 +       sigio_irq_fd = fd;
22758 +       return(0);
22759 +}
22760 +
22761 +static spinlock_t sigio_spinlock = SPIN_LOCK_UNLOCKED;
22762 +
22763 +void sigio_lock(void)
22764 +{
22765 +       spin_lock(&sigio_spinlock);
22766 +}
22767 +
22768 +void sigio_unlock(void)
22769 +{
22770 +       spin_unlock(&sigio_spinlock);
22771 +}
22772 +
22773 +/*
22774 + * Overrides for Emacs so that we follow Linus's tabbing style.
22775 + * Emacs will notice this stuff at the end of the file and automatically
22776 + * adjust the settings for this buffer only.  This must remain at the end
22777 + * of the file.
22778 + * ---------------------------------------------------------------------------
22779 + * Local variables:
22780 + * c-file-style: "linux"
22781 + * End:
22782 + */
22783 diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_user.c um/arch/um/kernel/sigio_user.c
22784 --- orig/arch/um/kernel/sigio_user.c    1969-12-31 19:00:00.000000000 -0500
22785 +++ um/arch/um/kernel/sigio_user.c      2003-11-07 01:41:13.000000000 -0500
22786 @@ -0,0 +1,438 @@
22787 +/* 
22788 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22789 + * Licensed under the GPL
22790 + */
22791 +
22792 +#include <unistd.h>
22793 +#include <stdlib.h>
22794 +#include <termios.h>
22795 +#include <pty.h>
22796 +#include <signal.h>
22797 +#include <errno.h>
22798 +#include <string.h>
22799 +#include <sched.h>
22800 +#include <sys/socket.h>
22801 +#include <sys/poll.h>
22802 +#include "init.h"
22803 +#include "user.h"
22804 +#include "kern_util.h"
22805 +#include "sigio.h"
22806 +#include "helper.h"
22807 +#include "os.h"
22808 +
22809 +/* Changed during early boot */
22810 +int pty_output_sigio = 0;
22811 +int pty_close_sigio = 0;
22812 +
22813 +/* Used as a flag during SIGIO testing early in boot */
22814 +static volatile int got_sigio = 0;
22815 +
22816 +void __init handler(int sig)
22817 +{
22818 +       got_sigio = 1;
22819 +}
22820 +
22821 +struct openpty_arg {
22822 +       int master;
22823 +       int slave;
22824 +       int err;
22825 +};
22826 +
22827 +static void openpty_cb(void *arg)
22828 +{
22829 +       struct openpty_arg *info = arg;
22830 +
22831 +       info->err = 0;
22832 +       if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
22833 +               info->err = -errno;
22834 +}
22835 +
22836 +void __init check_one_sigio(void (*proc)(int, int))
22837 +{
22838 +       struct sigaction old, new;
22839 +       struct termios tt;
22840 +       struct openpty_arg pty = { .master = -1, .slave = -1 };
22841 +       int master, slave, err;
22842 +
22843 +       initial_thread_cb(openpty_cb, &pty);
22844 +       if(pty.err){
22845 +               printk("openpty failed, errno = %d\n", -pty.err);
22846 +               return;
22847 +       }
22848 +
22849 +       master = pty.master;
22850 +       slave = pty.slave;
22851 +
22852 +       if((master == -1) || (slave == -1)){
22853 +               printk("openpty failed to allocate a pty\n");
22854 +               return;
22855 +       }
22856 +
22857 +       /* XXX These can fail with EINTR */
22858 +       if(tcgetattr(master, &tt) < 0)
22859 +               panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
22860 +       cfmakeraw(&tt);
22861 +       if(tcsetattr(master, TCSADRAIN, &tt) < 0)
22862 +               panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
22863 +
22864 +       err = os_sigio_async(master, slave);
22865 +       if(err < 0)
22866 +               panic("tty_fds : sigio_async failed, err = %d\n", -err);
22867 +
22868 +       if(sigaction(SIGIO, NULL, &old) < 0)
22869 +               panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
22870 +       new = old;
22871 +       new.sa_handler = handler;
22872 +       if(sigaction(SIGIO, &new, NULL) < 0)
22873 +               panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
22874 +
22875 +       got_sigio = 0;
22876 +       (*proc)(master, slave);
22877 +               
22878 +       os_close_file(master);
22879 +       os_close_file(slave);
22880 +
22881 +       if(sigaction(SIGIO, &old, NULL) < 0)
22882 +               panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
22883 +}
22884 +
22885 +static void tty_output(int master, int slave)
22886 +{
22887 +       int n;
22888 +       char buf[512];
22889 +
22890 +       printk("Checking that host ptys support output SIGIO...");
22891 +
22892 +       memset(buf, 0, sizeof(buf));
22893 +
22894 +       while(os_write_file(master, buf, sizeof(buf)) > 0) ;
22895 +       if(errno != EAGAIN)
22896 +               panic("check_sigio : write failed, errno = %d\n", errno);
22897 +       while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
22898 +
22899 +       if(got_sigio){
22900 +               printk("Yes\n");
22901 +               pty_output_sigio = 1;
22902 +       }
22903 +       else if(n == -EAGAIN) printk("No, enabling workaround\n");
22904 +       else panic("check_sigio : read failed, err = %d\n", n);
22905 +}
22906 +
22907 +static void tty_close(int master, int slave)
22908 +{
22909 +       printk("Checking that host ptys support SIGIO on close...");
22910 +
22911 +       os_close_file(slave);
22912 +       if(got_sigio){
22913 +               printk("Yes\n");
22914 +               pty_close_sigio = 1;
22915 +       }
22916 +       else printk("No, enabling workaround\n");
22917 +}
22918 +
22919 +void __init check_sigio(void)
22920 +{
22921 +       if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
22922 +          (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
22923 +               printk("No pseudo-terminals available - skipping pty SIGIO "
22924 +                      "check\n");
22925 +               return;
22926 +       }
22927 +       check_one_sigio(tty_output);
22928 +       check_one_sigio(tty_close);
22929 +}
22930 +
22931 +/* Protected by sigio_lock(), also used by sigio_cleanup, which is an 
22932 + * exitcall.
22933 + */
22934 +static int write_sigio_pid = -1;
22935 +
22936 +/* These arrays are initialized before the sigio thread is started, and
22937 + * the descriptors closed after it is killed.  So, it can't see them change.
22938 + * On the UML side, they are changed under the sigio_lock.
22939 + */
22940 +static int write_sigio_fds[2] = { -1, -1 };
22941 +static int sigio_private[2] = { -1, -1 };
22942 +
22943 +struct pollfds {
22944 +       struct pollfd *poll;
22945 +       int size;
22946 +       int used;
22947 +};
22948 +
22949 +/* Protected by sigio_lock().  Used by the sigio thread, but the UML thread
22950 + * synchronizes with it.
22951 + */
22952 +struct pollfds current_poll = {
22953 +       .poll           = NULL,
22954 +       .size           = 0,
22955 +       .used           = 0
22956 +};
22957 +
22958 +struct pollfds next_poll = {
22959 +       .poll           = NULL,
22960 +       .size           = 0,
22961 +       .used           = 0
22962 +};
22963 +
22964 +static int write_sigio_thread(void *unused)
22965 +{
22966 +       struct pollfds *fds, tmp;
22967 +       struct pollfd *p;
22968 +       int i, n, respond_fd;
22969 +       char c;
22970 +
22971 +       fds = &current_poll;
22972 +       while(1){
22973 +               n = poll(fds->poll, fds->used, -1);
22974 +               if(n < 0){
22975 +                       if(errno == EINTR) continue;
22976 +                       printk("write_sigio_thread : poll returned %d, "
22977 +                              "errno = %d\n", n, errno);
22978 +               }
22979 +               for(i = 0; i < fds->used; i++){
22980 +                       p = &fds->poll[i];
22981 +                       if(p->revents == 0) continue;
22982 +                       if(p->fd == sigio_private[1]){
22983 +                               n = os_read_file(sigio_private[1], &c, sizeof(c));
22984 +                               if(n != sizeof(c))
22985 +                                       printk("write_sigio_thread : "
22986 +                                              "read failed, err = %d\n", -n);
22987 +                               tmp = current_poll;
22988 +                               current_poll = next_poll;
22989 +                               next_poll = tmp;
22990 +                               respond_fd = sigio_private[1];
22991 +                       }
22992 +                       else {
22993 +                               respond_fd = write_sigio_fds[1];
22994 +                               fds->used--;
22995 +                               memmove(&fds->poll[i], &fds->poll[i + 1],
22996 +                                       (fds->used - i) * sizeof(*fds->poll));
22997 +                       }
22998 +
22999 +                       n = os_write_file(respond_fd, &c, sizeof(c));
23000 +                       if(n != sizeof(c))
23001 +                               printk("write_sigio_thread : write failed, "
23002 +                                      "err = %d\n", -n);
23003 +               }
23004 +       }
23005 +}
23006 +
23007 +static int need_poll(int n)
23008 +{
23009 +       if(n <= next_poll.size){
23010 +               next_poll.used = n;
23011 +               return(0);
23012 +       }
23013 +       if(next_poll.poll != NULL) kfree(next_poll.poll);
23014 +       next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
23015 +       if(next_poll.poll == NULL){
23016 +               printk("need_poll : failed to allocate new pollfds\n");
23017 +               next_poll.size = 0;
23018 +               next_poll.used = 0;
23019 +               return(-1);
23020 +       }
23021 +       next_poll.size = n;
23022 +       next_poll.used = n;
23023 +       return(0);
23024 +}
23025 +
23026 +static void update_thread(void)
23027 +{
23028 +       unsigned long flags;
23029 +       int n;
23030 +       char c;
23031 +
23032 +       flags = set_signals(0);
23033 +       n = os_write_file(sigio_private[0], &c, sizeof(c));
23034 +       if(n != sizeof(c)){
23035 +               printk("update_thread : write failed, err = %d\n", -n);
23036 +               goto fail;
23037 +       }
23038 +
23039 +       n = os_read_file(sigio_private[0], &c, sizeof(c));
23040 +       if(n != sizeof(c)){
23041 +               printk("update_thread : read failed, err = %d\n", -n);
23042 +               goto fail;
23043 +       }
23044 +
23045 +       set_signals(flags);
23046 +       return;
23047 + fail:
23048 +       sigio_lock();
23049 +       if(write_sigio_pid != -1) 
23050 +               os_kill_process(write_sigio_pid, 1);
23051 +       write_sigio_pid = -1;
23052 +       os_close_file(sigio_private[0]);
23053 +       os_close_file(sigio_private[1]);        
23054 +       os_close_file(write_sigio_fds[0]);
23055 +       os_close_file(write_sigio_fds[1]);
23056 +       sigio_unlock();
23057 +       set_signals(flags);
23058 +}
23059 +
23060 +int add_sigio_fd(int fd, int read)
23061 +{
23062 +       int err = 0, i, n, events;
23063 +
23064 +       sigio_lock();
23065 +       for(i = 0; i < current_poll.used; i++){
23066 +               if(current_poll.poll[i].fd == fd) 
23067 +                       goto out;
23068 +       }
23069 +
23070 +       n = current_poll.used + 1;
23071 +       err = need_poll(n);
23072 +       if(err) 
23073 +               goto out;
23074 +
23075 +       for(i = 0; i < current_poll.used; i++)
23076 +               next_poll.poll[i] = current_poll.poll[i];
23077 +
23078 +       if(read) events = POLLIN;
23079 +       else events = POLLOUT;
23080 +
23081 +       next_poll.poll[n - 1] = ((struct pollfd) { .fd          = fd,
23082 +                                                  .events      = events,
23083 +                                                  .revents     = 0 });
23084 +       update_thread();
23085 + out:
23086 +       sigio_unlock();
23087 +       return(err);
23088 +}
23089 +
23090 +int ignore_sigio_fd(int fd)
23091 +{
23092 +       struct pollfd *p;
23093 +       int err = 0, i, n = 0;
23094 +
23095 +       sigio_lock();
23096 +       for(i = 0; i < current_poll.used; i++){
23097 +               if(current_poll.poll[i].fd == fd) break;
23098 +       }
23099 +       if(i == current_poll.used)
23100 +               goto out;
23101 +       
23102 +       err = need_poll(current_poll.used - 1);
23103 +       if(err)
23104 +               goto out;
23105 +
23106 +       for(i = 0; i < current_poll.used; i++){
23107 +               p = &current_poll.poll[i];
23108 +               if(p->fd != fd) next_poll.poll[n++] = current_poll.poll[i];
23109 +       }
23110 +       if(n == i){
23111 +               printk("ignore_sigio_fd : fd %d not found\n", fd);
23112 +               err = -1;
23113 +               goto out;
23114 +       }
23115 +
23116 +       update_thread();
23117 + out:
23118 +       sigio_unlock();
23119 +       return(err);
23120 +}
23121 +
23122 +static int setup_initial_poll(int fd)
23123 +{
23124 +       struct pollfd *p;
23125 +
23126 +       p = um_kmalloc(sizeof(struct pollfd));
23127 +       if(p == NULL){
23128 +               printk("setup_initial_poll : failed to allocate poll\n");
23129 +               return(-1);
23130 +       }
23131 +       *p = ((struct pollfd) { .fd     = fd,
23132 +                               .events         = POLLIN,
23133 +                               .revents        = 0 });
23134 +       current_poll = ((struct pollfds) { .poll        = p,
23135 +                                          .used        = 1,
23136 +                                          .size        = 1 });
23137 +       return(0);
23138 +}
23139 +
23140 +void write_sigio_workaround(void)
23141 +{
23142 +       unsigned long stack;
23143 +       int err;
23144 +
23145 +       sigio_lock();
23146 +       if(write_sigio_pid != -1)
23147 +               goto out;
23148 +
23149 +       err = os_pipe(write_sigio_fds, 1, 1);
23150 +       if(err < 0){
23151 +               printk("write_sigio_workaround - os_pipe 1 failed, "
23152 +                      "err = %d\n", -err);
23153 +               goto out;
23154 +       }
23155 +       err = os_pipe(sigio_private, 1, 1);
23156 +       if(err < 0){
23157 +               printk("write_sigio_workaround - os_pipe 2 failed, "
23158 +                      "err = %d\n", -err);
23159 +               goto out_close1;
23160 +       }
23161 +       if(setup_initial_poll(sigio_private[1]))
23162 +               goto out_close2;
23163 +
23164 +       write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, 
23165 +                                           CLONE_FILES | CLONE_VM, &stack, 0);
23166 +
23167 +       if(write_sigio_pid < 0) goto out_close2;
23168 +
23169 +       if(write_sigio_irq(write_sigio_fds[0])) 
23170 +               goto out_kill;
23171 +
23172 + out:
23173 +       sigio_unlock();
23174 +       return;
23175 +
23176 + out_kill:
23177 +       os_kill_process(write_sigio_pid, 1);
23178 +       write_sigio_pid = -1;
23179 + out_close2:
23180 +       os_close_file(sigio_private[0]);
23181 +       os_close_file(sigio_private[1]);        
23182 + out_close1:
23183 +       os_close_file(write_sigio_fds[0]);
23184 +       os_close_file(write_sigio_fds[1]);
23185 +       sigio_unlock();
23186 +}
23187 +
23188 +int read_sigio_fd(int fd)
23189 +{
23190 +       int n;
23191 +       char c;
23192 +
23193 +       n = os_read_file(fd, &c, sizeof(c));
23194 +       if(n != sizeof(c)){
23195 +               if(n < 0) {
23196 +                       printk("read_sigio_fd - read failed, err = %d\n", -n);
23197 +                       return(n);
23198 +               } 
23199 +               else { 
23200 +                       printk("read_sigio_fd - short read, bytes = %d\n", n);
23201 +                       return(-EIO);
23202 +               }
23203 +       }
23204 +       return(n);
23205 +}
23206 +
23207 +static void sigio_cleanup(void)
23208 +{
23209 +       if(write_sigio_pid != -1)
23210 +               os_kill_process(write_sigio_pid, 1);
23211 +}
23212 +
23213 +__uml_exitcall(sigio_cleanup);
23214 +
23215 +/*
23216 + * Overrides for Emacs so that we follow Linus's tabbing style.
23217 + * Emacs will notice this stuff at the end of the file and automatically
23218 + * adjust the settings for this buffer only.  This must remain at the end
23219 + * of the file.
23220 + * ---------------------------------------------------------------------------
23221 + * Local variables:
23222 + * c-file-style: "linux"
23223 + * End:
23224 + */
23225 diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_kern.c um/arch/um/kernel/signal_kern.c
23226 --- orig/arch/um/kernel/signal_kern.c   1969-12-31 19:00:00.000000000 -0500
23227 +++ um/arch/um/kernel/signal_kern.c     2003-11-19 03:50:58.000000000 -0500
23228 @@ -0,0 +1,369 @@
23229 +/* 
23230 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
23231 + * Licensed under the GPL
23232 + */
23233 +
23234 +#include "linux/config.h"
23235 +#include "linux/stddef.h"
23236 +#include "linux/sys.h"
23237 +#include "linux/sched.h"
23238 +#include "linux/wait.h"
23239 +#include "linux/kernel.h"
23240 +#include "linux/smp_lock.h"
23241 +#include "linux/module.h"
23242 +#include "linux/slab.h"
23243 +#include "asm/signal.h"
23244 +#include "asm/uaccess.h"
23245 +#include "asm/ucontext.h"
23246 +#include "user_util.h"
23247 +#include "kern_util.h"
23248 +#include "signal_kern.h"
23249 +#include "signal_user.h"
23250 +#include "kern.h"
23251 +#include "frame_kern.h"
23252 +#include "sigcontext.h"
23253 +#include "mode.h"
23254 +
23255 +EXPORT_SYMBOL(block_signals);
23256 +EXPORT_SYMBOL(unblock_signals);
23257 +
23258 +static void force_segv(int sig)
23259 +{
23260 +       if(sig == SIGSEGV){
23261 +               struct k_sigaction *ka;
23262 +
23263 +               ka = &current->sig->action[SIGSEGV - 1];
23264 +               ka->sa.sa_handler = SIG_DFL;
23265 +       }
23266 +       force_sig(SIGSEGV, current);
23267 +}
23268 +
23269 +#define _S(nr) (1<<((nr)-1))
23270 +
23271 +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
23272 +
23273 +/*
23274 + * OK, we're invoking a handler
23275 + */    
23276 +static int handle_signal(struct pt_regs *regs, unsigned long signr, 
23277 +                        struct k_sigaction *ka, siginfo_t *info, 
23278 +                        sigset_t *oldset, int error)
23279 +{
23280 +        __sighandler_t handler;
23281 +       void (*restorer)(void);
23282 +       unsigned long sp;
23283 +       sigset_t save;
23284 +       int err, ret;
23285 +
23286 +       ret = 0;
23287 +       switch(error){
23288 +       case -ERESTARTNOHAND:
23289 +               ret = -EINTR;
23290 +               break;
23291 +
23292 +       case -ERESTARTSYS:
23293 +               if (!(ka->sa.sa_flags & SA_RESTART)) {
23294 +                       ret = -EINTR;
23295 +                       break;
23296 +               }
23297 +               /* fallthrough */
23298 +       case -ERESTARTNOINTR:
23299 +               PT_REGS_RESTART_SYSCALL(regs);
23300 +               PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
23301 +
23302 +               /* This is because of the UM_SET_SYSCALL_RETURN and the fact
23303 +                * that on i386 the system call number and return value are
23304 +                * in the same register.  When the system call restarts, %eax
23305 +                * had better have the system call number in it.  Since the
23306 +                * return value doesn't matter (except that it shouldn't be
23307 +                * -ERESTART*), we'll stick the system call number there.
23308 +                */
23309 +               ret = PT_REGS_SYSCALL_NR(regs);
23310 +               break;
23311 +       }
23312 +
23313 +       handler = ka->sa.sa_handler;
23314 +       save = *oldset;
23315 +
23316 +       if (ka->sa.sa_flags & SA_ONESHOT)
23317 +               ka->sa.sa_handler = SIG_DFL;
23318 +
23319 +       if (!(ka->sa.sa_flags & SA_NODEFER)) {
23320 +               spin_lock_irq(&current->sigmask_lock);
23321 +               sigorsets(&current->blocked, &current->blocked, 
23322 +                         &ka->sa.sa_mask);
23323 +               sigaddset(&current->blocked, signr);
23324 +               recalc_sigpending(current);
23325 +               spin_unlock_irq(&current->sigmask_lock);
23326 +       }
23327 +
23328 +       sp = PT_REGS_SP(regs);
23329 +
23330 +       if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
23331 +               sp = current->sas_ss_sp + current->sas_ss_size;
23332 +       
23333 +       if(error != 0) PT_REGS_SET_SYSCALL_RETURN(regs, ret);
23334 +
23335 +       if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer;
23336 +       else restorer = NULL;
23337 +
23338 +       if(ka->sa.sa_flags & SA_SIGINFO)
23339 +               err = setup_signal_stack_si(sp, signr, (unsigned long) handler,
23340 +                                           restorer, regs, info, &save);
23341 +       else
23342 +               err = setup_signal_stack_sc(sp, signr, (unsigned long) handler,
23343 +                                           restorer, regs, &save);
23344 +       if(err) goto segv;
23345 +
23346 +       return(0);
23347 + segv:
23348 +       force_segv(signr);
23349 +       return(1);
23350 +}
23351 +
23352 +/*
23353 + * Note that 'init' is a special process: it doesn't get signals it doesn't
23354 + * want to handle. Thus you cannot kill init even with a SIGKILL even by
23355 + * mistake.
23356 + */
23357 +
23358 +static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error)
23359 +{
23360 +       siginfo_t info;
23361 +       struct k_sigaction *ka;
23362 +       int err;
23363 +
23364 +       if (!oldset)
23365 +               oldset = &current->blocked;
23366 +
23367 +       for (;;) {
23368 +               unsigned long signr;
23369 +
23370 +               spin_lock_irq(&current->sigmask_lock);
23371 +               signr = dequeue_signal(&current->blocked, &info);
23372 +               spin_unlock_irq(&current->sigmask_lock);
23373 +
23374 +               if (!signr)
23375 +                       break;
23376 +
23377 +               if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
23378 +                       /* Let the debugger run.  */
23379 +                       current->exit_code = signr;
23380 +                       current->state = TASK_STOPPED;
23381 +                       notify_parent(current, SIGCHLD);
23382 +                       schedule();
23383 +
23384 +                       /* We're back.  Did the debugger cancel the sig?  */
23385 +                       signr = current->exit_code;
23386 +                       if (!signr)
23387 +                               continue;
23388 +                       current->exit_code = 0;
23389 +
23390 +                       /* The debugger continued.  Ignore SIGSTOP.  */
23391 +                       if (signr == SIGSTOP)
23392 +                               continue;
23393 +
23394 +                       /* Update the siginfo structure.  Is this good?  */
23395 +                       if (signr != info.si_signo) {
23396 +                               info.si_signo = signr;
23397 +                               info.si_errno = 0;
23398 +                               info.si_code = SI_USER;
23399 +                               info.si_pid = current->p_pptr->pid;
23400 +                               info.si_uid = current->p_pptr->uid;
23401 +                       }
23402 +
23403 +                       /* If the (new) signal is now blocked, requeue it.  */
23404 +                       if (sigismember(&current->blocked, signr)) {
23405 +                               send_sig_info(signr, &info, current);
23406 +                               continue;
23407 +                       }
23408 +               }
23409 +
23410 +               ka = &current->sig->action[signr-1];
23411 +               if (ka->sa.sa_handler == SIG_IGN) {
23412 +                       if (signr != SIGCHLD)
23413 +                               continue;
23414 +                       /* Check for SIGCHLD: it's special.  */
23415 +                       while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
23416 +                               /* nothing */;
23417 +                       continue;
23418 +               }
23419 +
23420 +               if (ka->sa.sa_handler == SIG_DFL) {
23421 +                       int exit_code = signr;
23422 +
23423 +                       /* Init gets no signals it doesn't want.  */
23424 +                       if (current->pid == 1)
23425 +                               continue;
23426 +
23427 +                       switch (signr) {
23428 +                       case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
23429 +                               continue;
23430 +
23431 +                       case SIGTSTP: case SIGTTIN: case SIGTTOU:
23432 +                               if (is_orphaned_pgrp(current->pgrp))
23433 +                                       continue;
23434 +                               /* FALLTHRU */
23435 +
23436 +                        case SIGSTOP: {
23437 +                                struct signal_struct *sig;
23438 +                               current->state = TASK_STOPPED;
23439 +                               current->exit_code = signr;
23440 +                                sig = current->p_pptr->sig;
23441 +                                if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
23442 +                                       notify_parent(current, SIGCHLD);
23443 +                               schedule();
23444 +                               continue;
23445 +                       }
23446 +                       case SIGQUIT: case SIGILL: case SIGTRAP:
23447 +                       case SIGABRT: case SIGFPE: case SIGSEGV:
23448 +                       case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
23449 +                               if (do_coredump(signr, &current->thread.regs))
23450 +                                       exit_code |= 0x80;
23451 +                               /* FALLTHRU */
23452 +
23453 +                       default:
23454 +                               sig_exit(signr, exit_code, &info);
23455 +                               /* NOTREACHED */
23456 +                       }
23457 +               }
23458 +
23459 +               /* Whee!  Actually deliver the signal.  */
23460 +               err = handle_signal(regs, signr, ka, &info, oldset, error);
23461 +               if(!err) return(1);
23462 +       }
23463 +
23464 +       /* Did we come from a system call? */
23465 +       if(PT_REGS_SYSCALL_NR(regs) >= 0){
23466 +               /* Restart the system call - no handlers present */
23467 +               if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND ||
23468 +                  PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS ||
23469 +                  PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOINTR){
23470 +                       PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
23471 +                       PT_REGS_RESTART_SYSCALL(regs);
23472 +               }
23473 +       }
23474 +
23475 +       /* This closes a way to execute a system call on the host.  If
23476 +        * you set a breakpoint on a system call instruction and singlestep
23477 +        * from it, the tracing thread used to PTRACE_SINGLESTEP the process
23478 +        * rather than PTRACE_SYSCALL it, allowing the system call to execute
23479 +        * on the host.  The tracing thread will check this flag and 
23480 +        * PTRACE_SYSCALL if necessary.
23481 +        */
23482 +       if((current->ptrace & PT_DTRACE) && 
23483 +          is_syscall(PT_REGS_IP(&current->thread.regs)))
23484 +               (void) CHOOSE_MODE(current->thread.mode.tt.singlestep_syscall = 1, 0);
23485 +
23486 +       return(0);
23487 +}
23488 +
23489 +int do_signal(int error)
23490 +{
23491 +       return(kern_do_signal(&current->thread.regs, NULL, error));
23492 +}
23493 +
23494 +/*
23495 + * Atomically swap in the new signal mask, and wait for a signal.
23496 + */
23497 +int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
23498 +{
23499 +       sigset_t saveset;
23500 +
23501 +       mask &= _BLOCKABLE;
23502 +       spin_lock_irq(&current->sigmask_lock);
23503 +       saveset = current->blocked;
23504 +       siginitset(&current->blocked, mask);
23505 +       recalc_sigpending(current);
23506 +       spin_unlock_irq(&current->sigmask_lock);
23507 +
23508 +       while (1) {
23509 +               current->state = TASK_INTERRUPTIBLE;
23510 +               schedule();
23511 +               if(kern_do_signal(&current->thread.regs, &saveset, -EINTR))
23512 +                       return(-EINTR);
23513 +       }
23514 +}
23515 +
23516 +int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
23517 +{
23518 +       sigset_t saveset, newset;
23519 +
23520 +       /* XXX: Don't preclude handling different sized sigset_t's.  */
23521 +       if (sigsetsize != sizeof(sigset_t))
23522 +               return -EINVAL;
23523 +
23524 +       if (copy_from_user(&newset, unewset, sizeof(newset)))
23525 +               return -EFAULT;
23526 +       sigdelsetmask(&newset, ~_BLOCKABLE);
23527 +
23528 +       spin_lock_irq(&current->sigmask_lock);
23529 +       saveset = current->blocked;
23530 +       current->blocked = newset;
23531 +       recalc_sigpending(current);
23532 +       spin_unlock_irq(&current->sigmask_lock);
23533 +
23534 +       while (1) {
23535 +               current->state = TASK_INTERRUPTIBLE;
23536 +               schedule();
23537 +               if (kern_do_signal(&current->thread.regs, &saveset, -EINTR))
23538 +                       return(-EINTR);
23539 +       }
23540 +}
23541 +
23542 +extern int userspace_pid[];
23543 +
23544 +static int copy_sc_from_user(struct pt_regs *to, void *from, 
23545 +                            struct arch_frame_data *arch)
23546 +{
23547 +       int ret;
23548 +
23549 +       ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
23550 +                         copy_sc_from_user_skas(userspace_pid[0], 
23551 +                                                &to->regs, from));
23552 +       return(ret);
23553 +}
23554 +
23555 +int sys_sigreturn(struct pt_regs regs)
23556 +{
23557 +       void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
23558 +       void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
23559 +       int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
23560 +
23561 +       spin_lock_irq(&current->sigmask_lock);
23562 +       copy_from_user(&current->blocked.sig[0], sc_sigmask(sc), 
23563 +                      sizeof(current->blocked.sig[0]));
23564 +       copy_from_user(&current->blocked.sig[1], mask, sig_size);
23565 +       sigdelsetmask(&current->blocked, ~_BLOCKABLE);
23566 +       recalc_sigpending(current);
23567 +       spin_unlock_irq(&current->sigmask_lock);
23568 +       copy_sc_from_user(&current->thread.regs, sc, 
23569 +                         &signal_frame_sc.common.arch);
23570 +       return(PT_REGS_SYSCALL_RET(&current->thread.regs));
23571 +}
23572 +
23573 +int sys_rt_sigreturn(struct pt_regs regs)
23574 +{
23575 +       struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
23576 +       int sig_size = _NSIG_WORDS * sizeof(unsigned long);
23577 +
23578 +       spin_lock_irq(&current->sigmask_lock);
23579 +       copy_from_user(&current->blocked, &uc->uc_sigmask, sig_size);
23580 +       sigdelsetmask(&current->blocked, ~_BLOCKABLE);
23581 +       recalc_sigpending(current);
23582 +       spin_unlock_irq(&current->sigmask_lock);
23583 +       copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext,
23584 +                         &signal_frame_si.common.arch);
23585 +       return(PT_REGS_SYSCALL_RET(&current->thread.regs));
23586 +}
23587 +
23588 +/*
23589 + * Overrides for Emacs so that we follow Linus's tabbing style.
23590 + * Emacs will notice this stuff at the end of the file and automatically
23591 + * adjust the settings for this buffer only.  This must remain at the end
23592 + * of the file.
23593 + * ---------------------------------------------------------------------------
23594 + * Local variables:
23595 + * c-file-style: "linux"
23596 + * End:
23597 + */
23598 diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_user.c um/arch/um/kernel/signal_user.c
23599 --- orig/arch/um/kernel/signal_user.c   1969-12-31 19:00:00.000000000 -0500
23600 +++ um/arch/um/kernel/signal_user.c     2003-10-21 03:26:07.000000000 -0400
23601 @@ -0,0 +1,142 @@
23602 +/* 
23603 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
23604 + * Licensed under the GPL
23605 + */
23606 +
23607 +#include <stdio.h>
23608 +#include <unistd.h>
23609 +#include <stdlib.h>
23610 +#include <signal.h>
23611 +#include <errno.h>
23612 +#include <stdarg.h>
23613 +#include <string.h>
23614 +#include <sys/mman.h>
23615 +#include "user_util.h"
23616 +#include "kern_util.h"
23617 +#include "user.h"
23618 +#include "signal_user.h"
23619 +#include "signal_kern.h"
23620 +#include "sysdep/sigcontext.h"
23621 +#include "sigcontext.h"
23622 +
23623 +void set_sigstack(void *sig_stack, int size)
23624 +{
23625 +       stack_t stack = ((stack_t) { .ss_flags  = 0,
23626 +                                    .ss_sp     = (__ptr_t) sig_stack,
23627 +                                    .ss_size   = size - sizeof(void *) });
23628 +
23629 +       if(sigaltstack(&stack, NULL) != 0)
23630 +               panic("enabling signal stack failed, errno = %d\n", errno);
23631 +}
23632 +
23633 +void set_handler(int sig, void (*handler)(int), int flags, ...)
23634 +{
23635 +       struct sigaction action;
23636 +       va_list ap;
23637 +       int mask;
23638 +
23639 +       va_start(ap, flags);
23640 +       action.sa_handler = handler;
23641 +       sigemptyset(&action.sa_mask);
23642 +       while((mask = va_arg(ap, int)) != -1){
23643 +               sigaddset(&action.sa_mask, mask);
23644 +       }
23645 +       action.sa_flags = flags;
23646 +       action.sa_restorer = NULL;
23647 +       if(sigaction(sig, &action, NULL) < 0)
23648 +               panic("sigaction failed");
23649 +}
23650 +
23651 +int change_sig(int signal, int on)
23652 +{
23653 +       sigset_t sigset, old;
23654 +
23655 +       sigemptyset(&sigset);
23656 +       sigaddset(&sigset, signal);
23657 +       sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
23658 +       return(!sigismember(&old, signal));
23659 +}
23660 +
23661 +static void change_signals(int type)
23662 +{
23663 +       sigset_t mask;
23664 +
23665 +       sigemptyset(&mask);
23666 +       sigaddset(&mask, SIGVTALRM);
23667 +       sigaddset(&mask, SIGALRM);
23668 +       sigaddset(&mask, SIGIO);
23669 +       sigaddset(&mask, SIGPROF);
23670 +       if(sigprocmask(type, &mask, NULL) < 0)
23671 +               panic("Failed to change signal mask - errno = %d", errno);
23672 +}
23673 +
23674 +void block_signals(void)
23675 +{
23676 +       change_signals(SIG_BLOCK);
23677 +}
23678 +
23679 +void unblock_signals(void)
23680 +{
23681 +       change_signals(SIG_UNBLOCK);
23682 +}
23683 +
23684 +#define SIGIO_BIT 0
23685 +#define SIGVTALRM_BIT 1
23686 +
23687 +static int enable_mask(sigset_t *mask)
23688 +{
23689 +       int sigs;
23690 +
23691 +       sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
23692 +       sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
23693 +       sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
23694 +       return(sigs);
23695 +}
23696 +
23697 +int get_signals(void)
23698 +{
23699 +       sigset_t mask;
23700 +       
23701 +       if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
23702 +               panic("Failed to get signal mask");
23703 +       return(enable_mask(&mask));
23704 +}
23705 +
23706 +int set_signals(int enable)
23707 +{
23708 +       sigset_t mask;
23709 +       int ret;
23710 +
23711 +       sigemptyset(&mask);
23712 +       if(enable & (1 << SIGIO_BIT)) 
23713 +               sigaddset(&mask, SIGIO);
23714 +       if(enable & (1 << SIGVTALRM_BIT)){
23715 +               sigaddset(&mask, SIGVTALRM);
23716 +               sigaddset(&mask, SIGALRM);
23717 +       }
23718 +       if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
23719 +               panic("Failed to enable signals");
23720 +       ret = enable_mask(&mask);
23721 +       sigemptyset(&mask);
23722 +       if((enable & (1 << SIGIO_BIT)) == 0) 
23723 +               sigaddset(&mask, SIGIO);
23724 +       if((enable & (1 << SIGVTALRM_BIT)) == 0){
23725 +               sigaddset(&mask, SIGVTALRM);
23726 +               sigaddset(&mask, SIGALRM);
23727 +       }
23728 +       if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
23729 +               panic("Failed to block signals");
23730 +
23731 +       return(ret);
23732 +}
23733 +
23734 +/*
23735 + * Overrides for Emacs so that we follow Linus's tabbing style.
23736 + * Emacs will notice this stuff at the end of the file and automatically
23737 + * adjust the settings for this buffer only.  This must remain at the end
23738 + * of the file.
23739 + * ---------------------------------------------------------------------------
23740 + * Local variables:
23741 + * c-file-style: "linux"
23742 + * End:
23743 + */
23744 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_kern.c um/arch/um/kernel/skas/exec_kern.c
23745 --- orig/arch/um/kernel/skas/exec_kern.c        1969-12-31 19:00:00.000000000 -0500
23746 +++ um/arch/um/kernel/skas/exec_kern.c  2003-10-21 03:26:07.000000000 -0400
23747 @@ -0,0 +1,41 @@
23748 +/* 
23749 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23750 + * Licensed under the GPL
23751 + */
23752 +
23753 +#include "linux/kernel.h"
23754 +#include "asm/current.h"
23755 +#include "asm/page.h"
23756 +#include "asm/signal.h"
23757 +#include "asm/ptrace.h"
23758 +#include "asm/uaccess.h"
23759 +#include "asm/mmu_context.h"
23760 +#include "tlb.h"
23761 +#include "skas.h"
23762 +#include "mmu.h"
23763 +#include "os.h"
23764 +
23765 +void flush_thread_skas(void)
23766 +{
23767 +       force_flush_all();
23768 +       switch_mm_skas(current->mm->context.skas.mm_fd);
23769 +}
23770 +
23771 +void start_thread_skas(struct pt_regs *regs, unsigned long eip, 
23772 +                      unsigned long esp)
23773 +{
23774 +       set_fs(USER_DS);
23775 +        PT_REGS_IP(regs) = eip;
23776 +       PT_REGS_SP(regs) = esp;
23777 +}
23778 +
23779 +/*
23780 + * Overrides for Emacs so that we follow Linus's tabbing style.
23781 + * Emacs will notice this stuff at the end of the file and automatically
23782 + * adjust the settings for this buffer only.  This must remain at the end
23783 + * of the file.
23784 + * ---------------------------------------------------------------------------
23785 + * Local variables:
23786 + * c-file-style: "linux"
23787 + * End:
23788 + */
23789 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_user.c um/arch/um/kernel/skas/exec_user.c
23790 --- orig/arch/um/kernel/skas/exec_user.c        1969-12-31 19:00:00.000000000 -0500
23791 +++ um/arch/um/kernel/skas/exec_user.c  2003-10-21 03:26:07.000000000 -0400
23792 @@ -0,0 +1,61 @@
23793 +/* 
23794 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23795 + * Licensed under the GPL
23796 + */
23797 +
23798 +#include <stdlib.h>
23799 +#include <errno.h>
23800 +#include <signal.h>
23801 +#include <sched.h>
23802 +#include <sys/wait.h>
23803 +#include <sys/ptrace.h>
23804 +#include "user.h"
23805 +#include "kern_util.h"
23806 +#include "os.h"
23807 +#include "time_user.h"
23808 +
23809 +static int user_thread_tramp(void *arg)
23810 +{
23811 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
23812 +               panic("user_thread_tramp - PTRACE_TRACEME failed, "
23813 +                     "errno = %d\n", errno);
23814 +       enable_timer();
23815 +       os_stop_process(os_getpid());
23816 +       return(0);
23817 +}
23818 +
23819 +int user_thread(unsigned long stack, int flags)
23820 +{
23821 +       int pid, status;
23822 +
23823 +       pid = clone(user_thread_tramp, (void *) stack_sp(stack), 
23824 +                   flags | CLONE_FILES | SIGCHLD, NULL);
23825 +       if(pid < 0){
23826 +               printk("user_thread - clone failed, errno = %d\n", errno);
23827 +               return(pid);
23828 +       }
23829 +
23830 +       if(waitpid(pid, &status, WUNTRACED) < 0){
23831 +               printk("user_thread - waitpid failed, errno = %d\n", errno);
23832 +               return(-errno);
23833 +       }
23834 +
23835 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
23836 +               printk("user_thread - trampoline didn't stop, status = %d\n", 
23837 +                      status);
23838 +               return(-EINVAL);
23839 +       }
23840 +
23841 +       return(pid);
23842 +}
23843 +
23844 +/*
23845 + * Overrides for Emacs so that we follow Linus's tabbing style.
23846 + * Emacs will notice this stuff at the end of the file and automatically
23847 + * adjust the settings for this buffer only.  This must remain at the end
23848 + * of the file.
23849 + * ---------------------------------------------------------------------------
23850 + * Local variables:
23851 + * c-file-style: "linux"
23852 + * End:
23853 + */
23854 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mmu.h um/arch/um/kernel/skas/include/mmu.h
23855 --- orig/arch/um/kernel/skas/include/mmu.h      1969-12-31 19:00:00.000000000 -0500
23856 +++ um/arch/um/kernel/skas/include/mmu.h        2003-10-21 03:26:07.000000000 -0400
23857 @@ -0,0 +1,27 @@
23858 +/* 
23859 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23860 + * Licensed under the GPL
23861 + */
23862 +
23863 +#ifndef __SKAS_MMU_H
23864 +#define __SKAS_MMU_H
23865 +
23866 +#include "linux/list.h"
23867 +#include "linux/spinlock.h"
23868 +
23869 +struct mmu_context_skas {
23870 +       int mm_fd;
23871 +};
23872 +
23873 +#endif
23874 +
23875 +/*
23876 + * Overrides for Emacs so that we follow Linus's tabbing style.
23877 + * Emacs will notice this stuff at the end of the file and automatically
23878 + * adjust the settings for this buffer only.  This must remain at the end
23879 + * of the file.
23880 + * ---------------------------------------------------------------------------
23881 + * Local variables:
23882 + * c-file-style: "linux"
23883 + * End:
23884 + */
23885 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode.h um/arch/um/kernel/skas/include/mode.h
23886 --- orig/arch/um/kernel/skas/include/mode.h     1969-12-31 19:00:00.000000000 -0500
23887 +++ um/arch/um/kernel/skas/include/mode.h       2003-11-19 03:27:36.000000000 -0500
23888 @@ -0,0 +1,37 @@
23889 +/* 
23890 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23891 + * Licensed under the GPL
23892 + */
23893 +
23894 +#ifndef __MODE_SKAS_H__
23895 +#define __MODE_SKAS_H__
23896 +
23897 +extern unsigned long exec_regs[];
23898 +extern unsigned long exec_fp_regs[];
23899 +extern unsigned long exec_fpx_regs[];
23900 +extern int have_fpx_regs;
23901 +
23902 +extern void user_time_init_skas(void);
23903 +extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, 
23904 +                                 void *from_ptr);
23905 +extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, 
23906 +                               union uml_pt_regs *regs, 
23907 +                               unsigned long fault_addr, int fault_type);
23908 +extern void sig_handler_common_skas(int sig, void *sc_ptr);
23909 +extern void halt_skas(void);
23910 +extern void reboot_skas(void);
23911 +extern void kill_off_processes_skas(void);
23912 +extern int is_skas_winch(int pid, int fd, void *data);
23913 +
23914 +#endif
23915 +
23916 +/*
23917 + * Overrides for Emacs so that we follow Linus's tabbing style.
23918 + * Emacs will notice this stuff at the end of the file and automatically
23919 + * adjust the settings for this buffer only.  This must remain at the end
23920 + * of the file.
23921 + * ---------------------------------------------------------------------------
23922 + * Local variables:
23923 + * c-file-style: "linux"
23924 + * End:
23925 + */
23926 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode_kern.h um/arch/um/kernel/skas/include/mode_kern.h
23927 --- orig/arch/um/kernel/skas/include/mode_kern.h        1969-12-31 19:00:00.000000000 -0500
23928 +++ um/arch/um/kernel/skas/include/mode_kern.h  2003-10-21 03:26:07.000000000 -0400
23929 @@ -0,0 +1,51 @@
23930 +/* 
23931 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23932 + * Licensed under the GPL
23933 + */
23934 +
23935 +#ifndef __SKAS_MODE_KERN_H__
23936 +#define __SKAS_MODE_KERN_H__
23937 +
23938 +#include "linux/sched.h"
23939 +#include "asm/page.h"
23940 +#include "asm/ptrace.h"
23941 +
23942 +extern void flush_thread_skas(void);
23943 +extern void *_switch_to_skas(void *prev, void *next);
23944 +extern void start_thread_skas(struct pt_regs *regs, unsigned long eip, 
23945 +                             unsigned long esp);
23946 +extern int copy_thread_skas(int nr, unsigned long clone_flags, 
23947 +                           unsigned long sp, unsigned long stack_top, 
23948 +                           struct task_struct *p, struct pt_regs *regs);
23949 +extern void release_thread_skas(struct task_struct *task);
23950 +extern void exit_thread_skas(void);
23951 +extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
23952 +extern void init_idle_skas(void);
23953 +extern void flush_tlb_kernel_vm_skas(void);
23954 +extern void __flush_tlb_one_skas(unsigned long addr);
23955 +extern void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start, 
23956 +                                unsigned long end);
23957 +extern void flush_tlb_mm_skas(struct mm_struct *mm);
23958 +extern void force_flush_all_skas(void);
23959 +extern long execute_syscall_skas(void *r);
23960 +extern void before_mem_skas(unsigned long unused);
23961 +extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
23962 +                                        unsigned long *task_size_out);
23963 +extern int start_uml_skas(void);
23964 +extern int external_pid_skas(struct task_struct *task);
23965 +extern int thread_pid_skas(struct thread_struct *thread);
23966 +
23967 +#define kmem_end_skas (host_task_size - 1024 * 1024)
23968 +
23969 +#endif
23970 +
23971 +/*
23972 + * Overrides for Emacs so that we follow Linus's tabbing style.
23973 + * Emacs will notice this stuff at the end of the file and automatically
23974 + * adjust the settings for this buffer only.  This must remain at the end
23975 + * of the file.
23976 + * ---------------------------------------------------------------------------
23977 + * Local variables:
23978 + * c-file-style: "linux"
23979 + * End:
23980 + */
23981 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/proc_mm.h um/arch/um/kernel/skas/include/proc_mm.h
23982 --- orig/arch/um/kernel/skas/include/proc_mm.h  1969-12-31 19:00:00.000000000 -0500
23983 +++ um/arch/um/kernel/skas/include/proc_mm.h    2003-10-21 03:26:07.000000000 -0400
23984 @@ -0,0 +1,55 @@
23985 +/* 
23986 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23987 + * Licensed under the GPL
23988 + */
23989 +
23990 +#ifndef __SKAS_PROC_MM_H
23991 +#define __SKAS_PROC_MM_H
23992 +
23993 +#define MM_MMAP 54
23994 +#define MM_MUNMAP 55
23995 +#define MM_MPROTECT 56
23996 +#define MM_COPY_SEGMENTS 57
23997 +
23998 +struct mm_mmap {
23999 +       unsigned long addr;
24000 +       unsigned long len;
24001 +       unsigned long prot;
24002 +       unsigned long flags;
24003 +       unsigned long fd;
24004 +       unsigned long offset;
24005 +};
24006 +
24007 +struct mm_munmap {
24008 +       unsigned long addr;
24009 +       unsigned long len;      
24010 +};
24011 +
24012 +struct mm_mprotect {
24013 +       unsigned long addr;
24014 +       unsigned long len;
24015 +        unsigned int prot;
24016 +};
24017 +
24018 +struct proc_mm_op {
24019 +       int op;
24020 +       union {
24021 +               struct mm_mmap mmap;
24022 +               struct mm_munmap munmap;
24023 +               struct mm_mprotect mprotect;
24024 +               int copy_segments;
24025 +       } u;
24026 +};
24027 +
24028 +#endif
24029 +
24030 +/*
24031 + * Overrides for Emacs so that we follow Linus's tabbing style.
24032 + * Emacs will notice this stuff at the end of the file and automatically
24033 + * adjust the settings for this buffer only.  This must remain at the end
24034 + * of the file.
24035 + * ---------------------------------------------------------------------------
24036 + * Local variables:
24037 + * c-file-style: "linux"
24038 + * End:
24039 + */
24040 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/ptrace-skas.h um/arch/um/kernel/skas/include/ptrace-skas.h
24041 --- orig/arch/um/kernel/skas/include/ptrace-skas.h      1969-12-31 19:00:00.000000000 -0500
24042 +++ um/arch/um/kernel/skas/include/ptrace-skas.h        2003-10-21 03:26:07.000000000 -0400
24043 @@ -0,0 +1,57 @@
24044 +/* 
24045 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24046 + * Licensed under the GPL
24047 + */
24048 +
24049 +#ifndef __PTRACE_SKAS_H
24050 +#define __PTRACE_SKAS_H
24051 +
24052 +#include "uml-config.h"
24053 +
24054 +#ifdef UML_CONFIG_MODE_SKAS
24055 +
24056 +#include "skas_ptregs.h"
24057 +
24058 +#define HOST_FRAME_SIZE 17
24059 +
24060 +#define REGS_IP(r) ((r)[HOST_IP])
24061 +#define REGS_SP(r) ((r)[HOST_SP])
24062 +#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
24063 +#define REGS_EAX(r) ((r)[HOST_EAX])
24064 +#define REGS_EBX(r) ((r)[HOST_EBX])
24065 +#define REGS_ECX(r) ((r)[HOST_ECX])
24066 +#define REGS_EDX(r) ((r)[HOST_EDX])
24067 +#define REGS_ESI(r) ((r)[HOST_ESI])
24068 +#define REGS_EDI(r) ((r)[HOST_EDI])
24069 +#define REGS_EBP(r) ((r)[HOST_EBP])
24070 +#define REGS_CS(r) ((r)[HOST_CS])
24071 +#define REGS_SS(r) ((r)[HOST_SS])
24072 +#define REGS_DS(r) ((r)[HOST_DS])
24073 +#define REGS_ES(r) ((r)[HOST_ES])
24074 +#define REGS_FS(r) ((r)[HOST_FS])
24075 +#define REGS_GS(r) ((r)[HOST_GS])
24076 +
24077 +#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res)
24078 +
24079 +#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
24080 +
24081 +#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
24082 +
24083 +#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
24084 +
24085 +#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
24086 +
24087 +#endif
24088 +
24089 +#endif
24090 +
24091 +/*
24092 + * Overrides for Emacs so that we follow Linus's tabbing style.
24093 + * Emacs will notice this stuff at the end of the file and automatically
24094 + * adjust the settings for this buffer only.  This must remain at the end
24095 + * of the file.
24096 + * ---------------------------------------------------------------------------
24097 + * Local variables:
24098 + * c-file-style: "linux"
24099 + * End:
24100 + */
24101 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/skas.h um/arch/um/kernel/skas/include/skas.h
24102 --- orig/arch/um/kernel/skas/include/skas.h     1969-12-31 19:00:00.000000000 -0500
24103 +++ um/arch/um/kernel/skas/include/skas.h       2003-11-19 03:00:51.000000000 -0500
24104 @@ -0,0 +1,49 @@
24105 +/* 
24106 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24107 + * Licensed under the GPL
24108 + */
24109 +
24110 +#ifndef __SKAS_H
24111 +#define __SKAS_H
24112 +
24113 +#include "sysdep/ptrace.h"
24114 +
24115 +extern int userspace_pid[];
24116 +
24117 +extern void switch_threads(void *me, void *next);
24118 +extern void thread_wait(void *sw, void *fb);
24119 +extern void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
24120 +                       void (*handler)(int));
24121 +extern int start_idle_thread(void *stack, void *switch_buf_ptr, 
24122 +                            void **fork_buf_ptr);
24123 +extern int user_thread(unsigned long stack, int flags);
24124 +extern void userspace(union uml_pt_regs *regs);
24125 +extern void new_thread_proc(void *stack, void (*handler)(int sig));
24126 +extern void remove_sigstack(void);
24127 +extern void new_thread_handler(int sig);
24128 +extern void handle_syscall(union uml_pt_regs *regs);
24129 +extern void map(int fd, unsigned long virt, unsigned long phys, 
24130 +               unsigned long len, int r, int w, int x);
24131 +extern int unmap(int fd, void *addr, int len);
24132 +extern int protect(int fd, unsigned long addr, unsigned long len, 
24133 +                  int r, int w, int x, int must_succeed);
24134 +extern void user_signal(int sig, union uml_pt_regs *regs);
24135 +extern int singlestepping_skas(void);
24136 +extern int new_mm(int from);
24137 +extern void save_registers(union uml_pt_regs *regs);
24138 +extern void restore_registers(union uml_pt_regs *regs);
24139 +extern void start_userspace(int cpu);
24140 +extern void init_registers(int pid);
24141 +
24142 +#endif
24143 +
24144 +/*
24145 + * Overrides for Emacs so that we follow Linus's tabbing style.
24146 + * Emacs will notice this stuff at the end of the file and automatically
24147 + * adjust the settings for this buffer only.  This must remain at the end
24148 + * of the file.
24149 + * ---------------------------------------------------------------------------
24150 + * Local variables:
24151 + * c-file-style: "linux"
24152 + * End:
24153 + */
24154 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/uaccess.h um/arch/um/kernel/skas/include/uaccess.h
24155 --- orig/arch/um/kernel/skas/include/uaccess.h  1969-12-31 19:00:00.000000000 -0500
24156 +++ um/arch/um/kernel/skas/include/uaccess.h    2004-01-17 06:35:41.000000000 -0500
24157 @@ -0,0 +1,40 @@
24158 +/* 
24159 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24160 + * Licensed under the GPL
24161 + */
24162 +
24163 +#ifndef __SKAS_UACCESS_H
24164 +#define __SKAS_UACCESS_H
24165 +
24166 +#include "asm/errno.h"
24167 +
24168 +#define access_ok_skas(type, addr, size) \
24169 +       ((segment_eq(get_fs(), KERNEL_DS)) || \
24170 +        (((unsigned long) (addr) < TASK_SIZE) && \
24171 +         ((unsigned long) (addr) + (size) <= TASK_SIZE)))
24172 +
24173 +static inline int verify_area_skas(int type, const void * addr, 
24174 +                                  unsigned long size)
24175 +{
24176 +       return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
24177 +}
24178 +
24179 +extern int copy_from_user_skas(void *to, const void *from, int n);
24180 +extern int copy_to_user_skas(void *to, const void *from, int n);
24181 +extern int strncpy_from_user_skas(char *dst, const char *src, int count);
24182 +extern int __clear_user_skas(void *mem, int len);
24183 +extern int clear_user_skas(void *mem, int len);
24184 +extern int strnlen_user_skas(const void *str, int len);
24185 +
24186 +#endif
24187 +
24188 +/*
24189 + * Overrides for Emacs so that we follow Linus's tabbing style.
24190 + * Emacs will notice this stuff at the end of the file and automatically
24191 + * adjust the settings for this buffer only.  This must remain at the end
24192 + * of the file.
24193 + * ---------------------------------------------------------------------------
24194 + * Local variables:
24195 + * c-file-style: "linux"
24196 + * End:
24197 + */
24198 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/Makefile um/arch/um/kernel/skas/Makefile
24199 --- orig/arch/um/kernel/skas/Makefile   1969-12-31 19:00:00.000000000 -0500
24200 +++ um/arch/um/kernel/skas/Makefile     2003-11-11 06:36:12.000000000 -0500
24201 @@ -0,0 +1,31 @@
24202 +# 
24203 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24204 +# Licensed under the GPL
24205 +#
24206 +
24207 +O_TARGET = skas.o
24208 +
24209 +obj-y = exec_kern.o exec_user.o mem.o mem_user.o mmu.o process.o \
24210 +       process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
24211 +       uaccess.o
24212 +
24213 +subdir-y = sys-$(SUBARCH)
24214 +
24215 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
24216 +
24217 +USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
24218 +
24219 +include $(TOPDIR)/Rules.make
24220 +
24221 +include/skas_ptregs.h : util/mk_ptregs
24222 +       util/mk_ptregs > $@
24223 +
24224 +util/mk_ptregs :
24225 +       $(MAKE) -C util
24226 +
24227 +$(USER_OBJS) : %.o: %.c
24228 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
24229 +
24230 +clean :
24231 +       $(MAKE) -C util clean
24232 +       $(RM) -f include/skas_ptregs.h
24233 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mem.c um/arch/um/kernel/skas/mem.c
24234 --- orig/arch/um/kernel/skas/mem.c      1969-12-31 19:00:00.000000000 -0500
24235 +++ um/arch/um/kernel/skas/mem.c        2003-10-21 03:26:07.000000000 -0400
24236 @@ -0,0 +1,30 @@
24237 +/* 
24238 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24239 + * Licensed under the GPL
24240 + */
24241 +
24242 +#include "linux/config.h"
24243 +#include "linux/mm.h"
24244 +#include "mem_user.h"
24245 +
24246 +unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, 
24247 +                                 unsigned long *task_size_out)
24248 +{
24249 +       /* Round up to the nearest 4M */
24250 +       unsigned long top = ROUND_4M((unsigned long) &arg);
24251 +
24252 +       *host_size_out = top;
24253 +       *task_size_out = top;
24254 +       return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
24255 +}
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/mem_user.c um/arch/um/kernel/skas/mem_user.c
24268 --- orig/arch/um/kernel/skas/mem_user.c 1969-12-31 19:00:00.000000000 -0500
24269 +++ um/arch/um/kernel/skas/mem_user.c   2003-10-21 03:26:07.000000000 -0400
24270 @@ -0,0 +1,105 @@
24271 +/* 
24272 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24273 + * Licensed under the GPL
24274 + */
24275 +
24276 +#include <errno.h>
24277 +#include <sys/mman.h>
24278 +#include <sys/ptrace.h>
24279 +#include "mem_user.h"
24280 +#include "mem.h"
24281 +#include "user.h"
24282 +#include "os.h"
24283 +#include "proc_mm.h"
24284 +
24285 +void map(int fd, unsigned long virt, unsigned long phys, unsigned long len, 
24286 +        int r, int w, int x)
24287 +{
24288 +       struct proc_mm_op map;
24289 +       __u64 offset;
24290 +       int prot, n, phys_fd;
24291 +
24292 +       prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
24293 +               (x ? PROT_EXEC : 0);
24294 +       phys_fd = phys_mapping(phys, &offset);
24295 +
24296 +       map = ((struct proc_mm_op) { .op        = MM_MMAP,
24297 +                                    .u         = 
24298 +                                    { .mmap    = 
24299 +                                      { .addr          = virt,
24300 +                                        .len           = len,
24301 +                                        .prot          = prot,
24302 +                                        .flags         = MAP_SHARED | 
24303 +                                                         MAP_FIXED,
24304 +                                        .fd            = phys_fd,
24305 +                                        .offset        = offset
24306 +                                      } } } );
24307 +       n = os_write_file(fd, &map, sizeof(map));
24308 +       if(n != sizeof(map)) 
24309 +               printk("map : /proc/mm map failed, err = %d\n", -n);
24310 +}
24311 +
24312 +int unmap(int fd, void *addr, int len)
24313 +{
24314 +       struct proc_mm_op unmap;
24315 +       int n;
24316 +
24317 +       unmap = ((struct proc_mm_op) { .op      = MM_MUNMAP,
24318 +                                      .u       = 
24319 +                                      { .munmap        = 
24320 +                                        { .addr        = (unsigned long) addr,
24321 +                                          .len         = len } } } );
24322 +       n = os_write_file(fd, &unmap, sizeof(unmap));
24323 +       if(n != sizeof(unmap)) {
24324 +               if(n < 0) 
24325 +                       return(n);
24326 +               else if(n > 0) 
24327 +                       return(-EIO);
24328 +       }
24329 +
24330 +       return(0);
24331 +}
24332 +
24333 +int protect(int fd, unsigned long addr, unsigned long len, int r, int w, 
24334 +           int x, int must_succeed)
24335 +{
24336 +       struct proc_mm_op protect;
24337 +       int prot, n;
24338 +
24339 +       prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
24340 +               (x ? PROT_EXEC : 0);
24341 +
24342 +       protect = ((struct proc_mm_op) { .op    = MM_MPROTECT,
24343 +                                      .u       = 
24344 +                                      { .mprotect      = 
24345 +                                        { .addr        = (unsigned long) addr,
24346 +                                          .len         = len,
24347 +                                          .prot        = prot } } } );
24348 +
24349 +       n = os_write_file(fd, &protect, sizeof(protect));
24350 +       if(n != sizeof(protect)) {
24351 +               if(n == 0) return(0);
24352 +
24353 +               if(must_succeed)
24354 +                       panic("protect failed, err = %d", -n);
24355 +
24356 +               return(-EIO);
24357 +       }
24358 +
24359 +       return(0);
24360 +}
24361 +
24362 +void before_mem_skas(unsigned long unused)
24363 +{
24364 +}
24365 +
24366 +/*
24367 + * Overrides for Emacs so that we follow Linus's tabbing style.
24368 + * Emacs will notice this stuff at the end of the file and automatically
24369 + * adjust the settings for this buffer only.  This must remain at the end
24370 + * of the file.
24371 + * ---------------------------------------------------------------------------
24372 + * Local variables:
24373 + * c-file-style: "linux"
24374 + * End:
24375 + */
24376 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mmu.c um/arch/um/kernel/skas/mmu.c
24377 --- orig/arch/um/kernel/skas/mmu.c      1969-12-31 19:00:00.000000000 -0500
24378 +++ um/arch/um/kernel/skas/mmu.c        2003-11-15 22:25:20.000000000 -0500
24379 @@ -0,0 +1,46 @@
24380 +/* 
24381 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24382 + * Licensed under the GPL
24383 + */
24384 +
24385 +#include "linux/list.h"
24386 +#include "linux/spinlock.h"
24387 +#include "linux/slab.h"
24388 +#include "asm/segment.h"
24389 +#include "asm/mmu.h"
24390 +#include "os.h"
24391 +#include "skas.h"
24392 +
24393 +int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
24394 +{
24395 +       int from;
24396 +
24397 +       if((current->mm != NULL) && (current->mm != &init_mm))
24398 +               from = current->mm->context.skas.mm_fd;
24399 +       else from = -1;
24400 +
24401 +       mm->context.skas.mm_fd = new_mm(from);
24402 +       if(mm->context.skas.mm_fd < 0){
24403 +               printk("init_new_context_skas - new_mm failed, errno = %d\n",
24404 +                      mm->context.skas.mm_fd);
24405 +               return(mm->context.skas.mm_fd);
24406 +       }
24407 +
24408 +       return(0);
24409 +}
24410 +
24411 +void destroy_context_skas(struct mm_struct *mm)
24412 +{
24413 +       os_close_file(mm->context.skas.mm_fd);
24414 +}
24415 +
24416 +/*
24417 + * Overrides for Emacs so that we follow Linus's tabbing style.
24418 + * Emacs will notice this stuff at the end of the file and automatically
24419 + * adjust the settings for this buffer only.  This must remain at the end
24420 + * of the file.
24421 + * ---------------------------------------------------------------------------
24422 + * Local variables:
24423 + * c-file-style: "linux"
24424 + * End:
24425 + */
24426 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process.c um/arch/um/kernel/skas/process.c
24427 --- orig/arch/um/kernel/skas/process.c  1969-12-31 19:00:00.000000000 -0500
24428 +++ um/arch/um/kernel/skas/process.c    2004-01-31 02:49:36.000000000 -0500
24429 @@ -0,0 +1,417 @@
24430 +/* 
24431 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24432 + * Licensed under the GPL
24433 + */
24434 +
24435 +#include <stdlib.h>
24436 +#include <unistd.h>
24437 +#include <errno.h>
24438 +#include <signal.h>
24439 +#include <setjmp.h>
24440 +#include <sched.h>
24441 +#include <sys/wait.h>
24442 +#include <sys/ptrace.h>
24443 +#include <sys/mman.h>
24444 +#include <sys/user.h>
24445 +#include <asm/unistd.h>
24446 +#include "user.h"
24447 +#include "ptrace_user.h"
24448 +#include "time_user.h"
24449 +#include "sysdep/ptrace.h"
24450 +#include "user_util.h"
24451 +#include "kern_util.h"
24452 +#include "skas.h"
24453 +#include "sysdep/sigcontext.h"
24454 +#include "os.h"
24455 +#include "proc_mm.h"
24456 +#include "skas_ptrace.h"
24457 +#include "chan_user.h"
24458 +
24459 +int is_skas_winch(int pid, int fd, void *data)
24460 +{
24461 +       if(pid != getpid())
24462 +               return(0);
24463 +
24464 +       register_winch_irq(-1, fd, -1, data);
24465 +       return(1);
24466 +}
24467 +
24468 +/* These are set once at boot time and not changed thereafter */
24469 +
24470 +unsigned long exec_regs[FRAME_SIZE];
24471 +unsigned long exec_fp_regs[HOST_FP_SIZE];
24472 +unsigned long exec_fpx_regs[HOST_XFP_SIZE];
24473 +int have_fpx_regs = 1;
24474 +
24475 +static void handle_segv(int pid)
24476 +{
24477 +       struct ptrace_faultinfo fault;
24478 +       int err;
24479 +
24480 +       err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault);
24481 +       if(err)
24482 +               panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n",
24483 +                     errno);
24484 +
24485 +       segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
24486 +}
24487 +
24488 +static void handle_trap(int pid, union uml_pt_regs *regs)
24489 +{
24490 +       int err, syscall_nr, status;
24491 +
24492 +       syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
24493 +       UPT_SYSCALL_NR(regs) = syscall_nr;
24494 +       if(syscall_nr < 1){
24495 +               relay_signal(SIGTRAP, regs);
24496 +               return;
24497 +       }
24498 +
24499 +       err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
24500 +       if(err < 0)
24501 +               panic("handle_trap - nullifying syscall failed errno = %d\n", 
24502 +                     errno);
24503 +
24504 +       err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
24505 +       if(err < 0)
24506 +               panic("handle_trap - continuing to end of syscall failed, "
24507 +                     "errno = %d\n", errno);
24508 +
24509 +       err = waitpid(pid, &status, WUNTRACED);
24510 +       if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
24511 +               panic("handle_trap - failed to wait at end of syscall, "
24512 +                     "errno = %d, status = %d\n", errno, status);
24513 +
24514 +       handle_syscall(regs);
24515 +}
24516 +
24517 +static int userspace_tramp(void *arg)
24518 +{
24519 +       init_new_thread_signals(0);
24520 +       enable_timer();
24521 +       ptrace(PTRACE_TRACEME, 0, 0, 0);
24522 +       os_stop_process(os_getpid());
24523 +       return(0);
24524 +}
24525 +
24526 +/* Each element set once, and only accessed by a single processor anyway */
24527 +#define NR_CPUS 1
24528 +int userspace_pid[NR_CPUS];
24529 +
24530 +void start_userspace(int cpu)
24531 +{
24532 +       void *stack;
24533 +       unsigned long sp;
24534 +       int pid, status, n;
24535 +
24536 +       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
24537 +                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
24538 +       if(stack == MAP_FAILED)
24539 +               panic("start_userspace : mmap failed, errno = %d", errno);
24540 +       sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
24541 +
24542 +       pid = clone(userspace_tramp, (void *) sp, 
24543 +                   CLONE_FILES | CLONE_VM | SIGCHLD, NULL);
24544 +       if(pid < 0)
24545 +               panic("start_userspace : clone failed, errno = %d", errno);
24546 +
24547 +       do {
24548 +               n = waitpid(pid, &status, WUNTRACED);
24549 +               if(n < 0)
24550 +                       panic("start_userspace : wait failed, errno = %d", 
24551 +                             errno);
24552 +       } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
24553 +
24554 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
24555 +               panic("start_userspace : expected SIGSTOP, got status = %d",
24556 +                     status);
24557 +
24558 +       if(munmap(stack, PAGE_SIZE) < 0)
24559 +               panic("start_userspace : munmap failed, errno = %d\n", errno);
24560 +
24561 +       userspace_pid[cpu] = pid;
24562 +}
24563 +
24564 +void userspace(union uml_pt_regs *regs)
24565 +{
24566 +       int err, status, op, pid = userspace_pid[0];
24567 +
24568 +       restore_registers(regs);
24569 +               
24570 +       err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
24571 +       if(err)
24572 +               panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", 
24573 +                      errno);
24574 +       while(1){
24575 +               err = waitpid(pid, &status, WUNTRACED);
24576 +               if(err < 0)
24577 +                       panic("userspace - waitpid failed, errno = %d\n", 
24578 +                             errno);
24579 +
24580 +               regs->skas.is_user = 1;
24581 +               save_registers(regs);
24582 +
24583 +               if(WIFSTOPPED(status)){
24584 +                       switch(WSTOPSIG(status)){
24585 +                       case SIGSEGV:
24586 +                               handle_segv(pid);
24587 +                               break;
24588 +                       case SIGTRAP:
24589 +                               handle_trap(pid, regs);
24590 +                               break;
24591 +                       case SIGIO:
24592 +                       case SIGVTALRM:
24593 +                       case SIGILL:
24594 +                       case SIGBUS:
24595 +                       case SIGFPE:
24596 +                       case SIGWINCH:
24597 +                               user_signal(WSTOPSIG(status), regs);
24598 +                               break;
24599 +                       default:
24600 +                               printk("userspace - child stopped with signal "
24601 +                                      "%d\n", WSTOPSIG(status));
24602 +                       }
24603 +                       interrupt_end();
24604 +               }
24605 +
24606 +               restore_registers(regs);
24607 +
24608 +               op = singlestepping_skas() ? PTRACE_SINGLESTEP : 
24609 +                       PTRACE_SYSCALL;
24610 +               err = ptrace(op, pid, 0, 0);
24611 +               if(err)
24612 +                       panic("userspace - PTRACE_SYSCALL failed, "
24613 +                             "errno = %d\n", errno);
24614 +       }
24615 +}
24616 +
24617 +void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
24618 +               void (*handler)(int))
24619 +{
24620 +       sigjmp_buf switch_buf, fork_buf;
24621 +
24622 +       *switch_buf_ptr = &switch_buf;
24623 +       *fork_buf_ptr = &fork_buf;
24624 +
24625 +       if(sigsetjmp(fork_buf, 1) == 0)
24626 +               new_thread_proc(stack, handler);
24627 +
24628 +       remove_sigstack();
24629 +}
24630 +
24631 +void thread_wait(void *sw, void *fb)
24632 +{
24633 +       sigjmp_buf buf, **switch_buf = sw, *fork_buf;
24634 +
24635 +       *switch_buf = &buf;
24636 +       fork_buf = fb;
24637 +       if(sigsetjmp(buf, 1) == 0)
24638 +               siglongjmp(*fork_buf, 1);
24639 +}
24640 +
24641 +static int move_registers(int pid, int int_op, int fp_op, 
24642 +                         union uml_pt_regs *regs, unsigned long *fp_regs)
24643 +{
24644 +       if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
24645 +               return(-errno);
24646 +       if(ptrace(fp_op, pid, 0, fp_regs) < 0)
24647 +               return(-errno);
24648 +       return(0);
24649 +}
24650 +
24651 +void save_registers(union uml_pt_regs *regs)
24652 +{
24653 +       unsigned long *fp_regs;
24654 +       int err, fp_op;
24655 +
24656 +       if(have_fpx_regs){
24657 +               fp_op = PTRACE_GETFPXREGS;
24658 +               fp_regs = regs->skas.xfp;
24659 +       }
24660 +       else {
24661 +               fp_op = PTRACE_GETFPREGS;
24662 +               fp_regs = regs->skas.fp;
24663 +       }
24664 +
24665 +       err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs, 
24666 +                            fp_regs);
24667 +       if(err)
24668 +               panic("save_registers - saving registers failed, errno = %d\n",
24669 +                     -err);
24670 +}
24671 +
24672 +void restore_registers(union uml_pt_regs *regs)
24673 +{
24674 +       unsigned long *fp_regs;
24675 +       int err, fp_op;
24676 +
24677 +       if(have_fpx_regs){
24678 +               fp_op = PTRACE_SETFPXREGS;
24679 +               fp_regs = regs->skas.xfp;
24680 +       }
24681 +       else {
24682 +               fp_op = PTRACE_SETFPREGS;
24683 +               fp_regs = regs->skas.fp;
24684 +       }
24685 +
24686 +       err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs, 
24687 +                            fp_regs);
24688 +       if(err)
24689 +               panic("restore_registers - saving registers failed, "
24690 +                     "errno = %d\n", -err);
24691 +}
24692 +
24693 +void switch_threads(void *me, void *next)
24694 +{
24695 +       sigjmp_buf my_buf, **me_ptr = me, *next_buf = next;
24696 +       
24697 +       *me_ptr = &my_buf;
24698 +       if(sigsetjmp(my_buf, 1) == 0)
24699 +               siglongjmp(*next_buf, 1);
24700 +}
24701 +
24702 +static sigjmp_buf initial_jmpbuf;
24703 +
24704 +/* XXX Make these percpu */
24705 +static void (*cb_proc)(void *arg);
24706 +static void *cb_arg;
24707 +static sigjmp_buf *cb_back;
24708 +
24709 +int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
24710 +{
24711 +       sigjmp_buf **switch_buf = switch_buf_ptr;
24712 +       int n;
24713 +
24714 +       *fork_buf_ptr = &initial_jmpbuf;
24715 +       n = sigsetjmp(initial_jmpbuf, 1);
24716 +       if(n == 0)
24717 +               new_thread_proc((void *) stack, new_thread_handler);
24718 +       else if(n == 1)
24719 +               remove_sigstack();
24720 +       else if(n == 2){
24721 +               (*cb_proc)(cb_arg);
24722 +               siglongjmp(*cb_back, 1);
24723 +       }
24724 +       else if(n == 3){
24725 +               kmalloc_ok = 0;
24726 +               return(0);
24727 +       }
24728 +       else if(n == 4){
24729 +               kmalloc_ok = 0;
24730 +               return(1);
24731 +       }
24732 +       siglongjmp(**switch_buf, 1);
24733 +}
24734 +
24735 +void remove_sigstack(void)
24736 +{
24737 +       stack_t stack = ((stack_t) { .ss_flags  = SS_DISABLE,
24738 +                                    .ss_sp     = NULL,
24739 +                                    .ss_size   = 0 });
24740 +
24741 +       if(sigaltstack(&stack, NULL) != 0)
24742 +               panic("disabling signal stack failed, errno = %d\n", errno);
24743 +}
24744 +
24745 +void initial_thread_cb_skas(void (*proc)(void *), void *arg)
24746 +{
24747 +       sigjmp_buf here;
24748 +
24749 +       cb_proc = proc;
24750 +       cb_arg = arg;
24751 +       cb_back = &here;
24752 +
24753 +       block_signals();
24754 +       if(sigsetjmp(here, 1) == 0)
24755 +               siglongjmp(initial_jmpbuf, 2);
24756 +       unblock_signals();
24757 +
24758 +       cb_proc = NULL;
24759 +       cb_arg = NULL;
24760 +       cb_back = NULL;
24761 +}
24762 +
24763 +void halt_skas(void)
24764 +{
24765 +       block_signals();
24766 +       siglongjmp(initial_jmpbuf, 3);
24767 +}
24768 +
24769 +void reboot_skas(void)
24770 +{
24771 +       block_signals();
24772 +       siglongjmp(initial_jmpbuf, 4);
24773 +}
24774 +
24775 +int new_mm(int from)
24776 +{
24777 +       struct proc_mm_op copy;
24778 +       int n, fd = os_open_file("/proc/mm", 
24779 +                                of_cloexec(of_write(OPENFLAGS())), 0);
24780 +
24781 +       if(fd < 0)
24782 +               return(fd);
24783 +
24784 +       if(from != -1){
24785 +               copy = ((struct proc_mm_op) { .op       = MM_COPY_SEGMENTS,
24786 +                                             .u        = 
24787 +                                             { .copy_segments  = from } } );
24788 +               n = os_write_file(fd, &copy, sizeof(copy));
24789 +               if(n != sizeof(copy)) 
24790 +                       printk("new_mm : /proc/mm copy_segments failed, "
24791 +                              "err = %d\n", -n);
24792 +       }
24793 +
24794 +       return(fd);
24795 +}
24796 +
24797 +void switch_mm_skas(int mm_fd)
24798 +{
24799 +       int err;
24800 +
24801 +#warning need cpu pid in switch_mm_skas
24802 +       err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd);
24803 +       if(err)
24804 +               panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
24805 +                     errno);
24806 +}
24807 +
24808 +void kill_off_processes_skas(void)
24809 +{
24810 +#warning need to loop over userspace_pids in kill_off_processes_skas
24811 +       os_kill_process(userspace_pid[0], 1);
24812 +}
24813 +
24814 +void init_registers(int pid)
24815 +{
24816 +       int err;
24817 +
24818 +       if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0)
24819 +               panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", 
24820 +                     errno);
24821 +
24822 +       err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
24823 +       if(!err)
24824 +               return;
24825 +
24826 +       have_fpx_regs = 0;
24827 +       if(errno != EIO)
24828 +               panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", 
24829 +                     errno);
24830 +
24831 +       err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
24832 +       if(err)
24833 +               panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", 
24834 +                     errno);
24835 +}
24836 +
24837 +/*
24838 + * Overrides for Emacs so that we follow Linus's tabbing style.
24839 + * Emacs will notice this stuff at the end of the file and automatically
24840 + * adjust the settings for this buffer only.  This must remain at the end
24841 + * of the file.
24842 + * ---------------------------------------------------------------------------
24843 + * Local variables:
24844 + * c-file-style: "linux"
24845 + * End:
24846 + */
24847 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process_kern.c um/arch/um/kernel/skas/process_kern.c
24848 --- orig/arch/um/kernel/skas/process_kern.c     1969-12-31 19:00:00.000000000 -0500
24849 +++ um/arch/um/kernel/skas/process_kern.c       2003-11-19 03:18:25.000000000 -0500
24850 @@ -0,0 +1,196 @@
24851 +/* 
24852 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24853 + * Licensed under the GPL
24854 + */
24855 +
24856 +#include "linux/sched.h"
24857 +#include "linux/slab.h"
24858 +#include "kern_util.h"
24859 +#include "time_user.h"
24860 +#include "signal_user.h"
24861 +#include "skas.h"
24862 +#include "os.h"
24863 +#include "user_util.h"
24864 +#include "tlb.h"
24865 +#include "frame.h"
24866 +#include "kern.h"
24867 +#include "mode.h"
24868 +
24869 +int singlestepping_skas(void)
24870 +{
24871 +       int ret = current->ptrace & PT_DTRACE;
24872 +
24873 +       current->ptrace &= ~PT_DTRACE;
24874 +       return(ret);
24875 +}
24876 +
24877 +void *_switch_to_skas(void *prev, void *next)
24878 +{
24879 +       struct task_struct *from, *to;
24880 +
24881 +       from = prev;
24882 +       to = next;
24883 +
24884 +       /* XXX need to check runqueues[cpu].idle */
24885 +       if(current->pid == 0)
24886 +               switch_timers(0);
24887 +
24888 +       to->thread.prev_sched = from;
24889 +       set_current(to);
24890 +
24891 +       switch_threads(&from->thread.mode.skas.switch_buf, 
24892 +                      to->thread.mode.skas.switch_buf);
24893 +
24894 +       if(current->pid == 0)
24895 +               switch_timers(1);
24896 +
24897 +       return(current->thread.prev_sched);
24898 +}
24899 +
24900 +extern void schedule_tail(struct task_struct *prev);
24901 +
24902 +void new_thread_handler(int sig)
24903 +{
24904 +       int (*fn)(void *), n;
24905 +       void *arg;
24906 +
24907 +       fn = current->thread.request.u.thread.proc;
24908 +       arg = current->thread.request.u.thread.arg;
24909 +       change_sig(SIGUSR1, 1);
24910 +       thread_wait(&current->thread.mode.skas.switch_buf, 
24911 +                   current->thread.mode.skas.fork_buf);
24912 +
24913 +       if(current->thread.prev_sched != NULL)
24914 +               schedule_tail(current->thread.prev_sched);
24915 +       current->thread.prev_sched = NULL;
24916 +
24917 +       /* The return value is 1 if the kernel thread execs a process,
24918 +        * 0 if it just exits
24919 +        */
24920 +       n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
24921 +       if(n == 1)
24922 +               userspace(&current->thread.regs.regs);
24923 +       else do_exit(0);
24924 +}
24925 +
24926 +void new_thread_proc(void *stack, void (*handler)(int sig))
24927 +{
24928 +       init_new_thread_stack(stack, handler);
24929 +       os_usr1_process(os_getpid());
24930 +}
24931 +
24932 +void release_thread_skas(struct task_struct *task)
24933 +{
24934 +}
24935 +
24936 +void exit_thread_skas(void)
24937 +{
24938 +}
24939 +
24940 +void fork_handler(int sig)
24941 +{
24942 +        change_sig(SIGUSR1, 1);
24943 +       thread_wait(&current->thread.mode.skas.switch_buf, 
24944 +                   current->thread.mode.skas.fork_buf);
24945 +       
24946 +       force_flush_all();
24947 +       if(current->thread.prev_sched != NULL)
24948 +               schedule_tail(current->thread.prev_sched);
24949 +       current->thread.prev_sched = NULL;
24950 +       unblock_signals();
24951 +
24952 +       userspace(&current->thread.regs.regs);
24953 +}
24954 +
24955 +int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
24956 +                    unsigned long stack_top, struct task_struct * p, 
24957 +                    struct pt_regs *regs)
24958 +{
24959 +       void (*handler)(int);
24960 +
24961 +       if(current->thread.forking){
24962 +               memcpy(&p->thread.regs.regs.skas, 
24963 +                      &current->thread.regs.regs.skas, 
24964 +                      sizeof(p->thread.regs.regs.skas));
24965 +               REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
24966 +               if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
24967 +
24968 +               handler = fork_handler;
24969 +       }
24970 +       else {
24971 +               memcpy(p->thread.regs.regs.skas.regs, exec_regs, 
24972 +                      sizeof(p->thread.regs.regs.skas.regs));
24973 +               memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs, 
24974 +                      sizeof(p->thread.regs.regs.skas.fp));
24975 +               memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs, 
24976 +                      sizeof(p->thread.regs.regs.skas.xfp));
24977 +                p->thread.request.u.thread = current->thread.request.u.thread;
24978 +               handler = new_thread_handler;
24979 +       }
24980 +
24981 +       new_thread((void *) p->thread.kernel_stack, 
24982 +                  &p->thread.mode.skas.switch_buf, 
24983 +                  &p->thread.mode.skas.fork_buf, handler);
24984 +       return(0);
24985 +}
24986 +
24987 +void init_idle_skas(void)
24988 +{
24989 +       cpu_tasks[current->processor].pid = os_getpid();
24990 +}
24991 +
24992 +extern void start_kernel(void);
24993 +
24994 +static int start_kernel_proc(void *unused)
24995 +{
24996 +       int pid;
24997 +
24998 +       block_signals();
24999 +       pid = os_getpid();
25000 +
25001 +       cpu_tasks[0].pid = pid;
25002 +       cpu_tasks[0].task = current;
25003 +#ifdef CONFIG_SMP
25004 +       cpu_online_map = 1;
25005 +#endif
25006 +       start_kernel();
25007 +       return(0);
25008 +}
25009 +
25010 +int start_uml_skas(void)
25011 +{
25012 +       start_userspace(0);
25013 +       capture_signal_stack();
25014 +       idle_timer();
25015 +
25016 +       init_new_thread_signals(1);
25017 +
25018 +       init_task.thread.request.u.thread.proc = start_kernel_proc;
25019 +       init_task.thread.request.u.thread.arg = NULL;
25020 +       return(start_idle_thread((void *) init_task.thread.kernel_stack,
25021 +                                &init_task.thread.mode.skas.switch_buf,
25022 +                                &init_task.thread.mode.skas.fork_buf));
25023 +}
25024 +
25025 +int external_pid_skas(struct task_struct *task)
25026 +{
25027 +#warning Need to look up userspace_pid by cpu  
25028 +       return(userspace_pid[0]);
25029 +}
25030 +
25031 +int thread_pid_skas(struct thread_struct *thread)
25032 +{
25033 +#warning Need to look up userspace_pid by cpu  
25034 +       return(userspace_pid[0]);
25035 +}
25036 +
25037 +/*
25038 + * Overrides for Emacs so that we follow Linus's tabbing style.
25039 + * Emacs will notice this stuff at the end of the file and automatically
25040 + * adjust the settings for this buffer only.  This must remain at the end
25041 + * of the file.
25042 + * ---------------------------------------------------------------------------
25043 + * Local variables:
25044 + * c-file-style: "linux"
25045 + * End:
25046 + */
25047 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_kern.c um/arch/um/kernel/skas/syscall_kern.c
25048 --- orig/arch/um/kernel/skas/syscall_kern.c     1969-12-31 19:00:00.000000000 -0500
25049 +++ um/arch/um/kernel/skas/syscall_kern.c       2004-01-04 08:20:29.000000000 -0500
25050 @@ -0,0 +1,42 @@
25051 +/* 
25052 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
25053 + * Licensed under the GPL
25054 + */
25055 +
25056 +#include "linux/sys.h"
25057 +#include "asm/errno.h"
25058 +#include "asm/unistd.h"
25059 +#include "asm/ptrace.h"
25060 +#include "asm/current.h"
25061 +#include "sysdep/syscalls.h"
25062 +#include "kern_util.h"
25063 +
25064 +extern syscall_handler_t *sys_call_table[];
25065 +
25066 +long execute_syscall_skas(void *r)
25067 +{
25068 +       struct pt_regs *regs = r;
25069 +       long res;
25070 +       int syscall;
25071 +
25072 +       current->thread.nsyscalls++;
25073 +       nsyscalls++;
25074 +       syscall = UPT_SYSCALL_NR(&regs->regs);
25075 +
25076 +       if((syscall >= NR_syscalls) || (syscall < 1))
25077 +               res = -ENOSYS;
25078 +       else res = EXECUTE_SYSCALL(syscall, regs);
25079 +
25080 +       return(res);
25081 +}
25082 +
25083 +/*
25084 + * Overrides for Emacs so that we follow Linus's tabbing style.
25085 + * Emacs will notice this stuff at the end of the file and automatically
25086 + * adjust the settings for this buffer only.  This must remain at the end
25087 + * of the file.
25088 + * ---------------------------------------------------------------------------
25089 + * Local variables:
25090 + * c-file-style: "linux"
25091 + * End:
25092 + */
25093 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_user.c um/arch/um/kernel/skas/syscall_user.c
25094 --- orig/arch/um/kernel/skas/syscall_user.c     1969-12-31 19:00:00.000000000 -0500
25095 +++ um/arch/um/kernel/skas/syscall_user.c       2003-10-21 03:26:07.000000000 -0400
25096 @@ -0,0 +1,46 @@
25097 +/* 
25098 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25099 + * Licensed under the GPL
25100 + */
25101 +
25102 +#include <stdlib.h>
25103 +#include <signal.h>
25104 +#include "kern_util.h"
25105 +#include "syscall_user.h"
25106 +#include "sysdep/ptrace.h"
25107 +#include "sysdep/sigcontext.h"
25108 +
25109 +/* XXX Bogus */
25110 +#define ERESTARTSYS    512
25111 +#define ERESTARTNOINTR 513
25112 +#define ERESTARTNOHAND 514
25113 +
25114 +void handle_syscall(union uml_pt_regs *regs)
25115 +{
25116 +       long result;
25117 +       int index;
25118 +
25119 +       index = record_syscall_start(UPT_SYSCALL_NR(regs));
25120 +
25121 +       syscall_trace();
25122 +       result = execute_syscall(regs);
25123 +
25124 +       REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
25125 +       if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || 
25126 +          (result == -ERESTARTNOINTR))
25127 +               do_signal(result);
25128 +
25129 +       syscall_trace();
25130 +       record_syscall_end(index, result);
25131 +}
25132 +
25133 +/*
25134 + * Overrides for Emacs so that we follow Linus's tabbing style.
25135 + * Emacs will notice this stuff at the end of the file and automatically
25136 + * adjust the settings for this buffer only.  This must remain at the end
25137 + * of the file.
25138 + * ---------------------------------------------------------------------------
25139 + * Local variables:
25140 + * c-file-style: "linux"
25141 + * End:
25142 + */
25143 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/Makefile um/arch/um/kernel/skas/sys-i386/Makefile
25144 --- orig/arch/um/kernel/skas/sys-i386/Makefile  1969-12-31 19:00:00.000000000 -0500
25145 +++ um/arch/um/kernel/skas/sys-i386/Makefile    2003-10-21 03:26:07.000000000 -0400
25146 @@ -0,0 +1,17 @@
25147 +# 
25148 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25149 +# Licensed under the GPL
25150 +#
25151 +
25152 +O_TARGET = sys-i386.o
25153 +
25154 +obj-y = sigcontext.o
25155 +
25156 +USER_OBJS = sigcontext.o
25157 +
25158 +include $(TOPDIR)/Rules.make
25159 +
25160 +$(USER_OBJS) : %.o: %.c
25161 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
25162 +
25163 +clean :
25164 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/sigcontext.c um/arch/um/kernel/skas/sys-i386/sigcontext.c
25165 --- orig/arch/um/kernel/skas/sys-i386/sigcontext.c      1969-12-31 19:00:00.000000000 -0500
25166 +++ um/arch/um/kernel/skas/sys-i386/sigcontext.c        2003-11-19 03:27:43.000000000 -0500
25167 @@ -0,0 +1,114 @@
25168 +/* 
25169 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25170 + * Licensed under the GPL
25171 + */
25172 +
25173 +#include <errno.h>
25174 +#include <asm/sigcontext.h>
25175 +#include <sys/ptrace.h>
25176 +#include <linux/ptrace.h>
25177 +#include "sysdep/ptrace.h"
25178 +#include "sysdep/ptrace_user.h"
25179 +#include "kern_util.h"
25180 +#include "user.h"
25181 +#include "sigcontext.h"
25182 +#include "mode.h"
25183 +
25184 +int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr)
25185 +{
25186 +       struct sigcontext sc, *from = from_ptr;
25187 +       unsigned long fpregs[FP_FRAME_SIZE];
25188 +       int err;
25189 +
25190 +       err = copy_from_user_proc(&sc, from, sizeof(sc));
25191 +       err |= copy_from_user_proc(fpregs, sc.fpstate, sizeof(fpregs));
25192 +       if(err)
25193 +               return(err);
25194 +
25195 +       regs->skas.regs[GS] = sc.gs;
25196 +       regs->skas.regs[FS] = sc.fs;
25197 +       regs->skas.regs[ES] = sc.es;
25198 +       regs->skas.regs[DS] = sc.ds;
25199 +       regs->skas.regs[EDI] = sc.edi;
25200 +       regs->skas.regs[ESI] = sc.esi;
25201 +       regs->skas.regs[EBP] = sc.ebp;
25202 +       regs->skas.regs[UESP] = sc.esp;
25203 +       regs->skas.regs[EBX] = sc.ebx;
25204 +       regs->skas.regs[EDX] = sc.edx;
25205 +       regs->skas.regs[ECX] = sc.ecx;
25206 +       regs->skas.regs[EAX] = sc.eax;
25207 +       regs->skas.regs[EIP] = sc.eip;
25208 +       regs->skas.regs[CS] = sc.cs;
25209 +       regs->skas.regs[EFL] = sc.eflags;
25210 +       regs->skas.regs[SS] = sc.ss;
25211 +       regs->skas.fault_addr = sc.cr2;
25212 +       regs->skas.fault_type = FAULT_WRITE(sc.err);
25213 +       regs->skas.trap_type = sc.trapno;
25214 +
25215 +       err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
25216 +       if(err < 0){
25217 +               printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
25218 +                      "errno = %d\n", errno);
25219 +               return(1);
25220 +       }
25221 +
25222 +       return(0);
25223 +}
25224 +
25225 +int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, 
25226 +                        union uml_pt_regs *regs, unsigned long fault_addr, 
25227 +                        int fault_type)
25228 +{
25229 +       struct sigcontext sc, *to = to_ptr;
25230 +       struct _fpstate *to_fp;
25231 +       unsigned long fpregs[FP_FRAME_SIZE];
25232 +       int err;
25233 +
25234 +       sc.gs = regs->skas.regs[GS];
25235 +       sc.fs = regs->skas.regs[FS];
25236 +       sc.es = regs->skas.regs[ES];
25237 +       sc.ds = regs->skas.regs[DS];
25238 +       sc.edi = regs->skas.regs[EDI];
25239 +       sc.esi = regs->skas.regs[ESI];
25240 +       sc.ebp = regs->skas.regs[EBP];
25241 +       sc.esp = regs->skas.regs[UESP];
25242 +       sc.ebx = regs->skas.regs[EBX];
25243 +       sc.edx = regs->skas.regs[EDX];
25244 +       sc.ecx = regs->skas.regs[ECX];
25245 +       sc.eax = regs->skas.regs[EAX];
25246 +       sc.eip = regs->skas.regs[EIP];
25247 +       sc.cs = regs->skas.regs[CS];
25248 +       sc.eflags = regs->skas.regs[EFL];
25249 +       sc.esp_at_signal = regs->skas.regs[UESP];
25250 +       sc.ss = regs->skas.regs[SS];
25251 +       sc.cr2 = fault_addr;
25252 +       sc.err = TO_SC_ERR(fault_type);
25253 +       sc.trapno = regs->skas.trap_type;
25254 +
25255 +       err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
25256 +       if(err < 0){
25257 +               printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
25258 +                      "errno = %d\n", errno);
25259 +               return(1);
25260 +       }
25261 +       to_fp = (struct _fpstate *) 
25262 +               (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
25263 +       sc.fpstate = to_fp;
25264 +
25265 +       if(err)
25266 +               return(err);
25267 +
25268 +       return(copy_to_user_proc(to, &sc, sizeof(sc)) ||
25269 +              copy_to_user_proc(to_fp, fpregs, sizeof(fpregs)));
25270 +}
25271 +
25272 +/*
25273 + * Overrides for Emacs so that we follow Linus's tabbing style.
25274 + * Emacs will notice this stuff at the end of the file and automatically
25275 + * adjust the settings for this buffer only.  This must remain at the end
25276 + * of the file.
25277 + * ---------------------------------------------------------------------------
25278 + * Local variables:
25279 + * c-file-style: "linux"
25280 + * End:
25281 + */
25282 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/time.c um/arch/um/kernel/skas/time.c
25283 --- orig/arch/um/kernel/skas/time.c     1969-12-31 19:00:00.000000000 -0500
25284 +++ um/arch/um/kernel/skas/time.c       2003-10-21 03:26:07.000000000 -0400
25285 @@ -0,0 +1,30 @@
25286 +/* 
25287 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25288 + * Licensed under the GPL
25289 + */
25290 +
25291 +#include <sys/signal.h>
25292 +#include <sys/time.h>
25293 +#include "time_user.h"
25294 +#include "process.h"
25295 +#include "user.h"
25296 +
25297 +void user_time_init_skas(void)
25298 +{
25299 +        if(signal(SIGALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
25300 +                panic("Couldn't set SIGALRM handler");
25301 +       if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
25302 +               panic("Couldn't set SIGVTALRM handler");
25303 +       set_interval(ITIMER_VIRTUAL);
25304 +}
25305 +
25306 +/*
25307 + * Overrides for Emacs so that we follow Linus's tabbing style.
25308 + * Emacs will notice this stuff at the end of the file and automatically
25309 + * adjust the settings for this buffer only.  This must remain at the end
25310 + * of the file.
25311 + * ---------------------------------------------------------------------------
25312 + * Local variables:
25313 + * c-file-style: "linux"
25314 + * End:
25315 + */
25316 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/tlb.c um/arch/um/kernel/skas/tlb.c
25317 --- orig/arch/um/kernel/skas/tlb.c      1969-12-31 19:00:00.000000000 -0500
25318 +++ um/arch/um/kernel/skas/tlb.c        2003-10-21 03:26:07.000000000 -0400
25319 @@ -0,0 +1,153 @@
25320 +/* 
25321 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25322 + * Licensed under the GPL
25323 + */
25324 +
25325 +#include "linux/stddef.h"
25326 +#include "linux/sched.h"
25327 +#include "asm/page.h"
25328 +#include "asm/pgtable.h"
25329 +#include "asm/mmu.h"
25330 +#include "user_util.h"
25331 +#include "mem_user.h"
25332 +#include "skas.h"
25333 +#include "os.h"
25334 +
25335 +static void fix_range(struct mm_struct *mm, unsigned long start_addr,
25336 +                     unsigned long end_addr, int force)
25337 +{
25338 +       pgd_t *npgd;
25339 +       pmd_t *npmd;
25340 +       pte_t *npte;
25341 +       unsigned long addr;
25342 +       int r, w, x, err, fd;
25343 +
25344 +       if(mm == NULL) return;
25345 +       fd = mm->context.skas.mm_fd;
25346 +       for(addr = start_addr; addr < end_addr;){
25347 +               npgd = pgd_offset(mm, addr);
25348 +               npmd = pmd_offset(npgd, addr);
25349 +               if(pmd_present(*npmd)){
25350 +                       npte = pte_offset(npmd, addr);
25351 +                       r = pte_read(*npte);
25352 +                       w = pte_write(*npte);
25353 +                       x = pte_exec(*npte);
25354 +                       if(!pte_dirty(*npte)) w = 0;
25355 +                       if(!pte_young(*npte)){
25356 +                               r = 0;
25357 +                               w = 0;
25358 +                       }
25359 +                       if(force || pte_newpage(*npte)){
25360 +                               err = unmap(fd, (void *) addr, PAGE_SIZE);
25361 +                               if(err < 0)
25362 +                                       panic("munmap failed, errno = %d\n",
25363 +                                             -err);
25364 +                               if(pte_present(*npte))
25365 +                                       map(fd, addr, 
25366 +                                           pte_val(*npte) & PAGE_MASK,
25367 +                                           PAGE_SIZE, r, w, x);
25368 +                       }
25369 +                       else if(pte_newprot(*npte)){
25370 +                               protect(fd, addr, PAGE_SIZE, r, w, x, 1);
25371 +                       }
25372 +                       *npte = pte_mkuptodate(*npte);
25373 +                       addr += PAGE_SIZE;
25374 +               }
25375 +               else {
25376 +                       if(force || pmd_newpage(*npmd)){
25377 +                               err = unmap(fd, (void *) addr, PMD_SIZE);
25378 +                               if(err < 0)
25379 +                                       panic("munmap failed, errno = %d\n",
25380 +                                             -err);
25381 +                               pmd_mkuptodate(*npmd);
25382 +                       }
25383 +                       addr += PMD_SIZE;
25384 +               }
25385 +       }
25386 +}
25387 +
25388 +static void flush_kernel_vm_range(unsigned long start, unsigned long end)
25389 +{
25390 +       struct mm_struct *mm;
25391 +       pgd_t *pgd;
25392 +       pmd_t *pmd;
25393 +       pte_t *pte;
25394 +       unsigned long addr;
25395 +       int updated = 0, err;
25396 +
25397 +       mm = &init_mm;
25398 +       for(addr = start_vm; addr < end_vm;){
25399 +               pgd = pgd_offset(mm, addr);
25400 +               pmd = pmd_offset(pgd, addr);
25401 +               if(pmd_present(*pmd)){
25402 +                       pte = pte_offset(pmd, addr);
25403 +                       if(!pte_present(*pte) || pte_newpage(*pte)){
25404 +                               updated = 1;
25405 +                               err = os_unmap_memory((void *) addr, 
25406 +                                                     PAGE_SIZE);
25407 +                               if(err < 0)
25408 +                                       panic("munmap failed, errno = %d\n",
25409 +                                             -err);
25410 +                               if(pte_present(*pte))
25411 +                                       map_memory(addr, 
25412 +                                                  pte_val(*pte) & PAGE_MASK,
25413 +                                                  PAGE_SIZE, 1, 1, 1);
25414 +                       }
25415 +                       else if(pte_newprot(*pte)){
25416 +                               updated = 1;
25417 +                               protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
25418 +                       }
25419 +                       addr += PAGE_SIZE;
25420 +               }
25421 +               else {
25422 +                       if(pmd_newpage(*pmd)){
25423 +                               updated = 1;
25424 +                               err = os_unmap_memory((void *) addr, PMD_SIZE);
25425 +                               if(err < 0)
25426 +                                       panic("munmap failed, errno = %d\n",
25427 +                                             -err);
25428 +                       }
25429 +                       addr += PMD_SIZE;
25430 +               }
25431 +       }
25432 +}
25433 +
25434 +void flush_tlb_kernel_vm_skas(void)
25435 +{
25436 +       flush_kernel_vm_range(start_vm, end_vm);
25437 +}
25438 +
25439 +void __flush_tlb_one_skas(unsigned long addr)
25440 +{
25441 +       flush_kernel_vm_range(addr, addr + PAGE_SIZE);
25442 +}
25443 +
25444 +void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start, 
25445 +                    unsigned long end)
25446 +{
25447 +       if(mm == NULL)
25448 +               flush_kernel_vm_range(start, end);
25449 +       else fix_range(mm, start, end, 0);
25450 +}
25451 +
25452 +void flush_tlb_mm_skas(struct mm_struct *mm)
25453 +{
25454 +       flush_tlb_kernel_vm_skas();
25455 +       fix_range(mm, 0, host_task_size, 0);
25456 +}
25457 +
25458 +void force_flush_all_skas(void)
25459 +{
25460 +       fix_range(current->mm, 0, host_task_size, 1);
25461 +}
25462 +
25463 +/*
25464 + * Overrides for Emacs so that we follow Linus's tabbing style.
25465 + * Emacs will notice this stuff at the end of the file and automatically
25466 + * adjust the settings for this buffer only.  This must remain at the end
25467 + * of the file.
25468 + * ---------------------------------------------------------------------------
25469 + * Local variables:
25470 + * c-file-style: "linux"
25471 + * End:
25472 + */
25473 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/trap_user.c um/arch/um/kernel/skas/trap_user.c
25474 --- orig/arch/um/kernel/skas/trap_user.c        1969-12-31 19:00:00.000000000 -0500
25475 +++ um/arch/um/kernel/skas/trap_user.c  2004-01-21 01:17:05.000000000 -0500
25476 @@ -0,0 +1,66 @@
25477 +/* 
25478 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
25479 + * Licensed under the GPL
25480 + */
25481 +
25482 +#include <signal.h>
25483 +#include <errno.h>
25484 +#include <asm/sigcontext.h>
25485 +#include "sysdep/ptrace.h"
25486 +#include "signal_user.h"
25487 +#include "user_util.h"
25488 +#include "kern_util.h"
25489 +#include "task.h"
25490 +#include "sigcontext.h"
25491 +
25492 +void sig_handler_common_skas(int sig, void *sc_ptr)
25493 +{
25494 +       struct sigcontext *sc = sc_ptr;
25495 +       struct skas_regs *r;
25496 +       struct signal_info *info;
25497 +       int save_errno = errno;
25498 +       int save_user;
25499 +
25500 +       r = &TASK_REGS(get_current())->skas;
25501 +       save_user = r->is_user;
25502 +       r->is_user = 0;
25503 +       r->fault_addr = SC_FAULT_ADDR(sc);
25504 +       r->fault_type = SC_FAULT_TYPE(sc);
25505 +       r->trap_type = SC_TRAP_TYPE(sc);
25506 +
25507 +       change_sig(SIGUSR1, 1);
25508 +       info = &sig_info[sig];
25509 +       if(!info->is_irq) unblock_signals();
25510 +
25511 +       (*info->handler)(sig, (union uml_pt_regs *) r);
25512 +
25513 +       errno = save_errno;
25514 +       r->is_user = save_user;
25515 +}
25516 +
25517 +extern int missed_ticks[];
25518 +
25519 +void user_signal(int sig, union uml_pt_regs *regs)
25520 +{
25521 +       struct signal_info *info;
25522 +
25523 +       regs->skas.is_user = 1;
25524 +       regs->skas.fault_addr = 0;
25525 +       regs->skas.fault_type = 0;
25526 +       regs->skas.trap_type = 0;
25527 +       info = &sig_info[sig];
25528 +       (*info->handler)(sig, regs);
25529 +
25530 +       unblock_signals();
25531 +}
25532 +
25533 +/*
25534 + * Overrides for Emacs so that we follow Linus's tabbing style.
25535 + * Emacs will notice this stuff at the end of the file and automatically
25536 + * adjust the settings for this buffer only.  This must remain at the end
25537 + * of the file.
25538 + * ---------------------------------------------------------------------------
25539 + * Local variables:
25540 + * c-file-style: "linux"
25541 + * End:
25542 + */
25543 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/uaccess.c um/arch/um/kernel/skas/uaccess.c
25544 --- orig/arch/um/kernel/skas/uaccess.c  1969-12-31 19:00:00.000000000 -0500
25545 +++ um/arch/um/kernel/skas/uaccess.c    2003-12-22 01:30:09.000000000 -0500
25546 @@ -0,0 +1,217 @@
25547 +/* 
25548 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
25549 + * Licensed under the GPL
25550 + */
25551 +
25552 +#include "linux/stddef.h"
25553 +#include "linux/kernel.h"
25554 +#include "linux/string.h"
25555 +#include "linux/fs.h"
25556 +#include "linux/highmem.h"
25557 +#include "asm/page.h"
25558 +#include "asm/pgtable.h"
25559 +#include "asm/uaccess.h"
25560 +#include "kern_util.h"
25561 +
25562 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 
25563 +                            pte_t *pte_out);
25564 +
25565 +static unsigned long maybe_map(unsigned long virt, int is_write)
25566 +{
25567 +       pte_t pte;
25568 +
25569 +       void *phys = um_virt_to_phys(current, virt, &pte);
25570 +       int dummy_code;
25571 +
25572 +       if(IS_ERR(phys) || (is_write && !pte_write(pte))){
25573 +               if(!handle_page_fault(virt, 0, is_write, 0, &dummy_code))
25574 +                       return(0);
25575 +               phys = um_virt_to_phys(current, virt, NULL);
25576 +       }
25577 +       return((unsigned long) phys);
25578 +}
25579 +
25580 +static int do_op(unsigned long addr, int len, int is_write, 
25581 +                int (*op)(unsigned long addr, int len, void *arg), void *arg)
25582 +{
25583 +       struct page *page;
25584 +       int n;
25585 +
25586 +       addr = maybe_map(addr, is_write);
25587 +       if(addr == -1)
25588 +               return(-1);
25589 +
25590 +       page = phys_to_page(addr);
25591 +       addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
25592 +       n = (*op)(addr, len, arg);
25593 +       kunmap(page);
25594 +
25595 +       return(n);
25596 +}
25597 +
25598 +static int buffer_op(unsigned long addr, int len, int is_write,
25599 +                    int (*op)(unsigned long addr, int len, void *arg),
25600 +                    void *arg)
25601 +{
25602 +       int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
25603 +       int remain = len, n;
25604 +
25605 +       n = do_op(addr, size, is_write, op, arg);
25606 +       if(n != 0)
25607 +               return(n < 0 ? remain : 0);
25608 +
25609 +       addr += size;
25610 +       remain -= size;
25611 +       if(remain == 0) 
25612 +               return(0);
25613 +
25614 +       while(addr < ((addr + remain) & PAGE_MASK)){
25615 +               n = do_op(addr, PAGE_SIZE, is_write, op, arg);
25616 +               if(n != 0)
25617 +                       return(n < 0 ? remain : 0);
25618 +
25619 +               addr += PAGE_SIZE;
25620 +               remain -= PAGE_SIZE;
25621 +       }
25622 +       if(remain == 0)
25623 +               return(0);
25624 +
25625 +       n = do_op(addr, remain, is_write, op, arg);
25626 +       if(n != 0)
25627 +               return(n < 0 ? remain : 0);
25628 +       return(0);
25629 +}
25630 +
25631 +static int copy_chunk_from_user(unsigned long from, int len, void *arg)
25632 +{
25633 +       unsigned long *to_ptr = arg, to = *to_ptr;
25634 +
25635 +       memcpy((void *) to, (void *) from, len);
25636 +       *to_ptr += len;
25637 +       return(0);
25638 +}
25639 +
25640 +int copy_from_user_skas(void *to, const void *from, int n)
25641 +{
25642 +       if(segment_eq(get_fs(), KERNEL_DS)){
25643 +               memcpy(to, from, n);
25644 +               return(0);
25645 +       }
25646 +
25647 +       return(access_ok_skas(VERIFY_READ, from, n) ?
25648 +              buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
25649 +              n);
25650 +}
25651 +
25652 +static int copy_chunk_to_user(unsigned long to, int len, void *arg)
25653 +{
25654 +       unsigned long *from_ptr = arg, from = *from_ptr;
25655 +
25656 +       memcpy((void *) to, (void *) from, len);
25657 +       *from_ptr += len;
25658 +       return(0);
25659 +}
25660 +
25661 +int copy_to_user_skas(void *to, const void *from, int n)
25662 +{
25663 +       if(segment_eq(get_fs(), KERNEL_DS)){
25664 +               memcpy(to, from, n);
25665 +               return(0);
25666 +       }
25667 +
25668 +       return(access_ok_skas(VERIFY_WRITE, to, n) ?
25669 +              buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
25670 +              n);
25671 +}
25672 +
25673 +static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
25674 +{
25675 +       char **to_ptr = arg, *to = *to_ptr;
25676 +       int n;
25677 +
25678 +       strncpy(to, (void *) from, len);
25679 +       n = strnlen(to, len);
25680 +       *to_ptr += n;
25681 +
25682 +       if(n < len) 
25683 +               return(1);
25684 +       return(0);
25685 +}
25686 +
25687 +int strncpy_from_user_skas(char *dst, const char *src, int count)
25688 +{
25689 +       int n;
25690 +       char *ptr = dst;
25691 +
25692 +       if(segment_eq(get_fs(), KERNEL_DS)){
25693 +               strncpy(dst, src, count);
25694 +               return(strnlen(dst, count));
25695 +       }
25696 +
25697 +       if(!access_ok_skas(VERIFY_READ, src, 1))
25698 +               return(-EFAULT);
25699 +
25700 +       n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user, 
25701 +                     &ptr);
25702 +       if(n != 0)
25703 +               return(-EFAULT);
25704 +       return(strnlen(dst, count));
25705 +}
25706 +
25707 +static int clear_chunk(unsigned long addr, int len, void *unused)
25708 +{
25709 +       memset((void *) addr, 0, len);
25710 +       return(0);
25711 +}
25712 +
25713 +int __clear_user_skas(void *mem, int len)
25714 +{
25715 +       return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
25716 +}
25717 +
25718 +int clear_user_skas(void *mem, int len)
25719 +{
25720 +       if(segment_eq(get_fs(), KERNEL_DS)){
25721 +               memset(mem, 0, len);
25722 +               return(0);
25723 +       }
25724 +
25725 +       return(access_ok_skas(VERIFY_WRITE, mem, len) ? 
25726 +              buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
25727 +}
25728 +
25729 +static int strnlen_chunk(unsigned long str, int len, void *arg)
25730 +{
25731 +       int *len_ptr = arg, n;
25732 +
25733 +       n = strnlen((void *) str, len);
25734 +       *len_ptr += n;
25735 +
25736 +       if(n < len)
25737 +               return(1);
25738 +       return(0);
25739 +}
25740 +
25741 +int strnlen_user_skas(const void *str, int len)
25742 +{
25743 +       int count = 0, n;
25744 +
25745 +       if(segment_eq(get_fs(), KERNEL_DS))
25746 +               return(strnlen(str, len) + 1);
25747 +
25748 +       n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
25749 +       if(n == 0)
25750 +               return(count + 1);
25751 +       return(-EFAULT);
25752 +}
25753 +
25754 +/*
25755 + * Overrides for Emacs so that we follow Linus's tabbing style.
25756 + * Emacs will notice this stuff at the end of the file and automatically
25757 + * adjust the settings for this buffer only.  This must remain at the end
25758 + * of the file.
25759 + * ---------------------------------------------------------------------------
25760 + * Local variables:
25761 + * c-file-style: "linux"
25762 + * End:
25763 + */
25764 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/Makefile um/arch/um/kernel/skas/util/Makefile
25765 --- orig/arch/um/kernel/skas/util/Makefile      1969-12-31 19:00:00.000000000 -0500
25766 +++ um/arch/um/kernel/skas/util/Makefile        2003-11-08 02:52:22.000000000 -0500
25767 @@ -0,0 +1,10 @@
25768 +all: mk_ptregs
25769 +
25770 +mk_ptregs : mk_ptregs.o
25771 +       $(HOSTCC) -o mk_ptregs mk_ptregs.o
25772 +
25773 +mk_ptregs.o : mk_ptregs.c
25774 +       $(HOSTCC) -c $< 
25775 +
25776 +clean : 
25777 +       $(RM) -f mk_ptregs *.o *~
25778 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/mk_ptregs.c um/arch/um/kernel/skas/util/mk_ptregs.c
25779 --- orig/arch/um/kernel/skas/util/mk_ptregs.c   1969-12-31 19:00:00.000000000 -0500
25780 +++ um/arch/um/kernel/skas/util/mk_ptregs.c     2003-12-22 01:31:11.000000000 -0500
25781 @@ -0,0 +1,51 @@
25782 +#include <stdio.h>
25783 +#include <asm/ptrace.h>
25784 +#include <asm/user.h>
25785 +
25786 +#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val))
25787 +
25788 +int main(int argc, char **argv)
25789 +{
25790 +       printf("/* Automatically generated by "
25791 +              "arch/um/kernel/skas/util/mk_ptregs */\n");
25792 +       printf("\n");
25793 +       printf("#ifndef __SKAS_PT_REGS_\n");
25794 +       printf("#define __SKAS_PT_REGS_\n");
25795 +       printf("\n");
25796 +       printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE);
25797 +       printf("#define HOST_FP_SIZE %d\n", 
25798 +              sizeof(struct user_i387_struct) / sizeof(unsigned long));
25799 +       printf("#define HOST_XFP_SIZE %d\n", 
25800 +              sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
25801 +
25802 +       PRINT_REG("IP", EIP);
25803 +       PRINT_REG("SP", UESP);
25804 +       PRINT_REG("EFLAGS", EFL);
25805 +       PRINT_REG("EAX", EAX);
25806 +       PRINT_REG("EBX", EBX);
25807 +       PRINT_REG("ECX", ECX);
25808 +       PRINT_REG("EDX", EDX);
25809 +       PRINT_REG("ESI", ESI);
25810 +       PRINT_REG("EDI", EDI);
25811 +       PRINT_REG("EBP", EBP);
25812 +       PRINT_REG("CS", CS);
25813 +       PRINT_REG("SS", SS);
25814 +       PRINT_REG("DS", DS);
25815 +       PRINT_REG("FS", FS);
25816 +       PRINT_REG("ES", ES);
25817 +       PRINT_REG("GS", GS);
25818 +       printf("\n");
25819 +       printf("#endif\n");
25820 +       return(0);
25821 +}
25822 +
25823 +/*
25824 + * Overrides for Emacs so that we follow Linus's tabbing style.
25825 + * Emacs will notice this stuff at the end of the file and automatically
25826 + * adjust the settings for this buffer only.  This must remain at the end
25827 + * of the file.
25828 + * ---------------------------------------------------------------------------
25829 + * Local variables:
25830 + * c-file-style: "linux"
25831 + * End:
25832 + */
25833 diff -Naur -X ../exclude-files orig/arch/um/kernel/smp.c um/arch/um/kernel/smp.c
25834 --- orig/arch/um/kernel/smp.c   1969-12-31 19:00:00.000000000 -0500
25835 +++ um/arch/um/kernel/smp.c     2003-11-15 02:59:25.000000000 -0500
25836 @@ -0,0 +1,328 @@
25837 +/* 
25838 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
25839 + * Licensed under the GPL
25840 + */
25841 +
25842 +#include "linux/config.h"
25843 +
25844 +#ifdef CONFIG_SMP
25845 +
25846 +#include "linux/sched.h"
25847 +#include "linux/threads.h"
25848 +#include "linux/interrupt.h"
25849 +#include "asm/smp.h"
25850 +#include "asm/processor.h"
25851 +#include "asm/spinlock.h"
25852 +#include "asm/softirq.h"
25853 +#include "asm/hardirq.h"
25854 +#include "asm/tlb.h"
25855 +#include "user_util.h"
25856 +#include "kern_util.h"
25857 +#include "irq_user.h"
25858 +#include "kern.h"
25859 +#include "os.h"
25860 +
25861 +/* Total count of live CPUs, set by smp_boot_cpus */
25862 +int smp_num_cpus = 1;
25863 +
25864 +/* The 'big kernel lock' */
25865 +spinlock_cacheline_t kernel_flag_cacheline = {SPIN_LOCK_UNLOCKED};
25866 +
25867 +/* Per CPU bogomips and other parameters */
25868 +
25869 +/* The only piece used here is the ipi pipe, which is set before SMP is
25870 + * started and never changed.
25871 + */
25872 +struct cpuinfo_um cpu_data[NR_CPUS];
25873 +
25874 +/* CPU online map, set by smp_boot_cpus */
25875 +unsigned long cpu_online_map;
25876 +
25877 +atomic_t global_bh_count;
25878 +
25879 +/* Set when the idlers are all forked */
25880 +int smp_threads_ready = 0;
25881 +
25882 +/* Not used by UML */
25883 +unsigned char global_irq_holder = 0;
25884 +unsigned volatile long global_irq_lock;
25885 +
25886 +/* A statistic, can be a little off */
25887 +static int num_reschedules_sent = 0;
25888 +
25889 +mmu_gather_t mmu_gathers[NR_CPUS];
25890 +
25891 +void smp_send_reschedule(int cpu)
25892 +{
25893 +       os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1);
25894 +       num_reschedules_sent++;
25895 +}
25896 +
25897 +static void show(char * str)
25898 +{
25899 +       int cpu = smp_processor_id();
25900 +
25901 +       printk(KERN_INFO "\n%s, CPU %d:\n", str, cpu);
25902 +}
25903 +       
25904 +#define MAXCOUNT 100000000
25905 +
25906 +static inline void wait_on_bh(void)
25907 +{
25908 +       int count = MAXCOUNT;
25909 +       do {
25910 +               if (!--count) {
25911 +                       show("wait_on_bh");
25912 +                       count = ~0;
25913 +               }
25914 +               /* nothing .. wait for the other bh's to go away */
25915 +       } while (atomic_read(&global_bh_count) != 0);
25916 +}
25917 +
25918 +/*
25919 + * This is called when we want to synchronize with
25920 + * bottom half handlers. We need to wait until
25921 + * no other CPU is executing any bottom half handler.
25922 + *
25923 + * Don't wait if we're already running in an interrupt
25924 + * context or are inside a bh handler. 
25925 + */
25926 +void synchronize_bh(void)
25927 +{
25928 +       if (atomic_read(&global_bh_count) && !in_interrupt())
25929 +               wait_on_bh();
25930 +}
25931 +
25932 +void smp_send_stop(void)
25933 +{
25934 +       int i;
25935
25936 +       printk(KERN_INFO "Stopping all CPUs...");
25937 +       for(i = 0; i < ncpus; i++){
25938 +               if(i == current->processor)
25939 +                       continue;
25940 +               os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
25941 +       }
25942 +       printk("done\n");
25943 +}
25944 +
25945 +
25946 +static atomic_t smp_commenced = ATOMIC_INIT(0);
25947 +static volatile unsigned long smp_callin_map = 0;
25948 +
25949 +void smp_commence(void)
25950 +{
25951 +       printk("All CPUs are go!\n");
25952 +
25953 +       wmb();
25954 +       atomic_set(&smp_commenced, 1);
25955 +}
25956 +
25957 +static int idle_proc(void *unused)
25958 +{
25959 +       int cpu, err;
25960 +
25961 +       set_current(current);
25962 +       del_from_runqueue(current);
25963 +       unhash_process(current);
25964 +
25965 +       cpu = current->processor;
25966 +       err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
25967 +       if(err < 0)
25968 +               panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
25969 +
25970 +       activate_ipi(cpu_data[cpu].ipi_pipe[0], 
25971 +                    current->thread.mode.tt.extern_pid);
25972
25973 +       wmb();
25974 +       if (test_and_set_bit(current->processor, &smp_callin_map)) {
25975 +               printk("huh, CPU#%d already present??\n", current->processor);
25976 +               BUG();
25977 +       }
25978 +
25979 +       while (!atomic_read(&smp_commenced))
25980 +               cpu_relax();
25981 +
25982 +       init_idle();
25983 +       cpu_idle();
25984 +       return(0);
25985 +}
25986 +
25987 +static int idle_thread(int (*fn)(void *), int cpu)
25988 +{
25989 +       struct task_struct *new_task;
25990 +       int pid;
25991 +       unsigned char c;
25992 +
25993 +        current->thread.request.u.thread.proc = fn;
25994 +        current->thread.request.u.thread.arg = NULL;
25995 +       pid = do_fork(CLONE_VM | CLONE_PID, 0, NULL, 0);
25996 +       if(pid < 0) 
25997 +               panic("do_fork failed in idle_thread");
25998 +       new_task = get_task(pid, 1);
25999 +
26000 +       cpu_tasks[cpu] = ((struct cpu_task) 
26001 +                         { .pid =      new_task->thread.mode.tt.extern_pid,
26002 +                           .task =     new_task } );
26003 +       init_tasks[cpu] = new_task;
26004 +       new_task->processor = cpu;
26005 +       new_task->cpus_allowed = 1 << cpu;
26006 +       new_task->cpus_runnable = new_task->cpus_allowed;
26007 +       CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, 
26008 +                         sizeof(c)),
26009 +                   ({ panic("skas mode doesn't support SMP"); }));
26010 +       return(new_task->thread.mode.tt.extern_pid);
26011 +}
26012 +
26013 +void smp_boot_cpus(void)
26014 +{
26015 +       int err;
26016 +
26017 +       set_bit(0, &cpu_online_map);
26018 +       set_bit(0, &smp_callin_map);
26019 +
26020 +       err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
26021 +       if(err < 0) 
26022 +               panic("CPU#0 failed to create IPI pipe, err = %d", -err);
26023 +
26024 +       activate_ipi(cpu_data[0].ipi_pipe[0], 
26025 +                    current->thread.mode.tt.extern_pid);
26026 +
26027 +       if(ncpus < 1){
26028 +               printk(KERN_INFO "ncpus set to 1\n");
26029 +               ncpus = 1;
26030 +       }
26031 +       else if(ncpus > NR_CPUS){
26032 +               printk(KERN_INFO 
26033 +                      "ncpus can't be greater than NR_CPUS, set to %d\n",
26034 +                      NR_CPUS);
26035 +               ncpus = NR_CPUS;
26036 +       }
26037 +
26038 +       if(ncpus > 1){
26039 +               int i, pid;
26040 +
26041 +               printk(KERN_INFO "Starting up other processors:\n");
26042 +               for(i=1;i<ncpus;i++){
26043 +                       int waittime;
26044 +
26045 +                       /* Do this early, for hard_smp_processor_id()  */
26046 +                       cpu_tasks[i].pid = -1;
26047 +                       set_bit(i, &cpu_online_map);
26048 +                       smp_num_cpus++;
26049 +
26050 +                       pid = idle_thread(idle_proc, i);
26051 +                       printk(KERN_INFO "\t#%d - idle thread pid = %d.. ",
26052 +                              i, pid);
26053 +
26054 +                       waittime = 200000000;
26055 +                       while (waittime-- && !test_bit(i, &smp_callin_map))
26056 +                               cpu_relax();
26057 +
26058 +                       if (test_bit(i, &smp_callin_map))
26059 +                               printk("online\n");
26060 +                       else {
26061 +                               printk("failed\n");
26062 +                               clear_bit(i, &cpu_online_map);
26063 +                       }
26064 +               }
26065 +       }
26066 +}
26067 +
26068 +int setup_profiling_timer(unsigned int multiplier)
26069 +{
26070 +       printk(KERN_INFO "setup_profiling_timer\n");
26071 +       return(0);
26072 +}
26073 +
26074 +void smp_call_function_slave(int cpu);
26075 +
26076 +void IPI_handler(int cpu)
26077 +{
26078 +       unsigned char c;
26079 +       int fd;
26080 +
26081 +       fd = cpu_data[cpu].ipi_pipe[0];
26082 +       while (os_read_file(fd, &c, 1) == 1) {
26083 +               switch (c) {
26084 +               case 'C':
26085 +                       smp_call_function_slave(cpu);
26086 +                       break;
26087 +
26088 +               case 'R':
26089 +                       current->need_resched = 1;
26090 +                       break;
26091 +
26092 +               case 'S':
26093 +                       printk("CPU#%d stopping\n", cpu);
26094 +                       while(1)
26095 +                               pause();
26096 +                       break;
26097 +
26098 +               default:
26099 +                       printk("CPU#%d received unknown IPI [%c]!\n", cpu, c);
26100 +                       break;
26101 +               }
26102 +       }
26103 +}
26104 +
26105 +int hard_smp_processor_id(void)
26106 +{
26107 +       return(pid_to_processor_id(os_getpid()));
26108 +}
26109 +
26110 +static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
26111 +static atomic_t scf_started;
26112 +static atomic_t scf_finished;
26113 +static void (*func)(void *info);
26114 +static void *info;
26115 +
26116 +void smp_call_function_slave(int cpu)
26117 +{
26118 +       atomic_inc(&scf_started);
26119 +       (*func)(info);
26120 +       atomic_inc(&scf_finished);
26121 +}
26122 +
26123 +int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, 
26124 +                     int wait)
26125 +{
26126 +       int cpus = smp_num_cpus - 1;
26127 +       int i;
26128 +
26129 +       if (!cpus)
26130 +               return 0;
26131 +
26132 +       spin_lock_bh(&call_lock);
26133 +       atomic_set(&scf_started, 0);
26134 +       atomic_set(&scf_finished, 0);
26135 +       func = _func;
26136 +       info = _info;
26137 +
26138 +       for (i=0;i<NR_CPUS;i++)
26139 +               if (i != current->processor && test_bit(i, &cpu_online_map))
26140 +                       os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
26141 +
26142 +       while (atomic_read(&scf_started) != cpus)
26143 +               barrier();
26144 +
26145 +       if (wait)
26146 +               while (atomic_read(&scf_finished) != cpus)
26147 +                       barrier();
26148 +
26149 +       spin_unlock_bh(&call_lock);
26150 +       return 0;
26151 +}
26152 +
26153 +#endif
26154 +
26155 +/*
26156 + * Overrides for Emacs so that we follow Linus's tabbing style.
26157 + * Emacs will notice this stuff at the end of the file and automatically
26158 + * adjust the settings for this buffer only.  This must remain at the end
26159 + * of the file.
26160 + * ---------------------------------------------------------------------------
26161 + * Local variables:
26162 + * c-file-style: "linux"
26163 + * End:
26164 + */
26165 diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_kern.c um/arch/um/kernel/syscall_kern.c
26166 --- orig/arch/um/kernel/syscall_kern.c  1969-12-31 19:00:00.000000000 -0500
26167 +++ um/arch/um/kernel/syscall_kern.c    2004-01-10 06:37:46.000000000 -0500
26168 @@ -0,0 +1,343 @@
26169 +/* 
26170 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
26171 + * Licensed under the GPL
26172 + */
26173 +
26174 +#include "linux/sched.h"
26175 +#include "linux/file.h"
26176 +#include "linux/smp_lock.h"
26177 +#include "linux/mm.h"
26178 +#include "linux/utsname.h"
26179 +#include "linux/msg.h"
26180 +#include "linux/shm.h"
26181 +#include "linux/sys.h"
26182 +#include "linux/unistd.h"
26183 +#include "linux/slab.h"
26184 +#include "linux/utime.h"
26185 +#include "asm/mman.h"
26186 +#include "asm/uaccess.h"
26187 +#include "asm/ipc.h"
26188 +#include "kern_util.h"
26189 +#include "user_util.h"
26190 +#include "sysdep/syscalls.h"
26191 +#include "mode_kern.h"
26192 +#include "choose-mode.h"
26193 +
26194 +/*  Unlocked, I don't care if this is a bit off */
26195 +int nsyscalls = 0;
26196 +
26197 +long um_mount(char * dev_name, char * dir_name, char * type,
26198 +             unsigned long new_flags, void * data)
26199 +{
26200 +       if(type == NULL) type = "";
26201 +       return(sys_mount(dev_name, dir_name, type, new_flags, data));
26202 +}
26203 +
26204 +long sys_fork(void)
26205 +{
26206 +       long ret;
26207 +
26208 +       current->thread.forking = 1;
26209 +        ret = do_fork(SIGCHLD, 0, NULL, 0);
26210 +       current->thread.forking = 0;
26211 +       return(ret);
26212 +}
26213 +
26214 +long sys_clone(unsigned long clone_flags, unsigned long newsp)
26215 +{
26216 +       long ret;
26217 +
26218 +       current->thread.forking = 1;
26219 +       ret = do_fork(clone_flags, newsp, NULL, 0);
26220 +       current->thread.forking = 0;
26221 +       return(ret);
26222 +}
26223 +
26224 +long sys_vfork(void)
26225 +{
26226 +       long ret;
26227 +
26228 +       current->thread.forking = 1;
26229 +       ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0);
26230 +       current->thread.forking = 0;
26231 +       return(ret);
26232 +}
26233 +
26234 +/* common code for old and new mmaps */
26235 +long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
26236 +             unsigned long prot, unsigned long flags, unsigned long fd,
26237 +             unsigned long pgoff)
26238 +{
26239 +       int error = -EBADF;
26240 +       struct file * file = NULL;
26241 +
26242 +       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
26243 +       if (!(flags & MAP_ANONYMOUS)) {
26244 +               file = fget(fd);
26245 +               if (!file)
26246 +                       goto out;
26247 +       }
26248 +
26249 +       down_write(&mm->mmap_sem);
26250 +       error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
26251 +       up_write(&mm->mmap_sem);
26252 +
26253 +       if (file)
26254 +               fput(file);
26255 + out:
26256 +       return error;
26257 +}
26258 +
26259 +long sys_mmap2(unsigned long addr, unsigned long len,
26260 +              unsigned long prot, unsigned long flags,
26261 +              unsigned long fd, unsigned long pgoff)
26262 +{
26263 +       return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
26264 +}
26265 +
26266 +/*
26267 + * Perform the select(nd, in, out, ex, tv) and mmap() system
26268 + * calls. Linux/i386 didn't use to be able to handle more than
26269 + * 4 system call parameters, so these system calls used a memory
26270 + * block for parameter passing..
26271 + */
26272 +
26273 +struct mmap_arg_struct {
26274 +       unsigned long addr;
26275 +       unsigned long len;
26276 +       unsigned long prot;
26277 +       unsigned long flags;
26278 +       unsigned long fd;
26279 +       unsigned long offset;
26280 +};
26281 +
26282 +int old_mmap(unsigned long addr, unsigned long len,
26283 +            unsigned long prot, unsigned long flags,
26284 +            unsigned long fd, unsigned long offset)
26285 +{
26286 +       int err = -EINVAL;
26287 +       if (offset & ~PAGE_MASK)
26288 +               goto out;
26289 +
26290 +       err = do_mmap2(current->mm, addr, len, prot, flags, fd, 
26291 +                      offset >> PAGE_SHIFT);
26292 + out:
26293 +       return err;
26294 +}
26295 +/*
26296 + * sys_pipe() is the normal C calling standard for creating
26297 + * a pipe. It's not the way unix traditionally does this, though.
26298 + */
26299 +int sys_pipe(unsigned long * fildes)
26300 +{
26301 +        int fd[2];
26302 +        int error;
26303 +
26304 +        error = do_pipe(fd);
26305 +        if (!error) {
26306 +               if (copy_to_user(fildes, fd, sizeof(fd)))
26307 +                        error = -EFAULT;
26308 +        }
26309 +        return error;
26310 +}
26311 +
26312 +int sys_pause(void)
26313 +{
26314 +       current->state = TASK_INTERRUPTIBLE;
26315 +       schedule();
26316 +       return -ERESTARTNOHAND;
26317 +}
26318 +
26319 +int sys_sigaction(int sig, const struct old_sigaction *act,
26320 +                        struct old_sigaction *oact)
26321 +{
26322 +       struct k_sigaction new_ka, old_ka;
26323 +       int ret;
26324 +
26325 +       if (act) {
26326 +               old_sigset_t mask;
26327 +               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
26328 +                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
26329 +                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
26330 +                       return -EFAULT;
26331 +               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
26332 +               __get_user(mask, &act->sa_mask);
26333 +               siginitset(&new_ka.sa.sa_mask, mask);
26334 +       }
26335 +
26336 +       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
26337 +
26338 +       if (!ret && oact) {
26339 +               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
26340 +                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
26341 +                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
26342 +                       return -EFAULT;
26343 +               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
26344 +               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
26345 +       }
26346 +
26347 +       return ret;
26348 +}
26349 +
26350 +/*
26351 + * sys_ipc() is the de-multiplexer for the SysV IPC calls..
26352 + *
26353 + * This is really horribly ugly.
26354 + */
26355 +int sys_ipc (uint call, int first, int second,
26356 +            int third, void *ptr, long fifth)
26357 +{
26358 +       int version, ret;
26359 +
26360 +       version = call >> 16; /* hack for backward compatibility */
26361 +       call &= 0xffff;
26362 +
26363 +       switch (call) {
26364 +       case SEMOP:
26365 +               return sys_semop (first, (struct sembuf *)ptr, second);
26366 +       case SEMGET:
26367 +               return sys_semget (first, second, third);
26368 +       case SEMCTL: {
26369 +               union semun fourth;
26370 +               if (!ptr)
26371 +                       return -EINVAL;
26372 +               if (get_user(fourth.__pad, (void **) ptr))
26373 +                       return -EFAULT;
26374 +               return sys_semctl (first, second, third, fourth);
26375 +       }
26376 +
26377 +       case MSGSND:
26378 +               return sys_msgsnd (first, (struct msgbuf *) ptr, 
26379 +                                  second, third);
26380 +       case MSGRCV:
26381 +               switch (version) {
26382 +               case 0: {
26383 +                       struct ipc_kludge tmp;
26384 +                       if (!ptr)
26385 +                               return -EINVAL;
26386 +                       
26387 +                       if (copy_from_user(&tmp,
26388 +                                          (struct ipc_kludge *) ptr, 
26389 +                                          sizeof (tmp)))
26390 +                               return -EFAULT;
26391 +                       return sys_msgrcv (first, tmp.msgp, second,
26392 +                                          tmp.msgtyp, third);
26393 +               }
26394 +               default:
26395 +                       panic("msgrcv with version != 0");
26396 +                       return sys_msgrcv (first,
26397 +                                          (struct msgbuf *) ptr,
26398 +                                          second, fifth, third);
26399 +               }
26400 +       case MSGGET:
26401 +               return sys_msgget ((key_t) first, second);
26402 +       case MSGCTL:
26403 +               return sys_msgctl (first, second, (struct msqid_ds *) ptr);
26404 +
26405 +       case SHMAT:
26406 +               switch (version) {
26407 +               default: {
26408 +                       ulong raddr;
26409 +                       ret = sys_shmat (first, (char *) ptr, second, &raddr);
26410 +                       if (ret)
26411 +                               return ret;
26412 +                       return put_user (raddr, (ulong *) third);
26413 +               }
26414 +               case 1: /* iBCS2 emulator entry point */
26415 +                       if (!segment_eq(get_fs(), get_ds()))
26416 +                               return -EINVAL;
26417 +                       return sys_shmat (first, (char *) ptr, second, (ulong *) third);
26418 +               }
26419 +       case SHMDT: 
26420 +               return sys_shmdt ((char *)ptr);
26421 +       case SHMGET:
26422 +               return sys_shmget (first, second, third);
26423 +       case SHMCTL:
26424 +               return sys_shmctl (first, second,
26425 +                                  (struct shmid_ds *) ptr);
26426 +       default:
26427 +               return -EINVAL;
26428 +       }
26429 +}
26430 +
26431 +int sys_uname(struct old_utsname * name)
26432 +{
26433 +       int err;
26434 +       if (!name)
26435 +               return -EFAULT;
26436 +       down_read(&uts_sem);
26437 +       err=copy_to_user(name, &system_utsname, sizeof (*name));
26438 +       up_read(&uts_sem);
26439 +       return err?-EFAULT:0;
26440 +}
26441 +
26442 +int sys_olduname(struct oldold_utsname * name)
26443 +{
26444 +       int error;
26445 +
26446 +       if (!name)
26447 +               return -EFAULT;
26448 +       if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
26449 +               return -EFAULT;
26450 +  
26451 +       down_read(&uts_sem);
26452 +       
26453 +       error = __copy_to_user(&name->sysname,&system_utsname.sysname,
26454 +                              __OLD_UTS_LEN);
26455 +       error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
26456 +       error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
26457 +                               __OLD_UTS_LEN);
26458 +       error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
26459 +       error |= __copy_to_user(&name->release,&system_utsname.release,
26460 +                               __OLD_UTS_LEN);
26461 +       error |= __put_user(0,name->release+__OLD_UTS_LEN);
26462 +       error |= __copy_to_user(&name->version,&system_utsname.version,
26463 +                               __OLD_UTS_LEN);
26464 +       error |= __put_user(0,name->version+__OLD_UTS_LEN);
26465 +       error |= __copy_to_user(&name->machine,&system_utsname.machine,
26466 +                               __OLD_UTS_LEN);
26467 +       error |= __put_user(0,name->machine+__OLD_UTS_LEN);
26468 +       
26469 +       up_read(&uts_sem);
26470 +       
26471 +       error = error ? -EFAULT : 0;
26472 +
26473 +       return error;
26474 +}
26475 +
26476 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
26477 +{
26478 +       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
26479 +}
26480 +
26481 +long execute_syscall(void *r)
26482 +{
26483 +       return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
26484 +}
26485 +
26486 +spinlock_t syscall_lock = SPIN_LOCK_UNLOCKED;
26487 +
26488 +static int syscall_index = 0;
26489 +
26490 +int next_syscall_index(int limit)
26491 +{
26492 +       int ret;
26493 +
26494 +       spin_lock(&syscall_lock);
26495 +       ret = syscall_index;
26496 +       if(++syscall_index == limit)
26497 +               syscall_index = 0;
26498 +       spin_unlock(&syscall_lock);
26499 +       return(ret);
26500 +}
26501 +
26502 +/*
26503 + * Overrides for Emacs so that we follow Linus's tabbing style.
26504 + * Emacs will notice this stuff at the end of the file and automatically
26505 + * adjust the settings for this buffer only.  This must remain at the end
26506 + * of the file.
26507 + * ---------------------------------------------------------------------------
26508 + * Local variables:
26509 + * c-file-style: "linux"
26510 + * End:
26511 + */
26512 diff -Naur -X ../exclude-files orig/arch/um/kernel/sys_call_table.c um/arch/um/kernel/sys_call_table.c
26513 --- orig/arch/um/kernel/sys_call_table.c        1969-12-31 19:00:00.000000000 -0500
26514 +++ um/arch/um/kernel/sys_call_table.c  2003-10-21 03:26:07.000000000 -0400
26515 @@ -0,0 +1,496 @@
26516 +/* 
26517 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
26518 + * Licensed under the GPL
26519 + */
26520 +
26521 +#include "linux/unistd.h"
26522 +#include "linux/version.h"
26523 +#include "linux/sys.h"
26524 +#include "asm/signal.h"
26525 +#include "sysdep/syscalls.h"
26526 +#include "kern_util.h"
26527 +
26528 +extern syscall_handler_t sys_ni_syscall;
26529 +extern syscall_handler_t sys_exit;
26530 +extern syscall_handler_t sys_fork;
26531 +extern syscall_handler_t sys_creat;
26532 +extern syscall_handler_t sys_link;
26533 +extern syscall_handler_t sys_unlink;
26534 +extern syscall_handler_t sys_chdir;
26535 +extern syscall_handler_t sys_mknod;
26536 +extern syscall_handler_t sys_chmod;
26537 +extern syscall_handler_t sys_lchown16;
26538 +extern syscall_handler_t sys_ni_syscall;
26539 +extern syscall_handler_t sys_stat;
26540 +extern syscall_handler_t sys_getpid;
26541 +extern syscall_handler_t sys_oldumount;
26542 +extern syscall_handler_t sys_setuid16;
26543 +extern syscall_handler_t sys_getuid16;
26544 +extern syscall_handler_t sys_ptrace;
26545 +extern syscall_handler_t sys_alarm;
26546 +extern syscall_handler_t sys_fstat;
26547 +extern syscall_handler_t sys_pause;
26548 +extern syscall_handler_t sys_utime;
26549 +extern syscall_handler_t sys_ni_syscall;
26550 +extern syscall_handler_t sys_ni_syscall;
26551 +extern syscall_handler_t sys_access;
26552 +extern syscall_handler_t sys_nice;
26553 +extern syscall_handler_t sys_ni_syscall;
26554 +extern syscall_handler_t sys_sync;
26555 +extern syscall_handler_t sys_kill;
26556 +extern syscall_handler_t sys_rename;
26557 +extern syscall_handler_t sys_mkdir;
26558 +extern syscall_handler_t sys_rmdir;
26559 +extern syscall_handler_t sys_pipe;
26560 +extern syscall_handler_t sys_times;
26561 +extern syscall_handler_t sys_ni_syscall;
26562 +extern syscall_handler_t sys_brk;
26563 +extern syscall_handler_t sys_setgid16;
26564 +extern syscall_handler_t sys_getgid16;
26565 +extern syscall_handler_t sys_signal;
26566 +extern syscall_handler_t sys_geteuid16;
26567 +extern syscall_handler_t sys_getegid16;
26568 +extern syscall_handler_t sys_acct;
26569 +extern syscall_handler_t sys_umount;
26570 +extern syscall_handler_t sys_ni_syscall;
26571 +extern syscall_handler_t sys_ioctl;
26572 +extern syscall_handler_t sys_fcntl;
26573 +extern syscall_handler_t sys_ni_syscall;
26574 +extern syscall_handler_t sys_setpgid;
26575 +extern syscall_handler_t sys_ni_syscall;
26576 +extern syscall_handler_t sys_olduname;
26577 +extern syscall_handler_t sys_umask;
26578 +extern syscall_handler_t sys_chroot;
26579 +extern syscall_handler_t sys_ustat;
26580 +extern syscall_handler_t sys_dup2;
26581 +extern syscall_handler_t sys_getppid;
26582 +extern syscall_handler_t sys_getpgrp;
26583 +extern syscall_handler_t sys_sigaction;
26584 +extern syscall_handler_t sys_sgetmask;
26585 +extern syscall_handler_t sys_ssetmask;
26586 +extern syscall_handler_t sys_setreuid16;
26587 +extern syscall_handler_t sys_setregid16;
26588 +extern syscall_handler_t sys_sigsuspend;
26589 +extern syscall_handler_t sys_sigpending;
26590 +extern syscall_handler_t sys_sethostname;
26591 +extern syscall_handler_t sys_setrlimit;
26592 +extern syscall_handler_t sys_old_getrlimit;
26593 +extern syscall_handler_t sys_getrusage;
26594 +extern syscall_handler_t sys_gettimeofday;
26595 +extern syscall_handler_t sys_settimeofday;
26596 +extern syscall_handler_t sys_getgroups16;
26597 +extern syscall_handler_t sys_setgroups16;
26598 +extern syscall_handler_t sys_symlink;
26599 +extern syscall_handler_t sys_lstat;
26600 +extern syscall_handler_t sys_readlink;
26601 +extern syscall_handler_t sys_uselib;
26602 +extern syscall_handler_t sys_swapon;
26603 +extern syscall_handler_t sys_reboot;
26604 +extern syscall_handler_t old_readdir;
26605 +extern syscall_handler_t sys_munmap;
26606 +extern syscall_handler_t sys_truncate;
26607 +extern syscall_handler_t sys_ftruncate;
26608 +extern syscall_handler_t sys_fchmod;
26609 +extern syscall_handler_t sys_fchown16;
26610 +extern syscall_handler_t sys_getpriority;
26611 +extern syscall_handler_t sys_setpriority;
26612 +extern syscall_handler_t sys_ni_syscall;
26613 +extern syscall_handler_t sys_statfs;
26614 +extern syscall_handler_t sys_fstatfs;
26615 +extern syscall_handler_t sys_ni_syscall;
26616 +extern syscall_handler_t sys_socketcall;
26617 +extern syscall_handler_t sys_syslog;
26618 +extern syscall_handler_t sys_setitimer;
26619 +extern syscall_handler_t sys_getitimer;
26620 +extern syscall_handler_t sys_newstat;
26621 +extern syscall_handler_t sys_newlstat;
26622 +extern syscall_handler_t sys_newfstat;
26623 +extern syscall_handler_t sys_uname;
26624 +extern syscall_handler_t sys_ni_syscall;
26625 +extern syscall_handler_t sys_vhangup;
26626 +extern syscall_handler_t sys_ni_syscall;
26627 +extern syscall_handler_t sys_ni_syscall;
26628 +extern syscall_handler_t sys_swapoff;
26629 +extern syscall_handler_t sys_sysinfo;
26630 +extern syscall_handler_t sys_ipc;
26631 +extern syscall_handler_t sys_fsync;
26632 +extern syscall_handler_t sys_sigreturn;
26633 +extern syscall_handler_t sys_rt_sigreturn;
26634 +extern syscall_handler_t sys_clone;
26635 +extern syscall_handler_t sys_setdomainname;
26636 +extern syscall_handler_t sys_newuname;
26637 +extern syscall_handler_t sys_ni_syscall;
26638 +extern syscall_handler_t sys_adjtimex;
26639 +extern syscall_handler_t sys_mprotect;
26640 +extern syscall_handler_t sys_sigprocmask;
26641 +extern syscall_handler_t sys_create_module;
26642 +extern syscall_handler_t sys_init_module;
26643 +extern syscall_handler_t sys_delete_module;
26644 +extern syscall_handler_t sys_get_kernel_syms;
26645 +extern syscall_handler_t sys_quotactl;
26646 +extern syscall_handler_t sys_getpgid;
26647 +extern syscall_handler_t sys_fchdir;
26648 +extern syscall_handler_t sys_bdflush;
26649 +extern syscall_handler_t sys_sysfs;
26650 +extern syscall_handler_t sys_personality;
26651 +extern syscall_handler_t sys_ni_syscall;
26652 +extern syscall_handler_t sys_setfsuid16;
26653 +extern syscall_handler_t sys_setfsgid16;
26654 +extern syscall_handler_t sys_llseek;
26655 +extern syscall_handler_t sys_getdents;
26656 +extern syscall_handler_t sys_flock;
26657 +extern syscall_handler_t sys_msync;
26658 +extern syscall_handler_t sys_readv;
26659 +extern syscall_handler_t sys_writev;
26660 +extern syscall_handler_t sys_getsid;
26661 +extern syscall_handler_t sys_fdatasync;
26662 +extern syscall_handler_t sys_sysctl;
26663 +extern syscall_handler_t sys_mlock;
26664 +extern syscall_handler_t sys_munlock;
26665 +extern syscall_handler_t sys_mlockall;
26666 +extern syscall_handler_t sys_munlockall;
26667 +extern syscall_handler_t sys_sched_setparam;
26668 +extern syscall_handler_t sys_sched_getparam;
26669 +extern syscall_handler_t sys_sched_setscheduler;
26670 +extern syscall_handler_t sys_sched_getscheduler;
26671 +extern syscall_handler_t sys_sched_get_priority_max;
26672 +extern syscall_handler_t sys_sched_get_priority_min;
26673 +extern syscall_handler_t sys_sched_rr_get_interval;
26674 +extern syscall_handler_t sys_nanosleep;
26675 +extern syscall_handler_t sys_mremap;
26676 +extern syscall_handler_t sys_setresuid16;
26677 +extern syscall_handler_t sys_getresuid16;
26678 +extern syscall_handler_t sys_ni_syscall;
26679 +extern syscall_handler_t sys_query_module;
26680 +extern syscall_handler_t sys_poll;
26681 +extern syscall_handler_t sys_nfsservctl;
26682 +extern syscall_handler_t sys_setresgid16;
26683 +extern syscall_handler_t sys_getresgid16;
26684 +extern syscall_handler_t sys_prctl;
26685 +extern syscall_handler_t sys_ni_syscall;
26686 +extern syscall_handler_t sys_rt_sigaction;
26687 +extern syscall_handler_t sys_rt_sigprocmask;
26688 +extern syscall_handler_t sys_rt_sigpending;
26689 +extern syscall_handler_t sys_rt_sigtimedwait;
26690 +extern syscall_handler_t sys_rt_sigqueueinfo;
26691 +extern syscall_handler_t sys_rt_sigsuspend;
26692 +extern syscall_handler_t sys_pread;
26693 +extern syscall_handler_t sys_pwrite;
26694 +extern syscall_handler_t sys_chown16;
26695 +extern syscall_handler_t sys_getcwd;
26696 +extern syscall_handler_t sys_capget;
26697 +extern syscall_handler_t sys_capset;
26698 +extern syscall_handler_t sys_sigaltstack;
26699 +extern syscall_handler_t sys_sendfile;
26700 +extern syscall_handler_t sys_ni_syscall;
26701 +extern syscall_handler_t sys_ni_syscall;
26702 +extern syscall_handler_t sys_vfork;
26703 +extern syscall_handler_t sys_getrlimit;
26704 +extern syscall_handler_t sys_mmap2;
26705 +extern syscall_handler_t sys_truncate64;
26706 +extern syscall_handler_t sys_ftruncate64;
26707 +extern syscall_handler_t sys_stat64;
26708 +extern syscall_handler_t sys_lstat64;
26709 +extern syscall_handler_t sys_fstat64;
26710 +extern syscall_handler_t sys_lchown;
26711 +extern syscall_handler_t sys_getuid;
26712 +extern syscall_handler_t sys_getgid;
26713 +extern syscall_handler_t sys_geteuid;
26714 +extern syscall_handler_t sys_getegid;
26715 +extern syscall_handler_t sys_setreuid;
26716 +extern syscall_handler_t sys_setregid;
26717 +extern syscall_handler_t sys_getgroups;
26718 +extern syscall_handler_t sys_setgroups;
26719 +extern syscall_handler_t sys_fchown;
26720 +extern syscall_handler_t sys_setresuid;
26721 +extern syscall_handler_t sys_getresuid;
26722 +extern syscall_handler_t sys_setresgid;
26723 +extern syscall_handler_t sys_getresgid;
26724 +extern syscall_handler_t sys_chown;
26725 +extern syscall_handler_t sys_setuid;
26726 +extern syscall_handler_t sys_setgid;
26727 +extern syscall_handler_t sys_setfsuid;
26728 +extern syscall_handler_t sys_setfsgid;
26729 +extern syscall_handler_t sys_pivot_root;
26730 +extern syscall_handler_t sys_mincore;
26731 +extern syscall_handler_t sys_madvise;
26732 +extern syscall_handler_t sys_fcntl64;
26733 +extern syscall_handler_t sys_getdents64;
26734 +extern syscall_handler_t sys_gettid;
26735 +extern syscall_handler_t sys_readahead;
26736 +extern syscall_handler_t sys_tkill;
26737 +extern syscall_handler_t sys_setxattr;
26738 +extern syscall_handler_t sys_lsetxattr;
26739 +extern syscall_handler_t sys_fsetxattr;
26740 +extern syscall_handler_t sys_getxattr;
26741 +extern syscall_handler_t sys_lgetxattr;
26742 +extern syscall_handler_t sys_fgetxattr;
26743 +extern syscall_handler_t sys_listxattr;
26744 +extern syscall_handler_t sys_llistxattr;
26745 +extern syscall_handler_t sys_flistxattr;
26746 +extern syscall_handler_t sys_removexattr;
26747 +extern syscall_handler_t sys_lremovexattr;
26748 +extern syscall_handler_t sys_fremovexattr;
26749 +extern syscall_handler_t sys_sendfile64;
26750 +
26751 +extern syscall_handler_t um_mount;
26752 +extern syscall_handler_t um_time;
26753 +extern syscall_handler_t um_stime;
26754 +
26755 +#define LAST_GENERIC_SYSCALL __NR_exit_group
26756 +
26757 +#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
26758 +#define LAST_SYSCALL LAST_GENERIC_SYSCALL
26759 +#else
26760 +#define LAST_SYSCALL LAST_ARCH_SYSCALL
26761 +#endif
26762 +
26763 +syscall_handler_t *sys_call_table[] = {
26764 +       [ 0 ] = sys_ni_syscall,
26765 +       [ __NR_exit ] = sys_exit,
26766 +       [ __NR_fork ] = sys_fork,
26767 +       [ __NR_read ] = (syscall_handler_t *) sys_read,
26768 +       [ __NR_write ] = (syscall_handler_t *) sys_write,
26769 +
26770 +       /* These three are declared differently in asm/unistd.h */
26771 +       [ __NR_open ] = (syscall_handler_t *) sys_open,
26772 +       [ __NR_close ] = (syscall_handler_t *) sys_close,
26773 +       [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid,
26774 +       [ __NR_creat ] = sys_creat,
26775 +       [ __NR_link ] = sys_link,
26776 +       [ __NR_unlink ] = sys_unlink,
26777 +
26778 +       /* declared differently in kern_util.h */
26779 +       [ __NR_execve ] = (syscall_handler_t *) sys_execve,
26780 +       [ __NR_chdir ] = sys_chdir,
26781 +       [ __NR_time ] = um_time,
26782 +       [ __NR_mknod ] = sys_mknod,
26783 +       [ __NR_chmod ] = sys_chmod,
26784 +       [ __NR_lchown ] = sys_lchown16,
26785 +       [ __NR_break ] = sys_ni_syscall,
26786 +       [ __NR_oldstat ] = sys_stat,
26787 +       [ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
26788 +       [ __NR_getpid ] = sys_getpid,
26789 +       [ __NR_mount ] = um_mount,
26790 +       [ __NR_umount ] = sys_oldumount,
26791 +       [ __NR_setuid ] = sys_setuid16,
26792 +       [ __NR_getuid ] = sys_getuid16,
26793 +       [ __NR_stime ] = um_stime,
26794 +       [ __NR_ptrace ] = sys_ptrace,
26795 +       [ __NR_alarm ] = sys_alarm,
26796 +       [ __NR_oldfstat ] = sys_fstat,
26797 +       [ __NR_pause ] = sys_pause,
26798 +       [ __NR_utime ] = sys_utime,
26799 +       [ __NR_stty ] = sys_ni_syscall,
26800 +       [ __NR_gtty ] = sys_ni_syscall,
26801 +       [ __NR_access ] = sys_access,
26802 +       [ __NR_nice ] = sys_nice,
26803 +       [ __NR_ftime ] = sys_ni_syscall,
26804 +       [ __NR_sync ] = sys_sync,
26805 +       [ __NR_kill ] = sys_kill,
26806 +       [ __NR_rename ] = sys_rename,
26807 +       [ __NR_mkdir ] = sys_mkdir,
26808 +       [ __NR_rmdir ] = sys_rmdir,
26809 +
26810 +       /* Declared differently in asm/unistd.h */
26811 +       [ __NR_dup ] = (syscall_handler_t *) sys_dup,
26812 +       [ __NR_pipe ] = sys_pipe,
26813 +       [ __NR_times ] = sys_times,
26814 +       [ __NR_prof ] = sys_ni_syscall,
26815 +       [ __NR_brk ] = sys_brk,
26816 +       [ __NR_setgid ] = sys_setgid16,
26817 +       [ __NR_getgid ] = sys_getgid16,
26818 +       [ __NR_signal ] = sys_signal,
26819 +       [ __NR_geteuid ] = sys_geteuid16,
26820 +       [ __NR_getegid ] = sys_getegid16,
26821 +       [ __NR_acct ] = sys_acct,
26822 +       [ __NR_umount2 ] = sys_umount,
26823 +       [ __NR_lock ] = sys_ni_syscall,
26824 +       [ __NR_ioctl ] = sys_ioctl,
26825 +       [ __NR_fcntl ] = sys_fcntl,
26826 +       [ __NR_mpx ] = sys_ni_syscall,
26827 +       [ __NR_setpgid ] = sys_setpgid,
26828 +       [ __NR_ulimit ] = sys_ni_syscall,
26829 +       [ __NR_oldolduname ] = sys_olduname,
26830 +       [ __NR_umask ] = sys_umask,
26831 +       [ __NR_chroot ] = sys_chroot,
26832 +       [ __NR_ustat ] = sys_ustat,
26833 +       [ __NR_dup2 ] = sys_dup2,
26834 +       [ __NR_getppid ] = sys_getppid,
26835 +       [ __NR_getpgrp ] = sys_getpgrp,
26836 +       [ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
26837 +       [ __NR_sigaction ] = sys_sigaction,
26838 +       [ __NR_sgetmask ] = sys_sgetmask,
26839 +       [ __NR_ssetmask ] = sys_ssetmask,
26840 +       [ __NR_setreuid ] = sys_setreuid16,
26841 +       [ __NR_setregid ] = sys_setregid16,
26842 +       [ __NR_sigsuspend ] = sys_sigsuspend,
26843 +       [ __NR_sigpending ] = sys_sigpending,
26844 +       [ __NR_sethostname ] = sys_sethostname,
26845 +       [ __NR_setrlimit ] = sys_setrlimit,
26846 +       [ __NR_getrlimit ] = sys_old_getrlimit,
26847 +       [ __NR_getrusage ] = sys_getrusage,
26848 +       [ __NR_gettimeofday ] = sys_gettimeofday,
26849 +       [ __NR_settimeofday ] = sys_settimeofday,
26850 +       [ __NR_getgroups ] = sys_getgroups16,
26851 +       [ __NR_setgroups ] = sys_setgroups16,
26852 +       [ __NR_symlink ] = sys_symlink,
26853 +       [ __NR_oldlstat ] = sys_lstat,
26854 +       [ __NR_readlink ] = sys_readlink,
26855 +       [ __NR_uselib ] = sys_uselib,
26856 +       [ __NR_swapon ] = sys_swapon,
26857 +       [ __NR_reboot ] = sys_reboot,
26858 +       [ __NR_readdir ] = old_readdir,
26859 +       [ __NR_munmap ] = sys_munmap,
26860 +       [ __NR_truncate ] = sys_truncate,
26861 +       [ __NR_ftruncate ] = sys_ftruncate,
26862 +       [ __NR_fchmod ] = sys_fchmod,
26863 +       [ __NR_fchown ] = sys_fchown16,
26864 +       [ __NR_getpriority ] = sys_getpriority,
26865 +       [ __NR_setpriority ] = sys_setpriority,
26866 +       [ __NR_profil ] = sys_ni_syscall,
26867 +       [ __NR_statfs ] = sys_statfs,
26868 +       [ __NR_fstatfs ] = sys_fstatfs,
26869 +       [ __NR_ioperm ] = sys_ni_syscall,
26870 +       [ __NR_socketcall ] = sys_socketcall,
26871 +       [ __NR_syslog ] = sys_syslog,
26872 +       [ __NR_setitimer ] = sys_setitimer,
26873 +       [ __NR_getitimer ] = sys_getitimer,
26874 +       [ __NR_stat ] = sys_newstat,
26875 +       [ __NR_lstat ] = sys_newlstat,
26876 +       [ __NR_fstat ] = sys_newfstat,
26877 +       [ __NR_olduname ] = sys_uname,
26878 +       [ __NR_iopl ] = sys_ni_syscall,
26879 +       [ __NR_vhangup ] = sys_vhangup,
26880 +       [ __NR_idle ] = sys_ni_syscall,
26881 +       [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
26882 +       [ __NR_swapoff ] = sys_swapoff,
26883 +       [ __NR_sysinfo ] = sys_sysinfo,
26884 +       [ __NR_ipc ] = sys_ipc,
26885 +       [ __NR_fsync ] = sys_fsync,
26886 +       [ __NR_sigreturn ] = sys_sigreturn,
26887 +       [ __NR_clone ] = sys_clone,
26888 +       [ __NR_setdomainname ] = sys_setdomainname,
26889 +       [ __NR_uname ] = sys_newuname,
26890 +       [ __NR_adjtimex ] = sys_adjtimex,
26891 +       [ __NR_mprotect ] = sys_mprotect,
26892 +       [ __NR_sigprocmask ] = sys_sigprocmask,
26893 +       [ __NR_create_module ] = sys_create_module,
26894 +       [ __NR_init_module ] = sys_init_module,
26895 +       [ __NR_delete_module ] = sys_delete_module,
26896 +       [ __NR_get_kernel_syms ] = sys_get_kernel_syms,
26897 +       [ __NR_quotactl ] = sys_quotactl,
26898 +       [ __NR_getpgid ] = sys_getpgid,
26899 +       [ __NR_fchdir ] = sys_fchdir,
26900 +       [ __NR_bdflush ] = sys_bdflush,
26901 +       [ __NR_sysfs ] = sys_sysfs,
26902 +       [ __NR_personality ] = sys_personality,
26903 +       [ __NR_afs_syscall ] = sys_ni_syscall,
26904 +       [ __NR_setfsuid ] = sys_setfsuid16,
26905 +       [ __NR_setfsgid ] = sys_setfsgid16,
26906 +       [ __NR__llseek ] = sys_llseek,
26907 +       [ __NR_getdents ] = sys_getdents,
26908 +       [ __NR__newselect ] = (syscall_handler_t *) sys_select,
26909 +       [ __NR_flock ] = sys_flock,
26910 +       [ __NR_msync ] = sys_msync,
26911 +       [ __NR_readv ] = sys_readv,
26912 +       [ __NR_writev ] = sys_writev,
26913 +       [ __NR_getsid ] = sys_getsid,
26914 +       [ __NR_fdatasync ] = sys_fdatasync,
26915 +       [ __NR__sysctl ] = sys_sysctl,
26916 +       [ __NR_mlock ] = sys_mlock,
26917 +       [ __NR_munlock ] = sys_munlock,
26918 +       [ __NR_mlockall ] = sys_mlockall,
26919 +       [ __NR_munlockall ] = sys_munlockall,
26920 +       [ __NR_sched_setparam ] = sys_sched_setparam,
26921 +       [ __NR_sched_getparam ] = sys_sched_getparam,
26922 +       [ __NR_sched_setscheduler ] = sys_sched_setscheduler,
26923 +       [ __NR_sched_getscheduler ] = sys_sched_getscheduler,
26924 +       [ __NR_sched_yield ] = (syscall_handler_t *) yield,
26925 +       [ __NR_sched_get_priority_max ] = sys_sched_get_priority_max,
26926 +       [ __NR_sched_get_priority_min ] = sys_sched_get_priority_min,
26927 +       [ __NR_sched_rr_get_interval ] = sys_sched_rr_get_interval,
26928 +       [ __NR_nanosleep ] = sys_nanosleep,
26929 +       [ __NR_mremap ] = sys_mremap,
26930 +       [ __NR_setresuid ] = sys_setresuid16,
26931 +       [ __NR_getresuid ] = sys_getresuid16,
26932 +       [ __NR_vm86 ] = sys_ni_syscall,
26933 +       [ __NR_query_module ] = sys_query_module,
26934 +       [ __NR_poll ] = sys_poll,
26935 +       [ __NR_nfsservctl ] = sys_nfsservctl,
26936 +       [ __NR_setresgid ] = sys_setresgid16,
26937 +       [ __NR_getresgid ] = sys_getresgid16,
26938 +       [ __NR_prctl ] = sys_prctl,
26939 +       [ __NR_rt_sigreturn ] = sys_rt_sigreturn,
26940 +       [ __NR_rt_sigaction ] = sys_rt_sigaction,
26941 +       [ __NR_rt_sigprocmask ] = sys_rt_sigprocmask,
26942 +       [ __NR_rt_sigpending ] = sys_rt_sigpending,
26943 +       [ __NR_rt_sigtimedwait ] = sys_rt_sigtimedwait,
26944 +       [ __NR_rt_sigqueueinfo ] = sys_rt_sigqueueinfo,
26945 +       [ __NR_rt_sigsuspend ] = sys_rt_sigsuspend,
26946 +       [ __NR_pread ] = sys_pread,
26947 +       [ __NR_pwrite ] = sys_pwrite,
26948 +       [ __NR_chown ] = sys_chown16,
26949 +       [ __NR_getcwd ] = sys_getcwd,
26950 +       [ __NR_capget ] = sys_capget,
26951 +       [ __NR_capset ] = sys_capset,
26952 +       [ __NR_sigaltstack ] = sys_sigaltstack,
26953 +       [ __NR_sendfile ] = sys_sendfile,
26954 +       [ __NR_getpmsg ] = sys_ni_syscall,
26955 +       [ __NR_putpmsg ] = sys_ni_syscall,
26956 +       [ __NR_vfork ] = sys_vfork,
26957 +       [ __NR_ugetrlimit ] = sys_getrlimit,
26958 +       [ __NR_mmap2 ] = sys_mmap2,
26959 +       [ __NR_truncate64 ] = sys_truncate64,
26960 +       [ __NR_ftruncate64 ] = sys_ftruncate64,
26961 +       [ __NR_stat64 ] = sys_stat64,
26962 +       [ __NR_lstat64 ] = sys_lstat64,
26963 +       [ __NR_fstat64 ] = sys_fstat64,
26964 +       [ __NR_fcntl64 ] = sys_fcntl64,
26965 +       [ __NR_getdents64 ] = sys_getdents64,
26966 +        [ __NR_security ] = sys_ni_syscall,
26967 +       [ __NR_gettid ] = sys_gettid,
26968 +       [ __NR_readahead ] = sys_readahead,
26969 +       [ __NR_setxattr ] = sys_setxattr,
26970 +       [ __NR_lsetxattr ] = sys_lsetxattr,
26971 +       [ __NR_fsetxattr ] = sys_fsetxattr,
26972 +       [ __NR_getxattr ] = sys_getxattr,
26973 +       [ __NR_lgetxattr ] = sys_lgetxattr,
26974 +       [ __NR_fgetxattr ] = sys_fgetxattr,
26975 +       [ __NR_listxattr ] = sys_listxattr,
26976 +       [ __NR_llistxattr ] = sys_llistxattr,
26977 +       [ __NR_flistxattr ] = sys_flistxattr,
26978 +       [ __NR_removexattr ] = sys_removexattr,
26979 +       [ __NR_lremovexattr ] = sys_lremovexattr,
26980 +       [ __NR_fremovexattr ] = sys_fremovexattr,
26981 +       [ __NR_tkill ] = sys_tkill,
26982 +       [ __NR_sendfile64 ] = sys_sendfile64,
26983 +       [ __NR_futex ] = sys_ni_syscall,
26984 +       [ __NR_sched_setaffinity ] = sys_ni_syscall,
26985 +       [ __NR_sched_getaffinity ] = sys_ni_syscall,
26986 +       [ __NR_set_thread_area ] = sys_ni_syscall,
26987 +       [ __NR_get_thread_area ] = sys_ni_syscall,
26988 +       [ __NR_io_setup ] = sys_ni_syscall,
26989 +       [ __NR_io_destroy ] = sys_ni_syscall,
26990 +       [ __NR_io_getevents ] = sys_ni_syscall,
26991 +       [ __NR_io_submit ] = sys_ni_syscall,
26992 +       [ __NR_io_cancel ] = sys_ni_syscall,
26993 +       [ __NR_alloc_hugepages ] = sys_ni_syscall,
26994 +       [ __NR_free_hugepages ] = sys_ni_syscall,
26995 +       [ __NR_exit_group ] = sys_ni_syscall,
26996 +
26997 +       ARCH_SYSCALLS
26998 +       [ LAST_SYSCALL + 1 ... NR_syscalls ] = 
26999 +               (syscall_handler_t *) sys_ni_syscall
27000 +};
27001 +
27002 +/*
27003 + * Overrides for Emacs so that we follow Linus's tabbing style.
27004 + * Emacs will notice this stuff at the end of the file and automatically
27005 + * adjust the settings for this buffer only.  This must remain at the end
27006 + * of the file.
27007 + * ---------------------------------------------------------------------------
27008 + * Local variables:
27009 + * c-file-style: "linux"
27010 + * End:
27011 + */
27012 diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_user.c um/arch/um/kernel/syscall_user.c
27013 --- orig/arch/um/kernel/syscall_user.c  1969-12-31 19:00:00.000000000 -0500
27014 +++ um/arch/um/kernel/syscall_user.c    2003-12-22 01:32:48.000000000 -0500
27015 @@ -0,0 +1,48 @@
27016 +/* 
27017 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27018 + * Licensed under the GPL
27019 + */
27020 +
27021 +#include <stdlib.h>
27022 +#include <sys/time.h>
27023 +#include "kern_util.h"
27024 +#include "syscall_user.h"
27025 +
27026 +struct {
27027 +       int syscall;
27028 +       int pid;
27029 +       int result;
27030 +       struct timeval start;
27031 +       struct timeval end;
27032 +} syscall_record[1024];
27033 +
27034 +int record_syscall_start(int syscall)
27035 +{
27036 +       int max, index;
27037 +
27038 +       max = sizeof(syscall_record)/sizeof(syscall_record[0]);
27039 +       index = next_syscall_index(max);
27040 +
27041 +       syscall_record[index].syscall = syscall;
27042 +       syscall_record[index].pid = current_pid();
27043 +       syscall_record[index].result = 0xdeadbeef;
27044 +       gettimeofday(&syscall_record[index].start, NULL);
27045 +       return(index);
27046 +}
27047 +
27048 +void record_syscall_end(int index, int result)
27049 +{
27050 +       syscall_record[index].result = result;
27051 +       gettimeofday(&syscall_record[index].end, NULL);
27052 +}
27053 +
27054 +/*
27055 + * Overrides for Emacs so that we follow Linus's tabbing style.
27056 + * Emacs will notice this stuff at the end of the file and automatically
27057 + * adjust the settings for this buffer only.  This must remain at the end
27058 + * of the file.
27059 + * ---------------------------------------------------------------------------
27060 + * Local variables:
27061 + * c-file-style: "linux"
27062 + * End:
27063 + */
27064 diff -Naur -X ../exclude-files orig/arch/um/kernel/sysrq.c um/arch/um/kernel/sysrq.c
27065 --- orig/arch/um/kernel/sysrq.c 1969-12-31 19:00:00.000000000 -0500
27066 +++ um/arch/um/kernel/sysrq.c   2003-10-21 03:26:07.000000000 -0400
27067 @@ -0,0 +1,98 @@
27068 +/* 
27069 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
27070 + * Licensed under the GPL
27071 + */
27072 +
27073 +#include "linux/sched.h"
27074 +#include "linux/kernel.h"
27075 +#include "linux/module.h"
27076 +#include "asm/page.h"
27077 +#include "asm/processor.h"
27078 +#include "sysrq.h"
27079 +#include "user_util.h"
27080 +
27081 + /*
27082 +  * If the address is either in the .text section of the
27083 +  * kernel, or in the vmalloc'ed module regions, it *may* 
27084 +  * be the address of a calling routine
27085 +  */
27086
27087 +#ifdef CONFIG_MODULES
27088 +
27089 +extern struct module *module_list;
27090 +extern struct module kernel_module;
27091 +
27092 +static inline int kernel_text_address(unsigned long addr)
27093 +{
27094 +       int retval = 0;
27095 +       struct module *mod;
27096 +
27097 +       if (addr >= (unsigned long) &_stext &&
27098 +           addr <= (unsigned long) &_etext)
27099 +               return 1;
27100 +
27101 +       for (mod = module_list; mod != &kernel_module; mod = mod->next) {
27102 +               /* mod_bound tests for addr being inside the vmalloc'ed
27103 +                * module area. Of course it'd be better to test only
27104 +                * for the .text subset... */
27105 +               if (mod_bound(addr, 0, mod)) {
27106 +                       retval = 1;
27107 +                       break;
27108 +               }
27109 +       }
27110 +
27111 +       return retval;
27112 +}
27113 +
27114 +#else
27115 +
27116 +static inline int kernel_text_address(unsigned long addr)
27117 +{
27118 +       return (addr >= (unsigned long) &_stext &&
27119 +               addr <= (unsigned long) &_etext);
27120 +}
27121 +
27122 +#endif
27123 +
27124 +void show_trace(unsigned long * stack)
27125 +{
27126 +        int i;
27127 +        unsigned long addr;
27128 +
27129 +        if (!stack)
27130 +                stack = (unsigned long*) &stack;
27131 +
27132 +        printk("Call Trace: ");
27133 +        i = 1;
27134 +        while (((long) stack & (THREAD_SIZE-1)) != 0) {
27135 +                addr = *stack++;
27136 +               if (kernel_text_address(addr)) {
27137 +                       if (i && ((i % 6) == 0))
27138 +                               printk("\n   ");
27139 +                       printk("[<%08lx>] ", addr);
27140 +                       i++;
27141 +                }
27142 +        }
27143 +        printk("\n");
27144 +}
27145 +
27146 +void show_trace_task(struct task_struct *tsk)
27147 +{
27148 +       unsigned long esp = PT_REGS_SP(&tsk->thread.regs);
27149 +
27150 +       /* User space on another CPU? */
27151 +       if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
27152 +               return;
27153 +       show_trace((unsigned long *)esp);
27154 +}
27155 +
27156 +/*
27157 + * Overrides for Emacs so that we follow Linus's tabbing style.
27158 + * Emacs will notice this stuff at the end of the file and automatically
27159 + * adjust the settings for this buffer only.  This must remain at the end
27160 + * of the file.
27161 + * ---------------------------------------------------------------------------
27162 + * Local variables:
27163 + * c-file-style: "linux"
27164 + * End:
27165 + */
27166 diff -Naur -X ../exclude-files orig/arch/um/kernel/tempfile.c um/arch/um/kernel/tempfile.c
27167 --- orig/arch/um/kernel/tempfile.c      1969-12-31 19:00:00.000000000 -0500
27168 +++ um/arch/um/kernel/tempfile.c        2003-12-22 01:33:38.000000000 -0500
27169 @@ -0,0 +1,82 @@
27170 +/*
27171 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27172 + * Licensed under the GPL
27173 + */
27174 +
27175 +#include <stdio.h>
27176 +#include <stdlib.h>
27177 +#include <unistd.h>
27178 +#include <string.h>
27179 +#include <errno.h>
27180 +#include <sys/param.h>
27181 +#include "init.h"
27182 +
27183 +/* Modified from create_mem_file and start_debugger */
27184 +static char *tempdir = NULL;
27185 +
27186 +static void __init find_tempdir(void)
27187 +{
27188 +       char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
27189 +       int i;
27190 +       char *dir = NULL;
27191 +
27192 +       if(tempdir != NULL) return;     /* We've already been called */
27193 +       for(i = 0; dirs[i]; i++){
27194 +               dir = getenv(dirs[i]);
27195 +               if((dir != NULL) && (*dir != '\0'))
27196 +                       break;
27197 +       }
27198 +       if((dir == NULL) || (*dir == '\0')) 
27199 +               dir = "/tmp";
27200 +
27201 +       tempdir = malloc(strlen(dir) + 2);
27202 +       if(tempdir == NULL){
27203 +               fprintf(stderr, "Failed to malloc tempdir, "
27204 +                       "errno = %d\n", errno);
27205 +               return;
27206 +       }
27207 +       strcpy(tempdir, dir);
27208 +       strcat(tempdir, "/");
27209 +}
27210 +
27211 +int make_tempfile(const char *template, char **out_tempname, int do_unlink)
27212 +{
27213 +       char tempname[MAXPATHLEN];
27214 +       int fd;
27215 +
27216 +       find_tempdir();
27217 +       if (*template != '/')
27218 +               strcpy(tempname, tempdir);
27219 +       else
27220 +               *tempname = 0;
27221 +       strcat(tempname, template);
27222 +       fd = mkstemp(tempname);
27223 +       if(fd < 0){
27224 +               fprintf(stderr, "open - cannot create %s: %s\n", tempname, 
27225 +                       strerror(errno));
27226 +               return -1;
27227 +       }
27228 +       if(do_unlink && (unlink(tempname) < 0)){
27229 +               perror("unlink");
27230 +               return -1;
27231 +       }
27232 +       if(out_tempname){
27233 +               *out_tempname = strdup(tempname);
27234 +               if(*out_tempname == NULL){
27235 +                       perror("strdup");
27236 +                       return -1;
27237 +               }
27238 +       }
27239 +       return(fd);
27240 +}
27241 +
27242 +/*
27243 + * Overrides for Emacs so that we follow Linus's tabbing style.
27244 + * Emacs will notice this stuff at the end of the file and automatically
27245 + * adjust the settings for this buffer only.  This must remain at the end
27246 + * of the file.
27247 + * ---------------------------------------------------------------------------
27248 + * Local variables:
27249 + * c-file-style: "linux"
27250 + * End:
27251 + */
27252 diff -Naur -X ../exclude-files orig/arch/um/kernel/time.c um/arch/um/kernel/time.c
27253 --- orig/arch/um/kernel/time.c  1969-12-31 19:00:00.000000000 -0500
27254 +++ um/arch/um/kernel/time.c    2004-02-12 07:09:48.000000000 -0500
27255 @@ -0,0 +1,172 @@
27256 +/* 
27257 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
27258 + * Licensed under the GPL
27259 + */
27260 +
27261 +#include <stdio.h>
27262 +#include <stdlib.h>
27263 +#include <unistd.h>
27264 +#include <time.h>
27265 +#include <sys/time.h>
27266 +#include <signal.h>
27267 +#include <errno.h>
27268 +#include "user_util.h"
27269 +#include "kern_util.h"
27270 +#include "user.h"
27271 +#include "process.h"
27272 +#include "signal_user.h"
27273 +#include "time_user.h"
27274 +
27275 +extern struct timeval xtime;
27276 +
27277 +struct timeval local_offset = { 0, 0 };
27278 +
27279 +void timer(void)
27280 +{
27281 +       gettimeofday(&xtime, NULL);
27282 +       timeradd(&xtime, &local_offset, &xtime);
27283 +}
27284 +
27285 +void set_interval(int timer_type)
27286 +{
27287 +       int usec = 1000000/hz();
27288 +       struct itimerval interval = ((struct itimerval) { { 0, usec },
27289 +                                                         { 0, usec } });
27290 +
27291 +       if(setitimer(timer_type, &interval, NULL) == -1)
27292 +               panic("setitimer failed - errno = %d\n", errno);
27293 +}
27294 +
27295 +void enable_timer(void)
27296 +{
27297 +       int usec = 1000000/hz();
27298 +       struct itimerval enable = ((struct itimerval) { { 0, usec },
27299 +                                                       { 0, usec }});
27300 +       if(setitimer(ITIMER_VIRTUAL, &enable, NULL))
27301 +               printk("enable_timer - setitimer failed, errno = %d\n",
27302 +                      errno);
27303 +}
27304 +
27305 +void switch_timers(int to_real)
27306 +{
27307 +       struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
27308 +       struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
27309 +                                                       { 0, 1000000/hz() }});
27310 +       int old, new;
27311 +
27312 +       if(to_real){
27313 +               old = ITIMER_VIRTUAL;
27314 +               new = ITIMER_REAL;
27315 +       }
27316 +       else {
27317 +               old = ITIMER_REAL;
27318 +               new = ITIMER_VIRTUAL;
27319 +       }
27320 +
27321 +       if((setitimer(old, &disable, NULL) < 0) ||
27322 +          (setitimer(new, &enable, NULL)))
27323 +               printk("switch_timers - setitimer failed, errno = %d\n",
27324 +                      errno);
27325 +}
27326 +
27327 +void idle_timer(void)
27328 +{
27329 +       if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
27330 +               panic("Couldn't unset SIGVTALRM handler");
27331 +       
27332 +       set_handler(SIGALRM, (__sighandler_t) alarm_handler, 
27333 +                   SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
27334 +       set_interval(ITIMER_REAL);
27335 +}
27336 +
27337 +static unsigned long long get_host_hz(void)
27338 +{
27339 +       char mhzline[16], *end;
27340 +       unsigned long long mhz;
27341 +       int ret, mult, rest, len;
27342 +
27343 +       ret = cpu_feature("cpu MHz", mhzline, 
27344 +                         sizeof(mhzline) / sizeof(mhzline[0]));
27345 +       if(!ret)
27346 +               panic ("Could not get host MHZ");
27347 +
27348 +       mhz = strtoul(mhzline, &end, 10);
27349 +
27350 +       /* This business is to parse a floating point number without using
27351 +        * floating types.
27352 +        */
27353 +
27354 +       rest = 0;
27355 +       mult = 0;
27356 +       if(*end == '.'){
27357 +               end++;
27358 +               len = strlen(end);
27359 +               if(len < 6)
27360 +                       mult = 6 - len;
27361 +               else if(len > 6)
27362 +                       end[6] = '\0';
27363 +               rest = strtoul(end, NULL, 10);
27364 +               while(mult-- > 0)
27365 +                       rest *= 10;
27366 +       }
27367 +
27368 +       return(1000000 * mhz + rest);
27369 +}
27370 +
27371 +unsigned long long host_hz = 0;
27372 +
27373 +void time_init(void)
27374 +{
27375 +       /* XXX This is to fill xtime with something real - otherwise by the
27376 +        * time /proc is mounted, no timers have fired, and xtime is still 0,
27377 +        * meaning it shows times of Jan 1 1970.  The real fix is to figure
27378 +        * out why no timers have happened by then.
27379 +        */
27380 +       timer();
27381 +
27382 +       host_hz = get_host_hz();
27383 +       if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
27384 +               panic("Couldn't set SIGVTALRM handler");
27385 +       set_interval(ITIMER_VIRTUAL);
27386 +}
27387 +
27388 +void do_gettimeofday(struct timeval *tv)
27389 +{
27390 +       unsigned long flags;
27391 +
27392 +       flags = time_lock();
27393 +       gettimeofday(tv, NULL);
27394 +       timeradd(tv, &local_offset, tv);
27395 +       time_unlock(flags);
27396 +}
27397 +
27398 +void do_settimeofday(struct timeval *tv)
27399 +{
27400 +       struct timeval now;
27401 +       unsigned long flags;
27402 +
27403 +       flags = time_lock();
27404 +       gettimeofday(&now, NULL);
27405 +       timersub(tv, &now, &local_offset);
27406 +       time_unlock(flags);
27407 +}
27408 +
27409 +void idle_sleep(int secs)
27410 +{
27411 +       struct timespec ts;
27412 +
27413 +       ts.tv_sec = secs;
27414 +       ts.tv_nsec = 0;
27415 +       nanosleep(&ts, NULL);
27416 +}
27417 +
27418 +/*
27419 + * Overrides for Emacs so that we follow Linus's tabbing style.
27420 + * Emacs will notice this stuff at the end of the file and automatically
27421 + * adjust the settings for this buffer only.  This must remain at the end
27422 + * of the file.
27423 + * ---------------------------------------------------------------------------
27424 + * Local variables:
27425 + * c-file-style: "linux"
27426 + * End:
27427 + */
27428 diff -Naur -X ../exclude-files orig/arch/um/kernel/time_kern.c um/arch/um/kernel/time_kern.c
27429 --- orig/arch/um/kernel/time_kern.c     1969-12-31 19:00:00.000000000 -0500
27430 +++ um/arch/um/kernel/time_kern.c       2004-02-14 06:51:31.000000000 -0500
27431 @@ -0,0 +1,205 @@
27432 +/* 
27433 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
27434 + * Licensed under the GPL
27435 + */
27436 +
27437 +#include "linux/kernel.h"
27438 +#include "linux/unistd.h"
27439 +#include "linux/stddef.h"
27440 +#include "linux/spinlock.h"
27441 +#include "linux/sched.h"
27442 +#include "linux/interrupt.h"
27443 +#include "linux/init.h"
27444 +#include "linux/delay.h"
27445 +#include "asm/irq.h"
27446 +#include "asm/param.h"
27447 +#include "asm/current.h"
27448 +#include "kern_util.h"
27449 +#include "user_util.h"
27450 +#include "time_user.h"
27451 +#include "mode.h"
27452 +
27453 +extern rwlock_t xtime_lock;
27454 +
27455 +int hz(void)
27456 +{
27457 +       return(HZ);
27458 +}
27459 +
27460 +/* Changed at early boot */
27461 +int timer_irq_inited = 0;
27462 +
27463 +/* missed_ticks will be modified after kernel memory has been 
27464 + * write-protected, so this puts it in a section which will be left 
27465 + * write-enabled.
27466 + */
27467 +int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
27468 +
27469 +static int first_tick;
27470 +static unsigned long long prev_tsc;
27471 +static long long delta;                /* Deviation per interval */
27472 +
27473 +extern unsigned long long host_hz;
27474 +
27475 +void timer_irq(union uml_pt_regs *regs)
27476 +{
27477 +       unsigned long long ticks = 0;
27478 +
27479 +       if(!timer_irq_inited){
27480 +               /* This is to ensure that ticks don't pile up when
27481 +                * the timer handler is suspended */
27482 +               first_tick = 0;
27483 +               return;
27484 +       }
27485 +
27486 +       if(first_tick){
27487 +#if defined(CONFIG_UML_REAL_TIME_CLOCK)
27488 +               unsigned long long tsc;
27489 +               /* We've had 1 tick */
27490 +               tsc = time_stamp();
27491 +
27492 +               delta += tsc - prev_tsc;
27493 +               prev_tsc = tsc;
27494 +
27495 +               ticks += (delta * HZ) / host_hz;
27496 +               delta -= (ticks * host_hz) / HZ;
27497 +#else
27498 +               ticks = 1;
27499 +#endif
27500 +       }
27501 +       else {
27502 +               prev_tsc = time_stamp();
27503 +               first_tick = 1;
27504 +       }
27505 +
27506 +       while(ticks > 0){
27507 +               do_IRQ(TIMER_IRQ, regs);
27508 +               ticks--;
27509 +       }
27510 +}
27511 +
27512 +void boot_timer_handler(int sig)
27513 +{
27514 +       struct pt_regs regs;
27515 +
27516 +       CHOOSE_MODE((void) 
27517 +                   (UPT_SC(&regs.regs) = (struct sigcontext *) (&sig + 1)),
27518 +                   (void) (regs.regs.skas.is_user = 0));
27519 +       do_timer(&regs);
27520 +}
27521 +
27522 +void um_timer(int irq, void *dev, struct pt_regs *regs)
27523 +{
27524 +       do_timer(regs);
27525 +       write_lock(&xtime_lock);
27526 +       vxtime_lock();
27527 +       timer();
27528 +       vxtime_unlock();
27529 +       write_unlock(&xtime_lock);
27530 +}
27531 +
27532 +long um_time(int * tloc)
27533 +{
27534 +       struct timeval now;
27535 +
27536 +       do_gettimeofday(&now);
27537 +       if (tloc) {
27538 +               if (put_user(now.tv_sec,tloc))
27539 +                       now.tv_sec = -EFAULT;
27540 +       }
27541 +       return now.tv_sec;
27542 +}
27543 +
27544 +long um_stime(int * tptr)
27545 +{
27546 +       int value;
27547 +       struct timeval new;
27548 +
27549 +       if (get_user(value, tptr))
27550 +                return -EFAULT;
27551 +       new.tv_sec = value;
27552 +       new.tv_usec = 0;
27553 +       do_settimeofday(&new);
27554 +       return 0;
27555 +}
27556 +
27557 +/* XXX Needs to be moved under sys-i386 */
27558 +void __delay(um_udelay_t time)
27559 +{
27560 +       /* Stolen from the i386 __loop_delay */
27561 +       int d0;
27562 +       __asm__ __volatile__(
27563 +               "\tjmp 1f\n"
27564 +               ".align 16\n"
27565 +               "1:\tjmp 2f\n"
27566 +               ".align 16\n"
27567 +               "2:\tdecl %0\n\tjns 2b"
27568 +               :"=&a" (d0)
27569 +               :"0" (time));
27570 +}
27571 +
27572 +void __udelay(um_udelay_t usecs)
27573 +{
27574 +       int i, n;
27575 +
27576 +       n = (loops_per_jiffy * HZ * usecs) / 1000000;
27577 +       for(i=0;i<n;i++) ;
27578 +}
27579 +
27580 +void __const_udelay(um_udelay_t usecs)
27581 +{
27582 +       int i, n;
27583 +
27584 +       n = (loops_per_jiffy * HZ * usecs) / 1000000;
27585 +       for(i=0;i<n;i++) ;
27586 +}
27587 +
27588 +void timer_handler(int sig, union uml_pt_regs *regs)
27589 +{
27590 +#ifdef CONFIG_SMP
27591 +       update_process_times(user_context(UPT_SP(regs)));
27592 +#endif
27593 +       if(current->processor == 0)
27594 +               timer_irq(regs);
27595 +}
27596 +
27597 +static spinlock_t timer_spinlock = SPIN_LOCK_UNLOCKED;
27598 +
27599 +unsigned long time_lock(void)
27600 +{
27601 +       unsigned long flags;
27602 +
27603 +       spin_lock_irqsave(&timer_spinlock, flags);
27604 +       return(flags);
27605 +}
27606 +
27607 +void time_unlock(unsigned long flags)
27608 +{
27609 +       spin_unlock_irqrestore(&timer_spinlock, flags);
27610 +}
27611 +
27612 +int __init timer_init(void)
27613 +{
27614 +       int err;
27615 +
27616 +       CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
27617 +       err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
27618 +       if(err != 0)
27619 +               printk(KERN_ERR "timer_init : request_irq failed - "
27620 +                      "errno = %d\n", -err);
27621 +       timer_irq_inited = 1;
27622 +       return(0);
27623 +}
27624 +
27625 +__initcall(timer_init);
27626 +
27627 +/*
27628 + * Overrides for Emacs so that we follow Linus's tabbing style.
27629 + * Emacs will notice this stuff at the end of the file and automatically
27630 + * adjust the settings for this buffer only.  This must remain at the end
27631 + * of the file.
27632 + * ---------------------------------------------------------------------------
27633 + * Local variables:
27634 + * c-file-style: "linux"
27635 + * End:
27636 + */
27637 diff -Naur -X ../exclude-files orig/arch/um/kernel/tlb.c um/arch/um/kernel/tlb.c
27638 --- orig/arch/um/kernel/tlb.c   1969-12-31 19:00:00.000000000 -0500
27639 +++ um/arch/um/kernel/tlb.c     2003-10-21 03:26:07.000000000 -0400
27640 @@ -0,0 +1,80 @@
27641 +/* 
27642 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
27643 + * Licensed under the GPL
27644 + */
27645 +
27646 +#include "linux/mm.h"
27647 +#include "asm/page.h"
27648 +#include "asm/pgalloc.h"
27649 +#include "choose-mode.h"
27650 +#include "mode_kern.h"
27651 +
27652 +void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
27653 +{
27654 +       address &= PAGE_MASK;
27655 +       flush_tlb_range(vma->vm_mm, address, address + PAGE_SIZE);
27656 +}
27657 +
27658 +void flush_tlb_all(void)
27659 +{
27660 +       flush_tlb_mm(current->mm);
27661 +}
27662 +
27663 +void flush_tlb_kernel_vm(void)
27664 +{
27665 +       CHOOSE_MODE(flush_tlb_kernel_vm_tt(), flush_tlb_kernel_vm_skas());
27666 +}
27667 +
27668 +void __flush_tlb_one(unsigned long addr)
27669 +{
27670 +       CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
27671 +}
27672 +
27673 +void flush_tlb_range(struct mm_struct *mm, unsigned long start, 
27674 +                    unsigned long end)
27675 +{
27676 +       CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, mm, start, 
27677 +                        end);
27678 +}
27679 +
27680 +void flush_tlb_mm(struct mm_struct *mm)
27681 +{
27682 +       CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
27683 +}
27684 +
27685 +void force_flush_all(void)
27686 +{
27687 +       CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
27688 +}
27689 +
27690 +
27691 +pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
27692 +{
27693 +       return(pgd_offset(mm, address));
27694 +}
27695 +
27696 +pmd_t *pmd_offset_proc(pgd_t *pgd, unsigned long address)
27697 +{
27698 +       return(pmd_offset(pgd, address));
27699 +}
27700 +
27701 +pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
27702 +{
27703 +       return(pte_offset(pmd, address));
27704 +}
27705 +
27706 +pte_t *addr_pte(struct task_struct *task, unsigned long addr)
27707 +{
27708 +       return(pte_offset(pmd_offset(pgd_offset(task->mm, addr), addr), addr));
27709 +}
27710 +
27711 +/*
27712 + * Overrides for Emacs so that we follow Linus's tabbing style.
27713 + * Emacs will notice this stuff at the end of the file and automatically
27714 + * adjust the settings for this buffer only.  This must remain at the end
27715 + * of the file.
27716 + * ---------------------------------------------------------------------------
27717 + * Local variables:
27718 + * c-file-style: "linux"
27719 + * End:
27720 + */
27721 diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_kern.c um/arch/um/kernel/trap_kern.c
27722 --- orig/arch/um/kernel/trap_kern.c     1969-12-31 19:00:00.000000000 -0500
27723 +++ um/arch/um/kernel/trap_kern.c       2003-12-22 22:48:41.000000000 -0500
27724 @@ -0,0 +1,220 @@
27725 +/* 
27726 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
27727 + * Licensed under the GPL
27728 + */
27729 +
27730 +#include "linux/kernel.h"
27731 +#include "linux/sched.h"
27732 +#include "linux/mm.h"
27733 +#include "linux/spinlock.h"
27734 +#include "linux/config.h"
27735 +#include "linux/init.h"
27736 +#include "asm/semaphore.h"
27737 +#include "asm/pgtable.h"
27738 +#include "asm/pgalloc.h"
27739 +#include "asm/a.out.h"
27740 +#include "asm/current.h"
27741 +#include "asm/irq.h"
27742 +#include "user_util.h"
27743 +#include "kern_util.h"
27744 +#include "kern.h"
27745 +#include "chan_kern.h"
27746 +#include "mconsole_kern.h"
27747 +#include "2_5compat.h"
27748 +#include "mem.h"
27749 +#include "mem_kern.h"
27750 +
27751 +unsigned long handle_page_fault(unsigned long address, unsigned long ip, 
27752 +                               int is_write, int is_user, int *code_out)
27753 +{
27754 +       struct mm_struct *mm = current->mm;
27755 +       struct vm_area_struct *vma;
27756 +       pgd_t *pgd;
27757 +       pmd_t *pmd;
27758 +       pte_t *pte;
27759 +       unsigned long page;
27760 +       int handled = 0;
27761 +
27762 +       *code_out = SEGV_MAPERR;
27763 +       down_read(&mm->mmap_sem);
27764 +       vma = find_vma(mm, address);
27765 +       if(!vma) 
27766 +               goto out;
27767 +       else if(vma->vm_start <= address) 
27768 +               goto good_area;
27769 +       else if(!(vma->vm_flags & VM_GROWSDOWN)) 
27770 +               goto out;
27771 +       else if(expand_stack(vma, address)) 
27772 +               goto out;
27773 +
27774 + good_area:
27775 +       *code_out = SEGV_ACCERR;
27776 +       if(is_write && !(vma->vm_flags & VM_WRITE)) 
27777 +               goto out;
27778 +       page = address & PAGE_MASK;
27779 +       if(page == (unsigned long) current + PAGE_SIZE)
27780 +               panic("Kernel stack overflow");
27781 +       pgd = pgd_offset(mm, page);
27782 +       pmd = pmd_offset(pgd, page);
27783 +       do {
27784 + survive:
27785 +               switch (handle_mm_fault(mm, vma, address, is_write)) {
27786 +               case 1:
27787 +                       current->min_flt++;
27788 +                       break;
27789 +               case 2:
27790 +                       current->maj_flt++;
27791 +                       break;
27792 +               default:
27793 +                       if (current->pid == 1) {
27794 +                               up_read(&mm->mmap_sem);
27795 +                               yield();
27796 +                               down_read(&mm->mmap_sem);
27797 +                               goto survive;
27798 +                       }
27799 +                       /* Fall through to bad area case */
27800 +               case 0:
27801 +                       goto out;
27802 +               }
27803 +               pte = pte_offset(pmd, page);
27804 +       } while(!pte_present(*pte));
27805 +       handled = 1;
27806 +       *pte = pte_mkyoung(*pte);
27807 +       if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
27808 +       flush_tlb_page(vma, page);
27809 + out:
27810 +       up_read(&mm->mmap_sem);
27811 +       return(handled);
27812 +}
27813 +
27814 +LIST_HEAD(physmem_remappers);
27815 +
27816 +void register_remapper(struct remapper *info)
27817 +{
27818 +       list_add(&info->list, &physmem_remappers);
27819 +}
27820 +
27821 +static int check_remapped_addr(unsigned long address, int is_write)
27822 +{
27823 +       struct remapper *remapper;
27824 +       struct list_head *ele;
27825 +       __u64 offset;
27826 +       int fd;
27827 +
27828 +       fd = phys_mapping(__pa(address), &offset);
27829 +       if(fd == -1)
27830 +               return(0);
27831 +
27832 +       list_for_each(ele, &physmem_remappers){
27833 +               remapper = list_entry(ele, struct remapper, list);
27834 +               if((*remapper->proc)(fd, address, is_write, offset))
27835 +                       return(1);
27836 +       }
27837 +
27838 +       return(0);
27839 +}
27840 +
27841 +unsigned long segv(unsigned long address, unsigned long ip, int is_write, 
27842 +                  int is_user, void *sc)
27843 +{
27844 +       struct siginfo si;
27845 +       void *catcher;
27846 +       int handled;
27847 +
27848 +        if(!is_user && (address >= start_vm) && (address < end_vm)){
27849 +                flush_tlb_kernel_vm();
27850 +                return(0);
27851 +        }
27852 +       else if(check_remapped_addr(address & PAGE_MASK, is_write))
27853 +               return(0);
27854 +       else if(current->mm == NULL)
27855 +               panic("Segfault with no mm");
27856 +
27857 +       handled = handle_page_fault(address, ip, is_write, is_user, 
27858 +                                   &si.si_code);
27859 +
27860 +       catcher = current->thread.fault_catcher;
27861 +       if(handled)
27862 +               return(0);
27863 +       else if(catcher != NULL){
27864 +               current->thread.fault_addr = (void *) address;
27865 +               do_longjmp(catcher, 1);
27866 +       } 
27867 +       else if(current->thread.fault_addr != NULL)
27868 +               panic("fault_addr set but no fault catcher");
27869 +       else if(arch_fixup(ip, sc))
27870 +               return(0);
27871 +
27872 +       if(!is_user) 
27873 +               panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", 
27874 +                     address, ip);
27875 +       si.si_signo = SIGSEGV;
27876 +       si.si_addr = (void *) address;
27877 +       current->thread.cr2 = address;
27878 +       current->thread.err = is_write;
27879 +       force_sig_info(SIGSEGV, &si, current);
27880 +       return(0);
27881 +}
27882 +
27883 +void bad_segv(unsigned long address, unsigned long ip, int is_write)
27884 +{
27885 +       struct siginfo si;
27886 +
27887 +       si.si_signo = SIGSEGV;
27888 +       si.si_code = SEGV_ACCERR;
27889 +       si.si_addr = (void *) address;
27890 +       current->thread.cr2 = address;
27891 +       current->thread.err = is_write;
27892 +       force_sig_info(SIGSEGV, &si, current);
27893 +}
27894 +
27895 +void relay_signal(int sig, union uml_pt_regs *regs)
27896 +{
27897 +       if(arch_handle_signal(sig, regs)) return;
27898 +       if(!UPT_IS_USER(regs))
27899 +               panic("Kernel mode signal %d", sig);
27900 +       force_sig(sig, current);
27901 +}
27902 +
27903 +void bus_handler(int sig, union uml_pt_regs *regs)
27904 +{
27905 +       if(current->thread.fault_catcher != NULL)
27906 +               do_longjmp(current->thread.fault_catcher, 1);
27907 +       else relay_signal(sig, regs);
27908 +}
27909 +
27910 +void winch(int sig, union uml_pt_regs *regs)
27911 +{
27912 +       do_IRQ(WINCH_IRQ, regs);
27913 +}
27914 +
27915 +void trap_init(void)
27916 +{
27917 +}
27918 +
27919 +spinlock_t trap_lock = SPIN_LOCK_UNLOCKED;
27920 +
27921 +static int trap_index = 0;
27922 +
27923 +int next_trap_index(int limit)
27924 +{
27925 +       int ret;
27926 +
27927 +       spin_lock(&trap_lock);
27928 +       ret = trap_index;
27929 +       if(++trap_index == limit)
27930 +               trap_index = 0;
27931 +       spin_unlock(&trap_lock);
27932 +       return(ret);
27933 +}
27934 +
27935 +/*
27936 + * Overrides for Emacs so that we follow Linus's tabbing style.
27937 + * Emacs will notice this stuff at the end of the file and automatically
27938 + * adjust the settings for this buffer only.  This must remain at the end
27939 + * of the file.
27940 + * ---------------------------------------------------------------------------
27941 + * Local variables:
27942 + * c-file-style: "linux"
27943 + * End:
27944 + */
27945 diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_user.c um/arch/um/kernel/trap_user.c
27946 --- orig/arch/um/kernel/trap_user.c     1969-12-31 19:00:00.000000000 -0500
27947 +++ um/arch/um/kernel/trap_user.c       2004-01-31 02:47:39.000000000 -0500
27948 @@ -0,0 +1,138 @@
27949 +/* 
27950 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
27951 + * Licensed under the GPL
27952 + */
27953 +
27954 +#include <stdlib.h>
27955 +#include <errno.h>
27956 +#include <setjmp.h>
27957 +#include <signal.h>
27958 +#include <sys/time.h>
27959 +#include <sys/ptrace.h>
27960 +#include <sys/wait.h>
27961 +#include <asm/page.h>
27962 +#include <asm/unistd.h>
27963 +#include <asm/ptrace.h>
27964 +#include "init.h"
27965 +#include "sysdep/ptrace.h"
27966 +#include "sigcontext.h"
27967 +#include "sysdep/sigcontext.h"
27968 +#include "irq_user.h"
27969 +#include "frame_user.h"
27970 +#include "signal_user.h"
27971 +#include "time_user.h"
27972 +#include "task.h"
27973 +#include "mode.h"
27974 +#include "choose-mode.h"
27975 +#include "kern_util.h"
27976 +#include "user_util.h"
27977 +#include "os.h"
27978 +
27979 +void kill_child_dead(int pid)
27980 +{
27981 +       kill(pid, SIGKILL);
27982 +       kill(pid, SIGCONT);
27983 +       while(waitpid(pid, NULL, 0) > 0) kill(pid, SIGCONT);
27984 +}
27985 +
27986 +/* Unlocked - don't care if this is a bit off */
27987 +int nsegfaults = 0;
27988 +
27989 +struct {
27990 +       unsigned long address;
27991 +       int is_write;
27992 +       int pid;
27993 +       unsigned long sp;
27994 +       int is_user;
27995 +} segfault_record[1024];
27996 +
27997 +void segv_handler(int sig, union uml_pt_regs *regs)
27998 +{
27999 +       int index, max;
28000 +
28001 +       if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){
28002 +               bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), 
28003 +                        UPT_FAULT_WRITE(regs));
28004 +               return;
28005 +       }
28006 +       max = sizeof(segfault_record)/sizeof(segfault_record[0]);
28007 +       index = next_trap_index(max);
28008 +
28009 +       nsegfaults++;
28010 +       segfault_record[index].address = UPT_FAULT_ADDR(regs);
28011 +       segfault_record[index].pid = os_getpid();
28012 +       segfault_record[index].is_write = UPT_FAULT_WRITE(regs);
28013 +       segfault_record[index].sp = UPT_SP(regs);
28014 +       segfault_record[index].is_user = UPT_IS_USER(regs);
28015 +       segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs),
28016 +            UPT_IS_USER(regs), regs);
28017 +}
28018 +
28019 +void usr2_handler(int sig, union uml_pt_regs *regs)
28020 +{
28021 +       CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
28022 +}
28023 +
28024 +struct signal_info sig_info[] = {
28025 +       [ SIGTRAP ] { .handler          = relay_signal,
28026 +                     .is_irq           = 0 },
28027 +       [ SIGFPE ] { .handler           = relay_signal,
28028 +                    .is_irq            = 0 },
28029 +       [ SIGILL ] { .handler           = relay_signal,
28030 +                    .is_irq            = 0 },
28031 +       [ SIGWINCH ] { .handler         = winch,
28032 +                      .is_irq          = 1 },
28033 +       [ SIGBUS ] { .handler           = bus_handler,
28034 +                    .is_irq            = 0 },
28035 +       [ SIGSEGV] { .handler           = segv_handler,
28036 +                    .is_irq            = 0 },
28037 +       [ SIGIO ] { .handler            = sigio_handler,
28038 +                   .is_irq             = 1 },
28039 +       [ SIGVTALRM ] { .handler        = timer_handler,
28040 +                       .is_irq         = 1 },
28041 +        [ SIGALRM ] { .handler          = timer_handler,
28042 +                      .is_irq           = 1 },
28043 +       [ SIGUSR2 ] { .handler          = usr2_handler,
28044 +                     .is_irq           = 0 },
28045 +};
28046 +
28047 +void sig_handler(int sig, struct sigcontext sc)
28048 +{
28049 +       CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
28050 +                        sig, &sc);
28051 +}
28052 +
28053 +extern int timer_irq_inited, missed_ticks[];
28054 +
28055 +void alarm_handler(int sig, struct sigcontext sc)
28056 +{
28057 +       if(!timer_irq_inited) return;
28058 +       missed_ticks[cpu()]++;
28059 +
28060 +       if(sig == SIGALRM)
28061 +               switch_timers(0);
28062 +
28063 +       CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
28064 +                        sig, &sc);
28065 +
28066 +       if(sig == SIGALRM)
28067 +               switch_timers(1);
28068 +}
28069 +
28070 +void do_longjmp(void *b, int val)
28071 +{
28072 +       sigjmp_buf *buf = b;
28073 +
28074 +       siglongjmp(*buf, val);
28075 +}
28076 +
28077 +/*
28078 + * Overrides for Emacs so that we follow Linus's tabbing style.
28079 + * Emacs will notice this stuff at the end of the file and automatically
28080 + * adjust the settings for this buffer only.  This must remain at the end
28081 + * of the file.
28082 + * ---------------------------------------------------------------------------
28083 + * Local variables:
28084 + * c-file-style: "linux"
28085 + * End:
28086 + */
28087 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_kern.c um/arch/um/kernel/tt/exec_kern.c
28088 --- orig/arch/um/kernel/tt/exec_kern.c  1969-12-31 19:00:00.000000000 -0500
28089 +++ um/arch/um/kernel/tt/exec_kern.c    2003-11-07 02:23:10.000000000 -0500
28090 @@ -0,0 +1,84 @@
28091 +/* 
28092 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28093 + * Licensed under the GPL
28094 + */
28095 +
28096 +#include "linux/kernel.h"
28097 +#include "linux/mm.h"
28098 +#include "asm/signal.h"
28099 +#include "asm/ptrace.h"
28100 +#include "asm/uaccess.h"
28101 +#include "asm/pgalloc.h"
28102 +#include "user_util.h"
28103 +#include "kern_util.h"
28104 +#include "irq_user.h"
28105 +#include "time_user.h"
28106 +#include "mem_user.h"
28107 +#include "os.h"
28108 +#include "tlb.h"
28109 +#include "mode.h"
28110 +
28111 +static int exec_tramp(void *sig_stack)
28112 +{
28113 +       init_new_thread_stack(sig_stack, NULL);
28114 +       init_new_thread_signals(1);
28115 +       os_stop_process(os_getpid());
28116 +       return(0);
28117 +}
28118 +
28119 +void flush_thread_tt(void)
28120 +{
28121 +       unsigned long stack;
28122 +       int new_pid;
28123 +
28124 +       stack = alloc_stack(0, 0);
28125 +       if(stack == 0){
28126 +               printk(KERN_ERR 
28127 +                      "flush_thread : failed to allocate temporary stack\n");
28128 +               do_exit(SIGKILL);
28129 +       }
28130 +               
28131 +       new_pid = start_fork_tramp((void *) current->thread.kernel_stack,
28132 +                                  stack, 0, exec_tramp);
28133 +       if(new_pid < 0){
28134 +               printk(KERN_ERR 
28135 +                      "flush_thread : new thread failed, errno = %d\n",
28136 +                      -new_pid);
28137 +               do_exit(SIGKILL);
28138 +       }
28139 +
28140 +       if(current->processor == 0)
28141 +               forward_interrupts(new_pid);
28142 +       current->thread.request.op = OP_EXEC;
28143 +       current->thread.request.u.exec.pid = new_pid;
28144 +       unprotect_stack((unsigned long) current);
28145 +       os_usr1_process(os_getpid());
28146 +
28147 +       enable_timer();
28148 +       free_page(stack);
28149 +       protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
28150 +       task_protections((unsigned long) current);
28151 +       force_flush_all();
28152 +       unblock_signals();
28153 +}
28154 +
28155 +void start_thread_tt(struct pt_regs *regs, unsigned long eip, 
28156 +                    unsigned long esp)
28157 +{
28158 +       set_fs(USER_DS);
28159 +       flush_tlb_mm(current->mm);
28160 +       PT_REGS_IP(regs) = eip;
28161 +       PT_REGS_SP(regs) = esp;
28162 +       PT_FIX_EXEC_STACK(esp);
28163 +}
28164 +
28165 +/*
28166 + * Overrides for Emacs so that we follow Linus's tabbing style.
28167 + * Emacs will notice this stuff at the end of the file and automatically
28168 + * adjust the settings for this buffer only.  This must remain at the end
28169 + * of the file.
28170 + * ---------------------------------------------------------------------------
28171 + * Local variables:
28172 + * c-file-style: "linux"
28173 + * End:
28174 + */
28175 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_user.c um/arch/um/kernel/tt/exec_user.c
28176 --- orig/arch/um/kernel/tt/exec_user.c  1969-12-31 19:00:00.000000000 -0500
28177 +++ um/arch/um/kernel/tt/exec_user.c    2003-10-21 03:26:07.000000000 -0400
28178 @@ -0,0 +1,49 @@
28179 +/* 
28180 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
28181 + * Licensed under the GPL
28182 + */
28183 +
28184 +#include <stdio.h>
28185 +#include <unistd.h>
28186 +#include <stdlib.h>
28187 +#include <sched.h>
28188 +#include <errno.h>
28189 +#include <sys/wait.h>
28190 +#include <sys/ptrace.h>
28191 +#include <signal.h>
28192 +#include "user_util.h"
28193 +#include "kern_util.h"
28194 +#include "user.h"
28195 +#include "ptrace_user.h"
28196 +
28197 +void do_exec(int old_pid, int new_pid)
28198 +{
28199 +       unsigned long regs[FRAME_SIZE];
28200 +
28201 +       if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) ||
28202 +          (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0) ||
28203 +          (waitpid(new_pid, 0, WUNTRACED) < 0))
28204 +               tracer_panic("do_exec failed to attach proc - errno = %d",
28205 +                            errno);
28206 +
28207 +       if(ptrace_getregs(old_pid, regs) < 0)
28208 +               tracer_panic("do_exec failed to get registers - errno = %d",
28209 +                            errno);
28210 +
28211 +       kill(old_pid, SIGKILL);
28212 +
28213 +       if(ptrace_setregs(new_pid, regs) < 0)
28214 +               tracer_panic("do_exec failed to start new proc - errno = %d",
28215 +                            errno);
28216 +}
28217 +
28218 +/*
28219 + * Overrides for Emacs so that we follow Linus's tabbing style.
28220 + * Emacs will notice this stuff at the end of the file and automatically
28221 + * adjust the settings for this buffer only.  This must remain at the end
28222 + * of the file.
28223 + * ---------------------------------------------------------------------------
28224 + * Local variables:
28225 + * c-file-style: "linux"
28226 + * End:
28227 + */
28228 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb.c um/arch/um/kernel/tt/gdb.c
28229 --- orig/arch/um/kernel/tt/gdb.c        1969-12-31 19:00:00.000000000 -0500
28230 +++ um/arch/um/kernel/tt/gdb.c  2003-10-21 03:26:07.000000000 -0400
28231 @@ -0,0 +1,278 @@
28232 +/* 
28233 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28234 + * Licensed under the GPL
28235 + */
28236 +
28237 +#include <stdio.h>
28238 +#include <stdlib.h>
28239 +#include <errno.h>
28240 +#include <string.h>
28241 +#include <signal.h>
28242 +#include <sys/ptrace.h>
28243 +#include <sys/types.h>
28244 +#include "uml-config.h"
28245 +#include "kern_constants.h"
28246 +#include "chan_user.h"
28247 +#include "init.h"
28248 +#include "user.h"
28249 +#include "debug.h"
28250 +#include "kern_util.h"
28251 +#include "user_util.h"
28252 +#include "tt.h"
28253 +#include "sysdep/thread.h"
28254 +
28255 +extern int debugger_pid;
28256 +extern int debugger_fd;
28257 +extern int debugger_parent;
28258 +
28259 +int detach(int pid, int sig)
28260 +{
28261 +       return(ptrace(PTRACE_DETACH, pid, 0, sig));
28262 +}
28263 +
28264 +int attach(int pid)
28265 +{
28266 +       int err;
28267 +
28268 +       err = ptrace(PTRACE_ATTACH, pid, 0, 0);
28269 +       if(err < 0) return(-errno);
28270 +       else return(err);
28271 +}
28272 +
28273 +int cont(int pid)
28274 +{
28275 +       return(ptrace(PTRACE_CONT, pid, 0, 0));
28276 +}
28277 +
28278 +#ifdef UML_CONFIG_PT_PROXY
28279 +
28280 +int debugger_signal(int status, pid_t pid)
28281 +{
28282 +       return(debugger_proxy(status, pid));
28283 +}
28284 +
28285 +void child_signal(pid_t pid, int status)
28286 +{
28287 +       child_proxy(pid, status);
28288 +}
28289 +
28290 +static void gdb_announce(char *dev_name, int dev)
28291 +{
28292 +       printf("gdb assigned device '%s'\n", dev_name);
28293 +}
28294 +
28295 +static struct chan_opts opts = {
28296 +       .announce       = gdb_announce,
28297 +       .xterm_title    = "UML kernel debugger",
28298 +       .raw            = 0,
28299 +       .tramp_stack    = 0,
28300 +       .in_kernel      = 0,
28301 +};
28302 +
28303 +/* Accessed by the tracing thread, which automatically serializes access */
28304 +static void *xterm_data;
28305 +static int xterm_fd;
28306 +
28307 +extern void *xterm_init(char *, int, struct chan_opts *);
28308 +extern int xterm_open(int, int, int, void *, char **);
28309 +extern void xterm_close(int, void *);
28310 +
28311 +int open_gdb_chan(void)
28312 +{
28313 +       char stack[UM_KERN_PAGE_SIZE], *dummy;
28314 +
28315 +       opts.tramp_stack = (unsigned long) stack;
28316 +       xterm_data = xterm_init("", 0, &opts);
28317 +       xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy);
28318 +       return(xterm_fd);
28319 +}
28320 +
28321 +static void exit_debugger_cb(void *unused)
28322 +{
28323 +       if(debugger_pid != -1){
28324 +               if(gdb_pid != -1){
28325 +                       fake_child_exit();
28326 +                       gdb_pid = -1;
28327 +               }
28328 +               else kill_child_dead(debugger_pid);
28329 +               debugger_pid = -1;
28330 +               if(debugger_parent != -1)
28331 +                       detach(debugger_parent, SIGINT);
28332 +       }
28333 +       if(xterm_data != NULL) xterm_close(xterm_fd, xterm_data);
28334 +}
28335 +
28336 +static void exit_debugger(void)
28337 +{
28338 +       initial_thread_cb(exit_debugger_cb, NULL);
28339 +}
28340 +
28341 +__uml_exitcall(exit_debugger);
28342 +
28343 +struct gdb_data {
28344 +       char *str;
28345 +       int err;
28346 +};
28347 +
28348 +static void config_gdb_cb(void *arg)
28349 +{
28350 +       struct gdb_data *data = arg;
28351 +       void *task;
28352 +       int pid;
28353 +
28354 +       data->err = -1;
28355 +       if(debugger_pid != -1) exit_debugger_cb(NULL);
28356 +       if(!strncmp(data->str, "pid,", strlen("pid,"))){
28357 +               data->str += strlen("pid,");
28358 +               pid = strtoul(data->str, NULL, 0);
28359 +               task = cpu_tasks[0].task;
28360 +               debugger_pid = attach_debugger(TASK_EXTERN_PID(task), pid, 0);
28361 +               if(debugger_pid != -1){
28362 +                       data->err = 0;
28363 +                       gdb_pid = pid;
28364 +               }
28365 +               return;
28366 +       }
28367 +       data->err = 0;
28368 +       debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
28369 +       init_proxy(debugger_pid, 0, 0);
28370 +}
28371 +
28372 +int gdb_config(char *str)
28373 +{
28374 +       struct gdb_data data;
28375 +
28376 +       if(*str++ != '=') return(-1);
28377 +       data.str = str;
28378 +       initial_thread_cb(config_gdb_cb, &data);
28379 +       return(data.err);
28380 +}
28381 +
28382 +void remove_gdb_cb(void *unused)
28383 +{
28384 +       exit_debugger_cb(NULL);
28385 +}
28386 +
28387 +int gdb_remove(char *unused)
28388 +{
28389 +       initial_thread_cb(remove_gdb_cb, NULL);
28390 +       return(0);
28391 +}
28392 +
28393 +void signal_usr1(int sig)
28394 +{
28395 +       if(debugger_pid != -1){
28396 +               printk(UM_KERN_ERR "The debugger is already running\n");
28397 +               return;
28398 +       }
28399 +       debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
28400 +       init_proxy(debugger_pid, 0, 0);
28401 +}
28402 +
28403 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
28404 +{
28405 +       int pid, status;
28406 +
28407 +       pid = start_debugger(linux_prog, startup, stop, &debugger_fd);
28408 +       status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
28409 +       if(pid < 0){
28410 +               cont(idle_pid);
28411 +               return(-1);
28412 +       }
28413 +       init_proxy(pid, 1, status);
28414 +       return(pid);
28415 +}
28416 +
28417 +int attach_debugger(int idle_pid, int pid, int stop)
28418 +{
28419 +       int status = 0, err;
28420 +
28421 +       err = attach(pid);
28422 +       if(err < 0){
28423 +               printf("Failed to attach pid %d, errno = %d\n", pid, -err);
28424 +               return(-1);
28425 +       }
28426 +       if(stop) status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
28427 +       init_proxy(pid, 1, status);
28428 +       return(pid);
28429 +}
28430 +
28431 +#ifdef notdef /* Put this back in when it does something useful */
28432 +static int __init uml_gdb_init_setup(char *line, int *add)
28433 +{
28434 +       gdb_init = uml_strdup(line);
28435 +       return 0;
28436 +}
28437 +
28438 +__uml_setup("gdb=", uml_gdb_init_setup, 
28439 +"gdb=<channel description>\n\n"
28440 +);
28441 +#endif
28442 +
28443 +static int __init uml_gdb_pid_setup(char *line, int *add)
28444 +{
28445 +       gdb_pid = strtoul(line, NULL, 0);
28446 +       *add = 0;
28447 +       return 0;
28448 +}
28449 +
28450 +__uml_setup("gdb-pid=", uml_gdb_pid_setup, 
28451 +"gdb-pid=<pid>\n"
28452 +"    gdb-pid is used to attach an external debugger to UML.  This may be\n"
28453 +"    an already-running gdb or a debugger-like process like strace.\n\n"
28454 +);
28455 +
28456 +#else
28457 +
28458 +int debugger_signal(int status, pid_t pid){ return(0); }
28459 +void child_signal(pid_t pid, int status){ }
28460 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
28461 +{
28462 +       printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
28463 +       kill_child_dead(idle_pid);
28464 +       exit(1);
28465 +}
28466 +
28467 +void signal_usr1(int sig)
28468 +{
28469 +       printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
28470 +}
28471 +
28472 +int attach_debugger(int idle_pid, int pid, int stop)
28473 +{
28474 +       printk(UM_KERN_ERR "attach_debugger called when CONFIG_PT_PROXY "
28475 +              "is off\n");
28476 +       return(-1);
28477 +}
28478 +
28479 +int config_gdb(char *str)
28480 +{
28481 +       return(-1);
28482 +}
28483 +
28484 +int remove_gdb(void)
28485 +{
28486 +       return(-1);
28487 +}
28488 +
28489 +int init_parent_proxy(int pid)
28490 +{
28491 +       return(-1);
28492 +}
28493 +
28494 +void debugger_parent_signal(int status, int pid)
28495 +{
28496 +}
28497 +
28498 +#endif
28499 +
28500 +/*
28501 + * Overrides for Emacs so that we follow Linus's tabbing style.
28502 + * Emacs will notice this stuff at the end of the file and automatically
28503 + * adjust the settings for this buffer only.  This must remain at the end
28504 + * of the file.
28505 + * ---------------------------------------------------------------------------
28506 + * Local variables:
28507 + * c-file-style: "linux"
28508 + * End:
28509 + */
28510 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb_kern.c um/arch/um/kernel/tt/gdb_kern.c
28511 --- orig/arch/um/kernel/tt/gdb_kern.c   1969-12-31 19:00:00.000000000 -0500
28512 +++ um/arch/um/kernel/tt/gdb_kern.c     2003-10-21 03:26:07.000000000 -0400
28513 @@ -0,0 +1,40 @@
28514 +/* 
28515 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28516 + * Licensed under the GPL
28517 + */
28518 +
28519 +#include "linux/init.h"
28520 +#include "linux/config.h"
28521 +#include "mconsole_kern.h"
28522 +
28523 +#ifdef CONFIG_MCONSOLE
28524 +
28525 +extern int gdb_config(char *str);
28526 +extern int gdb_remove(char *unused);
28527 +
28528 +static struct mc_device gdb_mc = {
28529 +       .name           = "gdb",
28530 +       .config         = gdb_config,
28531 +       .remove         = gdb_remove,
28532 +};
28533 +
28534 +int gdb_mc_init(void)
28535 +{
28536 +       mconsole_register_dev(&gdb_mc);
28537 +       return(0);
28538 +}
28539 +
28540 +__initcall(gdb_mc_init);
28541 +
28542 +#endif
28543 +
28544 +/*
28545 + * Overrides for Emacs so that we follow Linus's tabbing style.
28546 + * Emacs will notice this stuff at the end of the file and automatically
28547 + * adjust the settings for this buffer only.  This must remain at the end
28548 + * of the file.
28549 + * ---------------------------------------------------------------------------
28550 + * Local variables:
28551 + * c-file-style: "linux"
28552 + * End:
28553 + */
28554 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/debug.h um/arch/um/kernel/tt/include/debug.h
28555 --- orig/arch/um/kernel/tt/include/debug.h      1969-12-31 19:00:00.000000000 -0500
28556 +++ um/arch/um/kernel/tt/include/debug.h        2003-10-21 03:26:07.000000000 -0400
28557 @@ -0,0 +1,29 @@
28558 +/* 
28559 + * Copyright (C) 2000, 2001, 2002  Jeff Dike (jdike@karaya.com) and
28560 + * Lars Brinkhoff.
28561 + * Licensed under the GPL
28562 + */
28563 +
28564 +#ifndef __DEBUG_H
28565 +#define __DEBUG_H
28566 +
28567 +extern int debugger_proxy(int status, pid_t pid);
28568 +extern void child_proxy(pid_t pid, int status);
28569 +extern void init_proxy (pid_t pid, int waiting, int status);
28570 +extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
28571 +extern void fake_child_exit(void);
28572 +extern int gdb_config(char *str);
28573 +extern int gdb_remove(char *unused);
28574 +
28575 +#endif
28576 +
28577 +/*
28578 + * Overrides for Emacs so that we follow Linus's tabbing style.
28579 + * Emacs will notice this stuff at the end of the file and automatically
28580 + * adjust the settings for this buffer only.  This must remain at the end
28581 + * of the file.
28582 + * ---------------------------------------------------------------------------
28583 + * Local variables:
28584 + * c-file-style: "linux"
28585 + * End:
28586 + */
28587 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mmu.h um/arch/um/kernel/tt/include/mmu.h
28588 --- orig/arch/um/kernel/tt/include/mmu.h        1969-12-31 19:00:00.000000000 -0500
28589 +++ um/arch/um/kernel/tt/include/mmu.h  2003-10-21 03:26:07.000000000 -0400
28590 @@ -0,0 +1,23 @@
28591 +/* 
28592 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28593 + * Licensed under the GPL
28594 + */
28595 +
28596 +#ifndef __TT_MMU_H
28597 +#define __TT_MMU_H
28598 +
28599 +struct mmu_context_tt {
28600 +};
28601 +
28602 +#endif
28603 +
28604 +/*
28605 + * Overrides for Emacs so that we follow Linus's tabbing style.
28606 + * Emacs will notice this stuff at the end of the file and automatically
28607 + * adjust the settings for this buffer only.  This must remain at the end
28608 + * of the file.
28609 + * ---------------------------------------------------------------------------
28610 + * Local variables:
28611 + * c-file-style: "linux"
28612 + * End:
28613 + */
28614 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode.h um/arch/um/kernel/tt/include/mode.h
28615 --- orig/arch/um/kernel/tt/include/mode.h       1969-12-31 19:00:00.000000000 -0500
28616 +++ um/arch/um/kernel/tt/include/mode.h 2003-11-07 01:42:09.000000000 -0500
28617 @@ -0,0 +1,38 @@
28618 +/* 
28619 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28620 + * Licensed under the GPL
28621 + */
28622 +
28623 +#ifndef __MODE_TT_H__
28624 +#define __MODE_TT_H__
28625 +
28626 +#include "sysdep/ptrace.h"
28627 +
28628 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
28629 +
28630 +extern int tracing_pid;
28631 +
28632 +extern int tracer(int (*init_proc)(void *), void *sp);
28633 +extern void user_time_init_tt(void);
28634 +extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data);
28635 +extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, 
28636 +                             void *data);
28637 +extern void sig_handler_common_tt(int sig, void *sc);
28638 +extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
28639 +extern void reboot_tt(void);
28640 +extern void halt_tt(void);
28641 +extern int is_tracer_winch(int pid, int fd, void *data);
28642 +extern void kill_off_processes_tt(void);
28643 +
28644 +#endif
28645 +
28646 +/*
28647 + * Overrides for Emacs so that we follow Linus's tabbing style.
28648 + * Emacs will notice this stuff at the end of the file and automatically
28649 + * adjust the settings for this buffer only.  This must remain at the end
28650 + * of the file.
28651 + * ---------------------------------------------------------------------------
28652 + * Local variables:
28653 + * c-file-style: "linux"
28654 + * End:
28655 + */
28656 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode_kern.h um/arch/um/kernel/tt/include/mode_kern.h
28657 --- orig/arch/um/kernel/tt/include/mode_kern.h  1969-12-31 19:00:00.000000000 -0500
28658 +++ um/arch/um/kernel/tt/include/mode_kern.h    2003-10-21 03:26:07.000000000 -0400
28659 @@ -0,0 +1,52 @@
28660 +/* 
28661 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28662 + * Licensed under the GPL
28663 + */
28664 +
28665 +#ifndef __TT_MODE_KERN_H__
28666 +#define __TT_MODE_KERN_H__
28667 +
28668 +#include "linux/sched.h"
28669 +#include "asm/page.h"
28670 +#include "asm/ptrace.h"
28671 +#include "asm/uaccess.h"
28672 +
28673 +extern void *_switch_to_tt(void *prev, void *next);
28674 +extern void flush_thread_tt(void);
28675 +extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, 
28676 +                          unsigned long esp);
28677 +extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
28678 +                         unsigned long stack_top, struct task_struct *p, 
28679 +                         struct pt_regs *regs);
28680 +extern void release_thread_tt(struct task_struct *task);
28681 +extern void exit_thread_tt(void);
28682 +extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
28683 +extern void init_idle_tt(void);
28684 +extern void flush_tlb_kernel_vm_tt(void);
28685 +extern void __flush_tlb_one_tt(unsigned long addr);
28686 +extern void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start, 
28687 +                              unsigned long end);
28688 +extern void flush_tlb_mm_tt(struct mm_struct *mm);
28689 +extern void force_flush_all_tt(void);
28690 +extern long execute_syscall_tt(void *r);
28691 +extern void before_mem_tt(unsigned long brk_start);
28692 +extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, 
28693 +                                      unsigned long *task_size_out);
28694 +extern int start_uml_tt(void);
28695 +extern int external_pid_tt(struct task_struct *task);
28696 +extern int thread_pid_tt(struct thread_struct *thread);
28697 +
28698 +#define kmem_end_tt (host_task_size - ABOVE_KMEM)
28699 +
28700 +#endif
28701 +
28702 +/*
28703 + * Overrides for Emacs so that we follow Linus's tabbing style.
28704 + * Emacs will notice this stuff at the end of the file and automatically
28705 + * adjust the settings for this buffer only.  This must remain at the end
28706 + * of the file.
28707 + * ---------------------------------------------------------------------------
28708 + * Local variables:
28709 + * c-file-style: "linux"
28710 + * End:
28711 + */
28712 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/ptrace-tt.h um/arch/um/kernel/tt/include/ptrace-tt.h
28713 --- orig/arch/um/kernel/tt/include/ptrace-tt.h  1969-12-31 19:00:00.000000000 -0500
28714 +++ um/arch/um/kernel/tt/include/ptrace-tt.h    2003-10-21 03:26:07.000000000 -0400
28715 @@ -0,0 +1,26 @@
28716 +/* 
28717 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
28718 + * Licensed under the GPL
28719 + */
28720 +
28721 +#ifndef __PTRACE_TT_H
28722 +#define __PTRACE_TT_H
28723 +
28724 +#include "uml-config.h"
28725 +
28726 +#ifdef UML_CONFIG_MODE_TT
28727 +#include "sysdep/sc.h"
28728 +#endif
28729 +
28730 +#endif
28731 +
28732 +/*
28733 + * Overrides for Emacs so that we follow Linus's tabbing style.
28734 + * Emacs will notice this stuff at the end of the file and automatically
28735 + * adjust the settings for this buffer only.  This must remain at the end
28736 + * of the file.
28737 + * ---------------------------------------------------------------------------
28738 + * Local variables:
28739 + * c-file-style: "linux"
28740 + * End:
28741 + */
28742 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/tt.h um/arch/um/kernel/tt/include/tt.h
28743 --- orig/arch/um/kernel/tt/include/tt.h 1969-12-31 19:00:00.000000000 -0500
28744 +++ um/arch/um/kernel/tt/include/tt.h   2003-10-21 03:26:07.000000000 -0400
28745 @@ -0,0 +1,46 @@
28746 +/* 
28747 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28748 + * Licensed under the GPL
28749 + */
28750 +
28751 +#ifndef __TT_H__
28752 +#define __TT_H__
28753 +
28754 +#include "sysdep/ptrace.h"
28755 +
28756 +extern int gdb_pid;
28757 +extern int debug;
28758 +extern int debug_stop;
28759 +extern int debug_trace;
28760 +
28761 +extern int honeypot;
28762 +
28763 +extern int fork_tramp(void *sig_stack);
28764 +extern int do_proc_op(void *t, int proc_id);
28765 +extern int tracer(int (*init_proc)(void *), void *sp);
28766 +extern void attach_process(int pid);
28767 +extern void tracer_panic(char *format, ...);
28768 +extern void set_init_pid(int pid);
28769 +extern int set_user_mode(void *task);
28770 +extern void set_tracing(void *t, int tracing);
28771 +extern int is_tracing(void *task);
28772 +extern int singlestepping_tt(void *t);
28773 +extern void clear_singlestep(void *t);
28774 +extern void syscall_handler(int sig, union uml_pt_regs *regs);
28775 +extern void exit_kernel(int pid, void *task);
28776 +extern int do_syscall(void *task, int pid);
28777 +extern int is_valid_pid(int pid);
28778 +extern void remap_data(void *segment_start, void *segment_end, int w);
28779 +
28780 +#endif
28781 +
28782 +/*
28783 + * Overrides for Emacs so that we follow Linus's tabbing style.
28784 + * Emacs will notice this stuff at the end of the file and automatically
28785 + * adjust the settings for this buffer only.  This must remain at the end
28786 + * of the file.
28787 + * ---------------------------------------------------------------------------
28788 + * Local variables:
28789 + * c-file-style: "linux"
28790 + * End:
28791 + */
28792 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/uaccess.h um/arch/um/kernel/tt/include/uaccess.h
28793 --- orig/arch/um/kernel/tt/include/uaccess.h    1969-12-31 19:00:00.000000000 -0500
28794 +++ um/arch/um/kernel/tt/include/uaccess.h      2003-11-12 08:37:20.000000000 -0500
28795 @@ -0,0 +1,71 @@
28796 +/* 
28797 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
28798 + * Licensed under the GPL
28799 + */
28800 +
28801 +#ifndef __TT_UACCESS_H
28802 +#define __TT_UACCESS_H
28803 +
28804 +#include "linux/string.h"
28805 +#include "linux/sched.h"
28806 +#include "asm/processor.h"
28807 +#include "asm/errno.h"
28808 +#include "asm/current.h"
28809 +#include "asm/a.out.h"
28810 +#include "uml_uaccess.h"
28811 +
28812 +#define ABOVE_KMEM (16 * 1024 * 1024)
28813 +
28814 +extern unsigned long end_vm;
28815 +extern unsigned long uml_physmem;
28816 +
28817 +#define under_task_size(addr, size) \
28818 +       (((unsigned long) (addr) < TASK_SIZE) && \
28819 +         (((unsigned long) (addr) + (size)) < TASK_SIZE))
28820 +
28821 +#define is_stack(addr, size) \
28822 +       (((unsigned long) (addr) < STACK_TOP) && \
28823 +        ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
28824 +        (((unsigned long) (addr) + (size)) <= STACK_TOP))
28825 +
28826 +#define access_ok_tt(type, addr, size) \
28827 +       ((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \
28828 +         (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
28829 +          (under_task_size(addr, size) || is_stack(addr, size))))
28830 +
28831 +static inline int verify_area_tt(int type, const void * addr, 
28832 +                                unsigned long size)
28833 +{
28834 +       return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
28835 +}
28836 +
28837 +extern unsigned long get_fault_addr(void);
28838 +
28839 +extern int __do_copy_from_user(void *to, const void *from, int n,
28840 +                              void **fault_addr, void **fault_catcher);
28841 +extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
28842 +                                 void **fault_addr, void **fault_catcher);
28843 +extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
28844 +                          void **fault_catcher);
28845 +extern int __do_strnlen_user(const char *str, unsigned long n,
28846 +                            void **fault_addr, void **fault_catcher);
28847 +
28848 +extern int copy_from_user_tt(void *to, const void *from, int n);
28849 +extern int copy_to_user_tt(void *to, const void *from, int n);
28850 +extern int strncpy_from_user_tt(char *dst, const char *src, int count);
28851 +extern int __clear_user_tt(void *mem, int len);
28852 +extern int clear_user_tt(void *mem, int len);
28853 +extern int strnlen_user_tt(const void *str, int len);
28854 +
28855 +#endif
28856 +
28857 +/*
28858 + * Overrides for Emacs so that we follow Linus's tabbing style.
28859 + * Emacs will notice this stuff at the end of the file and automatically
28860 + * adjust the settings for this buffer only.  This must remain at the end
28861 + * of the file.
28862 + * ---------------------------------------------------------------------------
28863 + * Local variables:
28864 + * c-file-style: "linux"
28865 + * End:
28866 + */
28867 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ksyms.c um/arch/um/kernel/tt/ksyms.c
28868 --- orig/arch/um/kernel/tt/ksyms.c      1969-12-31 19:00:00.000000000 -0500
28869 +++ um/arch/um/kernel/tt/ksyms.c        2003-10-21 03:26:07.000000000 -0400
28870 @@ -0,0 +1,28 @@
28871 +/* 
28872 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
28873 + * Licensed under the GPL
28874 + */
28875 +
28876 +#include "linux/module.h"
28877 +#include "asm/uaccess.h"
28878 +#include "mode.h"
28879 +
28880 +EXPORT_SYMBOL(__do_copy_from_user);
28881 +EXPORT_SYMBOL(__do_copy_to_user);
28882 +EXPORT_SYMBOL(__do_strncpy_from_user);
28883 +EXPORT_SYMBOL(__do_strnlen_user); 
28884 +EXPORT_SYMBOL(__do_clear_user);
28885 +
28886 +EXPORT_SYMBOL(tracing_pid);
28887 +EXPORT_SYMBOL(honeypot);
28888 +
28889 +/*
28890 + * Overrides for Emacs so that we follow Linus's tabbing style.
28891 + * Emacs will notice this stuff at the end of the file and automatically
28892 + * adjust the settings for this buffer only.  This must remain at the end
28893 + * of the file.
28894 + * ---------------------------------------------------------------------------
28895 + * Local variables:
28896 + * c-file-style: "linux"
28897 + * End:
28898 + */
28899 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/Makefile um/arch/um/kernel/tt/Makefile
28900 --- orig/arch/um/kernel/tt/Makefile     1969-12-31 19:00:00.000000000 -0500
28901 +++ um/arch/um/kernel/tt/Makefile       2003-11-12 08:34:27.000000000 -0500
28902 @@ -0,0 +1,39 @@
28903 +# 
28904 +# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
28905 +# Licensed under the GPL
28906 +#
28907 +
28908 +O_TARGET = tt.o
28909 +
28910 +obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
28911 +       syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
28912 +       uaccess.o uaccess_user.o
28913 +
28914 +obj-$(CONFIG_PT_PROXY) += gdb_kern.o 
28915 +
28916 +subdir-y = sys-$(SUBARCH)
28917 +subdir-$(CONFIG_PT_PROXY) += ptproxy
28918 +
28919 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
28920 +
28921 +export-objs = ksyms.o
28922 +
28923 +USER_OBJS = $(filter %_user.o,$(obj-y)) gdb.o time.o tracer.o
28924 +
28925 +UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS))
28926 +UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS))
28927 +
28928 +include $(TOPDIR)/Rules.make
28929 +
28930 +$(USER_OBJS) : %.o: %.c
28931 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
28932 +
28933 +$(O_TARGET) : unmap_fin.o
28934 +
28935 +unmap.o: unmap.c
28936 +       $(CC) $(UNMAP_CFLAGS) -c -o $@ $<
28937 +
28938 +unmap_fin.o : unmap.o
28939 +       ld -r -o $@ $< -lc -L/usr/lib
28940 +
28941 +clean :
28942 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem.c um/arch/um/kernel/tt/mem.c
28943 --- orig/arch/um/kernel/tt/mem.c        1969-12-31 19:00:00.000000000 -0500
28944 +++ um/arch/um/kernel/tt/mem.c  2004-01-31 02:38:28.000000000 -0500
28945 @@ -0,0 +1,51 @@
28946 +/* 
28947 + * Copyright (C) 2002 - 2004 Jeff Dike (jdike@karaya.com)
28948 + * Licensed under the GPL
28949 + */
28950 +
28951 +#include "linux/stddef.h"
28952 +#include "linux/config.h"
28953 +#include "linux/mm.h"
28954 +#include "asm/uaccess.h"
28955 +#include "mem_user.h"
28956 +#include "kern_util.h"
28957 +#include "user_util.h"
28958 +#include "kern.h"
28959 +#include "tt.h"
28960 +
28961 +void before_mem_tt(unsigned long brk_start)
28962 +{
28963 +       if(!jail || debug)
28964 +               remap_data(UML_ROUND_DOWN(&_stext), UML_ROUND_UP(&_etext), 1);
28965 +       remap_data(UML_ROUND_DOWN(&_sdata), UML_ROUND_UP(&_edata), 1);
28966 +       remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1);
28967 +}
28968 +
28969 +#ifdef CONFIG_HOST_2G_2G
28970 +#define TOP 0x80000000
28971 +#else
28972 +#define TOP 0xc0000000
28973 +#endif
28974 +
28975 +#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
28976 +#define START (TOP - SIZE)
28977 +
28978 +unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, 
28979 +                               unsigned long *task_size_out)
28980 +{
28981 +       /* Round up to the nearest 4M */
28982 +       *host_size_out = ROUND_4M((unsigned long) &arg);
28983 +       *task_size_out = START;
28984 +       return(START);
28985 +}
28986 +
28987 +/*
28988 + * Overrides for Emacs so that we follow Linus's tabbing style.
28989 + * Emacs will notice this stuff at the end of the file and automatically
28990 + * adjust the settings for this buffer only.  This must remain at the end
28991 + * of the file.
28992 + * ---------------------------------------------------------------------------
28993 + * Local variables:
28994 + * c-file-style: "linux"
28995 + * End:
28996 + */
28997 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem_user.c um/arch/um/kernel/tt/mem_user.c
28998 --- orig/arch/um/kernel/tt/mem_user.c   1969-12-31 19:00:00.000000000 -0500
28999 +++ um/arch/um/kernel/tt/mem_user.c     2003-10-21 03:26:07.000000000 -0400
29000 @@ -0,0 +1,49 @@
29001 +/* 
29002 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29003 + * Licensed under the GPL
29004 + */
29005 +
29006 +#include <stdlib.h>
29007 +#include <stdio.h>
29008 +#include <unistd.h>
29009 +#include <string.h>
29010 +#include <errno.h>
29011 +#include <sys/mman.h>
29012 +#include "tt.h"
29013 +#include "mem_user.h"
29014 +#include "user_util.h"
29015 +
29016 +void remap_data(void *segment_start, void *segment_end, int w)
29017 +{
29018 +       void *addr;
29019 +       unsigned long size;
29020 +       int data, prot;
29021 +
29022 +       if(w) prot = PROT_WRITE;
29023 +       else prot = 0;
29024 +       prot |= PROT_READ | PROT_EXEC;
29025 +       size = (unsigned long) segment_end - 
29026 +               (unsigned long) segment_start;
29027 +       data = create_mem_file(size);
29028 +       addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0);
29029 +       if(addr == MAP_FAILED){
29030 +               perror("mapping new data segment");
29031 +               exit(1);
29032 +       }
29033 +       memcpy(addr, segment_start, size);
29034 +       if(switcheroo(data, prot, addr, segment_start, size) < 0){
29035 +               printf("switcheroo failed\n");
29036 +               exit(1);
29037 +       }
29038 +}
29039 +
29040 +/*
29041 + * Overrides for Emacs so that we follow Linus's tabbing style.
29042 + * Emacs will notice this stuff at the end of the file and automatically
29043 + * adjust the settings for this buffer only.  This must remain at the end
29044 + * of the file.
29045 + * ---------------------------------------------------------------------------
29046 + * Local variables:
29047 + * c-file-style: "linux"
29048 + * End:
29049 + */
29050 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/process_kern.c um/arch/um/kernel/tt/process_kern.c
29051 --- orig/arch/um/kernel/tt/process_kern.c       1969-12-31 19:00:00.000000000 -0500
29052 +++ um/arch/um/kernel/tt/process_kern.c 2004-01-31 02:39:08.000000000 -0500
29053 @@ -0,0 +1,535 @@
29054 +/* 
29055 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29056 + * Licensed under the GPL
29057 + */
29058 +
29059 +#include "linux/sched.h"
29060 +#include "linux/signal.h"
29061 +#include "linux/kernel.h"
29062 +#include "asm/system.h"
29063 +#include "asm/pgalloc.h"
29064 +#include "asm/ptrace.h"
29065 +#include "irq_user.h"
29066 +#include "signal_user.h"
29067 +#include "kern_util.h"
29068 +#include "user_util.h"
29069 +#include "os.h"
29070 +#include "kern.h"
29071 +#include "sigcontext.h"
29072 +#include "time_user.h"
29073 +#include "mem_user.h"
29074 +#include "tlb.h"
29075 +#include "mode.h"
29076 +#include "init.h"
29077 +#include "tt.h"
29078 +
29079 +void *_switch_to_tt(void *prev, void *next)
29080 +{
29081 +       struct task_struct *from, *to;
29082 +       unsigned long flags;
29083 +       int err, vtalrm, alrm, prof, cpu;
29084 +       char c;
29085 +       /* jailing and SMP are incompatible, so this doesn't need to be 
29086 +        * made per-cpu 
29087 +        */
29088 +       static int reading;
29089 +
29090 +       from = prev;
29091 +       to = next;
29092 +
29093 +       to->thread.prev_sched = from;
29094 +
29095 +       cpu = from->processor;
29096 +       if(cpu == 0)
29097 +               forward_interrupts(to->thread.mode.tt.extern_pid);
29098 +#ifdef CONFIG_SMP
29099 +       forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid);
29100 +#endif
29101 +       local_irq_save(flags);
29102 +
29103 +       vtalrm = change_sig(SIGVTALRM, 0);
29104 +       alrm = change_sig(SIGALRM, 0);
29105 +       prof = change_sig(SIGPROF, 0);
29106 +
29107 +       c = 0;
29108 +       set_current(to);
29109 +
29110 +       reading = 0;
29111 +       err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
29112 +       if(err != sizeof(c))
29113 +               panic("write of switch_pipe failed, err = %d", -err);
29114 +
29115 +       reading = 1;
29116 +       if(from->state == TASK_ZOMBIE)
29117 +               os_kill_process(os_getpid(), 0);
29118 +
29119 +       err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
29120 +       if(err != sizeof(c))
29121 +               panic("read of switch_pipe failed, errno = %d", -err);
29122 +
29123 +       /* This works around a nasty race with 'jail'.  If we are switching
29124 +        * between two threads of a threaded app and the incoming process 
29125 +        * runs before the outgoing process reaches the read, and it makes
29126 +        * it all the way out to userspace, then it will have write-protected 
29127 +        * the outgoing process stack.  Then, when the outgoing process 
29128 +        * returns from the write, it will segfault because it can no longer
29129 +        * write its own stack.  So, in order to avoid that, the incoming 
29130 +        * thread sits in a loop yielding until 'reading' is set.  This 
29131 +        * isn't entirely safe, since there may be a reschedule from a timer
29132 +        * happening between setting 'reading' and sleeping in read.  But,
29133 +        * it should get a whole quantum in which to reach the read and sleep,
29134 +        * which should be enough.
29135 +        */
29136 +
29137 +       if(jail){
29138 +               while(!reading) sched_yield();
29139 +       }
29140 +
29141 +       change_sig(SIGVTALRM, vtalrm);
29142 +       change_sig(SIGALRM, alrm);
29143 +       change_sig(SIGPROF, prof);
29144 +
29145 +       arch_switch();
29146 +
29147 +       flush_tlb_all();
29148 +       local_irq_restore(flags);
29149 +
29150 +       return(current->thread.prev_sched);
29151 +}
29152 +
29153 +void release_thread_tt(struct task_struct *task)
29154 +{
29155 +       os_kill_process(task->thread.mode.tt.extern_pid, 0);
29156 +}
29157 +
29158 +void exit_thread_tt(void)
29159 +{
29160 +       os_close_file(current->thread.mode.tt.switch_pipe[0]);
29161 +       os_close_file(current->thread.mode.tt.switch_pipe[1]);
29162 +}
29163 +
29164 +extern void schedule_tail(struct task_struct *prev);
29165 +
29166 +static void new_thread_handler(int sig)
29167 +{
29168 +       unsigned long disable;
29169 +       int (*fn)(void *);
29170 +       void *arg;
29171 +
29172 +       fn = current->thread.request.u.thread.proc;
29173 +       arg = current->thread.request.u.thread.arg;
29174 +
29175 +       UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
29176 +       disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
29177 +               (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
29178 +       SC_SIGMASK(UPT_SC(&current->thread.regs.regs)) &= ~disable;
29179 +
29180 +       suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
29181 +
29182 +       init_new_thread_signals(1);
29183 +       enable_timer();
29184 +       free_page(current->thread.temp_stack);
29185 +       set_cmdline("(kernel thread)");
29186 +       force_flush_all();
29187 +
29188 +       if(current->thread.prev_sched != NULL)
29189 +               schedule_tail(current->thread.prev_sched);
29190 +       current->thread.prev_sched = NULL;
29191 +
29192 +       change_sig(SIGUSR1, 1);
29193 +       change_sig(SIGVTALRM, 1);
29194 +       change_sig(SIGPROF, 1);
29195 +       sti();
29196 +       if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
29197 +               do_exit(0);
29198 +}
29199 +
29200 +static int new_thread_proc(void *stack)
29201 +{
29202 +       /* cli is needed to block out signals until this thread is properly
29203 +        * scheduled.  Otherwise, the tracing thread will get mighty upset 
29204 +        * about any signals that arrive before that.  
29205 +        * This has the complication that it sets the saved signal mask in
29206 +        * the sigcontext to block signals.  This gets restored when this
29207 +        * thread (or a descendant, since they get a copy of this sigcontext)
29208 +        * returns to userspace.
29209 +        * So, this is compensated for elsewhere.
29210 +        * XXX There is still a small window until cli() actually finishes
29211 +        * where signals are possible - shouldn't be a problem in practice 
29212 +        * since SIGIO hasn't been forwarded here yet, and the cli should 
29213 +        * finish before a SIGVTALRM has time to be delivered.
29214 +        */
29215 +       cli();
29216 +       init_new_thread_stack(stack, new_thread_handler);
29217 +       os_usr1_process(os_getpid());
29218 +       return(0);
29219 +}
29220 +
29221 +/* Signal masking - signals are blocked at the start of fork_tramp.  They
29222 + * are re-enabled when finish_fork_handler is entered by fork_tramp hitting
29223 + * itself with a SIGUSR1.  set_user_mode has to be run with SIGUSR1 off,
29224 + * so it is blocked before it's called.  They are re-enabled on sigreturn
29225 + * despite the fact that they were blocked when the SIGUSR1 was issued because
29226 + * copy_thread copies the parent's sigcontext, including the signal mask
29227 + * onto the signal frame.
29228 + */
29229 +
29230 +static void finish_fork_handler(int sig)
29231 +{
29232 +       UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
29233 +       suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
29234 +       
29235 +       init_new_thread_signals(1);
29236 +       enable_timer();
29237 +       sti();
29238 +       force_flush_all();
29239 +       if(current->mm != current->p_pptr->mm)
29240 +               protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
29241 +                              1, 0, 1);
29242 +       task_protections((unsigned long) current);
29243 +
29244 +       if(current->thread.prev_sched != NULL)
29245 +               schedule_tail(current->thread.prev_sched);
29246 +       current->thread.prev_sched = NULL;
29247 +
29248 +       free_page(current->thread.temp_stack);
29249 +       cli();
29250 +       change_sig(SIGUSR1, 0);
29251 +       set_user_mode(current);
29252 +}
29253 +
29254 +int fork_tramp(void *stack)
29255 +{
29256 +       cli();
29257 +       arch_init_thread();
29258 +       init_new_thread_stack(stack, finish_fork_handler);
29259 +       os_usr1_process(os_getpid());
29260 +       return(0);
29261 +}
29262 +
29263 +int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
29264 +                  unsigned long stack_top, struct task_struct * p, 
29265 +                  struct pt_regs *regs)
29266 +{
29267 +       int (*tramp)(void *);
29268 +       int new_pid, err;
29269 +       unsigned long stack;
29270 +       
29271 +       if(current->thread.forking)
29272 +               tramp = fork_tramp;
29273 +       else {
29274 +               tramp = new_thread_proc;
29275 +               p->thread.request.u.thread = current->thread.request.u.thread;
29276 +       }
29277 +
29278 +       err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
29279 +       if(err < 0){
29280 +               printk("copy_thread : pipe failed, err = %d\n", -err);
29281 +               return(err);
29282 +       }
29283 +
29284 +       stack = alloc_stack(0, 0);
29285 +       if(stack == 0){
29286 +               printk(KERN_ERR "copy_thread : failed to allocate "
29287 +                      "temporary stack\n");
29288 +               return(-ENOMEM);
29289 +       }
29290 +
29291 +       clone_flags &= CLONE_VM;
29292 +       p->thread.temp_stack = stack;
29293 +       new_pid = start_fork_tramp((void *) p->thread.kernel_stack, stack,
29294 +                                  clone_flags, tramp);
29295 +       if(new_pid < 0){
29296 +               printk(KERN_ERR "copy_thread : clone failed - errno = %d\n", 
29297 +                      -new_pid);
29298 +               return(new_pid);
29299 +       }
29300 +
29301 +       if(current->thread.forking){
29302 +               sc_to_sc(UPT_SC(&p->thread.regs.regs), 
29303 +                        UPT_SC(&current->thread.regs.regs));
29304 +               SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
29305 +               if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
29306 +       }
29307 +       p->thread.mode.tt.extern_pid = new_pid;
29308 +
29309 +       current->thread.request.op = OP_FORK;
29310 +       current->thread.request.u.fork.pid = new_pid;
29311 +       os_usr1_process(os_getpid());
29312 +       return(0);
29313 +}
29314 +
29315 +void reboot_tt(void)
29316 +{
29317 +       current->thread.request.op = OP_REBOOT;
29318 +       os_usr1_process(os_getpid());
29319 +}
29320 +
29321 +void halt_tt(void)
29322 +{
29323 +       current->thread.request.op = OP_HALT;
29324 +       os_usr1_process(os_getpid());
29325 +}
29326 +
29327 +void kill_off_processes_tt(void)
29328 +{
29329 +       struct task_struct *p;
29330 +       int me;
29331 +
29332 +       me = os_getpid();
29333 +       for_each_task(p){
29334 +               int pid = p->thread.mode.tt.extern_pid;
29335 +               if((pid != me) && (pid != -1))
29336 +                       os_kill_process(p->thread.mode.tt.extern_pid, 0);
29337 +       }
29338 +       if((init_task.thread.mode.tt.extern_pid != me) &&
29339 +          (init_task.thread.mode.tt.extern_pid != -1))
29340 +               os_kill_process(init_task.thread.mode.tt.extern_pid, 0);
29341 +}
29342 +
29343 +void initial_thread_cb_tt(void (*proc)(void *), void *arg)
29344 +{
29345 +       if(os_getpid() == tracing_pid){
29346 +               (*proc)(arg);
29347 +       }
29348 +       else {
29349 +               current->thread.request.op = OP_CB;
29350 +               current->thread.request.u.cb.proc = proc;
29351 +               current->thread.request.u.cb.arg = arg;
29352 +               os_usr1_process(os_getpid());
29353 +       }
29354 +}
29355 +
29356 +int do_proc_op(void *t, int proc_id)
29357 +{
29358 +       struct task_struct *task;
29359 +       struct thread_struct *thread;
29360 +       int op, pid;
29361 +
29362 +       task = t;
29363 +       thread = &task->thread;
29364 +       op = thread->request.op;
29365 +       switch(op){
29366 +       case OP_NONE:
29367 +       case OP_TRACE_ON:
29368 +               break;
29369 +       case OP_EXEC:
29370 +               pid = thread->request.u.exec.pid;
29371 +               do_exec(thread->mode.tt.extern_pid, pid);
29372 +               thread->mode.tt.extern_pid = pid;
29373 +               cpu_tasks[task->processor].pid = pid;
29374 +               break;
29375 +       case OP_FORK:
29376 +               attach_process(thread->request.u.fork.pid);
29377 +               break;
29378 +       case OP_CB:
29379 +               (*thread->request.u.cb.proc)(thread->request.u.cb.arg);
29380 +               break;
29381 +       case OP_REBOOT:
29382 +       case OP_HALT:
29383 +               break;
29384 +       default:
29385 +               tracer_panic("Bad op in do_proc_op");
29386 +               break;
29387 +       }
29388 +       thread->request.op = OP_NONE;
29389 +       return(op);
29390 +}
29391 +
29392 +void init_idle_tt(void)
29393 +{
29394 +       idle_timer();
29395 +}
29396 +
29397 +/* Changed by jail_setup, which is a setup */
29398 +int jail = 0;
29399 +
29400 +int __init jail_setup(char *line, int *add)
29401 +{
29402 +       int ok = 1;
29403 +
29404 +       if(jail) return(0);
29405 +#ifdef CONFIG_SMP
29406 +       printf("'jail' may not used used in a kernel with CONFIG_SMP "
29407 +              "enabled\n");
29408 +       ok = 0;
29409 +#endif
29410 +#ifdef CONFIG_HOSTFS
29411 +       printf("'jail' may not used used in a kernel with CONFIG_HOSTFS "
29412 +              "enabled\n");
29413 +       ok = 0;
29414 +#endif
29415 +#ifdef CONFIG_MODULES
29416 +       printf("'jail' may not used used in a kernel with CONFIG_MODULES "
29417 +              "enabled\n");
29418 +       ok = 0;
29419 +#endif 
29420 +       if(!ok) exit(1);
29421 +
29422 +       /* CAP_SYS_RAWIO controls the ability to open /dev/mem and /dev/kmem.
29423 +        * Removing it from the bounding set eliminates the ability of anything
29424 +        * to acquire it, and thus read or write kernel memory.
29425 +        */
29426 +       cap_lower(cap_bset, CAP_SYS_RAWIO);
29427 +       jail = 1;
29428 +       return(0);
29429 +}
29430 +
29431 +__uml_setup("jail", jail_setup,
29432 +"jail\n"
29433 +"    Enables the protection of kernel memory from processes.\n\n"
29434 +);
29435 +
29436 +static void mprotect_kernel_mem(int w)
29437 +{
29438 +       unsigned long start, end;
29439 +       int pages;
29440 +
29441 +       if(!jail || (current == &init_task)) return;
29442 +
29443 +       pages = (1 << CONFIG_KERNEL_STACK_ORDER);
29444 +
29445 +       start = (unsigned long) current + PAGE_SIZE;
29446 +       end = (unsigned long) current + PAGE_SIZE * pages;
29447 +       protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
29448 +       protect_memory(end, high_physmem - end, 1, w, 1, 1);
29449 +
29450 +       start = (unsigned long) UML_ROUND_DOWN(&_stext);
29451 +       end = (unsigned long) UML_ROUND_UP(&_etext);
29452 +       protect_memory(start, end - start, 1, w, 1, 1);
29453 +
29454 +       start = (unsigned long) UML_ROUND_DOWN(&_unprotected_end);
29455 +       end = (unsigned long) UML_ROUND_UP(&_edata);
29456 +       protect_memory(start, end - start, 1, w, 1, 1);
29457 +
29458 +       start = (unsigned long) UML_ROUND_DOWN(&__bss_start);
29459 +       end = (unsigned long) UML_ROUND_UP(&_end);
29460 +       protect_memory(start, end - start, 1, w, 1, 1);
29461 +
29462 +       mprotect_kernel_vm(w);
29463 +}
29464 +
29465 +void unprotect_kernel_mem(void)
29466 +{
29467 +       mprotect_kernel_mem(1);
29468 +}
29469 +
29470 +void protect_kernel_mem(void)
29471 +{
29472 +       mprotect_kernel_mem(0);
29473 +}
29474 +
29475 +extern void start_kernel(void);
29476 +
29477 +static int start_kernel_proc(void *unused)
29478 +{
29479 +       int pid;
29480 +
29481 +       block_signals();
29482 +       pid = os_getpid();
29483 +
29484 +       cpu_tasks[0].pid = pid;
29485 +       cpu_tasks[0].task = current;
29486 +#ifdef CONFIG_SMP
29487 +       cpu_online_map = 1;
29488 +#endif
29489 +       if(debug) os_stop_process(pid);
29490 +       start_kernel();
29491 +       return(0);
29492 +}
29493 +
29494 +void set_tracing(void *task, int tracing)
29495 +{
29496 +       ((struct task_struct *) task)->thread.mode.tt.tracing = tracing;
29497 +}
29498 +
29499 +int is_tracing(void *t)
29500 +{
29501 +       return (((struct task_struct *) t)->thread.mode.tt.tracing);
29502 +}
29503 +
29504 +int set_user_mode(void *t)
29505 +{
29506 +       struct task_struct *task;
29507 +
29508 +       task = t ? t : current;
29509 +       if(task->thread.mode.tt.tracing) 
29510 +               return(1);
29511 +       task->thread.request.op = OP_TRACE_ON;
29512 +       os_usr1_process(os_getpid());
29513 +       return(0);
29514 +}
29515 +
29516 +void set_init_pid(int pid)
29517 +{
29518 +       int err;
29519 +
29520 +       init_task.thread.mode.tt.extern_pid = pid;
29521 +       err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
29522 +       if(err) 
29523 +               panic("Can't create switch pipe for init_task, errno = %d", 
29524 +                     -err);
29525 +}
29526 +
29527 +int singlestepping_tt(void *t)
29528 +{
29529 +       struct task_struct *task = t;
29530 +
29531 +       if(task->thread.mode.tt.singlestep_syscall)
29532 +               return(0);
29533 +       return(task->ptrace & PT_DTRACE);
29534 +}
29535 +
29536 +void clear_singlestep(void *t)
29537 +{
29538 +       struct task_struct *task = t;
29539 +
29540 +       task->ptrace &= ~PT_DTRACE;
29541 +}
29542 +
29543 +int start_uml_tt(void)
29544 +{
29545 +       void *sp;
29546 +       int pages;
29547 +
29548 +       pages = (1 << CONFIG_KERNEL_STACK_ORDER) - 2;
29549 +       sp = (void *) init_task.thread.kernel_stack + pages * PAGE_SIZE - 
29550 +               sizeof(unsigned long);
29551 +       return(tracer(start_kernel_proc, sp));
29552 +}
29553 +
29554 +int external_pid_tt(struct task_struct *task)
29555 +{
29556 +       return(task->thread.mode.tt.extern_pid);
29557 +}
29558 +
29559 +int thread_pid_tt(struct thread_struct *thread)
29560 +{
29561 +       return(thread->mode.tt.extern_pid);
29562 +}
29563 +
29564 +int is_valid_pid(int pid)
29565 +{
29566 +       struct task_struct *task;
29567 +
29568 +        read_lock(&tasklist_lock);
29569 +        for_each_task(task){
29570 +                if(task->thread.mode.tt.extern_pid == pid){
29571 +                       read_unlock(&tasklist_lock);
29572 +                       return(1);
29573 +                }
29574 +        }
29575 +       read_unlock(&tasklist_lock);
29576 +       return(0);
29577 +}
29578 +
29579 +/*
29580 + * Overrides for Emacs so that we follow Linus's tabbing style.
29581 + * Emacs will notice this stuff at the end of the file and automatically
29582 + * adjust the settings for this buffer only.  This must remain at the end
29583 + * of the file.
29584 + * ---------------------------------------------------------------------------
29585 + * Local variables:
29586 + * c-file-style: "linux"
29587 + * End:
29588 + */
29589 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/Makefile um/arch/um/kernel/tt/ptproxy/Makefile
29590 --- orig/arch/um/kernel/tt/ptproxy/Makefile     1969-12-31 19:00:00.000000000 -0500
29591 +++ um/arch/um/kernel/tt/ptproxy/Makefile       2003-10-21 03:26:07.000000000 -0400
29592 @@ -0,0 +1,12 @@
29593 +O_TARGET = ptproxy.o
29594 +
29595 +obj-y = proxy.o ptrace.o sysdep.o wait.o
29596 +
29597 +USER_OBJS = $(obj-y)
29598 +
29599 +include $(TOPDIR)/Rules.make
29600 +
29601 +$(USER_OBJS) : %.o: %.c
29602 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
29603 +
29604 +clean:
29605 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/proxy.c um/arch/um/kernel/tt/ptproxy/proxy.c
29606 --- orig/arch/um/kernel/tt/ptproxy/proxy.c      1969-12-31 19:00:00.000000000 -0500
29607 +++ um/arch/um/kernel/tt/ptproxy/proxy.c        2003-10-21 03:26:07.000000000 -0400
29608 @@ -0,0 +1,371 @@
29609 +/**********************************************************************
29610 +proxy.c
29611 +
29612 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
29613 +terms and conditions.
29614 +
29615 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
29616 +**********************************************************************/
29617 +
29618 +/* XXX This file shouldn't refer to CONFIG_* */
29619 +
29620 +#include <errno.h>
29621 +#include <stdio.h>
29622 +#include <stdlib.h>
29623 +#include <unistd.h>
29624 +#include <signal.h>
29625 +#include <string.h>
29626 +#include <termios.h>
29627 +#include <sys/wait.h>
29628 +#include <sys/types.h>
29629 +#include <sys/ptrace.h>
29630 +#include <sys/ioctl.h>
29631 +#include <asm/unistd.h>
29632 +
29633 +#include "ptproxy.h"
29634 +#include "sysdep.h"
29635 +#include "wait.h"
29636 +
29637 +#include "user_util.h"
29638 +#include "user.h"
29639 +#include "os.h"
29640 +#include "tempfile.h"
29641 +
29642 +static int debugger_wait(debugger_state *debugger, int *status, int options,
29643 +                        int (*syscall)(debugger_state *debugger, pid_t child),
29644 +                        int (*normal_return)(debugger_state *debugger, 
29645 +                                             pid_t unused),
29646 +                        int (*wait_return)(debugger_state *debugger, 
29647 +                                           pid_t unused))
29648 +{
29649 +       if(debugger->real_wait){
29650 +               debugger->handle_trace = normal_return;
29651 +               syscall_continue(debugger->pid);
29652 +               debugger->real_wait = 0;
29653 +               return(1);
29654 +       }
29655 +       debugger->wait_status_ptr = status;
29656 +       debugger->wait_options = options;
29657 +       if((debugger->debugee != NULL) && debugger->debugee->event){
29658 +               syscall_continue(debugger->pid);
29659 +               wait_for_stop(debugger->pid, SIGTRAP, PTRACE_SYSCALL,
29660 +                             NULL);
29661 +               (*wait_return)(debugger, -1);
29662 +               return(0);
29663 +       }
29664 +       else if(debugger->wait_options & WNOHANG){
29665 +               syscall_cancel(debugger->pid, 0);
29666 +               debugger->handle_trace = syscall;
29667 +               return(0);
29668 +       }
29669 +       else {
29670 +               syscall_pause(debugger->pid);
29671 +               debugger->handle_trace = wait_return;
29672 +               debugger->waiting = 1;
29673 +       }
29674 +       return(1);
29675 +}
29676 +
29677 +/*
29678 + * Handle debugger trap, i.e. syscall.
29679 + */
29680 +
29681 +int debugger_syscall(debugger_state *debugger, pid_t child)
29682 +{
29683 +       long arg1, arg2, arg3, arg4, arg5, result;
29684 +       int syscall, ret = 0;
29685 +
29686 +       syscall = get_syscall(debugger->pid, &arg1, &arg2, &arg3, &arg4, 
29687 +                             &arg5);
29688 +
29689 +       switch(syscall){
29690 +       case __NR_execve:
29691 +               /* execve never returns */
29692 +               debugger->handle_trace = debugger_syscall; 
29693 +               break;
29694 +
29695 +       case __NR_ptrace:
29696 +               if(debugger->debugee->pid != 0) arg2 = debugger->debugee->pid;
29697 +               if(!debugger->debugee->in_context) 
29698 +                       child = debugger->debugee->pid;
29699 +               result = proxy_ptrace(debugger, arg1, arg2, arg3, arg4, child,
29700 +                                     &ret);
29701 +               syscall_cancel(debugger->pid, result);
29702 +               debugger->handle_trace = debugger_syscall;
29703 +               return(ret);
29704 +
29705 +       case __NR_waitpid:
29706 +       case __NR_wait4:
29707 +               if(!debugger_wait(debugger, (int *) arg2, arg3, 
29708 +                                 debugger_syscall, debugger_normal_return, 
29709 +                                 proxy_wait_return))
29710 +                       return(0);
29711 +               break;
29712 +
29713 +       case __NR_kill:
29714 +               if(!debugger->debugee->in_context) 
29715 +                       child = debugger->debugee->pid;
29716 +               if(arg1 == debugger->debugee->pid){
29717 +                       result = kill(child, arg2);
29718 +                       syscall_cancel(debugger->pid, result);
29719 +                       debugger->handle_trace = debugger_syscall;
29720 +                       return(0);
29721 +               }
29722 +               else debugger->handle_trace = debugger_normal_return;
29723 +               break;
29724 +
29725 +       default:
29726 +               debugger->handle_trace = debugger_normal_return;
29727 +       }
29728 +
29729 +       syscall_continue(debugger->pid);
29730 +       return(0);
29731 +}
29732 +
29733 +/* Used by the tracing thread */
29734 +static debugger_state parent;
29735 +static int parent_syscall(debugger_state *debugger, int pid);
29736 +
29737 +int init_parent_proxy(int pid)
29738 +{
29739 +       parent = ((debugger_state) { .pid               = pid,
29740 +                                    .wait_options      = 0,
29741 +                                    .wait_status_ptr   = NULL,
29742 +                                    .waiting           = 0,
29743 +                                    .real_wait         = 0,
29744 +                                    .expecting_child   = 0,
29745 +                                    .handle_trace      = parent_syscall,
29746 +                                    .debugee           = NULL } );
29747 +       return(0);
29748 +}
29749 +
29750 +int parent_normal_return(debugger_state *debugger, pid_t unused)
29751 +{
29752 +       debugger->handle_trace = parent_syscall;
29753 +       syscall_continue(debugger->pid);
29754 +       return(0);
29755 +}
29756 +
29757 +static int parent_syscall(debugger_state *debugger, int pid)
29758 +{
29759 +       long arg1, arg2, arg3, arg4, arg5;
29760 +       int syscall;
29761 +
29762 +       syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5);
29763 +               
29764 +       if((syscall == __NR_waitpid) || (syscall == __NR_wait4)){
29765 +               debugger_wait(&parent, (int *) arg2, arg3, parent_syscall,
29766 +                             parent_normal_return, parent_wait_return);
29767 +       }
29768 +       else ptrace(PTRACE_SYSCALL, pid, 0, 0);
29769 +       return(0);
29770 +}
29771 +
29772 +int debugger_normal_return(debugger_state *debugger, pid_t unused)
29773 +{
29774 +       debugger->handle_trace = debugger_syscall;
29775 +       syscall_continue(debugger->pid);
29776 +       return(0);
29777 +}
29778 +
29779 +void debugger_cancelled_return(debugger_state *debugger, int result)
29780 +{
29781 +       debugger->handle_trace = debugger_syscall;
29782 +       syscall_set_result(debugger->pid, result);
29783 +       syscall_continue(debugger->pid);
29784 +}
29785 +
29786 +/* Used by the tracing thread */
29787 +static debugger_state debugger;
29788 +static debugee_state debugee;
29789 +
29790 +void init_proxy (pid_t debugger_pid, int stopped, int status)
29791 +{
29792 +       debugger.pid = debugger_pid;
29793 +       debugger.handle_trace = debugger_syscall;
29794 +       debugger.debugee = &debugee;
29795 +       debugger.waiting = 0;
29796 +       debugger.real_wait = 0;
29797 +       debugger.expecting_child = 0;
29798 +
29799 +       debugee.pid = 0;
29800 +       debugee.traced = 0;
29801 +       debugee.stopped = stopped;
29802 +       debugee.event = 0;
29803 +       debugee.zombie = 0;
29804 +       debugee.died = 0;
29805 +       debugee.wait_status = status;
29806 +       debugee.in_context = 1;
29807 +}
29808 +
29809 +int debugger_proxy(int status, int pid)
29810 +{
29811 +       int ret = 0, sig;
29812 +
29813 +       if(WIFSTOPPED(status)){
29814 +               sig = WSTOPSIG(status);
29815 +               if (sig == SIGTRAP)
29816 +                       ret = (*debugger.handle_trace)(&debugger, pid);
29817 +                                                      
29818 +               else if(sig == SIGCHLD){
29819 +                       if(debugger.expecting_child){
29820 +                               ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
29821 +                               debugger.expecting_child = 0;
29822 +                       }
29823 +                       else if(debugger.waiting)
29824 +                               real_wait_return(&debugger);
29825 +                       else {
29826 +                               ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
29827 +                               debugger.real_wait = 1;
29828 +                       }
29829 +               }
29830 +               else ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
29831 +       }
29832 +       else if(WIFEXITED(status)){
29833 +               tracer_panic("debugger (pid %d) exited with status %d", 
29834 +                            debugger.pid, WEXITSTATUS(status));
29835 +       }
29836 +       else if(WIFSIGNALED(status)){
29837 +               tracer_panic("debugger (pid %d) exited with signal %d", 
29838 +                            debugger.pid, WTERMSIG(status));
29839 +       }
29840 +       else {
29841 +               tracer_panic("proxy got unknown status (0x%x) on debugger "
29842 +                            "(pid %d)", status, debugger.pid);
29843 +       }
29844 +       return(ret);
29845 +}
29846 +
29847 +void child_proxy(pid_t pid, int status)
29848 +{
29849 +       debugee.event = 1;
29850 +       debugee.wait_status = status;
29851 +
29852 +       if(WIFSTOPPED(status)){
29853 +               debugee.stopped = 1;
29854 +               debugger.expecting_child = 1;
29855 +               kill(debugger.pid, SIGCHLD);
29856 +       }
29857 +       else if(WIFEXITED(status) || WIFSIGNALED(status)){
29858 +               debugee.zombie = 1;
29859 +               debugger.expecting_child = 1;
29860 +               kill(debugger.pid, SIGCHLD);
29861 +       }
29862 +       else panic("proxy got unknown status (0x%x) on child (pid %d)", 
29863 +                  status, pid);
29864 +}
29865 +
29866 +void debugger_parent_signal(int status, int pid)
29867 +{
29868 +       int sig;
29869 +
29870 +       if(WIFSTOPPED(status)){
29871 +               sig = WSTOPSIG(status);
29872 +               if(sig == SIGTRAP) (*parent.handle_trace)(&parent, pid);
29873 +               else ptrace(PTRACE_SYSCALL, pid, 0, sig);
29874 +       }
29875 +}
29876 +
29877 +void fake_child_exit(void)
29878 +{
29879 +       int status, pid;
29880 +
29881 +       child_proxy(1, W_EXITCODE(0, 0));
29882 +       while(debugger.waiting == 1){
29883 +               pid = waitpid(debugger.pid, &status, WUNTRACED);
29884 +               if(pid != debugger.pid){
29885 +                       printk("fake_child_exit - waitpid failed, "
29886 +                              "errno = %d\n", errno);
29887 +                       return;
29888 +               }
29889 +               debugger_proxy(status, debugger.pid);
29890 +       }
29891 +       pid = waitpid(debugger.pid, &status, WUNTRACED);
29892 +       if(pid != debugger.pid){
29893 +               printk("fake_child_exit - waitpid failed, "
29894 +                      "errno = %d\n", errno);
29895 +               return;
29896 +       }
29897 +       if(ptrace(PTRACE_DETACH, debugger.pid, 0, SIGCONT) < 0)
29898 +               printk("fake_child_exit - PTRACE_DETACH failed, errno = %d\n",
29899 +                      errno);
29900 +}
29901 +
29902 +char gdb_init_string[] = 
29903 +"att 1 \n\
29904 +b panic \n\
29905 +b stop \n\
29906 +handle SIGWINCH nostop noprint pass \n\
29907 +";
29908 +
29909 +int start_debugger(char *prog, int startup, int stop, int *fd_out)
29910 +{
29911 +       int slave, child;
29912 +
29913 +       slave = open_gdb_chan();
29914 +       child = fork();
29915 +       if(child == 0){
29916 +               char *tempname = NULL;
29917 +               int fd;
29918 +
29919 +               if(setsid() < 0) perror("setsid");
29920 +               if((dup2(slave, 0) < 0) || (dup2(slave, 1) < 0) || 
29921 +                  (dup2(slave, 2) < 0)){
29922 +                       printk("start_debugger : dup2 failed, errno = %d\n",
29923 +                              errno);
29924 +                       exit(1);
29925 +               }
29926 +               if(ioctl(0, TIOCSCTTY, 0) < 0){
29927 +                       printk("start_debugger : TIOCSCTTY failed, "
29928 +                              "errno = %d\n", errno);
29929 +                       exit(1);
29930 +               }
29931 +               if(tcsetpgrp (1, os_getpid()) < 0){
29932 +                       printk("start_debugger : tcsetpgrp failed, "
29933 +                              "errno = %d\n", errno);
29934 +#ifdef notdef
29935 +                       exit(1);
29936 +#endif
29937 +               }
29938 +               fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
29939 +               if(fd < 0){
29940 +                       printk("start_debugger : make_tempfile failed,"
29941 +                              "err = %d\n", -fd);
29942 +                       exit(1);
29943 +               }
29944 +               os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
29945 +               if(startup){
29946 +                       if(stop){
29947 +                               os_write_file(fd, "b start_kernel\n",
29948 +                                     strlen("b start_kernel\n"));
29949 +                       }
29950 +                       os_write_file(fd, "c\n", strlen("c\n"));
29951 +               }
29952 +               if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
29953 +                       printk("start_debugger :  PTRACE_TRACEME failed, "
29954 +                              "errno = %d\n", errno);
29955 +                       exit(1);
29956 +               }
29957 +               execlp("gdb", "gdb", "--command", tempname, prog, NULL);
29958 +               printk("start_debugger : exec of gdb failed, errno = %d\n",
29959 +                      errno);
29960 +       }
29961 +       if(child < 0){
29962 +               printk("start_debugger : fork for gdb failed, errno = %d\n",
29963 +                      errno);
29964 +               return(-1);
29965 +       }
29966 +       *fd_out = slave;
29967 +       return(child);
29968 +}
29969 +
29970 +/*
29971 + * Overrides for Emacs so that we follow Linus's tabbing style.
29972 + * Emacs will notice this stuff at the end of the file and automatically
29973 + * adjust the settings for this buffer only.  This must remain at the end
29974 + * of the file.
29975 + * ---------------------------------------------------------------------------
29976 + * Local variables:
29977 + * c-file-style: "linux"
29978 + * End:
29979 + */
29980 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptproxy.h um/arch/um/kernel/tt/ptproxy/ptproxy.h
29981 --- orig/arch/um/kernel/tt/ptproxy/ptproxy.h    1969-12-31 19:00:00.000000000 -0500
29982 +++ um/arch/um/kernel/tt/ptproxy/ptproxy.h      2003-10-21 03:26:07.000000000 -0400
29983 @@ -0,0 +1,61 @@
29984 +/**********************************************************************
29985 +ptproxy.h
29986 +
29987 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
29988 +terms and conditions.
29989 +**********************************************************************/
29990 +
29991 +#ifndef __PTPROXY_H
29992 +#define __PTPROXY_H
29993 +
29994 +#include <sys/types.h>
29995 +
29996 +typedef struct debugger debugger_state;
29997 +typedef struct debugee debugee_state;
29998 +
29999 +struct debugger
30000 +{
30001 +       pid_t pid;
30002 +       int wait_options;
30003 +       int *wait_status_ptr;
30004 +       unsigned int waiting : 1;
30005 +       unsigned int real_wait : 1;
30006 +       unsigned int expecting_child : 1;
30007 +       int (*handle_trace) (debugger_state *, pid_t);
30008 +
30009 +       debugee_state *debugee;
30010 +};
30011 +
30012 +struct debugee
30013 +{
30014 +       pid_t pid;
30015 +       int wait_status;
30016 +       unsigned int died : 1;
30017 +       unsigned int event : 1;
30018 +       unsigned int stopped : 1;
30019 +       unsigned int trace_singlestep : 1;
30020 +       unsigned int trace_syscall : 1;
30021 +       unsigned int traced : 1;
30022 +       unsigned int zombie : 1;
30023 +       unsigned int in_context : 1;
30024 +};
30025 +
30026 +extern int debugger_syscall(debugger_state *debugger, pid_t pid);
30027 +extern int debugger_normal_return (debugger_state *debugger, pid_t unused);
30028 +
30029 +extern long proxy_ptrace (struct debugger *, int, pid_t, long, long, pid_t,
30030 +                         int *strace_out);
30031 +extern void debugger_cancelled_return(debugger_state *debugger, int result);
30032 +
30033 +#endif
30034 +
30035 +/*
30036 + * Overrides for Emacs so that we follow Linus's tabbing style.
30037 + * Emacs will notice this stuff at the end of the file and automatically
30038 + * adjust the settings for this buffer only.  This must remain at the end
30039 + * of the file.
30040 + * ---------------------------------------------------------------------------
30041 + * Local variables:
30042 + * c-file-style: "linux"
30043 + * End:
30044 + */
30045 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptrace.c um/arch/um/kernel/tt/ptproxy/ptrace.c
30046 --- orig/arch/um/kernel/tt/ptproxy/ptrace.c     1969-12-31 19:00:00.000000000 -0500
30047 +++ um/arch/um/kernel/tt/ptproxy/ptrace.c       2003-10-21 03:26:07.000000000 -0400
30048 @@ -0,0 +1,239 @@
30049 +/**********************************************************************
30050 +ptrace.c
30051 +
30052 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
30053 +terms and conditions.
30054 +
30055 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
30056 +**********************************************************************/
30057 +
30058 +#include <errno.h>
30059 +#include <unistd.h>
30060 +#include <signal.h>
30061 +#include <sys/types.h>
30062 +#include <sys/time.h>
30063 +#include <sys/ptrace.h>
30064 +#include <sys/wait.h>
30065 +#include <asm/ptrace.h>
30066 +
30067 +#include "ptproxy.h"
30068 +#include "debug.h"
30069 +#include "user_util.h"
30070 +#include "kern_util.h"
30071 +#include "ptrace_user.h"
30072 +#include "tt.h"
30073 +
30074 +long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
30075 +                 long arg3, long arg4, pid_t child, int *ret)
30076 +{
30077 +       sigset_t relay;
30078 +       long result;
30079 +       int status;
30080 +
30081 +       *ret = 0;
30082 +       if(debugger->debugee->died) return(-ESRCH);
30083 +
30084 +       switch(arg1){
30085 +       case PTRACE_ATTACH:
30086 +               if(debugger->debugee->traced) return(-EPERM);
30087 +
30088 +               debugger->debugee->pid = arg2;
30089 +               debugger->debugee->traced = 1;
30090 +
30091 +               if(is_valid_pid(arg2) && (arg2 != child)){
30092 +                       debugger->debugee->in_context = 0;
30093 +                       kill(arg2, SIGSTOP);
30094 +                       debugger->debugee->event = 1;
30095 +                       debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);
30096 +               }
30097 +               else {
30098 +                       debugger->debugee->in_context = 1;
30099 +                       if(debugger->debugee->stopped) 
30100 +                               child_proxy(child, W_STOPCODE(SIGSTOP));
30101 +                       else kill(child, SIGSTOP);
30102 +               }
30103 +
30104 +               return(0);
30105 +
30106 +       case PTRACE_DETACH:
30107 +               if(!debugger->debugee->traced) return(-EPERM);
30108 +               
30109 +               debugger->debugee->traced = 0;
30110 +               debugger->debugee->pid = 0;
30111 +               if(!debugger->debugee->in_context)
30112 +                       kill(child, SIGCONT);
30113 +
30114 +               return(0);
30115 +
30116 +       case PTRACE_CONT:
30117 +               if(!debugger->debugee->in_context) return(-EPERM);
30118 +               *ret = PTRACE_CONT;
30119 +               return(ptrace(PTRACE_CONT, child, arg3, arg4));
30120 +
30121 +#ifdef UM_HAVE_GETFPREGS
30122 +       case PTRACE_GETFPREGS:
30123 +       {
30124 +               long regs[FP_FRAME_SIZE];
30125 +               int i, result;
30126 +
30127 +               result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
30128 +               if(result == -1) return(-errno);
30129 +               
30130 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30131 +                       ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
30132 +                              regs[i]);
30133 +               return(result);
30134 +       }
30135 +#endif
30136 +
30137 +#ifdef UM_HAVE_GETFPXREGS
30138 +       case PTRACE_GETFPXREGS:
30139 +       {
30140 +               long regs[FPX_FRAME_SIZE];
30141 +               int i, result;
30142 +
30143 +               result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
30144 +               if(result == -1) return(-errno);
30145 +               
30146 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30147 +                       ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
30148 +                              regs[i]);
30149 +               return(result);
30150 +       }
30151 +#endif
30152 +
30153 +#ifdef UM_HAVE_GETREGS
30154 +       case PTRACE_GETREGS:
30155 +       {
30156 +               long regs[FRAME_SIZE];
30157 +               int i, result;
30158 +
30159 +               result = ptrace(PTRACE_GETREGS, child, 0, regs);
30160 +               if(result == -1) return(-errno);
30161 +
30162 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30163 +                       ptrace (PTRACE_POKEDATA, debugger->pid,
30164 +                               arg4 + 4 * i, regs[i]);
30165 +               return(result);
30166 +       }
30167 +       break;
30168 +#endif
30169 +
30170 +       case PTRACE_KILL:
30171 +               result = ptrace(PTRACE_KILL, child, arg3, arg4);
30172 +               if(result == -1) return(-errno);
30173 +
30174 +               return(result);
30175 +
30176 +       case PTRACE_PEEKDATA:
30177 +       case PTRACE_PEEKTEXT:
30178 +       case PTRACE_PEEKUSER:
30179 +               /* The value being read out could be -1, so we have to 
30180 +                * check errno to see if there's an error, and zero it
30181 +                * beforehand so we're not faked out by an old error
30182 +                */
30183 +
30184 +               errno = 0;
30185 +               result = ptrace(arg1, child, arg3, 0);
30186 +               if((result == -1) && (errno != 0)) return(-errno);
30187 +
30188 +               result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
30189 +               if(result == -1) return(-errno);
30190 +                       
30191 +               return(result);
30192 +
30193 +       case PTRACE_POKEDATA:
30194 +       case PTRACE_POKETEXT:
30195 +       case PTRACE_POKEUSER:
30196 +               result = ptrace(arg1, child, arg3, arg4);
30197 +               if(result == -1) return(-errno);
30198 +
30199 +               if(arg1 == PTRACE_POKEUSER) ptrace_pokeuser(arg3, arg4);
30200 +               return(result);
30201 +
30202 +#ifdef UM_HAVE_SETFPREGS
30203 +       case PTRACE_SETFPREGS:
30204 +       {
30205 +               long regs[FP_FRAME_SIZE];
30206 +               int i;
30207 +
30208 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30209 +                       regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
30210 +                                         arg4 + 4 * i, 0);
30211 +               result = ptrace(PTRACE_SETFPREGS, child, 0, regs);
30212 +               if(result == -1) return(-errno);
30213 +
30214 +               return(result);
30215 +       }
30216 +#endif
30217 +
30218 +#ifdef UM_HAVE_SETFPXREGS
30219 +       case PTRACE_SETFPXREGS:
30220 +       {
30221 +               long regs[FPX_FRAME_SIZE];
30222 +               int i;
30223 +
30224 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30225 +                       regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
30226 +                                         arg4 + 4 * i, 0);
30227 +               result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);
30228 +               if(result == -1) return(-errno);
30229 +
30230 +               return(result);
30231 +       }
30232 +#endif
30233 +
30234 +#ifdef UM_HAVE_SETREGS
30235 +       case PTRACE_SETREGS:
30236 +       {
30237 +               long regs[FRAME_SIZE];
30238 +               int i;
30239 +
30240 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30241 +                       regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,
30242 +                                        arg4 + 4 * i, 0);
30243 +               result = ptrace(PTRACE_SETREGS, child, 0, regs);
30244 +               if(result == -1) return(-errno);
30245 +
30246 +               return(result);
30247 +       }
30248 +#endif
30249 +
30250 +       case PTRACE_SINGLESTEP:
30251 +               if(!debugger->debugee->in_context) return(-EPERM);
30252 +               sigemptyset(&relay);
30253 +               sigaddset(&relay, SIGSEGV);
30254 +               sigaddset(&relay, SIGILL);
30255 +               sigaddset(&relay, SIGBUS);
30256 +               result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4);
30257 +               if(result == -1) return(-errno);
30258 +               
30259 +               status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
30260 +                                      &relay);
30261 +               child_proxy(child, status);
30262 +               return(result);
30263 +
30264 +       case PTRACE_SYSCALL:
30265 +               if(!debugger->debugee->in_context) return(-EPERM);
30266 +               result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);
30267 +               if(result == -1) return(-errno);
30268 +
30269 +               *ret = PTRACE_SYSCALL;
30270 +               return(result);
30271 +
30272 +       case PTRACE_TRACEME:
30273 +       default:
30274 +               return(-EINVAL);
30275 +       }
30276 +}
30277 +
30278 +/*
30279 + * Overrides for Emacs so that we follow Linus's tabbing style.
30280 + * Emacs will notice this stuff at the end of the file and automatically
30281 + * adjust the settings for this buffer only.  This must remain at the end
30282 + * of the file.
30283 + * ---------------------------------------------------------------------------
30284 + * Local variables:
30285 + * c-file-style: "linux"
30286 + * End:
30287 + */
30288 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.c um/arch/um/kernel/tt/ptproxy/sysdep.c
30289 --- orig/arch/um/kernel/tt/ptproxy/sysdep.c     1969-12-31 19:00:00.000000000 -0500
30290 +++ um/arch/um/kernel/tt/ptproxy/sysdep.c       2003-10-21 03:26:07.000000000 -0400
30291 @@ -0,0 +1,72 @@
30292 +/**********************************************************************
30293 +sysdep.c
30294 +
30295 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
30296 +terms and conditions.
30297 +**********************************************************************/
30298 +
30299 +#include <stdio.h>
30300 +#include <string.h>
30301 +#include <stdlib.h>
30302 +#include <signal.h>
30303 +#include <errno.h>
30304 +#include <sys/types.h>
30305 +#include <sys/ptrace.h>
30306 +#include <asm/ptrace.h>
30307 +#include <linux/unistd.h>
30308 +#include "ptrace_user.h"
30309 +#include "user_util.h"
30310 +#include "user.h"
30311 +
30312 +int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4, 
30313 +               long *arg5)
30314 +{
30315 +       *arg1 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG1_OFFSET, 0);
30316 +       *arg2 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG2_OFFSET, 0);
30317 +       *arg3 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG3_OFFSET, 0);
30318 +       *arg4 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG4_OFFSET, 0);
30319 +       *arg5 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG5_OFFSET, 0);
30320 +       return(ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET, 0));
30321 +}
30322 +
30323 +void syscall_cancel(pid_t pid, int result)
30324 +{
30325 +       if((ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
30326 +                  __NR_getpid) < 0) ||
30327 +          (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) ||
30328 +          (wait_for_stop(pid, SIGTRAP, PTRACE_SYSCALL, NULL) < 0) ||
30329 +          (ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result) < 0) ||
30330 +          (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0))
30331 +               printk("ptproxy: couldn't cancel syscall: errno = %d\n", 
30332 +                      errno);
30333 +}
30334 +
30335 +void syscall_set_result(pid_t pid, long result)
30336 +{
30337 +       ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result);
30338 +}
30339 +
30340 +void syscall_continue(pid_t pid)
30341 +{
30342 +       ptrace(PTRACE_SYSCALL, pid, 0, 0);
30343 +}
30344 +
30345 +int syscall_pause(pid_t pid) 
30346 +{
30347 +       if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_pause) < 0){
30348 +               printk("syscall_change - ptrace failed, errno = %d\n", errno);
30349 +               return(-1);
30350 +       }
30351 +       return(0);
30352 +}
30353 +
30354 +/*
30355 + * Overrides for Emacs so that we follow Linus's tabbing style.
30356 + * Emacs will notice this stuff at the end of the file and automatically
30357 + * adjust the settings for this buffer only.  This must remain at the end
30358 + * of the file.
30359 + * ---------------------------------------------------------------------------
30360 + * Local variables:
30361 + * c-file-style: "linux"
30362 + * End:
30363 + */
30364 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.h um/arch/um/kernel/tt/ptproxy/sysdep.h
30365 --- orig/arch/um/kernel/tt/ptproxy/sysdep.h     1969-12-31 19:00:00.000000000 -0500
30366 +++ um/arch/um/kernel/tt/ptproxy/sysdep.h       2003-10-21 03:26:07.000000000 -0400
30367 @@ -0,0 +1,25 @@
30368 +/**********************************************************************
30369 +sysdep.h
30370 +
30371 +Copyright (C) 1999 Lars Brinkhoff.
30372 +Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
30373 +See the file COPYING for licensing terms and conditions.
30374 +**********************************************************************/
30375 +
30376 +extern int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, 
30377 +                      long *arg4, long *arg5);
30378 +extern void syscall_cancel (pid_t pid, long result);
30379 +extern void syscall_set_result (pid_t pid, long result);
30380 +extern void syscall_continue (pid_t pid);
30381 +extern int syscall_pause(pid_t pid);
30382 +
30383 +/*
30384 + * Overrides for Emacs so that we follow Linus's tabbing style.
30385 + * Emacs will notice this stuff at the end of the file and automatically
30386 + * adjust the settings for this buffer only.  This must remain at the end
30387 + * of the file.
30388 + * ---------------------------------------------------------------------------
30389 + * Local variables:
30390 + * c-file-style: "linux"
30391 + * End:
30392 + */
30393 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.c um/arch/um/kernel/tt/ptproxy/wait.c
30394 --- orig/arch/um/kernel/tt/ptproxy/wait.c       1969-12-31 19:00:00.000000000 -0500
30395 +++ um/arch/um/kernel/tt/ptproxy/wait.c 2004-01-17 05:27:18.000000000 -0500
30396 @@ -0,0 +1,88 @@
30397 +/**********************************************************************
30398 +wait.c
30399 +
30400 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
30401 +terms and conditions.
30402 +
30403 +**********************************************************************/
30404 +
30405 +#include <errno.h>
30406 +#include <signal.h>
30407 +#include <sys/wait.h>
30408 +#include <sys/ptrace.h>
30409 +#include <asm/ptrace.h>
30410 +
30411 +#include "ptproxy.h"
30412 +#include "sysdep.h"
30413 +#include "wait.h"
30414 +#include "user_util.h"
30415 +#include "sysdep/ptrace.h"
30416 +#include "sysdep/ptrace_user.h"
30417 +#include "sysdep/sigcontext.h"
30418 +
30419 +int proxy_wait_return(struct debugger *debugger, pid_t unused)
30420 +{
30421 +       debugger->waiting = 0;
30422 +
30423 +       if(debugger->debugee->died || (debugger->wait_options & __WCLONE)){
30424 +               debugger_cancelled_return(debugger, -ECHILD);
30425 +               return(0);
30426 +       }
30427 +
30428 +       if(debugger->debugee->zombie && debugger->debugee->event)
30429 +               debugger->debugee->died = 1;
30430 +
30431 +       if(debugger->debugee->event){
30432 +               debugger->debugee->event = 0;
30433 +               ptrace(PTRACE_POKEDATA, debugger->pid,
30434 +                      debugger->wait_status_ptr, 
30435 +                      debugger->debugee->wait_status);
30436 +               /* if (wait4)
30437 +                  ptrace (PTRACE_POKEDATA, pid, rusage_ptr, ...); */
30438 +               debugger_cancelled_return(debugger, debugger->debugee->pid);
30439 +               return(0);
30440 +       }
30441 +
30442 +       /* pause will return -EINTR, which happens to be right for wait */
30443 +       debugger_normal_return(debugger, -1);
30444 +       return(0);
30445 +}
30446 +
30447 +int parent_wait_return(struct debugger *debugger, pid_t unused)
30448 +{
30449 +       return(debugger_normal_return(debugger, -1));
30450 +}
30451 +
30452 +int real_wait_return(struct debugger *debugger)
30453 +{
30454 +       unsigned long ip;
30455 +       int pid;
30456 +
30457 +       pid = debugger->pid;
30458 +
30459 +       ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
30460 +       IP_RESTART_SYSCALL(ip);
30461 +
30462 +       if(ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip) < 0)
30463 +               tracer_panic("real_wait_return : Failed to restart system "
30464 +                            "call, errno = %d\n", errno);
30465 +
30466 +       if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
30467 +          (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
30468 +          (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
30469 +          debugger_normal_return(debugger, -1))
30470 +               tracer_panic("real_wait_return : gdb failed to wait, "
30471 +                            "errno = %d\n", errno);
30472 +       return(0);
30473 +}
30474 +
30475 +/*
30476 + * Overrides for Emacs so that we follow Linus's tabbing style.
30477 + * Emacs will notice this stuff at the end of the file and automatically
30478 + * adjust the settings for this buffer only.  This must remain at the end
30479 + * of the file.
30480 + * ---------------------------------------------------------------------------
30481 + * Local variables:
30482 + * c-file-style: "linux"
30483 + * End:
30484 + */
30485 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.h um/arch/um/kernel/tt/ptproxy/wait.h
30486 --- orig/arch/um/kernel/tt/ptproxy/wait.h       1969-12-31 19:00:00.000000000 -0500
30487 +++ um/arch/um/kernel/tt/ptproxy/wait.h 2003-10-21 03:26:07.000000000 -0400
30488 @@ -0,0 +1,15 @@
30489 +/**********************************************************************
30490 +wait.h
30491 +
30492 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
30493 +terms and conditions.
30494 +**********************************************************************/
30495 +
30496 +#ifndef __PTPROXY_WAIT_H
30497 +#define __PTPROXY_WAIT_H
30498 +
30499 +extern int proxy_wait_return(struct debugger *debugger, pid_t unused);
30500 +extern int real_wait_return(struct debugger *debugger);
30501 +extern int parent_wait_return(struct debugger *debugger, pid_t unused);
30502 +
30503 +#endif
30504 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_kern.c um/arch/um/kernel/tt/syscall_kern.c
30505 --- orig/arch/um/kernel/tt/syscall_kern.c       1969-12-31 19:00:00.000000000 -0500
30506 +++ um/arch/um/kernel/tt/syscall_kern.c 2003-10-21 03:26:07.000000000 -0400
30507 @@ -0,0 +1,142 @@
30508 +/* 
30509 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
30510 + * Licensed under the GPL
30511 + */
30512 +
30513 +#include "linux/types.h"
30514 +#include "linux/utime.h"
30515 +#include "linux/sys.h"
30516 +#include "asm/unistd.h"
30517 +#include "asm/ptrace.h"
30518 +#include "asm/uaccess.h"
30519 +#include "sysdep/syscalls.h"
30520 +#include "kern_util.h"
30521 +
30522 +static inline int check_area(void *ptr, int size)
30523 +{
30524 +       return(verify_area(VERIFY_WRITE, ptr, size));
30525 +}
30526 +
30527 +static int check_readlink(struct pt_regs *regs)
30528 +{
30529 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
30530 +                         UPT_SYSCALL_ARG2(&regs->regs)));
30531 +}
30532 +
30533 +static int check_utime(struct pt_regs *regs)
30534 +{
30535 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
30536 +                         sizeof(struct utimbuf)));
30537 +}
30538 +
30539 +static int check_oldstat(struct pt_regs *regs)
30540 +{
30541 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
30542 +                         sizeof(struct __old_kernel_stat)));
30543 +}
30544 +
30545 +static int check_stat(struct pt_regs *regs)
30546 +{
30547 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
30548 +                         sizeof(struct stat)));
30549 +}
30550 +
30551 +static int check_stat64(struct pt_regs *regs)
30552 +{
30553 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
30554 +                         sizeof(struct stat64)));
30555 +}
30556 +
30557 +struct bogus {
30558 +       int kernel_ds;
30559 +       int (*check_params)(struct pt_regs *);
30560 +};
30561 +
30562 +struct bogus this_is_bogus[256] = {
30563 +       [ __NR_mknod ] = { 1, NULL },
30564 +       [ __NR_mkdir ] = { 1, NULL },
30565 +       [ __NR_rmdir ] = { 1, NULL },
30566 +       [ __NR_unlink ] = { 1, NULL },
30567 +       [ __NR_symlink ] = { 1, NULL },
30568 +       [ __NR_link ] = { 1, NULL },
30569 +       [ __NR_rename ] = { 1, NULL },
30570 +       [ __NR_umount ] = { 1, NULL },
30571 +       [ __NR_mount ] = { 1, NULL },
30572 +       [ __NR_pivot_root ] = { 1, NULL },
30573 +       [ __NR_chdir ] = { 1, NULL },
30574 +       [ __NR_chroot ] = { 1, NULL },
30575 +       [ __NR_open ] = { 1, NULL },
30576 +       [ __NR_quotactl ] = { 1, NULL },
30577 +       [ __NR_sysfs ] = { 1, NULL },
30578 +       [ __NR_readlink ] = { 1, check_readlink },
30579 +       [ __NR_acct ] = { 1, NULL },
30580 +       [ __NR_execve ] = { 1, NULL },
30581 +       [ __NR_uselib ] = { 1, NULL },
30582 +       [ __NR_statfs ] = { 1, NULL },
30583 +       [ __NR_truncate ] = { 1, NULL },
30584 +       [ __NR_access ] = { 1, NULL },
30585 +       [ __NR_chmod ] = { 1, NULL },
30586 +       [ __NR_chown ] = { 1, NULL },
30587 +       [ __NR_lchown ] = { 1, NULL },
30588 +       [ __NR_utime ] = { 1, check_utime },
30589 +       [ __NR_oldlstat ] = { 1, check_oldstat },
30590 +       [ __NR_oldstat ] = { 1, check_oldstat },
30591 +       [ __NR_stat ] = { 1, check_stat },
30592 +       [ __NR_lstat ] = { 1, check_stat },
30593 +       [ __NR_stat64 ] = { 1, check_stat64 },
30594 +       [ __NR_lstat64 ] = { 1, check_stat64 },
30595 +       [ __NR_chown32 ] = { 1, NULL },
30596 +};
30597 +
30598 +/* sys_utimes */
30599 +
30600 +static int check_bogosity(struct pt_regs *regs)
30601 +{
30602 +       struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(&regs->regs)];
30603 +
30604 +       if(!bogon->kernel_ds) return(0);
30605 +       if(bogon->check_params && (*bogon->check_params)(regs))
30606 +               return(-EFAULT);
30607 +       set_fs(KERNEL_DS);
30608 +       return(0);
30609 +}
30610 +
30611 +extern syscall_handler_t *sys_call_table[];
30612 +
30613 +long execute_syscall_tt(void *r)
30614 +{
30615 +       struct pt_regs *regs = r;
30616 +       long res;
30617 +       int syscall;
30618 +
30619 +       current->thread.nsyscalls++;
30620 +       nsyscalls++;
30621 +       syscall = UPT_SYSCALL_NR(&regs->regs);
30622 +
30623 +       if((syscall >= NR_syscalls) || (syscall < 0))
30624 +               res = -ENOSYS;
30625 +       else if(honeypot && check_bogosity(regs))
30626 +               res = -EFAULT;
30627 +       else res = EXECUTE_SYSCALL(syscall, regs);
30628 +
30629 +       set_fs(USER_DS);
30630 +
30631 +       if(current->thread.mode.tt.singlestep_syscall){
30632 +               current->thread.mode.tt.singlestep_syscall = 0;
30633 +               current->ptrace &= ~PT_DTRACE;
30634 +               force_sig(SIGTRAP, current);
30635 +       }
30636 +
30637 +       return(res);
30638 +}
30639 +
30640 +/*
30641 + * Overrides for Emacs so that we follow Linus's tabbing style.
30642 + * Emacs will notice this stuff at the end of the file and automatically
30643 + * adjust the settings for this buffer only.  This must remain at the end
30644 + * of the file.
30645 + * ---------------------------------------------------------------------------
30646 + * Local variables:
30647 + * c-file-style: "linux"
30648 + * End:
30649 + */
30650 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_user.c um/arch/um/kernel/tt/syscall_user.c
30651 --- orig/arch/um/kernel/tt/syscall_user.c       1969-12-31 19:00:00.000000000 -0500
30652 +++ um/arch/um/kernel/tt/syscall_user.c 2003-10-21 03:26:07.000000000 -0400
30653 @@ -0,0 +1,89 @@
30654 +/* 
30655 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
30656 + * Licensed under the GPL
30657 + */
30658 +
30659 +#include <unistd.h>
30660 +#include <signal.h>
30661 +#include <errno.h>
30662 +#include <sys/ptrace.h>
30663 +#include <asm/unistd.h>
30664 +#include "sysdep/ptrace.h"
30665 +#include "sigcontext.h"
30666 +#include "ptrace_user.h"
30667 +#include "task.h"
30668 +#include "user_util.h"
30669 +#include "kern_util.h"
30670 +#include "syscall_user.h"
30671 +#include "tt.h"
30672 +
30673 +/* XXX Bogus */
30674 +#define ERESTARTSYS    512
30675 +#define ERESTARTNOINTR 513
30676 +#define ERESTARTNOHAND 514
30677 +
30678 +void syscall_handler_tt(int sig, union uml_pt_regs *regs)
30679 +{
30680 +       void *sc;
30681 +       long result;
30682 +       int index, syscall;
30683 +
30684 +       syscall = UPT_SYSCALL_NR(regs);
30685 +       sc = UPT_SC(regs);
30686 +       SC_START_SYSCALL(sc);
30687 +
30688 +       index = record_syscall_start(syscall);
30689 +       syscall_trace();
30690 +       result = execute_syscall(regs);
30691 +
30692 +       /* regs->sc may have changed while the system call ran (there may
30693 +        * have been an interrupt or segfault), so it needs to be refreshed.
30694 +        */
30695 +       UPT_SC(regs) = sc;
30696 +
30697 +       SC_SET_SYSCALL_RETURN(sc, result);
30698 +       if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || 
30699 +          (result == -ERESTARTNOINTR))
30700 +               do_signal(result);
30701 +
30702 +       syscall_trace();
30703 +       record_syscall_end(index, result);
30704 +}
30705 +
30706 +int do_syscall(void *task, int pid)
30707 +{
30708 +       unsigned long proc_regs[FRAME_SIZE];
30709 +       union uml_pt_regs *regs;
30710 +       int syscall;
30711 +
30712 +       if(ptrace_getregs(pid, proc_regs) < 0)
30713 +               tracer_panic("Couldn't read registers");
30714 +       syscall = PT_SYSCALL_NR(proc_regs);
30715 +
30716 +       regs = TASK_REGS(task);
30717 +       UPT_SYSCALL_NR(regs) = syscall;
30718 +
30719 +       if(syscall < 1) return(0);
30720 +
30721 +       if((syscall != __NR_sigreturn) &&
30722 +          ((unsigned long *) PT_IP(proc_regs) >= &_stext) && 
30723 +          ((unsigned long *) PT_IP(proc_regs) <= &_etext))
30724 +               tracer_panic("I'm tracing myself and I can't get out");
30725 +
30726 +       if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
30727 +                 __NR_getpid) < 0)
30728 +               tracer_panic("do_syscall : Nullifying syscall failed, "
30729 +                            "errno = %d", errno);
30730 +       return(1);
30731 +}
30732 +
30733 +/*
30734 + * Overrides for Emacs so that we follow Linus's tabbing style.
30735 + * Emacs will notice this stuff at the end of the file and automatically
30736 + * adjust the settings for this buffer only.  This must remain at the end
30737 + * of the file.
30738 + * ---------------------------------------------------------------------------
30739 + * Local variables:
30740 + * c-file-style: "linux"
30741 + * End:
30742 + */
30743 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/Makefile um/arch/um/kernel/tt/sys-i386/Makefile
30744 --- orig/arch/um/kernel/tt/sys-i386/Makefile    1969-12-31 19:00:00.000000000 -0500
30745 +++ um/arch/um/kernel/tt/sys-i386/Makefile      2003-10-21 03:26:07.000000000 -0400
30746 @@ -0,0 +1,17 @@
30747 +# 
30748 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
30749 +# Licensed under the GPL
30750 +#
30751 +
30752 +O_TARGET = sys-i386.o
30753 +
30754 +obj-y = sigcontext.o
30755 +
30756 +USER_OBJS = sigcontext.o
30757 +
30758 +include $(TOPDIR)/Rules.make
30759 +
30760 +$(USER_OBJS) : %.o: %.c
30761 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
30762 +
30763 +clean :
30764 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/sigcontext.c um/arch/um/kernel/tt/sys-i386/sigcontext.c
30765 --- orig/arch/um/kernel/tt/sys-i386/sigcontext.c        1969-12-31 19:00:00.000000000 -0500
30766 +++ um/arch/um/kernel/tt/sys-i386/sigcontext.c  2003-10-21 03:26:07.000000000 -0400
30767 @@ -0,0 +1,60 @@
30768 +/* 
30769 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
30770 + * Licensed under the GPL
30771 + */
30772 +
30773 +#include <stdlib.h>
30774 +#include <asm/sigcontext.h>
30775 +#include "kern_util.h"
30776 +#include "sysdep/frame.h"
30777 +
30778 +int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data)
30779 +{
30780 +       struct arch_frame_data *arch = data;
30781 +       struct sigcontext *to = to_ptr, *from = from_ptr;
30782 +       struct _fpstate *to_fp, *from_fp;
30783 +       unsigned long sigs;
30784 +       int err;
30785 +
30786 +       to_fp = to->fpstate;
30787 +       from_fp = from->fpstate;
30788 +       sigs = to->oldmask;
30789 +       err = copy_from_user_proc(to, from, sizeof(*to));
30790 +       to->oldmask = sigs;
30791 +       if(to_fp != NULL){
30792 +               err |= copy_from_user_proc(&to->fpstate, &to_fp,
30793 +                                          sizeof(to->fpstate));
30794 +               err |= copy_from_user_proc(to_fp, from_fp, arch->fpstate_size);
30795 +       }
30796 +       return(err);
30797 +}
30798 +
30799 +int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data)
30800 +{
30801 +       struct arch_frame_data *arch = data;
30802 +       struct sigcontext *to = to_ptr, *from = from_ptr;
30803 +       struct _fpstate *to_fp, *from_fp;
30804 +       int err;
30805 +
30806 +       to_fp = (struct _fpstate *) 
30807 +               (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
30808 +       from_fp = from->fpstate;
30809 +       err = copy_to_user_proc(to, from, sizeof(*to));
30810 +       if(from_fp != NULL){
30811 +               err |= copy_to_user_proc(&to->fpstate, &to_fp,
30812 +                                        sizeof(to->fpstate));
30813 +               err |= copy_to_user_proc(to_fp, from_fp, arch->fpstate_size);
30814 +       }
30815 +       return(err);
30816 +}
30817 +
30818 +/*
30819 + * Overrides for Emacs so that we follow Linus's tabbing style.
30820 + * Emacs will notice this stuff at the end of the file and automatically
30821 + * adjust the settings for this buffer only.  This must remain at the end
30822 + * of the file.
30823 + * ---------------------------------------------------------------------------
30824 + * Local variables:
30825 + * c-file-style: "linux"
30826 + * End:
30827 + */
30828 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/time.c um/arch/um/kernel/tt/time.c
30829 --- orig/arch/um/kernel/tt/time.c       1969-12-31 19:00:00.000000000 -0500
30830 +++ um/arch/um/kernel/tt/time.c 2003-10-21 03:26:07.000000000 -0400
30831 @@ -0,0 +1,28 @@
30832 +/* 
30833 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
30834 + * Licensed under the GPL
30835 + */
30836 +
30837 +#include <signal.h>
30838 +#include <sys/time.h>
30839 +#include <time_user.h>
30840 +#include "process.h"
30841 +#include "user.h"
30842 +
30843 +void user_time_init_tt(void)
30844 +{
30845 +       if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
30846 +               panic("Couldn't set SIGVTALRM handler");
30847 +       set_interval(ITIMER_VIRTUAL);
30848 +}
30849 +
30850 +/*
30851 + * Overrides for Emacs so that we follow Linus's tabbing style.
30852 + * Emacs will notice this stuff at the end of the file and automatically
30853 + * adjust the settings for this buffer only.  This must remain at the end
30854 + * of the file.
30855 + * ---------------------------------------------------------------------------
30856 + * Local variables:
30857 + * c-file-style: "linux"
30858 + * End:
30859 + */
30860 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tlb.c um/arch/um/kernel/tt/tlb.c
30861 --- orig/arch/um/kernel/tt/tlb.c        1969-12-31 19:00:00.000000000 -0500
30862 +++ um/arch/um/kernel/tt/tlb.c  2003-11-13 00:40:57.000000000 -0500
30863 @@ -0,0 +1,220 @@
30864 +/* 
30865 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
30866 + * Licensed under the GPL
30867 + */
30868 +
30869 +#include "linux/stddef.h"
30870 +#include "linux/kernel.h"
30871 +#include "linux/sched.h"
30872 +#include "asm/page.h"
30873 +#include "asm/pgtable.h"
30874 +#include "asm/uaccess.h"
30875 +#include "user_util.h"
30876 +#include "mem_user.h"
30877 +#include "os.h"
30878 +
30879 +static void fix_range(struct mm_struct *mm, unsigned long start_addr, 
30880 +                     unsigned long end_addr, int force)
30881 +{
30882 +       pgd_t *npgd;
30883 +       pmd_t *npmd;
30884 +       pte_t *npte;
30885 +       unsigned long addr;
30886 +       int r, w, x, err;
30887 +
30888 +       if((current->thread.mode.tt.extern_pid != -1) && 
30889 +          (current->thread.mode.tt.extern_pid != os_getpid()))
30890 +               panic("fix_range fixing wrong address space, current = 0x%p",
30891 +                     current);
30892 +       if(mm == NULL) return;
30893 +       for(addr=start_addr;addr<end_addr;){
30894 +               if(addr == TASK_SIZE){
30895 +                       /* Skip over kernel text, kernel data, and physical
30896 +                        * memory, which don't have ptes, plus kernel virtual
30897 +                        * memory, which is flushed separately, and remap
30898 +                        * the process stack.  The only way to get here is
30899 +                        * if (end_addr == STACK_TOP) > TASK_SIZE, which is
30900 +                        * only true in the honeypot case.
30901 +                        */
30902 +                       addr = STACK_TOP - ABOVE_KMEM;
30903 +                       continue;
30904 +               }
30905 +               npgd = pgd_offset(mm, addr);
30906 +               npmd = pmd_offset(npgd, addr);
30907 +               if(pmd_present(*npmd)){
30908 +                       npte = pte_offset(npmd, addr);
30909 +                       r = pte_read(*npte);
30910 +                       w = pte_write(*npte);
30911 +                       x = pte_exec(*npte);
30912 +                       if(!pte_dirty(*npte)) w = 0;
30913 +                       if(!pte_young(*npte)){
30914 +                               r = 0;
30915 +                               w = 0;
30916 +                       }
30917 +                       if(force || pte_newpage(*npte)){
30918 +                               err = os_unmap_memory((void *) addr, 
30919 +                                                     PAGE_SIZE);
30920 +                               if(err < 0)
30921 +                                       panic("munmap failed, errno = %d\n",
30922 +                                             -err);
30923 +                               if(pte_present(*npte))
30924 +                                       map_memory(addr, 
30925 +                                                  pte_val(*npte) & PAGE_MASK,
30926 +                                                  PAGE_SIZE, r, w, x);
30927 +                       }
30928 +                       else if(pte_newprot(*npte)){
30929 +                               protect_memory(addr, PAGE_SIZE, r, w, x, 1);
30930 +                       }
30931 +                       *npte = pte_mkuptodate(*npte);
30932 +                       addr += PAGE_SIZE;
30933 +               }
30934 +               else {
30935 +                       if(force || pmd_newpage(*npmd)){
30936 +                               err = os_unmap_memory((void *) addr, PMD_SIZE);
30937 +                               if(err < 0)
30938 +                                       panic("munmap failed, errno = %d\n",
30939 +                                             -err);
30940 +                               pmd_mkuptodate(*npmd);
30941 +                       }
30942 +                       addr += PMD_SIZE;
30943 +               }
30944 +       }
30945 +}
30946 +
30947 +atomic_t vmchange_seq = ATOMIC_INIT(1);
30948 +
30949 +static void flush_kernel_vm_range(unsigned long start, unsigned long end,
30950 +                                 int update_seq)
30951 +{
30952 +       struct mm_struct *mm;
30953 +       pgd_t *pgd;
30954 +       pmd_t *pmd;
30955 +       pte_t *pte;
30956 +       unsigned long addr;
30957 +       int updated = 0, err;
30958 +
30959 +       mm = &init_mm;
30960 +       for(addr = start; addr < end;){
30961 +               pgd = pgd_offset(mm, addr);
30962 +               pmd = pmd_offset(pgd, addr);
30963 +               if(pmd_present(*pmd)){
30964 +                       pte = pte_offset(pmd, addr);
30965 +                       if(!pte_present(*pte) || pte_newpage(*pte)){
30966 +                               updated = 1;
30967 +                               err = os_unmap_memory((void *) addr, 
30968 +                                                     PAGE_SIZE);
30969 +                               if(err < 0)
30970 +                                       panic("munmap failed, errno = %d\n",
30971 +                                             -err);
30972 +                               if(pte_present(*pte))
30973 +                                       map_memory(addr, 
30974 +                                                  pte_val(*pte) & PAGE_MASK,
30975 +                                                  PAGE_SIZE, 1, 1, 1);
30976 +                       }
30977 +                       else if(pte_newprot(*pte)){
30978 +                               updated = 1;
30979 +                               protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
30980 +                       }
30981 +                       addr += PAGE_SIZE;
30982 +               }
30983 +               else {
30984 +                       if(pmd_newpage(*pmd)){
30985 +                               updated = 1;
30986 +                               err = os_unmap_memory((void *) addr, PMD_SIZE);
30987 +                               if(err < 0)
30988 +                                       panic("munmap failed, errno = %d\n",
30989 +                                             -err);
30990 +                       }
30991 +                       addr += PMD_SIZE;
30992 +               }
30993 +       }
30994 +       if(updated && update_seq) atomic_inc(&vmchange_seq);
30995 +}
30996 +
30997 +static void protect_vm_page(unsigned long addr, int w, int must_succeed)
30998 +{
30999 +       int err;
31000 +
31001 +       err = protect_memory(addr, PAGE_SIZE, 1, w, 1, must_succeed);
31002 +       if(err == 0) return;
31003 +       else if((err == -EFAULT) || (err == -ENOMEM)){
31004 +               flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
31005 +               protect_vm_page(addr, w, 1);
31006 +       }
31007 +       else panic("protect_vm_page : protect failed, errno = %d\n", err);
31008 +}
31009 +
31010 +void mprotect_kernel_vm(int w)
31011 +{
31012 +       struct mm_struct *mm;
31013 +       pgd_t *pgd;
31014 +       pmd_t *pmd;
31015 +       pte_t *pte;
31016 +       unsigned long addr;
31017 +       
31018 +       mm = &init_mm;
31019 +       for(addr = start_vm; addr < end_vm;){
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)) protect_vm_page(addr, w, 0);
31025 +                       addr += PAGE_SIZE;
31026 +               }
31027 +               else addr += PMD_SIZE;
31028 +       }
31029 +}
31030 +
31031 +void flush_tlb_kernel_vm_tt(void)
31032 +{
31033 +       flush_kernel_vm_range(start_vm, end_vm, 1);
31034 +}
31035 +
31036 +void __flush_tlb_one_tt(unsigned long addr)
31037 +{
31038 +       flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
31039 +}
31040 +
31041 +void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start, 
31042 +                    unsigned long end)
31043 +{
31044 +       if(mm != current->mm) return;
31045 +
31046 +       /* Assumes that the range start ... end is entirely within
31047 +        * either process memory or kernel vm
31048 +        */
31049 +       if((start >= start_vm) && (start < end_vm)) 
31050 +               flush_kernel_vm_range(start, end, 1);
31051 +       else fix_range(mm, start, end, 0);
31052 +}
31053 +
31054 +void flush_tlb_mm_tt(struct mm_struct *mm)
31055 +{
31056 +       unsigned long seq;
31057 +
31058 +       if(mm != current->mm) return;
31059 +
31060 +       fix_range(mm, 0, STACK_TOP, 0);
31061 +
31062 +       seq = atomic_read(&vmchange_seq);
31063 +       if(current->thread.mode.tt.vm_seq == seq) return;
31064 +       current->thread.mode.tt.vm_seq = seq;
31065 +       flush_kernel_vm_range(start_vm, end_vm, 0);
31066 +}
31067 +
31068 +void force_flush_all_tt(void)
31069 +{
31070 +       fix_range(current->mm, 0, STACK_TOP, 1);
31071 +       flush_kernel_vm_range(start_vm, end_vm, 0);
31072 +}
31073 +
31074 +/*
31075 + * Overrides for Emacs so that we follow Linus's tabbing style.
31076 + * Emacs will notice this stuff at the end of the file and automatically
31077 + * adjust the settings for this buffer only.  This must remain at the end
31078 + * of the file.
31079 + * ---------------------------------------------------------------------------
31080 + * Local variables:
31081 + * c-file-style: "linux"
31082 + * End:
31083 + */
31084 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tracer.c um/arch/um/kernel/tt/tracer.c
31085 --- orig/arch/um/kernel/tt/tracer.c     1969-12-31 19:00:00.000000000 -0500
31086 +++ um/arch/um/kernel/tt/tracer.c       2003-10-21 03:26:07.000000000 -0400
31087 @@ -0,0 +1,454 @@
31088 +/* 
31089 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
31090 + * Licensed under the GPL
31091 + */
31092 +
31093 +#include <stdio.h>
31094 +#include <stdlib.h>
31095 +#include <stdarg.h>
31096 +#include <unistd.h>
31097 +#include <signal.h>
31098 +#include <errno.h>
31099 +#include <sched.h>
31100 +#include <string.h>
31101 +#include <sys/mman.h>
31102 +#include <sys/ptrace.h>
31103 +#include <sys/time.h>
31104 +#include <sys/wait.h>
31105 +#include "user.h"
31106 +#include "sysdep/ptrace.h"
31107 +#include "sigcontext.h"
31108 +#include "sysdep/sigcontext.h"
31109 +#include "os.h"
31110 +#include "signal_user.h"
31111 +#include "user_util.h"
31112 +#include "mem_user.h"
31113 +#include "process.h"
31114 +#include "kern_util.h"
31115 +#include "frame.h"
31116 +#include "chan_user.h"
31117 +#include "ptrace_user.h"
31118 +#include "mode.h"
31119 +#include "tt.h"
31120 +
31121 +static int tracer_winch[2];
31122 +
31123 +int is_tracer_winch(int pid, int fd, void *data)
31124 +{
31125 +       if(pid != tracing_pid)
31126 +               return(0);
31127 +
31128 +       register_winch_irq(tracer_winch[0], fd, -1, data);
31129 +       return(1);
31130 +}
31131 +
31132 +static void tracer_winch_handler(int sig)
31133 +{
31134 +       int n;
31135 +       char c = 1;
31136 +
31137 +       n = os_write_file(tracer_winch[1], &c, sizeof(c));
31138 +       if(n != sizeof(c))
31139 +               printk("tracer_winch_handler - write failed, err = %d\n", -n);
31140 +}
31141 +
31142 +/* Called only by the tracing thread during initialization */
31143 +
31144 +static void setup_tracer_winch(void)
31145 +{
31146 +       int err;
31147 +
31148 +       err = os_pipe(tracer_winch, 1, 1);
31149 +       if(err < 0){
31150 +               printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
31151 +               return;
31152 +       }
31153 +       signal(SIGWINCH, tracer_winch_handler);
31154 +}
31155 +
31156 +void attach_process(int pid)
31157 +{
31158 +       if((ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) ||
31159 +          (ptrace(PTRACE_CONT, pid, 0, 0) < 0))
31160 +               tracer_panic("OP_FORK failed to attach pid");
31161 +       wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
31162 +       if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
31163 +               tracer_panic("OP_FORK failed to continue process");
31164 +}
31165 +
31166 +void tracer_panic(char *format, ...)
31167 +{
31168 +       va_list ap;
31169 +
31170 +       va_start(ap, format);
31171 +       vprintf(format, ap);
31172 +       printf("\n");
31173 +       while(1) pause();
31174 +}
31175 +
31176 +static void tracer_segv(int sig, struct sigcontext sc)
31177 +{
31178 +       printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
31179 +              SC_FAULT_ADDR(&sc), SC_IP(&sc));
31180 +       while(1)
31181 +               pause();
31182 +}
31183 +
31184 +/* Changed early in boot, and then only read */
31185 +int debug = 0;
31186 +int debug_stop = 1;
31187 +int debug_parent = 0;
31188 +int honeypot = 0;
31189 +
31190 +static int signal_tramp(void *arg)
31191 +{
31192 +       int (*proc)(void *);
31193 +
31194 +       if(honeypot && munmap((void *) (host_task_size - 0x10000000),
31195 +                             0x10000000)) 
31196 +               panic("Unmapping stack failed");
31197 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
31198 +               panic("ptrace PTRACE_TRACEME failed");
31199 +       os_stop_process(os_getpid());
31200 +       change_sig(SIGWINCH, 0);
31201 +       signal(SIGUSR1, SIG_IGN);
31202 +       change_sig(SIGCHLD, 0);
31203 +       signal(SIGSEGV, (__sighandler_t) sig_handler);
31204 +       set_cmdline("(idle thread)");
31205 +       set_init_pid(os_getpid());
31206 +       proc = arg;
31207 +       return((*proc)(NULL));
31208 +}
31209 +
31210 +static void sleeping_process_signal(int pid, int sig)
31211 +{
31212 +       switch(sig){
31213 +       /* These two result from UML being ^Z-ed and bg-ed.  PTRACE_CONT is
31214 +        * right because the process must be in the kernel already.
31215 +        */
31216 +       case SIGCONT:
31217 +       case SIGTSTP:
31218 +               if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
31219 +                       tracer_panic("sleeping_process_signal : Failed to "
31220 +                                    "continue pid %d, signal = %d, "
31221 +                                    "errno = %d\n", pid, sig, errno);
31222 +               break;
31223 +
31224 +       /* This happens when the debugger (e.g. strace) is doing system call 
31225 +        * tracing on the kernel.  During a context switch, the current task
31226 +        * will be set to the incoming process and the outgoing process will
31227 +        * hop into write and then read.  Since it's not the current process
31228 +        * any more, the trace of those will land here.  So, we need to just 
31229 +        * PTRACE_SYSCALL it.
31230 +        */
31231 +       case SIGTRAP:
31232 +               if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
31233 +                       tracer_panic("sleeping_process_signal : Failed to "
31234 +                                    "PTRACE_SYSCALL pid %d, errno = %d\n",
31235 +                                    pid, errno);
31236 +               break;
31237 +       case SIGSTOP:
31238 +               break;
31239 +       default:
31240 +               tracer_panic("sleeping process %d got unexpected "
31241 +                            "signal : %d\n", pid, sig);
31242 +               break;
31243 +       }
31244 +}
31245 +
31246 +/* Accessed only by the tracing thread */
31247 +int debugger_pid = -1;
31248 +int debugger_parent = -1;
31249 +int debugger_fd = -1;
31250 +int gdb_pid = -1;
31251 +
31252 +struct {
31253 +       int pid;
31254 +       int signal;
31255 +       unsigned long addr;
31256 +       struct timeval time;
31257 +} signal_record[1024][32];
31258 +
31259 +int signal_index[32];
31260 +int nsignals = 0;
31261 +int debug_trace = 0;
31262 +extern int io_nsignals, io_count, intr_count;
31263 +
31264 +extern void signal_usr1(int sig);
31265 +
31266 +int tracing_pid = -1;
31267 +
31268 +int tracer(int (*init_proc)(void *), void *sp)
31269 +{
31270 +       void *task = NULL;
31271 +       unsigned long eip = 0;
31272 +       int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
31273 +       int last_index, proc_id = 0, n, err, old_tracing = 0, strace = 0;
31274 +
31275 +       capture_signal_stack();
31276 +       signal(SIGPIPE, SIG_IGN);
31277 +       setup_tracer_winch();
31278 +       tracing_pid = os_getpid();
31279 +       printf("tracing thread pid = %d\n", tracing_pid);
31280 +
31281 +       pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
31282 +       n = waitpid(pid, &status, WUNTRACED);
31283 +       if(n < 0){
31284 +               printf("waitpid on idle thread failed, errno = %d\n", errno);
31285 +               exit(1);
31286 +       }
31287 +       if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
31288 +               printf("Failed to continue idle thread, errno = %d\n", errno);
31289 +               exit(1);
31290 +       }
31291 +
31292 +       signal(SIGSEGV, (sighandler_t) tracer_segv);
31293 +       signal(SIGUSR1, signal_usr1);
31294 +       if(debug_trace){
31295 +               printf("Tracing thread pausing to be attached\n");
31296 +               stop();
31297 +       }
31298 +       if(debug){
31299 +               if(gdb_pid != -1) 
31300 +                       debugger_pid = attach_debugger(pid, gdb_pid, 1);
31301 +               else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop);
31302 +               if(debug_parent){
31303 +                       debugger_parent = os_process_parent(debugger_pid);
31304 +                       init_parent_proxy(debugger_parent);
31305 +                       err = attach(debugger_parent);
31306 +                       if(err){
31307 +                               printf("Failed to attach debugger parent %d, "
31308 +                                      "errno = %d\n", debugger_parent, -err);
31309 +                               debugger_parent = -1;
31310 +                       }
31311 +                       else {
31312 +                               if(ptrace(PTRACE_SYSCALL, debugger_parent, 
31313 +                                         0, 0) < 0){
31314 +                                       printf("Failed to continue debugger "
31315 +                                              "parent, errno = %d\n", errno);
31316 +                                       debugger_parent = -1;
31317 +                               }
31318 +                       }
31319 +               }
31320 +       }
31321 +       set_cmdline("(tracing thread)");
31322 +       while(1){
31323 +               pid = waitpid(-1, &status, WUNTRACED);
31324 +               if(pid <= 0){
31325 +                       if(errno != ECHILD){
31326 +                               printf("wait failed - errno = %d\n", errno);
31327 +                       }
31328 +                       continue;
31329 +               }
31330 +               if(pid == debugger_pid){
31331 +                       int cont = 0;
31332 +
31333 +                       if(WIFEXITED(status) || WIFSIGNALED(status))
31334 +                               debugger_pid = -1;
31335 +                       /* XXX Figure out how to deal with gdb and SMP */
31336 +                       else cont = debugger_signal(status, cpu_tasks[0].pid);
31337 +                       if(cont == PTRACE_SYSCALL) strace = 1;
31338 +                       continue;
31339 +               }
31340 +               else if(pid == debugger_parent){
31341 +                       debugger_parent_signal(status, pid);
31342 +                       continue;
31343 +               }
31344 +               nsignals++;
31345 +               if(WIFEXITED(status)) ;
31346 +#ifdef notdef
31347 +               {
31348 +                       printf("Child %d exited with status %d\n", pid, 
31349 +                              WEXITSTATUS(status));
31350 +               }
31351 +#endif
31352 +               else if(WIFSIGNALED(status)){
31353 +                       sig = WTERMSIG(status);
31354 +                       if(sig != 9){
31355 +                               printf("Child %d exited with signal %d\n", pid,
31356 +                                      sig);
31357 +                       }
31358 +               }
31359 +               else if(WIFSTOPPED(status)){
31360 +                       proc_id = pid_to_processor_id(pid);
31361 +                       sig = WSTOPSIG(status);
31362 +                       if(signal_index[proc_id] == 1024){
31363 +                               signal_index[proc_id] = 0;
31364 +                               last_index = 1023;
31365 +                       }
31366 +                       else last_index = signal_index[proc_id] - 1;
31367 +                       if(((sig == SIGPROF) || (sig == SIGVTALRM) || 
31368 +                           (sig == SIGALRM)) &&
31369 +                          (signal_record[proc_id][last_index].signal == sig)&&
31370 +                          (signal_record[proc_id][last_index].pid == pid))
31371 +                               signal_index[proc_id] = last_index;
31372 +                       signal_record[proc_id][signal_index[proc_id]].pid = pid;
31373 +                       gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL);
31374 +                       eip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
31375 +                       signal_record[proc_id][signal_index[proc_id]].addr = eip;
31376 +                       signal_record[proc_id][signal_index[proc_id]++].signal = sig;
31377 +                       
31378 +                       if(proc_id == -1){
31379 +                               sleeping_process_signal(pid, sig);
31380 +                               continue;
31381 +                       }
31382 +
31383 +                       task = cpu_tasks[proc_id].task;
31384 +                       tracing = is_tracing(task);
31385 +                       old_tracing = tracing;
31386 +
31387 +                       switch(sig){
31388 +                       case SIGUSR1:
31389 +                               sig = 0;
31390 +                               op = do_proc_op(task, proc_id);
31391 +                               switch(op){
31392 +                               case OP_TRACE_ON:
31393 +                                       arch_leave_kernel(task, pid);
31394 +                                       tracing = 1;
31395 +                                       break;
31396 +                               case OP_REBOOT:
31397 +                               case OP_HALT:
31398 +                                       unmap_physmem();
31399 +                                       kmalloc_ok = 0;
31400 +                                       ptrace(PTRACE_KILL, pid, 0, 0);
31401 +                                       return(op == OP_REBOOT);
31402 +                               case OP_NONE:
31403 +                                       printf("Detaching pid %d\n", pid);
31404 +                                       detach(pid, SIGSTOP);
31405 +                                       continue;
31406 +                               default:
31407 +                                       break;
31408 +                               }
31409 +                               /* OP_EXEC switches host processes on us,
31410 +                                * we want to continue the new one.
31411 +                                */
31412 +                               pid = cpu_tasks[proc_id].pid;
31413 +                               break;
31414 +                       case SIGTRAP:
31415 +                               if(!tracing && (debugger_pid != -1)){
31416 +                                       child_signal(pid, status);
31417 +                                       continue;
31418 +                               }
31419 +                               tracing = 0;
31420 +                               if(do_syscall(task, pid)) sig = SIGUSR2;
31421 +                               else clear_singlestep(task);
31422 +                               break;
31423 +                       case SIGPROF:
31424 +                               if(tracing) sig = 0;
31425 +                               break;
31426 +                       case SIGCHLD:
31427 +                       case SIGHUP:
31428 +                               sig = 0;
31429 +                               break;
31430 +                       case SIGSEGV:
31431 +                       case SIGIO:
31432 +                       case SIGALRM:
31433 +                       case SIGVTALRM:
31434 +                       case SIGFPE:
31435 +                       case SIGBUS:
31436 +                       case SIGILL:
31437 +                       case SIGWINCH:
31438 +                       default:
31439 +                               tracing = 0;
31440 +                               break;
31441 +                       }
31442 +                       set_tracing(task, tracing);
31443 +
31444 +                       if(!tracing && old_tracing)
31445 +                               arch_enter_kernel(task, pid);
31446 +
31447 +                       if(!tracing && (debugger_pid != -1) && (sig != 0) &&
31448 +                               (sig != SIGALRM) && (sig != SIGVTALRM) &&
31449 +                               (sig != SIGSEGV) && (sig != SIGTRAP) &&
31450 +                               (sig != SIGUSR2) && (sig != SIGIO) &&
31451 +                               (sig != SIGFPE)){
31452 +                               child_signal(pid, status);
31453 +                               continue;
31454 +                       }
31455 +
31456 +                       if(tracing){
31457 +                               if(singlestepping_tt(task))
31458 +                                       cont_type = PTRACE_SINGLESTEP;
31459 +                               else cont_type = PTRACE_SYSCALL;
31460 +                       }
31461 +                       else cont_type = PTRACE_CONT;
31462 +
31463 +                       if((cont_type == PTRACE_CONT) && 
31464 +                          (debugger_pid != -1) && strace)
31465 +                               cont_type = PTRACE_SYSCALL;
31466 +
31467 +                       if(ptrace(cont_type, pid, 0, sig) != 0){
31468 +                               tracer_panic("ptrace failed to continue "
31469 +                                            "process - errno = %d\n", 
31470 +                                            errno);
31471 +                       }
31472 +               }
31473 +       }
31474 +       return(0);
31475 +}
31476 +
31477 +static int __init uml_debug_setup(char *line, int *add)
31478 +{
31479 +       char *next;
31480 +
31481 +       debug = 1;
31482 +       *add = 0;
31483 +       if(*line != '=') return(0);
31484 +       line++;
31485 +
31486 +       while(line != NULL){
31487 +               next = strchr(line, ',');
31488 +               if(next) *next++ = '\0';
31489 +               
31490 +               if(!strcmp(line, "go")) debug_stop = 0;
31491 +               else if(!strcmp(line, "parent")) debug_parent = 1;
31492 +               else printf("Unknown debug option : '%s'\n", line);
31493 +
31494 +               line = next;
31495 +       }
31496 +       return(0);
31497 +}
31498 +
31499 +__uml_setup("debug", uml_debug_setup,
31500 +"debug\n"
31501 +"    Starts up the kernel under the control of gdb. See the \n"
31502 +"    kernel debugging tutorial and the debugging session pages\n"
31503 +"    at http://user-mode-linux.sourceforge.net/ for more information.\n\n"
31504 +);
31505 +
31506 +static int __init uml_debugtrace_setup(char *line, int *add)
31507 +{
31508 +       debug_trace = 1;
31509 +       return 0;
31510 +}
31511 +__uml_setup("debugtrace", uml_debugtrace_setup,
31512 +"debugtrace\n"
31513 +"    Causes the tracing thread to pause until it is attached by a\n"
31514 +"    debugger and continued.  This is mostly for debugging crashes\n"
31515 +"    early during boot, and should be pretty much obsoleted by\n"
31516 +"    the debug switch.\n\n"
31517 +);
31518 +
31519 +static int __init uml_honeypot_setup(char *line, int *add)
31520 +{
31521 +       jail_setup("", add);
31522 +       honeypot = 1;
31523 +       return 0;
31524 +}
31525 +__uml_setup("honeypot", uml_honeypot_setup, 
31526 +"honeypot\n"
31527 +"    This makes UML put process stacks in the same location as they are\n"
31528 +"    on the host, allowing expoits such as stack smashes to work against\n"
31529 +"    UML.  This implies 'jail'.\n\n"
31530 +);
31531 +
31532 +/*
31533 + * Overrides for Emacs so that we follow Linus's tabbing style.
31534 + * Emacs will notice this stuff at the end of the file and automatically
31535 + * adjust the settings for this buffer only.  This must remain at the end
31536 + * of the file.
31537 + * ---------------------------------------------------------------------------
31538 + * Local variables:
31539 + * c-file-style: "linux"
31540 + * End:
31541 + */
31542 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/trap_user.c um/arch/um/kernel/tt/trap_user.c
31543 --- orig/arch/um/kernel/tt/trap_user.c  1969-12-31 19:00:00.000000000 -0500
31544 +++ um/arch/um/kernel/tt/trap_user.c    2003-10-21 03:26:07.000000000 -0400
31545 @@ -0,0 +1,59 @@
31546 +/* 
31547 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
31548 + * Licensed under the GPL
31549 + */
31550 +
31551 +#include <stdlib.h>
31552 +#include <errno.h>
31553 +#include <signal.h>
31554 +#include <asm/sigcontext.h>
31555 +#include "sysdep/ptrace.h"
31556 +#include "signal_user.h"
31557 +#include "user_util.h"
31558 +#include "kern_util.h"
31559 +#include "task.h"
31560 +#include "tt.h"
31561 +
31562 +void sig_handler_common_tt(int sig, void *sc_ptr)
31563 +{
31564 +       struct sigcontext *sc = sc_ptr;
31565 +       struct tt_regs save_regs, *r;
31566 +       struct signal_info *info;
31567 +       int save_errno = errno, is_user;
31568 +
31569 +       unprotect_kernel_mem();
31570 +
31571 +       r = &TASK_REGS(get_current())->tt;
31572 +       save_regs = *r;
31573 +       is_user = user_context(SC_SP(sc));
31574 +       r->sc = sc;
31575 +       if(sig != SIGUSR2) 
31576 +               r->syscall = -1;
31577 +
31578 +       change_sig(SIGUSR1, 1);
31579 +       info = &sig_info[sig];
31580 +       if(!info->is_irq) unblock_signals();
31581 +
31582 +       (*info->handler)(sig, (union uml_pt_regs *) r);
31583 +
31584 +       if(is_user){
31585 +               interrupt_end();
31586 +               block_signals();
31587 +               change_sig(SIGUSR1, 0);
31588 +               set_user_mode(NULL);
31589 +       }
31590 +       *r = save_regs;
31591 +       errno = save_errno;
31592 +       if(is_user) protect_kernel_mem();
31593 +}
31594 +
31595 +/*
31596 + * Overrides for Emacs so that we follow Linus's tabbing style.
31597 + * Emacs will notice this stuff at the end of the file and automatically
31598 + * adjust the settings for this buffer only.  This must remain at the end
31599 + * of the file.
31600 + * ---------------------------------------------------------------------------
31601 + * Local variables:
31602 + * c-file-style: "linux"
31603 + * End:
31604 + */
31605 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/uaccess.c um/arch/um/kernel/tt/uaccess.c
31606 --- orig/arch/um/kernel/tt/uaccess.c    1969-12-31 19:00:00.000000000 -0500
31607 +++ um/arch/um/kernel/tt/uaccess.c      2003-11-13 00:12:45.000000000 -0500
31608 @@ -0,0 +1,73 @@
31609 +/* 
31610 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
31611 + * Licensed under the GPL
31612 + */
31613 +
31614 +#include "linux/sched.h"
31615 +#include "asm/uaccess.h"
31616 +
31617 +int copy_from_user_tt(void *to, const void *from, int n)
31618 +{
31619 +       if(!access_ok_tt(VERIFY_READ, from, n)) 
31620 +               return(n);
31621 +
31622 +       return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
31623 +                                  &current->thread.fault_catcher));
31624 +}
31625 +
31626 +int copy_to_user_tt(void *to, const void *from, int n)
31627 +{
31628 +       if(!access_ok_tt(VERIFY_WRITE, to, n))
31629 +               return(n);
31630 +               
31631 +       return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
31632 +                                &current->thread.fault_catcher));
31633 +}
31634 +
31635 +int strncpy_from_user_tt(char *dst, const char *src, int count)
31636 +{
31637 +       int n;
31638 +
31639 +       if(!access_ok_tt(VERIFY_READ, src, 1)) 
31640 +               return(-EFAULT);
31641 +
31642 +       n = __do_strncpy_from_user(dst, src, count, 
31643 +                                  &current->thread.fault_addr,
31644 +                                  &current->thread.fault_catcher);
31645 +       if(n < 0) return(-EFAULT);
31646 +       return(n);
31647 +}
31648 +
31649 +int __clear_user_tt(void *mem, int len)
31650 +{
31651 +       return(__do_clear_user(mem, len,
31652 +                              &current->thread.fault_addr,
31653 +                              &current->thread.fault_catcher));
31654 +}
31655 +
31656 +int clear_user_tt(void *mem, int len)
31657 +{
31658 +       if(!access_ok_tt(VERIFY_WRITE, mem, len))
31659 +               return(len);
31660 +
31661 +       return(__do_clear_user(mem, len, &current->thread.fault_addr,
31662 +                              &current->thread.fault_catcher));
31663 +}
31664 +
31665 +int strnlen_user_tt(const void *str, int len)
31666 +{
31667 +       return(__do_strnlen_user(str, len,
31668 +                                &current->thread.fault_addr,
31669 +                                &current->thread.fault_catcher));
31670 +}
31671 +
31672 +/*
31673 + * Overrides for Emacs so that we follow Linus's tabbing style.
31674 + * Emacs will notice this stuff at the end of the file and automatically
31675 + * adjust the settings for this buffer only.  This must remain at the end
31676 + * of the file.
31677 + * ---------------------------------------------------------------------------
31678 + * Local variables:
31679 + * c-file-style: "linux"
31680 + * End:
31681 + */
31682 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/uaccess_user.c um/arch/um/kernel/tt/uaccess_user.c
31683 --- orig/arch/um/kernel/tt/uaccess_user.c       1969-12-31 19:00:00.000000000 -0500
31684 +++ um/arch/um/kernel/tt/uaccess_user.c 2004-01-31 02:48:29.000000000 -0500
31685 @@ -0,0 +1,98 @@
31686 +/* 
31687 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
31688 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
31689 + * Licensed under the GPL
31690 + */
31691 +
31692 +#include <setjmp.h>
31693 +#include <string.h>
31694 +#include "user_util.h"
31695 +#include "uml_uaccess.h"
31696 +#include "task.h"
31697 +#include "kern_util.h"
31698 +
31699 +int __do_copy_from_user(void *to, const void *from, int n,
31700 +                       void **fault_addr, void **fault_catcher)
31701 +{
31702 +       struct tt_regs save = TASK_REGS(get_current())->tt;
31703 +       unsigned long fault;
31704 +       int faulted;
31705 +
31706 +       fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
31707 +                              __do_copy, &faulted);
31708 +       TASK_REGS(get_current())->tt = save;
31709 +
31710 +       if(!faulted) return(0);
31711 +       else return(n - (fault - (unsigned long) from));
31712 +}
31713 +
31714 +static void __do_strncpy(void *dst, const void *src, int count)
31715 +{
31716 +       strncpy(dst, src, count);
31717 +}      
31718 +
31719 +int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
31720 +                          void **fault_addr, void **fault_catcher)
31721 +{
31722 +       struct tt_regs save = TASK_REGS(get_current())->tt;
31723 +       unsigned long fault;
31724 +       int faulted;
31725 +
31726 +       fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
31727 +                              __do_strncpy, &faulted);
31728 +       TASK_REGS(get_current())->tt = save;
31729 +
31730 +       if(!faulted) return(strlen(dst));
31731 +       else return(-1);
31732 +}
31733 +
31734 +static void __do_clear(void *to, const void *from, int n)
31735 +{
31736 +       memset(to, 0, n);
31737 +}      
31738 +
31739 +int __do_clear_user(void *mem, unsigned long len,
31740 +                   void **fault_addr, void **fault_catcher)
31741 +{
31742 +       struct tt_regs save = TASK_REGS(get_current())->tt;
31743 +       unsigned long fault;
31744 +       int faulted;
31745 +
31746 +       fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
31747 +                              __do_clear, &faulted);
31748 +       TASK_REGS(get_current())->tt = save;
31749 +
31750 +       if(!faulted) return(0);
31751 +       else return(len - (fault - (unsigned long) mem));
31752 +}
31753 +
31754 +int __do_strnlen_user(const char *str, unsigned long n,
31755 +                     void **fault_addr, void **fault_catcher)
31756 +{
31757 +       struct tt_regs save = TASK_REGS(get_current())->tt;
31758 +       int ret;
31759 +       unsigned long *faddrp = (unsigned long *)fault_addr;
31760 +       sigjmp_buf jbuf;
31761 +
31762 +       *fault_catcher = &jbuf;
31763 +       if(sigsetjmp(jbuf, 1) == 0)
31764 +               ret = strlen(str) + 1;
31765 +       else ret = *faddrp - (unsigned long) str;
31766 +
31767 +       *fault_addr = NULL;
31768 +       *fault_catcher = NULL;
31769 +
31770 +       TASK_REGS(get_current())->tt = save;
31771 +       return ret;
31772 +}
31773 +
31774 +/*
31775 + * Overrides for Emacs so that we follow Linus's tabbing style.
31776 + * Emacs will notice this stuff at the end of the file and automatically
31777 + * adjust the settings for this buffer only.  This must remain at the end
31778 + * of the file.
31779 + * ---------------------------------------------------------------------------
31780 + * Local variables:
31781 + * c-file-style: "linux"
31782 + * End:
31783 + */
31784 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/unmap.c um/arch/um/kernel/tt/unmap.c
31785 --- orig/arch/um/kernel/tt/unmap.c      1969-12-31 19:00:00.000000000 -0500
31786 +++ um/arch/um/kernel/tt/unmap.c        2003-10-21 03:26:07.000000000 -0400
31787 @@ -0,0 +1,31 @@
31788 +/* 
31789 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
31790 + * Licensed under the GPL
31791 + */
31792 +
31793 +#include <sys/mman.h>
31794 +
31795 +int switcheroo(int fd, int prot, void *from, void *to, int size)
31796 +{
31797 +       if(munmap(to, size) < 0){
31798 +               return(-1);
31799 +       }
31800 +       if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
31801 +               return(-1);
31802 +       }
31803 +       if(munmap(from, size) < 0){
31804 +               return(-1);
31805 +       }
31806 +       return(0);
31807 +}
31808 +
31809 +/*
31810 + * Overrides for Emacs so that we follow Linus's tabbing style.
31811 + * Emacs will notice this stuff at the end of the file and automatically
31812 + * adjust the settings for this buffer only.  This must remain at the end
31813 + * of the file.
31814 + * ---------------------------------------------------------------------------
31815 + * Local variables:
31816 + * c-file-style: "linux"
31817 + * End:
31818 + */
31819 diff -Naur -X ../exclude-files orig/arch/um/kernel/tty_log.c um/arch/um/kernel/tty_log.c
31820 --- orig/arch/um/kernel/tty_log.c       1969-12-31 19:00:00.000000000 -0500
31821 +++ um/arch/um/kernel/tty_log.c 2003-10-21 03:26:07.000000000 -0400
31822 @@ -0,0 +1,228 @@
31823 +/* 
31824 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and 
31825 + * geoffrey hing <ghing@net.ohio-state.edu>
31826 + * Licensed under the GPL
31827 + */
31828 +
31829 +#include <errno.h>
31830 +#include <string.h>
31831 +#include <stdio.h>
31832 +#include <stdlib.h>
31833 +#include <unistd.h>
31834 +#include <sys/time.h>
31835 +#include "init.h"
31836 +#include "user.h"
31837 +#include "kern_util.h"
31838 +#include "os.h"
31839 +
31840 +#define TTY_LOG_DIR "./"
31841 +
31842 +/* Set early in boot and then unchanged */
31843 +static char *tty_log_dir = TTY_LOG_DIR;
31844 +static int tty_log_fd = -1;
31845 +
31846 +#define TTY_LOG_OPEN 1
31847 +#define TTY_LOG_CLOSE 2
31848 +#define TTY_LOG_WRITE 3
31849 +#define TTY_LOG_EXEC 4
31850 +
31851 +#define TTY_READ 1
31852 +#define TTY_WRITE 2
31853 +
31854 +struct tty_log_buf {
31855 +       int what;
31856 +       unsigned long tty;
31857 +       int len;
31858 +       int direction;
31859 +       unsigned long sec;
31860 +       unsigned long usec;
31861 +};
31862 +
31863 +int open_tty_log(void *tty, void *current_tty)
31864 +{
31865 +       struct timeval tv;
31866 +       struct tty_log_buf data;
31867 +       char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
31868 +       int fd;
31869 +
31870 +       gettimeofday(&tv, NULL);
31871 +       if(tty_log_fd != -1){
31872 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_OPEN,
31873 +                                              .tty  = (unsigned long) tty,
31874 +                                              .len  = sizeof(current_tty),
31875 +                                              .direction = 0,
31876 +                                              .sec = tv.tv_sec,
31877 +                                              .usec = tv.tv_usec } );
31878 +               os_write_file(tty_log_fd, &data, sizeof(data));
31879 +               os_write_file(tty_log_fd, &current_tty, data.len);
31880 +               return(tty_log_fd);
31881 +       }
31882 +
31883 +       sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
31884 +               (unsigned int) tv.tv_usec);
31885 +
31886 +       fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
31887 +                         0644);
31888 +       if(fd < 0){
31889 +               printk("open_tty_log : couldn't open '%s', errno = %d\n",
31890 +                      buf, -fd);
31891 +       }
31892 +       return(fd);
31893 +}
31894 +
31895 +void close_tty_log(int fd, void *tty)
31896 +{
31897 +       struct tty_log_buf data;
31898 +       struct timeval tv;
31899 +
31900 +       if(tty_log_fd != -1){
31901 +               gettimeofday(&tv, NULL);
31902 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_CLOSE,
31903 +                                              .tty  = (unsigned long) tty,
31904 +                                              .len  = 0,
31905 +                                              .direction = 0,
31906 +                                              .sec = tv.tv_sec,
31907 +                                              .usec = tv.tv_usec } );
31908 +               os_write_file(tty_log_fd, &data, sizeof(data));
31909 +               return;
31910 +       }
31911 +       os_close_file(fd);
31912 +}
31913 +
31914 +static int log_chunk(int fd, const char *buf, int len)
31915 +{
31916 +       int total = 0, try, missed, n;
31917 +       char chunk[64];
31918 +
31919 +       while(len > 0){
31920 +               try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
31921 +               missed = copy_from_user_proc(chunk, (char *) buf, try);
31922 +               try -= missed;
31923 +               n = os_write_file(fd, chunk, try);
31924 +               if(n != try) {
31925 +                       if(n < 0) 
31926 +                               return(n);
31927 +                       return(-EIO);
31928 +               }
31929 +               if(missed != 0)
31930 +                       return(-EFAULT);
31931 +
31932 +               len -= try;
31933 +               total += try;
31934 +               buf += try;
31935 +       }
31936 +
31937 +       return(total);
31938 +}
31939 +
31940 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
31941 +{
31942 +       struct timeval tv;
31943 +       struct tty_log_buf data;
31944 +       int direction;
31945 +
31946 +       if(fd == tty_log_fd){
31947 +               gettimeofday(&tv, NULL);
31948 +               direction = is_read ? TTY_READ : TTY_WRITE;
31949 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_WRITE,
31950 +                                              .tty  = (unsigned long) tty,
31951 +                                              .len  = len,
31952 +                                              .direction = direction,
31953 +                                              .sec = tv.tv_sec,
31954 +                                              .usec = tv.tv_usec } );
31955 +               os_write_file(tty_log_fd, &data, sizeof(data));
31956 +       }
31957 +
31958 +       return(log_chunk(fd, buf, len));
31959 +}
31960 +
31961 +void log_exec(char **argv, void *tty)
31962 +{
31963 +       struct timeval tv;
31964 +       struct tty_log_buf data;
31965 +       char **ptr,*arg;
31966 +       int len;
31967 +       
31968 +       if(tty_log_fd == -1) return;
31969 +
31970 +       gettimeofday(&tv, NULL);
31971 +
31972 +       len = 0;
31973 +       for(ptr = argv; ; ptr++){
31974 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
31975 +                       return;
31976 +               if(arg == NULL) break;
31977 +               len += strlen_user_proc(arg);
31978 +       }
31979 +
31980 +       data = ((struct tty_log_buf) { .what    = TTY_LOG_EXEC,
31981 +                                      .tty  = (unsigned long) tty,
31982 +                                      .len  = len,
31983 +                                      .direction = 0,
31984 +                                      .sec = tv.tv_sec,
31985 +                                      .usec = tv.tv_usec } );
31986 +       os_write_file(tty_log_fd, &data, sizeof(data));
31987 +
31988 +       for(ptr = argv; ; ptr++){
31989 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
31990 +                       return;
31991 +               if(arg == NULL) break;
31992 +               log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
31993 +       }
31994 +}
31995 +
31996 +extern void register_tty_logger(int (*opener)(void *, void *),
31997 +                               int (*writer)(int, const char *, int, 
31998 +                                             void *, int),
31999 +                               void (*closer)(int, void *));
32000 +
32001 +static int register_logger(void)
32002 +{
32003 +       register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
32004 +       return(0);
32005 +}
32006 +
32007 +__uml_initcall(register_logger);
32008 +
32009 +static int __init set_tty_log_dir(char *name, int *add)
32010 +{
32011 +       tty_log_dir = name;
32012 +       return 0;
32013 +}
32014 +
32015 +__uml_setup("tty_log_dir=", set_tty_log_dir,
32016 +"tty_log_dir=<directory>\n"
32017 +"    This is used to specify the directory where the logs of all pty\n"
32018 +"    data from this UML machine will be written.\n\n"
32019 +);
32020 +
32021 +static int __init set_tty_log_fd(char *name, int *add)
32022 +{
32023 +       char *end;
32024 +
32025 +       tty_log_fd = strtoul(name, &end, 0);
32026 +       if((*end != '\0') || (end == name)){
32027 +               printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
32028 +               tty_log_fd = -1;
32029 +       }
32030 +       return 0;
32031 +}
32032 +
32033 +__uml_setup("tty_log_fd=", set_tty_log_fd,
32034 +"tty_log_fd=<fd>\n"
32035 +"    This is used to specify a preconfigured file descriptor to which all\n"
32036 +"    tty data will be written.  Preconfigure the descriptor with something\n"
32037 +"    like '10>tty_log tty_log_fd=10'.\n\n"
32038 +);
32039 +
32040 +
32041 +/*
32042 + * Overrides for Emacs so that we follow Linus's tabbing style.
32043 + * Emacs will notice this stuff at the end of the file and automatically
32044 + * adjust the settings for this buffer only.  This must remain at the end
32045 + * of the file.
32046 + * ---------------------------------------------------------------------------
32047 + * Local variables:
32048 + * c-file-style: "linux"
32049 + * End:
32050 + */
32051 diff -Naur -X ../exclude-files orig/arch/um/kernel/uaccess_user.c um/arch/um/kernel/uaccess_user.c
32052 --- orig/arch/um/kernel/uaccess_user.c  1969-12-31 19:00:00.000000000 -0500
32053 +++ um/arch/um/kernel/uaccess_user.c    2004-01-31 02:48:08.000000000 -0500
32054 @@ -0,0 +1,64 @@
32055 +/* 
32056 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
32057 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32058 + * Licensed under the GPL
32059 + */
32060 +
32061 +#include <setjmp.h>
32062 +#include <string.h>
32063 +
32064 +/* These are here rather than tt/uaccess.c because skas mode needs them in
32065 + * order to do SIGBUS recovery when a tmpfs mount runs out of room.
32066 + */
32067 +
32068 +unsigned long __do_user_copy(void *to, const void *from, int n,
32069 +                            void **fault_addr, void **fault_catcher,
32070 +                            void (*op)(void *to, const void *from,
32071 +                                       int n), int *faulted_out)
32072 +{
32073 +       unsigned long *faddrp = (unsigned long *) fault_addr, ret;
32074 +
32075 +       sigjmp_buf jbuf;
32076 +       *fault_catcher = &jbuf;
32077 +       if(sigsetjmp(jbuf, 1) == 0){
32078 +               (*op)(to, from, n);
32079 +               ret = 0;
32080 +               *faulted_out = 0;
32081 +       } 
32082 +       else {
32083 +               ret = *faddrp;
32084 +               *faulted_out = 1;
32085 +       }
32086 +       *fault_addr = NULL;
32087 +       *fault_catcher = NULL;
32088 +       return ret;
32089 +}
32090 +
32091 +void __do_copy(void *to, const void *from, int n)
32092 +{
32093 +       memcpy(to, from, n);
32094 +}      
32095 +
32096 +
32097 +int __do_copy_to_user(void *to, const void *from, int n,
32098 +                     void **fault_addr, void **fault_catcher)
32099 +{
32100 +       unsigned long fault;
32101 +       int faulted;
32102 +
32103 +       fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
32104 +                              __do_copy, &faulted);
32105 +       if(!faulted) return(0);
32106 +       else return(n - (fault - (unsigned long) to));
32107 +}
32108 +
32109 +/*
32110 + * Overrides for Emacs so that we follow Linus's tabbing style.
32111 + * Emacs will notice this stuff at the end of the file and automatically
32112 + * adjust the settings for this buffer only.  This must remain at the end
32113 + * of the file.
32114 + * ---------------------------------------------------------------------------
32115 + * Local variables:
32116 + * c-file-style: "linux"
32117 + * End:
32118 + */
32119 diff -Naur -X ../exclude-files orig/arch/um/kernel/um_arch.c um/arch/um/kernel/um_arch.c
32120 --- orig/arch/um/kernel/um_arch.c       1969-12-31 19:00:00.000000000 -0500
32121 +++ um/arch/um/kernel/um_arch.c 2004-01-10 00:11:09.000000000 -0500
32122 @@ -0,0 +1,431 @@
32123 +/* 
32124 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
32125 + * Licensed under the GPL
32126 + */
32127 +
32128 +#include "linux/config.h"
32129 +#include "linux/kernel.h"
32130 +#include "linux/sched.h"
32131 +#include "linux/notifier.h"
32132 +#include "linux/mm.h"
32133 +#include "linux/types.h"
32134 +#include "linux/tty.h"
32135 +#include "linux/init.h"
32136 +#include "linux/bootmem.h"
32137 +#include "linux/spinlock.h"
32138 +#include "linux/utsname.h"
32139 +#include "linux/sysrq.h"
32140 +#include "linux/seq_file.h"
32141 +#include "linux/delay.h"
32142 +#include "asm/page.h"
32143 +#include "asm/pgtable.h"
32144 +#include "asm/ptrace.h"
32145 +#include "asm/elf.h"
32146 +#include "asm/user.h"
32147 +#include "ubd_user.h"
32148 +#include "asm/current.h"
32149 +#include "user_util.h"
32150 +#include "kern_util.h"
32151 +#include "kern.h"
32152 +#include "mprot.h"
32153 +#include "mem_user.h"
32154 +#include "mem.h"
32155 +#include "umid.h"
32156 +#include "initrd.h"
32157 +#include "init.h"
32158 +#include "os.h"
32159 +#include "choose-mode.h"
32160 +#include "mode_kern.h"
32161 +#include "mode.h"
32162 +
32163 +#define DEFAULT_COMMAND_LINE "root=/dev/ubd0"
32164 +
32165 +struct cpuinfo_um boot_cpu_data = { 
32166 +       .loops_per_jiffy        = 0,
32167 +       .pgd_quick              = NULL,
32168 +       .pmd_quick              = NULL,
32169 +       .pte_quick              = NULL,
32170 +       .pgtable_cache_sz       = 0,
32171 +       .ipi_pipe               = { -1, -1 }
32172 +};
32173 +
32174 +unsigned long thread_saved_pc(struct thread_struct *thread)
32175 +{
32176 +       return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
32177 +                                             thread)));
32178 +}
32179 +
32180 +static int show_cpuinfo(struct seq_file *m, void *v)
32181 +{
32182 +       int index = 0;
32183 +
32184 +#ifdef CONFIG_SMP
32185 +       index = (struct cpuinfo_um *)v - cpu_data;
32186 +       if (!(cpu_online_map & (1 << index)))
32187 +               return 0;
32188 +#endif
32189 +
32190 +       seq_printf(m, "processor\t: %d\n", index);
32191 +       seq_printf(m, "vendor_id\t: User Mode Linux\n");
32192 +       seq_printf(m, "model name\t: UML\n");
32193 +       seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
32194 +       seq_printf(m, "host\t\t: %s\n", host_info);
32195 +       seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
32196 +                  loops_per_jiffy/(500000/HZ),
32197 +                  (loops_per_jiffy/(5000/HZ)) % 100);
32198 +
32199 +       return(0);
32200 +}
32201 +
32202 +static void *c_start(struct seq_file *m, loff_t *pos)
32203 +{
32204 +       return *pos < NR_CPUS ? cpu_data + *pos : NULL;
32205 +}
32206 +
32207 +static void *c_next(struct seq_file *m, void *v, loff_t *pos)
32208 +{
32209 +       ++*pos;
32210 +       return c_start(m, pos);
32211 +}
32212 +
32213 +static void c_stop(struct seq_file *m, void *v)
32214 +{
32215 +}
32216 +
32217 +struct seq_operations cpuinfo_op = {
32218 +       .start  = c_start,
32219 +       .next   = c_next,
32220 +       .stop   = c_stop,
32221 +       .show   = show_cpuinfo,
32222 +};
32223 +
32224 +pte_t * __bad_pagetable(void)
32225 +{
32226 +       panic("Someone should implement __bad_pagetable");
32227 +       return(NULL);
32228 +}
32229 +
32230 +/* Set in linux_main */
32231 +unsigned long host_task_size;
32232 +unsigned long task_size;
32233 +unsigned long uml_start;
32234 +
32235 +/* Set in early boot */
32236 +unsigned long uml_physmem;
32237 +unsigned long uml_reserved;
32238 +unsigned long start_vm;
32239 +unsigned long end_vm;
32240 +int ncpus = 1;
32241 +
32242 +#ifdef CONFIG_MODE_TT
32243 +/* Pointer set in linux_main, the array itself is private to each thread,
32244 + * and changed at address space creation time so this poses no concurrency
32245 + * problems.
32246 + */
32247 +static char *argv1_begin = NULL;
32248 +static char *argv1_end = NULL;
32249 +#endif
32250 +
32251 +/* Set in early boot */
32252 +static int have_root __initdata = 0;
32253 +long physmem_size = 32 * 1024 * 1024;
32254 +
32255 +void set_cmdline(char *cmd)
32256 +{
32257 +#ifdef CONFIG_MODE_TT
32258 +       char *umid, *ptr;
32259 +
32260 +       if(CHOOSE_MODE(honeypot, 0)) return;
32261 +
32262 +       umid = get_umid(1);
32263 +       if(umid != NULL){
32264 +               snprintf(argv1_begin, 
32265 +                        (argv1_end - argv1_begin) * sizeof(*ptr), 
32266 +                        "(%s) ", umid);
32267 +               ptr = &argv1_begin[strlen(argv1_begin)];
32268 +       }
32269 +       else ptr = argv1_begin;
32270 +
32271 +       snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
32272 +       memset(argv1_begin + strlen(argv1_begin), '\0', 
32273 +              argv1_end - argv1_begin - strlen(argv1_begin));
32274 +#endif
32275 +}
32276 +
32277 +static char *usage_string = 
32278 +"User Mode Linux v%s\n"
32279 +"      available at http://user-mode-linux.sourceforge.net/\n\n";
32280 +
32281 +static int __init uml_version_setup(char *line, int *add)
32282 +{
32283 +       printf("%s\n", system_utsname.release);
32284 +       exit(0);
32285 +}
32286 +
32287 +__uml_setup("--version", uml_version_setup,
32288 +"--version\n"
32289 +"    Prints the version number of the kernel.\n\n"
32290 +);
32291 +
32292 +static int __init uml_root_setup(char *line, int *add)
32293 +{
32294 +       have_root = 1;
32295 +       return 0;
32296 +}
32297 +
32298 +__uml_setup("root=", uml_root_setup,
32299 +"root=<file containing the root fs>\n"
32300 +"    This is actually used by the generic kernel in exactly the same\n"
32301 +"    way as in any other kernel. If you configure a number of block\n"
32302 +"    devices and want to boot off something other than ubd0, you \n"
32303 +"    would use something like:\n"
32304 +"        root=/dev/ubd5\n\n"
32305 +);
32306 +
32307 +#ifdef CONFIG_SMP
32308 +static int __init uml_ncpus_setup(char *line, int *add)
32309 +{
32310 +       if (!sscanf(line, "%d", &ncpus)) {
32311 +               printf("Couldn't parse [%s]\n", line);
32312 +               return -1;
32313 +       }
32314 +
32315 +       return 0;
32316 +}
32317 +
32318 +__uml_setup("ncpus=", uml_ncpus_setup,
32319 +"ncpus=<# of desired CPUs>\n"
32320 +"    This tells an SMP kernel how many virtual processors to start.\n\n" 
32321 +);
32322 +#endif
32323 +
32324 +int force_tt = 0;
32325 +
32326 +#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
32327 +#define DEFAULT_TT 0
32328 +
32329 +static int __init mode_tt_setup(char *line, int *add)
32330 +{
32331 +       force_tt = 1;
32332 +       return(0);
32333 +}
32334 +
32335 +#else
32336 +#ifdef CONFIG_MODE_SKAS
32337 +
32338 +#define DEFAULT_TT 0
32339 +
32340 +static int __init mode_tt_setup(char *line, int *add)
32341 +{
32342 +       printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
32343 +       return(0);
32344 +}
32345 +
32346 +#else
32347 +#ifdef CONFIG_MODE_TT
32348 +
32349 +#define DEFAULT_TT 1
32350 +
32351 +static int __init mode_tt_setup(char *line, int *add)
32352 +{
32353 +       printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
32354 +       return(0);
32355 +}
32356 +
32357 +#else
32358 +
32359 +#error Either CONFIG_MODE_TT or CONFIG_MODE_SKAS must be enabled
32360 +
32361 +#endif
32362 +#endif
32363 +#endif
32364 +
32365 +__uml_setup("mode=tt", mode_tt_setup,
32366 +"mode=tt\n"
32367 +"    When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n"
32368 +"    forces UML to run in tt (tracing thread) mode.  It is not the default\n"
32369 +"    because it's slower and less secure than skas mode.\n\n"
32370 +);
32371 +
32372 +int mode_tt = DEFAULT_TT;
32373 +
32374 +static int __init Usage(char *line, int *add)
32375 +{
32376 +       const char **p;
32377 +
32378 +       printf(usage_string, system_utsname.release);
32379 +       p = &__uml_help_start;
32380 +       while (p < &__uml_help_end) {
32381 +               printf("%s", *p);
32382 +               p++;
32383 +       }
32384 +       exit(0);
32385 +}
32386 +
32387 +__uml_setup("--help", Usage,
32388 +"--help\n"
32389 +"    Prints this message.\n\n"
32390 +);
32391 +
32392 +static int __init uml_checksetup(char *line, int *add)
32393 +{
32394 +       struct uml_param *p;
32395 +
32396 +       p = &__uml_setup_start;
32397 +       while(p < &__uml_setup_end) {
32398 +               int n;
32399 +
32400 +               n = strlen(p->str);
32401 +               if(!strncmp(line, p->str, n)){
32402 +                       if (p->setup_func(line + n, add)) return 1;
32403 +               }
32404 +               p++;
32405 +       }
32406 +       return 0;
32407 +}
32408 +
32409 +static void __init uml_postsetup(void)
32410 +{
32411 +       initcall_t *p;
32412 +
32413 +       p = &__uml_postsetup_start;
32414 +       while(p < &__uml_postsetup_end){
32415 +               (*p)();
32416 +               p++;
32417 +       }
32418 +       return;
32419 +}
32420 +
32421 +/* Set during early boot */
32422 +unsigned long brk_start;
32423 +unsigned long end_iomem;
32424 +
32425 +#define MIN_VMALLOC (32 * 1024 * 1024)
32426 +
32427 +int linux_main(int argc, char **argv)
32428 +{
32429 +       unsigned long avail;
32430 +       unsigned long virtmem_size, max_physmem;
32431 +       unsigned int i, add;
32432 +
32433 +       for (i = 1; i < argc; i++){
32434 +               if((i == 1) && (argv[i][0] == ' ')) continue;
32435 +               add = 1;
32436 +               uml_checksetup(argv[i], &add);
32437 +               if(add) add_arg(saved_command_line, argv[i]);
32438 +       }
32439 +       if(have_root == 0) add_arg(saved_command_line, DEFAULT_COMMAND_LINE);
32440 +
32441 +       mode_tt = force_tt ? 1 : !can_do_skas();
32442 +       uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
32443 +                                    &host_task_size, &task_size);
32444 +
32445 +       brk_start = (unsigned long) sbrk(0);
32446 +       CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
32447 +
32448 +       uml_physmem = uml_start;
32449 +
32450 +       /* Reserve up to 4M after the current brk */
32451 +       uml_reserved = ROUND_4M(brk_start) + (1 << 22);
32452 +
32453 +       setup_machinename(system_utsname.machine);
32454 +
32455 +#ifdef CONFIG_MODE_TT
32456 +       argv1_begin = argv[1];
32457 +       argv1_end = &argv[1][strlen(argv[1])];
32458 +#endif
32459 +  
32460 +       highmem = 0;
32461 +       iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
32462 +       max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
32463 +
32464 +       /* Zones have to begin on a 1 << MAX_ORDER page boundary,
32465 +        * so this makes sure that's true for highmem
32466 +        */
32467 +       max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1);
32468 +       if(physmem_size + iomem_size > max_physmem){
32469 +               highmem = physmem_size + iomem_size - max_physmem;
32470 +               physmem_size -= highmem;
32471 +#ifndef CONFIG_HIGHMEM
32472 +               highmem = 0;
32473 +               printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
32474 +                      "to %ld bytes\n", physmem_size);
32475 +#endif
32476 +       }
32477 +
32478 +       high_physmem = uml_physmem + physmem_size;
32479 +       end_iomem = high_physmem + iomem_size;
32480 +       high_memory = (void *) end_iomem;
32481 +
32482 +       start_vm = VMALLOC_START;
32483 +
32484 +       setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
32485 +       if(init_maps(physmem_size, iomem_size, highmem)){
32486 +               printf("Failed to allocate mem_map for %ld bytes of physical "
32487 +                      "memory and %ld bytes of highmem\n", physmem_size,
32488 +                      highmem);
32489 +               exit(1);
32490 +       }
32491 +
32492 +       virtmem_size = physmem_size;
32493 +       avail = get_kmem_end() - start_vm;
32494 +       if(physmem_size > avail) virtmem_size = avail;
32495 +       end_vm = start_vm + virtmem_size;
32496 +
32497 +       if(virtmem_size < physmem_size)
32498 +               printf("Kernel virtual memory size shrunk to %ld bytes\n",
32499 +                      virtmem_size);
32500 +
32501 +       uml_postsetup();
32502 +
32503 +       init_task.thread.kernel_stack = (unsigned long) &init_task + 
32504 +               2 * PAGE_SIZE;
32505 +
32506 +       task_protections((unsigned long) &init_task);
32507 +       os_flush_stdout();
32508 +
32509 +       return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
32510 +}
32511 +
32512 +static int panic_exit(struct notifier_block *self, unsigned long unused1,
32513 +                     void *unused2)
32514 +{
32515 +#ifdef CONFIG_SYSRQ
32516 +       handle_sysrq('p', &current->thread.regs, NULL, NULL);
32517 +#endif
32518 +       machine_halt();
32519 +       return(0);
32520 +}
32521 +
32522 +static struct notifier_block panic_exit_notifier = {
32523 +       .notifier_call          = panic_exit,
32524 +       .next                   = NULL,
32525 +       .priority               = 0
32526 +};
32527 +
32528 +void __init setup_arch(char **cmdline_p)
32529 +{
32530 +       notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
32531 +       paging_init();
32532 +       strcpy(command_line, saved_command_line);
32533 +       *cmdline_p = command_line;
32534 +       setup_hostinfo();
32535 +}
32536 +
32537 +void __init check_bugs(void)
32538 +{
32539 +       arch_check_bugs();
32540 +       check_ptrace();
32541 +       check_sigio();
32542 +}
32543 +
32544 +/*
32545 + * Overrides for Emacs so that we follow Linus's tabbing style.
32546 + * Emacs will notice this stuff at the end of the file and automatically
32547 + * adjust the settings for this buffer only.  This must remain at the end
32548 + * of the file.
32549 + * ---------------------------------------------------------------------------
32550 + * Local variables:
32551 + * c-file-style: "linux"
32552 + * End:
32553 + */
32554 diff -Naur -X ../exclude-files orig/arch/um/kernel/umid.c um/arch/um/kernel/umid.c
32555 --- orig/arch/um/kernel/umid.c  1969-12-31 19:00:00.000000000 -0500
32556 +++ um/arch/um/kernel/umid.c    2004-01-26 10:13:01.000000000 -0500
32557 @@ -0,0 +1,327 @@
32558 +/* 
32559 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32560 + * Licensed under the GPL
32561 + */
32562 +
32563 +#include <stdio.h>
32564 +#include <unistd.h>
32565 +#include <errno.h>
32566 +#include <string.h>
32567 +#include <stdlib.h>
32568 +#include <dirent.h>
32569 +#include <signal.h>
32570 +#include <sys/stat.h>
32571 +#include <sys/param.h>
32572 +#include "user.h"
32573 +#include "umid.h"
32574 +#include "init.h"
32575 +#include "os.h"
32576 +#include "user_util.h"
32577 +#include "choose-mode.h"
32578 +
32579 +#define UMID_LEN 64
32580 +#define UML_DIR "~/.uml/"
32581 +
32582 +/* Changed by set_umid and make_umid, which are run early in boot */
32583 +static char umid[UMID_LEN] = { 0 };
32584 +
32585 +/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
32586 +static char *uml_dir = UML_DIR;
32587 +
32588 +/* Changed by set_umid */
32589 +static int umid_is_random = 1;
32590 +static int umid_inited = 0;
32591 +
32592 +static int make_umid(int (*printer)(const char *fmt, ...));
32593 +
32594 +static int __init set_umid(char *name, int is_random, 
32595 +                          int (*printer)(const char *fmt, ...))
32596 +{
32597 +       if(umid_inited){
32598 +               (*printer)("Unique machine name can't be set twice\n");
32599 +               return(-1);
32600 +       }
32601 +
32602 +       if(strlen(name) > UMID_LEN - 1)
32603 +               (*printer)("Unique machine name is being truncated to %s "
32604 +                          "characters\n", UMID_LEN);
32605 +       strncpy(umid, name, UMID_LEN - 1);
32606 +       umid[UMID_LEN - 1] = '\0';
32607 +
32608 +       umid_is_random = is_random;
32609 +       umid_inited = 1;
32610 +       return 0;
32611 +}
32612 +
32613 +static int __init set_umid_arg(char *name, int *add)
32614 +{
32615 +       return(set_umid(name, 0, printf));
32616 +}
32617 +
32618 +__uml_setup("umid=", set_umid_arg,
32619 +"umid=<name>\n"
32620 +"    This is used to assign a unique identity to this UML machine and\n"
32621 +"    is used for naming the pid file and management console socket.\n\n"
32622 +);
32623 +
32624 +int __init umid_file_name(char *name, char *buf, int len)
32625 +{
32626 +       int n;
32627 +
32628 +       if(!umid_inited && make_umid(printk)) return(-1);
32629 +
32630 +       n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
32631 +       if(n > len){
32632 +               printk("umid_file_name : buffer too short\n");
32633 +               return(-1);
32634 +       }
32635 +
32636 +       sprintf(buf, "%s%s/%s", uml_dir, umid, name);
32637 +       return(0);
32638 +}
32639 +
32640 +extern int tracing_pid;
32641 +
32642 +static int __init create_pid_file(void)
32643 +{
32644 +       char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
32645 +       char pid[sizeof("nnnnn\0")];
32646 +       int fd, n;
32647 +
32648 +       if(umid_file_name("pid", file, sizeof(file))) return 0;
32649 +
32650 +       fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
32651 +                         0644);
32652 +       if(fd < 0){
32653 +               printf("Open of machine pid file \"%s\" failed - "
32654 +                      "err = %d\n", file, -fd);
32655 +               return 0;
32656 +       }
32657 +
32658 +       sprintf(pid, "%d\n", os_getpid());
32659 +       n = os_write_file(fd, pid, strlen(pid));
32660 +       if(n != strlen(pid))
32661 +               printf("Write of pid file failed - err = %d\n", -n);
32662 +       os_close_file(fd);
32663 +       return 0;
32664 +}
32665 +
32666 +static int actually_do_remove(char *dir)
32667 +{
32668 +       DIR *directory;
32669 +       struct dirent *ent;
32670 +       int len;
32671 +       char file[256];
32672 +
32673 +       directory = opendir(dir);
32674 +       if(directory == NULL){
32675 +               printk("actually_do_remove : couldn't open directory '%s', "
32676 +                      "errno = %d\n", dir, errno);
32677 +               return(1);
32678 +       }
32679 +       while((ent = readdir(directory)) != NULL){
32680 +               if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
32681 +                       continue;
32682 +               len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
32683 +               if(len > sizeof(file)){
32684 +                       printk("Not deleting '%s' from '%s' - name too long\n",
32685 +                              ent->d_name, dir);
32686 +                       continue;
32687 +               }
32688 +               sprintf(file, "%s/%s", dir, ent->d_name);
32689 +               if(unlink(file) < 0){
32690 +                       printk("actually_do_remove : couldn't remove '%s' "
32691 +                              "from '%s', errno = %d\n", ent->d_name, dir, 
32692 +                              errno);
32693 +                       return(1);
32694 +               }
32695 +       }
32696 +       if(rmdir(dir) < 0){
32697 +               printk("actually_do_remove : couldn't rmdir '%s', "
32698 +                      "errno = %d\n", dir, errno);
32699 +               return(1);
32700 +       }
32701 +       return(0);
32702 +}
32703 +
32704 +void remove_umid_dir(void)
32705 +{
32706 +       char dir[strlen(uml_dir) + UMID_LEN + 1];
32707 +       if(!umid_inited) return;
32708 +
32709 +       sprintf(dir, "%s%s", uml_dir, umid);
32710 +       actually_do_remove(dir);
32711 +}
32712 +
32713 +char *get_umid(int only_if_set)
32714 +{
32715 +       if(only_if_set && umid_is_random) return(NULL);
32716 +       return(umid);
32717 +}
32718 +
32719 +int not_dead_yet(char *dir)
32720 +{
32721 +       char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
32722 +       char pid[sizeof("nnnnn\0")], *end;
32723 +       int dead, fd, p, n;
32724 +
32725 +       sprintf(file, "%s/pid", dir);
32726 +       dead = 0;
32727 +       fd = os_open_file(file, of_read(OPENFLAGS()), 0);
32728 +       if(fd < 0){
32729 +               if(fd != -ENOENT){
32730 +                       printk("not_dead_yet : couldn't open pid file '%s', "
32731 +                              "err = %d\n", file, -fd);
32732 +                       return(1);
32733 +               }
32734 +               dead = 1;
32735 +       }
32736 +       if(fd > 0){
32737 +               n = os_read_file(fd, pid, sizeof(pid));
32738 +               if(n < 0){
32739 +                       printk("not_dead_yet : couldn't read pid file '%s', "
32740 +                              "err = %d\n", file, -n);
32741 +                       return(1);
32742 +               }
32743 +               p = strtoul(pid, &end, 0);
32744 +               if(end == pid){
32745 +                       printk("not_dead_yet : couldn't parse pid file '%s', "
32746 +                              "errno = %d\n", file, errno);
32747 +                       dead = 1;
32748 +               }
32749 +               if(((kill(p, 0) < 0) && (errno == ESRCH)) ||
32750 +                  (p == CHOOSE_MODE(tracing_pid, os_getpid())))
32751 +                       dead = 1;
32752 +       }
32753 +       if(!dead) return(1);
32754 +       return(actually_do_remove(dir));
32755 +}
32756 +
32757 +static int __init set_uml_dir(char *name, int *add)
32758 +{
32759 +       if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
32760 +               uml_dir = malloc(strlen(name) + 1);
32761 +               if(uml_dir == NULL){
32762 +                       printf("Failed to malloc uml_dir - error = %d\n",
32763 +                              errno);
32764 +                       uml_dir = name;
32765 +                       /* Return 0 here because do_initcalls doesn't look at
32766 +                        * the return value.
32767 +                        */
32768 +                       return(0);
32769 +               }
32770 +               sprintf(uml_dir, "%s/", name);
32771 +       }
32772 +       else uml_dir = name;
32773 +       return(0);
32774 +}
32775 +
32776 +static int __init make_uml_dir(void)
32777 +{
32778 +       char dir[MAXPATHLEN + 1] = { '\0' };
32779 +       int len;
32780 +
32781 +       if(*uml_dir == '~'){
32782 +               char *home = getenv("HOME");
32783 +
32784 +               if(home == NULL){
32785 +                       printf("make_uml_dir : no value in environment for "
32786 +                              "$HOME\n");
32787 +                       exit(1);
32788 +               }
32789 +               strncpy(dir, home, sizeof(dir));
32790 +               uml_dir++;
32791 +       }
32792 +       len = strlen(dir);
32793 +       strncat(dir, uml_dir, sizeof(dir) - len);
32794 +       len = strlen(dir);
32795 +       if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){
32796 +               dir[len] = '/';
32797 +               dir[len + 1] = '\0';
32798 +       }
32799 +
32800 +       uml_dir = malloc(strlen(dir) + 1);
32801 +       if(uml_dir == NULL){
32802 +               printf("make_uml_dir : malloc failed, errno = %d\n", errno);
32803 +               exit(1);
32804 +       }
32805 +       strcpy(uml_dir, dir);
32806 +       
32807 +       if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
32808 +               printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
32809 +               return(-1);
32810 +       }
32811 +       return 0;
32812 +}
32813 +
32814 +static int __init make_umid(int (*printer)(const char *fmt, ...))
32815 +{
32816 +       int fd, err;
32817 +       char tmp[strlen(uml_dir) + UMID_LEN + 1];
32818 +
32819 +       strncpy(tmp, uml_dir, sizeof(tmp) - 1);
32820 +       tmp[sizeof(tmp) - 1] = '\0';
32821 +
32822 +       if(!umid_inited){
32823 +               strcat(tmp, "XXXXXX");
32824 +               fd = mkstemp(tmp);
32825 +               if(fd < 0){
32826 +                       (*printer)("make_umid - mkstemp failed, errno = %d\n",
32827 +                                  errno);
32828 +                       return(1);
32829 +               }
32830 +
32831 +               os_close_file(fd);
32832 +               /* There's a nice tiny little race between this unlink and
32833 +                * the mkdir below.  It'd be nice if there were a mkstemp
32834 +                * for directories.
32835 +                */
32836 +               unlink(tmp);
32837 +               set_umid(&tmp[strlen(uml_dir)], 1, printer);
32838 +       }
32839 +       
32840 +       sprintf(tmp, "%s%s", uml_dir, umid);
32841 +
32842 +       err = mkdir(tmp, 0777);
32843 +       if(err < 0){
32844 +               if(errno == EEXIST){
32845 +                       if(not_dead_yet(tmp)){
32846 +                               (*printer)("umid '%s' is in use\n", umid);
32847 +                               return(-1);
32848 +                       }
32849 +                       err = mkdir(tmp, 0777);
32850 +               }
32851 +       }
32852 +       if(err < 0){
32853 +               (*printer)("Failed to create %s - errno = %d\n", umid, errno);
32854 +               return(-1);
32855 +       }
32856 +
32857 +       return(0);
32858 +}
32859 +
32860 +__uml_setup("uml_dir=", set_uml_dir,
32861 +"uml_dir=<directory>\n"
32862 +"    The location to place the pid and umid files.\n\n"
32863 +);
32864 +
32865 +__uml_postsetup(make_uml_dir);
32866 +
32867 +static int __init make_umid_setup(void)
32868 +{
32869 +       return(make_umid(printf));
32870 +}
32871 +
32872 +__uml_postsetup(make_umid_setup);
32873 +__uml_postsetup(create_pid_file);
32874 +
32875 +/*
32876 + * Overrides for Emacs so that we follow Linus's tabbing style.
32877 + * Emacs will notice this stuff at the end of the file and automatically
32878 + * adjust the settings for this buffer only.  This must remain at the end
32879 + * of the file.
32880 + * ---------------------------------------------------------------------------
32881 + * Local variables:
32882 + * c-file-style: "linux"
32883 + * End:
32884 + */
32885 diff -Naur -X ../exclude-files orig/arch/um/kernel/user_syms.c um/arch/um/kernel/user_syms.c
32886 --- orig/arch/um/kernel/user_syms.c     1969-12-31 19:00:00.000000000 -0500
32887 +++ um/arch/um/kernel/user_syms.c       2004-01-23 00:44:09.000000000 -0500
32888 @@ -0,0 +1,119 @@
32889 +#include <stdio.h>
32890 +#include <unistd.h>
32891 +#include <dirent.h>
32892 +#include <fcntl.h>
32893 +#include <errno.h>
32894 +#include <utime.h>
32895 +#include <string.h>
32896 +#include <sys/stat.h>
32897 +#include <sys/vfs.h>
32898 +#include <sys/ioctl.h>
32899 +#include "user_util.h"
32900 +#include "mem_user.h"
32901 +
32902 +/* XXX All the __CONFIG_* stuff is broken because this file can't include
32903 + * config.h
32904 + */
32905 +
32906 +/* Had to steal this from linux/module.h because that file can't be included
32907 + * since this includes various user-level headers.
32908 + */
32909 +
32910 +struct module_symbol
32911 +{
32912 +       unsigned long value;
32913 +       const char *name;
32914 +};
32915 +
32916 +/* Indirect stringification.  */
32917 +
32918 +#define __MODULE_STRING_1(x)   #x
32919 +#define __MODULE_STRING(x)     __MODULE_STRING_1(x)
32920 +
32921 +#if !defined(__AUTOCONF_INCLUDED__)
32922 +
32923 +#define __EXPORT_SYMBOL(sym,str)   error config_must_be_included_before_module
32924 +#define EXPORT_SYMBOL(var)        error config_must_be_included_before_module
32925 +#define EXPORT_SYMBOL_NOVERS(var)  error config_must_be_included_before_module
32926 +
32927 +#elif !defined(__CONFIG_MODULES__)
32928 +
32929 +#define __EXPORT_SYMBOL(sym,str)
32930 +#define EXPORT_SYMBOL(var)
32931 +#define EXPORT_SYMBOL_NOVERS(var)
32932 +
32933 +#else
32934 +
32935 +#define __EXPORT_SYMBOL(sym, str)                      \
32936 +const char __kstrtab_##sym[]                           \
32937 +__attribute__((section(".kstrtab"))) = str;            \
32938 +const struct module_symbol __ksymtab_##sym             \
32939 +__attribute__((section("__ksymtab"))) =                        \
32940 +{ (unsigned long)&sym, __kstrtab_##sym }
32941 +
32942 +#if defined(__MODVERSIONS__) || !defined(__CONFIG_MODVERSIONS__)
32943 +#define EXPORT_SYMBOL(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(var))
32944 +#else
32945 +#define EXPORT_SYMBOL(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var)))
32946 +#endif
32947 +
32948 +#define EXPORT_SYMBOL_NOVERS(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(var))
32949 +
32950 +#endif
32951 +
32952 +EXPORT_SYMBOL(__errno_location);
32953 +
32954 +EXPORT_SYMBOL(access);
32955 +EXPORT_SYMBOL(open);
32956 +EXPORT_SYMBOL(open64);
32957 +EXPORT_SYMBOL(close);
32958 +EXPORT_SYMBOL(read);
32959 +EXPORT_SYMBOL(write);
32960 +EXPORT_SYMBOL(dup2);
32961 +EXPORT_SYMBOL(__xstat);
32962 +EXPORT_SYMBOL(__lxstat);
32963 +EXPORT_SYMBOL(__lxstat64);
32964 +EXPORT_SYMBOL(lseek);
32965 +EXPORT_SYMBOL(lseek64);
32966 +EXPORT_SYMBOL(chown);
32967 +EXPORT_SYMBOL(truncate);
32968 +EXPORT_SYMBOL(utime);
32969 +EXPORT_SYMBOL(chmod);
32970 +EXPORT_SYMBOL(rename);
32971 +EXPORT_SYMBOL(__xmknod);
32972 +
32973 +EXPORT_SYMBOL(symlink);
32974 +EXPORT_SYMBOL(link);
32975 +EXPORT_SYMBOL(unlink);
32976 +EXPORT_SYMBOL(readlink);
32977 +
32978 +EXPORT_SYMBOL(mkdir);
32979 +EXPORT_SYMBOL(rmdir);
32980 +EXPORT_SYMBOL(opendir);
32981 +EXPORT_SYMBOL(readdir);
32982 +EXPORT_SYMBOL(closedir);
32983 +EXPORT_SYMBOL(seekdir);
32984 +EXPORT_SYMBOL(telldir);
32985 +
32986 +EXPORT_SYMBOL(ioctl);
32987 +
32988 +extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes,
32989 +                       __off64_t __offset);
32990 +extern ssize_t pwrite64 (int __fd, __const void *__buf, size_t __n,
32991 +                        __off64_t __offset);
32992 +EXPORT_SYMBOL(pread64);
32993 +EXPORT_SYMBOL(pwrite64);
32994 +
32995 +EXPORT_SYMBOL(statfs);
32996 +EXPORT_SYMBOL(statfs64);
32997 +
32998 +EXPORT_SYMBOL(memcpy);
32999 +EXPORT_SYMBOL(getuid);
33000 +
33001 +EXPORT_SYMBOL(memset);
33002 +EXPORT_SYMBOL(strstr);
33003 +EXPORT_SYMBOL(strpbrk);
33004 +EXPORT_SYMBOL(strlen);
33005 +EXPORT_SYMBOL(printf);
33006 +
33007 +EXPORT_SYMBOL(find_iomem);
33008 diff -Naur -X ../exclude-files orig/arch/um/kernel/user_util.c um/arch/um/kernel/user_util.c
33009 --- orig/arch/um/kernel/user_util.c     1969-12-31 19:00:00.000000000 -0500
33010 +++ um/arch/um/kernel/user_util.c       2003-10-21 03:26:07.000000000 -0400
33011 @@ -0,0 +1,164 @@
33012 +/* 
33013 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
33014 + * Licensed under the GPL
33015 + */
33016 +
33017 +#include <stdio.h>
33018 +#include <stdlib.h>
33019 +#include <unistd.h>
33020 +#include <limits.h>
33021 +#include <sys/mman.h> 
33022 +#include <sys/stat.h>
33023 +#include <sys/ptrace.h>
33024 +#include <sys/utsname.h>
33025 +#include <sys/param.h>
33026 +#include <sys/time.h>
33027 +#include "asm/types.h"
33028 +#include <ctype.h>
33029 +#include <signal.h>
33030 +#include <wait.h>
33031 +#include <errno.h>
33032 +#include <stdarg.h>
33033 +#include <sched.h>
33034 +#include <termios.h>
33035 +#include <string.h>
33036 +#include "user_util.h"
33037 +#include "kern_util.h"
33038 +#include "user.h"
33039 +#include "mem_user.h"
33040 +#include "init.h"
33041 +#include "helper.h"
33042 +#include "uml-config.h"
33043 +
33044 +#define COMMAND_LINE_SIZE _POSIX_ARG_MAX
33045 +
33046 +/* Changed in linux_main and setup_arch, which run before SMP is started */
33047 +char saved_command_line[COMMAND_LINE_SIZE] = { 0 };
33048 +char command_line[COMMAND_LINE_SIZE] = { 0 };
33049 +
33050 +void add_arg(char *cmd_line, char *arg)
33051 +{
33052 +       if (strlen(cmd_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
33053 +               printf("add_arg: Too much command line!\n");
33054 +               exit(1);
33055 +       }
33056 +       if(strlen(cmd_line) > 0) strcat(cmd_line, " ");
33057 +       strcat(cmd_line, arg);
33058 +}
33059 +
33060 +void stop(void)
33061 +{
33062 +       while(1) sleep(1000000);
33063 +}
33064 +
33065 +void stack_protections(unsigned long address)
33066 +{
33067 +       int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
33068 +
33069 +        if(mprotect((void *) address, page_size(), prot) < 0)
33070 +               panic("protecting stack failed, errno = %d", errno);
33071 +}
33072 +
33073 +void task_protections(unsigned long address)
33074 +{
33075 +       unsigned long guard = address + page_size();
33076 +       unsigned long stack = guard + page_size();
33077 +       int prot = 0, pages;
33078 +#ifdef notdef
33079 +       if(mprotect((void *) guard, page_size(), prot) < 0)
33080 +               panic("protecting guard page failed, errno = %d", errno);
33081 +#endif
33082 +       pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
33083 +       prot = PROT_READ | PROT_WRITE | PROT_EXEC;
33084 +       if(mprotect((void *) stack, pages * page_size(), prot) < 0)
33085 +               panic("protecting stack failed, errno = %d", errno);
33086 +}
33087 +
33088 +int wait_for_stop(int pid, int sig, int cont_type, void *relay)
33089 +{
33090 +       sigset_t *relay_signals = relay;
33091 +       int status, ret;
33092 +
33093 +       while(1){
33094 +               ret = waitpid(pid, &status, WUNTRACED);
33095 +               if((ret < 0) ||
33096 +                  !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
33097 +                       if(ret < 0){
33098 +                               if(errno == EINTR) continue;
33099 +                               printk("wait failed, errno = %d\n",
33100 +                                      errno);
33101 +                       }
33102 +                       else if(WIFEXITED(status)) 
33103 +                               printk("process exited with status %d\n", 
33104 +                                      WEXITSTATUS(status));
33105 +                       else if(WIFSIGNALED(status))
33106 +                               printk("process exited with signal %d\n", 
33107 +                                      WTERMSIG(status));
33108 +                       else if((WSTOPSIG(status) == SIGVTALRM) ||
33109 +                               (WSTOPSIG(status) == SIGALRM) ||
33110 +                               (WSTOPSIG(status) == SIGIO) ||
33111 +                               (WSTOPSIG(status) == SIGPROF) ||
33112 +                               (WSTOPSIG(status) == SIGCHLD) ||
33113 +                               (WSTOPSIG(status) == SIGWINCH) ||
33114 +                               (WSTOPSIG(status) == SIGINT)){
33115 +                               ptrace(cont_type, pid, 0, WSTOPSIG(status));
33116 +                               continue;
33117 +                       }
33118 +                       else if((relay_signals != NULL) &&
33119 +                               sigismember(relay_signals, WSTOPSIG(status))){
33120 +                               ptrace(cont_type, pid, 0, WSTOPSIG(status));
33121 +                               continue;
33122 +                       }
33123 +                       else printk("process stopped with signal %d\n", 
33124 +                                   WSTOPSIG(status));
33125 +                       panic("wait_for_stop failed to wait for %d to stop "
33126 +                             "with %d\n", pid, sig);
33127 +               }
33128 +               return(status);
33129 +       }
33130 +}
33131 +
33132 +int raw(int fd, int complain)
33133 +{
33134 +       struct termios tt;
33135 +       int err;
33136 +
33137 +       tcgetattr(fd, &tt);
33138 +       cfmakeraw(&tt);
33139 +       err = tcsetattr(fd, TCSANOW, &tt);
33140 +       if((err < 0) && complain){
33141 +               printk("tcsetattr failed, errno = %d\n", errno);
33142 +               return(-errno);
33143 +       }
33144 +       return(0);
33145 +}
33146 +
33147 +void setup_machinename(char *machine_out)
33148 +{
33149 +       struct utsname host;
33150 +
33151 +       uname(&host);
33152 +       strcpy(machine_out, host.machine);
33153 +}
33154 +
33155 +char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1];
33156 +
33157 +void setup_hostinfo(void)
33158 +{
33159 +       struct utsname host;
33160 +
33161 +       uname(&host);
33162 +       sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename,
33163 +               host.release, host.version, host.machine);
33164 +}
33165 +
33166 +/*
33167 + * Overrides for Emacs so that we follow Linus's tabbing style.
33168 + * Emacs will notice this stuff at the end of the file and automatically
33169 + * adjust the settings for this buffer only.  This must remain at the end
33170 + * of the file.
33171 + * ---------------------------------------------------------------------------
33172 + * Local variables:
33173 + * c-file-style: "linux"
33174 + * End:
33175 + */
33176 diff -Naur -X ../exclude-files orig/arch/um/link.ld.in um/arch/um/link.ld.in
33177 --- orig/arch/um/link.ld.in     1969-12-31 19:00:00.000000000 -0500
33178 +++ um/arch/um/link.ld.in       2003-10-21 03:26:07.000000000 -0400
33179 @@ -0,0 +1,94 @@
33180 +OUTPUT_FORMAT("ELF_FORMAT")
33181 +OUTPUT_ARCH(ELF_ARCH)
33182 +ENTRY(_start)
33183 +
33184 +SECTIONS
33185 +{
33186 +  . = START() + SIZEOF_HEADERS;
33187 +
33188 +  __binary_start = .;
33189 +ifdef(`MODE_TT', `
33190 +  .thread_private : {
33191 +    __start_thread_private = .;
33192 +    errno = .;
33193 +    . += 4;
33194 +    arch/um/kernel/tt/unmap_fin.o (.data)
33195 +    __end_thread_private = .;
33196 +  }
33197 +  . = ALIGN(4096);
33198 +  .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
33199 +')
33200 +  . = ALIGN(4096);             /* Init code and data */
33201 +  _stext = .;
33202 +  __init_begin = .;
33203 +  .text.init : { *(.text.init) }
33204 +  . = ALIGN(4096);
33205 +  .text      :
33206 +  {
33207 +    *(.text)
33208 +    /* .gnu.warning sections are handled specially by elf32.em.  */
33209 +    *(.gnu.warning)
33210 +    *(.gnu.linkonce.t*)
33211 +  }
33212 +  .fini      : { *(.fini)    } =0x9090
33213 +  .rodata    : { *(.rodata) *(.gnu.linkonce.r*) }
33214 +  .rodata1   : { *(.rodata1) }
33215 +  _etext = .;
33216 +  PROVIDE (etext = .);
33217 +
33218 +  . = ALIGN(4096);
33219 +  PROVIDE (_sdata = .);
33220 +
33221 +include(`arch/um/common.ld.in')
33222 +
33223 +  .data    :
33224 +  {
33225 +    . = ALIGN(KERNEL_STACK_SIZE);              /* init_task */
33226 +    *(.data.init_task)
33227 +    *(.data)
33228 +    *(.gnu.linkonce.d*)
33229 +    CONSTRUCTORS
33230 +  }
33231 +  .data1   : { *(.data1) }
33232 +  .ctors         :
33233 +  {
33234 +    *(.ctors)
33235 +  }
33236 +  .dtors         :
33237 +  {
33238 +    *(.dtors)
33239 +  }
33240 +
33241 +  .got           : { *(.got.plt) *(.got) }
33242 +  .dynamic       : { *(.dynamic) }
33243 +  /* We want the small data sections together, so single-instruction offsets
33244 +     can access them all, and initialized data all before uninitialized, so
33245 +     we can shorten the on-disk segment size.  */
33246 +  .sdata     : { *(.sdata) }
33247 +  _edata  =  .;
33248 +  PROVIDE (edata = .);
33249 +  . = ALIGN(0x1000);
33250 +  .sbss      : 
33251 +  {
33252 +   __bss_start = .;
33253 +   PROVIDE(_bss_start = .);
33254 +   *(.sbss) 
33255 +   *(.scommon) 
33256 +  }
33257 +  .bss       :
33258 +  {
33259 +   *(.dynbss)
33260 +   *(.bss)
33261 +   *(COMMON)
33262 +  }
33263 +  _end = . ;
33264 +  PROVIDE (end = .);
33265 +  /* Stabs debugging sections.  */
33266 +  .stab 0 : { *(.stab) }
33267 +  .stabstr 0 : { *(.stabstr) }
33268 +  .stab.excl 0 : { *(.stab.excl) }
33269 +  .stab.exclstr 0 : { *(.stab.exclstr) }
33270 +  .stab.index 0 : { *(.stab.index) }
33271 +  .stab.indexstr 0 : { *(.stab.indexstr) }
33272 +  .comment 0 : { *(.comment) }
33273 +}
33274 diff -Naur -X ../exclude-files orig/arch/um/main.c um/arch/um/main.c
33275 --- orig/arch/um/main.c 1969-12-31 19:00:00.000000000 -0500
33276 +++ um/arch/um/main.c   2004-01-29 00:48:42.000000000 -0500
33277 @@ -0,0 +1,199 @@
33278 +/* 
33279 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
33280 + * Licensed under the GPL
33281 + */
33282 +
33283 +#include <unistd.h>
33284 +#include <stdio.h> 
33285 +#include <stdlib.h>
33286 +#include <string.h>
33287 +#include <signal.h>
33288 +#include <errno.h>
33289 +#include <sys/resource.h>
33290 +#include <sys/mman.h>
33291 +#include <sys/user.h>
33292 +#include <asm/page.h>
33293 +#include "user_util.h"
33294 +#include "kern_util.h"
33295 +#include "mem_user.h"
33296 +#include "signal_user.h"
33297 +#include "user.h"
33298 +#include "init.h"
33299 +#include "mode.h"
33300 +#include "choose-mode.h"
33301 +#include "uml-config.h"
33302 +
33303 +/* Set in set_stklim, which is called from main and __wrap_malloc.  
33304 + * __wrap_malloc only calls it if main hasn't started.
33305 + */
33306 +unsigned long stacksizelim;
33307 +
33308 +/* Set in main */
33309 +char *linux_prog;
33310 +
33311 +#define PGD_BOUND (4 * 1024 * 1024)
33312 +#define STACKSIZE (8 * 1024 * 1024)
33313 +#define THREAD_NAME_LEN (256)
33314 +
33315 +static void set_stklim(void)
33316 +{
33317 +       struct rlimit lim;
33318 +
33319 +       if(getrlimit(RLIMIT_STACK, &lim) < 0){
33320 +               perror("getrlimit");
33321 +               exit(1);
33322 +       }
33323 +       if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){
33324 +               lim.rlim_cur = STACKSIZE;
33325 +               if(setrlimit(RLIMIT_STACK, &lim) < 0){
33326 +                       perror("setrlimit");
33327 +                       exit(1);
33328 +               }
33329 +       }
33330 +       stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1);
33331 +}
33332 +
33333 +static __init void do_uml_initcalls(void)
33334 +{
33335 +       initcall_t *call;
33336 +
33337 +       call = &__uml_initcall_start;
33338 +       while (call < &__uml_initcall_end){;
33339 +               (*call)();
33340 +               call++;
33341 +       }
33342 +}
33343 +
33344 +static void last_ditch_exit(int sig)
33345 +{
33346 +       CHOOSE_MODE(kmalloc_ok = 0, (void) 0);
33347 +       signal(SIGINT, SIG_DFL);
33348 +       signal(SIGTERM, SIG_DFL);
33349 +       signal(SIGHUP, SIG_DFL);
33350 +       uml_cleanup();
33351 +       exit(1);
33352 +}
33353 +
33354 +extern int uml_exitcode;
33355 +
33356 +int main(int argc, char **argv, char **envp)
33357 +{
33358 +       char **new_argv;
33359 +       sigset_t mask;
33360 +       int ret, i;
33361 +
33362 +       /* Enable all signals except SIGIO - in some environments, we can 
33363 +        * enter with some signals blocked
33364 +        */
33365 +
33366 +       sigemptyset(&mask);
33367 +       sigaddset(&mask, SIGIO);
33368 +       if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){
33369 +               perror("sigprocmask");
33370 +               exit(1);
33371 +       }
33372 +
33373 +#ifdef UML_CONFIG_MODE_TT
33374 +       /* Allocate memory for thread command lines */
33375 +       if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
33376 +
33377 +               char padding[THREAD_NAME_LEN] = { 
33378 +                       [ 0 ...  THREAD_NAME_LEN - 2] = ' ', '\0' 
33379 +               };
33380 +
33381 +               new_argv = malloc((argc + 2) * sizeof(char*));
33382 +               if(!new_argv) {
33383 +                       perror("Allocating extended argv");
33384 +                       exit(1);
33385 +               }       
33386 +               
33387 +               new_argv[0] = argv[0];
33388 +               new_argv[1] = padding;
33389 +               
33390 +               for(i = 2; i <= argc; i++)
33391 +                       new_argv[i] = argv[i - 1];
33392 +               new_argv[argc + 1] = NULL;
33393 +               
33394 +               execvp(new_argv[0], new_argv);
33395 +               perror("execing with extended args");
33396 +               exit(1);
33397 +       }       
33398 +#endif
33399 +
33400 +       linux_prog = argv[0];
33401 +
33402 +       set_stklim();
33403 +
33404 +       new_argv = malloc((argc + 1) * sizeof(char *));
33405 +       if(new_argv == NULL){
33406 +               perror("Mallocing argv");
33407 +               exit(1);
33408 +       }
33409 +       for(i=0;i<argc;i++){
33410 +               new_argv[i] = strdup(argv[i]);
33411 +               if(new_argv[i] == NULL){
33412 +                       perror("Mallocing an arg");
33413 +                       exit(1);
33414 +               }
33415 +       }
33416 +       new_argv[argc] = NULL;
33417 +
33418 +       set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
33419 +       set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
33420 +       set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
33421 +
33422 +       do_uml_initcalls();
33423 +       ret = linux_main(argc, argv);
33424 +       
33425 +       /* Reboot */
33426 +       if(ret){
33427 +               printf("\n");
33428 +
33429 +               execvp(new_argv[0], new_argv);
33430 +               perror("Failed to exec kernel");
33431 +               ret = 1;
33432 +       }
33433 +       printf("\n");
33434 +       return(uml_exitcode);
33435 +}
33436 +
33437 +#define CAN_KMALLOC() \
33438 +       (kmalloc_ok && CHOOSE_MODE((getpid() != tracing_pid), 1))
33439 +
33440 +extern void *__real_malloc(int);
33441 +
33442 +void *__wrap_malloc(int size)
33443 +{
33444 +       if(CAN_KMALLOC())
33445 +               return(um_kmalloc(size));
33446 +       else
33447 +               return(__real_malloc(size));
33448 +}
33449 +
33450 +void *__wrap_calloc(int n, int size)
33451 +{
33452 +       void *ptr = __wrap_malloc(n * size);
33453 +
33454 +       if(ptr == NULL) return(NULL);
33455 +       memset(ptr, 0, n * size);
33456 +       return(ptr);
33457 +}
33458 +
33459 +extern void __real_free(void *);
33460 +
33461 +void __wrap_free(void *ptr)
33462 +{
33463 +       if(CAN_KMALLOC()) kfree(ptr);
33464 +       else __real_free(ptr);
33465 +}
33466 +
33467 +/*
33468 + * Overrides for Emacs so that we follow Linus's tabbing style.
33469 + * Emacs will notice this stuff at the end of the file and automatically
33470 + * adjust the settings for this buffer only.  This must remain at the end
33471 + * of the file.
33472 + * ---------------------------------------------------------------------------
33473 + * Local variables:
33474 + * c-file-style: "linux"
33475 + * End:
33476 + */
33477 diff -Naur -X ../exclude-files orig/arch/um/Makefile um/arch/um/Makefile
33478 --- orig/arch/um/Makefile       1969-12-31 19:00:00.000000000 -0500
33479 +++ um/arch/um/Makefile 2004-02-14 06:26:41.000000000 -0500
33480 @@ -0,0 +1,174 @@
33481 +# 
33482 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33483 +# Licensed under the GPL
33484 +#
33485 +
33486 +OS := $(shell uname -s)
33487 +
33488 +ARCH_DIR = arch/um
33489 +
33490 +core-y := kernel sys-$(SUBARCH) os-$(OS)
33491 +drivers-y := fs drivers
33492 +subdir-y := $(core-y) $(drivers-y)
33493 +SUBDIRS += $(foreach dir,$(subdir-y),$(ARCH_DIR)/$(dir))
33494 +
33495 +CORE_FILES += $(foreach dir,$(core-y),$(ARCH_DIR)/$(dir)/built-in.o)
33496 +DRIVERS += $(foreach dir,$(drivers-y),$(ARCH_DIR)/$(dir)/built-in.o)
33497 +
33498 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
33499 +include $(ARCH_DIR)/Makefile-os-$(OS)
33500 +
33501 +MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
33502 +MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
33503 +
33504 +ifneq ($(MAKEFILE-y),)
33505 +  include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
33506 +endif
33507 +
33508 +EXTRAVERSION := $(EXTRAVERSION)-1um
33509 +
33510 +include/linux/version.h: arch/$(ARCH)/Makefile
33511 +
33512 +# Recalculate MODLIB to reflect the EXTRAVERSION changes (via KERNELRELEASE)
33513 +# The way the toplevel Makefile is written EXTRAVERSION is not supposed
33514 +# to be changed outside the toplevel Makefile, but recalculating MODLIB is
33515 +# a sufficient workaround until we no longer need architecture dependent
33516 +# EXTRAVERSION...
33517 +MODLIB := $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
33518 +
33519 +ifeq ($(CONFIG_DEBUGSYM),y)
33520 +CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS))
33521 +endif
33522 +
33523 +CFLAGS-$(CONFIG_DEBUGSYM) += -g
33524 +
33525 +ARCH_INCLUDE = -I$(TOPDIR)/$(ARCH_DIR)/include
33526 +
33527 +# -Derrno=kernel_errno - This turns all kernel references to errno into
33528 +# kernel_errno to separate them from the libc errno.  This allows -fno-common
33529 +# in CFLAGS.  Otherwise, it would cause ld to complain about the two different
33530 +# errnos.
33531 +
33532 +CFLAGS += $(ARCH_CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
33533 +       -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
33534 +       $(MODE_INCLUDE)
33535 +
33536 +LINKFLAGS += -r
33537 +
33538 +LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
33539 +
33540 +# These are needed for clean and mrproper, since in that case .config is not
33541 +# included; the values here are meaningless
33542 +
33543 +CONFIG_NEST_LEVEL ?= 0
33544 +CONFIG_KERNEL_HALF_GIGS ?=  0
33545 +
33546 +SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
33547 +
33548 +# These aren't in Makefile-tt because they are needed in the !CONFIG_MODE_TT +
33549 +# CONFIG_MODE_SKAS + CONFIG_STATIC_LINK case.
33550 +
33551 +LINK_TT = -static
33552 +LD_SCRIPT_TT := link.ld
33553 +
33554 +ifeq ($(CONFIG_STATIC_LINK),y)
33555 +  LINK-y += $(LINK_TT)
33556 +  LD_SCRIPT-y := $(LD_SCRIPT_TT)
33557 +else
33558 +ifeq ($(CONFIG_MODE_TT),y)
33559 +  LINK-y += $(LINK_TT)
33560 +  LD_SCRIPT-y := $(LD_SCRIPT_TT)
33561 +else
33562 +ifeq ($(CONFIG_MODE_SKAS),y)
33563 +  LINK-y += $(LINK_SKAS)
33564 +  LD_SCRIPT-y := $(LD_SCRIPT_SKAS)
33565 +endif
33566 +endif
33567 +endif
33568 +
33569 +LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
33570 +M4_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT)
33571 +
33572 +$(LD_SCRIPT-y): $(LD_SCRIPT-y).in
33573 +       pages=$$(( 1 << $(CONFIG_KERNEL_STACK_ORDER) )) ; \
33574 +       m4 -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
33575 +               -DELF_FORMAT=$(ELF_FORMAT) $(M4_MODE_TT) \
33576 +               -DKERNEL_STACK_SIZE=$$(( 4096 * $$pages )) $< > $@
33577 +
33578 +SYMLINK_HEADERS = archparam.h system.h sigcontext.h processor.h ptrace.h \
33579 +       arch-signal.h
33580 +SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
33581 +
33582 +ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \
33583 +       $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
33584 +
33585 +ifeq ($(CONFIG_MODE_SKAS), y)
33586 +$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
33587 +endif
33588 +
33589 +GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h 
33590 +
33591 +setup: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) 
33592 +
33593 +linux: setup $(ARCH_DIR)/main.o vmlinux $(LD_SCRIPT-y)
33594 +       mv vmlinux vmlinux.o
33595 +       $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
33596 +               -o linux $(ARCH_DIR)/main.o vmlinux.o -L/usr/lib -lutil
33597 +
33598 +USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
33599 +USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
33600 +USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
33601 +       $(MODE_INCLUDE)
33602 +
33603 +# To get a definition of F_SETSIG
33604 +USER_CFLAGS += -D_GNU_SOURCE
33605 +
33606 +CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/link.ld $(ARCH_DIR)/dyn_link.ld \
33607 +       $(GEN_HEADERS) $(ARCH_DIR)/include/uml-config.h
33608 +
33609 +$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
33610 +       $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
33611 +
33612 +archmrproper:
33613 +       rm -f $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
33614 +               $(LD_SCRIPT) $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
33615 +
33616 +archclean: sysclean
33617 +       find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
33618 +               -o -name '*.gcov' \) -type f -print | xargs rm -f
33619 +       cd $(ARCH_DIR) ; \
33620 +       for dir in $(subdir-y) util ; do $(MAKE) -C $$dir clean; done
33621 +
33622 +archdep: 
33623 +
33624 +$(SYMLINK_HEADERS):
33625 +       cd $(TOPDIR)/$(dir $@) ; \
33626 +       ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
33627 +
33628 +include/asm-um/arch:
33629 +       cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
33630 +
33631 +arch/um/include/sysdep:
33632 +       cd $(TOPDIR)/arch/um/include && ln -sf sysdep-$(SUBARCH) sysdep
33633 +
33634 +arch/um/os:
33635 +       cd $(ARCH_DIR) && ln -sf os-$(OS) os
33636 +
33637 +$(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
33638 +       $< > $@
33639 +
33640 +$(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
33641 +       $< > $@
33642 +
33643 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
33644 +       sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
33645 +
33646 +$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/util/mk_task_user.c \
33647 +       $(ARCH_DIR)/util/mk_task_kern.c $(SYS_HEADERS)
33648 +       $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_task
33649 +
33650 +$(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util/mk_constants_user.c \
33651 +       $(ARCH_DIR)/util/mk_constants_kern.c 
33652 +       $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_constants
33653 +
33654 +export SUBARCH USER_CFLAGS OS
33655 diff -Naur -X ../exclude-files orig/arch/um/Makefile-i386 um/arch/um/Makefile-i386
33656 --- orig/arch/um/Makefile-i386  1969-12-31 19:00:00.000000000 -0500
33657 +++ um/arch/um/Makefile-i386    2003-10-21 03:26:07.000000000 -0400
33658 @@ -0,0 +1,35 @@
33659 +ifeq ($(CONFIG_HOST_2G_2G), y)
33660 +TOP_ADDR = 0x80000000
33661 +else
33662 +TOP_ADDR = 0xc0000000
33663 +endif
33664 +
33665 +ARCH_CFLAGS = -U__$(SUBARCH)__ -U$(SUBARCH) -DUM_FASTCALL
33666 +ELF_ARCH = $(SUBARCH)
33667 +ELF_FORMAT = elf32-$(SUBARCH)
33668 +
33669 +I386_H = $(ARCH_DIR)/include/sysdep-i386
33670 +SYS = $(ARCH_DIR)/sys-i386
33671 +UTIL = $(SYS)/util
33672 +SUBDIRS += $(UTIL)
33673 +
33674 +SYS_HEADERS = $(I386_H)/sc.h $(I386_H)/thread.h
33675 +
33676 +$(I386_H)/sc.h : $(UTIL)/mk_sc
33677 +       $(UTIL)/mk_sc > $@
33678 +
33679 +$(I386_H)/thread.h : $(UTIL)/mk_thread
33680 +       $(UTIL)/mk_thread > $@
33681 +
33682 +$(UTIL)/mk_sc : $(UTIL)/mk_sc.c
33683 +       $(MAKE) -C $(UTIL) mk_sc
33684 +
33685 +$(UTIL)/mk_thread : $(UTIL)/mk_thread_user.c $(UTIL)/mk_thread_kern.c \
33686 +       $(I386_H)/sc.h
33687 +       $(MAKE) -C $(UTIL) mk_thread
33688 +
33689 +sysclean :
33690 +       rm -f $(SYS_HEADERS)
33691 +       $(MAKE) -C $(UTIL) clean
33692 +       $(MAKE) -C $(SYS) clean
33693 +
33694 diff -Naur -X ../exclude-files orig/arch/um/Makefile-ia64 um/arch/um/Makefile-ia64
33695 --- orig/arch/um/Makefile-ia64  1969-12-31 19:00:00.000000000 -0500
33696 +++ um/arch/um/Makefile-ia64    2003-10-21 03:26:07.000000000 -0400
33697 @@ -0,0 +1 @@
33698 +START_ADDR = 0x1000000000000000
33699 diff -Naur -X ../exclude-files orig/arch/um/Makefile-os-Linux um/arch/um/Makefile-os-Linux
33700 --- orig/arch/um/Makefile-os-Linux      1969-12-31 19:00:00.000000000 -0500
33701 +++ um/arch/um/Makefile-os-Linux        2003-10-21 03:26:07.000000000 -0400
33702 @@ -0,0 +1,7 @@
33703 +# 
33704 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
33705 +# Licensed under the GPL
33706 +#
33707 +
33708 +SUBDIRS += $(ARCH_DIR)/os-$(OS)/drivers
33709 +DRIVERS += $(ARCH_DIR)/os-$(OS)/drivers/drivers.o
33710 diff -Naur -X ../exclude-files orig/arch/um/Makefile-ppc um/arch/um/Makefile-ppc
33711 --- orig/arch/um/Makefile-ppc   1969-12-31 19:00:00.000000000 -0500
33712 +++ um/arch/um/Makefile-ppc     2003-10-21 03:26:07.000000000 -0400
33713 @@ -0,0 +1,9 @@
33714 +ifeq ($(CONFIG_HOST_2G_2G), y)
33715 +START_ADDR = 0x80000000
33716 +else
33717 +START_ADDR = 0xc0000000
33718 +endif
33719 +ARCH_CFLAGS = -U__powerpc__ -D__UM_PPC__
33720 +
33721 +# The arch is ppc, but the elf32 name is powerpc
33722 +ELF_SUBARCH = powerpc
33723 diff -Naur -X ../exclude-files orig/arch/um/Makefile-skas um/arch/um/Makefile-skas
33724 --- orig/arch/um/Makefile-skas  1969-12-31 19:00:00.000000000 -0500
33725 +++ um/arch/um/Makefile-skas    2003-10-21 03:26:07.000000000 -0400
33726 @@ -0,0 +1,20 @@
33727 +# 
33728 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33729 +# Licensed under the GPL
33730 +#
33731 +
33732 +PROFILE += -pg
33733 +
33734 +CFLAGS-$(CONFIG_GCOV) += -fprofile-arcs -ftest-coverage
33735 +CFLAGS-$(CONFIG_GPROF) += $(PROFILE)
33736 +LINK-$(CONFIG_GPROF) += $(PROFILE)
33737 +
33738 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/skas/include
33739 +
33740 +LINK_SKAS = -Wl,-rpath,/lib 
33741 +LD_SCRIPT_SKAS = dyn_link.ld
33742 +
33743 +GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
33744 +
33745 +$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
33746 +       $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
33747 diff -Naur -X ../exclude-files orig/arch/um/Makefile-tt um/arch/um/Makefile-tt
33748 --- orig/arch/um/Makefile-tt    1969-12-31 19:00:00.000000000 -0500
33749 +++ um/arch/um/Makefile-tt      2003-10-21 03:26:07.000000000 -0400
33750 @@ -0,0 +1,7 @@
33751 +# 
33752 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33753 +# Licensed under the GPL
33754 +#
33755 +
33756 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/tt/include
33757 +
33758 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/etap.h um/arch/um/os-Linux/drivers/etap.h
33759 --- orig/arch/um/os-Linux/drivers/etap.h        1969-12-31 19:00:00.000000000 -0500
33760 +++ um/arch/um/os-Linux/drivers/etap.h  2003-10-21 03:26:07.000000000 -0400
33761 @@ -0,0 +1,27 @@
33762 +/* 
33763 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
33764 + * Licensed under the GPL
33765 + */
33766 +
33767 +#include "net_user.h"
33768 +
33769 +struct ethertap_data {
33770 +       char *dev_name;
33771 +       char *gate_addr;
33772 +       int data_fd;
33773 +       int control_fd;
33774 +       void *dev;
33775 +};
33776 +
33777 +extern struct net_user_info ethertap_user_info;
33778 +
33779 +/*
33780 + * Overrides for Emacs so that we follow Linus's tabbing style.
33781 + * Emacs will notice this stuff at the end of the file and automatically
33782 + * adjust the settings for this buffer only.  This must remain at the end
33783 + * of the file.
33784 + * ---------------------------------------------------------------------------
33785 + * Local variables:
33786 + * c-file-style: "linux"
33787 + * End:
33788 + */
33789 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_kern.c um/arch/um/os-Linux/drivers/ethertap_kern.c
33790 --- orig/arch/um/os-Linux/drivers/ethertap_kern.c       1969-12-31 19:00:00.000000000 -0500
33791 +++ um/arch/um/os-Linux/drivers/ethertap_kern.c 2003-10-21 03:26:07.000000000 -0400
33792 @@ -0,0 +1,122 @@
33793 +/*
33794 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
33795 + * James Leu (jleu@mindspring.net).
33796 + * Copyright (C) 2001 by various other people who didn't put their name here.
33797 + * Licensed under the GPL.
33798 + */
33799 +
33800 +#include "linux/init.h"
33801 +#include "linux/netdevice.h"
33802 +#include "linux/etherdevice.h"
33803 +#include "linux/init.h"
33804 +#include "net_kern.h"
33805 +#include "net_user.h"
33806 +#include "etap.h"
33807 +
33808 +struct ethertap_init {
33809 +       char *dev_name;
33810 +       char *gate_addr;
33811 +};
33812 +
33813 +static void etap_init(struct net_device *dev, void *data)
33814 +{
33815 +       struct uml_net_private *pri;
33816 +       struct ethertap_data *epri;
33817 +       struct ethertap_init *init = data;
33818 +
33819 +       init_etherdev(dev, 0);
33820 +       pri = dev->priv;
33821 +       epri = (struct ethertap_data *) pri->user;
33822 +       *epri = ((struct ethertap_data)
33823 +               { .dev_name             = init->dev_name,
33824 +                 .gate_addr            = init->gate_addr,
33825 +                 .data_fd              = -1,
33826 +                 .control_fd           = -1,
33827 +                 .dev                  = dev });
33828 +
33829 +       printk("ethertap backend - %s", epri->dev_name);
33830 +       if(epri->gate_addr != NULL) 
33831 +               printk(", IP = %s", epri->gate_addr);
33832 +       printk("\n");
33833 +}
33834 +
33835 +static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
33836 +{
33837 +       int len;
33838 +
33839 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
33840 +       if(*skb == NULL) return(-ENOMEM);
33841 +       len = net_recvfrom(fd, (*skb)->mac.raw, 
33842 +                          (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
33843 +       if(len <= 0) return(len);
33844 +       skb_pull(*skb, 2);
33845 +       len -= 2;
33846 +       return(len);
33847 +}
33848 +
33849 +static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
33850 +{
33851 +       if(skb_headroom(*skb) < 2){
33852 +               struct sk_buff *skb2;
33853 +
33854 +               skb2 = skb_realloc_headroom(*skb, 2);
33855 +               dev_kfree_skb(*skb);
33856 +               if (skb2 == NULL) return(-ENOMEM);
33857 +               *skb = skb2;
33858 +       }
33859 +       skb_push(*skb, 2);
33860 +       return(net_send(fd, (*skb)->data, (*skb)->len));
33861 +}
33862 +
33863 +struct net_kern_info ethertap_kern_info = {
33864 +       .init                   = etap_init,
33865 +       .protocol               = eth_protocol,
33866 +       .read                   = etap_read,
33867 +       .write                  = etap_write,
33868 +};
33869 +
33870 +int ethertap_setup(char *str, char **mac_out, void *data)
33871 +{
33872 +       struct ethertap_init *init = data;
33873 +
33874 +       *init = ((struct ethertap_init)
33875 +               { .dev_name     = NULL,
33876 +                 .gate_addr    = NULL });
33877 +       if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
33878 +                           &init->gate_addr))
33879 +               return(0);
33880 +       if(init->dev_name == NULL){
33881 +               printk("ethertap_setup : Missing tap device name\n");
33882 +               return(0);
33883 +       }
33884 +
33885 +       return(1);
33886 +}
33887 +
33888 +static struct transport ethertap_transport = {
33889 +       .list           = LIST_HEAD_INIT(ethertap_transport.list),
33890 +       .name           = "ethertap",
33891 +       .setup          = ethertap_setup,
33892 +       .user           = &ethertap_user_info,
33893 +       .kern           = &ethertap_kern_info,
33894 +       .private_size   = sizeof(struct ethertap_data),
33895 +};
33896 +
33897 +static int register_ethertap(void)
33898 +{
33899 +       register_transport(&ethertap_transport);
33900 +       return(1);
33901 +}
33902 +
33903 +__initcall(register_ethertap);
33904 +
33905 +/*
33906 + * Overrides for Emacs so that we follow Linus's tabbing style.
33907 + * Emacs will notice this stuff at the end of the file and automatically
33908 + * adjust the settings for this buffer only.  This must remain at the end
33909 + * of the file.
33910 + * ---------------------------------------------------------------------------
33911 + * Local variables:
33912 + * c-file-style: "linux"
33913 + * End:
33914 + */
33915 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_user.c um/arch/um/os-Linux/drivers/ethertap_user.c
33916 --- orig/arch/um/os-Linux/drivers/ethertap_user.c       1969-12-31 19:00:00.000000000 -0500
33917 +++ um/arch/um/os-Linux/drivers/ethertap_user.c 2003-10-21 03:26:07.000000000 -0400
33918 @@ -0,0 +1,238 @@
33919 +/*
33920 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
33921 + * James Leu (jleu@mindspring.net).
33922 + * Copyright (C) 2001 by various other people who didn't put their name here.
33923 + * Licensed under the GPL.
33924 + */
33925 +
33926 +#include <stdio.h>
33927 +#include <unistd.h>
33928 +#include <stddef.h>
33929 +#include <stdlib.h>
33930 +#include <sys/errno.h>
33931 +#include <sys/socket.h>
33932 +#include <sys/wait.h>
33933 +#include <sys/un.h>
33934 +#include <net/if.h>
33935 +#include "user.h"
33936 +#include "kern_util.h"
33937 +#include "net_user.h"
33938 +#include "etap.h"
33939 +#include "helper.h"
33940 +#include "os.h"
33941 +
33942 +#define MAX_PACKET ETH_MAX_PACKET
33943 +
33944 +void etap_user_init(void *data, void *dev)
33945 +{
33946 +       struct ethertap_data *pri = data;
33947 +
33948 +       pri->dev = dev;
33949 +}
33950 +
33951 +struct addr_change {
33952 +       enum { ADD_ADDR, DEL_ADDR } what;
33953 +       unsigned char addr[4];
33954 +       unsigned char netmask[4];
33955 +};
33956 +
33957 +static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
33958 +                       int fd)
33959 +{
33960 +       struct addr_change change;
33961 +       void *output;
33962 +       int n;
33963 +
33964 +       change.what = op;
33965 +       memcpy(change.addr, addr, sizeof(change.addr));
33966 +       memcpy(change.netmask, netmask, sizeof(change.netmask));
33967 +       n = os_write_file(fd, &change, sizeof(change));
33968 +       if(n != sizeof(change))
33969 +               printk("etap_change - request failed, err = %d\n", -n);
33970 +       output = um_kmalloc(page_size());
33971 +       if(output == NULL)
33972 +               printk("etap_change : Failed to allocate output buffer\n");
33973 +       read_output(fd, output, page_size());
33974 +       if(output != NULL){
33975 +               printk("%s", output);
33976 +               kfree(output);
33977 +       }
33978 +}
33979 +
33980 +static void etap_open_addr(unsigned char *addr, unsigned char *netmask,
33981 +                          void *arg)
33982 +{
33983 +       etap_change(ADD_ADDR, addr, netmask, *((int *) arg));
33984 +}
33985 +
33986 +static void etap_close_addr(unsigned char *addr, unsigned char *netmask,
33987 +                           void *arg)
33988 +{
33989 +       etap_change(DEL_ADDR, addr, netmask, *((int *) arg));
33990 +}
33991 +
33992 +struct etap_pre_exec_data {
33993 +       int control_remote;
33994 +       int control_me;
33995 +       int data_me;
33996 +};
33997 +
33998 +static void etap_pre_exec(void *arg)
33999 +{
34000 +       struct etap_pre_exec_data *data = arg;
34001 +
34002 +       dup2(data->control_remote, 1);
34003 +       os_close_file(data->data_me);
34004 +       os_close_file(data->control_me);
34005 +}
34006 +
34007 +static int etap_tramp(char *dev, char *gate, int control_me, 
34008 +                     int control_remote, int data_me, int data_remote)
34009 +{
34010 +       struct etap_pre_exec_data pe_data;
34011 +       int pid, status, err, n;
34012 +       char version_buf[sizeof("nnnnn\0")];
34013 +       char data_fd_buf[sizeof("nnnnnn\0")];
34014 +       char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
34015 +       char *setup_args[] = { "uml_net", version_buf, "ethertap", dev,
34016 +                              data_fd_buf, gate_buf, NULL };
34017 +       char *nosetup_args[] = { "uml_net", version_buf, "ethertap", 
34018 +                                dev, data_fd_buf, NULL };
34019 +       char **args, c;
34020 +
34021 +       sprintf(data_fd_buf, "%d", data_remote);
34022 +       sprintf(version_buf, "%d", UML_NET_VERSION);
34023 +       if(gate != NULL){
34024 +               strcpy(gate_buf, gate);
34025 +               args = setup_args;
34026 +       }
34027 +       else args = nosetup_args;
34028 +
34029 +       err = 0;
34030 +       pe_data.control_remote = control_remote;
34031 +       pe_data.control_me = control_me;
34032 +       pe_data.data_me = data_me;
34033 +       pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
34034 +
34035 +       if(pid < 0) err = pid;
34036 +       os_close_file(data_remote);
34037 +       os_close_file(control_remote);
34038 +       n = os_read_file(control_me, &c, sizeof(c));
34039 +       if(n != sizeof(c)){
34040 +               printk("etap_tramp : read of status failed, err = %d\n", -n);
34041 +               return(-EINVAL);
34042 +       }
34043 +       if(c != 1){
34044 +               printk("etap_tramp : uml_net failed\n");
34045 +               err = -EINVAL;
34046 +               if(waitpid(pid, &status, 0) < 0)
34047 +                       err = -errno;
34048 +               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
34049 +                       printk("uml_net didn't exit with status 1\n");
34050 +       }
34051 +       return(err);
34052 +}
34053 +
34054 +static int etap_open(void *data)
34055 +{
34056 +       struct ethertap_data *pri = data;
34057 +       char *output;
34058 +       int data_fds[2], control_fds[2], err, output_len;
34059 +
34060 +       err = tap_open_common(pri->dev, pri->gate_addr);
34061 +       if(err) return(err);
34062 +
34063 +       err = os_pipe(data_fds, 0, 0);
34064 +       if(err < 0){
34065 +               printk("data os_pipe failed - err = %d\n", -err);
34066 +               return(err);
34067 +       }
34068 +
34069 +       err = os_pipe(control_fds, 1, 0);
34070 +       if(err < 0){
34071 +               printk("control os_pipe failed - err = %d\n", -err);
34072 +               return(err);
34073 +       }
34074 +       
34075 +       err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], 
34076 +                        control_fds[1], data_fds[0], data_fds[1]);
34077 +       output_len = page_size();
34078 +       output = um_kmalloc(output_len);
34079 +       read_output(control_fds[0], output, output_len);
34080 +
34081 +       if(output == NULL)
34082 +               printk("etap_open : failed to allocate output buffer\n");
34083 +       else {
34084 +               printk("%s", output);
34085 +               kfree(output);
34086 +       }
34087 +
34088 +       if(err < 0){
34089 +               printk("etap_tramp failed - err = %d\n", -err);
34090 +               return(err);
34091 +       }
34092 +
34093 +       pri->data_fd = data_fds[0];
34094 +       pri->control_fd = control_fds[0];
34095 +       iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
34096 +       return(data_fds[0]);
34097 +}
34098 +
34099 +static void etap_close(int fd, void *data)
34100 +{
34101 +       struct ethertap_data *pri = data;
34102 +
34103 +       iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
34104 +       os_close_file(fd);
34105 +       os_shutdown_socket(pri->data_fd, 1, 1);
34106 +       os_close_file(pri->data_fd);
34107 +       pri->data_fd = -1;
34108 +       os_close_file(pri->control_fd);
34109 +       pri->control_fd = -1;
34110 +}
34111 +
34112 +static int etap_set_mtu(int mtu, void *data)
34113 +{
34114 +       return(mtu);
34115 +}
34116 +
34117 +static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
34118 +                         void *data)
34119 +{
34120 +       struct ethertap_data *pri = data;
34121 +
34122 +       tap_check_ips(pri->gate_addr, addr);
34123 +       if(pri->control_fd == -1) return;
34124 +       etap_open_addr(addr, netmask, &pri->control_fd);
34125 +}
34126 +
34127 +static void etap_del_addr(unsigned char *addr, unsigned char *netmask, 
34128 +                         void *data)
34129 +{
34130 +       struct ethertap_data *pri = data;
34131 +
34132 +       if(pri->control_fd == -1) return;
34133 +       etap_close_addr(addr, netmask, &pri->control_fd);
34134 +}
34135 +
34136 +struct net_user_info ethertap_user_info = {
34137 +       .init           = etap_user_init,
34138 +       .open           = etap_open,
34139 +       .close          = etap_close,
34140 +       .remove         = NULL,
34141 +       .set_mtu        = etap_set_mtu,
34142 +       .add_address    = etap_add_addr,
34143 +       .delete_address = etap_del_addr,
34144 +       .max_packet     = MAX_PACKET - ETH_HEADER_ETHERTAP
34145 +};
34146 +
34147 +/*
34148 + * Overrides for Emacs so that we follow Linus's tabbing style.
34149 + * Emacs will notice this stuff at the end of the file and automatically
34150 + * adjust the settings for this buffer only.  This must remain at the end
34151 + * of the file.
34152 + * ---------------------------------------------------------------------------
34153 + * Local variables:
34154 + * c-file-style: "linux"
34155 + * End:
34156 + */
34157 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/Makefile um/arch/um/os-Linux/drivers/Makefile
34158 --- orig/arch/um/os-Linux/drivers/Makefile      1969-12-31 19:00:00.000000000 -0500
34159 +++ um/arch/um/os-Linux/drivers/Makefile        2003-10-21 03:26:07.000000000 -0400
34160 @@ -0,0 +1,31 @@
34161 +# 
34162 +# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
34163 +# Licensed under the GPL
34164 +#
34165 +
34166 +O_TARGET := drivers.o
34167 +
34168 +list-multi := tuntap.o ethertap.o
34169 +
34170 +ethertap-objs := ethertap_kern.o ethertap_user.o
34171 +tuntap-objs := tuntap_kern.o tuntap_user.o
34172 +
34173 +obj-y = 
34174 +obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap.o
34175 +obj-$(CONFIG_UML_NET_TUNTAP) += tuntap.o
34176 +
34177 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y)),$($(f)-objs))
34178 +
34179 +USER_OBJS = $(filter %_user.o,$(obj-y) $(USER_SINGLE_OBJS))
34180 +
34181 +include $(TOPDIR)/Rules.make
34182 +
34183 +$(USER_OBJS) : %.o: %.c
34184 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
34185 +
34186 +ethertap.o : $(ethertap-objs)
34187 +
34188 +tuntap.o : $(tuntap-objs)
34189 +
34190 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
34191 +       $(LD) $(LD_RFLAG) -r -o $@ $($(patsubst %.o,%,$@)-objs)
34192 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap.h um/arch/um/os-Linux/drivers/tuntap.h
34193 --- orig/arch/um/os-Linux/drivers/tuntap.h      1969-12-31 19:00:00.000000000 -0500
34194 +++ um/arch/um/os-Linux/drivers/tuntap.h        2003-10-21 03:26:07.000000000 -0400
34195 @@ -0,0 +1,32 @@
34196 +/* 
34197 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
34198 + * Licensed under the GPL
34199 + */
34200 +
34201 +#ifndef __UM_TUNTAP_H
34202 +#define __UM_TUNTAP_H
34203 +
34204 +#include "net_user.h"
34205 +
34206 +struct tuntap_data {
34207 +       char *dev_name;
34208 +       int fixed_config;
34209 +       char *gate_addr;
34210 +       int fd;
34211 +       void *dev;
34212 +};
34213 +
34214 +extern struct net_user_info tuntap_user_info;
34215 +
34216 +#endif
34217 +
34218 +/*
34219 + * Overrides for Emacs so that we follow Linus's tabbing style.
34220 + * Emacs will notice this stuff at the end of the file and automatically
34221 + * adjust the settings for this buffer only.  This must remain at the end
34222 + * of the file.
34223 + * ---------------------------------------------------------------------------
34224 + * Local variables:
34225 + * c-file-style: "linux"
34226 + * End:
34227 + */
34228 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_kern.c um/arch/um/os-Linux/drivers/tuntap_kern.c
34229 --- orig/arch/um/os-Linux/drivers/tuntap_kern.c 1969-12-31 19:00:00.000000000 -0500
34230 +++ um/arch/um/os-Linux/drivers/tuntap_kern.c   2003-10-21 03:26:07.000000000 -0400
34231 @@ -0,0 +1,105 @@
34232 +/* 
34233 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
34234 + * Licensed under the GPL
34235 + */
34236 +
34237 +#include "linux/stddef.h"
34238 +#include "linux/netdevice.h"
34239 +#include "linux/etherdevice.h"
34240 +#include "linux/skbuff.h"
34241 +#include "linux/init.h"
34242 +#include "asm/errno.h"
34243 +#include "net_kern.h"
34244 +#include "net_user.h"
34245 +#include "tuntap.h"
34246 +
34247 +struct tuntap_init {
34248 +       char *dev_name;
34249 +       char *gate_addr;
34250 +};
34251 +
34252 +static void tuntap_init(struct net_device *dev, void *data)
34253 +{
34254 +       struct uml_net_private *pri;
34255 +       struct tuntap_data *tpri;
34256 +       struct tuntap_init *init = data;
34257 +
34258 +       init_etherdev(dev, 0);
34259 +       pri = dev->priv;
34260 +       tpri = (struct tuntap_data *) pri->user;
34261 +       *tpri = ((struct tuntap_data)
34262 +               { .dev_name             = init->dev_name,
34263 +                 .fixed_config         = (init->dev_name != NULL),
34264 +                 .gate_addr            = init->gate_addr,
34265 +                 .fd                   = -1,
34266 +                 .dev                  = dev });
34267 +       printk("TUN/TAP backend - ");
34268 +       if(tpri->gate_addr != NULL) 
34269 +               printk("IP = %s", tpri->gate_addr);
34270 +       printk("\n");
34271 +}
34272 +
34273 +static int tuntap_read(int fd, struct sk_buff **skb, 
34274 +                      struct uml_net_private *lp)
34275 +{
34276 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
34277 +       if(*skb == NULL) return(-ENOMEM);
34278 +       return(net_read(fd, (*skb)->mac.raw, 
34279 +                       (*skb)->dev->mtu + ETH_HEADER_OTHER));
34280 +}
34281 +
34282 +static int tuntap_write(int fd, struct sk_buff **skb, 
34283 +                       struct uml_net_private *lp)
34284 +{
34285 +       return(net_write(fd, (*skb)->data, (*skb)->len));
34286 +}
34287 +
34288 +struct net_kern_info tuntap_kern_info = {
34289 +       .init                   = tuntap_init,
34290 +       .protocol               = eth_protocol,
34291 +       .read                   = tuntap_read,
34292 +       .write                  = tuntap_write,
34293 +};
34294 +
34295 +int tuntap_setup(char *str, char **mac_out, void *data)
34296 +{
34297 +       struct tuntap_init *init = data;
34298 +
34299 +       *init = ((struct tuntap_init)
34300 +               { .dev_name     = NULL,
34301 +                 .gate_addr    = NULL });
34302 +       if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
34303 +                           &init->gate_addr))
34304 +               return(0);
34305 +
34306 +       return(1);
34307 +}
34308 +
34309 +static struct transport tuntap_transport = {
34310 +       .list           = LIST_HEAD_INIT(tuntap_transport.list),
34311 +       .name           = "tuntap",
34312 +       .setup          = tuntap_setup,
34313 +       .user           = &tuntap_user_info,
34314 +       .kern           = &tuntap_kern_info,
34315 +       .private_size   = sizeof(struct tuntap_data),
34316 +       .setup_size     = sizeof(struct tuntap_init),
34317 +};
34318 +
34319 +static int register_tuntap(void)
34320 +{
34321 +       register_transport(&tuntap_transport);
34322 +       return(1);
34323 +}
34324 +
34325 +__initcall(register_tuntap);
34326 +
34327 +/*
34328 + * Overrides for Emacs so that we follow Linus's tabbing style.
34329 + * Emacs will notice this stuff at the end of the file and automatically
34330 + * adjust the settings for this buffer only.  This must remain at the end
34331 + * of the file.
34332 + * ---------------------------------------------------------------------------
34333 + * Local variables:
34334 + * c-file-style: "linux"
34335 + * End:
34336 + */
34337 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_user.c um/arch/um/os-Linux/drivers/tuntap_user.c
34338 --- orig/arch/um/os-Linux/drivers/tuntap_user.c 1969-12-31 19:00:00.000000000 -0500
34339 +++ um/arch/um/os-Linux/drivers/tuntap_user.c   2003-11-12 00:02:30.000000000 -0500
34340 @@ -0,0 +1,224 @@
34341 +/* 
34342 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
34343 + * Licensed under the GPL
34344 + */
34345 +
34346 +#include <stdio.h>
34347 +#include <stddef.h>
34348 +#include <stdlib.h>
34349 +#include <unistd.h>
34350 +#include <errno.h>
34351 +#include <sys/wait.h>
34352 +#include <sys/socket.h>
34353 +#include <sys/un.h>
34354 +#include <sys/uio.h>
34355 +#include <sys/ioctl.h>
34356 +#include <net/if.h>
34357 +#include <linux/if_tun.h>
34358 +#include "net_user.h"
34359 +#include "tuntap.h"
34360 +#include "kern_util.h"
34361 +#include "user.h"
34362 +#include "helper.h"
34363 +#include "os.h"
34364 +
34365 +#define MAX_PACKET ETH_MAX_PACKET
34366 +
34367 +void tuntap_user_init(void *data, void *dev)
34368 +{
34369 +       struct tuntap_data *pri = data;
34370 +
34371 +       pri->dev = dev;
34372 +}
34373 +
34374 +static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
34375 +                           void *data)
34376 +{
34377 +       struct tuntap_data *pri = data;
34378 +
34379 +       tap_check_ips(pri->gate_addr, addr);
34380 +       if((pri->fd == -1) || pri->fixed_config) return;
34381 +       open_addr(addr, netmask, pri->dev_name);
34382 +}
34383 +
34384 +static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
34385 +                           void *data)
34386 +{
34387 +       struct tuntap_data *pri = data;
34388 +
34389 +       if((pri->fd == -1) || pri->fixed_config) return;
34390 +       close_addr(addr, netmask, pri->dev_name);
34391 +}
34392 +
34393 +struct tuntap_pre_exec_data {
34394 +       int stdout;
34395 +       int close_me;
34396 +};
34397 +
34398 +static void tuntap_pre_exec(void *arg)
34399 +{
34400 +       struct tuntap_pre_exec_data *data = arg;
34401 +       
34402 +       dup2(data->stdout, 1);
34403 +       os_close_file(data->close_me);
34404 +}
34405 +
34406 +static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
34407 +                            char *buffer, int buffer_len, int *used_out)
34408 +{
34409 +       struct tuntap_pre_exec_data data;
34410 +       char version_buf[sizeof("nnnnn\0")];
34411 +       char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate,
34412 +                        NULL };
34413 +       char buf[CMSG_SPACE(sizeof(*fd_out))];
34414 +       struct msghdr msg;
34415 +       struct cmsghdr *cmsg;
34416 +       struct iovec iov;
34417 +       int pid, n;
34418 +
34419 +       sprintf(version_buf, "%d", UML_NET_VERSION);
34420 +
34421 +       data.stdout = remote;
34422 +       data.close_me = me;
34423 +
34424 +       pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
34425 +
34426 +       if(pid < 0) return(-pid);
34427 +
34428 +       os_close_file(remote);
34429 +
34430 +       msg.msg_name = NULL;
34431 +       msg.msg_namelen = 0;
34432 +       if(buffer != NULL){
34433 +               iov = ((struct iovec) { buffer, buffer_len });
34434 +               msg.msg_iov = &iov;
34435 +               msg.msg_iovlen = 1;
34436 +       }
34437 +       else {
34438 +               msg.msg_iov = NULL;
34439 +               msg.msg_iovlen = 0;
34440 +       }
34441 +       msg.msg_control = buf;
34442 +       msg.msg_controllen = sizeof(buf);
34443 +       msg.msg_flags = 0;
34444 +       n = recvmsg(me, &msg, 0);
34445 +       *used_out = n;
34446 +       if(n < 0){
34447 +               printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", 
34448 +                      errno);
34449 +               return(-errno);
34450 +       }
34451 +       waitpid(pid, NULL, 0);
34452 +
34453 +       cmsg = CMSG_FIRSTHDR(&msg);
34454 +       if(cmsg == NULL){
34455 +               printk("tuntap_open_tramp : didn't receive a message\n");
34456 +               return(-EINVAL);
34457 +       }
34458 +       if((cmsg->cmsg_level != SOL_SOCKET) || 
34459 +          (cmsg->cmsg_type != SCM_RIGHTS)){
34460 +               printk("tuntap_open_tramp : didn't receive a descriptor\n");
34461 +               return(-EINVAL);
34462 +       }
34463 +       *fd_out = ((int *) CMSG_DATA(cmsg))[0];
34464 +       return(0);
34465 +}
34466 +
34467 +static int tuntap_open(void *data)
34468 +{
34469 +       struct ifreq ifr;
34470 +       struct tuntap_data *pri = data;
34471 +       char *output, *buffer;
34472 +       int err, fds[2], len, used;
34473 +
34474 +       err = tap_open_common(pri->dev, pri->gate_addr);
34475 +       if(err < 0) 
34476 +               return(err);
34477 +
34478 +       if(pri->fixed_config){
34479 +               pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
34480 +               if(pri->fd < 0){
34481 +                       printk("Failed to open /dev/net/tun, err = %d\n",
34482 +                              -pri->fd);
34483 +                       return(pri->fd);
34484 +               }
34485 +               memset(&ifr, 0, sizeof(ifr));
34486 +               ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
34487 +               strncpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name) - 1);
34488 +               if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
34489 +                       printk("TUNSETIFF failed, errno = %d\n", errno);
34490 +                       os_close_file(pri->fd);
34491 +                       return(-errno);
34492 +               }
34493 +       }
34494 +       else {
34495 +               err = os_pipe(fds, 0, 0);
34496 +               if(err < 0){
34497 +                       printk("tuntap_open : os_pipe failed - err = %d\n",
34498 +                              -err);
34499 +                       return(err);
34500 +               }
34501 +
34502 +               buffer = get_output_buffer(&len);
34503 +               if(buffer != NULL) len--;
34504 +               used = 0;
34505 +
34506 +               err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
34507 +                                       fds[1], buffer, len, &used);
34508 +
34509 +               output = buffer;
34510 +               if(err < 0) {
34511 +                       printk("%s", output);
34512 +                       free_output_buffer(buffer);
34513 +                       printk("tuntap_open_tramp failed - err = %d\n", -err);
34514 +                       return(err);
34515 +               }
34516 +
34517 +               pri->dev_name = uml_strdup(buffer);
34518 +               output += IFNAMSIZ;
34519 +               printk("%s", output);
34520 +               free_output_buffer(buffer);
34521 +
34522 +               os_close_file(fds[0]);
34523 +               iter_addresses(pri->dev, open_addr, pri->dev_name);
34524 +       }
34525 +
34526 +       return(pri->fd);
34527 +}
34528 +
34529 +static void tuntap_close(int fd, void *data)
34530 +{
34531 +       struct tuntap_data *pri = data;
34532 +
34533 +       if(!pri->fixed_config) 
34534 +               iter_addresses(pri->dev, close_addr, pri->dev_name);
34535 +       os_close_file(fd);
34536 +       pri->fd = -1;
34537 +}
34538 +
34539 +static int tuntap_set_mtu(int mtu, void *data)
34540 +{
34541 +       return(mtu);
34542 +}
34543 +
34544 +struct net_user_info tuntap_user_info = {
34545 +       .init           = tuntap_user_init,
34546 +       .open           = tuntap_open,
34547 +       .close          = tuntap_close,
34548 +       .remove         = NULL,
34549 +       .set_mtu        = tuntap_set_mtu,
34550 +       .add_address    = tuntap_add_addr,
34551 +       .delete_address = tuntap_del_addr,
34552 +       .max_packet     = MAX_PACKET
34553 +};
34554 +
34555 +/*
34556 + * Overrides for Emacs so that we follow Linus's tabbing style.
34557 + * Emacs will notice this stuff at the end of the file and automatically
34558 + * adjust the settings for this buffer only.  This must remain at the end
34559 + * of the file.
34560 + * ---------------------------------------------------------------------------
34561 + * Local variables:
34562 + * c-file-style: "linux"
34563 + * End:
34564 + */
34565 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/file.c um/arch/um/os-Linux/file.c
34566 --- orig/arch/um/os-Linux/file.c        1969-12-31 19:00:00.000000000 -0500
34567 +++ um/arch/um/os-Linux/file.c  2004-01-10 06:52:24.000000000 -0500
34568 @@ -0,0 +1,668 @@
34569 +/* 
34570 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34571 + * Licensed under the GPL
34572 + */
34573 +
34574 +#include <stdio.h>
34575 +#include <unistd.h>
34576 +#include <errno.h>
34577 +#include <fcntl.h>
34578 +#include <signal.h>
34579 +#include <sys/types.h>
34580 +#include <sys/stat.h>
34581 +#include <sys/socket.h>
34582 +#include <sys/un.h>
34583 +#include <sys/ioctl.h>
34584 +#include <sys/mount.h>
34585 +#include <sys/uio.h>
34586 +#include "os.h"
34587 +#include "user.h"
34588 +#include "kern_util.h"
34589 +
34590 +static void copy_stat(struct uml_stat *dst, struct stat64 *src)
34591 +{
34592 +       *dst = ((struct uml_stat) {
34593 +               .ust_dev     = src->st_dev,     /* device */
34594 +               .ust_ino     = src->st_ino,     /* inode */
34595 +               .ust_mode    = src->st_mode,    /* protection */
34596 +               .ust_nlink   = src->st_nlink,   /* number of hard links */
34597 +               .ust_uid     = src->st_uid,     /* user ID of owner */
34598 +               .ust_gid     = src->st_gid,     /* group ID of owner */
34599 +               .ust_size    = src->st_size,    /* total size, in bytes */
34600 +               .ust_blksize = src->st_blksize, /* blocksize for filesys I/O */
34601 +               .ust_blocks  = src->st_blocks,  /* number of blocks allocated */
34602 +               .ust_atime   = src->st_atime,   /* time of last access */
34603 +               .ust_mtime   = src->st_mtime,   /* time of last modification */
34604 +               .ust_ctime   = src->st_ctime,   /* time of last change */
34605 +       });
34606 +}
34607 +
34608 +int os_stat_fd(const int fd, struct uml_stat *ubuf)
34609 +{
34610 +       struct stat64 sbuf;
34611 +       int err;
34612 +
34613 +       do {
34614 +               err = fstat64(fd, &sbuf);
34615 +       } while((err < 0) && (errno == EINTR)) ;
34616 +
34617 +       if(err < 0) 
34618 +               return(-errno);
34619 +
34620 +       if(ubuf != NULL)
34621 +               copy_stat(ubuf, &sbuf);
34622 +       return(err);
34623 +}
34624 +
34625 +int os_stat_file(const char *file_name, struct uml_stat *ubuf)
34626 +{
34627 +       struct stat64 sbuf;
34628 +       int err;
34629 +
34630 +       do {
34631 +               err = stat64(file_name, &sbuf);
34632 +       } while((err < 0) && (errno == EINTR)) ;
34633 +
34634 +       if(err < 0) 
34635 +               return(-errno);
34636 +
34637 +       if(ubuf != NULL)
34638 +               copy_stat(ubuf, &sbuf);
34639 +       return(err);
34640 +}
34641 +
34642 +int os_access(const char* file, int mode)
34643 +{
34644 +       int amode, err;
34645 +
34646 +       amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) |
34647 +             (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ;
34648 +
34649 +       err = access(file, amode);
34650 +       if(err < 0)
34651 +               return(-errno);
34652 +
34653 +       return(0);
34654 +}
34655 +
34656 +void os_print_error(int error, const char* str)
34657 +{
34658 +       errno = error < 0 ? -error : error;
34659 +
34660 +       perror(str);
34661 +}
34662 +
34663 +/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
34664 +int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
34665 +{
34666 +       int err;
34667 +
34668 +       err = ioctl(fd, cmd, arg);
34669 +       if(err < 0)
34670 +               return(-errno);
34671 +
34672 +       return(err);
34673 +}
34674 +
34675 +int os_window_size(int fd, int *rows, int *cols)
34676 +{
34677 +       struct winsize size;
34678 +
34679 +       if(ioctl(fd, TIOCGWINSZ, &size) < 0)
34680 +               return(-errno);
34681 +
34682 +       *rows = size.ws_row;
34683 +       *cols = size.ws_col;
34684 +
34685 +       return(0);
34686 +}
34687 +
34688 +int os_new_tty_pgrp(int fd, int pid)
34689 +{
34690 +       if(ioctl(fd, TIOCSCTTY, 0) < 0){
34691 +               printk("TIOCSCTTY failed, errno = %d\n", errno);
34692 +               return(-errno);
34693 +       }
34694 +
34695 +       if(tcsetpgrp(fd, pid) < 0){
34696 +               printk("tcsetpgrp failed, errno = %d\n", errno);
34697 +               return(-errno);
34698 +       }
34699 +
34700 +       return(0);
34701 +}
34702 +
34703 +/* FIXME: ensure namebuf in os_get_if_name is big enough */
34704 +int os_get_ifname(int fd, char* namebuf)
34705 +{
34706 +       if(ioctl(fd, SIOCGIFNAME, namebuf) < 0)
34707 +               return(-errno);
34708 +
34709 +       return(0);
34710 +}
34711 +
34712 +int os_set_slip(int fd)
34713 +{
34714 +       int disc, sencap;
34715 +
34716 +       disc = N_SLIP;
34717 +       if(ioctl(fd, TIOCSETD, &disc) < 0){
34718 +               printk("Failed to set slip line discipline - "
34719 +                      "errno = %d\n", errno);
34720 +               return(-errno);
34721 +       }
34722 +
34723 +       sencap = 0;
34724 +       if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){
34725 +               printk("Failed to set slip encapsulation - "
34726 +                      "errno = %d\n", errno);
34727 +               return(-errno);
34728 +       }
34729 +
34730 +       return(0);
34731 +}
34732 +
34733 +int os_set_owner(int fd, int pid)
34734 +{
34735 +       if(fcntl(fd, F_SETOWN, pid) < 0){
34736 +               int save_errno = errno;
34737 +
34738 +               if(fcntl(fd, F_GETOWN, 0) != pid)
34739 +                       return(-save_errno);
34740 +       }
34741 +
34742 +       return(0);
34743 +}
34744 +
34745 +/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */ 
34746 +int os_sigio_async(int master, int slave)
34747 +{
34748 +       int flags;
34749 +
34750 +       flags = fcntl(master, F_GETFL);
34751 +       if(flags < 0) {
34752 +               printk("fcntl F_GETFL failed, errno = %d\n", errno);
34753 +               return(-errno);
34754 +       }
34755 +
34756 +       if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
34757 +          (fcntl(master, F_SETOWN, os_getpid()) < 0)){
34758 +               printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", errno);
34759 +               return(-errno);
34760 +       }
34761 +
34762 +       if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){
34763 +               printk("fcntl F_SETFL failed, errno = %d\n", errno);
34764 +               return(-errno);
34765 +       }
34766 +
34767 +       return(0);
34768 +}
34769 +
34770 +int os_mode_fd(int fd, int mode)
34771 +{
34772 +       int err;
34773 +
34774 +       do {
34775 +               err = fchmod(fd, mode);
34776 +       } while((err < 0) && (errno==EINTR)) ;
34777 +
34778 +       if(err < 0)
34779 +               return(-errno);
34780 +
34781 +       return(0);
34782 +}
34783 +
34784 +int os_file_type(char *file)
34785 +{
34786 +       struct uml_stat buf;
34787 +       int err;
34788 +
34789 +       err = os_stat_file(file, &buf);
34790 +       if(err < 0)
34791 +               return(err);
34792 +
34793 +       if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR);
34794 +       else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK);
34795 +       else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV);
34796 +       else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV);
34797 +       else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO);
34798 +       else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK);
34799 +       else return(OS_TYPE_FILE);
34800 +}
34801 +
34802 +int os_file_mode(char *file, struct openflags *mode_out)
34803 +{
34804 +       int err;
34805 +
34806 +       *mode_out = OPENFLAGS();
34807 +
34808 +       err = os_access(file, OS_ACC_W_OK);
34809 +       if((err < 0) && (err != -EACCES))
34810 +               return(err);
34811 +
34812 +       *mode_out = of_write(*mode_out);
34813 +
34814 +       err = os_access(file, OS_ACC_R_OK);
34815 +       if((err < 0) && (err != -EACCES))
34816 +               return(err);
34817 +
34818 +       *mode_out = of_read(*mode_out);
34819 +
34820 +       return(0);
34821 +}
34822 +
34823 +int os_open_file(char *file, struct openflags flags, int mode)
34824 +{
34825 +       int fd, f = 0;
34826 +
34827 +       if(flags.r && flags.w) f = O_RDWR;
34828 +       else if(flags.r) f = O_RDONLY;
34829 +       else if(flags.w) f = O_WRONLY;
34830 +       else f = 0;
34831 +
34832 +       if(flags.s) f |= O_SYNC;
34833 +       if(flags.c) f |= O_CREAT;
34834 +       if(flags.t) f |= O_TRUNC;
34835 +       if(flags.e) f |= O_EXCL;
34836 +
34837 +       fd = open64(file, f, mode);
34838 +       if(fd < 0)
34839 +               return(-errno);
34840 +
34841 +       if(flags.cl && fcntl(fd, F_SETFD, 1)){
34842 +               os_close_file(fd);
34843 +               return(-errno);
34844 +       }
34845 +
34846 +       return(fd);
34847 +}
34848 +
34849 +int os_connect_socket(char *name)
34850 +{
34851 +       struct sockaddr_un sock;
34852 +       int fd, err;
34853 +
34854 +       sock.sun_family = AF_UNIX;
34855 +       snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
34856 +
34857 +       fd = socket(AF_UNIX, SOCK_STREAM, 0);
34858 +       if(fd < 0)
34859 +               return(fd);
34860 +
34861 +       err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
34862 +       if(err)
34863 +               return(-errno);
34864 +
34865 +       return(fd);
34866 +}
34867 +
34868 +void os_close_file(int fd)
34869 +{
34870 +       close(fd);
34871 +}
34872 +
34873 +int os_seek_file(int fd, __u64 offset)
34874 +{
34875 +       __u64 actual;
34876 +
34877 +       actual = lseek64(fd, offset, SEEK_SET);
34878 +       if(actual != offset) return(-errno);
34879 +       return(0);
34880 +}
34881 +
34882 +static int fault_buffer(void *start, int len, 
34883 +                       int (*copy_proc)(void *addr, void *buf, int len))
34884 +{
34885 +       int page = getpagesize(), i;
34886 +       char c;
34887 +
34888 +       for(i = 0; i < len; i += page){
34889 +               if((*copy_proc)(start + i, &c, sizeof(c)))
34890 +                       return(-EFAULT);
34891 +       }
34892 +       if((len % page) != 0){
34893 +               if((*copy_proc)(start + len - 1, &c, sizeof(c)))
34894 +                       return(-EFAULT);
34895 +       }
34896 +       return(0);
34897 +}
34898 +
34899 +static int file_io(int fd, void *buf, int len,
34900 +                  int (*io_proc)(int fd, void *buf, int len),
34901 +                  int (*copy_user_proc)(void *addr, void *buf, int len))
34902 +{
34903 +       int n, err;
34904 +
34905 +       do {
34906 +               n = (*io_proc)(fd, buf, len);
34907 +               if((n < 0) && (errno == EFAULT)){
34908 +                       err = fault_buffer(buf, len, copy_user_proc);
34909 +                       if(err)
34910 +                               return(err);
34911 +                       n = (*io_proc)(fd, buf, len);
34912 +               }
34913 +       } while((n < 0) && (errno == EINTR));
34914 +
34915 +       if(n < 0)
34916 +               return(-errno);
34917 +       return(n);
34918 +}
34919 +
34920 +int os_read_file(int fd, void *buf, int len)
34921 +{
34922 +       return(file_io(fd, buf, len, (int (*)(int, void *, int)) read, 
34923 +                      copy_from_user_proc));
34924 +}
34925 +
34926 +int os_write_file(int fd, const void *buf, int len)
34927 +{
34928 +       return(file_io(fd, (void *) buf, len, 
34929 +                      (int (*)(int, void *, int)) write, copy_to_user_proc));
34930 +}
34931 +
34932 +int os_file_size(char *file, long long *size_out)
34933 +{
34934 +       struct uml_stat buf;
34935 +       int err;
34936 +
34937 +       err = os_stat_file(file, &buf);
34938 +       if(err < 0){
34939 +               printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
34940 +               return(err);
34941 +       }
34942 +
34943 +       if(S_ISBLK(buf.ust_mode)){
34944 +               int fd, blocks;
34945 +
34946 +               fd = os_open_file(file, of_read(OPENFLAGS()), 0);
34947 +               if(fd < 0){
34948 +                       printk("Couldn't open \"%s\", errno = %d\n", file, -fd);
34949 +                       return(fd);
34950 +               }
34951 +               if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
34952 +                       printk("Couldn't get the block size of \"%s\", "
34953 +                              "errno = %d\n", file, errno);
34954 +                       err = -errno;
34955 +                       os_close_file(fd);
34956 +                       return(err);
34957 +               }
34958 +               *size_out = ((long long) blocks) * 512;
34959 +               os_close_file(fd);
34960 +               return(0);
34961 +       }
34962 +       *size_out = buf.ust_size;
34963 +       return(0);
34964 +}
34965 +
34966 +int os_file_modtime(char *file, unsigned long *modtime)
34967 +{
34968 +       struct uml_stat buf;
34969 +       int err;
34970 +
34971 +       err = os_stat_file(file, &buf);
34972 +       if(err < 0){
34973 +               printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
34974 +               return(err);
34975 +       }
34976 +
34977 +       *modtime = buf.ust_mtime;
34978 +       return(0);
34979 +}
34980 +
34981 +int os_get_exec_close(int fd, int* close_on_exec)
34982 +{
34983 +       int ret;
34984 +
34985 +       do {
34986 +               ret = fcntl(fd, F_GETFD);
34987 +       } while((ret < 0) && (errno == EINTR)) ;
34988 +
34989 +       if(ret < 0)
34990 +               return(-errno);
34991 +
34992 +       *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0;
34993 +       return(ret);
34994 +}
34995 +
34996 +int os_set_exec_close(int fd, int close_on_exec)
34997 +{
34998 +       int flag, err;
34999 +
35000 +       if(close_on_exec) flag = FD_CLOEXEC;
35001 +       else flag = 0;
35002 +
35003 +       do {
35004 +               err = fcntl(fd, F_SETFD, flag);
35005 +       } while((err < 0) && (errno == EINTR)) ;
35006 +
35007 +       if(err < 0)
35008 +               return(-errno);
35009 +       return(err);
35010 +}
35011 +
35012 +int os_pipe(int *fds, int stream, int close_on_exec)
35013 +{
35014 +       int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
35015 +
35016 +       err = socketpair(AF_UNIX, type, 0, fds);
35017 +       if(err < 0) 
35018 +               return(-errno);
35019 +
35020 +       if(!close_on_exec)
35021 +               return(0);
35022 +
35023 +       err = os_set_exec_close(fds[0], 1);
35024 +       if(err < 0)
35025 +               goto error;
35026 +
35027 +       err = os_set_exec_close(fds[1], 1);
35028 +       if(err < 0)
35029 +               goto error;
35030 +
35031 +       return(0);
35032 +
35033 + error:
35034 +       printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
35035 +       os_close_file(fds[1]);
35036 +       os_close_file(fds[0]);
35037 +       return(err);
35038 +}
35039 +
35040 +int os_set_fd_async(int fd, int owner)
35041 +{
35042 +       /* XXX This should do F_GETFL first */
35043 +       if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){
35044 +               printk("os_set_fd_async : failed to set O_ASYNC and "
35045 +                      "O_NONBLOCK on fd # %d, errno = %d\n", fd, errno);
35046 +               return(-errno);
35047 +       }
35048 +#ifdef notdef
35049 +       if(fcntl(fd, F_SETFD, 1) < 0){
35050 +               printk("os_set_fd_async : Setting FD_CLOEXEC failed, "
35051 +                      "errno = %d\n", errno);
35052 +       }
35053 +#endif
35054 +
35055 +       if((fcntl(fd, F_SETSIG, SIGIO) < 0) ||
35056 +          (fcntl(fd, F_SETOWN, owner) < 0)){
35057 +               printk("os_set_fd_async : Failed to fcntl F_SETOWN "
35058 +                      "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, 
35059 +                      owner, errno);
35060 +               return(-errno);
35061 +       }
35062 +
35063 +       return(0);
35064 +}
35065 +
35066 +int os_set_fd_block(int fd, int blocking)
35067 +{
35068 +       int flags;
35069 +
35070 +       flags = fcntl(fd, F_GETFL);
35071 +
35072 +       if(blocking) flags &= ~O_NONBLOCK;
35073 +       else flags |= O_NONBLOCK;
35074 +
35075 +       if(fcntl(fd, F_SETFL, flags) < 0){
35076 +               printk("Failed to change blocking on fd # %d, errno = %d\n",
35077 +                      fd, errno);
35078 +               return(-errno);
35079 +       }
35080 +       return(0);
35081 +}
35082 +
35083 +int os_accept_connection(int fd)
35084 +{
35085 +       int new;
35086 +
35087 +       new = accept(fd, NULL, 0);
35088 +       if(new < 0) 
35089 +               return(-errno);
35090 +       return(new);
35091 +}
35092 +
35093 +#ifndef SHUT_RD
35094 +#define SHUT_RD 0
35095 +#endif
35096 +
35097 +#ifndef SHUT_WR
35098 +#define SHUT_WR 1
35099 +#endif
35100 +
35101 +#ifndef SHUT_RDWR
35102 +#define SHUT_RDWR 2
35103 +#endif
35104 +
35105 +int os_shutdown_socket(int fd, int r, int w)
35106 +{
35107 +       int what, err;
35108 +
35109 +       if(r && w) what = SHUT_RDWR;
35110 +       else if(r) what = SHUT_RD;
35111 +       else if(w) what = SHUT_WR;
35112 +       else {
35113 +               printk("os_shutdown_socket : neither r or w was set\n");
35114 +               return(-EINVAL);
35115 +       }
35116 +       err = shutdown(fd, what);
35117 +       if(err < 0)
35118 +               return(-errno);
35119 +       return(0);
35120 +}
35121 +
35122 +int os_rcv_fd(int fd, int *helper_pid_out)
35123 +{
35124 +       int new, n;
35125 +       char buf[CMSG_SPACE(sizeof(new))];
35126 +       struct msghdr msg;
35127 +       struct cmsghdr *cmsg;
35128 +       struct iovec iov;
35129 +
35130 +       msg.msg_name = NULL;
35131 +       msg.msg_namelen = 0;
35132 +       iov = ((struct iovec) { .iov_base  = helper_pid_out,
35133 +                               .iov_len   = sizeof(*helper_pid_out) });
35134 +       msg.msg_iov = &iov;
35135 +       msg.msg_iovlen = 1;
35136 +       msg.msg_control = buf;
35137 +       msg.msg_controllen = sizeof(buf);
35138 +       msg.msg_flags = 0;
35139 +
35140 +       n = recvmsg(fd, &msg, 0);
35141 +       if(n < 0)
35142 +               return(-errno);
35143 +
35144 +       else if(n != sizeof(iov.iov_len))
35145 +               *helper_pid_out = -1;
35146 +
35147 +       cmsg = CMSG_FIRSTHDR(&msg);
35148 +       if(cmsg == NULL){
35149 +               printk("rcv_fd didn't receive anything, error = %d\n", errno);
35150 +               return(-1);
35151 +       }
35152 +       if((cmsg->cmsg_level != SOL_SOCKET) || 
35153 +          (cmsg->cmsg_type != SCM_RIGHTS)){
35154 +               printk("rcv_fd didn't receive a descriptor\n");
35155 +               return(-1);
35156 +       }
35157 +
35158 +       new = ((int *) CMSG_DATA(cmsg))[0];
35159 +       return(new);
35160 +}
35161 +
35162 +int os_create_unix_socket(char *file, int len, int close_on_exec)
35163 +{
35164 +       struct sockaddr_un addr;
35165 +       int sock, err;
35166 +
35167 +       sock = socket(PF_UNIX, SOCK_DGRAM, 0);
35168 +       if (sock < 0){
35169 +               printk("create_unix_socket - socket failed, errno = %d\n",
35170 +                      errno);
35171 +               return(-errno);
35172 +       }
35173 +
35174 +       if(close_on_exec) {
35175 +               err = os_set_exec_close(sock, 1);
35176 +               if(err < 0)
35177 +                       printk("create_unix_socket : close_on_exec failed, "
35178 +                      "err = %d", -err);
35179 +       }
35180 +
35181 +       addr.sun_family = AF_UNIX;
35182 +
35183 +       /* XXX Be more careful about overflow */
35184 +       snprintf(addr.sun_path, len, "%s", file);
35185 +
35186 +       err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
35187 +       if (err < 0){
35188 +               printk("create_listening_socket at '%s' - bind failed, "
35189 +                      "errno = %d\n", file, errno);
35190 +               return(-errno);
35191 +       }
35192 +
35193 +       return(sock);
35194 +}
35195 +
35196 +void os_flush_stdout(void)
35197 +{
35198 +       fflush(stdout);
35199 +}
35200 +
35201 +int os_lock_file(int fd, int excl)
35202 +{
35203 +       int type = excl ? F_WRLCK : F_RDLCK;
35204 +       struct flock lock = ((struct flock) { .l_type   = type,
35205 +                                             .l_whence = SEEK_SET,
35206 +                                             .l_start  = 0,
35207 +                                             .l_len    = 0 } );
35208 +       int err, save;
35209 +
35210 +       err = fcntl(fd, F_SETLK, &lock);
35211 +       if(!err)
35212 +               goto out;
35213 +
35214 +       save = -errno;
35215 +       err = fcntl(fd, F_GETLK, &lock);
35216 +       if(err){
35217 +               err = -errno;
35218 +               goto out;
35219 +       }
35220 +
35221 +       printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
35222 +       err = save;
35223 + out:
35224 +       return(err);
35225 +}
35226 +
35227 +/*
35228 + * Overrides for Emacs so that we follow Linus's tabbing style.
35229 + * Emacs will notice this stuff at the end of the file and automatically
35230 + * adjust the settings for this buffer only.  This must remain at the end
35231 + * of the file.
35232 + * ---------------------------------------------------------------------------
35233 + * Local variables:
35234 + * c-file-style: "linux"
35235 + * End:
35236 + */
35237 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/include/file.h um/arch/um/os-Linux/include/file.h
35238 --- orig/arch/um/os-Linux/include/file.h        1969-12-31 19:00:00.000000000 -0500
35239 +++ um/arch/um/os-Linux/include/file.h  2003-10-21 03:26:07.000000000 -0400
35240 @@ -0,0 +1,22 @@
35241 +/* 
35242 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
35243 + * Licensed under the GPL
35244 + */
35245 +
35246 +#ifndef __OS_FILE_H__
35247 +#define __OS_FILE_H__
35248 +
35249 +#define DEV_NULL "/dev/null"
35250 +
35251 +#endif
35252 +
35253 +/*
35254 + * Overrides for Emacs so that we follow Linus's tabbing style.
35255 + * Emacs will notice this stuff at the end of the file and automatically
35256 + * adjust the settings for this buffer only.  This must remain at the end
35257 + * of the file.
35258 + * ---------------------------------------------------------------------------
35259 + * Local variables:
35260 + * c-file-style: "linux"
35261 + * End:
35262 + */
35263 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/Makefile um/arch/um/os-Linux/Makefile
35264 --- orig/arch/um/os-Linux/Makefile      1969-12-31 19:00:00.000000000 -0500
35265 +++ um/arch/um/os-Linux/Makefile        2003-10-21 03:26:07.000000000 -0400
35266 @@ -0,0 +1,17 @@
35267 +# 
35268 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
35269 +# Licensed under the GPL
35270 +#
35271 +
35272 +O_TARGET = built-in.o
35273 +
35274 +obj-y = file.o process.o tty.o
35275 +
35276 +include $(TOPDIR)/Rules.make
35277 +
35278 +$(obj-y) : %.o: %.c
35279 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
35280 +
35281 +clean :
35282 +
35283 +archmrproper:
35284 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/process.c um/arch/um/os-Linux/process.c
35285 --- orig/arch/um/os-Linux/process.c     1969-12-31 19:00:00.000000000 -0500
35286 +++ um/arch/um/os-Linux/process.c       2004-01-10 06:53:44.000000000 -0500
35287 @@ -0,0 +1,148 @@
35288 +/* 
35289 + * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
35290 + * Licensed under the GPL
35291 + */
35292 +
35293 +#include <unistd.h>
35294 +#include <stdio.h>
35295 +#include <errno.h>
35296 +#include <signal.h>
35297 +#include <sys/mman.h>
35298 +#include <sys/wait.h>
35299 +#include "os.h"
35300 +#include "user.h"
35301 +
35302 +#define ARBITRARY_ADDR -1
35303 +#define FAILURE_PID    -1
35304 +
35305 +unsigned long os_process_pc(int pid)
35306 +{
35307 +       char proc_stat[sizeof("/proc/#####/stat\0")], buf[256];
35308 +       unsigned long pc;
35309 +       int fd, err;
35310 +
35311 +       sprintf(proc_stat, "/proc/%d/stat", pid);
35312 +       fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
35313 +       if(fd < 0){
35314 +               printk("os_process_pc - couldn't open '%s', err = %d\n", 
35315 +                      proc_stat, -fd);
35316 +               return(ARBITRARY_ADDR);
35317 +       }
35318 +       err = os_read_file(fd, buf, sizeof(buf));
35319 +       if(err < 0){
35320 +               printk("os_process_pc - couldn't read '%s', err = %d\n", 
35321 +                      proc_stat, -err);
35322 +               os_close_file(fd);
35323 +               return(ARBITRARY_ADDR);
35324 +       }
35325 +       os_close_file(fd);
35326 +       pc = ARBITRARY_ADDR;
35327 +       if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d "
35328 +                 "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
35329 +                 "%*d %*d %*d %*d %ld", &pc) != 1){
35330 +               printk("os_process_pc - couldn't find pc in '%s'\n", buf);
35331 +       }
35332 +       return(pc);
35333 +}
35334 +
35335 +int os_process_parent(int pid)
35336 +{
35337 +       char stat[sizeof("/proc/nnnnn/stat\0")];
35338 +       char data[256];
35339 +       int parent, n, fd;
35340 +
35341 +       if(pid == -1) return(-1);
35342 +
35343 +       snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
35344 +       fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
35345 +       if(fd < 0){
35346 +               printk("Couldn't open '%s', err = %d\n", stat, -fd);
35347 +               return(FAILURE_PID);
35348 +       }
35349 +
35350 +       n = os_read_file(fd, data, sizeof(data));
35351 +       os_close_file(fd);
35352 +
35353 +       if(n < 0){
35354 +               printk("Couldn't read '%s', err = %d\n", stat, -n);
35355 +               return(FAILURE_PID);
35356 +       }
35357 +
35358 +       parent = FAILURE_PID;
35359 +       /* XXX This will break if there is a space in the command */
35360 +       n = sscanf(data, "%*d %*s %*c %d", &parent);
35361 +       if(n != 1) 
35362 +               printk("Failed to scan '%s'\n", data);
35363 +
35364 +       return(parent);
35365 +}
35366 +
35367 +void os_stop_process(int pid)
35368 +{
35369 +       kill(pid, SIGSTOP);
35370 +}
35371 +
35372 +void os_kill_process(int pid, int reap_child)
35373 +{
35374 +       kill(pid, SIGKILL);
35375 +       if(reap_child)
35376 +               waitpid(pid, NULL, 0);
35377 +               
35378 +}
35379 +
35380 +void os_usr1_process(int pid)
35381 +{
35382 +       kill(pid, SIGUSR1);
35383 +}
35384 +
35385 +int os_getpid(void)
35386 +{
35387 +       return(getpid());
35388 +}
35389 +
35390 +int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
35391 +                 int r, int w, int x)
35392 +{
35393 +       void *loc;
35394 +       int prot;
35395 +
35396 +       prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
35397 +               (x ? PROT_EXEC : 0);
35398 +
35399 +       loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 
35400 +                    fd, off);
35401 +       if(loc == MAP_FAILED)
35402 +               return(-errno);
35403 +       return(0);
35404 +}
35405 +
35406 +int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
35407 +{
35408 +        int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
35409 +                   (x ? PROT_EXEC : 0));
35410 +
35411 +        if(mprotect(addr, len, prot) < 0)
35412 +               return(-errno);
35413 +        return(0);
35414 +}
35415 +
35416 +int os_unmap_memory(void *addr, int len)
35417 +{
35418 +        int err;
35419 +
35420 +        err = munmap(addr, len);
35421 +       if(err < 0)
35422 +               return(-errno);
35423 +        return(0);
35424 +}
35425 +
35426 +/*
35427 + * Overrides for Emacs so that we follow Linus's tabbing style.
35428 + * Emacs will notice this stuff at the end of the file and automatically
35429 + * adjust the settings for this buffer only.  This must remain at the end
35430 + * of the file.
35431 + * ---------------------------------------------------------------------------
35432 + * Local variables:
35433 + * c-file-style: "linux"
35434 + * End:
35435 + */
35436 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/tty.c um/arch/um/os-Linux/tty.c
35437 --- orig/arch/um/os-Linux/tty.c 1969-12-31 19:00:00.000000000 -0500
35438 +++ um/arch/um/os-Linux/tty.c   2003-10-21 03:26:07.000000000 -0400
35439 @@ -0,0 +1,61 @@
35440 +/* 
35441 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
35442 + * Licensed under the GPL
35443 + */
35444 +
35445 +#include <stdlib.h>
35446 +#include <errno.h>
35447 +#include "os.h"
35448 +#include "user.h"
35449 +#include "kern_util.h"
35450 +
35451 +struct grantpt_info {
35452 +       int fd;
35453 +       int res;
35454 +       int err;
35455 +};
35456 +
35457 +static void grantpt_cb(void *arg)
35458 +{
35459 +       struct grantpt_info *info = arg;
35460 +
35461 +       info->res = grantpt(info->fd);
35462 +       info->err = errno;
35463 +}
35464 +
35465 +int get_pty(void)
35466 +{
35467 +       struct grantpt_info info;
35468 +       int fd;
35469 +
35470 +       fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0);
35471 +       if(fd < 0){
35472 +               printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd);
35473 +               return(fd);
35474 +       }
35475 +
35476 +       info.fd = fd;
35477 +       initial_thread_cb(grantpt_cb, &info);
35478 +
35479 +       if(info.res < 0){
35480 +               printk("get_pty : Couldn't grant pty - errno = %d\n", 
35481 +                      -info.err);
35482 +               return(-1);
35483 +       }
35484 +       if(unlockpt(fd) < 0){
35485 +               printk("get_pty : Couldn't unlock pty - errno = %d\n", errno);
35486 +               return(-1);
35487 +       }
35488 +       return(fd);
35489 +}
35490 +
35491 +/*
35492 + * Overrides for Emacs so that we follow Linus's tabbing style.
35493 + * Emacs will notice this stuff at the end of the file and automatically
35494 + * adjust the settings for this buffer only.  This must remain at the end
35495 + * of the file.
35496 + * ---------------------------------------------------------------------------
35497 + * Local variables:
35498 + * c-file-style: "linux"
35499 + * End:
35500 + */
35501 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/bugs.c um/arch/um/sys-i386/bugs.c
35502 --- orig/arch/um/sys-i386/bugs.c        1969-12-31 19:00:00.000000000 -0500
35503 +++ um/arch/um/sys-i386/bugs.c  2004-01-21 22:42:39.000000000 -0500
35504 @@ -0,0 +1,222 @@
35505 +/* 
35506 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
35507 + * Licensed under the GPL
35508 + */
35509 +
35510 +#include <unistd.h>
35511 +#include <errno.h>
35512 +#include <string.h>
35513 +#include <sys/signal.h>
35514 +#include <asm/ldt.h>
35515 +#include "kern_util.h"
35516 +#include "user.h"
35517 +#include "sysdep/ptrace.h"
35518 +#include "task.h"
35519 +#include "os.h"
35520 +
35521 +#define MAXTOKEN 64
35522 +
35523 +/* Set during early boot */
35524 +int host_has_cmov = 1;
35525 +int host_has_xmm = 0;
35526 +
35527 +static char token(int fd, char *buf, int len, char stop)
35528 +{
35529 +       int n;
35530 +       char *ptr, *end, c;
35531 +
35532 +       ptr = buf;
35533 +       end = &buf[len];
35534 +       do {
35535 +               n = os_read_file(fd, ptr, sizeof(*ptr));
35536 +               c = *ptr++;
35537 +               if(n != sizeof(*ptr)){
35538 +                       if(n == 0) return(0);
35539 +                       printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
35540 +                       if(n < 0) 
35541 +                               return(n);
35542 +                       else 
35543 +                               return(-EIO);
35544 +               }
35545 +       } while((c != '\n') && (c != stop) && (ptr < end));
35546 +
35547 +       if(ptr == end){
35548 +               printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
35549 +               return(-1);
35550 +       }
35551 +       *(ptr - 1) = '\0';
35552 +       return(c);
35553 +}
35554 +
35555 +static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
35556 +{
35557 +       int n;
35558 +       char c;
35559 +
35560 +       scratch[len - 1] = '\0';
35561 +       while(1){
35562 +               c = token(fd, scratch, len - 1, ':');
35563 +               if(c <= 0)
35564 +                       return(0);
35565 +               else if(c != ':'){
35566 +                       printk("Failed to find ':' in /proc/cpuinfo\n");
35567 +                       return(0);
35568 +               }
35569 +
35570 +               if(!strncmp(scratch, key, strlen(key))) 
35571 +                       return(1);
35572 +
35573 +               do {
35574 +                       n = os_read_file(fd, &c, sizeof(c));
35575 +                       if(n != sizeof(c)){
35576 +                               printk("Failed to find newline in "
35577 +                                      "/proc/cpuinfo, err = %d\n", -n);
35578 +                               return(0);
35579 +                       }
35580 +               } while(c != '\n');
35581 +       }
35582 +       return(0);
35583 +}
35584 +
35585 +int cpu_feature(char *what, char *buf, int len)
35586 +{
35587 +       int fd, ret = 0;
35588 +
35589 +       fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
35590 +       if(fd < 0){
35591 +               printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
35592 +               return(0);
35593 +       }
35594 +
35595 +       if(!find_cpuinfo_line(fd, what, buf, len)){
35596 +               printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
35597 +               goto out_close;
35598 +       }
35599 +
35600 +       token(fd, buf, len, '\n');
35601 +       ret = 1;
35602 +
35603 + out_close:
35604 +       os_close_file(fd);
35605 +       return(ret);
35606 +}
35607 +
35608 +static int check_cpu_flag(char *feature, int *have_it)
35609 +{
35610 +       char buf[MAXTOKEN], c;
35611 +       int fd, len = sizeof(buf)/sizeof(buf[0]);
35612 +
35613 +       printk("Checking for host processor %s support...", feature);
35614 +       fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
35615 +       if(fd < 0){
35616 +               printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
35617 +               return(0);
35618 +       }
35619 +
35620 +       *have_it = 0;
35621 +       if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0])))
35622 +               goto out;
35623 +
35624 +       c = token(fd, buf, len - 1, ' ');
35625 +       if(c < 0) goto out;
35626 +       else if(c != ' '){
35627 +               printk("Failed to find ' ' in /proc/cpuinfo\n");
35628 +               goto out;
35629 +       }
35630 +
35631 +       while(1){
35632 +               c = token(fd, buf, len - 1, ' ');
35633 +               if(c < 0) goto out;
35634 +               else if(c == '\n') break;
35635 +
35636 +               if(!strcmp(buf, feature)){
35637 +                       *have_it = 1;
35638 +                       goto out;
35639 +               }
35640 +       }
35641 + out:
35642 +       if(*have_it == 0) printk("No\n");
35643 +       else if(*have_it == 1) printk("Yes\n");
35644 +       os_close_file(fd);
35645 +       return(1);
35646 +}
35647 +
35648 +#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems
35649 +       * for some people.
35650 +       */
35651 +static void disable_lcall(void)
35652 +{
35653 +       struct modify_ldt_ldt_s ldt;
35654 +       int err;
35655 +
35656 +       bzero(&ldt, sizeof(ldt));
35657 +       ldt.entry_number = 7;
35658 +       ldt.base_addr = 0;
35659 +       ldt.limit = 0;
35660 +       err = modify_ldt(1, &ldt, sizeof(ldt));
35661 +       if(err)
35662 +               printk("Failed to disable lcall7 - errno = %d\n", errno);
35663 +}
35664 +#endif
35665 +
35666 +void arch_init_thread(void)
35667 +{
35668 +#if 0
35669 +       disable_lcall();
35670 +#endif
35671 +}
35672 +
35673 +void arch_check_bugs(void)
35674 +{
35675 +       int have_it;
35676 +
35677 +       if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){
35678 +               printk("/proc/cpuinfo not available - skipping CPU capability "
35679 +                      "checks\n");
35680 +               return;
35681 +       }
35682 +       if(check_cpu_flag("cmov", &have_it)) 
35683 +               host_has_cmov = have_it;
35684 +       if(check_cpu_flag("xmm", &have_it)) 
35685 +               host_has_xmm = have_it;
35686 +}
35687 +
35688 +int arch_handle_signal(int sig, union uml_pt_regs *regs)
35689 +{
35690 +       unsigned char tmp[2];
35691 +
35692 +       /* This is testing for a cmov (0x0f 0x4x) instruction causing a
35693 +        * SIGILL in init.
35694 +        */
35695 +       if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0);
35696 +
35697 +       if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2))
35698 +               panic("SIGILL in init, could not read instructions!\n");
35699 +       if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
35700 +               return(0);
35701 +
35702 +       if(host_has_cmov == 0)
35703 +               panic("SIGILL caused by cmov, which this processor doesn't "
35704 +                     "implement, boot a filesystem compiled for older "
35705 +                     "processors");
35706 +       else if(host_has_cmov == 1)
35707 +               panic("SIGILL caused by cmov, which this processor claims to "
35708 +                     "implement");
35709 +       else if(host_has_cmov == -1)
35710 +               panic("SIGILL caused by cmov, couldn't tell if this processor "
35711 +                     "implements it, boot a filesystem compiled for older "
35712 +                     "processors");
35713 +       else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
35714 +       return(0);
35715 +}
35716 +
35717 +/*
35718 + * Overrides for Emacs so that we follow Linus's tabbing style.
35719 + * Emacs will notice this stuff at the end of the file and automatically
35720 + * adjust the settings for this buffer only.  This must remain at the end
35721 + * of the file.
35722 + * ---------------------------------------------------------------------------
35723 + * Local variables:
35724 + * c-file-style: "linux"
35725 + * End:
35726 + */
35727 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/checksum.S um/arch/um/sys-i386/checksum.S
35728 --- orig/arch/um/sys-i386/checksum.S    1969-12-31 19:00:00.000000000 -0500
35729 +++ um/arch/um/sys-i386/checksum.S      2003-10-21 03:26:07.000000000 -0400
35730 @@ -0,0 +1,460 @@
35731 +/*
35732 + * INET                An implementation of the TCP/IP protocol suite for the LINUX
35733 + *             operating system.  INET is implemented using the  BSD Socket
35734 + *             interface as the means of communication with the user level.
35735 + *
35736 + *             IP/TCP/UDP checksumming routines
35737 + *
35738 + * Authors:    Jorge Cwik, <jorge@laser.satlink.net>
35739 + *             Arnt Gulbrandsen, <agulbra@nvg.unit.no>
35740 + *             Tom May, <ftom@netcom.com>
35741 + *              Pentium Pro/II routines:
35742 + *              Alexander Kjeldaas <astor@guardian.no>
35743 + *              Finn Arne Gangstad <finnag@guardian.no>
35744 + *             Lots of code moved from tcp.c and ip.c; see those files
35745 + *             for more names.
35746 + *
35747 + * Changes:     Ingo Molnar, converted csum_partial_copy() to 2.1 exception
35748 + *                          handling.
35749 + *             Andi Kleen,  add zeroing on error
35750 + *                   converted to pure assembler
35751 + *
35752 + *             This program is free software; you can redistribute it and/or
35753 + *             modify it under the terms of the GNU General Public License
35754 + *             as published by the Free Software Foundation; either version
35755 + *             2 of the License, or (at your option) any later version.
35756 + */
35757 +
35758 +#include <linux/config.h>
35759 +#include <asm/errno.h>
35760 +                               
35761 +/*
35762 + * computes a partial checksum, e.g. for TCP/UDP fragments
35763 + */
35764 +
35765 +/*     
35766 +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
35767 + */
35768 +               
35769 +.text
35770 +.align 4
35771 +.globl arch_csum_partial                                                               
35772 +               
35773 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
35774 +
35775 +         /*            
35776 +          * Experiments with Ethernet and SLIP connections show that buff
35777 +          * is aligned on either a 2-byte or 4-byte boundary.  We get at
35778 +          * least a twofold speedup on 486 and Pentium if it is 4-byte aligned.
35779 +          * Fortunately, it is easy to convert 2-byte alignment to 4-byte
35780 +          * alignment for the unrolled loop.
35781 +          */           
35782 +arch_csum_partial:     
35783 +       pushl %esi
35784 +       pushl %ebx
35785 +       movl 20(%esp),%eax      # Function arg: unsigned int sum
35786 +       movl 16(%esp),%ecx      # Function arg: int len
35787 +       movl 12(%esp),%esi      # Function arg: unsigned char *buff
35788 +       testl $2, %esi          # Check alignment.
35789 +       jz 2f                   # Jump if alignment is ok.
35790 +       subl $2, %ecx           # Alignment uses up two bytes.
35791 +       jae 1f                  # Jump if we had at least two bytes.
35792 +       addl $2, %ecx           # ecx was < 2.  Deal with it.
35793 +       jmp 4f
35794 +1:     movw (%esi), %bx
35795 +       addl $2, %esi
35796 +       addw %bx, %ax
35797 +       adcl $0, %eax
35798 +2:
35799 +       movl %ecx, %edx
35800 +       shrl $5, %ecx
35801 +       jz 2f
35802 +       testl %esi, %esi
35803 +1:     movl (%esi), %ebx
35804 +       adcl %ebx, %eax
35805 +       movl 4(%esi), %ebx
35806 +       adcl %ebx, %eax
35807 +       movl 8(%esi), %ebx
35808 +       adcl %ebx, %eax
35809 +       movl 12(%esi), %ebx
35810 +       adcl %ebx, %eax
35811 +       movl 16(%esi), %ebx
35812 +       adcl %ebx, %eax
35813 +       movl 20(%esi), %ebx
35814 +       adcl %ebx, %eax
35815 +       movl 24(%esi), %ebx
35816 +       adcl %ebx, %eax
35817 +       movl 28(%esi), %ebx
35818 +       adcl %ebx, %eax
35819 +       lea 32(%esi), %esi
35820 +       dec %ecx
35821 +       jne 1b
35822 +       adcl $0, %eax
35823 +2:     movl %edx, %ecx
35824 +       andl $0x1c, %edx
35825 +       je 4f
35826 +       shrl $2, %edx           # This clears CF
35827 +3:     adcl (%esi), %eax
35828 +       lea 4(%esi), %esi
35829 +       dec %edx
35830 +       jne 3b
35831 +       adcl $0, %eax
35832 +4:     andl $3, %ecx
35833 +       jz 7f
35834 +       cmpl $2, %ecx
35835 +       jb 5f
35836 +       movw (%esi),%cx
35837 +       leal 2(%esi),%esi
35838 +       je 6f
35839 +       shll $16,%ecx
35840 +5:     movb (%esi),%cl
35841 +6:     addl %ecx,%eax
35842 +       adcl $0, %eax 
35843 +7:     
35844 +       popl %ebx
35845 +       popl %esi
35846 +       ret
35847 +
35848 +#else
35849 +
35850 +/* Version for PentiumII/PPro */
35851 +
35852 +arch_csum_partial:
35853 +       pushl %esi
35854 +       pushl %ebx
35855 +       movl 20(%esp),%eax      # Function arg: unsigned int sum
35856 +       movl 16(%esp),%ecx      # Function arg: int len
35857 +       movl 12(%esp),%esi      # Function arg: const unsigned char *buf
35858 +
35859 +       testl $2, %esi         
35860 +       jnz 30f                 
35861 +10:
35862 +       movl %ecx, %edx
35863 +       movl %ecx, %ebx
35864 +       andl $0x7c, %ebx
35865 +       shrl $7, %ecx
35866 +       addl %ebx,%esi
35867 +       shrl $2, %ebx  
35868 +       negl %ebx
35869 +       lea 45f(%ebx,%ebx,2), %ebx
35870 +       testl %esi, %esi
35871 +       jmp *%ebx
35872 +
35873 +       # Handle 2-byte-aligned regions
35874 +20:    addw (%esi), %ax
35875 +       lea 2(%esi), %esi
35876 +       adcl $0, %eax
35877 +       jmp 10b
35878 +
35879 +30:    subl $2, %ecx          
35880 +       ja 20b                 
35881 +       je 32f
35882 +       movzbl (%esi),%ebx      # csumming 1 byte, 2-aligned
35883 +       addl %ebx, %eax
35884 +       adcl $0, %eax
35885 +       jmp 80f
35886 +32:
35887 +       addw (%esi), %ax        # csumming 2 bytes, 2-aligned
35888 +       adcl $0, %eax
35889 +       jmp 80f
35890 +
35891 +40: 
35892 +       addl -128(%esi), %eax
35893 +       adcl -124(%esi), %eax
35894 +       adcl -120(%esi), %eax
35895 +       adcl -116(%esi), %eax   
35896 +       adcl -112(%esi), %eax   
35897 +       adcl -108(%esi), %eax
35898 +       adcl -104(%esi), %eax
35899 +       adcl -100(%esi), %eax
35900 +       adcl -96(%esi), %eax
35901 +       adcl -92(%esi), %eax
35902 +       adcl -88(%esi), %eax
35903 +       adcl -84(%esi), %eax
35904 +       adcl -80(%esi), %eax
35905 +       adcl -76(%esi), %eax
35906 +       adcl -72(%esi), %eax
35907 +       adcl -68(%esi), %eax
35908 +       adcl -64(%esi), %eax     
35909 +       adcl -60(%esi), %eax     
35910 +       adcl -56(%esi), %eax     
35911 +       adcl -52(%esi), %eax   
35912 +       adcl -48(%esi), %eax   
35913 +       adcl -44(%esi), %eax
35914 +       adcl -40(%esi), %eax
35915 +       adcl -36(%esi), %eax
35916 +       adcl -32(%esi), %eax
35917 +       adcl -28(%esi), %eax
35918 +       adcl -24(%esi), %eax
35919 +       adcl -20(%esi), %eax
35920 +       adcl -16(%esi), %eax
35921 +       adcl -12(%esi), %eax
35922 +       adcl -8(%esi), %eax
35923 +       adcl -4(%esi), %eax
35924 +45:
35925 +       lea 128(%esi), %esi
35926 +       adcl $0, %eax
35927 +       dec %ecx
35928 +       jge 40b
35929 +       movl %edx, %ecx
35930 +50:    andl $3, %ecx
35931 +       jz 80f
35932 +
35933 +       # Handle the last 1-3 bytes without jumping
35934 +       notl %ecx               # 1->2, 2->1, 3->0, higher bits are masked
35935 +       movl $0xffffff,%ebx     # by the shll and shrl instructions
35936 +       shll $3,%ecx
35937 +       shrl %cl,%ebx
35938 +       andl -128(%esi),%ebx    # esi is 4-aligned so should be ok
35939 +       addl %ebx,%eax
35940 +       adcl $0,%eax
35941 +80: 
35942 +       popl %ebx
35943 +       popl %esi
35944 +       ret
35945 +                               
35946 +#endif
35947 +
35948 +/*
35949 +unsigned int csum_partial_copy_generic (const char *src, char *dst,
35950 +                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr)
35951 + */ 
35952 +
35953 +/*
35954 + * Copy from ds while checksumming, otherwise like csum_partial
35955 + *
35956 + * The macros SRC and DST specify the type of access for the instruction.
35957 + * thus we can call a custom exception handler for all access types.
35958 + *
35959 + * FIXME: could someone double-check whether I haven't mixed up some SRC and
35960 + *       DST definitions? It's damn hard to trigger all cases.  I hope I got
35961 + *       them all but there's no guarantee.
35962 + */
35963 +
35964 +#define SRC(y...)                      \
35965 +       9999: y;                        \
35966 +       .section __ex_table, "a";       \
35967 +       .long 9999b, 6001f      ;       \
35968 +       .previous
35969 +
35970 +#define DST(y...)                      \
35971 +       9999: y;                        \
35972 +       .section __ex_table, "a";       \
35973 +       .long 9999b, 6002f      ;       \
35974 +       .previous
35975 +
35976 +.align 4
35977 +.globl csum_partial_copy_generic_i386
35978 +                               
35979 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
35980 +
35981 +#define ARGBASE 16             
35982 +#define FP             12
35983 +               
35984 +csum_partial_copy_generic_i386:
35985 +       subl  $4,%esp   
35986 +       pushl %edi
35987 +       pushl %esi
35988 +       pushl %ebx
35989 +       movl ARGBASE+16(%esp),%eax      # sum
35990 +       movl ARGBASE+12(%esp),%ecx      # len
35991 +       movl ARGBASE+4(%esp),%esi       # src
35992 +       movl ARGBASE+8(%esp),%edi       # dst
35993 +
35994 +       testl $2, %edi                  # Check alignment. 
35995 +       jz 2f                           # Jump if alignment is ok.
35996 +       subl $2, %ecx                   # Alignment uses up two bytes.
35997 +       jae 1f                          # Jump if we had at least two bytes.
35998 +       addl $2, %ecx                   # ecx was < 2.  Deal with it.
35999 +       jmp 4f
36000 +SRC(1: movw (%esi), %bx        )
36001 +       addl $2, %esi
36002 +DST(   movw %bx, (%edi)        )
36003 +       addl $2, %edi
36004 +       addw %bx, %ax   
36005 +       adcl $0, %eax
36006 +2:
36007 +       movl %ecx, FP(%esp)
36008 +       shrl $5, %ecx
36009 +       jz 2f
36010 +       testl %esi, %esi
36011 +SRC(1: movl (%esi), %ebx       )
36012 +SRC(   movl 4(%esi), %edx      )
36013 +       adcl %ebx, %eax
36014 +DST(   movl %ebx, (%edi)       )
36015 +       adcl %edx, %eax
36016 +DST(   movl %edx, 4(%edi)      )
36017 +
36018 +SRC(   movl 8(%esi), %ebx      )
36019 +SRC(   movl 12(%esi), %edx     )
36020 +       adcl %ebx, %eax
36021 +DST(   movl %ebx, 8(%edi)      )
36022 +       adcl %edx, %eax
36023 +DST(   movl %edx, 12(%edi)     )
36024 +
36025 +SRC(   movl 16(%esi), %ebx     )
36026 +SRC(   movl 20(%esi), %edx     )
36027 +       adcl %ebx, %eax
36028 +DST(   movl %ebx, 16(%edi)     )
36029 +       adcl %edx, %eax
36030 +DST(   movl %edx, 20(%edi)     )
36031 +
36032 +SRC(   movl 24(%esi), %ebx     )
36033 +SRC(   movl 28(%esi), %edx     )
36034 +       adcl %ebx, %eax
36035 +DST(   movl %ebx, 24(%edi)     )
36036 +       adcl %edx, %eax
36037 +DST(   movl %edx, 28(%edi)     )
36038 +
36039 +       lea 32(%esi), %esi
36040 +       lea 32(%edi), %edi
36041 +       dec %ecx
36042 +       jne 1b
36043 +       adcl $0, %eax
36044 +2:     movl FP(%esp), %edx
36045 +       movl %edx, %ecx
36046 +       andl $0x1c, %edx
36047 +       je 4f
36048 +       shrl $2, %edx                   # This clears CF
36049 +SRC(3: movl (%esi), %ebx       )
36050 +       adcl %ebx, %eax
36051 +DST(   movl %ebx, (%edi)       )
36052 +       lea 4(%esi), %esi
36053 +       lea 4(%edi), %edi
36054 +       dec %edx
36055 +       jne 3b
36056 +       adcl $0, %eax
36057 +4:     andl $3, %ecx
36058 +       jz 7f
36059 +       cmpl $2, %ecx
36060 +       jb 5f
36061 +SRC(   movw (%esi), %cx        )
36062 +       leal 2(%esi), %esi
36063 +DST(   movw %cx, (%edi)        )
36064 +       leal 2(%edi), %edi
36065 +       je 6f
36066 +       shll $16,%ecx
36067 +SRC(5: movb (%esi), %cl        )
36068 +DST(   movb %cl, (%edi)        )
36069 +6:     addl %ecx, %eax
36070 +       adcl $0, %eax
36071 +7:
36072 +5000:
36073 +
36074 +# Exception handler:
36075 +.section .fixup, "ax"                                                  
36076 +
36077 +6001:
36078 +       movl ARGBASE+20(%esp), %ebx     # src_err_ptr
36079 +       movl $-EFAULT, (%ebx)
36080 +
36081 +       # zero the complete destination - computing the rest
36082 +       # is too much work 
36083 +       movl ARGBASE+8(%esp), %edi      # dst
36084 +       movl ARGBASE+12(%esp), %ecx     # len
36085 +       xorl %eax,%eax
36086 +       rep ; stosb
36087 +
36088 +       jmp 5000b
36089 +
36090 +6002:
36091 +       movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
36092 +       movl $-EFAULT,(%ebx)
36093 +       jmp 5000b
36094 +
36095 +.previous
36096 +
36097 +       popl %ebx
36098 +       popl %esi
36099 +       popl %edi
36100 +       popl %ecx                       # equivalent to addl $4,%esp
36101 +       ret     
36102 +
36103 +#else
36104 +
36105 +/* Version for PentiumII/PPro */
36106 +
36107 +#define ROUND1(x) \
36108 +       SRC(movl x(%esi), %ebx  )       ;       \
36109 +       addl %ebx, %eax                 ;       \
36110 +       DST(movl %ebx, x(%edi)  )       ; 
36111 +
36112 +#define ROUND(x) \
36113 +       SRC(movl x(%esi), %ebx  )       ;       \
36114 +       adcl %ebx, %eax                 ;       \
36115 +       DST(movl %ebx, x(%edi)  )       ;
36116 +
36117 +#define ARGBASE 12
36118 +               
36119 +csum_partial_copy_generic_i386:
36120 +       pushl %ebx
36121 +       pushl %edi
36122 +       pushl %esi
36123 +       movl ARGBASE+4(%esp),%esi       #src
36124 +       movl ARGBASE+8(%esp),%edi       #dst    
36125 +       movl ARGBASE+12(%esp),%ecx      #len
36126 +       movl ARGBASE+16(%esp),%eax      #sum
36127 +#      movl %ecx, %edx  
36128 +       movl %ecx, %ebx  
36129 +       movl %esi, %edx
36130 +       shrl $6, %ecx     
36131 +       andl $0x3c, %ebx  
36132 +       negl %ebx
36133 +       subl %ebx, %esi  
36134 +       subl %ebx, %edi  
36135 +       lea  -1(%esi),%edx
36136 +       andl $-32,%edx
36137 +       lea 3f(%ebx,%ebx), %ebx
36138 +       testl %esi, %esi 
36139 +       jmp *%ebx
36140 +1:     addl $64,%esi
36141 +       addl $64,%edi 
36142 +       SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl)
36143 +       ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52)    
36144 +       ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36)    
36145 +       ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20)    
36146 +       ROUND (-16) ROUND(-12) ROUND(-8)  ROUND(-4)     
36147 +3:     adcl $0,%eax
36148 +       addl $64, %edx
36149 +       dec %ecx
36150 +       jge 1b
36151 +4:     movl ARGBASE+12(%esp),%edx      #len
36152 +       andl $3, %edx
36153 +       jz 7f
36154 +       cmpl $2, %edx
36155 +       jb 5f
36156 +SRC(   movw (%esi), %dx         )
36157 +       leal 2(%esi), %esi
36158 +DST(   movw %dx, (%edi)         )
36159 +       leal 2(%edi), %edi
36160 +       je 6f
36161 +       shll $16,%edx
36162 +5:
36163 +SRC(   movb (%esi), %dl         )
36164 +DST(   movb %dl, (%edi)         )
36165 +6:     addl %edx, %eax
36166 +       adcl $0, %eax
36167 +7:
36168 +.section .fixup, "ax"
36169 +6001:  movl    ARGBASE+20(%esp), %ebx  # src_err_ptr   
36170 +       movl $-EFAULT, (%ebx)
36171 +       # zero the complete destination (computing the rest is too much work)
36172 +       movl ARGBASE+8(%esp),%edi       # dst
36173 +       movl ARGBASE+12(%esp),%ecx      # len
36174 +       xorl %eax,%eax
36175 +       rep; stosb
36176 +       jmp 7b
36177 +6002:  movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
36178 +       movl $-EFAULT, (%ebx)
36179 +       jmp  7b                 
36180 +.previous                              
36181 +
36182 +       popl %esi
36183 +       popl %edi
36184 +       popl %ebx
36185 +       ret
36186 +                               
36187 +#undef ROUND
36188 +#undef ROUND1          
36189 +               
36190 +#endif
36191 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/fault.c um/arch/um/sys-i386/fault.c
36192 --- orig/arch/um/sys-i386/fault.c       1969-12-31 19:00:00.000000000 -0500
36193 +++ um/arch/um/sys-i386/fault.c 2003-10-21 03:26:07.000000000 -0400
36194 @@ -0,0 +1,34 @@
36195 +/* 
36196 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36197 + * Licensed under the GPL
36198 + */
36199 +
36200 +#include <signal.h>
36201 +#include "sysdep/ptrace.h"
36202 +#include "sysdep/sigcontext.h"
36203 +
36204 +extern unsigned long search_exception_table(unsigned long addr);
36205 +
36206 +int arch_fixup(unsigned long address, void *sc_ptr)
36207 +{
36208 +       struct sigcontext *sc = sc_ptr;
36209 +       unsigned long fixup;
36210 +
36211 +       fixup = search_exception_table(address);
36212 +       if(fixup != 0){
36213 +               sc->eip = fixup;
36214 +               return(1);
36215 +       }
36216 +       return(0);
36217 +}
36218 +
36219 +/*
36220 + * Overrides for Emacs so that we follow Linus's tabbing style.
36221 + * Emacs will notice this stuff at the end of the file and automatically
36222 + * adjust the settings for this buffer only.  This must remain at the end
36223 + * of the file.
36224 + * ---------------------------------------------------------------------------
36225 + * Local variables:
36226 + * c-file-style: "linux"
36227 + * End:
36228 + */
36229 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ksyms.c um/arch/um/sys-i386/ksyms.c
36230 --- orig/arch/um/sys-i386/ksyms.c       1969-12-31 19:00:00.000000000 -0500
36231 +++ um/arch/um/sys-i386/ksyms.c 2003-10-21 03:26:07.000000000 -0400
36232 @@ -0,0 +1,17 @@
36233 +#include "linux/module.h"
36234 +#include "linux/in6.h"
36235 +#include "linux/rwsem.h"
36236 +#include "asm/byteorder.h"
36237 +#include "asm/semaphore.h"
36238 +#include "asm/uaccess.h"
36239 +#include "asm/checksum.h"
36240 +#include "asm/errno.h"
36241 +
36242 +EXPORT_SYMBOL(__down_failed);
36243 +EXPORT_SYMBOL(__down_failed_interruptible);
36244 +EXPORT_SYMBOL(__down_failed_trylock);
36245 +EXPORT_SYMBOL(__up_wakeup);
36246 +
36247 +/* Networking helper routines. */
36248 +EXPORT_SYMBOL(csum_partial_copy_from);
36249 +EXPORT_SYMBOL(csum_partial_copy_to);
36250 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ldt.c um/arch/um/sys-i386/ldt.c
36251 --- orig/arch/um/sys-i386/ldt.c 1969-12-31 19:00:00.000000000 -0500
36252 +++ um/arch/um/sys-i386/ldt.c   2004-01-19 04:01:11.000000000 -0500
36253 @@ -0,0 +1,94 @@
36254 +/*
36255 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
36256 + * Licensed under the GPL
36257 + */
36258 +
36259 +#include "linux/config.h"
36260 +#include "linux/slab.h"
36261 +#include "asm/uaccess.h"
36262 +#include "asm/ptrace.h"
36263 +#include "choose-mode.h"
36264 +#include "kern.h"
36265 +
36266 +#ifdef CONFIG_MODE_TT
36267 +extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
36268 +
36269 +/* XXX this needs copy_to_user and copy_from_user */
36270 +
36271 +int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
36272 +{
36273 +       if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT);
36274 +       return(modify_ldt(func, ptr, bytecount));
36275 +}
36276 +#endif
36277 +
36278 +#ifdef CONFIG_MODE_SKAS
36279 +extern int userspace_pid;
36280 +
36281 +int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
36282 +{
36283 +       struct ptrace_ldt ldt;
36284 +       void *buf;
36285 +       int res, n;
36286 +
36287 +       buf = kmalloc(bytecount, GFP_KERNEL);
36288 +       if(buf == NULL)
36289 +               return(-ENOMEM);
36290 +
36291 +       res = 0;
36292 +
36293 +       switch(func){
36294 +       case 1:
36295 +       case 0x11:
36296 +               res = copy_from_user(buf, ptr, bytecount);
36297 +               break;
36298 +       }
36299 +
36300 +       if(res != 0){
36301 +               res = -EFAULT;
36302 +               goto out;
36303 +       }
36304 +
36305 +       ldt = ((struct ptrace_ldt) { .func      = func,
36306 +                                    .ptr       = buf,
36307 +                                    .bytecount = bytecount });
36308 +       res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt);
36309 +       if(res < 0)
36310 +               goto out;
36311 +
36312 +       switch(func){
36313 +       case 0:
36314 +       case 2:
36315 +               n = res;
36316 +               res = copy_to_user(ptr, buf, n);
36317 +               if(res != 0)
36318 +                       res = -EFAULT;
36319 +               else 
36320 +                       res = n;
36321 +               break;
36322 +       }
36323 +
36324 + out:
36325 +       kfree(buf);
36326 +       return(res);
36327 +}
36328 +#endif
36329 +
36330 +int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
36331 +{
36332 +       return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func, 
36333 +                               ptr, bytecount));
36334 +}
36335 +
36336 +
36337 +
36338 +/*
36339 + * Overrides for Emacs so that we follow Linus's tabbing style.
36340 + * Emacs will notice this stuff at the end of the file and automatically
36341 + * adjust the settings for this buffer only.  This must remain at the end
36342 + * of the file.
36343 + * ---------------------------------------------------------------------------
36344 + * Local variables:
36345 + * c-file-style: "linux"
36346 + * End:
36347 + */
36348 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/Makefile um/arch/um/sys-i386/Makefile
36349 --- orig/arch/um/sys-i386/Makefile      1969-12-31 19:00:00.000000000 -0500
36350 +++ um/arch/um/sys-i386/Makefile        2003-11-09 11:55:24.000000000 -0500
36351 @@ -0,0 +1,46 @@
36352 +# 
36353 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36354 +# Licensed under the GPL
36355 +#
36356 +
36357 +O_TARGET = built-in.o
36358 +
36359 +obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \
36360 +       ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o time.o
36361 +export-objs = ksyms.o
36362 +
36363 +USER_OBJS = bugs.o ptrace_user.o sigcontext.o fault.o
36364 +
36365 +SYMLINKS = semaphore.c extable.c
36366 +
36367 +semaphore.c-dir = kernel
36368 +extable.c-dir = mm
36369 +
36370 +include $(TOPDIR)/Rules.make
36371 +
36372 +$(USER_OBJS) : %.o: %.c
36373 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
36374 +
36375 +define make_link
36376 +       -rm -f $1
36377 +       ln -sf $(TOPDIR)/arch/i386/$($1-dir)/$1 $1
36378 +endef
36379 +
36380 +$(SYMLINKS): 
36381 +       $(call make_link,$@)
36382 +
36383 +clean:
36384 +       $(MAKE) -C util clean
36385 +       rm -f $(SYMLINKS)
36386 +
36387 +fastdep:
36388 +
36389 +dep:
36390 +
36391 +archmrproper:
36392 +
36393 +archclean:
36394 +
36395 +archdep:
36396 +
36397 +modules:
36398 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace.c um/arch/um/sys-i386/ptrace.c
36399 --- orig/arch/um/sys-i386/ptrace.c      1969-12-31 19:00:00.000000000 -0500
36400 +++ um/arch/um/sys-i386/ptrace.c        2003-10-21 03:26:07.000000000 -0400
36401 @@ -0,0 +1,365 @@
36402 +/* 
36403 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
36404 + * Licensed under the GPL
36405 + */
36406 +
36407 +#include "linux/sched.h"
36408 +#include "asm/elf.h"
36409 +#include "asm/ptrace.h"
36410 +#include "asm/uaccess.h"
36411 +#include "ptrace_user.h"
36412 +#include "sysdep/sigcontext.h"
36413 +#include "sysdep/sc.h"
36414 +
36415 +void arch_switch(void)
36416 +{
36417 +       update_debugregs(current->thread.arch.debugregs_seq);
36418 +}
36419 +
36420 +int is_syscall(unsigned long addr)
36421 +{
36422 +       unsigned short instr;
36423 +       int n;
36424 +
36425 +       n = copy_from_user(&instr, (void *) addr, sizeof(instr));
36426 +       if(n){
36427 +               printk("is_syscall : failed to read instruction from 0x%lu\n", 
36428 +                      addr);
36429 +               return(0);
36430 +       }
36431 +       return(instr == 0x80cd);
36432 +}
36433 +
36434 +/* determines which flags the user has access to. */
36435 +/* 1 = access 0 = no access */
36436 +#define FLAG_MASK 0x00044dd5
36437 +
36438 +int putreg(struct task_struct *child, int regno, unsigned long value)
36439 +{
36440 +       regno >>= 2;
36441 +       switch (regno) {
36442 +       case FS:
36443 +               if (value && (value & 3) != 3)
36444 +                       return -EIO;
36445 +               PT_REGS_FS(&child->thread.regs) = value;
36446 +               return 0;
36447 +       case GS:
36448 +               if (value && (value & 3) != 3)
36449 +                       return -EIO;
36450 +               PT_REGS_GS(&child->thread.regs) = value;
36451 +               return 0;
36452 +       case DS:
36453 +       case ES:
36454 +               if (value && (value & 3) != 3)
36455 +                       return -EIO;
36456 +               value &= 0xffff;
36457 +               break;
36458 +       case SS:
36459 +       case CS:
36460 +               if ((value & 3) != 3)
36461 +                       return -EIO;
36462 +               value &= 0xffff;
36463 +               break;
36464 +       case EFL:
36465 +               value &= FLAG_MASK;
36466 +               value |= PT_REGS_EFLAGS(&child->thread.regs);
36467 +               break;
36468 +       }
36469 +       PT_REGS_SET(&child->thread.regs, regno, value);
36470 +       return 0;
36471 +}
36472 +
36473 +unsigned long getreg(struct task_struct *child, int regno)
36474 +{
36475 +       unsigned long retval = ~0UL;
36476 +
36477 +       regno >>= 2;
36478 +       switch (regno) {
36479 +       case FS:
36480 +       case GS:
36481 +       case DS:
36482 +       case ES:
36483 +       case SS:
36484 +       case CS:
36485 +               retval = 0xffff;
36486 +               /* fall through */
36487 +       default:
36488 +               retval &= PT_REG(&child->thread.regs, regno);
36489 +       }
36490 +       return retval;
36491 +}
36492 +
36493 +struct i387_fxsave_struct {
36494 +       unsigned short  cwd;
36495 +       unsigned short  swd;
36496 +       unsigned short  twd;
36497 +       unsigned short  fop;
36498 +       long    fip;
36499 +       long    fcs;
36500 +       long    foo;
36501 +       long    fos;
36502 +       long    mxcsr;
36503 +       long    reserved;
36504 +       long    st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
36505 +       long    xmm_space[32];  /* 8*16 bytes for each XMM-reg = 128 bytes */
36506 +       long    padding[56];
36507 +};
36508 +
36509 +/*
36510 + * FPU tag word conversions.
36511 + */
36512 +
36513 +static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
36514 +{
36515 +       unsigned int tmp; /* to avoid 16 bit prefixes in the code */
36516
36517 +       /* Transform each pair of bits into 01 (valid) or 00 (empty) */
36518 +        tmp = ~twd;
36519 +        tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
36520 +        /* and move the valid bits to the lower byte. */
36521 +        tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
36522 +        tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
36523 +        tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
36524 +        return tmp;
36525 +}
36526 +
36527 +static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
36528 +{
36529 +       struct _fpxreg *st = NULL;
36530 +       unsigned long twd = (unsigned long) fxsave->twd;
36531 +       unsigned long tag;
36532 +       unsigned long ret = 0xffff0000;
36533 +       int i;
36534 +
36535 +#define FPREG_ADDR(f, n)       ((char *)&(f)->st_space + (n) * 16);
36536 +
36537 +       for ( i = 0 ; i < 8 ; i++ ) {
36538 +               if ( twd & 0x1 ) {
36539 +                       st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
36540 +
36541 +                       switch ( st->exponent & 0x7fff ) {
36542 +                       case 0x7fff:
36543 +                               tag = 2;                /* Special */
36544 +                               break;
36545 +                       case 0x0000:
36546 +                               if ( !st->significand[0] &&
36547 +                                    !st->significand[1] &&
36548 +                                    !st->significand[2] &&
36549 +                                    !st->significand[3] ) {
36550 +                                       tag = 1;        /* Zero */
36551 +                               } else {
36552 +                                       tag = 2;        /* Special */
36553 +                               }
36554 +                               break;
36555 +                       default:
36556 +                               if ( st->significand[3] & 0x8000 ) {
36557 +                                       tag = 0;        /* Valid */
36558 +                               } else {
36559 +                                       tag = 2;        /* Special */
36560 +                               }
36561 +                               break;
36562 +                       }
36563 +               } else {
36564 +                       tag = 3;                        /* Empty */
36565 +               }
36566 +               ret |= (tag << (2 * i));
36567 +               twd = twd >> 1;
36568 +       }
36569 +       return ret;
36570 +}
36571 +
36572 +/*
36573 + * FXSR floating point environment conversions.
36574 + */
36575 +
36576 +#ifdef CONFIG_MODE_TT
36577 +static inline int convert_fxsr_to_user_tt(struct _fpstate *buf, 
36578 +                                         struct pt_regs *regs)
36579 +{
36580 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
36581 +       unsigned long env[7];
36582 +       struct _fpreg *to;
36583 +       struct _fpxreg *from;
36584 +       int i;
36585 +
36586 +       env[0] = (unsigned long)fxsave->cwd | 0xffff0000;
36587 +       env[1] = (unsigned long)fxsave->swd | 0xffff0000;
36588 +       env[2] = twd_fxsr_to_i387(fxsave);
36589 +       env[3] = fxsave->fip;
36590 +       env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
36591 +       env[5] = fxsave->foo;
36592 +       env[6] = fxsave->fos;
36593 +
36594 +       if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
36595 +               return 1;
36596 +
36597 +       to = &buf->_st[0];
36598 +       from = (struct _fpxreg *) &fxsave->st_space[0];
36599 +       for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
36600 +               if ( __copy_to_user( to, from, sizeof(*to) ) )
36601 +                       return 1;
36602 +       }
36603 +       return 0;
36604 +}
36605 +#endif
36606 +
36607 +static inline int convert_fxsr_to_user(struct _fpstate *buf, 
36608 +                                      struct pt_regs *regs)
36609 +{
36610 +       return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0));
36611 +}
36612 +
36613 +#ifdef CONFIG_MODE_TT
36614 +static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
36615 +                                           struct _fpstate *buf)
36616 +{
36617 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
36618 +       unsigned long env[7];
36619 +       struct _fpxreg *to;
36620 +       struct _fpreg *from;
36621 +       int i;
36622 +
36623 +       if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
36624 +               return 1;
36625 +
36626 +       fxsave->cwd = (unsigned short)(env[0] & 0xffff);
36627 +       fxsave->swd = (unsigned short)(env[1] & 0xffff);
36628 +       fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
36629 +       fxsave->fip = env[3];
36630 +       fxsave->fop = (unsigned short)((env[4] & 0xffff0000) >> 16);
36631 +       fxsave->fcs = (env[4] & 0xffff);
36632 +       fxsave->foo = env[5];
36633 +       fxsave->fos = env[6];
36634 +
36635 +       to = (struct _fpxreg *) &fxsave->st_space[0];
36636 +       from = &buf->_st[0];
36637 +       for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
36638 +               if ( __copy_from_user( to, from, sizeof(*from) ) )
36639 +                       return 1;
36640 +       }
36641 +       return 0;
36642 +}
36643 +#endif
36644 +
36645 +static inline int convert_fxsr_from_user(struct pt_regs *regs, 
36646 +                                        struct _fpstate *buf)
36647 +{
36648 +       return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0));
36649 +}
36650 +
36651 +int get_fpregs(unsigned long buf, struct task_struct *child)
36652 +{
36653 +       int err;
36654 +
36655 +       err = convert_fxsr_to_user((struct _fpstate *) buf, 
36656 +                                  &child->thread.regs);
36657 +       if(err) return(-EFAULT);
36658 +       else return(0);
36659 +}
36660 +
36661 +int set_fpregs(unsigned long buf, struct task_struct *child)
36662 +{
36663 +       int err;
36664 +
36665 +       err = convert_fxsr_from_user(&child->thread.regs, 
36666 +                                    (struct _fpstate *) buf);
36667 +       if(err) return(-EFAULT);
36668 +       else return(0);
36669 +}
36670 +
36671 +#ifdef CONFIG_MODE_TT
36672 +int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
36673 +{
36674 +       struct pt_regs *regs = &tsk->thread.regs;
36675 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
36676 +       int err;
36677 +
36678 +       err = __copy_to_user((void *) buf, fxsave,
36679 +                            sizeof(struct user_fxsr_struct));
36680 +       if(err) return -EFAULT;
36681 +       else return 0;
36682 +}
36683 +#endif
36684 +
36685 +int get_fpxregs(unsigned long buf, struct task_struct *tsk)
36686 +{
36687 +       return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0));
36688 +}
36689 +
36690 +#ifdef CONFIG_MODE_TT
36691 +int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
36692 +{
36693 +       struct pt_regs *regs = &tsk->thread.regs;
36694 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
36695 +       int err;
36696 +
36697 +       err = __copy_from_user(fxsave, (void *) buf,
36698 +                              sizeof(struct user_fxsr_struct) );
36699 +       if(err) return -EFAULT;
36700 +       else return 0;
36701 +}
36702 +#endif
36703 +
36704 +int set_fpxregs(unsigned long buf, struct task_struct *tsk)
36705 +{
36706 +       return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0));
36707 +}
36708 +
36709 +#ifdef notdef
36710 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
36711 +{
36712 +       fpu->cwd = (((SC_FP_CW(PT_REGS_SC(regs)) & 0xffff) << 16) |
36713 +                   (SC_FP_SW(PT_REGS_SC(regs)) & 0xffff));
36714 +       fpu->swd = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
36715 +       fpu->twd = SC_FP_IPOFF(PT_REGS_SC(regs));
36716 +       fpu->fip = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
36717 +       fpu->fcs = SC_FP_DATAOFF(PT_REGS_SC(regs));
36718 +       fpu->foo = SC_FP_DATASEL(PT_REGS_SC(regs));
36719 +       fpu->fos = 0;
36720 +       memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)),
36721 +              sizeof(fpu->st_space));
36722 +       return(1);
36723 +}
36724 +#endif
36725 +
36726 +#ifdef CONFIG_MODE_TT
36727 +static inline void copy_fpu_fxsave_tt(struct pt_regs *regs,
36728 +                                     struct user_i387_struct *buf)
36729 +{
36730 +       struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs));
36731 +       unsigned short *to;
36732 +       unsigned short *from;
36733 +       int i;
36734 +
36735 +       memcpy( buf, fpu, 7 * sizeof(long) );
36736 +
36737 +       to = (unsigned short *) &buf->st_space[0];
36738 +       from = (unsigned short *) &fpu->st_space[0];
36739 +       for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) {
36740 +               memcpy( to, from, 5 * sizeof(unsigned short) );
36741 +       }
36742 +}
36743 +#endif
36744 +
36745 +static inline void copy_fpu_fxsave(struct pt_regs *regs,
36746 +                                  struct user_i387_struct *buf)
36747 +{
36748 +       (void) CHOOSE_MODE(copy_fpu_fxsave_tt(regs, buf), 0);
36749 +}
36750 +
36751 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
36752 +{
36753 +       copy_fpu_fxsave(regs, (struct user_i387_struct *) fpu);
36754 +       return(1);
36755 +}
36756 +
36757 +/*
36758 + * Overrides for Emacs so that we follow Linus's tabbing style.
36759 + * Emacs will notice this stuff at the end of the file and automatically
36760 + * adjust the settings for this buffer only.  This must remain at the end
36761 + * of the file.
36762 + * ---------------------------------------------------------------------------
36763 + * Local variables:
36764 + * c-file-style: "linux"
36765 + * End:
36766 + */
36767 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace_user.c um/arch/um/sys-i386/ptrace_user.c
36768 --- orig/arch/um/sys-i386/ptrace_user.c 1969-12-31 19:00:00.000000000 -0500
36769 +++ um/arch/um/sys-i386/ptrace_user.c   2003-12-17 01:33:17.000000000 -0500
36770 @@ -0,0 +1,117 @@
36771 +/* 
36772 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36773 + * Licensed under the GPL
36774 + */
36775 +
36776 +#include <stdio.h>
36777 +#include <errno.h>
36778 +#include <unistd.h>
36779 +#include <linux/stddef.h>
36780 +#include <sys/ptrace.h>
36781 +#include <asm/ptrace.h>
36782 +#include <asm/user.h>
36783 +#include "kern_util.h"
36784 +#include "sysdep/thread.h"
36785 +#include "user.h"
36786 +#include "os.h"
36787 +
36788 +int ptrace_getregs(long pid, unsigned long *regs_out)
36789 +{
36790 +       return(ptrace(PTRACE_GETREGS, pid, 0, regs_out));
36791 +}
36792 +
36793 +int ptrace_setregs(long pid, unsigned long *regs)
36794 +{
36795 +       return(ptrace(PTRACE_SETREGS, pid, 0, regs));
36796 +}
36797 +
36798 +int ptrace_getfpregs(long pid, unsigned long *regs)
36799 +{
36800 +       return(ptrace(PTRACE_GETFPREGS, pid, 0, regs));
36801 +}
36802 +
36803 +static void write_debugregs(int pid, unsigned long *regs)
36804 +{
36805 +       struct user *dummy;
36806 +       int nregs, i;
36807 +
36808 +       dummy = NULL;
36809 +       nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
36810 +       for(i = 0; i < nregs; i++){
36811 +               if((i == 4) || (i == 5)) continue;
36812 +               if(ptrace(PTRACE_POKEUSER, pid, &dummy->u_debugreg[i],
36813 +                         regs[i]) < 0)
36814 +                       printk("write_debugregs - ptrace failed on "
36815 +                              "register %d, errno = %d\n", errno);
36816 +       }
36817 +}
36818 +
36819 +static void read_debugregs(int pid, unsigned long *regs)
36820 +{
36821 +       struct user *dummy;
36822 +       int nregs, i;
36823 +
36824 +       dummy = NULL;
36825 +       nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
36826 +       for(i = 0; i < nregs; i++){
36827 +               regs[i] = ptrace(PTRACE_PEEKUSER, pid, 
36828 +                                &dummy->u_debugreg[i], 0);
36829 +       }
36830 +}
36831 +
36832 +/* Accessed only by the tracing thread */
36833 +static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
36834 +static int debugregs_seq = 0;
36835 +
36836 +void arch_enter_kernel(void *task, int pid)
36837 +{
36838 +       read_debugregs(pid, TASK_DEBUGREGS(task));
36839 +       write_debugregs(pid, kernel_debugregs);
36840 +}
36841 +
36842 +void arch_leave_kernel(void *task, int pid)
36843 +{
36844 +       read_debugregs(pid, kernel_debugregs);
36845 +       write_debugregs(pid, TASK_DEBUGREGS(task));
36846 +}
36847 +
36848 +void ptrace_pokeuser(unsigned long addr, unsigned long data)
36849 +{
36850 +       if((addr < offsetof(struct user, u_debugreg[0])) ||
36851 +          (addr > offsetof(struct user, u_debugreg[7])))
36852 +               return;
36853 +       addr -= offsetof(struct user, u_debugreg[0]);
36854 +       addr = addr >> 2;
36855 +       if(kernel_debugregs[addr] == data) return;
36856 +
36857 +       kernel_debugregs[addr] = data;
36858 +       debugregs_seq++;
36859 +}
36860 +
36861 +static void update_debugregs_cb(void *arg)
36862 +{
36863 +       int pid = *((int *) arg);
36864 +
36865 +       write_debugregs(pid, kernel_debugregs);
36866 +}
36867 +
36868 +void update_debugregs(int seq)
36869 +{
36870 +       int me;
36871 +
36872 +       if(seq == debugregs_seq) return;
36873 +
36874 +       me = os_getpid();
36875 +       initial_thread_cb(update_debugregs_cb, &me);
36876 +}
36877 +
36878 +/*
36879 + * Overrides for Emacs so that we follow Linus's tabbing style.
36880 + * Emacs will notice this stuff at the end of the file and automatically
36881 + * adjust the settings for this buffer only.  This must remain at the end
36882 + * of the file.
36883 + * ---------------------------------------------------------------------------
36884 + * Local variables:
36885 + * c-file-style: "linux"
36886 + * End:
36887 + */
36888 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sigcontext.c um/arch/um/sys-i386/sigcontext.c
36889 --- orig/arch/um/sys-i386/sigcontext.c  1969-12-31 19:00:00.000000000 -0500
36890 +++ um/arch/um/sys-i386/sigcontext.c    2003-10-21 03:26:07.000000000 -0400
36891 @@ -0,0 +1,80 @@
36892 +/* 
36893 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
36894 + * Licensed under the GPL
36895 + */
36896 +
36897 +#include <stddef.h>
36898 +#include <string.h>
36899 +#include <asm/ptrace.h>
36900 +#include <asm/sigcontext.h>
36901 +#include "sysdep/ptrace.h"
36902 +#include "kern_util.h"
36903 +#include "frame_user.h"
36904 +
36905 +int sc_size(void *data)
36906 +{
36907 +       struct arch_frame_data *arch = data;
36908 +
36909 +       return(sizeof(struct sigcontext) + arch->fpstate_size);
36910 +}
36911 +
36912 +void sc_to_sc(void *to_ptr, void *from_ptr)
36913 +{
36914 +       struct sigcontext *to = to_ptr, *from = from_ptr;
36915 +       int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size;
36916 +
36917 +       memcpy(to, from, size);
36918 +       if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1);
36919 +}
36920 +
36921 +unsigned long *sc_sigmask(void *sc_ptr)
36922 +{
36923 +       struct sigcontext *sc = sc_ptr;
36924 +
36925 +       return(&sc->oldmask);
36926 +}
36927 +
36928 +int sc_get_fpregs(unsigned long buf, void *sc_ptr)
36929 +{
36930 +       struct sigcontext *sc = sc_ptr;
36931 +       struct _fpstate *from = sc->fpstate, *to = (struct _fpstate *) buf;
36932 +       int err = 0;
36933 +
36934 +       if(from == NULL){
36935 +               err |= clear_user_proc(&to->cw, sizeof(to->cw));
36936 +               err |= clear_user_proc(&to->sw, sizeof(to->sw));
36937 +               err |= clear_user_proc(&to->tag, sizeof(to->tag));
36938 +               err |= clear_user_proc(&to->ipoff, sizeof(to->ipoff));
36939 +               err |= clear_user_proc(&to->cssel, sizeof(to->cssel));
36940 +               err |= clear_user_proc(&to->dataoff, sizeof(to->dataoff));
36941 +               err |= clear_user_proc(&to->datasel, sizeof(to->datasel));
36942 +               err |= clear_user_proc(&to->_st, sizeof(to->_st));
36943 +       }
36944 +       else {
36945 +               err |= copy_to_user_proc(&to->cw, &from->cw, sizeof(to->cw));
36946 +               err |= copy_to_user_proc(&to->sw, &from->sw, sizeof(to->sw));
36947 +               err |= copy_to_user_proc(&to->tag, &from->tag, 
36948 +                                        sizeof(to->tag));
36949 +               err |= copy_to_user_proc(&to->ipoff, &from->ipoff, 
36950 +                                        sizeof(to->ipoff));
36951 +               err |= copy_to_user_proc(&to->cssel,& from->cssel, 
36952 +                                        sizeof(to->cssel));
36953 +               err |= copy_to_user_proc(&to->dataoff, &from->dataoff, 
36954 +                                   sizeof(to->dataoff));
36955 +               err |= copy_to_user_proc(&to->datasel, &from->datasel, 
36956 +                                   sizeof(to->datasel));
36957 +               err |= copy_to_user_proc(to->_st, from->_st, sizeof(to->_st));
36958 +       }
36959 +       return(err);
36960 +}
36961 +
36962 +/*
36963 + * Overrides for Emacs so that we follow Linus's tabbing style.
36964 + * Emacs will notice this stuff at the end of the file and automatically
36965 + * adjust the settings for this buffer only.  This must remain at the end
36966 + * of the file.
36967 + * ---------------------------------------------------------------------------
36968 + * Local variables:
36969 + * c-file-style: "linux"
36970 + * End:
36971 + */
36972 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/syscalls.c um/arch/um/sys-i386/syscalls.c
36973 --- orig/arch/um/sys-i386/syscalls.c    1969-12-31 19:00:00.000000000 -0500
36974 +++ um/arch/um/sys-i386/syscalls.c      2003-10-21 03:26:07.000000000 -0400
36975 @@ -0,0 +1,68 @@
36976 +/* 
36977 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
36978 + * Licensed under the GPL
36979 + */
36980 +
36981 +#include "asm/mman.h"
36982 +#include "asm/uaccess.h"
36983 +#include "asm/unistd.h"
36984 +
36985 +/*
36986 + * Perform the select(nd, in, out, ex, tv) and mmap() system
36987 + * calls. Linux/i386 didn't use to be able to handle more than
36988 + * 4 system call parameters, so these system calls used a memory
36989 + * block for parameter passing..
36990 + */
36991 +
36992 +struct mmap_arg_struct {
36993 +       unsigned long addr;
36994 +       unsigned long len;
36995 +       unsigned long prot;
36996 +       unsigned long flags;
36997 +       unsigned long fd;
36998 +       unsigned long offset;
36999 +};
37000 +
37001 +extern int old_mmap(unsigned long addr, unsigned long len,
37002 +                   unsigned long prot, unsigned long flags,
37003 +                   unsigned long fd, unsigned long offset);
37004 +
37005 +int old_mmap_i386(struct mmap_arg_struct *arg)
37006 +{
37007 +       struct mmap_arg_struct a;
37008 +       int err = -EFAULT;
37009 +
37010 +       if (copy_from_user(&a, arg, sizeof(a)))
37011 +               goto out;
37012 +
37013 +       err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
37014 + out:
37015 +       return err;
37016 +}
37017 +
37018 +struct sel_arg_struct {
37019 +       unsigned long n;
37020 +       fd_set *inp, *outp, *exp;
37021 +       struct timeval *tvp;
37022 +};
37023 +
37024 +int old_select(struct sel_arg_struct *arg)
37025 +{
37026 +       struct sel_arg_struct a;
37027 +
37028 +       if (copy_from_user(&a, arg, sizeof(a)))
37029 +               return -EFAULT;
37030 +       /* sys_select() does the appropriate kernel locking */
37031 +       return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
37032 +}
37033 +
37034 +/*
37035 + * Overrides for Emacs so that we follow Linus's tabbing style.
37036 + * Emacs will notice this stuff at the end of the file and automatically
37037 + * adjust the settings for this buffer only.  This must remain at the end
37038 + * of the file.
37039 + * ---------------------------------------------------------------------------
37040 + * Local variables:
37041 + * c-file-style: "linux"
37042 + * End:
37043 + */
37044 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sysrq.c um/arch/um/sys-i386/sysrq.c
37045 --- orig/arch/um/sys-i386/sysrq.c       1969-12-31 19:00:00.000000000 -0500
37046 +++ um/arch/um/sys-i386/sysrq.c 2003-10-21 03:26:07.000000000 -0400
37047 @@ -0,0 +1,30 @@
37048 +#include "linux/kernel.h"
37049 +#include "linux/smp.h"
37050 +#include "linux/sched.h"
37051 +#include "asm/ptrace.h"
37052 +#include "sysrq.h"
37053 +
37054 +void show_regs(struct pt_regs *regs)
37055 +{
37056 +        printk("\n");
37057 +        printk("EIP: %04lx:[<%08lx>] CPU: %d %s", 
37058 +              0xffff & PT_REGS_CS(regs), PT_REGS_IP(regs),
37059 +              smp_processor_id(), print_tainted());
37060 +        if (PT_REGS_CS(regs) & 3)
37061 +                printk(" ESP: %04lx:%08lx", 0xffff & PT_REGS_SS(regs),
37062 +                      PT_REGS_SP(regs));
37063 +        printk(" EFLAGS: %08lx\n    %s\n", PT_REGS_EFLAGS(regs),
37064 +              print_tainted());
37065 +        printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
37066 +                PT_REGS_EAX(regs), PT_REGS_EBX(regs), 
37067 +              PT_REGS_ECX(regs), 
37068 +              PT_REGS_EDX(regs));
37069 +        printk("ESI: %08lx EDI: %08lx EBP: %08lx",
37070 +              PT_REGS_ESI(regs), PT_REGS_EDI(regs), 
37071 +              PT_REGS_EBP(regs));
37072 +        printk(" DS: %04lx ES: %04lx\n",
37073 +              0xffff & PT_REGS_DS(regs), 
37074 +              0xffff & PT_REGS_ES(regs));
37075 +
37076 +        show_trace((unsigned long *) &regs);
37077 +}
37078 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/time.c um/arch/um/sys-i386/time.c
37079 --- orig/arch/um/sys-i386/time.c        1969-12-31 19:00:00.000000000 -0500
37080 +++ um/arch/um/sys-i386/time.c  2003-11-10 01:46:49.000000000 -0500
37081 @@ -0,0 +1,24 @@
37082 +/*
37083 + * sys-i386/time.c 
37084 + * Created             25.9.2002       Sapan Bhatia
37085 + *
37086 + */
37087 +
37088 +unsigned long long time_stamp(void)
37089 +{
37090 +       unsigned long low, high;
37091 +
37092 +       asm("rdtsc" : "=a" (low), "=d" (high));
37093 +       return((((unsigned long long) high) << 32) + low);
37094 +}
37095 +
37096 +/*
37097 + * Overrides for Emacs so that we follow Linus's tabbing style.
37098 + * Emacs will notice this stuff at the end of the file and automatically
37099 + * adjust the settings for this buffer only.  This must remain at the end
37100 + * of the file.
37101 + * ---------------------------------------------------------------------------
37102 + * Local variables:
37103 + * c-file-style: "linux"
37104 + * End:
37105 + */
37106 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/Makefile um/arch/um/sys-i386/util/Makefile
37107 --- orig/arch/um/sys-i386/util/Makefile 1969-12-31 19:00:00.000000000 -0500
37108 +++ um/arch/um/sys-i386/util/Makefile   2003-11-08 08:26:40.000000000 -0500
37109 @@ -0,0 +1,28 @@
37110 +EXE = mk_sc mk_thread
37111 +
37112 +include $(TOPDIR)/Rules.make
37113 +
37114 +all : $(EXE)
37115 +
37116 +mk_sc : mk_sc.o
37117 +       $(HOSTCC) -o mk_sc mk_sc.o
37118 +
37119 +mk_sc.o : mk_sc.c
37120 +       $(HOSTCC) -c $< 
37121 +
37122 +mk_thread : mk_thread_user.o mk_thread_kern.o
37123 +       $(HOSTCC) -o mk_thread mk_thread_user.o mk_thread_kern.o
37124 +
37125 +mk_thread_user.o : mk_thread_user.c
37126 +       $(HOSTCC) -c $< 
37127 +
37128 +mk_thread_kern.o : mk_thread_kern.c
37129 +       $(HOSTCC) $(CFLAGS) -c $< 
37130 +
37131 +clean :
37132 +       $(RM) $(EXE) *.o
37133 +
37134 +archmrproper : clean
37135 +
37136 +fastdep :
37137 +
37138 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/mk_sc.c um/arch/um/sys-i386/util/mk_sc.c
37139 --- orig/arch/um/sys-i386/util/mk_sc.c  1969-12-31 19:00:00.000000000 -0500
37140 +++ um/arch/um/sys-i386/util/mk_sc.c    2003-10-21 03:26:07.000000000 -0400
37141 @@ -0,0 +1,52 @@
37142 +#include <stdio.h>
37143 +#include <signal.h>
37144 +#include <linux/stddef.h>
37145 +
37146 +#define SC_OFFSET(name, field) \
37147 +  printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
37148 +        offsetof(struct sigcontext, field))
37149 +
37150 +#define SC_FP_OFFSET(name, field) \
37151 +  printf("#define " name \
37152 +        "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
37153 +        offsetof(struct _fpstate, field))
37154 +
37155 +#define SC_FP_OFFSET_PTR(name, field, type) \
37156 +  printf("#define " name \
37157 +        "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
37158 +        offsetof(struct _fpstate, field))
37159 +
37160 +int main(int argc, char **argv)
37161 +{
37162 +  SC_OFFSET("SC_IP", eip);
37163 +  SC_OFFSET("SC_SP", esp);
37164 +  SC_OFFSET("SC_FS", fs);
37165 +  SC_OFFSET("SC_GS", gs);
37166 +  SC_OFFSET("SC_DS", ds);
37167 +  SC_OFFSET("SC_ES", es);
37168 +  SC_OFFSET("SC_SS", ss);
37169 +  SC_OFFSET("SC_CS", cs);
37170 +  SC_OFFSET("SC_EFLAGS", eflags);
37171 +  SC_OFFSET("SC_EAX", eax);
37172 +  SC_OFFSET("SC_EBX", ebx);
37173 +  SC_OFFSET("SC_ECX", ecx);
37174 +  SC_OFFSET("SC_EDX", edx);
37175 +  SC_OFFSET("SC_EDI", edi);
37176 +  SC_OFFSET("SC_ESI", esi);
37177 +  SC_OFFSET("SC_EBP", ebp);
37178 +  SC_OFFSET("SC_TRAPNO", trapno);
37179 +  SC_OFFSET("SC_ERR", err);
37180 +  SC_OFFSET("SC_CR2", cr2);
37181 +  SC_OFFSET("SC_FPSTATE", fpstate);
37182 +  SC_OFFSET("SC_SIGMASK", oldmask);
37183 +  SC_FP_OFFSET("SC_FP_CW", cw);
37184 +  SC_FP_OFFSET("SC_FP_SW", sw);
37185 +  SC_FP_OFFSET("SC_FP_TAG", tag);
37186 +  SC_FP_OFFSET("SC_FP_IPOFF", ipoff);
37187 +  SC_FP_OFFSET("SC_FP_CSSEL", cssel);
37188 +  SC_FP_OFFSET("SC_FP_DATAOFF", dataoff);
37189 +  SC_FP_OFFSET("SC_FP_DATASEL", datasel);
37190 +  SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate");
37191 +  SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void");
37192 +  return(0);
37193 +}
37194 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
37195 --- orig/arch/um/sys-i386/util/mk_thread_kern.c 1969-12-31 19:00:00.000000000 -0500
37196 +++ um/arch/um/sys-i386/util/mk_thread_kern.c   2003-10-21 03:26:07.000000000 -0400
37197 @@ -0,0 +1,22 @@
37198 +#include "linux/config.h"
37199 +#include "linux/stddef.h"
37200 +#include "linux/sched.h"
37201 +
37202 +extern void print_head(void);
37203 +extern void print_constant_ptr(char *name, int value);
37204 +extern void print_constant(char *name, char *type, int value);
37205 +extern void print_tail(void);
37206 +
37207 +#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
37208 +
37209 +int main(int argc, char **argv)
37210 +{
37211 +  print_head();
37212 +  print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs));
37213 +#ifdef CONFIG_MODE_TT
37214 +  print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
37215 +#endif
37216 +  print_tail();
37217 +  return(0);
37218 +}
37219 +
37220 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
37221 --- orig/arch/um/sys-i386/util/mk_thread_user.c 1969-12-31 19:00:00.000000000 -0500
37222 +++ um/arch/um/sys-i386/util/mk_thread_user.c   2003-10-21 03:26:07.000000000 -0400
37223 @@ -0,0 +1,30 @@
37224 +#include <stdio.h>
37225 +
37226 +void print_head(void)
37227 +{
37228 +  printf("/*\n");
37229 +  printf(" * Generated by mk_thread\n");
37230 +  printf(" */\n");
37231 +  printf("\n");
37232 +  printf("#ifndef __UM_THREAD_H\n");
37233 +  printf("#define __UM_THREAD_H\n");
37234 +  printf("\n");
37235 +}
37236 +
37237 +void print_constant_ptr(char *name, int value)
37238 +{
37239 +  printf("#define %s(task) ((unsigned long *) "
37240 +        "&(((char *) (task))[%d]))\n", name, value);
37241 +}
37242 +
37243 +void print_constant(char *name, char *type, int value)
37244 +{
37245 +  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, 
37246 +        value);
37247 +}
37248 +
37249 +void print_tail(void)
37250 +{
37251 +  printf("\n");
37252 +  printf("#endif\n");
37253 +}
37254 diff -Naur -X ../exclude-files orig/arch/um/sys-ia64/Makefile um/arch/um/sys-ia64/Makefile
37255 --- orig/arch/um/sys-ia64/Makefile      1969-12-31 19:00:00.000000000 -0500
37256 +++ um/arch/um/sys-ia64/Makefile        2003-10-21 03:26:07.000000000 -0400
37257 @@ -0,0 +1,26 @@
37258 +OBJ = sys.o
37259 +
37260 +OBJS =
37261 +
37262 +all: $(OBJ)
37263 +
37264 +$(OBJ): $(OBJS)
37265 +       rm -f $@
37266 +       $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
37267 +clean:
37268 +       rm -f $(OBJS)
37269 +
37270 +fastdep:
37271 +
37272 +archmrproper:
37273 +
37274 +archclean:
37275 +       rm -f link.ld
37276 +       @$(MAKEBOOT) clean
37277 +
37278 +archdep:
37279 +       @$(MAKEBOOT) dep
37280 +
37281 +modules:
37282 +
37283 +include $(TOPDIR)/Rules.make
37284 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/Makefile um/arch/um/sys-ppc/Makefile
37285 --- orig/arch/um/sys-ppc/Makefile       1969-12-31 19:00:00.000000000 -0500
37286 +++ um/arch/um/sys-ppc/Makefile 2003-10-21 03:26:07.000000000 -0400
37287 @@ -0,0 +1,80 @@
37288 +OBJ = sys.o
37289 +
37290 +.S.o:
37291 +       $(CC) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
37292 +
37293 +OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \
37294 +       ptrace_user.o sysrq.o
37295 +
37296 +EXTRA_AFLAGS := -DCONFIG_ALL_PPC -I. -I$(TOPDIR)/arch/ppc/kernel
37297 +
37298 +all: $(OBJ)
37299 +
37300 +$(OBJ): $(OBJS)
37301 +       rm -f $@
37302 +       $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
37303 +
37304 +ptrace_user.o: ptrace_user.c
37305 +       $(CC) -D__KERNEL__ $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
37306 +
37307 +sigcontext.o: sigcontext.c
37308 +       $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
37309 +
37310 +semaphore.c:
37311 +       rm -f $@
37312 +       ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
37313 +
37314 +checksum.S:
37315 +       rm -f $@
37316 +       ln -s $(TOPDIR)/arch/ppc/lib/$@ $@
37317 +
37318 +mk_defs.c:
37319 +       rm -f $@
37320 +       ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
37321 +
37322 +ppc_defs.head:
37323 +       rm -f $@
37324 +       ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
37325 +
37326 +ppc_defs.h: mk_defs.c ppc_defs.head \
37327 +               $(TOPDIR)/include/asm-ppc/mmu.h \
37328 +               $(TOPDIR)/include/asm-ppc/processor.h \
37329 +               $(TOPDIR)/include/asm-ppc/pgtable.h \
37330 +               $(TOPDIR)/include/asm-ppc/ptrace.h
37331 +#      $(CC) $(CFLAGS) -S mk_defs.c
37332 +       cp ppc_defs.head ppc_defs.h
37333 +# for bk, this way we can write to the file even if it's not checked out
37334 +       echo '#define THREAD 608' >> ppc_defs.h
37335 +       echo '#define PT_REGS 8' >> ppc_defs.h
37336 +       echo '#define CLONE_VM 256' >> ppc_defs.h
37337 +#      chmod u+w ppc_defs.h
37338 +#      grep '^#define' mk_defs.s >> ppc_defs.h
37339 +#      rm mk_defs.s
37340 +
37341 +# the asm link is horrible, and breaks the other targets.  This is also
37342 +# not going to work with parallel makes.
37343 +
37344 +checksum.o: checksum.S
37345 +       rm -f asm
37346 +       ln -s $(TOPDIR)/include/asm-ppc asm
37347 +       $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
37348 +       rm -f asm
37349 +
37350 +misc.o: misc.S ppc_defs.h
37351 +       rm -f asm
37352 +       ln -s $(TOPDIR)/include/asm-ppc asm
37353 +       $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
37354 +       rm -f asm
37355 +
37356 +clean:
37357 +       rm -f $(OBJS)
37358 +       rm -f ppc_defs.h
37359 +       rm -f checksum.S semaphore.c mk_defs.c
37360 +
37361 +fastdep:
37362 +
37363 +dep:
37364 +
37365 +modules:
37366 +
37367 +include $(TOPDIR)/Rules.make
37368 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/misc.S um/arch/um/sys-ppc/misc.S
37369 --- orig/arch/um/sys-ppc/misc.S 1969-12-31 19:00:00.000000000 -0500
37370 +++ um/arch/um/sys-ppc/misc.S   2003-10-21 03:26:07.000000000 -0400
37371 @@ -0,0 +1,116 @@
37372 +/*
37373 + * This file contains miscellaneous low-level functions.
37374 + *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
37375 + *
37376 + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
37377 + * and Paul Mackerras.
37378 + *
37379 + * A couple of functions stolen from arch/ppc/kernel/misc.S for UML
37380 + * by Chris Emerson.
37381 + *
37382 + * This program is free software; you can redistribute it and/or
37383 + * modify it under the terms of the GNU General Public License
37384 + * as published by the Free Software Foundation; either version
37385 + * 2 of the License, or (at your option) any later version.
37386 + *
37387 + */
37388 +
37389 +#include <linux/config.h>
37390 +#include <asm/processor.h>
37391 +#include "ppc_asm.h"
37392 +
37393 +#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
37394 +#define CACHE_LINE_SIZE                16
37395 +#define LG_CACHE_LINE_SIZE     4
37396 +#define MAX_COPY_PREFETCH      1
37397 +#elif !defined(CONFIG_PPC64BRIDGE)
37398 +#define CACHE_LINE_SIZE                32
37399 +#define LG_CACHE_LINE_SIZE     5
37400 +#define MAX_COPY_PREFETCH      4
37401 +#else
37402 +#define CACHE_LINE_SIZE                128
37403 +#define LG_CACHE_LINE_SIZE     7
37404 +#define MAX_COPY_PREFETCH      1
37405 +#endif /* CONFIG_4xx || CONFIG_8xx */
37406 +
37407 +       .text
37408 +
37409 +/*
37410 + * Clear a page using the dcbz instruction, which doesn't cause any
37411 + * memory traffic (except to write out any cache lines which get
37412 + * displaced).  This only works on cacheable memory.
37413 + */
37414 +_GLOBAL(clear_page)
37415 +       li      r0,4096/CACHE_LINE_SIZE
37416 +       mtctr   r0
37417 +#ifdef CONFIG_8xx
37418 +       li      r4, 0
37419 +1:     stw     r4, 0(r3)
37420 +       stw     r4, 4(r3)
37421 +       stw     r4, 8(r3)
37422 +       stw     r4, 12(r3)
37423 +#else
37424 +1:     dcbz    0,r3
37425 +#endif
37426 +       addi    r3,r3,CACHE_LINE_SIZE
37427 +       bdnz    1b
37428 +       blr
37429 +
37430 +/*
37431 + * Copy a whole page.  We use the dcbz instruction on the destination
37432 + * to reduce memory traffic (it eliminates the unnecessary reads of
37433 + * the destination into cache).  This requires that the destination
37434 + * is cacheable.
37435 + */
37436 +#define COPY_16_BYTES          \
37437 +       lwz     r6,4(r4);       \
37438 +       lwz     r7,8(r4);       \
37439 +       lwz     r8,12(r4);      \
37440 +       lwzu    r9,16(r4);      \
37441 +       stw     r6,4(r3);       \
37442 +       stw     r7,8(r3);       \
37443 +       stw     r8,12(r3);      \
37444 +       stwu    r9,16(r3)
37445 +
37446 +_GLOBAL(copy_page)
37447 +       addi    r3,r3,-4
37448 +       addi    r4,r4,-4
37449 +       li      r5,4
37450 +
37451 +#ifndef CONFIG_8xx
37452 +#if MAX_COPY_PREFETCH > 1
37453 +       li      r0,MAX_COPY_PREFETCH
37454 +       li      r11,4
37455 +       mtctr   r0
37456 +11:    dcbt    r11,r4
37457 +       addi    r11,r11,CACHE_LINE_SIZE
37458 +       bdnz    11b
37459 +#else /* MAX_COPY_PREFETCH == 1 */
37460 +       dcbt    r5,r4
37461 +       li      r11,CACHE_LINE_SIZE+4
37462 +#endif /* MAX_COPY_PREFETCH */
37463 +#endif /* CONFIG_8xx */
37464 +
37465 +       li      r0,4096/CACHE_LINE_SIZE
37466 +       mtctr   r0
37467 +1:
37468 +#ifndef CONFIG_8xx
37469 +       dcbt    r11,r4
37470 +       dcbz    r5,r3
37471 +#endif
37472 +       COPY_16_BYTES
37473 +#if CACHE_LINE_SIZE >= 32
37474 +       COPY_16_BYTES
37475 +#if CACHE_LINE_SIZE >= 64
37476 +       COPY_16_BYTES
37477 +       COPY_16_BYTES
37478 +#if CACHE_LINE_SIZE >= 128
37479 +       COPY_16_BYTES
37480 +       COPY_16_BYTES
37481 +       COPY_16_BYTES
37482 +       COPY_16_BYTES
37483 +#endif
37484 +#endif
37485 +#endif
37486 +       bdnz    1b
37487 +       blr
37488 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/miscthings.c um/arch/um/sys-ppc/miscthings.c
37489 --- orig/arch/um/sys-ppc/miscthings.c   1969-12-31 19:00:00.000000000 -0500
37490 +++ um/arch/um/sys-ppc/miscthings.c     2003-10-21 03:26:07.000000000 -0400
37491 @@ -0,0 +1,53 @@
37492 +#include "linux/threads.h"
37493 +#include "linux/stddef.h"  // for NULL
37494 +#include "linux/elf.h"  // for AT_NULL
37495 +
37496 +/* The following function nicked from arch/ppc/kernel/process.c and
37497 + * adapted slightly */
37498 +/*
37499 + * XXX ld.so expects the auxiliary table to start on
37500 + * a 16-byte boundary, so we have to find it and
37501 + * move it up. :-(
37502 + */
37503 +void shove_aux_table(unsigned long sp)
37504 +{
37505 +       int argc;
37506 +       char *p;
37507 +       unsigned long e;
37508 +       unsigned long aux_start, offset;
37509 +
37510 +       argc = *(int *)sp;
37511 +       sp += sizeof(int) + (argc + 1) * sizeof(char *);
37512 +       /* skip over the environment pointers */
37513 +       do {
37514 +               p = *(char **)sp;
37515 +               sp += sizeof(char *);
37516 +       } while (p != NULL);
37517 +       aux_start = sp;
37518 +       /* skip to the end of the auxiliary table */
37519 +       do {
37520 +               e = *(unsigned long *)sp;
37521 +               sp += 2 * sizeof(unsigned long);
37522 +       } while (e != AT_NULL);
37523 +       offset = ((aux_start + 15) & ~15) - aux_start;
37524 +       if (offset != 0) {
37525 +               do {
37526 +                       sp -= sizeof(unsigned long);
37527 +                       e = *(unsigned long *)sp;
37528 +                       *(unsigned long *)(sp + offset) = e;
37529 +               } while (sp > aux_start);
37530 +       }
37531 +}
37532 +/* END stuff taken from arch/ppc/kernel/process.c */
37533 +
37534 +
37535 +/*
37536 + * Overrides for Emacs so that we follow Linus's tabbing style.
37537 + * Emacs will notice this stuff at the end of the file and automatically
37538 + * adjust the settings for this buffer only.  This must remain at the end
37539 + * of the file.
37540 + * ---------------------------------------------------------------------------
37541 + * Local variables:
37542 + * c-file-style: "linux"
37543 + * End:
37544 + */
37545 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace.c um/arch/um/sys-ppc/ptrace.c
37546 --- orig/arch/um/sys-ppc/ptrace.c       1969-12-31 19:00:00.000000000 -0500
37547 +++ um/arch/um/sys-ppc/ptrace.c 2003-10-21 03:26:07.000000000 -0400
37548 @@ -0,0 +1,28 @@
37549 +#include "linux/sched.h"
37550 +#include "asm/ptrace.h"
37551 +
37552 +int putreg(struct task_struct *child, unsigned long regno, 
37553 +                 unsigned long value)
37554 +{
37555 +       child->thread.process_regs.regs[regno >> 2] = value;
37556 +       return 0;
37557 +}
37558 +
37559 +unsigned long getreg(struct task_struct *child, unsigned long regno)
37560 +{
37561 +       unsigned long retval = ~0UL;
37562 +
37563 +       retval &= child->thread.process_regs.regs[regno >> 2];
37564 +       return retval;
37565 +}
37566 +
37567 +/*
37568 + * Overrides for Emacs so that we follow Linus's tabbing style.
37569 + * Emacs will notice this stuff at the end of the file and automatically
37570 + * adjust the settings for this buffer only.  This must remain at the end
37571 + * of the file.
37572 + * ---------------------------------------------------------------------------
37573 + * Local variables:
37574 + * c-file-style: "linux"
37575 + * End:
37576 + */
37577 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace_user.c um/arch/um/sys-ppc/ptrace_user.c
37578 --- orig/arch/um/sys-ppc/ptrace_user.c  1969-12-31 19:00:00.000000000 -0500
37579 +++ um/arch/um/sys-ppc/ptrace_user.c    2003-10-21 03:26:07.000000000 -0400
37580 @@ -0,0 +1,40 @@
37581 +#include <sys/ptrace.h>
37582 +#include <errno.h>
37583 +#include <asm/ptrace.h>
37584 +#include "sysdep/ptrace.h"
37585 +
37586 +int ptrace_getregs(long pid, unsigned long *regs_out)
37587 +{
37588 +    int i;
37589 +    for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
37590 +       errno = 0;
37591 +       regs_out->regs[i] = ptrace(PTRACE_PEEKUSER, pid, i*4, 0);
37592 +       if (errno) {
37593 +           return -errno;
37594 +       }
37595 +    }
37596 +    return 0;
37597 +}
37598 +
37599 +int ptrace_setregs(long pid, unsigned long *regs_in)
37600 +{
37601 +    int i;
37602 +    for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
37603 +       if (i != 34 /* FIXME: PT_ORIG_R3 */ && i <= PT_MQ) {
37604 +           if (ptrace(PTRACE_POKEUSER, pid, i*4, regs_in->regs[i]) < 0) {
37605 +               return -errno;
37606 +           }
37607 +       }
37608 +    }
37609 +    return 0;
37610 +}
37611 +/*
37612 + * Overrides for Emacs so that we follow Linus's tabbing style.
37613 + * Emacs will notice this stuff at the end of the file and automatically
37614 + * adjust the settings for this buffer only.  This must remain at the end
37615 + * of the file.
37616 + * ---------------------------------------------------------------------------
37617 + * Local variables:
37618 + * c-file-style: "linux"
37619 + * End:
37620 + */
37621 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sigcontext.c um/arch/um/sys-ppc/sigcontext.c
37622 --- orig/arch/um/sys-ppc/sigcontext.c   1969-12-31 19:00:00.000000000 -0500
37623 +++ um/arch/um/sys-ppc/sigcontext.c     2003-10-21 03:26:07.000000000 -0400
37624 @@ -0,0 +1,15 @@
37625 +#include "asm/ptrace.h"
37626 +#include "asm/sigcontext.h"
37627 +#include "sysdep/ptrace.h"
37628 +#include "user_util.h"
37629 +
37630 +/*
37631 + * Overrides for Emacs so that we follow Linus's tabbing style.
37632 + * Emacs will notice this stuff at the end of the file and automatically
37633 + * adjust the settings for this buffer only.  This must remain at the end
37634 + * of the file.
37635 + * ---------------------------------------------------------------------------
37636 + * Local variables:
37637 + * c-file-style: "linux"
37638 + * End:
37639 + */
37640 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sysrq.c um/arch/um/sys-ppc/sysrq.c
37641 --- orig/arch/um/sys-ppc/sysrq.c        1969-12-31 19:00:00.000000000 -0500
37642 +++ um/arch/um/sys-ppc/sysrq.c  2003-10-21 03:26:07.000000000 -0400
37643 @@ -0,0 +1,43 @@
37644 +/* 
37645 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
37646 + * Licensed under the GPL
37647 + */
37648 +
37649 +#include "linux/kernel.h"
37650 +#include "linux/smp.h"
37651 +#include "asm/ptrace.h"
37652 +#include "sysrq.h"
37653 +
37654 +void show_regs(struct pt_regs_subarch *regs)
37655 +{
37656 +       printk("\n");
37657 +       printk("show_regs(): insert regs here.\n");
37658 +#if 0
37659 +        printk("\n");
37660 +        printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs, regs->eip,
37661 +              smp_processor_id());
37662 +        if (regs->xcs & 3)
37663 +                printk(" ESP: %04x:%08lx",0xffff & regs->xss, regs->esp);
37664 +        printk(" EFLAGS: %08lx\n", regs->eflags);
37665 +        printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
37666 +                regs->eax, regs->ebx, regs->ecx, regs->edx);
37667 +        printk("ESI: %08lx EDI: %08lx EBP: %08lx",
37668 +                regs->esi, regs->edi, regs->ebp);
37669 +        printk(" DS: %04x ES: %04x\n",
37670 +                0xffff & regs->xds, 0xffff & regs->xes);
37671 +#endif
37672 +
37673 +        show_trace(&regs->gpr[1]);
37674 +}
37675 +
37676 +
37677 +/*
37678 + * Overrides for Emacs so that we follow Linus's tabbing style.
37679 + * Emacs will notice this stuff at the end of the file and automatically
37680 + * adjust the settings for this buffer only.  This must remain at the end
37681 + * of the file.
37682 + * ---------------------------------------------------------------------------
37683 + * Local variables:
37684 + * c-file-style: "linux"
37685 + * End:
37686 + */
37687 diff -Naur -X ../exclude-files orig/arch/um/util/Makefile um/arch/um/util/Makefile
37688 --- orig/arch/um/util/Makefile  1969-12-31 19:00:00.000000000 -0500
37689 +++ um/arch/um/util/Makefile    2003-11-08 02:51:30.000000000 -0500
37690 @@ -0,0 +1,26 @@
37691 +ALL = mk_task mk_constants
37692 +
37693 +all : $(ALL)
37694 +
37695 +mk_task : mk_task_user.o mk_task_kern.o
37696 +       $(HOSTCC) -o mk_task mk_task_user.o mk_task_kern.o
37697 +
37698 +mk_task_user.o : mk_task_user.c
37699 +       $(HOSTCC) -c $< 
37700 +
37701 +mk_task_kern.o : mk_task_kern.c
37702 +       $(HOSTCC) $(CFLAGS) -c $< 
37703 +
37704 +mk_constants : mk_constants_user.o mk_constants_kern.o
37705 +       $(HOSTCC) -o mk_constants mk_constants_user.o mk_constants_kern.o
37706 +
37707 +mk_constants_user.o : mk_constants_user.c
37708 +       $(HOSTCC) -c $< 
37709 +
37710 +mk_constants_kern.o : mk_constants_kern.c
37711 +       $(HOSTCC) $(CFLAGS) -c $< 
37712 +
37713 +clean :
37714 +       $(RM) $(ALL) *.o *~
37715 +
37716 +archmrproper : clean
37717 diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_kern.c um/arch/um/util/mk_constants_kern.c
37718 --- orig/arch/um/util/mk_constants_kern.c       1969-12-31 19:00:00.000000000 -0500
37719 +++ um/arch/um/util/mk_constants_kern.c 2004-01-10 06:54:51.000000000 -0500
37720 @@ -0,0 +1,25 @@
37721 +#include "linux/kernel.h"
37722 +#include "linux/stringify.h"
37723 +#include "asm/page.h"
37724 +
37725 +extern void print_head(void);
37726 +extern void print_constant_str(char *name, char *value);
37727 +extern void print_constant_int(char *name, int value);
37728 +extern void print_tail(void);
37729 +
37730 +int main(int argc, char **argv)
37731 +{
37732 +  print_head();
37733 +  print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
37734 +
37735 +  print_constant_str("UM_KERN_EMERG", KERN_EMERG);
37736 +  print_constant_str("UM_KERN_ALERT", KERN_ALERT);
37737 +  print_constant_str("UM_KERN_CRIT", KERN_CRIT);
37738 +  print_constant_str("UM_KERN_ERR", KERN_ERR);
37739 +  print_constant_str("UM_KERN_WARNING", KERN_WARNING);
37740 +  print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
37741 +  print_constant_str("UM_KERN_INFO", KERN_INFO);
37742 +  print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
37743 +  print_tail();
37744 +  return(0);
37745 +}
37746 diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_user.c um/arch/um/util/mk_constants_user.c
37747 --- orig/arch/um/util/mk_constants_user.c       1969-12-31 19:00:00.000000000 -0500
37748 +++ um/arch/um/util/mk_constants_user.c 2003-10-21 03:26:07.000000000 -0400
37749 @@ -0,0 +1,28 @@
37750 +#include <stdio.h>
37751 +
37752 +void print_head(void)
37753 +{
37754 +  printf("/*\n");
37755 +  printf(" * Generated by mk_constants\n");
37756 +  printf(" */\n");
37757 +  printf("\n");
37758 +  printf("#ifndef __UM_CONSTANTS_H\n");
37759 +  printf("#define __UM_CONSTANTS_H\n");
37760 +  printf("\n");
37761 +}
37762 +
37763 +void print_constant_str(char *name, char *value)
37764 +{
37765 +  printf("#define %s \"%s\"\n", name, value);
37766 +}
37767 +
37768 +void print_constant_int(char *name, int value)
37769 +{
37770 +  printf("#define %s %d\n", name, value);
37771 +}
37772 +
37773 +void print_tail(void)
37774 +{
37775 +  printf("\n");
37776 +  printf("#endif\n");
37777 +}
37778 diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_kern.c um/arch/um/util/mk_task_kern.c
37779 --- orig/arch/um/util/mk_task_kern.c    1969-12-31 19:00:00.000000000 -0500
37780 +++ um/arch/um/util/mk_task_kern.c      2003-10-21 03:26:07.000000000 -0400
37781 @@ -0,0 +1,17 @@
37782 +#include "linux/sched.h"
37783 +#include "linux/stddef.h"
37784 +
37785 +extern void print(char *name, char *type, int offset);
37786 +extern void print_ptr(char *name, char *type, int offset);
37787 +extern void print_head(void);
37788 +extern void print_tail(void);
37789 +
37790 +int main(int argc, char **argv)
37791 +{
37792 +  print_head();
37793 +  print_ptr("TASK_REGS", "union uml_pt_regs", 
37794 +           offsetof(struct task_struct, thread.regs));
37795 +  print("TASK_PID", "int", offsetof(struct task_struct, pid));
37796 +  print_tail();
37797 +  return(0);
37798 +}
37799 diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_user.c um/arch/um/util/mk_task_user.c
37800 --- orig/arch/um/util/mk_task_user.c    1969-12-31 19:00:00.000000000 -0500
37801 +++ um/arch/um/util/mk_task_user.c      2003-10-21 03:26:07.000000000 -0400
37802 @@ -0,0 +1,30 @@
37803 +#include <stdio.h>
37804 +
37805 +void print(char *name, char *type, int offset)
37806 +{
37807 +  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
37808 +        offset);
37809 +}
37810 +
37811 +void print_ptr(char *name, char *type, int offset)
37812 +{
37813 +  printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
37814 +        offset);
37815 +}
37816 +
37817 +void print_head(void)
37818 +{
37819 +  printf("/*\n");
37820 +  printf(" * Generated by mk_task\n");
37821 +  printf(" */\n");
37822 +  printf("\n");
37823 +  printf("#ifndef __TASK_H\n");
37824 +  printf("#define __TASK_H\n");
37825 +  printf("\n");
37826 +}
37827 +
37828 +void print_tail(void)
37829 +{
37830 +  printf("\n");
37831 +  printf("#endif\n");
37832 +}
37833 diff -Naur -X ../exclude-files orig/CREDITS um/CREDITS
37834 --- orig/CREDITS        2003-12-16 22:16:23.000000000 -0500
37835 +++ um/CREDITS  2003-12-16 22:17:22.000000000 -0500
37836 @@ -434,6 +434,7 @@
37837  E: lars@nocrew.org
37838  W: http://lars.nocrew.org/
37839  D: dsp56k device driver
37840 +D: ptrace proxy in user mode kernel port
37841  S: Kopmansg 2
37842  S: 411 13  Goteborg
37843  S: Sweden
37844 @@ -719,7 +720,7 @@
37845  E: jdike@karaya.com
37846  W: http://user-mode-linux.sourceforge.net
37847  D: User mode kernel port
37848 -S: RR1 Box 67C
37849 +S: 375 Tubbs Hill Rd
37850  S: Deering NH 03244
37851  S: USA
37852  
37853 diff -Naur -X ../exclude-files orig/Documentation/Configure.help um/Documentation/Configure.help
37854 --- orig/Documentation/Configure.help   2003-12-16 22:16:23.000000000 -0500
37855 +++ um/Documentation/Configure.help     2003-12-16 22:17:22.000000000 -0500
37856 @@ -15821,6 +15821,63 @@
37857    The module will be called speedtch.o. If you want to compile it as
37858    a module, say M here and read <file:Documentation/modules.txt>.
37859  
37860 +Support for /proc/mm
37861 +CONFIG_PROC_MM
37862 +  Enables support for address space separation through /proc/mm.
37863 +  A host kernel needs to have this enabled in order for UML to
37864 +  run in skas mode.  UML kernels do not need to have this option
37865 +  unless they will host sub-UMLs.
37866 +
37867 +  If you don't know what this does just say Y.
37868 +
37869 +Separate Kernel Address Space support
37870 +CONFIG_MODE_SKAS
37871 +  This option controls whether skas (separate kernel address space)
37872 +  support is compiled in.  If you have applied the skas patch to the
37873 +  host and enabled support for /proc/mm in the host kernel, then you
37874 +  certainly want to say Y here (and consider saying N to
37875 +  CONFIG_MODE_TT).  Otherwise, it is safe to say Y.  Disabling this
37876 +  option will shrink the UML binary slightly.
37877 +
37878 +Tracing thread support
37879 +CONFIG_MODE_TT
37880 +  This option controls whether tracing thread support is compiled
37881 +  into UML.  Normally, this should be set to Y.  If you intend to
37882 +  use only skas mode (and the host has the skas patch applied to it),
37883 +  then it is OK to say N here.
37884 +
37885 +Force a static link
37886 +CONFIG_STATIC_LINK
37887 +  If CONFIG_MODE_TT is disabled, then this option gives you the ability
37888 +  to force a static link of UML.  Normally, if only skas mode is built
37889 +  in to UML, it will be linked as a shared binary.  This is inconvenient
37890 +  for use in a chroot jail.  So, if you intend to run UML inside a
37891 +  chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
37892 +  here.
37893 +
37894 +2G/2G host address space split
37895 +CONFIG_HOST_2G_2G
37896 +  Most Linux machines are configured so that the kernel occupies the
37897 +  upper 1G of the 4G address space and processes use the lower 3G.
37898 +  However, some machine are configured with a 2G/2G split, with the
37899 +  kernel occupying the upper 2G and processes using the lower 2G.
37900 +
37901 +  To allow UML to run on a such host you have to say Y here. N should be
37902 +  a safe choice most of the time.
37903 +
37904 +Kernel stack size order
37905 +CONFIG_KERNEL_STACK_ORDER
37906 +  This option determines the size of UML kernel stacks.  They will
37907 +  be 1 << order pages.  The default is OK unless you're running Valgrind
37908 +  on UML, in which case, set this to 3.
37909 +
37910 +UML ubd block driver
37911 +CONFIG_BLK_DEV_UBD
37912 +  The User-Mode Linux port includes a driver called UBD which will let
37913 +  you access arbitrary files on the host computer as block devices.
37914 +  Unless you know that you do not need such virtual block devices say
37915 +  Y here.
37916 +
37917  CONFIG_USB_GADGET
37918    USB is a master/slave protocol, organized with one master
37919    host (such as a PC) controlling up to 127 peripheral devices.
37920 @@ -15905,17 +15962,15 @@
37921  
37922  Always do synchronous disk IO for UBD
37923  CONFIG_BLK_DEV_UBD_SYNC
37924 -  The User-Mode Linux port includes a driver called UBD which will let
37925 -  you access arbitrary files on the host computer as block devices.
37926 -  Writes to such a block device are not immediately written to the
37927 -  host's disk; this may cause problems if, for example, the User-Mode
37928 -  Linux 'Virtual Machine' uses a journalling file system and the host
37929 -  computer crashes.
37930 +  Writes to the virtual block device are not immediately written to the host's
37931 +  disk; this may cause problems if, for example, the User-Mode Linux
37932 +  'Virtual Machine' uses a journalling filesystem and the host computer
37933 +  crashes.
37934  
37935    Synchronous operation (i.e. always writing data to the host's disk
37936    immediately) is configurable on a per-UBD basis by using a special
37937    kernel command line option.  Alternatively, you can say Y here to
37938 -  turn on synchronous operation by default for all block.
37939 +  turn on synchronous operation by default for all block devices.
37940  
37941    If you're running a journalling file system (like reiserfs, for
37942    example) in your virtual machine, you will want to say Y here.  If
37943 @@ -15927,6 +15982,7 @@
37944  CONFIG_PT_PROXY
37945    This option enables a debugging interface which allows gdb to debug
37946    the kernel without needing to actually attach to kernel threads.
37947 +  CONFIG_XTERM_CHAN must be enabled in order to enable CONFIG_PT_PROXY.
37948    If you want to do kernel debugging, say Y here; otherwise say N.
37949  
37950  Management console
37951 @@ -15959,7 +16015,7 @@
37952    This option allows developers to retrieve coverage data from a UML
37953    session.
37954  
37955 -  See <http://user-mode-linux.sourceforge.net/gcov.html> for more
37956 +  See <http://user-mode-linux.sourceforge.net/gprof.html> for more
37957    details.
37958  
37959    If you're involved in UML kernel development and want to use gcov,
37960 @@ -15996,6 +16052,19 @@
37961    If you'd like to be able to work with files stored on the host, 
37962    say Y or M here; otherwise say N.
37963  
37964 +HoneyPot ProcFS
37965 +CONFIG_HPPFS
37966 +  hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
37967 +  entries to be overridden, removed, or fabricated from the host.
37968 +  Its purpose is to allow a UML to appear to be a physical machine
37969 +  by removing or changing anything in /proc which gives away the
37970 +  identity of a UML.
37971 +
37972 +  See <http://user-mode-linux.sf.net/hppfs.html> for more information.
37973 +
37974 +  You only need this if you are setting up a UML honeypot.  Otherwise,
37975 +  it is safe to say 'N' here.
37976 +
37977  Example IO Memory driver
37978  CONFIG_MMAPPER
37979    The User-Mode Linux port can provide support for IO Memory
37980 @@ -16011,6 +16080,21 @@
37981    If you'd like to be able to provide a simulated IO port space for
37982    User-Mode Linux processes, say Y.  If unsure, say N.
37983  
37984 +Anonymous Memory support
37985 +CONFIG_DEV_ANON
37986 +  Don't ask. Just say Y.
37987 +
37988 +Support for software watchdog inside UML
37989 +CONFIG_UML_WATCHDOG
37990 +  Support for a virtual hardware watchdog. It's safe to say N here.
37991 +
37992 +COW block device
37993 +CONFIG_COW
37994 +  This is a layered driver which sits above two other block devices.
37995 +  One is read-only, and the other is a read-write layer which stores
37996 +  all changes.  This provides the illusion that the read-only layer
37997 +  can be mounted read-write and changed.
37998 +
37999  Virtual Serial Line
38000  CONFIG_SSL
38001    The User-Mode Linux environment allows you to create virtual serial
38002 @@ -16121,26 +16205,197 @@
38003  
38004  SLIP transport
38005  CONFIG_UML_NET_SLIP
38006 -  The Slip User-Mode Linux network transport allows a running UML to
38007 +  The slip User-Mode Linux network transport allows a running UML to
38008    network with its host over a point-to-point link.  Unlike Ethertap,
38009    which can carry any Ethernet frame (and hence even non-IP packets),
38010 -  the Slip transport can only carry IP packets.
38011 +  the slip transport can only carry IP packets.
38012  
38013 -  To use this, your host must support Slip devices.
38014 +  To use this, your host must support slip devices.
38015  
38016    For more information, see
38017    <http://user-mode-linux.sourceforge.net/networking.html>.  That site
38018 -  has examples of the UML command line to use to enable Slip
38019 +  has examples of the UML command line to use to enable slip
38020    networking, and details of a few quirks with it.
38021  
38022 -  The Ethertap Transport is preferred over Slip because of its
38023 -  limitation.  If you prefer Slip, however, say Y here.  Otherwise
38024 +  The Ethertap Transport is preferred over slip because of its
38025 +  limitations.  If you prefer slip, however, say Y here.  Otherwise
38026    choose the Multicast transport (to network multiple UMLs on 
38027    multiple hosts), Ethertap (to network with the host and the
38028    outside world), and/or the Daemon transport (to network multiple
38029    UMLs on a single host).  You may choose more than one without
38030    conflict.  If you don't need UML networking, say N.
38031  
38032 +SLiRP transport
38033 +CONFIG_UML_NET_SLIRP
38034 +  The SLiRP User-Mode Linux network transport allows a running UML
38035 +  to network by invoking a program that can handle SLIP encapsulated
38036 +  packets.  This is commonly (but not limited to) the application
38037 +  known as SLiRP, a program that can re-socket IP packets back onto
38038 +  the host on which it is run.  Only IP packets are supported,
38039 +  unlike other network transports that can handle all Ethernet
38040 +  frames.  In general, slirp allows the UML the same IP connectivity
38041 +  to the outside world that the host user is permitted, and unlike
38042 +  other transports, SLiRP works without the need of root level
38043 +  privleges, setuid binaries, or SLIP devices on the host.  This
38044 +  also means not every type of connection is possible, but most
38045 +  situations can be accomodated with carefully crafted slirp
38046 +  commands that can be passed along as part of the network device's
38047 +  setup string.  The effect of this transport on the UML is similar
38048 +  that of a host behind a firewall that masquerades all network
38049 +  connections passing through it (but is less secure).
38050 +
38051 +  To use this you should first have slirp compiled somewhere
38052 +  accessible on the host, and have read its documentation.  If you
38053 +  don't need UML networking, say N.
38054 +
38055 +  Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
38056 +
38057 +pcap transport
38058 +CONFIG_UML_NET_PCAP
38059 + The pcap transport makes a pcap packet stream on the host look
38060 +  like an ethernet device inside UML.  This is useful for making
38061 +  UML act as a network monitor for the host.  You must have libcap
38062 +  installed in order to build the pcap transport into UML.
38063 +
38064 +  For more information, see
38065 +  <http://user-mode-linux.sourceforge.net/networking.html>  That site
38066 +  has examples of the UML command line to use to enable this option.
38067 +
38068 +  If you intend to use UML as a network monitor for the host, say
38069 +  Y here.  Otherwise, say N.
38070 +
38071 +Default main console channel initialization
38072 +CONFIG_CON_ZERO_CHAN
38073 +  This is the string describing the channel to which the main console
38074 +  will be attached by default.  This value can be overridden from the
38075 +  command line.  The default value is "fd:0,fd:1", which attaches the
38076 +  main console to stdin and stdout.
38077 +  It is safe to leave this unchanged.
38078 +
38079 +Default console channel initialization
38080 +CONFIG_CON_CHAN
38081 +  This is the string describing the channel to which all consoles
38082 +  except the main console will be attached by default.  This value can
38083 +  be overridden from the command line.  The default value is "xterm",
38084 +  which brings them up in xterms.
38085 +  It is safe to leave this unchanged, although you may wish to change
38086 +  this if you expect the UML that you build to be run in environments
38087 +  which don't have X or xterm available.
38088 +
38089 +Default serial line channel initialization
38090 +CONFIG_SSL_CHAN
38091 +  This is the string describing the channel to which the serial lines
38092 +  will be attached by default.  This value can be overridden from the
38093 +  command line.  The default value is "pty", which attaches them to
38094 +  traditional pseudo-terminals.
38095 +  It is safe to leave this unchanged, although you may wish to change
38096 +  this if you expect the UML that you build to be run in environments
38097 +  which don't have a set of /dev/pty* devices.
38098 +
38099 +Nesting level
38100 +CONFIG_NEST_LEVEL
38101 +  This is set to the number of layers of UMLs that this UML will be run
38102 +  in.  Normally, this is zero, meaning that it will run directly on the
38103 +  host.  Setting it to one will build a UML that can run inside a UML
38104 +  that is running on the host.  Generally, if you intend this UML to run
38105 +  inside another UML, set CONFIG_NEST_LEVEL to one more than the host UML.
38106 +  Note that if the hosting UML has its CONFIG_KERNEL_HALF_GIGS set to 
38107 +  greater than one, then the guest UML should have its CONFIG_NEST_LEVEL 
38108 +  set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
38109 +  Only change this if you are running nested UMLs.
38110 +
38111 +Kernel address space size (in .5G units)
38112 +CONFIG_KERNEL_HALF_GIGS
38113 +  This determines the amount of address space that UML will allocate for
38114 +  its own, measured in half Gigabyte units.  The default is 1.
38115 +  Change this only if you need to boot UML with an unusually large amount
38116 +  of physical memory.
38117 +
38118 +UML sound support
38119 +CONFIG_UML_SOUND
38120 +  This option enables UML sound support.  If enabled, it will pull in
38121 +  soundcore and the UML hostaudio relay, which acts as a intermediary
38122 +  between the host's dsp and mixer devices and the UML sound system.
38123 +  It is safe to say 'Y' here.
38124 +
38125 +UML SMP support
38126 +CONFIG_UML_SMP
38127 +  This option enables UML SMP support.  UML implements virtual SMP by
38128 +  allowing as many processes to run simultaneously on the host as
38129 +  there are virtual processors configured.  Obviously, if the host is
38130 +  a uniprocessor, those processes will timeshare, but, inside UML,
38131 +  will appear to be running simultaneously.  If the host is a
38132 +  multiprocessor, then UML processes may run simultaneously, depending
38133 +  on the host scheduler.
38134 +  CONFIG_SMP will be set to whatever this option is set to.
38135 +  It is safe to leave this unchanged.
38136 +
38137 +file descriptor channel support
38138 +CONFIG_FD_CHAN
38139 +  This option enables support for attaching UML consoles and serial
38140 +  lines to already set up file descriptors.  Generally, the main
38141 +  console is attached to file descriptors 0 and 1 (stdin and stdout),
38142 +  so it would be wise to leave this enabled unless you intend to
38143 +  attach it to some other host device.
38144 +
38145 +null device channel support
38146 +CONFIG_NULL_CHAN
38147 +  This option enables support for attaching UML consoles and serial
38148 +  lines to a device similar to /dev/null.  Data written to it disappears
38149 +  and there is never any data to be read.
38150 +
38151 +port channel support
38152 +CONFIG_PORT_CHAN
38153 +  This option enables support for attaching UML consoles and serial
38154 +  lines to host portals.  They may be accessed with 'telnet <host>
38155 +  <port number>'.  Any number of consoles and serial lines may be
38156 +  attached to a single portal, although what UML device you get when
38157 +  you telnet to that portal will be unpredictable.
38158 +  It is safe to say 'Y' here.
38159 +
38160 +pty channel support
38161 +CONFIG_PTY_CHAN
38162 +  This option enables support for attaching UML consoles and serial
38163 +  lines to host pseudo-terminals.  Access to both traditional
38164 +  pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled
38165 +  with this option.  The assignment of UML devices to host devices
38166 +  will be announced in the kernel message log.
38167 +  It is safe to say 'Y' here.
38168 +
38169 +tty channel support
38170 +CONFIG_TTY_CHAN
38171 +  This option enables support for attaching UML consoles and serial
38172 +  lines to host terminals.  Access to both virtual consoles
38173 +  (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and
38174 +  /dev/pts/*) are controlled by this option.
38175 +  It is safe to say 'Y' here.
38176 +
38177 +xterm channel support
38178 +CONFIG_XTERM_CHAN
38179 +  This option enables support for attaching UML consoles and serial
38180 +  lines to xterms.  Each UML device so assigned will be brought up in
38181 +  its own xterm.
38182 +  If you disable this option, then CONFIG_PT_PROXY will be disabled as
38183 +  well, since UML's gdb currently requires an xterm.
38184 +  It is safe to say 'Y' here.
38185 +
38186 +tty logging
38187 +CONFIG_TTY_LOG
38188 +  This option enables logging of all data going through pseudo-terminals
38189 +  to the host.  This is primarily useful for honeypots, where you want
38190 +  secure keystroke logging that can't be detected or disabled by root.
38191 +  Say 'N' unless you are setting up a UML honeypot or otherwise know that
38192 +  you want this option.
38193 +
38194 +UML real-time clock support
38195 +CONFIG_UML_REAL_TIME_CLOCK
38196 +  This option ties the UML clock to the host clock, so that time passes at
38197 +  the same rate as on the host, regardless of how much CPU time the UML is
38198 +  getting.  This should normally be enabled.  The exception would be if you're
38199 +  debugging UML.  In this case, time spent staring at the debugger with UML
38200 +  stopped will cause lots of timer ticks to be backed up, and UML will spent
38201 +  lots of time calling the timer when it is finally continued.
38202 +
38203  Microtek USB scanner support
38204  CONFIG_USB_MICROTEK
38205    Say Y here if you want support for the Microtek X6USB and
38206 diff -Naur -X ../exclude-files orig/drivers/char/Makefile um/drivers/char/Makefile
38207 --- orig/drivers/char/Makefile  2003-12-16 22:16:26.000000000 -0500
38208 +++ um/drivers/char/Makefile    2003-12-16 22:17:25.000000000 -0500
38209 @@ -109,6 +109,12 @@
38210    endif
38211  endif
38212  
38213 +ifeq ($(ARCH),um)
38214 +  KEYMAP   =
38215 +  KEYBD    =
38216 +  CONSOLE  =
38217 +endif
38218 +
38219  ifeq ($(ARCH),sh)
38220    KEYMAP   =
38221    KEYBD    =
38222 diff -Naur -X ../exclude-files orig/drivers/char/mem.c um/drivers/char/mem.c
38223 --- orig/drivers/char/mem.c     2003-12-16 22:16:27.000000000 -0500
38224 +++ um/drivers/char/mem.c       2004-01-05 11:23:32.000000000 -0500
38225 @@ -220,7 +220,8 @@
38226         ssize_t read = 0;
38227         ssize_t virtr = 0;
38228         char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
38229 -               
38230 +
38231 +       p = (unsigned long) __va(p);
38232         if (p < (unsigned long) high_memory) {
38233                 read = count;
38234                 if (count > (unsigned long) high_memory - p)
38235 @@ -269,7 +270,7 @@
38236                 }
38237                 free_page((unsigned long)kbuf);
38238         }
38239 -       *ppos = p;
38240 +       *ppos = __pa((void *) p);
38241         return virtr + read;
38242  }
38243  
38244 @@ -664,6 +665,8 @@
38245         write:          write_full,
38246  };
38247  
38248 +extern struct file_operations anon_file_operations;
38249 +
38250  static int memory_open(struct inode * inode, struct file * filp)
38251  {
38252         switch (MINOR(inode->i_rdev)) {
38253 @@ -693,6 +696,9 @@
38254                 case 9:
38255                         filp->f_op = &urandom_fops;
38256                         break;
38257 +               case 10:
38258 +                       filp->f_op = &anon_file_operations;
38259 +                       break;
38260                 default:
38261                         return -ENXIO;
38262         }
38263 @@ -719,7 +725,8 @@
38264         {5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
38265         {7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
38266         {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
38267 -       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops}
38268 +       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops},
38269 +       {10, "anon", S_IRUGO | S_IWUSR,             &anon_file_operations},
38270      };
38271      int i;
38272  
38273 diff -Naur -X ../exclude-files orig/drivers/char/tty_io.c um/drivers/char/tty_io.c
38274 --- orig/drivers/char/tty_io.c  2003-12-16 22:16:27.000000000 -0500
38275 +++ um/drivers/char/tty_io.c    2003-12-16 22:17:25.000000000 -0500
38276 @@ -649,6 +649,23 @@
38277         wake_up_interruptible(&tty->write_wait);
38278  }
38279  
38280 +#ifdef CONFIG_TTY_LOG
38281 +
38282 +int (*open_log)(void *, void *) = NULL;
38283 +int (*write_log)(int, const char *, int, void *, int) = NULL;
38284 +void (*close_log)(int, void *) = NULL;
38285 +
38286 +void register_tty_logger(int (*opener)(void *, void *),
38287 +                        int (*writer)(int, const char *, int, void *, int),
38288 +                        void (*closer)(int, void *))
38289 +{
38290 +        open_log = opener;
38291 +       write_log = writer;
38292 +       close_log = closer;
38293 +}
38294 +
38295 +#endif
38296 +
38297  static ssize_t tty_read(struct file * file, char * buf, size_t count, 
38298                         loff_t *ppos)
38299  {
38300 @@ -689,8 +706,13 @@
38301         else
38302                 i = -EIO;
38303         unlock_kernel();
38304 -       if (i > 0)
38305 +       if (i > 0){
38306                 inode->i_atime = CURRENT_TIME;
38307 +#ifdef CONFIG_TTY_LOG
38308 +               if((tty->log_fd >= 0) && (write_log != NULL))
38309 +                       (*write_log)(tty->log_fd, buf, i, tty, 1);
38310 +#endif
38311 +       }
38312         return i;
38313  }
38314  
38315 @@ -744,6 +766,10 @@
38316         if (written) {
38317                 file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
38318                 ret = written;
38319 +#ifdef CONFIG_TTY_LOG
38320 +               if((tty->log_fd >= 0) && (write_log != NULL))
38321 +                       (*write_log)(tty->log_fd, buf - ret, ret, tty, 0);
38322 +#endif
38323         }
38324         up(&tty->atomic_write);
38325         return ret;
38326 @@ -971,6 +997,7 @@
38327                         goto release_mem_out;
38328                 }
38329         }
38330 +
38331         goto success;
38332  
38333         /*
38334 @@ -1290,6 +1317,11 @@
38335         run_task_queue(&tq_timer);
38336         flush_scheduled_tasks();
38337  
38338 +#ifdef CONFIG_TTY_LOG
38339 +       if((tty->log_fd >= 0) && (close_log != NULL))
38340 +               (*close_log)(tty->log_fd, tty);
38341 +#endif
38342 +
38343         /* 
38344          * The release_mem function takes care of the details of clearing
38345          * the slots and preserving the termios structure.
38346 @@ -1448,6 +1480,11 @@
38347                         nr_warns++;
38348                 }
38349         }
38350 +
38351 +#ifdef CONFIG_TTY_LOG
38352 +       if((tty->log_fd < 0) && (open_log != NULL))
38353 +              tty->log_fd = (*open_log)(tty, current->tty);
38354 +#endif
38355         return 0;
38356  }
38357  
38358 @@ -2047,6 +2084,9 @@
38359         spin_lock_init(&tty->read_lock);
38360         INIT_LIST_HEAD(&tty->tty_files);
38361         INIT_TQUEUE(&tty->SAK_tq, 0, 0);
38362 +#ifdef CONFIG_TTY_LOG
38363 +       tty->log_fd = -1;
38364 +#endif
38365  }
38366  
38367  /*
38368 diff -Naur -X ../exclude-files orig/drivers/net/setup.c um/drivers/net/setup.c
38369 --- orig/drivers/net/setup.c    2002-09-15 12:13:19.000000000 -0400
38370 +++ um/drivers/net/setup.c      2003-10-21 03:26:07.000000000 -0400
38371 @@ -28,7 +28,6 @@
38372  extern int lmc_setup(void);
38373  
38374  extern int madgemc_probe(void);
38375 -extern int uml_net_probe(void);
38376  
38377  /* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is string of 9 zeros. */
38378  #define __PAD6 "\0\0\0\0\0\0\0\0\0"
38379 @@ -103,9 +102,6 @@
38380  #ifdef CONFIG_MADGEMC
38381         {madgemc_probe, 0},
38382  #endif
38383 -#ifdef CONFIG_UML_NET
38384 -       {uml_net_probe, 0},
38385 -#endif
38386   
38387         {NULL, 0},
38388  };
38389 diff -Naur -X ../exclude-files orig/fs/bad_inode.c um/fs/bad_inode.c
38390 --- orig/fs/bad_inode.c 2002-08-21 11:47:27.000000000 -0400
38391 +++ um/fs/bad_inode.c   2003-10-21 03:26:07.000000000 -0400
38392 @@ -83,6 +83,7 @@
38393   
38394  void make_bad_inode(struct inode * inode) 
38395  {
38396 +       inode->i_state = 0;
38397         inode->i_mode = S_IFREG;
38398         inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
38399         inode->i_op = &bad_inode_ops;   
38400 diff -Naur -X ../exclude-files orig/include/asm-i386/hardirq.h um/include/asm-i386/hardirq.h
38401 --- orig/include/asm-i386/hardirq.h     2004-01-11 22:46:12.000000000 -0500
38402 +++ um/include/asm-i386/hardirq.h       2004-02-14 06:28:59.000000000 -0500
38403 @@ -4,6 +4,7 @@
38404  #include <linux/config.h>
38405  #include <linux/threads.h>
38406  #include <linux/irq.h>
38407 +#include <asm/processor.h>             /* for cpu_relax */
38408  
38409  /* assembly code in softirq.h is sensitive to the offsets of these fields */
38410  typedef struct {
38411 diff -Naur -X ../exclude-files orig/include/asm-um/a.out.h um/include/asm-um/a.out.h
38412 --- orig/include/asm-um/a.out.h 1969-12-31 19:00:00.000000000 -0500
38413 +++ um/include/asm-um/a.out.h   2003-10-21 03:26:07.000000000 -0400
38414 @@ -0,0 +1,20 @@
38415 +#ifndef __UM_A_OUT_H
38416 +#define __UM_A_OUT_H
38417 +
38418 +#include "linux/config.h"
38419 +#include "asm/arch/a.out.h"
38420 +#include "choose-mode.h"
38421 +
38422 +#undef STACK_TOP
38423 +
38424 +extern unsigned long stacksizelim;
38425 +
38426 +extern unsigned long host_task_size;
38427 +
38428 +#define STACK_ROOM (stacksizelim)
38429 +
38430 +extern int honeypot;
38431 +#define STACK_TOP \
38432 +       CHOOSE_MODE((honeypot ? host_task_size : task_size), task_size)
38433 +
38434 +#endif
38435 diff -Naur -X ../exclude-files orig/include/asm-um/archparam-i386.h um/include/asm-um/archparam-i386.h
38436 --- orig/include/asm-um/archparam-i386.h        1969-12-31 19:00:00.000000000 -0500
38437 +++ um/include/asm-um/archparam-i386.h  2003-12-16 08:50:39.000000000 -0500
38438 @@ -0,0 +1,80 @@
38439 +/* 
38440 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
38441 + * Licensed under the GPL
38442 + */
38443 +
38444 +#ifndef __UM_ARCHPARAM_I386_H
38445 +#define __UM_ARCHPARAM_I386_H
38446 +
38447 +/********* Bits for asm-um/elf.h ************/
38448 +
38449 +#include "user.h"
38450 +
38451 +#define ELF_PLATFORM "i586"
38452 +
38453 +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
38454 +
38455 +typedef struct user_i387_struct elf_fpregset_t;
38456 +typedef unsigned long elf_greg_t;
38457 +
38458 +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
38459 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
38460 +
38461 +#define ELF_DATA        ELFDATA2LSB
38462 +#define ELF_ARCH        EM_386
38463 +
38464 +#define ELF_PLAT_INIT(regs, load_addr) do { \
38465 +       PT_REGS_EBX(regs) = 0; \
38466 +       PT_REGS_ECX(regs) = 0; \
38467 +       PT_REGS_EDX(regs) = 0; \
38468 +       PT_REGS_ESI(regs) = 0; \
38469 +       PT_REGS_EDI(regs) = 0; \
38470 +       PT_REGS_EBP(regs) = 0; \
38471 +       PT_REGS_EAX(regs) = 0; \
38472 +} while(0)
38473 +
38474 +/* Shamelessly stolen from include/asm-i386/elf.h */
38475 +
38476 +#define ELF_CORE_COPY_REGS(pr_reg, regs) do {  \
38477 +       pr_reg[0] = PT_REGS_EBX(regs);          \
38478 +       pr_reg[1] = PT_REGS_ECX(regs);          \
38479 +       pr_reg[2] = PT_REGS_EDX(regs);          \
38480 +       pr_reg[3] = PT_REGS_ESI(regs);          \
38481 +       pr_reg[4] = PT_REGS_EDI(regs);          \
38482 +       pr_reg[5] = PT_REGS_EBP(regs);          \
38483 +       pr_reg[6] = PT_REGS_EAX(regs);          \
38484 +       pr_reg[7] = PT_REGS_DS(regs);           \
38485 +       pr_reg[8] = PT_REGS_ES(regs);           \
38486 +       /* fake once used fs and gs selectors? */       \
38487 +       pr_reg[9] = PT_REGS_DS(regs);           \
38488 +       pr_reg[10] = PT_REGS_DS(regs);          \
38489 +       pr_reg[11] = PT_REGS_SYSCALL_NR(regs);  \
38490 +       pr_reg[12] = PT_REGS_IP(regs);          \
38491 +       pr_reg[13] = PT_REGS_CS(regs);          \
38492 +       pr_reg[14] = PT_REGS_EFLAGS(regs);      \
38493 +       pr_reg[15] = PT_REGS_SP(regs);          \
38494 +       pr_reg[16] = PT_REGS_SS(regs);          \
38495 +} while(0);
38496 +
38497 +/********* Bits for asm-um/delay.h **********/
38498 +
38499 +typedef unsigned long um_udelay_t;
38500 +
38501 +/********* Nothing for asm-um/hardirq.h **********/
38502 +
38503 +/********* Nothing for asm-um/hw_irq.h **********/
38504 +
38505 +/********* Nothing for asm-um/string.h **********/
38506 +
38507 +#endif
38508 +
38509 +/*
38510 + * Overrides for Emacs so that we follow Linus's tabbing style.
38511 + * Emacs will notice this stuff at the end of the file and automatically
38512 + * adjust the settings for this buffer only.  This must remain at the end
38513 + * of the file.
38514 + * ---------------------------------------------------------------------------
38515 + * Local variables:
38516 + * c-file-style: "linux"
38517 + * End:
38518 + */
38519 diff -Naur -X ../exclude-files orig/include/asm-um/archparam-ppc.h um/include/asm-um/archparam-ppc.h
38520 --- orig/include/asm-um/archparam-ppc.h 1969-12-31 19:00:00.000000000 -0500
38521 +++ um/include/asm-um/archparam-ppc.h   2003-10-21 03:26:07.000000000 -0400
38522 @@ -0,0 +1,41 @@
38523 +#ifndef __UM_ARCHPARAM_PPC_H
38524 +#define __UM_ARCHPARAM_PPC_H
38525 +
38526 +/********* Bits for asm-um/elf.h ************/
38527 +
38528 +#define ELF_PLATFORM (0)
38529 +
38530 +#define ELF_ET_DYN_BASE (0x08000000)
38531 +
38532 +/* the following stolen from asm-ppc/elf.h */
38533 +#define ELF_NGREG      48      /* includes nip, msr, lr, etc. */
38534 +#define ELF_NFPREG     33      /* includes fpscr */
38535 +/* General registers */
38536 +typedef unsigned long elf_greg_t;
38537 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
38538 +
38539 +/* Floating point registers */
38540 +typedef double elf_fpreg_t;
38541 +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
38542 +
38543 +#define ELF_DATA        ELFDATA2MSB
38544 +#define ELF_ARCH       EM_PPC
38545 +
38546 +/********* Bits for asm-um/delay.h **********/
38547 +
38548 +typedef unsigned int um_udelay_t;
38549 +
38550 +/********* Bits for asm-um/hw_irq.h **********/
38551 +
38552 +struct hw_interrupt_type;
38553 +
38554 +/********* Bits for asm-um/hardirq.h **********/
38555 +
38556 +#define irq_enter(cpu, irq) hardirq_enter(cpu)
38557 +#define irq_exit(cpu, irq) hardirq_exit(cpu)
38558 +
38559 +/********* Bits for asm-um/string.h **********/
38560 +
38561 +#define __HAVE_ARCH_STRRCHR
38562 +
38563 +#endif
38564 diff -Naur -X ../exclude-files orig/include/asm-um/arch-signal-i386.h um/include/asm-um/arch-signal-i386.h
38565 --- orig/include/asm-um/arch-signal-i386.h      1969-12-31 19:00:00.000000000 -0500
38566 +++ um/include/asm-um/arch-signal-i386.h        2003-10-21 03:26:07.000000000 -0400
38567 @@ -0,0 +1,24 @@
38568 +/* 
38569 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38570 + * Licensed under the GPL
38571 + */
38572 +
38573 +#ifndef __UM_ARCH_SIGNAL_I386_H
38574 +#define __UM_ARCH_SIGNAL_I386_H
38575 +
38576 +struct arch_signal_context {
38577 +       unsigned long extrasigs[_NSIG_WORDS];
38578 +};
38579 +
38580 +#endif
38581 +
38582 +/*
38583 + * Overrides for Emacs so that we follow Linus's tabbing style.
38584 + * Emacs will notice this stuff at the end of the file and automatically
38585 + * adjust the settings for this buffer only.  This must remain at the end
38586 + * of the file.
38587 + * ---------------------------------------------------------------------------
38588 + * Local variables:
38589 + * c-file-style: "linux"
38590 + * End:
38591 + */
38592 diff -Naur -X ../exclude-files orig/include/asm-um/atomic.h um/include/asm-um/atomic.h
38593 --- orig/include/asm-um/atomic.h        1969-12-31 19:00:00.000000000 -0500
38594 +++ um/include/asm-um/atomic.h  2004-02-14 06:28:59.000000000 -0500
38595 @@ -0,0 +1,6 @@
38596 +#ifndef __UM_ATOMIC_H
38597 +#define __UM_ATOMIC_H
38598 +
38599 +#include "asm/arch/atomic.h"
38600 +
38601 +#endif
38602 diff -Naur -X ../exclude-files orig/include/asm-um/bitops.h um/include/asm-um/bitops.h
38603 --- orig/include/asm-um/bitops.h        1969-12-31 19:00:00.000000000 -0500
38604 +++ um/include/asm-um/bitops.h  2004-02-14 06:28:59.000000000 -0500
38605 @@ -0,0 +1,6 @@
38606 +#ifndef __UM_BITOPS_H
38607 +#define __UM_BITOPS_H
38608 +
38609 +#include "asm/arch/bitops.h"
38610 +
38611 +#endif
38612 diff -Naur -X ../exclude-files orig/include/asm-um/boot.h um/include/asm-um/boot.h
38613 --- orig/include/asm-um/boot.h  1969-12-31 19:00:00.000000000 -0500
38614 +++ um/include/asm-um/boot.h    2003-10-21 03:26:07.000000000 -0400
38615 @@ -0,0 +1,6 @@
38616 +#ifndef __UM_BOOT_H
38617 +#define __UM_BOOT_H
38618 +
38619 +#include "asm/arch/boot.h"
38620 +
38621 +#endif
38622 diff -Naur -X ../exclude-files orig/include/asm-um/bugs.h um/include/asm-um/bugs.h
38623 --- orig/include/asm-um/bugs.h  1969-12-31 19:00:00.000000000 -0500
38624 +++ um/include/asm-um/bugs.h    2003-10-21 03:26:07.000000000 -0400
38625 @@ -0,0 +1,6 @@
38626 +#ifndef __UM_BUGS_H
38627 +#define __UM_BUGS_H
38628 +
38629 +void check_bugs(void);
38630 +
38631 +#endif
38632 diff -Naur -X ../exclude-files orig/include/asm-um/byteorder.h um/include/asm-um/byteorder.h
38633 --- orig/include/asm-um/byteorder.h     1969-12-31 19:00:00.000000000 -0500
38634 +++ um/include/asm-um/byteorder.h       2004-01-16 03:32:58.000000000 -0500
38635 @@ -0,0 +1,6 @@
38636 +#ifndef __UM_BYTEORDER_H
38637 +#define __UM_BYTEORDER_H
38638 +
38639 +#include "asm/arch/byteorder.h"
38640 +
38641 +#endif
38642 diff -Naur -X ../exclude-files orig/include/asm-um/cache.h um/include/asm-um/cache.h
38643 --- orig/include/asm-um/cache.h 1969-12-31 19:00:00.000000000 -0500
38644 +++ um/include/asm-um/cache.h   2003-10-21 03:26:07.000000000 -0400
38645 @@ -0,0 +1,6 @@
38646 +#ifndef __UM_CACHE_H
38647 +#define __UM_CACHE_H
38648 +
38649 +#define        L1_CACHE_BYTES  32
38650 +
38651 +#endif
38652 diff -Naur -X ../exclude-files orig/include/asm-um/checksum.h um/include/asm-um/checksum.h
38653 --- orig/include/asm-um/checksum.h      1969-12-31 19:00:00.000000000 -0500
38654 +++ um/include/asm-um/checksum.h        2003-10-21 03:26:07.000000000 -0400
38655 @@ -0,0 +1,6 @@
38656 +#ifndef __UM_CHECKSUM_H
38657 +#define __UM_CHECKSUM_H
38658 +
38659 +#include "sysdep/checksum.h"
38660 +
38661 +#endif
38662 diff -Naur -X ../exclude-files orig/include/asm-um/cobalt.h um/include/asm-um/cobalt.h
38663 --- orig/include/asm-um/cobalt.h        1969-12-31 19:00:00.000000000 -0500
38664 +++ um/include/asm-um/cobalt.h  2003-10-21 03:26:07.000000000 -0400
38665 @@ -0,0 +1,6 @@
38666 +#ifndef __UM_COBALT_H
38667 +#define __UM_COBALT_H
38668 +
38669 +#include "asm/arch/cobalt.h"
38670 +
38671 +#endif
38672 diff -Naur -X ../exclude-files orig/include/asm-um/current.h um/include/asm-um/current.h
38673 --- orig/include/asm-um/current.h       1969-12-31 19:00:00.000000000 -0500
38674 +++ um/include/asm-um/current.h 2004-02-14 06:28:59.000000000 -0500
38675 @@ -0,0 +1,34 @@
38676 +/* 
38677 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
38678 + * Licensed under the GPL
38679 + */
38680 +
38681 +#ifndef __UM_CURRENT_H
38682 +#define __UM_CURRENT_H
38683 +
38684 +#ifndef __ASSEMBLY__
38685 +
38686 +#include "linux/config.h"
38687 +#include "asm/page.h"
38688 +
38689 +struct task_struct;
38690 +
38691 +#define CURRENT_TASK(dummy) (((unsigned long) &dummy) & \
38692 +                            (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
38693 +
38694 +#define current ({ int dummy; (struct task_struct *) CURRENT_TASK(dummy); })
38695 +
38696 +#endif /* __ASSEMBLY__ */
38697 +
38698 +#endif
38699 +
38700 +/*
38701 + * Overrides for Emacs so that we follow Linus's tabbing style.
38702 + * Emacs will notice this stuff at the end of the file and automatically
38703 + * adjust the settings for this buffer only.  This must remain at the end
38704 + * of the file.
38705 + * ---------------------------------------------------------------------------
38706 + * Local variables:
38707 + * c-file-style: "linux"
38708 + * End:
38709 + */
38710 diff -Naur -X ../exclude-files orig/include/asm-um/delay.h um/include/asm-um/delay.h
38711 --- orig/include/asm-um/delay.h 1969-12-31 19:00:00.000000000 -0500
38712 +++ um/include/asm-um/delay.h   2003-12-16 22:26:58.000000000 -0500
38713 @@ -0,0 +1,7 @@
38714 +#ifndef __UM_DELAY_H
38715 +#define __UM_DELAY_H
38716 +
38717 +#include "asm/arch/delay.h"
38718 +#include "asm/archparam.h"
38719 +
38720 +#endif
38721 diff -Naur -X ../exclude-files orig/include/asm-um/desc.h um/include/asm-um/desc.h
38722 --- orig/include/asm-um/desc.h  1969-12-31 19:00:00.000000000 -0500
38723 +++ um/include/asm-um/desc.h    2003-10-21 03:26:07.000000000 -0400
38724 @@ -0,0 +1,6 @@
38725 +#ifndef __UM_DESC_H
38726 +#define __UM_DESC_H
38727 +
38728 +#include "asm/arch/desc.h"
38729 +
38730 +#endif
38731 diff -Naur -X ../exclude-files orig/include/asm-um/div64.h um/include/asm-um/div64.h
38732 --- orig/include/asm-um/div64.h 1969-12-31 19:00:00.000000000 -0500
38733 +++ um/include/asm-um/div64.h   2003-10-21 03:26:07.000000000 -0400
38734 @@ -0,0 +1,6 @@
38735 +#ifndef _UM_DIV64_H
38736 +#define _UM_DIV64_H
38737 +
38738 +#include "asm/arch/div64.h"
38739 +
38740 +#endif
38741 diff -Naur -X ../exclude-files orig/include/asm-um/dma.h um/include/asm-um/dma.h
38742 --- orig/include/asm-um/dma.h   1969-12-31 19:00:00.000000000 -0500
38743 +++ um/include/asm-um/dma.h     2004-01-16 03:32:59.000000000 -0500
38744 @@ -0,0 +1,10 @@
38745 +#ifndef __UM_DMA_H
38746 +#define __UM_DMA_H
38747 +
38748 +#include "asm/io.h"
38749 +
38750 +extern unsigned long uml_physmem;
38751 +
38752 +#define MAX_DMA_ADDRESS (uml_physmem)
38753 +
38754 +#endif
38755 diff -Naur -X ../exclude-files orig/include/asm-um/elf.h um/include/asm-um/elf.h
38756 --- orig/include/asm-um/elf.h   1969-12-31 19:00:00.000000000 -0500
38757 +++ um/include/asm-um/elf.h     2003-12-16 22:29:20.000000000 -0500
38758 @@ -0,0 +1,18 @@
38759 +#ifndef __UM_ELF_H
38760 +#define __UM_ELF_H
38761 +
38762 +#include "asm/archparam.h"
38763 +
38764 +#define ELF_HWCAP (0)
38765 +
38766 +#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
38767 +
38768 +#define ELF_EXEC_PAGESIZE 4096
38769 +
38770 +#define elf_check_arch(x) (1)
38771 +
38772 +#define ELF_CLASS ELFCLASS32
38773 +
38774 +#define USE_ELF_CORE_DUMP
38775 +
38776 +#endif
38777 diff -Naur -X ../exclude-files orig/include/asm-um/errno.h um/include/asm-um/errno.h
38778 --- orig/include/asm-um/errno.h 1969-12-31 19:00:00.000000000 -0500
38779 +++ um/include/asm-um/errno.h   2003-10-21 03:26:07.000000000 -0400
38780 @@ -0,0 +1,6 @@
38781 +#ifndef __UM_ERRNO_H
38782 +#define __UM_ERRNO_H
38783 +
38784 +#include "asm/arch/errno.h"
38785 +
38786 +#endif
38787 diff -Naur -X ../exclude-files orig/include/asm-um/fcntl.h um/include/asm-um/fcntl.h
38788 --- orig/include/asm-um/fcntl.h 1969-12-31 19:00:00.000000000 -0500
38789 +++ um/include/asm-um/fcntl.h   2003-10-21 03:26:07.000000000 -0400
38790 @@ -0,0 +1,6 @@
38791 +#ifndef __UM_FCNTL_H
38792 +#define __UM_FCNTL_H
38793 +
38794 +#include "asm/arch/fcntl.h"
38795 +
38796 +#endif
38797 diff -Naur -X ../exclude-files orig/include/asm-um/fixmap.h um/include/asm-um/fixmap.h
38798 --- orig/include/asm-um/fixmap.h        1969-12-31 19:00:00.000000000 -0500
38799 +++ um/include/asm-um/fixmap.h  2004-02-14 06:29:00.000000000 -0500
38800 @@ -0,0 +1,89 @@
38801 +#ifndef __UM_FIXMAP_H
38802 +#define __UM_FIXMAP_H
38803 +
38804 +#include <linux/config.h>
38805 +#include <asm/kmap_types.h>
38806 +
38807 +/*
38808 + * Here we define all the compile-time 'special' virtual
38809 + * addresses. The point is to have a constant address at
38810 + * compile time, but to set the physical address only
38811 + * in the boot process. We allocate these special  addresses
38812 + * from the end of virtual memory (0xfffff000) backwards.
38813 + * Also this lets us do fail-safe vmalloc(), we
38814 + * can guarantee that these special addresses and
38815 + * vmalloc()-ed addresses never overlap.
38816 + *
38817 + * these 'compile-time allocated' memory buffers are
38818 + * fixed-size 4k pages. (or larger if used with an increment
38819 + * highger than 1) use fixmap_set(idx,phys) to associate
38820 + * physical memory with fixmap indices.
38821 + *
38822 + * TLB entries of such buffers will not be flushed across
38823 + * task switches.
38824 + */
38825 +
38826 +/*
38827 + * on UP currently we will have no trace of the fixmap mechanizm,
38828 + * no page table allocations, etc. This might change in the
38829 + * future, say framebuffers for the console driver(s) could be
38830 + * fix-mapped?
38831 + */
38832 +enum fixed_addresses {
38833 +#ifdef CONFIG_HIGHMEM
38834 +       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
38835 +       FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
38836 +#endif
38837 +       __end_of_fixed_addresses
38838 +};
38839 +
38840 +extern void __set_fixmap (enum fixed_addresses idx,
38841 +                         unsigned long phys, pgprot_t flags);
38842 +
38843 +#define set_fixmap(idx, phys) \
38844 +               __set_fixmap(idx, phys, PAGE_KERNEL)
38845 +/*
38846 + * Some hardware wants to get fixmapped without caching.
38847 + */
38848 +#define set_fixmap_nocache(idx, phys) \
38849 +               __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
38850 +/*
38851 + * used by vmalloc.c.
38852 + *
38853 + * Leave one empty page between vmalloc'ed areas and
38854 + * the start of the fixmap, and leave one page empty
38855 + * at the top of mem..
38856 + */
38857 +extern unsigned long get_kmem_end(void);
38858 +
38859 +#define FIXADDR_TOP    (get_kmem_end() - 0x2000)
38860 +#define FIXADDR_SIZE   (__end_of_fixed_addresses << PAGE_SHIFT)
38861 +#define FIXADDR_START  (FIXADDR_TOP - FIXADDR_SIZE)
38862 +
38863 +#define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
38864 +
38865 +extern void __this_fixmap_does_not_exist(void);
38866 +
38867 +/*
38868 + * 'index to address' translation. If anyone tries to use the idx
38869 + * directly without tranlation, we catch the bug with a NULL-deference
38870 + * kernel oops. Illegal ranges of incoming indices are caught too.
38871 + */
38872 +static inline unsigned long fix_to_virt(const unsigned int idx)
38873 +{
38874 +       /*
38875 +        * this branch gets completely eliminated after inlining,
38876 +        * except when someone tries to use fixaddr indices in an
38877 +        * illegal way. (such as mixing up address types or using
38878 +        * out-of-range indices).
38879 +        *
38880 +        * If it doesn't get removed, the linker will complain
38881 +        * loudly with a reasonably clear error message..
38882 +        */
38883 +       if (idx >= __end_of_fixed_addresses)
38884 +               __this_fixmap_does_not_exist();
38885 +
38886 +        return __fix_to_virt(idx);
38887 +}
38888 +
38889 +#endif
38890 diff -Naur -X ../exclude-files orig/include/asm-um/floppy.h um/include/asm-um/floppy.h
38891 --- orig/include/asm-um/floppy.h        1969-12-31 19:00:00.000000000 -0500
38892 +++ um/include/asm-um/floppy.h  2003-10-21 03:26:07.000000000 -0400
38893 @@ -0,0 +1,6 @@
38894 +#ifndef __UM_FLOPPY_H
38895 +#define __UM_FLOPPY_H
38896 +
38897 +#include "asm/arch/floppy.h"
38898 +
38899 +#endif
38900 diff -Naur -X ../exclude-files orig/include/asm-um/hardirq.h um/include/asm-um/hardirq.h
38901 --- orig/include/asm-um/hardirq.h       1969-12-31 19:00:00.000000000 -0500
38902 +++ um/include/asm-um/hardirq.h 2004-02-14 06:28:59.000000000 -0500
38903 @@ -0,0 +1,6 @@
38904 +#ifndef __UM_HARDIRQ_H
38905 +#define __UM_HARDIRQ_H
38906 +
38907 +#include "asm/arch/hardirq.h"
38908 +
38909 +#endif
38910 diff -Naur -X ../exclude-files orig/include/asm-um/hdreg.h um/include/asm-um/hdreg.h
38911 --- orig/include/asm-um/hdreg.h 1969-12-31 19:00:00.000000000 -0500
38912 +++ um/include/asm-um/hdreg.h   2003-10-21 03:26:07.000000000 -0400
38913 @@ -0,0 +1,6 @@
38914 +#ifndef __UM_HDREG_H
38915 +#define __UM_HDREG_H
38916 +
38917 +#include "asm/arch/hdreg.h"
38918 +
38919 +#endif
38920 diff -Naur -X ../exclude-files orig/include/asm-um/highmem.h um/include/asm-um/highmem.h
38921 --- orig/include/asm-um/highmem.h       1969-12-31 19:00:00.000000000 -0500
38922 +++ um/include/asm-um/highmem.h 2004-02-14 06:29:00.000000000 -0500
38923 @@ -0,0 +1,12 @@
38924 +#ifndef __UM_HIGHMEM_H
38925 +#define __UM_HIGHMEM_H
38926 +
38927 +#include "asm/page.h"
38928 +#include "asm/fixmap.h"
38929 +#include "asm/arch/highmem.h"
38930 +
38931 +#undef PKMAP_BASE
38932 +
38933 +#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK)
38934 +
38935 +#endif
38936 diff -Naur -X ../exclude-files orig/include/asm-um/hw_irq.h um/include/asm-um/hw_irq.h
38937 --- orig/include/asm-um/hw_irq.h        1969-12-31 19:00:00.000000000 -0500
38938 +++ um/include/asm-um/hw_irq.h  2003-12-16 22:26:55.000000000 -0500
38939 @@ -0,0 +1,10 @@
38940 +#ifndef _ASM_UM_HW_IRQ_H
38941 +#define _ASM_UM_HW_IRQ_H
38942 +
38943 +#include "asm/irq.h"
38944 +#include "asm/archparam.h"
38945 +
38946 +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
38947 +{}
38948 +
38949 +#endif
38950 diff -Naur -X ../exclude-files orig/include/asm-um/ide.h um/include/asm-um/ide.h
38951 --- orig/include/asm-um/ide.h   1969-12-31 19:00:00.000000000 -0500
38952 +++ um/include/asm-um/ide.h     2004-01-16 23:40:52.000000000 -0500
38953 @@ -0,0 +1,6 @@
38954 +#ifndef __UM_IDE_H
38955 +#define __UM_IDE_H
38956 +
38957 +#include "asm/arch/ide.h"
38958 +
38959 +#endif
38960 diff -Naur -X ../exclude-files orig/include/asm-um/init.h um/include/asm-um/init.h
38961 --- orig/include/asm-um/init.h  1969-12-31 19:00:00.000000000 -0500
38962 +++ um/include/asm-um/init.h    2003-10-21 03:26:07.000000000 -0400
38963 @@ -0,0 +1,11 @@
38964 +#ifndef _UM_INIT_H
38965 +#define _UM_INIT_H
38966 +
38967 +#ifdef notdef
38968 +#define __init
38969 +#define __initdata
38970 +#define __initfunc(__arginit) __arginit
38971 +#define __cacheline_aligned 
38972 +#endif
38973 +
38974 +#endif
38975 diff -Naur -X ../exclude-files orig/include/asm-um/ioctl.h um/include/asm-um/ioctl.h
38976 --- orig/include/asm-um/ioctl.h 1969-12-31 19:00:00.000000000 -0500
38977 +++ um/include/asm-um/ioctl.h   2003-10-21 03:26:07.000000000 -0400
38978 @@ -0,0 +1,6 @@
38979 +#ifndef __UM_IOCTL_H
38980 +#define __UM_IOCTL_H
38981 +
38982 +#include "asm/arch/ioctl.h"
38983 +
38984 +#endif
38985 diff -Naur -X ../exclude-files orig/include/asm-um/ioctls.h um/include/asm-um/ioctls.h
38986 --- orig/include/asm-um/ioctls.h        1969-12-31 19:00:00.000000000 -0500
38987 +++ um/include/asm-um/ioctls.h  2003-11-07 02:10:43.000000000 -0500
38988 @@ -0,0 +1,6 @@
38989 +#ifndef __UM_IOCTLS_H
38990 +#define __UM_IOCTLS_H
38991 +
38992 +#include "asm/arch/ioctls.h"
38993 +
38994 +#endif
38995 diff -Naur -X ../exclude-files orig/include/asm-um/io.h um/include/asm-um/io.h
38996 --- orig/include/asm-um/io.h    1969-12-31 19:00:00.000000000 -0500
38997 +++ um/include/asm-um/io.h      2004-01-16 03:32:59.000000000 -0500
38998 @@ -0,0 +1,25 @@
38999 +#ifndef __UM_IO_H
39000 +#define __UM_IO_H
39001 +
39002 +#include "asm/page.h"
39003 +
39004 +#define IO_SPACE_LIMIT 0xdeadbeef /* Sure hope nothing uses this */
39005 +
39006 +static inline int inb(unsigned long i) { return(0); }
39007 +static inline void outb(char c, unsigned long i) { }
39008 +
39009 +/*
39010 + * Change virtual addresses to physical addresses and vv.
39011 + * These are pretty trivial
39012 + */
39013 +static inline unsigned long virt_to_phys(volatile void * address)
39014 +{
39015 +       return __pa((void *) address);
39016 +}
39017 +
39018 +static inline void * phys_to_virt(unsigned long address)
39019 +{
39020 +       return __va(address);
39021 +}
39022 +
39023 +#endif
39024 diff -Naur -X ../exclude-files orig/include/asm-um/ipcbuf.h um/include/asm-um/ipcbuf.h
39025 --- orig/include/asm-um/ipcbuf.h        1969-12-31 19:00:00.000000000 -0500
39026 +++ um/include/asm-um/ipcbuf.h  2003-10-21 03:26:07.000000000 -0400
39027 @@ -0,0 +1,6 @@
39028 +#ifndef __UM_IPCBUF_H
39029 +#define __UM_IPCBUF_H
39030 +
39031 +#include "asm/arch/ipcbuf.h"
39032 +
39033 +#endif
39034 diff -Naur -X ../exclude-files orig/include/asm-um/ipc.h um/include/asm-um/ipc.h
39035 --- orig/include/asm-um/ipc.h   1969-12-31 19:00:00.000000000 -0500
39036 +++ um/include/asm-um/ipc.h     2003-10-21 03:26:07.000000000 -0400
39037 @@ -0,0 +1,6 @@
39038 +#ifndef __UM_IPC_H
39039 +#define __UM_IPC_H
39040 +
39041 +#include "asm/arch/ipc.h"
39042 +
39043 +#endif
39044 diff -Naur -X ../exclude-files orig/include/asm-um/irq.h um/include/asm-um/irq.h
39045 --- orig/include/asm-um/irq.h   1969-12-31 19:00:00.000000000 -0500
39046 +++ um/include/asm-um/irq.h     2003-10-21 03:26:07.000000000 -0400
39047 @@ -0,0 +1,22 @@
39048 +#ifndef __UM_IRQ_H
39049 +#define __UM_IRQ_H
39050 +
39051 +#define TIMER_IRQ              0
39052 +#define UMN_IRQ                        1
39053 +#define CONSOLE_IRQ            2
39054 +#define CONSOLE_WRITE_IRQ      3
39055 +#define UBD_IRQ                        4
39056 +#define UM_ETH_IRQ             5
39057 +#define SSL_IRQ                        6
39058 +#define SSL_WRITE_IRQ          7
39059 +#define ACCEPT_IRQ             8
39060 +#define MCONSOLE_IRQ           9
39061 +#define WINCH_IRQ              10
39062 +#define SIGIO_WRITE_IRQ        11
39063 +#define TELNETD_IRQ            12
39064 +#define XTERM_IRQ              13
39065 +
39066 +#define LAST_IRQ XTERM_IRQ
39067 +#define NR_IRQS (LAST_IRQ + 1)
39068 +
39069 +#endif
39070 diff -Naur -X ../exclude-files orig/include/asm-um/keyboard.h um/include/asm-um/keyboard.h
39071 --- orig/include/asm-um/keyboard.h      1969-12-31 19:00:00.000000000 -0500
39072 +++ um/include/asm-um/keyboard.h        2003-10-21 03:26:07.000000000 -0400
39073 @@ -0,0 +1,6 @@
39074 +#ifndef __UM_KEYBOARD_H
39075 +#define __UM_KEYBOARD_H
39076 +
39077 +#include "asm/arch/keyboard.h"
39078 +
39079 +#endif
39080 diff -Naur -X ../exclude-files orig/include/asm-um/kmap_types.h um/include/asm-um/kmap_types.h
39081 --- orig/include/asm-um/kmap_types.h    1969-12-31 19:00:00.000000000 -0500
39082 +++ um/include/asm-um/kmap_types.h      2003-10-21 03:26:07.000000000 -0400
39083 @@ -0,0 +1,11 @@
39084 +/* 
39085 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39086 + * Licensed under the GPL
39087 + */
39088 +
39089 +#ifndef __UM_KMAP_TYPES_H
39090 +#define __UM_KMAP_TYPES_H
39091 +
39092 +#include "asm/arch/kmap_types.h"
39093 +
39094 +#endif
39095 diff -Naur -X ../exclude-files orig/include/asm-um/linux_logo.h um/include/asm-um/linux_logo.h
39096 --- orig/include/asm-um/linux_logo.h    1969-12-31 19:00:00.000000000 -0500
39097 +++ um/include/asm-um/linux_logo.h      2003-10-21 03:26:07.000000000 -0400
39098 @@ -0,0 +1,6 @@
39099 +#ifndef __UM_LINUX_LOGO_H
39100 +#define __UM_LINUX_LOGO_H
39101 +
39102 +#include "asm/arch/linux_logo.h"
39103 +
39104 +#endif
39105 diff -Naur -X ../exclude-files orig/include/asm-um/locks.h um/include/asm-um/locks.h
39106 --- orig/include/asm-um/locks.h 1969-12-31 19:00:00.000000000 -0500
39107 +++ um/include/asm-um/locks.h   2003-10-21 03:26:07.000000000 -0400
39108 @@ -0,0 +1,6 @@
39109 +#ifndef __UM_LOCKS_H
39110 +#define __UM_LOCKS_H
39111 +
39112 +#include "asm/arch/locks.h"
39113 +
39114 +#endif
39115 diff -Naur -X ../exclude-files orig/include/asm-um/mca_dma.h um/include/asm-um/mca_dma.h
39116 --- orig/include/asm-um/mca_dma.h       1969-12-31 19:00:00.000000000 -0500
39117 +++ um/include/asm-um/mca_dma.h 2003-10-21 03:26:07.000000000 -0400
39118 @@ -0,0 +1,6 @@
39119 +#ifndef mca___UM_DMA_H
39120 +#define mca___UM_DMA_H
39121 +
39122 +#include "asm/arch/mca_dma.h"
39123 +
39124 +#endif
39125 diff -Naur -X ../exclude-files orig/include/asm-um/mman.h um/include/asm-um/mman.h
39126 --- orig/include/asm-um/mman.h  1969-12-31 19:00:00.000000000 -0500
39127 +++ um/include/asm-um/mman.h    2003-10-21 03:26:07.000000000 -0400
39128 @@ -0,0 +1,6 @@
39129 +#ifndef __UM_MMAN_H
39130 +#define __UM_MMAN_H
39131 +
39132 +#include "asm/arch/mman.h"
39133 +
39134 +#endif
39135 diff -Naur -X ../exclude-files orig/include/asm-um/mmu_context.h um/include/asm-um/mmu_context.h
39136 --- orig/include/asm-um/mmu_context.h   1969-12-31 19:00:00.000000000 -0500
39137 +++ um/include/asm-um/mmu_context.h     2004-02-14 06:28:59.000000000 -0500
39138 @@ -0,0 +1,72 @@
39139 +/* 
39140 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39141 + * Licensed under the GPL
39142 + */
39143 +
39144 +#ifndef __UM_MMU_CONTEXT_H
39145 +#define __UM_MMU_CONTEXT_H
39146 +
39147 +#include "linux/sched.h"
39148 +#include "choose-mode.h"
39149 +
39150 +#define get_mmu_context(task) do ; while(0)
39151 +#define activate_context(tsk) do ; while(0)
39152 +
39153 +static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
39154 +{
39155 +}
39156 +
39157 +extern void switch_mm_skas(int mm_fd);
39158 +
39159 +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
39160 +                            struct task_struct *tsk, unsigned cpu)
39161 +{
39162 +       if(prev != next){
39163 +               clear_bit(cpu, &prev->cpu_vm_mask);
39164 +               set_bit(cpu, &next->cpu_vm_mask);
39165 +               if(next != &init_mm)
39166 +                       CHOOSE_MODE((void) 0, 
39167 +                                   switch_mm_skas(next->context.skas.mm_fd));
39168 +       }
39169 +}
39170 +
39171 +static inline void enter_lazy_tlb(struct mm_struct *mm, 
39172 +                                 struct task_struct *tsk, unsigned cpu)
39173 +{
39174 +}
39175 +
39176 +extern int init_new_context_skas(struct task_struct *task, 
39177 +                                struct mm_struct *mm);
39178 +
39179 +static inline int init_new_context_tt(struct task_struct *task, 
39180 +                                     struct mm_struct *mm)
39181 +{
39182 +       return(0);
39183 +}
39184 +
39185 +static inline int init_new_context(struct task_struct *task, 
39186 +                                  struct mm_struct *mm)
39187 +{
39188 +       return(CHOOSE_MODE_PROC(init_new_context_tt, init_new_context_skas, 
39189 +                               task, mm));
39190 +}
39191 +
39192 +extern void destroy_context_skas(struct mm_struct *mm);
39193 +
39194 +static inline void destroy_context(struct mm_struct *mm)
39195 +{
39196 +       CHOOSE_MODE((void) 0, destroy_context_skas(mm));
39197 +}
39198 +
39199 +#endif
39200 +
39201 +/*
39202 + * Overrides for Emacs so that we follow Linus's tabbing style.
39203 + * Emacs will notice this stuff at the end of the file and automatically
39204 + * adjust the settings for this buffer only.  This must remain at the end
39205 + * of the file.
39206 + * ---------------------------------------------------------------------------
39207 + * Local variables:
39208 + * c-file-style: "linux"
39209 + * End:
39210 + */
39211 diff -Naur -X ../exclude-files orig/include/asm-um/mmu.h um/include/asm-um/mmu.h
39212 --- orig/include/asm-um/mmu.h   1969-12-31 19:00:00.000000000 -0500
39213 +++ um/include/asm-um/mmu.h     2003-10-21 03:26:07.000000000 -0400
39214 @@ -0,0 +1,22 @@
39215 +/* 
39216 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39217 + * Licensed under the GPL
39218 + */
39219 +
39220 +#ifndef __MMU_H
39221 +#define __MMU_H
39222 +
39223 +#include "um_mmu.h"
39224 +
39225 +#endif
39226 +
39227 +/*
39228 + * Overrides for Emacs so that we follow Linus's tabbing style.
39229 + * Emacs will notice this stuff at the end of the file and automatically
39230 + * adjust the settings for this buffer only.  This must remain at the end
39231 + * of the file.
39232 + * ---------------------------------------------------------------------------
39233 + * Local variables:
39234 + * c-file-style: "linux"
39235 + * End:
39236 + */
39237 diff -Naur -X ../exclude-files orig/include/asm-um/module.h um/include/asm-um/module.h
39238 --- orig/include/asm-um/module.h        1969-12-31 19:00:00.000000000 -0500
39239 +++ um/include/asm-um/module.h  2003-10-21 03:26:07.000000000 -0400
39240 @@ -0,0 +1,6 @@
39241 +#ifndef __UM_MODULE_H
39242 +#define __UM_MODULE_H
39243 +
39244 +#include "asm/arch/module.h"
39245 +
39246 +#endif
39247 diff -Naur -X ../exclude-files orig/include/asm-um/msgbuf.h um/include/asm-um/msgbuf.h
39248 --- orig/include/asm-um/msgbuf.h        1969-12-31 19:00:00.000000000 -0500
39249 +++ um/include/asm-um/msgbuf.h  2003-10-21 03:26:07.000000000 -0400
39250 @@ -0,0 +1,6 @@
39251 +#ifndef __UM_MSGBUF_H
39252 +#define __UM_MSGBUF_H
39253 +
39254 +#include "asm/arch/msgbuf.h"
39255 +
39256 +#endif
39257 diff -Naur -X ../exclude-files orig/include/asm-um/mtrr.h um/include/asm-um/mtrr.h
39258 --- orig/include/asm-um/mtrr.h  1969-12-31 19:00:00.000000000 -0500
39259 +++ um/include/asm-um/mtrr.h    2004-02-12 05:46:29.000000000 -0500
39260 @@ -0,0 +1,6 @@
39261 +#ifndef __UM_MTRR_H
39262 +#define __UM_MTRR_H
39263 +
39264 +#include "asm/arch/mtrr.h"
39265 +
39266 +#endif
39267 diff -Naur -X ../exclude-files orig/include/asm-um/namei.h um/include/asm-um/namei.h
39268 --- orig/include/asm-um/namei.h 1969-12-31 19:00:00.000000000 -0500
39269 +++ um/include/asm-um/namei.h   2003-10-21 03:26:07.000000000 -0400
39270 @@ -0,0 +1,6 @@
39271 +#ifndef __UM_NAMEI_H
39272 +#define __UM_NAMEI_H
39273 +
39274 +#include "asm/arch/namei.h"
39275 +
39276 +#endif
39277 diff -Naur -X ../exclude-files orig/include/asm-um/page.h um/include/asm-um/page.h
39278 --- orig/include/asm-um/page.h  1969-12-31 19:00:00.000000000 -0500
39279 +++ um/include/asm-um/page.h    2004-01-16 03:32:58.000000000 -0500
39280 @@ -0,0 +1,68 @@
39281 +/* 
39282 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
39283 + * Licensed under the GPL
39284 + */
39285 +
39286 +#ifndef __UM_PAGE_H
39287 +#define __UM_PAGE_H
39288 +
39289 +struct page;
39290 +
39291 +#include "asm/arch/page.h"
39292 +
39293 +#undef BUG
39294 +#undef PAGE_BUG
39295 +#undef __pa
39296 +#undef __va
39297 +#undef virt_to_page
39298 +#undef VALID_PAGE
39299 +#undef PAGE_OFFSET
39300 +#undef KERNELBASE
39301 +
39302 +extern unsigned long uml_physmem;
39303 +
39304 +#define PAGE_OFFSET (uml_physmem)
39305 +#define KERNELBASE PAGE_OFFSET
39306 +
39307 +#ifndef __ASSEMBLY__
39308 +
39309 +extern void stop(void);
39310 +
39311 +#define BUG() do { \
39312 +       panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
39313 +} while (0)
39314 +
39315 +#define PAGE_BUG(page) do { \
39316 +       BUG(); \
39317 +} while (0)
39318 +
39319 +#endif /* __ASSEMBLY__ */
39320 +
39321 +#define __va_space (8*1024*1024)
39322 +
39323 +extern unsigned long to_phys(void *virt);
39324 +extern void *to_virt(unsigned long phys);
39325 +
39326 +#define __pa(virt) to_phys((void *) virt)
39327 +#define __va(phys) to_virt((unsigned long) phys)
39328 +
39329 +#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
39330 +
39331 +extern struct page *arch_validate(struct page *page, int mask, int order);
39332 +#define HAVE_ARCH_VALIDATE
39333 +
39334 +extern void arch_free_page(struct page *page, int order);
39335 +#define HAVE_ARCH_FREE_PAGE
39336 +
39337 +#endif
39338 +
39339 +/*
39340 + * Overrides for Emacs so that we follow Linus's tabbing style.
39341 + * Emacs will notice this stuff at the end of the file and automatically
39342 + * adjust the settings for this buffer only.  This must remain at the end
39343 + * of the file.
39344 + * ---------------------------------------------------------------------------
39345 + * Local variables:
39346 + * c-file-style: "linux"
39347 + * End:
39348 + */
39349 diff -Naur -X ../exclude-files orig/include/asm-um/page_offset.h um/include/asm-um/page_offset.h
39350 --- orig/include/asm-um/page_offset.h   1969-12-31 19:00:00.000000000 -0500
39351 +++ um/include/asm-um/page_offset.h     2003-10-21 03:26:07.000000000 -0400
39352 @@ -0,0 +1 @@
39353 +#define PAGE_OFFSET_RAW (uml_physmem)
39354 diff -Naur -X ../exclude-files orig/include/asm-um/param.h um/include/asm-um/param.h
39355 --- orig/include/asm-um/param.h 1969-12-31 19:00:00.000000000 -0500
39356 +++ um/include/asm-um/param.h   2004-02-13 02:26:52.000000000 -0500
39357 @@ -0,0 +1,22 @@
39358 +#ifndef _UM_PARAM_H
39359 +#define _UM_PARAM_H
39360 +
39361 +#define HZ 100
39362 +
39363 +#define EXEC_PAGESIZE   4096
39364 +
39365 +#ifndef NGROUPS
39366 +#define NGROUPS         32
39367 +#endif
39368 +
39369 +#ifndef NOGROUP
39370 +#define NOGROUP         (-1)
39371 +#endif
39372 +
39373 +#define MAXHOSTNAMELEN  64      /* max length of hostname */
39374 +
39375 +#ifdef __KERNEL__
39376 +# define CLOCKS_PER_SEC 100    /* frequency at which times() counts */
39377 +#endif
39378 +
39379 +#endif
39380 diff -Naur -X ../exclude-files orig/include/asm-um/pci.h um/include/asm-um/pci.h
39381 --- orig/include/asm-um/pci.h   1969-12-31 19:00:00.000000000 -0500
39382 +++ um/include/asm-um/pci.h     2003-10-21 03:26:07.000000000 -0400
39383 @@ -0,0 +1,6 @@
39384 +#ifndef __UM_PCI_H
39385 +#define __UM_PCI_H
39386 +
39387 +#define PCI_DMA_BUS_IS_PHYS     (1)
39388 +
39389 +#endif
39390 diff -Naur -X ../exclude-files orig/include/asm-um/pgalloc.h um/include/asm-um/pgalloc.h
39391 --- orig/include/asm-um/pgalloc.h       1969-12-31 19:00:00.000000000 -0500
39392 +++ um/include/asm-um/pgalloc.h 2004-02-14 06:29:00.000000000 -0500
39393 @@ -0,0 +1,164 @@
39394 +/* 
39395 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
39396 + * Derived from include/asm-i386/pgalloc.h and include/asm-i386/pgtable.h
39397 + * Licensed under the GPL
39398 + */
39399 +
39400 +#ifndef __UM_PGALLOC_H
39401 +#define __UM_PGALLOC_H
39402 +
39403 +#include "linux/config.h"
39404 +#include "linux/mm.h"
39405 +#include "asm/fixmap.h"
39406 +#include "choose-mode.h"
39407 +
39408 +#define pgd_quicklist (current_cpu_data.pgd_quick)
39409 +#define pmd_quicklist (current_cpu_data.pmd_quick)
39410 +#define pte_quicklist (current_cpu_data.pte_quick)
39411 +#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
39412 +
39413 +#define pmd_populate(mm, pmd, pte) set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
39414 +
39415 +/*
39416 + * Allocate and free page tables.
39417 + */
39418 +
39419 +static inline pgd_t *get_pgd_slow_tt(void)
39420 +{
39421 +       pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
39422 +
39423 +       if (pgd) {
39424 +               memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
39425 +               memcpy(pgd + USER_PTRS_PER_PGD, 
39426 +                      swapper_pg_dir + USER_PTRS_PER_PGD, 
39427 +                      (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
39428 +       }
39429 +       return pgd;
39430 +}
39431 +
39432 +static inline pgd_t *get_pgd_slow_skas(void)
39433 +{
39434 +       pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
39435 +
39436 +       if (pgd)
39437 +               memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
39438 +       return pgd;
39439 +}
39440 +
39441 +static inline pgd_t *get_pgd_slow(void)
39442 +{
39443 +       return(CHOOSE_MODE(get_pgd_slow_tt(), get_pgd_slow_skas()));
39444 +}
39445 +
39446 +static inline pgd_t *get_pgd_fast(void)
39447 +{
39448 +       unsigned long *ret;
39449 +
39450 +       ret = pgd_quicklist;
39451 +       if (ret != NULL) {
39452 +               pgd_quicklist = (unsigned long *)(*ret);
39453 +               ret[0] = 0;
39454 +               pgtable_cache_size--;
39455 +       } else
39456 +               ret = (unsigned long *)get_pgd_slow();
39457 +       return (pgd_t *)ret;
39458 +}
39459 +
39460 +static inline void free_pgd_fast(pgd_t *pgd)
39461 +{
39462 +       *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
39463 +       pgd_quicklist = (unsigned long *) pgd;
39464 +       pgtable_cache_size++;
39465 +}
39466 +
39467 +static inline void free_pgd_slow(pgd_t *pgd)
39468 +{
39469 +       free_page((unsigned long)pgd);
39470 +}
39471 +
39472 +static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
39473 +{
39474 +       pte_t *pte;
39475 +
39476 +       pte = (pte_t *) __get_free_page(GFP_KERNEL);
39477 +       if (pte)
39478 +               clear_page(pte);
39479 +       return pte;
39480 +}
39481 +
39482 +static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
39483 +{
39484 +       unsigned long *ret;
39485 +
39486 +       ret = (unsigned long *)pte_quicklist;
39487 +       if (ret != NULL) {
39488 +               pte_quicklist = (unsigned long *)(*ret);
39489 +               ret[0] = ret[1];
39490 +               pgtable_cache_size--;
39491 +       }
39492 +       return (pte_t *)ret;
39493 +}
39494 +
39495 +static inline void pte_free_fast(pte_t *pte)
39496 +{
39497 +       *(unsigned long *)pte = (unsigned long) pte_quicklist;
39498 +       pte_quicklist = (unsigned long *) pte;
39499 +       pgtable_cache_size++;
39500 +}
39501 +
39502 +static inline void pte_free_slow(pte_t *pte)
39503 +{
39504 +       free_page((unsigned long)pte);
39505 +}
39506 +
39507 +#define pte_free(pte)           pte_free_fast(pte)
39508 +#define pgd_free(pgd)           free_pgd_slow(pgd)
39509 +#define pgd_alloc(mm)           get_pgd_fast()
39510 +
39511 +/*
39512 + * allocating and freeing a pmd is trivial: the 1-entry pmd is
39513 + * inside the pgd, so has no extra memory associated with it.
39514 + */
39515 +
39516 +#define pmd_alloc_one_fast(mm, addr)   ({ BUG(); ((pmd_t *)1); })
39517 +#define pmd_alloc_one(mm, addr)                ({ BUG(); ((pmd_t *)2); })
39518 +#define pmd_free_slow(x)               do { } while (0)
39519 +#define pmd_free_fast(x)               do { } while (0)
39520 +#define pmd_free(x)                    do { } while (0)
39521 +#define pgd_populate(mm, pmd, pte)     BUG()
39522 +
39523 +/*
39524 + * TLB flushing:
39525 + *
39526 + *  - flush_tlb() flushes the current mm struct TLBs
39527 + *  - flush_tlb_all() flushes all processes TLBs
39528 + *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
39529 + *  - flush_tlb_page(vma, vmaddr) flushes one page
39530 + *  - flush_tlb_kernel_vm() flushes the kernel vm area
39531 + *  - flush_tlb_range(mm, start, end) flushes a range of pages
39532 + *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
39533 + */
39534 +
39535 +extern void flush_tlb_all(void);
39536 +extern void flush_tlb_mm(struct mm_struct *mm);
39537 +extern void flush_tlb_range(struct mm_struct *mm, unsigned long start, 
39538 +                           unsigned long end);
39539 +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
39540 +extern void flush_tlb_kernel_vm(void);
39541 +
39542 +static inline void flush_tlb_pgtables(struct mm_struct *mm,
39543 +                                     unsigned long start, unsigned long end)
39544 +{
39545 +}
39546 +
39547 +#endif
39548 +/*
39549 + * Overrides for Emacs so that we follow Linus's tabbing style.
39550 + * Emacs will notice this stuff at the end of the file and automatically
39551 + * adjust the settings for this buffer only.  This must remain at the end
39552 + * of the file.
39553 + * ---------------------------------------------------------------------------
39554 + * Local variables:
39555 + * c-file-style: "linux"
39556 + * End:
39557 + */
39558 diff -Naur -X ../exclude-files orig/include/asm-um/pgtable.h um/include/asm-um/pgtable.h
39559 --- orig/include/asm-um/pgtable.h       1969-12-31 19:00:00.000000000 -0500
39560 +++ um/include/asm-um/pgtable.h 2004-02-14 06:28:59.000000000 -0500
39561 @@ -0,0 +1,413 @@
39562 +/* 
39563 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
39564 + * Derived from include/asm-i386/pgtable.h
39565 + * Licensed under the GPL
39566 + */
39567 +
39568 +#ifndef __UM_PGTABLE_H
39569 +#define __UM_PGTABLE_H
39570 +
39571 +#include "linux/sched.h"
39572 +#include "asm/processor.h"
39573 +#include "asm/page.h"
39574 +
39575 +extern pgd_t swapper_pg_dir[1024];
39576 +
39577 +#define flush_cache_all() do ; while (0)
39578 +#define flush_cache_mm(mm) do ; while (0)
39579 +#define flush_cache_range(vma, start, end) do ; while (0)
39580 +#define flush_cache_page(vma, vmaddr) do ; while (0)
39581 +#define flush_page_to_ram(page) do ; while (0)
39582 +#define flush_dcache_page(page)        do ; while (0)
39583 +#define flush_icache_range(from, to) do ; while (0)
39584 +#define flush_icache_page(vma,pg) do ; while (0)
39585 +#define flush_icache_user_range(vma,pg,adr,len)        do ; while (0)
39586 +
39587 +extern void __flush_tlb_one(unsigned long addr);
39588 +
39589 +extern void pte_free(pte_t *pte);
39590 +
39591 +extern void pgd_free(pgd_t *pgd);
39592 +
39593 +extern int do_check_pgt_cache(int, int);
39594 +
39595 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
39596 +                            pte_t *pte_out);
39597 +
39598 +/* zero page used for uninitialized stuff */
39599 +extern unsigned long *empty_zero_page;
39600 +
39601 +#define pgtable_cache_init() do ; while (0)
39602 +
39603 +/* PMD_SHIFT determines the size of the area a second-level page table can map */
39604 +#define PMD_SHIFT      22
39605 +#define PMD_SIZE       (1UL << PMD_SHIFT)
39606 +#define PMD_MASK       (~(PMD_SIZE-1))
39607 +
39608 +/* PGDIR_SHIFT determines what a third-level page table entry can map */
39609 +#define PGDIR_SHIFT    22
39610 +#define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
39611 +#define PGDIR_MASK     (~(PGDIR_SIZE-1))
39612 +
39613 +/*
39614 + * entries per page directory level: the i386 is two-level, so
39615 + * we don't really have any PMD directory physically.
39616 + */
39617 +#define PTRS_PER_PTE   1024
39618 +#define PTRS_PER_PMD   1
39619 +#define PTRS_PER_PGD   1024
39620 +#define USER_PTRS_PER_PGD      (TASK_SIZE/PGDIR_SIZE)
39621 +#define FIRST_USER_PGD_NR       0
39622 +
39623 +#define pte_ERROR(e) \
39624 +        printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
39625 +#define pmd_ERROR(e) \
39626 +        printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
39627 +#define pgd_ERROR(e) \
39628 +        printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
39629 +
39630 +/*
39631 + * pgd entries used up by user/kernel:
39632 + */
39633 +
39634 +#define USER_PGD_PTRS (TASK_SIZE >> PGDIR_SHIFT)
39635 +#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
39636 +
39637 +#ifndef __ASSEMBLY__
39638 +/* Just any arbitrary offset to the start of the vmalloc VM area: the
39639 + * current 8MB value just means that there will be a 8MB "hole" after the
39640 + * physical memory until the kernel virtual memory starts.  That means that
39641 + * any out-of-bounds memory accesses will hopefully be caught.
39642 + * The vmalloc() routines leaves a hole of 4kB between each vmalloced
39643 + * area for the same reason. ;)
39644 + */
39645 +
39646 +extern unsigned long end_iomem;
39647 +
39648 +#define VMALLOC_OFFSET (__va_space)
39649 +#define VMALLOC_START  ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
39650 +#define VMALLOC_VMADDR(x) ((unsigned long)(x))
39651 +
39652 +#if CONFIG_HIGHMEM
39653 +# define VMALLOC_END   (PKMAP_BASE-2*PAGE_SIZE)
39654 +#else
39655 +# define VMALLOC_END   (FIXADDR_START-2*PAGE_SIZE)
39656 +#endif
39657 +
39658 +#define _PAGE_PRESENT  0x001
39659 +#define _PAGE_NEWPAGE  0x002
39660 +#define _PAGE_PROTNONE 0x004   /* If not present */
39661 +#define _PAGE_RW       0x008
39662 +#define _PAGE_USER     0x010
39663 +#define _PAGE_ACCESSED 0x020
39664 +#define _PAGE_DIRTY    0x040
39665 +#define _PAGE_NEWPROT   0x080
39666 +
39667 +#define REGION_MASK    0xf0000000
39668 +#define REGION_SHIFT   28
39669 +
39670 +#define _PAGE_TABLE    (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
39671 +#define _KERNPG_TABLE  (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
39672 +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
39673 +
39674 +#define PAGE_NONE      __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
39675 +#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
39676 +#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
39677 +#define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
39678 +#define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
39679 +#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
39680 +
39681 +/*
39682 + * The i386 can't do page protection for execute, and considers that the same are read.
39683 + * Also, write permissions imply read permissions. This is the closest we can get..
39684 + */
39685 +#define __P000 PAGE_NONE
39686 +#define __P001 PAGE_READONLY
39687 +#define __P010 PAGE_COPY
39688 +#define __P011 PAGE_COPY
39689 +#define __P100 PAGE_READONLY
39690 +#define __P101 PAGE_READONLY
39691 +#define __P110 PAGE_COPY
39692 +#define __P111 PAGE_COPY
39693 +
39694 +#define __S000 PAGE_NONE
39695 +#define __S001 PAGE_READONLY
39696 +#define __S010 PAGE_SHARED
39697 +#define __S011 PAGE_SHARED
39698 +#define __S100 PAGE_READONLY
39699 +#define __S101 PAGE_READONLY
39700 +#define __S110 PAGE_SHARED
39701 +#define __S111 PAGE_SHARED
39702 +
39703 +/*
39704 + * Define this if things work differently on an i386 and an i486:
39705 + * it will (on an i486) warn about kernel memory accesses that are
39706 + * done without a 'verify_area(VERIFY_WRITE,..)'
39707 + */
39708 +#undef TEST_VERIFY_AREA
39709 +
39710 +/* page table for 0-4MB for everybody */
39711 +extern unsigned long pg0[1024];
39712 +
39713 +/*
39714 + * BAD_PAGETABLE is used when we need a bogus page-table, while
39715 + * BAD_PAGE is used for a bogus page.
39716 + *
39717 + * ZERO_PAGE is a global shared page that is always zero: used
39718 + * for zero-mapped memory areas etc..
39719 + */
39720 +extern pte_t __bad_page(void);
39721 +extern pte_t * __bad_pagetable(void);
39722 +
39723 +#define BAD_PAGETABLE __bad_pagetable()
39724 +#define BAD_PAGE __bad_page()
39725 +
39726 +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
39727 +
39728 +/* number of bits that fit into a memory pointer */
39729 +#define BITS_PER_PTR                   (8*sizeof(unsigned long))
39730 +
39731 +/* to align the pointer to a pointer address */
39732 +#define PTR_MASK                       (~(sizeof(void*)-1))
39733 +
39734 +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
39735 +/* 64-bit machines, beware!  SRB. */
39736 +#define SIZEOF_PTR_LOG2                        2
39737 +
39738 +/* to find an entry in a page-table */
39739 +#define PAGE_PTR(address) \
39740 +((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
39741 +
39742 +#define pte_none(x)    !(pte_val(x) & ~_PAGE_NEWPAGE)
39743 +#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
39744 +
39745 +#define pte_clear(xp)  do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
39746 +
39747 +#define pmd_none(x)    (!(pmd_val(x) & ~_PAGE_NEWPAGE))
39748 +#define        pmd_bad(x)      ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
39749 +#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
39750 +#define pmd_clear(xp)  do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
39751 +
39752 +#define pmd_newpage(x)  (pmd_val(x) & _PAGE_NEWPAGE)
39753 +#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE)
39754 +
39755 +/*
39756 + * The "pgd_xxx()" functions here are trivial for a folded two-level
39757 + * setup: the pgd is never bad, and a pmd always exists (as it's folded
39758 + * into the pgd entry)
39759 + */
39760 +static inline int pgd_none(pgd_t pgd)          { return 0; }
39761 +static inline int pgd_bad(pgd_t pgd)           { return 0; }
39762 +static inline int pgd_present(pgd_t pgd)       { return 1; }
39763 +static inline void pgd_clear(pgd_t * pgdp)     { }
39764 +
39765 +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
39766 +
39767 +#define pte_page(pte) virt_to_page(__va(pte_val(pte)))
39768 +#define pmd_page(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
39769 +
39770 +extern struct page *phys_to_page(const unsigned long phys);
39771 +extern struct page *__virt_to_page(const unsigned long virt);
39772 +#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
39773 +
39774 +static inline pte_t pte_mknewprot(pte_t pte)
39775 +{
39776 +       pte_val(pte) |= _PAGE_NEWPROT;
39777 +       return(pte);
39778 +}
39779 +
39780 +static inline pte_t pte_mknewpage(pte_t pte)
39781 +{
39782 +       pte_val(pte) |= _PAGE_NEWPAGE;
39783 +       return(pte);
39784 +}
39785 +
39786 +static inline void set_pte(pte_t *pteptr, pte_t pteval)
39787 +{
39788 +       /* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so
39789 +        * fix_range knows to unmap it.  _PAGE_NEWPROT is specific to
39790 +        * mapped pages.
39791 +        */
39792 +       *pteptr = pte_mknewpage(pteval);
39793 +       if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr);
39794 +}
39795 +
39796 +/*
39797 + * (pmds are folded into pgds so this doesnt get actually called,
39798 + * but the define is needed for a generic inline function.)
39799 + */
39800 +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
39801 +#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
39802 +
39803 +/*
39804 + * The following only work if pte_present() is true.
39805 + * Undefined behaviour if not..
39806 + */
39807 +static inline int pte_read(pte_t pte)
39808 +{ 
39809 +       return((pte_val(pte) & _PAGE_USER) && 
39810 +              !(pte_val(pte) & _PAGE_PROTNONE));
39811 +}
39812 +
39813 +static inline int pte_exec(pte_t pte){
39814 +       return((pte_val(pte) & _PAGE_USER) &&
39815 +              !(pte_val(pte) & _PAGE_PROTNONE));
39816 +}
39817 +
39818 +static inline int pte_write(pte_t pte)
39819 +{
39820 +       return((pte_val(pte) & _PAGE_RW) &&
39821 +              !(pte_val(pte) & _PAGE_PROTNONE));
39822 +}
39823 +
39824 +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
39825 +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
39826 +static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
39827 +static inline int pte_newprot(pte_t pte)
39828 +{ 
39829 +       return(pte_present(pte) && (pte_val(pte) & _PAGE_NEWPROT)); 
39830 +}
39831 +
39832 +static inline pte_t pte_rdprotect(pte_t pte)
39833 +{ 
39834 +       pte_val(pte) &= ~_PAGE_USER; 
39835 +       return(pte_mknewprot(pte));
39836 +}
39837 +
39838 +static inline pte_t pte_exprotect(pte_t pte)
39839 +{ 
39840 +       pte_val(pte) &= ~_PAGE_USER;
39841 +       return(pte_mknewprot(pte));
39842 +}
39843 +
39844 +static inline pte_t pte_mkclean(pte_t pte)
39845 +{
39846 +       pte_val(pte) &= ~_PAGE_DIRTY; 
39847 +       return(pte);
39848 +}
39849 +
39850 +static inline pte_t pte_mkold(pte_t pte)       
39851 +{ 
39852 +       pte_val(pte) &= ~_PAGE_ACCESSED; 
39853 +       return(pte);
39854 +}
39855 +
39856 +static inline pte_t pte_wrprotect(pte_t pte)
39857 +{ 
39858 +       pte_val(pte) &= ~_PAGE_RW; 
39859 +       return(pte_mknewprot(pte)); 
39860 +}
39861 +
39862 +static inline pte_t pte_mkread(pte_t pte)
39863 +{ 
39864 +       pte_val(pte) |= _PAGE_USER; 
39865 +       return(pte_mknewprot(pte)); 
39866 +}
39867 +
39868 +static inline pte_t pte_mkexec(pte_t pte)
39869 +{ 
39870 +       pte_val(pte) |= _PAGE_USER; 
39871 +       return(pte_mknewprot(pte)); 
39872 +}
39873 +
39874 +static inline pte_t pte_mkdirty(pte_t pte)
39875 +{ 
39876 +       pte_val(pte) |= _PAGE_DIRTY; 
39877 +       return(pte);
39878 +}
39879 +
39880 +static inline pte_t pte_mkyoung(pte_t pte)
39881 +{
39882 +       pte_val(pte) |= _PAGE_ACCESSED; 
39883 +       return(pte);
39884 +}
39885 +
39886 +static inline pte_t pte_mkwrite(pte_t pte)     
39887 +{
39888 +       pte_val(pte) |= _PAGE_RW; 
39889 +       return(pte_mknewprot(pte)); 
39890 +}
39891 +
39892 +static inline pte_t pte_mkuptodate(pte_t pte)  
39893 +{
39894 +       pte_val(pte) &= ~_PAGE_NEWPAGE;
39895 +       if(pte_present(pte)) pte_val(pte) &= ~_PAGE_NEWPROT;
39896 +       return(pte); 
39897 +}
39898 +
39899 +extern unsigned long page_to_phys(struct page *page);
39900 +
39901 +/*
39902 + * Conversion functions: convert a page and protection to a page entry,
39903 + * and a page entry and page directory to the page they refer to.
39904 + */
39905 +
39906 +extern pte_t mk_pte(struct page *page, pgprot_t pgprot);
39907 +
39908 +/* This takes a physical page address that is used by the remapping 
39909 + * functions 
39910 + */
39911 +#define mk_pte_phys(phys, pgprot) \
39912 +       (pte_mknewpage(mk_pte(virt_to_page(__va(phys)), pgprot)))
39913 +
39914 +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
39915 +{
39916 +       pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
39917 +       if(pte_present(pte)) pte = pte_mknewpage(pte_mknewprot(pte));
39918 +       return pte; 
39919 +}
39920 +
39921 +/* to find an entry in a page-table-directory. */
39922 +#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
39923 +#define __pgd_offset(address) pgd_index(address)
39924 +
39925 +/* to find an entry in a page-table-directory */
39926 +#define pgd_offset(mm, address) \
39927 +((mm)->pgd + ((address) >> PGDIR_SHIFT))
39928 +
39929 +/* to find an entry in a kernel page-table-directory */
39930 +#define pgd_offset_k(address) pgd_offset(&init_mm, address)
39931 +
39932 +#define __pmd_offset(address) \
39933 +               (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
39934 +
39935 +/* Find an entry in the second-level page table.. */
39936 +static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
39937 +{
39938 +       return (pmd_t *) dir;
39939 +}
39940 +
39941 +/* Find an entry in the third-level page table.. */ 
39942 +#define pte_offset(pmd, address) \
39943 +       ((pte_t *) (pmd_page(*pmd) + ((address>>10) & ((PTRS_PER_PTE-1)<<2))))
39944 +
39945 +#define update_mmu_cache(vma,address,pte) do ; while (0)
39946 +
39947 +/* Encode and de-code a swap entry */
39948 +#define SWP_TYPE(x)                    (((x).val >> 3) & 0x7f)
39949 +#define SWP_OFFSET(x)                  ((x).val >> 10)
39950 +
39951 +#define SWP_ENTRY(type, offset) \
39952 +       ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
39953 +#define pte_to_swp_entry(pte) \
39954 +       ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
39955 +#define swp_entry_to_pte(x)            ((pte_t) { (x).val })
39956 +
39957 +#define PageSkip(x) (0)
39958 +#define kern_addr_valid(addr) (1)
39959 +
39960 +#include <asm-generic/pgtable.h>
39961 +
39962 +#endif
39963 +
39964 +#endif
39965 +/*
39966 + * Overrides for Emacs so that we follow Linus's tabbing style.
39967 + * Emacs will notice this stuff at the end of the file and automatically
39968 + * adjust the settings for this buffer only.  This must remain at the end
39969 + * of the file.
39970 + * ---------------------------------------------------------------------------
39971 + * Local variables:
39972 + * c-file-style: "linux"
39973 + * End:
39974 + */
39975 diff -Naur -X ../exclude-files orig/include/asm-um/poll.h um/include/asm-um/poll.h
39976 --- orig/include/asm-um/poll.h  1969-12-31 19:00:00.000000000 -0500
39977 +++ um/include/asm-um/poll.h    2003-10-21 03:26:07.000000000 -0400
39978 @@ -0,0 +1,6 @@
39979 +#ifndef __UM_POLL_H
39980 +#define __UM_POLL_H
39981 +
39982 +#include "asm/arch/poll.h"
39983 +
39984 +#endif
39985 diff -Naur -X ../exclude-files orig/include/asm-um/posix_types.h um/include/asm-um/posix_types.h
39986 --- orig/include/asm-um/posix_types.h   1969-12-31 19:00:00.000000000 -0500
39987 +++ um/include/asm-um/posix_types.h     2003-10-21 03:26:07.000000000 -0400
39988 @@ -0,0 +1,6 @@
39989 +#ifndef __UM_POSIX_TYPES_H
39990 +#define __UM_POSIX_TYPES_H
39991 +
39992 +#include "asm/arch/posix_types.h"
39993 +
39994 +#endif
39995 diff -Naur -X ../exclude-files orig/include/asm-um/processor-generic.h um/include/asm-um/processor-generic.h
39996 --- orig/include/asm-um/processor-generic.h     1969-12-31 19:00:00.000000000 -0500
39997 +++ um/include/asm-um/processor-generic.h       2004-02-14 06:28:59.000000000 -0500
39998 @@ -0,0 +1,177 @@
39999 +/* 
40000 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
40001 + * Licensed under the GPL
40002 + */
40003 +
40004 +#ifndef __UM_PROCESSOR_GENERIC_H
40005 +#define __UM_PROCESSOR_GENERIC_H
40006 +
40007 +struct pt_regs;
40008 +
40009 +struct task_struct;
40010 +
40011 +#include "linux/config.h"
40012 +#include "linux/signal.h"
40013 +#include "asm/ptrace.h"
40014 +#include "asm/siginfo.h"
40015 +#include "choose-mode.h"
40016 +
40017 +struct mm_struct;
40018 +
40019 +#define current_text_addr() ((void *) 0)
40020 +
40021 +#define cpu_relax()    do ; while (0)
40022 +
40023 +struct thread_struct {
40024 +       int forking;
40025 +       unsigned long kernel_stack;
40026 +       int nsyscalls;
40027 +       struct pt_regs regs;
40028 +       unsigned long cr2;
40029 +       int err;
40030 +       unsigned long trap_no;
40031 +       void *fault_addr;
40032 +       void *fault_catcher;
40033 +       struct task_struct *prev_sched;
40034 +       unsigned long temp_stack;
40035 +       void *exec_buf;
40036 +       struct arch_thread arch;
40037 +       union {
40038 +#ifdef CONFIG_MODE_TT
40039 +               struct {
40040 +                       int extern_pid;
40041 +                       int tracing;
40042 +                       int switch_pipe[2];
40043 +                       int singlestep_syscall;
40044 +                       int vm_seq;
40045 +               } tt;
40046 +#endif
40047 +#ifdef CONFIG_MODE_SKAS
40048 +               struct {
40049 +                       void *switch_buf;
40050 +                       void *fork_buf;
40051 +                       int mm_count;
40052 +               } skas;
40053 +#endif
40054 +       } mode;
40055 +       struct {
40056 +               int op;
40057 +               union {
40058 +                       struct {
40059 +                               int pid;
40060 +                       } fork, exec;
40061 +                       struct {
40062 +                               int (*proc)(void *);
40063 +                               void *arg;
40064 +                       } thread;
40065 +                       struct {
40066 +                               void (*proc)(void *);
40067 +                               void *arg;
40068 +                       } cb;
40069 +               } u;
40070 +       } request;
40071 +};
40072 +
40073 +#define INIT_THREAD \
40074 +{ \
40075 +       .forking                = 0, \
40076 +       .kernel_stack           = 0, \
40077 +       .nsyscalls              = 0, \
40078 +        .regs                  = EMPTY_REGS, \
40079 +       .cr2                    = 0, \
40080 +       .err                    = 0, \
40081 +       .fault_addr             = NULL, \
40082 +       .prev_sched             = NULL, \
40083 +       .temp_stack             = 0, \
40084 +       .exec_buf               = NULL, \
40085 +       .arch                   = INIT_ARCH_THREAD, \
40086 +       .request                = { 0 } \
40087 +}
40088 +
40089 +#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
40090 +
40091 +typedef struct {
40092 +       unsigned long seg;
40093 +} mm_segment_t;
40094 +
40095 +extern struct task_struct *alloc_task_struct(void);
40096 +extern void free_task_struct(struct task_struct *task);
40097 +
40098 +#define get_task_struct(tsk)      atomic_inc(&virt_to_page(tsk)->count)
40099 +
40100 +extern void release_thread(struct task_struct *);
40101 +extern int arch_kernel_thread(int (*fn)(void *), void * arg, 
40102 +                             unsigned long flags);
40103 +extern void dump_thread(struct pt_regs *regs, struct user *u);
40104 +
40105 +extern unsigned long thread_saved_pc(struct thread_struct *t);
40106 +
40107 +static inline void mm_copy_segments(struct mm_struct *from_mm, 
40108 +                                   struct mm_struct *new_mm)
40109 +{
40110 +}
40111 +
40112 +static inline void copy_segments(struct task_struct *p, 
40113 +                                struct mm_struct *new_mm)
40114 +{
40115 +}
40116 +
40117 +static inline void release_segments(struct mm_struct *mm)
40118 +{
40119 +}
40120 +
40121 +#define init_task      (init_task_union.task)
40122 +#define init_stack     (init_task_union.stack)
40123 +
40124 +/*
40125 + * User space process size: 3GB (default).
40126 + */
40127 +extern unsigned long task_size;
40128 +
40129 +#define TASK_SIZE      (task_size)
40130 +
40131 +/* This decides where the kernel will search for a free chunk of vm
40132 + * space during mmap's.
40133 + */
40134 +#define TASK_UNMAPPED_BASE     (0x40000000)
40135 +
40136 +extern void start_thread(struct pt_regs *regs, unsigned long entry, 
40137 +                        unsigned long stack);
40138 +
40139 +struct cpuinfo_um {
40140 +       unsigned long loops_per_jiffy;
40141 +       unsigned long *pgd_quick;
40142 +       unsigned long *pmd_quick;
40143 +       unsigned long *pte_quick;
40144 +       unsigned long pgtable_cache_sz;  
40145 +       int ipi_pipe[2];
40146 +};
40147 +
40148 +extern struct cpuinfo_um boot_cpu_data;
40149 +
40150 +#define my_cpu_data            cpu_data[smp_processor_id()]
40151 +
40152 +#ifdef CONFIG_SMP
40153 +extern struct cpuinfo_um cpu_data[];
40154 +#define current_cpu_data cpu_data[smp_processor_id()]
40155 +#else
40156 +#define cpu_data (&boot_cpu_data)
40157 +#define current_cpu_data boot_cpu_data
40158 +#endif
40159 +
40160 +#define KSTK_EIP(tsk) (PT_REGS_IP(&tsk->thread.regs))
40161 +#define KSTK_ESP(tsk) (PT_REGS_SP(&tsk->thread.regs))
40162 +#define get_wchan(p) (0)
40163 +
40164 +#endif
40165 +
40166 +/*
40167 + * Overrides for Emacs so that we follow Linus's tabbing style.
40168 + * Emacs will notice this stuff at the end of the file and automatically
40169 + * adjust the settings for this buffer only.  This must remain at the end
40170 + * of the file.
40171 + * ---------------------------------------------------------------------------
40172 + * Local variables:
40173 + * c-file-style: "linux"
40174 + * End:
40175 + */
40176 diff -Naur -X ../exclude-files orig/include/asm-um/processor-i386.h um/include/asm-um/processor-i386.h
40177 --- orig/include/asm-um/processor-i386.h        1969-12-31 19:00:00.000000000 -0500
40178 +++ um/include/asm-um/processor-i386.h  2004-02-14 06:28:59.000000000 -0500
40179 @@ -0,0 +1,35 @@
40180 +/* 
40181 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40182 + * Licensed under the GPL
40183 + */
40184 +
40185 +#ifndef __UM_PROCESSOR_I386_H
40186 +#define __UM_PROCESSOR_I386_H
40187 +
40188 +extern int cpu_has_xmm;
40189 +extern int cpu_has_cmov;
40190 +
40191 +struct arch_thread {
40192 +       unsigned long debugregs[8];
40193 +       int debugregs_seq;
40194 +};
40195 +
40196 +#define INIT_ARCH_THREAD { .debugregs                  = { [ 0 ... 7 ] = 0 }, \
40197 +                           .debugregs_seq      = 0 }
40198 +
40199 +#include "asm/arch/user.h"
40200 +
40201 +#include "asm/processor-generic.h"
40202 +
40203 +#endif
40204 +
40205 +/*
40206 + * Overrides for Emacs so that we follow Linus's tabbing style.
40207 + * Emacs will notice this stuff at the end of the file and automatically
40208 + * adjust the settings for this buffer only.  This must remain at the end
40209 + * of the file.
40210 + * ---------------------------------------------------------------------------
40211 + * Local variables:
40212 + * c-file-style: "linux"
40213 + * End:
40214 + */
40215 diff -Naur -X ../exclude-files orig/include/asm-um/processor-ppc.h um/include/asm-um/processor-ppc.h
40216 --- orig/include/asm-um/processor-ppc.h 1969-12-31 19:00:00.000000000 -0500
40217 +++ um/include/asm-um/processor-ppc.h   2003-10-21 03:26:07.000000000 -0400
40218 @@ -0,0 +1,15 @@
40219 +#ifndef __UM_PROCESSOR_PPC_H
40220 +#define __UM_PROCESSOR_PPC_H
40221 +
40222 +#if defined(__ASSEMBLY__)
40223 +
40224 +#define CONFIG_ALL_PPC
40225 +#include "arch/processor.h"
40226 +
40227 +#else
40228 +
40229 +#include "asm/processor-generic.h"
40230 +
40231 +#endif
40232 +
40233 +#endif
40234 diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-generic.h um/include/asm-um/ptrace-generic.h
40235 --- orig/include/asm-um/ptrace-generic.h        1969-12-31 19:00:00.000000000 -0500
40236 +++ um/include/asm-um/ptrace-generic.h  2004-02-14 06:28:59.000000000 -0500
40237 @@ -0,0 +1,74 @@
40238 +/* 
40239 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
40240 + * Licensed under the GPL
40241 + */
40242 +
40243 +#ifndef __UM_PTRACE_GENERIC_H
40244 +#define __UM_PTRACE_GENERIC_H
40245 +
40246 +#ifndef __ASSEMBLY__
40247 +
40248 +#include "linux/config.h"
40249 +
40250 +#include "asm/current.h"
40251 +
40252 +#define pt_regs pt_regs_subarch
40253 +#define show_regs show_regs_subarch
40254 +
40255 +#include "asm/arch/ptrace.h"
40256 +
40257 +#undef pt_regs
40258 +#undef show_regs
40259 +#undef user_mode
40260 +#undef instruction_pointer
40261 +
40262 +#include "sysdep/ptrace.h"
40263 +#include "skas_ptrace.h"
40264 +
40265 +struct pt_regs {
40266 +       union uml_pt_regs regs;
40267 +};
40268 +
40269 +#define EMPTY_REGS { regs : EMPTY_UML_PT_REGS }
40270 +
40271 +#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
40272 +#define PT_REGS_SP(r) UPT_SP(&(r)->regs)
40273 +
40274 +#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg)
40275 +#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val)
40276 +
40277 +#define PT_REGS_SET_SYSCALL_RETURN(r, res) \
40278 +       UPT_SET_SYSCALL_RETURN(&(r)->regs, res)
40279 +#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs)
40280 +
40281 +#define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs)
40282 +
40283 +#define PT_REGS_SC(r) UPT_SC(&(r)->regs)
40284 +
40285 +struct task_struct;
40286 +
40287 +extern unsigned long getreg(struct task_struct *child, int regno);
40288 +extern int putreg(struct task_struct *child, int regno, unsigned long value);
40289 +extern int get_fpregs(unsigned long buf, struct task_struct *child);
40290 +extern int set_fpregs(unsigned long buf, struct task_struct *child);
40291 +extern int get_fpxregs(unsigned long buf, struct task_struct *child);
40292 +extern int set_fpxregs(unsigned long buf, struct task_struct *tsk);
40293 +
40294 +extern void show_regs(struct pt_regs *regs);
40295 +
40296 +#define INIT_TASK_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
40297 +
40298 +#endif
40299 +
40300 +#endif
40301 +
40302 +/*
40303 + * Overrides for Emacs so that we follow Linus's tabbing style.
40304 + * Emacs will notice this stuff at the end of the file and automatically
40305 + * adjust the settings for this buffer only.  This must remain at the end
40306 + * of the file.
40307 + * ---------------------------------------------------------------------------
40308 + * Local variables:
40309 + * c-file-style: "linux"
40310 + * End:
40311 + */
40312 diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-i386.h um/include/asm-um/ptrace-i386.h
40313 --- orig/include/asm-um/ptrace-i386.h   1969-12-31 19:00:00.000000000 -0500
40314 +++ um/include/asm-um/ptrace-i386.h     2004-02-14 06:28:59.000000000 -0500
40315 @@ -0,0 +1,46 @@
40316 +/* 
40317 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
40318 + * Licensed under the GPL
40319 + */
40320 +
40321 +#ifndef __UM_PTRACE_I386_H
40322 +#define __UM_PTRACE_I386_H
40323 +
40324 +#include "sysdep/ptrace.h"
40325 +#include "asm/ptrace-generic.h"
40326 +
40327 +#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
40328 +#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs)
40329 +#define PT_REGS_ECX(r) UPT_ECX(&(r)->regs)
40330 +#define PT_REGS_EDX(r) UPT_EDX(&(r)->regs)
40331 +#define PT_REGS_ESI(r) UPT_ESI(&(r)->regs)
40332 +#define PT_REGS_EDI(r) UPT_EDI(&(r)->regs)
40333 +#define PT_REGS_EBP(r) UPT_EBP(&(r)->regs)
40334 +
40335 +#define PT_REGS_CS(r) UPT_CS(&(r)->regs)
40336 +#define PT_REGS_SS(r) UPT_SS(&(r)->regs)
40337 +#define PT_REGS_DS(r) UPT_DS(&(r)->regs)
40338 +#define PT_REGS_ES(r) UPT_ES(&(r)->regs)
40339 +#define PT_REGS_FS(r) UPT_FS(&(r)->regs)
40340 +#define PT_REGS_GS(r) UPT_GS(&(r)->regs)
40341 +
40342 +#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs)
40343 +
40344 +#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_EAX(r)
40345 +#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r)
40346 +#define PT_FIX_EXEC_STACK(sp) do ; while(0)
40347 +
40348 +#define user_mode(r) UPT_IS_USER(&(r)->regs)
40349 +
40350 +#endif
40351 +
40352 +/*
40353 + * Overrides for Emacs so that we follow Linus's tabbing style.
40354 + * Emacs will notice this stuff at the end of the file and automatically
40355 + * adjust the settings for this buffer only.  This must remain at the end
40356 + * of the file.
40357 + * ---------------------------------------------------------------------------
40358 + * Local variables:
40359 + * c-file-style: "linux"
40360 + * End:
40361 + */
40362 diff -Naur -X ../exclude-files orig/include/asm-um/resource.h um/include/asm-um/resource.h
40363 --- orig/include/asm-um/resource.h      1969-12-31 19:00:00.000000000 -0500
40364 +++ um/include/asm-um/resource.h        2003-10-21 03:26:07.000000000 -0400
40365 @@ -0,0 +1,6 @@
40366 +#ifndef __UM_RESOURCE_H
40367 +#define __UM_RESOURCE_H
40368 +
40369 +#include "asm/arch/resource.h"
40370 +
40371 +#endif
40372 diff -Naur -X ../exclude-files orig/include/asm-um/rwlock.h um/include/asm-um/rwlock.h
40373 --- orig/include/asm-um/rwlock.h        1969-12-31 19:00:00.000000000 -0500
40374 +++ um/include/asm-um/rwlock.h  2003-10-21 03:26:07.000000000 -0400
40375 @@ -0,0 +1,6 @@
40376 +#ifndef __UM_RWLOCK_H
40377 +#define __UM_RWLOCK_H
40378 +
40379 +#include "asm/arch/rwlock.h"
40380 +
40381 +#endif
40382 diff -Naur -X ../exclude-files orig/include/asm-um/rwsem.h um/include/asm-um/rwsem.h
40383 --- orig/include/asm-um/rwsem.h 1969-12-31 19:00:00.000000000 -0500
40384 +++ um/include/asm-um/rwsem.h   2004-02-14 06:28:59.000000000 -0500
40385 @@ -0,0 +1,10 @@
40386 +#ifndef __UM_RWSEM_H__
40387 +#define __UM_RWSEM_H__
40388 +
40389 +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
40390 +#define __builtin_expect(exp,c) (exp)
40391 +#endif
40392 +
40393 +#include "asm/arch/rwsem.h"
40394 +
40395 +#endif
40396 diff -Naur -X ../exclude-files orig/include/asm-um/scatterlist.h um/include/asm-um/scatterlist.h
40397 --- orig/include/asm-um/scatterlist.h   1969-12-31 19:00:00.000000000 -0500
40398 +++ um/include/asm-um/scatterlist.h     2003-10-21 03:26:07.000000000 -0400
40399 @@ -0,0 +1,6 @@
40400 +#ifndef __UM_SCATTERLIST_H
40401 +#define __UM_SCATTERLIST_H
40402 +
40403 +#include "asm/arch/scatterlist.h"
40404 +
40405 +#endif
40406 diff -Naur -X ../exclude-files orig/include/asm-um/segment.h um/include/asm-um/segment.h
40407 --- orig/include/asm-um/segment.h       1969-12-31 19:00:00.000000000 -0500
40408 +++ um/include/asm-um/segment.h 2003-10-21 03:26:07.000000000 -0400
40409 @@ -0,0 +1,4 @@
40410 +#ifndef __UM_SEGMENT_H
40411 +#define __UM_SEGMENT_H
40412 +
40413 +#endif
40414 diff -Naur -X ../exclude-files orig/include/asm-um/semaphore.h um/include/asm-um/semaphore.h
40415 --- orig/include/asm-um/semaphore.h     1969-12-31 19:00:00.000000000 -0500
40416 +++ um/include/asm-um/semaphore.h       2004-02-14 06:28:59.000000000 -0500
40417 @@ -0,0 +1,6 @@
40418 +#ifndef __UM_SEMAPHORE_H
40419 +#define __UM_SEMAPHORE_H
40420 +
40421 +#include "asm/arch/semaphore.h"
40422 +
40423 +#endif
40424 diff -Naur -X ../exclude-files orig/include/asm-um/sembuf.h um/include/asm-um/sembuf.h
40425 --- orig/include/asm-um/sembuf.h        1969-12-31 19:00:00.000000000 -0500
40426 +++ um/include/asm-um/sembuf.h  2003-10-21 03:26:07.000000000 -0400
40427 @@ -0,0 +1,6 @@
40428 +#ifndef __UM_SEMBUF_H
40429 +#define __UM_SEMBUF_H
40430 +
40431 +#include "asm/arch/sembuf.h"
40432 +
40433 +#endif
40434 diff -Naur -X ../exclude-files orig/include/asm-um/serial.h um/include/asm-um/serial.h
40435 --- orig/include/asm-um/serial.h        1969-12-31 19:00:00.000000000 -0500
40436 +++ um/include/asm-um/serial.h  2003-10-21 03:26:07.000000000 -0400
40437 @@ -0,0 +1,6 @@
40438 +#ifndef __UM_SERIAL_H
40439 +#define __UM_SERIAL_H
40440 +
40441 +#include "asm/arch/serial.h"
40442 +
40443 +#endif
40444 diff -Naur -X ../exclude-files orig/include/asm-um/shmbuf.h um/include/asm-um/shmbuf.h
40445 --- orig/include/asm-um/shmbuf.h        1969-12-31 19:00:00.000000000 -0500
40446 +++ um/include/asm-um/shmbuf.h  2003-10-21 03:26:07.000000000 -0400
40447 @@ -0,0 +1,6 @@
40448 +#ifndef __UM_SHMBUF_H
40449 +#define __UM_SHMBUF_H
40450 +
40451 +#include "asm/arch/shmbuf.h"
40452 +
40453 +#endif
40454 diff -Naur -X ../exclude-files orig/include/asm-um/shmparam.h um/include/asm-um/shmparam.h
40455 --- orig/include/asm-um/shmparam.h      1969-12-31 19:00:00.000000000 -0500
40456 +++ um/include/asm-um/shmparam.h        2003-10-21 03:26:07.000000000 -0400
40457 @@ -0,0 +1,6 @@
40458 +#ifndef __UM_SHMPARAM_H
40459 +#define __UM_SHMPARAM_H
40460 +
40461 +#include "asm/arch/shmparam.h"
40462 +
40463 +#endif
40464 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-generic.h um/include/asm-um/sigcontext-generic.h
40465 --- orig/include/asm-um/sigcontext-generic.h    1969-12-31 19:00:00.000000000 -0500
40466 +++ um/include/asm-um/sigcontext-generic.h      2003-10-21 03:26:07.000000000 -0400
40467 @@ -0,0 +1,6 @@
40468 +#ifndef __UM_SIGCONTEXT_GENERIC_H
40469 +#define __UM_SIGCONTEXT_GENERIC_H
40470 +
40471 +#include "asm/arch/sigcontext.h"
40472 +
40473 +#endif
40474 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-i386.h um/include/asm-um/sigcontext-i386.h
40475 --- orig/include/asm-um/sigcontext-i386.h       1969-12-31 19:00:00.000000000 -0500
40476 +++ um/include/asm-um/sigcontext-i386.h 2003-10-21 03:26:07.000000000 -0400
40477 @@ -0,0 +1,6 @@
40478 +#ifndef __UM_SIGCONTEXT_I386_H
40479 +#define __UM_SIGCONTEXT_I386_H
40480 +
40481 +#include "asm/sigcontext-generic.h"
40482 +
40483 +#endif
40484 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-ppc.h um/include/asm-um/sigcontext-ppc.h
40485 --- orig/include/asm-um/sigcontext-ppc.h        1969-12-31 19:00:00.000000000 -0500
40486 +++ um/include/asm-um/sigcontext-ppc.h  2003-10-21 03:26:07.000000000 -0400
40487 @@ -0,0 +1,10 @@
40488 +#ifndef __UM_SIGCONTEXT_PPC_H
40489 +#define __UM_SIGCONTEXT_PPC_H
40490 +
40491 +#define pt_regs sys_pt_regs
40492 +
40493 +#include "asm/sigcontext-generic.h"
40494 +
40495 +#undef pt_regs
40496 +
40497 +#endif
40498 diff -Naur -X ../exclude-files orig/include/asm-um/siginfo.h um/include/asm-um/siginfo.h
40499 --- orig/include/asm-um/siginfo.h       1969-12-31 19:00:00.000000000 -0500
40500 +++ um/include/asm-um/siginfo.h 2004-02-14 06:28:59.000000000 -0500
40501 @@ -0,0 +1,6 @@
40502 +#ifndef __UM_SIGINFO_H
40503 +#define __UM_SIGINFO_H
40504 +
40505 +#include "asm/arch/siginfo.h"
40506 +
40507 +#endif
40508 diff -Naur -X ../exclude-files orig/include/asm-um/signal.h um/include/asm-um/signal.h
40509 --- orig/include/asm-um/signal.h        1969-12-31 19:00:00.000000000 -0500
40510 +++ um/include/asm-um/signal.h  2004-02-14 06:28:59.000000000 -0500
40511 @@ -0,0 +1,22 @@
40512 +/* 
40513 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40514 + * Licensed under the GPL
40515 + */
40516 +
40517 +#ifndef __UM_SIGNAL_H
40518 +#define __UM_SIGNAL_H
40519 +
40520 +#include "asm/arch/signal.h"
40521 +
40522 +#endif
40523 +
40524 +/*
40525 + * Overrides for Emacs so that we follow Linus's tabbing style.
40526 + * Emacs will notice this stuff at the end of the file and automatically
40527 + * adjust the settings for this buffer only.  This must remain at the end
40528 + * of the file.
40529 + * ---------------------------------------------------------------------------
40530 + * Local variables:
40531 + * c-file-style: "linux"
40532 + * End:
40533 + */
40534 diff -Naur -X ../exclude-files orig/include/asm-um/smp.h um/include/asm-um/smp.h
40535 --- orig/include/asm-um/smp.h   1969-12-31 19:00:00.000000000 -0500
40536 +++ um/include/asm-um/smp.h     2004-02-14 06:28:59.000000000 -0500
40537 @@ -0,0 +1,19 @@
40538 +#ifndef __UM_SMP_H
40539 +#define __UM_SMP_H
40540 +
40541 +#ifdef CONFIG_SMP
40542 +
40543 +#include "linux/config.h"
40544 +#include "asm/current.h"
40545 +
40546 +#define smp_processor_id() (current->processor)
40547 +#define cpu_logical_map(n) (n)
40548 +#define cpu_number_map(n) (n)
40549 +#define PROC_CHANGE_PENALTY    15 /* Pick a number, any number */
40550 +extern int hard_smp_processor_id(void);
40551 +extern unsigned long cpu_online_map;
40552 +#define NO_PROC_ID -1
40553 +
40554 +#endif
40555 +
40556 +#endif
40557 diff -Naur -X ../exclude-files orig/include/asm-um/smplock.h um/include/asm-um/smplock.h
40558 --- orig/include/asm-um/smplock.h       1969-12-31 19:00:00.000000000 -0500
40559 +++ um/include/asm-um/smplock.h 2004-02-14 06:28:59.000000000 -0500
40560 @@ -0,0 +1,6 @@
40561 +#ifndef __UM_SMPLOCK_H
40562 +#define __UM_SMPLOCK_H
40563 +
40564 +#include "asm/arch/smplock.h"
40565 +
40566 +#endif
40567 diff -Naur -X ../exclude-files orig/include/asm-um/socket.h um/include/asm-um/socket.h
40568 --- orig/include/asm-um/socket.h        1969-12-31 19:00:00.000000000 -0500
40569 +++ um/include/asm-um/socket.h  2003-11-07 02:10:43.000000000 -0500
40570 @@ -0,0 +1,6 @@
40571 +#ifndef __UM_SOCKET_H
40572 +#define __UM_SOCKET_H
40573 +
40574 +#include "asm/arch/socket.h"
40575 +
40576 +#endif
40577 diff -Naur -X ../exclude-files orig/include/asm-um/sockios.h um/include/asm-um/sockios.h
40578 --- orig/include/asm-um/sockios.h       1969-12-31 19:00:00.000000000 -0500
40579 +++ um/include/asm-um/sockios.h 2003-10-21 03:26:07.000000000 -0400
40580 @@ -0,0 +1,6 @@
40581 +#ifndef __UM_SOCKIOS_H
40582 +#define __UM_SOCKIOS_H
40583 +
40584 +#include "asm/arch/sockios.h"
40585 +
40586 +#endif
40587 diff -Naur -X ../exclude-files orig/include/asm-um/softirq.h um/include/asm-um/softirq.h
40588 --- orig/include/asm-um/softirq.h       1969-12-31 19:00:00.000000000 -0500
40589 +++ um/include/asm-um/softirq.h 2004-02-14 06:28:59.000000000 -0500
40590 @@ -0,0 +1,13 @@
40591 +#ifndef __UM_SOFTIRQ_H
40592 +#define __UM_SOFTIRQ_H
40593 +
40594 +#include "linux/smp.h"
40595 +#include "asm/system.h"
40596 +#include "asm/processor.h"
40597 +
40598 +/* A gratuitous name change */
40599 +#define i386_bh_lock um_bh_lock
40600 +#include "asm/arch/softirq.h"
40601 +#undef i386_bh_lock
40602 +
40603 +#endif
40604 diff -Naur -X ../exclude-files orig/include/asm-um/spinlock.h um/include/asm-um/spinlock.h
40605 --- orig/include/asm-um/spinlock.h      1969-12-31 19:00:00.000000000 -0500
40606 +++ um/include/asm-um/spinlock.h        2004-02-14 06:28:59.000000000 -0500
40607 @@ -0,0 +1,10 @@
40608 +#ifndef __UM_SPINLOCK_H
40609 +#define __UM_SPINLOCK_H
40610 +
40611 +#include "linux/config.h"
40612 +
40613 +#ifdef CONFIG_SMP
40614 +#include "asm/arch/spinlock.h"
40615 +#endif
40616 +
40617 +#endif
40618 diff -Naur -X ../exclude-files orig/include/asm-um/statfs.h um/include/asm-um/statfs.h
40619 --- orig/include/asm-um/statfs.h        1969-12-31 19:00:00.000000000 -0500
40620 +++ um/include/asm-um/statfs.h  2004-02-14 06:28:59.000000000 -0500
40621 @@ -0,0 +1,6 @@
40622 +#ifndef _UM_STATFS_H
40623 +#define _UM_STATFS_H
40624 +
40625 +#include "asm/arch/statfs.h"
40626 +
40627 +#endif
40628 diff -Naur -X ../exclude-files orig/include/asm-um/stat.h um/include/asm-um/stat.h
40629 --- orig/include/asm-um/stat.h  1969-12-31 19:00:00.000000000 -0500
40630 +++ um/include/asm-um/stat.h    2003-10-21 03:26:07.000000000 -0400
40631 @@ -0,0 +1,6 @@
40632 +#ifndef __UM_STAT_H
40633 +#define __UM_STAT_H
40634 +
40635 +#include "asm/arch/stat.h"
40636 +
40637 +#endif
40638 diff -Naur -X ../exclude-files orig/include/asm-um/string.h um/include/asm-um/string.h
40639 --- orig/include/asm-um/string.h        1969-12-31 19:00:00.000000000 -0500
40640 +++ um/include/asm-um/string.h  2004-01-16 03:32:58.000000000 -0500
40641 @@ -0,0 +1,7 @@
40642 +#ifndef __UM_STRING_H
40643 +#define __UM_STRING_H
40644 +
40645 +#include "asm/arch/string.h"
40646 +#include "asm/archparam.h"
40647 +
40648 +#endif
40649 diff -Naur -X ../exclude-files orig/include/asm-um/system-generic.h um/include/asm-um/system-generic.h
40650 --- orig/include/asm-um/system-generic.h        1969-12-31 19:00:00.000000000 -0500
40651 +++ um/include/asm-um/system-generic.h  2004-02-14 06:28:59.000000000 -0500
40652 @@ -0,0 +1,50 @@
40653 +#ifndef __UM_SYSTEM_GENERIC_H
40654 +#define __UM_SYSTEM_GENERIC_H
40655 +
40656 +#include "asm/arch/system.h"
40657 +
40658 +#undef prepare_to_switch
40659 +#undef switch_to
40660 +#undef __save_flags
40661 +#undef save_flags
40662 +#undef __restore_flags
40663 +#undef restore_flags
40664 +#undef __cli
40665 +#undef __sti
40666 +#undef cli
40667 +#undef sti
40668 +#undef local_irq_save
40669 +#undef local_irq_restore
40670 +#undef local_irq_disable
40671 +#undef local_irq_enable
40672 +
40673 +#define prepare_to_switch() do ; while(0)
40674 +
40675 +void *_switch_to(void *prev, void *next);
40676 +
40677 +#define switch_to(prev, next, last) prev = _switch_to(prev, next)
40678 +
40679 +extern int get_signals(void);
40680 +extern int set_signals(int enable);
40681 +extern void block_signals(void);
40682 +extern void unblock_signals(void);
40683 +
40684 +#define local_irq_save(flags) do { (flags) = set_signals(0); } while(0)
40685 +
40686 +#define local_irq_restore(flags) do { set_signals(flags); } while(0)
40687 +
40688 +#define local_irq_enable() unblock_signals()
40689 +#define local_irq_disable() block_signals()
40690 +
40691 +#define __sti() unblock_signals()
40692 +#define sti() unblock_signals()
40693 +#define __cli() block_signals()
40694 +#define cli() block_signals()
40695 +
40696 +#define __save_flags(x) do { (x) = get_signals(); } while(0)
40697 +#define save_flags(x) __save_flags(x)
40698 +
40699 +#define __restore_flags(x) local_irq_restore(x)
40700 +#define restore_flags(x) __restore_flags(x)
40701 +
40702 +#endif
40703 diff -Naur -X ../exclude-files orig/include/asm-um/system-i386.h um/include/asm-um/system-i386.h
40704 --- orig/include/asm-um/system-i386.h   1969-12-31 19:00:00.000000000 -0500
40705 +++ um/include/asm-um/system-i386.h     2004-02-14 06:28:59.000000000 -0500
40706 @@ -0,0 +1,39 @@
40707 +#ifndef __UM_SYSTEM_I386_H
40708 +#define __UM_SYSTEM_I386_H
40709 +
40710 +#include "asm/system-generic.h"
40711 +
40712 +#define __HAVE_ARCH_CMPXCHG 1
40713 +
40714 +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
40715 +                                     unsigned long new, int size)
40716 +{
40717 +       unsigned long prev;
40718 +       switch (size) {
40719 +       case 1:
40720 +               __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
40721 +                                    : "=a"(prev)
40722 +                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
40723 +                                    : "memory");
40724 +               return prev;
40725 +       case 2:
40726 +               __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
40727 +                                    : "=a"(prev)
40728 +                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
40729 +                                    : "memory");
40730 +               return prev;
40731 +       case 4:
40732 +               __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
40733 +                                    : "=a"(prev)
40734 +                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
40735 +                                    : "memory");
40736 +               return prev;
40737 +       }
40738 +       return old;
40739 +}
40740 +
40741 +#define cmpxchg(ptr,o,n)\
40742 +       ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
40743 +                                       (unsigned long)(n),sizeof(*(ptr))))
40744 +    
40745 +#endif
40746 diff -Naur -X ../exclude-files orig/include/asm-um/system-ppc.h um/include/asm-um/system-ppc.h
40747 --- orig/include/asm-um/system-ppc.h    1969-12-31 19:00:00.000000000 -0500
40748 +++ um/include/asm-um/system-ppc.h      2003-10-21 03:26:07.000000000 -0400
40749 @@ -0,0 +1,12 @@
40750 +#ifndef __UM_SYSTEM_PPC_H
40751 +#define __UM_SYSTEM_PPC_H
40752 +
40753 +#define _switch_to _ppc_switch_to
40754 +
40755 +#include "asm/arch/system.h"
40756 +
40757 +#undef _switch_to
40758
40759 +#include "asm/system-generic.h"
40760 +
40761 +#endif
40762 diff -Naur -X ../exclude-files orig/include/asm-um/termbits.h um/include/asm-um/termbits.h
40763 --- orig/include/asm-um/termbits.h      1969-12-31 19:00:00.000000000 -0500
40764 +++ um/include/asm-um/termbits.h        2003-11-07 02:10:43.000000000 -0500
40765 @@ -0,0 +1,6 @@
40766 +#ifndef __UM_TERMBITS_H
40767 +#define __UM_TERMBITS_H
40768 +
40769 +#include "asm/arch/termbits.h"
40770 +
40771 +#endif
40772 diff -Naur -X ../exclude-files orig/include/asm-um/termios.h um/include/asm-um/termios.h
40773 --- orig/include/asm-um/termios.h       1969-12-31 19:00:00.000000000 -0500
40774 +++ um/include/asm-um/termios.h 2003-12-16 22:26:55.000000000 -0500
40775 @@ -0,0 +1,6 @@
40776 +#ifndef __UM_TERMIOS_H
40777 +#define __UM_TERMIOS_H
40778 +
40779 +#include "asm/arch/termios.h"
40780 +
40781 +#endif
40782 diff -Naur -X ../exclude-files orig/include/asm-um/timex.h um/include/asm-um/timex.h
40783 --- orig/include/asm-um/timex.h 1969-12-31 19:00:00.000000000 -0500
40784 +++ um/include/asm-um/timex.h   2004-02-14 06:28:59.000000000 -0500
40785 @@ -0,0 +1,18 @@
40786 +#ifndef __UM_TIMEX_H
40787 +#define __UM_TIMEX_H
40788 +
40789 +#include "linux/time.h"
40790 +
40791 +typedef unsigned long cycles_t;
40792 +
40793 +#define cacheflush_time (0)
40794 +
40795 +static inline cycles_t get_cycles (void)
40796 +{
40797 +       return 0;
40798 +}
40799 +
40800 +#define vxtime_lock()          do ; while (0)
40801 +#define vxtime_unlock()                do ; while (0)
40802 +
40803 +#endif
40804 diff -Naur -X ../exclude-files orig/include/asm-um/tlb.h um/include/asm-um/tlb.h
40805 --- orig/include/asm-um/tlb.h   1969-12-31 19:00:00.000000000 -0500
40806 +++ um/include/asm-um/tlb.h     2003-10-21 03:26:07.000000000 -0400
40807 @@ -0,0 +1 @@
40808 +#include <asm-generic/tlb.h>
40809 diff -Naur -X ../exclude-files orig/include/asm-um/types.h um/include/asm-um/types.h
40810 --- orig/include/asm-um/types.h 1969-12-31 19:00:00.000000000 -0500
40811 +++ um/include/asm-um/types.h   2004-01-16 03:32:58.000000000 -0500
40812 @@ -0,0 +1,6 @@
40813 +#ifndef __UM_TYPES_H
40814 +#define __UM_TYPES_H
40815 +
40816 +#include "asm/arch/types.h"
40817 +
40818 +#endif
40819 diff -Naur -X ../exclude-files orig/include/asm-um/uaccess.h um/include/asm-um/uaccess.h
40820 --- orig/include/asm-um/uaccess.h       1969-12-31 19:00:00.000000000 -0500
40821 +++ um/include/asm-um/uaccess.h 2004-02-14 06:28:59.000000000 -0500
40822 @@ -0,0 +1,99 @@
40823 +/* 
40824 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40825 + * Licensed under the GPL
40826 + */
40827 +
40828 +#ifndef __UM_UACCESS_H
40829 +#define __UM_UACCESS_H
40830 +
40831 +#include "linux/sched.h"
40832 +
40833 +#define VERIFY_READ 0
40834 +#define VERIFY_WRITE 1
40835 +
40836 +/*
40837 + * The fs value determines whether argument validity checking should be
40838 + * performed or not.  If get_fs() == USER_DS, checking is performed, with
40839 + * get_fs() == KERNEL_DS, checking is bypassed.
40840 + *
40841 + * For historical reasons, these macros are grossly misnamed.
40842 + */
40843 +
40844 +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
40845 +
40846 +#define KERNEL_DS      MAKE_MM_SEG(0xFFFFFFFF)
40847 +#define USER_DS                MAKE_MM_SEG(TASK_SIZE)
40848 +
40849 +#define get_ds()       (KERNEL_DS)
40850 +#define get_fs()       (current->addr_limit)
40851 +#define set_fs(x)      (current->addr_limit = (x))
40852 +
40853 +#define segment_eq(a, b) ((a).seg == (b).seg)
40854 +
40855 +#include "um_uaccess.h"
40856 +
40857 +#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
40858 +
40859 +#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
40860 +
40861 +#define __get_user(x, ptr) \
40862 +({ \
40863 +        const __typeof__(ptr) __private_ptr = ptr; \
40864 +        __typeof__(*(__private_ptr)) __private_val; \
40865 +        int __private_ret = -EFAULT; \
40866 +        (x) = 0; \
40867 +       if (__copy_from_user(&__private_val, (__private_ptr), \
40868 +           sizeof(*(__private_ptr))) == 0) {\
40869 +               (x) = (__typeof__(*(__private_ptr))) __private_val; \
40870 +               __private_ret = 0; \
40871 +       } \
40872 +        __private_ret; \
40873 +}) 
40874 +
40875 +#define get_user(x, ptr) \
40876 +({ \
40877 +        const __typeof__((*ptr)) *private_ptr = (ptr); \
40878 +        (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \
40879 +        __get_user(x, private_ptr) : ((x) = 0, -EFAULT)); \
40880 +})
40881 +
40882 +#define __put_user(x, ptr) \
40883 +({ \
40884 +        __typeof__(ptr) __private_ptr = ptr; \
40885 +        __typeof__(*(__private_ptr)) __private_val; \
40886 +        int __private_ret = -EFAULT; \
40887 +        __private_val = (__typeof__(*(__private_ptr))) (x); \
40888 +        if (__copy_to_user((__private_ptr), &__private_val, \
40889 +                          sizeof(*(__private_ptr))) == 0) { \
40890 +               __private_ret = 0; \
40891 +       } \
40892 +        __private_ret; \
40893 +})
40894 +
40895 +#define put_user(x, ptr) \
40896 +({ \
40897 +        __typeof__(*(ptr)) *private_ptr = (ptr); \
40898 +        (access_ok(VERIFY_WRITE, private_ptr, sizeof(*private_ptr)) ? \
40899 +        __put_user(x, private_ptr) : -EFAULT); \
40900 +})
40901 +
40902 +#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
40903 +
40904 +struct exception_table_entry
40905 +{
40906 +        unsigned long insn;
40907 +       unsigned long fixup;
40908 +};
40909 +
40910 +#endif
40911 +
40912 +/*
40913 + * Overrides for Emacs so that we follow Linus's tabbing style.
40914 + * Emacs will notice this stuff at the end of the file and automatically
40915 + * adjust the settings for this buffer only.  This must remain at the end
40916 + * of the file.
40917 + * ---------------------------------------------------------------------------
40918 + * Local variables:
40919 + * c-file-style: "linux"
40920 + * End:
40921 + */
40922 diff -Naur -X ../exclude-files orig/include/asm-um/ucontext.h um/include/asm-um/ucontext.h
40923 --- orig/include/asm-um/ucontext.h      1969-12-31 19:00:00.000000000 -0500
40924 +++ um/include/asm-um/ucontext.h        2003-10-21 03:26:07.000000000 -0400
40925 @@ -0,0 +1,6 @@
40926 +#ifndef _ASM_UM_UCONTEXT_H
40927 +#define _ASM_UM_UCONTEXT_H
40928 +
40929 +#include "asm/arch/ucontext.h"
40930 +
40931 +#endif
40932 diff -Naur -X ../exclude-files orig/include/asm-um/unaligned.h um/include/asm-um/unaligned.h
40933 --- orig/include/asm-um/unaligned.h     1969-12-31 19:00:00.000000000 -0500
40934 +++ um/include/asm-um/unaligned.h       2003-10-21 03:26:07.000000000 -0400
40935 @@ -0,0 +1,6 @@
40936 +#ifndef __UM_UNALIGNED_H
40937 +#define __UM_UNALIGNED_H
40938 +
40939 +#include "asm/arch/unaligned.h"
40940 +
40941 +#endif
40942 diff -Naur -X ../exclude-files orig/include/asm-um/unistd.h um/include/asm-um/unistd.h
40943 --- orig/include/asm-um/unistd.h        1969-12-31 19:00:00.000000000 -0500
40944 +++ um/include/asm-um/unistd.h  2004-02-14 06:29:00.000000000 -0500
40945 @@ -0,0 +1,121 @@
40946 +/* 
40947 + * Copyright (C) 2000, 2001  Jeff Dike (jdike@karaya.com)
40948 + * Licensed under the GPL
40949 + */
40950 +
40951 +#ifndef _UM_UNISTD_H_
40952 +#define _UM_UNISTD_H_
40953 +
40954 +#include "linux/resource.h"
40955 +#include "asm/uaccess.h"
40956 +
40957 +extern long sys_open(const char *filename, int flags, int mode);
40958 +extern long sys_dup(unsigned int fildes);
40959 +extern long sys_close(unsigned int fd);
40960 +extern int um_execve(const char *file, char *const argv[], char *const env[]);
40961 +extern long sys_setsid(void);
40962 +extern long sys_waitpid(pid_t pid, unsigned int * stat_addr, int options);
40963 +extern long sys_wait4(pid_t pid,unsigned int *stat_addr, int options, 
40964 +                     struct rusage *ru);
40965 +extern long sys_mount(char *dev_name, char *dir_name, char *type, 
40966 +                     unsigned long flags, void *data);
40967 +extern long sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, 
40968 +                      struct timeval *tvp);
40969 +extern long sys_lseek(unsigned int fildes, unsigned long offset, int whence);
40970 +extern long sys_read(unsigned int fildes, char *buf, int len);
40971 +extern long sys_write(unsigned int fildes, char *buf, int len);
40972 +
40973 +#ifdef __KERNEL_SYSCALLS__
40974 +
40975 +#define KERNEL_CALL(ret_t, sys, args...)       \
40976 +       mm_segment_t fs = get_fs();             \
40977 +       ret_t ret;                              \
40978 +       set_fs(KERNEL_DS);                      \
40979 +       ret = sys(args);                        \
40980 +       set_fs(fs);                             \
40981 +       if (ret >= 0)                           \
40982 +               return ret;                     \
40983 +       errno = -(long)ret;                     \
40984 +       return -1;
40985 +
40986 +static inline long open(const char *pathname, int flags, int mode) 
40987 +{
40988 +       KERNEL_CALL(int, sys_open, pathname, flags, mode)
40989 +}
40990 +
40991 +static inline long dup(unsigned int fd)
40992 +{
40993 +       KERNEL_CALL(int, sys_dup, fd);
40994 +}
40995 +
40996 +static inline long close(unsigned int fd)
40997 +{
40998 +       KERNEL_CALL(int, sys_close, fd);
40999 +}
41000 +
41001 +static inline int execve(const char *filename, char *const argv[], 
41002 +                        char *const envp[])
41003 +{
41004 +       KERNEL_CALL(int, um_execve, filename, argv, envp);
41005 +}
41006 +
41007 +static inline long waitpid(pid_t pid, unsigned int *status, int options)
41008 +{
41009 +       KERNEL_CALL(pid_t, sys_wait4, pid, status, options, NULL)
41010 +}
41011 +
41012 +static inline pid_t wait(int *status)
41013 +{
41014 +       KERNEL_CALL(pid_t, sys_wait4, -1, status, 0, NULL)
41015 +}
41016 +
41017 +static inline pid_t setsid(void)
41018 +{
41019 +       KERNEL_CALL(pid_t, sys_setsid)
41020 +}
41021 +
41022 +static inline long lseek(unsigned int fd, off_t offset, unsigned int whence)
41023 +{
41024 +       KERNEL_CALL(long, sys_lseek, fd, offset, whence)
41025 +}
41026 +
41027 +static inline int read(unsigned int fd, char * buf, int len)
41028 +{
41029 +       KERNEL_CALL(int, sys_read, fd, buf, len)
41030 +}
41031 +
41032 +static inline int write(unsigned int fd, char * buf, int len)
41033 +{
41034 +       KERNEL_CALL(int, sys_write, fd, buf, len)
41035 +}
41036 +
41037 +#endif
41038 +
41039 +/* Save the value of __KERNEL_SYSCALLS__, undefine it, include the underlying
41040 + * arch's unistd.h for the system call numbers, and restore the old 
41041 + * __KERNEL_SYSCALLS__.
41042 + */
41043 +
41044 +#ifdef __KERNEL_SYSCALLS__
41045 +#define __SAVE_KERNEL_SYSCALLS__ __KERNEL_SYSCALLS__
41046 +#endif
41047 +
41048 +#undef __KERNEL_SYSCALLS__
41049 +#include "asm/arch/unistd.h"
41050 +
41051 +#ifdef __KERNEL_SYSCALLS__
41052 +#define __KERNEL_SYSCALLS__ __SAVE_KERNEL_SYSCALLS__
41053 +#endif
41054 +
41055 +#endif
41056 +
41057 +/*
41058 + * Overrides for Emacs so that we follow Linus's tabbing style.
41059 + * Emacs will notice this stuff at the end of the file and automatically
41060 + * adjust the settings for this buffer only.  This must remain at the end
41061 + * of the file.
41062 + * ---------------------------------------------------------------------------
41063 + * Local variables:
41064 + * c-file-style: "linux"
41065 + * End:
41066 + */
41067 diff -Naur -X ../exclude-files orig/include/asm-um/user.h um/include/asm-um/user.h
41068 --- orig/include/asm-um/user.h  1969-12-31 19:00:00.000000000 -0500
41069 +++ um/include/asm-um/user.h    2004-02-14 06:31:38.000000000 -0500
41070 @@ -0,0 +1,6 @@
41071 +#ifndef __UM_USER_H
41072 +#define __UM_USER_H
41073 +
41074 +#include "asm/arch/user.h"
41075 +
41076 +#endif
41077 diff -Naur -X ../exclude-files orig/include/asm-um/vga.h um/include/asm-um/vga.h
41078 --- orig/include/asm-um/vga.h   1969-12-31 19:00:00.000000000 -0500
41079 +++ um/include/asm-um/vga.h     2003-10-21 03:26:07.000000000 -0400
41080 @@ -0,0 +1,6 @@
41081 +#ifndef __UM_VGA_H
41082 +#define __UM_VGA_H
41083 +
41084 +#include "asm/arch/vga.h"
41085 +
41086 +#endif
41087 diff -Naur -X ../exclude-files orig/include/asm-um/xor.h um/include/asm-um/xor.h
41088 --- orig/include/asm-um/xor.h   1969-12-31 19:00:00.000000000 -0500
41089 +++ um/include/asm-um/xor.h     2003-10-21 03:26:07.000000000 -0400
41090 @@ -0,0 +1,6 @@
41091 +#ifndef __UM_XOR_H
41092 +#define __UM_XOR_H
41093 +
41094 +#include "asm-generic/xor.h"
41095 +
41096 +#endif
41097 diff -Naur -X ../exclude-files orig/include/linux/blk.h um/include/linux/blk.h
41098 --- orig/include/linux/blk.h    2004-01-11 22:46:30.000000000 -0500
41099 +++ um/include/linux/blk.h      2004-02-14 06:29:18.000000000 -0500
41100 @@ -320,6 +320,24 @@
41101  #define DEVICE_REQUEST do_ida_request
41102  #define DEVICE_NR(device) (MINOR(device) >> 4)
41103  
41104 +#elif (MAJOR_NR == UBD_MAJOR)
41105 +
41106 +#define DEVICE_NAME "User-mode block device"
41107 +#define DEVICE_INTR do_ubd
41108 +#define DEVICE_REQUEST do_ubd_request
41109 +#define DEVICE_NR(device) (MINOR(device) >> UBD_SHIFT)
41110 +#define DEVICE_ON(device)
41111 +#define DEVICE_OFF(device)
41112 +
41113 +#elif (MAJOR_NR == COW_MAJOR)
41114 +
41115 +#define DEVICE_NAME "COW device"
41116 +#define DEVICE_INTR do_cow
41117 +#define DEVICE_REQUEST do_cow_request
41118 +#define DEVICE_NR(device) (MINOR(device) >> COW_SHIFT)
41119 +#define DEVICE_ON(device)
41120 +#define DEVICE_OFF(device)
41121 +
41122  #endif /* MAJOR_NR == whatever */
41123  
41124  /* provide DEVICE_xxx defaults, if not explicitly defined
41125 diff -Naur -X ../exclude-files orig/include/linux/fs.h um/include/linux/fs.h
41126 --- orig/include/linux/fs.h     2003-12-16 22:16:36.000000000 -0500
41127 +++ um/include/linux/fs.h       2004-02-14 06:28:59.000000000 -0500
41128 @@ -320,6 +320,8 @@
41129  #include <linux/ncp_fs_i.h>
41130  #include <linux/proc_fs_i.h>
41131  #include <linux/usbdev_fs_i.h>
41132 +#include <linux/hostfs_fs_i.h>
41133 +#include <linux/hppfs_fs_i.h>
41134  #include <linux/jffs2_fs_i.h>
41135  #include <linux/cramfs_fs_sb.h>
41136  
41137 @@ -516,7 +518,9 @@
41138                 struct proc_inode_info          proc_i;
41139                 struct socket                   socket_i;
41140                 struct usbdev_inode_info        usbdev_i;
41141 -               struct jffs2_inode_info         jffs2_i;
41142 +               struct hostfs_inode_info        hostfs_i;
41143 +               struct hppfs_inode_info         hppfs_i;
41144 +               struct jffs2_inode_info         jffs2_i;
41145                 void                            *generic_ip;
41146         } u;
41147  };
41148 @@ -864,6 +868,8 @@
41149         unsigned int (*poll) (struct file *, struct poll_table_struct *);
41150         int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
41151         int (*mmap) (struct file *, struct vm_area_struct *);
41152 +       void (*munmap) (struct file *, struct vm_area_struct *, 
41153 +                       unsigned long start, unsigned long len);
41154         int (*open) (struct inode *, struct file *);
41155         int (*flush) (struct file *);
41156         int (*release) (struct inode *, struct file *);
41157 diff -Naur -X ../exclude-files orig/include/linux/ghash.h um/include/linux/ghash.h
41158 --- orig/include/linux/ghash.h  1997-07-07 11:24:28.000000000 -0400
41159 +++ um/include/linux/ghash.h    2003-10-21 03:26:07.000000000 -0400
41160 @@ -153,6 +153,26 @@
41161         return NULL;\
41162  }
41163  
41164 +/* LINKAGE - empty or "static", depending on whether you want the definitions to
41165 + *     be public or not
41166 + * NAME - a string to stick in names to make this hash table type distinct from
41167 + *     any others
41168 + * HASHSIZE - number of buckets
41169 + * TYPE - type of data contained in the buckets - must be a structure, one 
41170 + *     field is of type NAME_ptrs, another is the hash key
41171 + * PTRS - TYPE must contain a field of type NAME_ptrs, PTRS is the name of that
41172 + *     field
41173 + * KEYTYPE - type of the key field within TYPE
41174 + * KEY - name of the key field within TYPE
41175 + * KEYCMP - pointer to function that compares KEYTYPEs to each other - the
41176 + *     prototype is int KEYCMP(KEYTYPE, KEYTYPE), it returns zero for equal, 
41177 + *     non-zero for not equal
41178 + * HASHFN - the hash function - the prototype is int HASHFN(KEYTYPE),
41179 + *     it returns a number in the range 0 ... HASHSIZE - 1
41180 + * Call DEF_HASH_STRUCTS, define your hash table as a NAME_table, then call
41181 + * DEF_HASH.
41182 + */
41183 +
41184  #define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
41185  \
41186  struct NAME##_table {\
41187 @@ -165,7 +185,7 @@
41188         TYPE * prev_hash;\
41189  };
41190  
41191 -#define DEF_HASH(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
41192 +#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\
41193  \
41194  LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
41195  {\
41196 @@ -206,12 +226,10 @@
41197  \
41198  LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
41199  {\
41200 -       int ix = hashfn(pos);\
41201 +       int ix = HASHFN(pos);\
41202         TYPE * ptr = tbl->hashtable[ix];\
41203         while(ptr && KEYCMP(ptr->KEY, pos))\
41204                 ptr = ptr->PTRS.next_hash;\
41205 -       if(ptr && !KEYEQ(ptr->KEY, pos))\
41206 -               ptr = NULL;\
41207         return ptr;\
41208  }
41209  
41210 diff -Naur -X ../exclude-files orig/include/linux/hostfs_fs_i.h um/include/linux/hostfs_fs_i.h
41211 --- orig/include/linux/hostfs_fs_i.h    1969-12-31 19:00:00.000000000 -0500
41212 +++ um/include/linux/hostfs_fs_i.h      2003-10-21 03:26:07.000000000 -0400
41213 @@ -0,0 +1,21 @@
41214 +#ifndef _HOSTFS_FS_I
41215 +#define _HOSTFS_FS_I
41216 +
41217 +struct hostfs_inode_info {
41218 +       char *host_filename;
41219 +       int fd;
41220 +       int mode;
41221 +};
41222 +
41223 +#endif
41224 +
41225 +/*
41226 + * Overrides for Emacs so that we follow Linus's tabbing style.
41227 + * Emacs will notice this stuff at the end of the file and automatically
41228 + * adjust the settings for this buffer only.  This must remain at the end
41229 + * of the file.
41230 + * ---------------------------------------------------------------------------
41231 + * Local variables:
41232 + * c-file-style: "linux"
41233 + * End:
41234 + */
41235 diff -Naur -X ../exclude-files orig/include/linux/hppfs_fs_i.h um/include/linux/hppfs_fs_i.h
41236 --- orig/include/linux/hppfs_fs_i.h     1969-12-31 19:00:00.000000000 -0500
41237 +++ um/include/linux/hppfs_fs_i.h       2003-10-21 03:26:07.000000000 -0400
41238 @@ -0,0 +1,19 @@
41239 +#ifndef _HPPFS_FS_I
41240 +#define _HPPFS_FS_I
41241 +
41242 +struct hppfs_inode_info {
41243 +       struct dentry *proc_dentry;
41244 +};
41245 +
41246 +#endif
41247 +
41248 +/*
41249 + * Overrides for Emacs so that we follow Linus's tabbing style.
41250 + * Emacs will notice this stuff at the end of the file and automatically
41251 + * adjust the settings for this buffer only.  This must remain at the end
41252 + * of the file.
41253 + * ---------------------------------------------------------------------------
41254 + * Local variables:
41255 + * c-file-style: "linux"
41256 + * End:
41257 + */
41258 diff -Naur -X ../exclude-files orig/include/linux/kernel.h um/include/linux/kernel.h
41259 --- orig/include/linux/kernel.h 2004-01-11 22:46:12.000000000 -0500
41260 +++ um/include/linux/kernel.h   2004-02-14 06:28:59.000000000 -0500
41261 @@ -49,7 +49,7 @@
41262  # define ATTRIB_NORET  __attribute__((noreturn))
41263  # define NORET_AND     noreturn,
41264  
41265 -#ifdef __i386__
41266 +#if defined(__i386__) || defined(UM_FASTCALL)
41267  #define FASTCALL(x)    x __attribute__((regparm(3)))
41268  #else
41269  #define FASTCALL(x)    x
41270 diff -Naur -X ../exclude-files orig/include/linux/kernel_stat.h um/include/linux/kernel_stat.h
41271 --- orig/include/linux/kernel_stat.h    2004-01-11 22:46:12.000000000 -0500
41272 +++ um/include/linux/kernel_stat.h      2004-02-14 06:28:59.000000000 -0500
41273 @@ -12,7 +12,7 @@
41274   * used by rstatd/perfmeter
41275   */
41276  
41277 -#define DK_MAX_MAJOR 16
41278 +#define DK_MAX_MAJOR 99
41279  #define DK_MAX_DISK 16
41280  
41281  struct kernel_stat {
41282 diff -Naur -X ../exclude-files orig/include/linux/mm.h um/include/linux/mm.h
41283 --- orig/include/linux/mm.h     2003-12-16 22:16:36.000000000 -0500
41284 +++ um/include/linux/mm.h       2004-02-14 06:28:59.000000000 -0500
41285 @@ -438,6 +438,18 @@
41286  extern struct page * FASTCALL(__alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist));
41287  extern struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order);
41288  
41289 +#ifndef HAVE_ARCH_VALIDATE
41290 +static inline struct page *arch_validate(struct page *page, 
41291 +                                        unsigned int gfp_mask, int order)
41292 +{
41293 +        return(page);
41294 +}
41295 +#endif
41296 +
41297 +#ifndef HAVE_ARCH_FREE_PAGE
41298 +static inline void arch_free_page(struct page *page, int order) { }
41299 +#endif
41300 +
41301  static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
41302  {
41303         /*
41304 @@ -445,7 +457,7 @@
41305          */
41306         if (order >= MAX_ORDER)
41307                 return NULL;
41308 -       return _alloc_pages(gfp_mask, order);
41309 +       return arch_validate(_alloc_pages(gfp_mask, order), gfp_mask, order);
41310  }
41311  
41312  #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
41313 @@ -505,6 +517,9 @@
41314  int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
41315                 int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
41316  
41317 +extern long do_mprotect(struct mm_struct *mm, unsigned long start, 
41318 +                       size_t len, unsigned long prot);
41319 +
41320  /*
41321   * On a two-level page table, this ends up being trivial. Thus the
41322   * inlining and the symmetry break with pte_alloc() that does all
41323 @@ -552,9 +567,10 @@
41324  
41325  extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
41326  
41327 -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
41328 -       unsigned long len, unsigned long prot,
41329 -       unsigned long flag, unsigned long pgoff);
41330 +extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file, 
41331 +                                  unsigned long addr, unsigned long len,
41332 +                                  unsigned long prot, unsigned long flag,
41333 +                                  unsigned long pgoff);
41334  
41335  static inline unsigned long do_mmap(struct file *file, unsigned long addr,
41336         unsigned long len, unsigned long prot,
41337 @@ -564,7 +580,8 @@
41338         if ((offset + PAGE_ALIGN(len)) < offset)
41339                 goto out;
41340         if (!(offset & ~PAGE_MASK))
41341 -               ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
41342 +               ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, 
41343 +                                   offset >> PAGE_SHIFT);
41344  out:
41345         return ret;
41346  }
41347 diff -Naur -X ../exclude-files orig/include/linux/proc_mm.h um/include/linux/proc_mm.h
41348 --- orig/include/linux/proc_mm.h        1969-12-31 19:00:00.000000000 -0500
41349 +++ um/include/linux/proc_mm.h  2004-02-14 06:30:22.000000000 -0500
41350 @@ -0,0 +1,48 @@
41351 +/* 
41352 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
41353 + * Licensed under the GPL
41354 + */
41355 +
41356 +#ifndef __PROC_MM_H
41357 +#define __PROC_MM_H
41358 +
41359 +#include "linux/sched.h"
41360 +
41361 +#define MM_MMAP 54
41362 +#define MM_MUNMAP 55
41363 +#define MM_MPROTECT 56
41364 +#define MM_COPY_SEGMENTS 57
41365 +
41366 +struct mm_mmap {
41367 +       unsigned long addr;
41368 +       unsigned long len;
41369 +       unsigned long prot;
41370 +       unsigned long flags;
41371 +       unsigned long fd;
41372 +       unsigned long offset;
41373 +};
41374 +
41375 +struct mm_munmap {
41376 +       unsigned long addr;
41377 +       unsigned long len;      
41378 +};
41379 +
41380 +struct mm_mprotect {
41381 +       unsigned long addr;
41382 +       unsigned long len;
41383 +        unsigned int prot;
41384 +};
41385 +
41386 +struct proc_mm_op {
41387 +       int op;
41388 +       union {
41389 +               struct mm_mmap mmap;
41390 +               struct mm_munmap munmap;
41391 +               struct mm_mprotect mprotect;
41392 +               int copy_segments;
41393 +       } u;
41394 +};
41395 +
41396 +extern struct mm_struct *proc_mm_get_mm(int fd);
41397 +
41398 +#endif
41399 diff -Naur -X ../exclude-files orig/include/linux/shmem_fs.h um/include/linux/shmem_fs.h
41400 --- orig/include/linux/shmem_fs.h       2003-09-02 15:44:03.000000000 -0400
41401 +++ um/include/linux/shmem_fs.h 2003-12-09 00:03:31.000000000 -0500
41402 @@ -22,6 +22,8 @@
41403         unsigned long           next_index;
41404         swp_entry_t             i_direct[SHMEM_NR_DIRECT]; /* for the first blocks */
41405         void                  **i_indirect; /* indirect blocks */
41406 +       unsigned long           map_direct[SHMEM_NR_DIRECT];
41407 +       void                  **map_indirect;
41408         unsigned long           swapped;    /* data pages assigned to swap */
41409         unsigned long           flags;
41410         struct list_head        list;
41411 diff -Naur -X ../exclude-files orig/include/linux/tty.h um/include/linux/tty.h
41412 --- orig/include/linux/tty.h    2004-01-11 22:46:12.000000000 -0500
41413 +++ um/include/linux/tty.h      2004-02-14 06:28:59.000000000 -0500
41414 @@ -309,6 +309,9 @@
41415         spinlock_t read_lock;
41416         /* If the tty has a pending do_SAK, queue it here - akpm */
41417         struct tq_struct SAK_tq;
41418 +#ifdef CONFIG_TTY_LOG
41419 +        int log_fd;
41420 +#endif
41421  };
41422  
41423  /* tty magic number */
41424 @@ -365,6 +368,7 @@
41425  extern int specialix_init(void);
41426  extern int espserial_init(void);
41427  extern int macserial_init(void);
41428 +extern int stdio_init(void);
41429  extern int a2232board_init(void);
41430  
41431  extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
41432 @@ -420,5 +424,7 @@
41433  extern int vt_ioctl(struct tty_struct *tty, struct file * file,
41434                     unsigned int cmd, unsigned long arg);
41435  
41436 +extern void stdio_console_init(void);
41437 +
41438  #endif /* __KERNEL__ */
41439  #endif
41440 diff -Naur -X ../exclude-files orig/init/do_mounts.c um/init/do_mounts.c
41441 --- orig/init/do_mounts.c       2003-12-16 22:16:36.000000000 -0500
41442 +++ um/init/do_mounts.c 2003-12-16 22:17:32.000000000 -0500
41443 @@ -154,6 +154,22 @@
41444         { "pf",         0x2f00 },
41445         { "apblock", APBLOCK_MAJOR << 8},
41446         { "ddv", DDV_MAJOR << 8},
41447 +       { "ubd0", UBD_MAJOR << 8 | 0 << 4},
41448 +       { "ubda", UBD_MAJOR << 8 | 0 << 4},
41449 +       { "ubd1", UBD_MAJOR << 8 | 1 << 4},
41450 +       { "ubdb", UBD_MAJOR << 8 | 1 << 4},
41451 +       { "ubd2", UBD_MAJOR << 8 | 2 << 4},
41452 +       { "ubdc", UBD_MAJOR << 8 | 2 << 4},
41453 +       { "ubd3", UBD_MAJOR << 8 | 3 << 4},
41454 +       { "ubdd", UBD_MAJOR << 8 | 3 << 4},
41455 +       { "ubd4", UBD_MAJOR << 8 | 4 << 4},
41456 +       { "ubde", UBD_MAJOR << 8 | 4 << 4},
41457 +       { "ubd5", UBD_MAJOR << 8 | 5 << 4},
41458 +       { "ubdf", UBD_MAJOR << 8 | 5 << 4},
41459 +       { "ubd6", UBD_MAJOR << 8 | 6 << 4},
41460 +       { "ubdg", UBD_MAJOR << 8 | 6 << 4},
41461 +       { "ubd7", UBD_MAJOR << 8 | 7 << 4},
41462 +       { "ubdh", UBD_MAJOR << 8 | 7 << 4},
41463         { "jsfd",    JSFD_MAJOR << 8},
41464  #if defined(CONFIG_ARCH_S390)
41465         { "dasda", (DASD_MAJOR << MINORBITS) },
41466 diff -Naur -X ../exclude-files orig/kernel/panic.c um/kernel/panic.c
41467 --- orig/kernel/panic.c 2003-12-16 22:16:36.000000000 -0500
41468 +++ um/kernel/panic.c   2003-12-16 22:17:32.000000000 -0500
41469 @@ -74,7 +74,7 @@
41470         smp_send_stop();
41471  #endif
41472  
41473 -       notifier_call_chain(&panic_notifier_list, 0, NULL);
41474 +       notifier_call_chain(&panic_notifier_list, 0, buf);
41475  
41476         if (panic_timeout > 0)
41477         {
41478 diff -Naur -X ../exclude-files orig/MAINTAINERS um/MAINTAINERS
41479 --- orig/MAINTAINERS    2003-12-16 22:16:23.000000000 -0500
41480 +++ um/MAINTAINERS      2003-12-16 22:17:22.000000000 -0500
41481 @@ -2055,6 +2055,14 @@
41482  L:     linux-usb-devel@lists.sourceforge.net
41483  W:     http://usb.in.tum.de
41484  S:     Maintained
41485 +
41486 +USER-MODE PORT
41487 +P:     Jeff Dike
41488 +M:     jdike@karaya.com
41489 +L:     user-mode-linux-devel@lists.sourceforge.net
41490 +L:     user-mode-linux-user@lists.sourceforge.net
41491 +W:     http://user-mode-linux.sourceforge.net
41492 +S:     Maintained
41493         
41494  USB "USBNET" DRIVER
41495  P:     David Brownell
41496 diff -Naur -X ../exclude-files orig/Makefile um/Makefile
41497 --- orig/Makefile       2004-02-14 06:26:12.000000000 -0500
41498 +++ um/Makefile 2004-02-14 06:26:19.000000000 -0500
41499 @@ -5,7 +5,15 @@
41500  
41501  KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
41502  
41503 -ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
41504 +# SUBARCH tells the usermode build what the underlying arch is.  That is set
41505 +# first, and if a usermode build is happening, the "ARCH=um" on the command
41506 +# line overrides the setting of ARCH below.  If a native build is happening,
41507 +# then ARCH is assigned, getting whatever value it gets normally, and 
41508 +# SUBARCH is subsequently ignored.
41509 +
41510 +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
41511 +ARCH := $(SUBARCH)
41512 +
41513  KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
41514  
41515  CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
41516 diff -Naur -X ../exclude-files orig/mm/Makefile um/mm/Makefile
41517 --- orig/mm/Makefile    2002-08-21 11:47:43.000000000 -0400
41518 +++ um/mm/Makefile      2003-10-21 03:26:08.000000000 -0400
41519 @@ -17,5 +17,6 @@
41520             shmem.o
41521  
41522  obj-$(CONFIG_HIGHMEM) += highmem.o
41523 +obj-$(CONFIG_PROC_MM) += proc_mm.o
41524  
41525  include $(TOPDIR)/Rules.make
41526 diff -Naur -X ../exclude-files orig/mm/mmap.c um/mm/mmap.c
41527 --- orig/mm/mmap.c      2003-12-16 22:16:36.000000000 -0500
41528 +++ um/mm/mmap.c        2003-12-16 22:17:32.000000000 -0500
41529 @@ -390,10 +390,11 @@
41530         return 0;
41531  }
41532  
41533 -unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned long len,
41534 -       unsigned long prot, unsigned long flags, unsigned long pgoff)
41535 +unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file, 
41536 +                           unsigned long addr, unsigned long len,
41537 +                           unsigned long prot, unsigned long flags, 
41538 +                           unsigned long pgoff)
41539  {
41540 -       struct mm_struct * mm = current->mm;
41541         struct vm_area_struct * vma, * prev;
41542         unsigned int vm_flags;
41543         int correct_wcount = 0;
41544 @@ -994,6 +995,11 @@
41545                 remove_shared_vm_struct(mpnt);
41546                 mm->map_count--;
41547  
41548 +               if((mpnt->vm_file != NULL) && (mpnt->vm_file->f_op != NULL) &&
41549 +                  (mpnt->vm_file->f_op->munmap != NULL))
41550 +                       mpnt->vm_file->f_op->munmap(mpnt->vm_file, mpnt, st, 
41551 +                                                   size);
41552 +
41553                 zap_page_range(mm, st, size);
41554  
41555                 /*
41556 diff -Naur -X ../exclude-files orig/mm/mprotect.c um/mm/mprotect.c
41557 --- orig/mm/mprotect.c  2003-12-16 22:16:36.000000000 -0500
41558 +++ um/mm/mprotect.c    2003-12-16 22:17:32.000000000 -0500
41559 @@ -264,7 +264,8 @@
41560         return 0;
41561  }
41562  
41563 -asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
41564 +long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
41565 +                unsigned long prot)
41566  {
41567         unsigned long nstart, end, tmp;
41568         struct vm_area_struct * vma, * next, * prev;
41569 @@ -281,9 +282,9 @@
41570         if (end == start)
41571                 return 0;
41572  
41573 -       down_write(&current->mm->mmap_sem);
41574 +       down_write(&mm->mmap_sem);
41575  
41576 -       vma = find_vma_prev(current->mm, start, &prev);
41577 +       vma = find_vma_prev(mm, start, &prev);
41578         error = -ENOMEM;
41579         if (!vma || vma->vm_start > start)
41580                 goto out;
41581 @@ -332,6 +333,11 @@
41582                 prev->vm_mm->map_count--;
41583         }
41584  out:
41585 -       up_write(&current->mm->mmap_sem);
41586 +       up_write(&mm->mmap_sem);
41587         return error;
41588  }
41589 +
41590 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
41591 +{
41592 +        return(do_mprotect(current->mm, start, len, prot));
41593 +}
41594 diff -Naur -X ../exclude-files orig/mm/page_alloc.c um/mm/page_alloc.c
41595 --- orig/mm/page_alloc.c        2003-12-16 22:16:36.000000000 -0500
41596 +++ um/mm/page_alloc.c  2003-12-16 22:17:32.000000000 -0500
41597 @@ -89,6 +89,7 @@
41598         struct page *base;
41599         zone_t *zone;
41600  
41601 +       arch_free_page(page, order);
41602         /*
41603          * Yes, think what happens when other parts of the kernel take 
41604          * a reference to a page in order to pin it for io. -ben
41605 diff -Naur -X ../exclude-files orig/mm/proc_mm.c um/mm/proc_mm.c
41606 --- orig/mm/proc_mm.c   1969-12-31 19:00:00.000000000 -0500
41607 +++ um/mm/proc_mm.c     2003-10-21 03:26:08.000000000 -0400
41608 @@ -0,0 +1,173 @@
41609 +/* 
41610 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
41611 + * Licensed under the GPL
41612 + */
41613 +
41614 +#include "linux/init.h"
41615 +#include "linux/proc_fs.h"
41616 +#include "linux/proc_mm.h"
41617 +#include "linux/file.h"
41618 +#include "asm/uaccess.h"
41619 +#include "asm/mmu_context.h"
41620 +
41621 +static struct file_operations proc_mm_fops;
41622 +
41623 +struct mm_struct *proc_mm_get_mm(int fd)
41624 +{
41625 +       struct mm_struct *ret = ERR_PTR(-EBADF);
41626 +       struct file *file;
41627 +
41628 +       file = fget(fd);
41629 +       if (!file)
41630 +               goto out;
41631 +
41632 +       ret = ERR_PTR(-EINVAL);
41633 +       if(file->f_op != &proc_mm_fops)
41634 +               goto out_fput;
41635 +
41636 +       ret = file->private_data;
41637 + out_fput:
41638 +       fput(file);
41639 + out:
41640 +       return(ret);
41641 +}
41642 +
41643 +extern long do_mmap2(struct mm_struct *mm, unsigned long addr, 
41644 +                    unsigned long len, unsigned long prot, 
41645 +                    unsigned long flags, unsigned long fd,
41646 +                    unsigned long pgoff);
41647 +
41648 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
41649 +                            size_t count, loff_t *ppos)
41650 +{
41651 +       struct mm_struct *mm = file->private_data;
41652 +       struct proc_mm_op req;
41653 +       int n, ret;
41654 +
41655 +       if(count > sizeof(req))
41656 +               return(-EINVAL);
41657 +
41658 +       n = copy_from_user(&req, buffer, count);
41659 +       if(n != 0)
41660 +               return(-EFAULT);
41661 +
41662 +       ret = count;
41663 +       switch(req.op){
41664 +       case MM_MMAP: {
41665 +               struct mm_mmap *map = &req.u.mmap;
41666 +
41667 +               ret = do_mmap2(mm, map->addr, map->len, map->prot, 
41668 +                              map->flags, map->fd, map->offset >> PAGE_SHIFT);
41669 +               if((ret & ~PAGE_MASK) == 0)
41670 +                       ret = count;
41671 +       
41672 +               break;
41673 +       }
41674 +       case MM_MUNMAP: {
41675 +               struct mm_munmap *unmap = &req.u.munmap;
41676 +
41677 +               down_write(&mm->mmap_sem);
41678 +               ret = do_munmap(mm, unmap->addr, unmap->len);
41679 +               up_write(&mm->mmap_sem);
41680 +
41681 +               if(ret == 0)
41682 +                       ret = count;
41683 +               break;
41684 +       }
41685 +       case MM_MPROTECT: {
41686 +               struct mm_mprotect *protect = &req.u.mprotect;
41687 +
41688 +               ret = do_mprotect(mm, protect->addr, protect->len, 
41689 +                                 protect->prot);
41690 +               if(ret == 0)
41691 +                       ret = count;
41692 +               break;
41693 +       }
41694 +
41695 +       case MM_COPY_SEGMENTS: {
41696 +               struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
41697 +
41698 +               if(IS_ERR(from)){
41699 +                       ret = PTR_ERR(from);
41700 +                       break;
41701 +               }
41702 +
41703 +               mm_copy_segments(from, mm);
41704 +               break;
41705 +       }
41706 +       default:
41707 +               ret = -EINVAL;
41708 +               break;
41709 +       }
41710 +
41711 +       return(ret);
41712 +}
41713 +
41714 +static int open_proc_mm(struct inode *inode, struct file *file)
41715 +{
41716 +       struct mm_struct *mm = mm_alloc();
41717 +       int ret;
41718 +
41719 +       ret = -ENOMEM;
41720 +       if(mm == NULL)
41721 +               goto out_mem;
41722 +
41723 +       ret = init_new_context(current, mm);
41724 +       if(ret)
41725 +               goto out_free;
41726 +
41727 +       spin_lock(&mmlist_lock);
41728 +       list_add(&mm->mmlist, &current->mm->mmlist);
41729 +       mmlist_nr++;
41730 +       spin_unlock(&mmlist_lock);
41731 +
41732 +       file->private_data = mm;
41733 +
41734 +       return(0);
41735 +
41736 + out_free:
41737 +       mmput(mm);
41738 + out_mem:
41739 +       return(ret);
41740 +}
41741 +
41742 +static int release_proc_mm(struct inode *inode, struct file *file)
41743 +{
41744 +       struct mm_struct *mm = file->private_data;
41745 +
41746 +       mmput(mm);
41747 +       return(0);
41748 +}
41749 +
41750 +static struct file_operations proc_mm_fops = {
41751 +       .open           = open_proc_mm,
41752 +       .release        = release_proc_mm,
41753 +       .write          = write_proc_mm,
41754 +};
41755 +
41756 +static int make_proc_mm(void)
41757 +{
41758 +       struct proc_dir_entry *ent;
41759 +
41760 +       ent = create_proc_entry("mm", 0222, &proc_root);
41761 +       if(ent == NULL){
41762 +               printk("make_proc_mm : Failed to register /proc/mm\n");
41763 +               return(0);
41764 +       }
41765 +       ent->proc_fops = &proc_mm_fops;
41766 +
41767 +       return(0);
41768 +}
41769 +
41770 +__initcall(make_proc_mm);
41771 +
41772 +/*
41773 + * Overrides for Emacs so that we follow Linus's tabbing style.
41774 + * Emacs will notice this stuff at the end of the file and automatically
41775 + * adjust the settings for this buffer only.  This must remain at the end
41776 + * of the file.
41777 + * ---------------------------------------------------------------------------
41778 + * Local variables:
41779 + * c-file-style: "linux"
41780 + * End:
41781 + */
41782 diff -Naur -X ../exclude-files orig/mm/shmem.c um/mm/shmem.c
41783 --- orig/mm/shmem.c     2003-12-16 22:16:36.000000000 -0500
41784 +++ um/mm/shmem.c       2003-12-16 22:17:32.000000000 -0500
41785 @@ -128,16 +128,17 @@
41786   *                    +-> 48-51
41787   *                    +-> 52-55
41788   */
41789 -static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, unsigned long *page)
41790 +static void *shmem_block(unsigned long index, unsigned long *page,
41791 +                        unsigned long *direct, void ***indirect)
41792  {
41793         unsigned long offset;
41794         void **dir;
41795  
41796         if (index < SHMEM_NR_DIRECT)
41797 -               return info->i_direct+index;
41798 -       if (!info->i_indirect) {
41799 +               return direct+index;
41800 +       if (!*indirect) {
41801                 if (page) {
41802 -                       info->i_indirect = (void **) *page;
41803 +                       *indirect = (void **) *page;
41804                         *page = 0;
41805                 }
41806                 return NULL;                    /* need another page */
41807 @@ -146,7 +147,7 @@
41808         index -= SHMEM_NR_DIRECT;
41809         offset = index % ENTRIES_PER_PAGE;
41810         index /= ENTRIES_PER_PAGE;
41811 -       dir = info->i_indirect;
41812 +       dir = *indirect;
41813  
41814         if (index >= ENTRIES_PER_PAGE/2) {
41815                 index -= ENTRIES_PER_PAGE/2;
41816 @@ -169,7 +170,21 @@
41817                 *dir = (void *) *page;
41818                 *page = 0;
41819         }
41820 -       return (swp_entry_t *) *dir + offset;
41821 +       return (unsigned long **) *dir + offset;
41822 +}
41823 +
41824 +static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, unsigned long *page)
41825 +{
41826 +       return((swp_entry_t *) shmem_block(index, page, 
41827 +                                          (unsigned long *) info->i_direct, 
41828 +                                          &info->i_indirect));
41829 +}
41830 +
41831 +static unsigned long *shmem_map_count(struct shmem_inode_info *info, 
41832 +                                     unsigned long index, unsigned long *page)
41833 +{
41834 +       return((unsigned long *) shmem_block(index, page, info->map_direct, 
41835 +                                            &info->map_indirect));
41836  }
41837  
41838  /*
41839 @@ -838,6 +853,7 @@
41840         ops = &shmem_vm_ops;
41841         if (!S_ISREG(inode->i_mode))
41842                 return -EACCES;
41843 +
41844         UPDATE_ATIME(inode);
41845         vma->vm_ops = ops;
41846         return 0;
41847 @@ -1723,4 +1739,125 @@
41848         return 0;
41849  }
41850  
41851 +static int adjust_map_counts(struct shmem_inode_info *info, 
41852 +                            unsigned long offset, unsigned long len, 
41853 +                            int adjust)
41854 +{
41855 +       unsigned long idx, i, *count, page = 0;
41856 +
41857 +       spin_lock(&info->lock);
41858 +       offset >>= PAGE_SHIFT;
41859 +       len >>= PAGE_SHIFT;
41860 +       for(i = 0; i < len; i++){
41861 +               idx = (i + offset) >> (PAGE_CACHE_SHIFT - PAGE_SHIFT);
41862 +
41863 +               while((count = shmem_map_count(info, idx, &page)) == NULL){
41864 +                       spin_unlock(&info->lock);
41865 +                       page = get_zeroed_page(GFP_KERNEL);
41866 +                       if(page == 0)
41867 +                               return(-ENOMEM);
41868 +                       spin_lock(&info->lock);
41869 +               }
41870 +
41871 +               if(page != 0)
41872 +                       free_page(page);
41873 +
41874 +               *count += adjust;
41875 +       }
41876 +       spin_unlock(&info->lock);
41877 +       return(0);
41878 +}
41879 +
41880  EXPORT_SYMBOL(shmem_file_setup);
41881 +
41882 +struct file_operations anon_file_operations;
41883 +
41884 +static int anon_mmap(struct file *file, struct vm_area_struct *vma)
41885 +{
41886 +        struct file *new;
41887 +       struct inode *inode;
41888 +       loff_t size = vma->vm_end - vma->vm_start;
41889 +       int err;
41890 +
41891 +       if(file->private_data == NULL){
41892 +               new = shmem_file_setup("dev/anon", size);
41893 +               if(IS_ERR(new))
41894 +                       return(PTR_ERR(new));
41895 +
41896 +               new->f_op = &anon_file_operations;
41897 +               file->private_data = new;
41898 +       }
41899 +       
41900 +       if (vma->vm_file)
41901 +               fput(vma->vm_file);
41902 +       vma->vm_file = file->private_data;
41903 +       get_file(vma->vm_file);
41904 +
41905 +       inode = vma->vm_file->f_dentry->d_inode;
41906 +       err = adjust_map_counts(SHMEM_I(inode), vma->vm_pgoff, size, 1);
41907 +       if(err)
41908 +               return(err);
41909 +
41910 +       vma->vm_ops = &shmem_vm_ops;
41911 +       return 0;
41912 +}
41913 +
41914 +static void anon_munmap(struct file *file, struct vm_area_struct *vma, 
41915 +                       unsigned long start, unsigned long len)
41916 +{
41917 +       struct inode *inode = file->f_dentry->d_inode;
41918 +       struct shmem_inode_info *info = SHMEM_I(inode);
41919 +       pgd_t *pgd;
41920 +       pmd_t *pmd;
41921 +       pte_t *pte;
41922 +       struct page *page;
41923 +       unsigned long addr, idx, *count;
41924 +
41925 +       for(addr = start; addr < start + len; addr += PAGE_SIZE){
41926 +               idx = (addr - vma->vm_start + vma->vm_pgoff);
41927 +               idx >>= PAGE_CACHE_SHIFT;
41928 +
41929 +               count = shmem_map_count(info, idx, NULL);
41930 +               BUG_ON(count == NULL);
41931 +
41932 +               (*count)--;
41933 +               if(*count > 0)
41934 +                       continue;
41935 +
41936 +               pgd = pgd_offset(vma->vm_mm, addr);
41937 +               if(pgd_none(*pgd))
41938 +                       continue;
41939 +
41940 +               pmd = pmd_offset(pgd, addr);
41941 +               if(pmd_none(*pmd))
41942 +                       continue;
41943 +
41944 +               pte = pte_offset(pmd, addr);
41945 +               if(!pte_present(*pte)) /* XXX need to handle swapped pages */
41946 +                       continue;
41947 +
41948 +               *pte = pte_mkclean(*pte);
41949 +
41950 +               page = pte_page(*pte);
41951 +               LockPage(page);
41952 +               lru_cache_del(page);
41953 +               ClearPageDirty(page);
41954 +               remove_inode_page(page);
41955 +               UnlockPage(page);
41956 +
41957 +               page_cache_release(page);
41958 +       }
41959 +}
41960 +
41961 +int anon_release(struct inode *inode, struct file *file)
41962 +{
41963 +       if(file->private_data != NULL)
41964 +               fput(file->private_data);
41965 +       return(0);
41966 +}
41967 +
41968 +struct file_operations anon_file_operations = {
41969 +       .mmap           = anon_mmap,
41970 +       .munmap         = anon_munmap,
41971 +       .release        = anon_release,
41972 +};