Whamcloud - gitweb
land b1_5 onto HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / uml-patch-2.4.29-1.patch
1 Index: linux-2.4.29/arch/um/config_block.in
2 ===================================================================
3 --- linux-2.4.29.orig/arch/um/config_block.in   1970-01-01 03:00:00.000000000 +0300
4 +++ linux-2.4.29/arch/um/config_block.in        2005-05-03 22:28:14.000000000 +0300
5 @@ -0,0 +1,22 @@
6 +mainmenu_option next_comment
7 +comment 'Block Devices'
8 +
9 +bool 'Virtual block device' CONFIG_BLK_DEV_UBD
10 +dep_bool '  Always do synchronous disk IO for UBD' CONFIG_BLK_DEV_UBD_SYNC $CONFIG_BLK_DEV_UBD
11 +bool 'COW device' CONFIG_COW
12 +
13 +if [ "$CONFIG_BLK_DEV_UBD" = "y" -o "$CONFIG_COW" = "y" ] ; then
14 +       define_bool CONFIG_COW_COMMON y
15 +fi
16 +
17 +tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
18 +dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
19 +tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
20 +if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
21 +       int '   Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
22 +fi
23 +dep_bool '  Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM
24 +
25 +tristate 'Example IO memory driver' CONFIG_MMAPPER
26 +
27 +endmenu
28 Index: linux-2.4.29/arch/um/config_char.in
29 ===================================================================
30 --- linux-2.4.29.orig/arch/um/config_char.in    1970-01-01 03:00:00.000000000 +0300
31 +++ linux-2.4.29/arch/um/config_char.in 2005-05-03 22:28:14.000000000 +0300
32 @@ -0,0 +1,37 @@
33 +mainmenu_option next_comment
34 +comment 'Character Devices'
35 +
36 +define_bool CONFIG_STDIO_CONSOLE y
37 +
38 +bool 'Virtual serial line' CONFIG_SSL
39 +
40 +bool 'file descriptor channel support' CONFIG_FD_CHAN
41 +bool 'null channel support' CONFIG_NULL_CHAN
42 +bool 'port channel support' CONFIG_PORT_CHAN
43 +bool 'pty channel support' CONFIG_PTY_CHAN
44 +bool 'tty channel support' CONFIG_TTY_CHAN
45 +bool 'xterm channel support' CONFIG_XTERM_CHAN
46 +string 'Default main console channel initialization' CONFIG_CON_ZERO_CHAN \
47 +            "fd:0,fd:1"
48 +string 'Default console channel initialization' CONFIG_CON_CHAN "xterm"
49 +string 'Default serial line channel initialization' CONFIG_SSL_CHAN "pty"
50 +
51 +
52 +bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
53 +if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
54 +   int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
55 +fi
56 +
57 +bool 'Watchdog Timer Support' CONFIG_WATCHDOG
58 +dep_bool '  Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT \
59 +       $CONFIG_WATCHDOG
60 +dep_tristate '  Software Watchdog' CONFIG_SOFT_WATCHDOG $CONFIG_WATCHDOG
61 +dep_tristate '  UML watchdog' CONFIG_UML_WATCHDOG $CONFIG_WATCHDOG
62 +
63 +tristate 'Sound support' CONFIG_UML_SOUND
64 +define_tristate CONFIG_SOUND $CONFIG_UML_SOUND
65 +define_tristate CONFIG_HOSTAUDIO $CONFIG_UML_SOUND
66 +
67 +bool 'Enable tty logging' CONFIG_TTY_LOG
68 +
69 +endmenu
70 Index: linux-2.4.29/arch/um/config.in
71 ===================================================================
72 --- linux-2.4.29.orig/arch/um/config.in 1970-01-01 03:00:00.000000000 +0300
73 +++ linux-2.4.29/arch/um/config.in      2005-05-03 22:28:14.000000000 +0300
74 @@ -0,0 +1,123 @@
75 +define_bool CONFIG_USERMODE y
76 +
77 +mainmenu_name "Linux/Usermode Kernel Configuration"
78 +
79 +define_bool CONFIG_ISA n
80 +define_bool CONFIG_SBUS n
81 +define_bool CONFIG_PCI n
82 +
83 +define_bool CONFIG_UID16 y
84 +
85 +define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
86 +
87 +mainmenu_option next_comment
88 +comment 'Code maturity level options'
89 +bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
90 +endmenu
91 +
92 +mainmenu_option next_comment
93 +comment 'General Setup'
94 +
95 +bool 'Separate kernel address space support' CONFIG_MODE_SKAS
96 +
97 +# This is to ensure that at least one of the modes is enabled.  When neither
98 +# is present in defconfig, they default to N, which is bad.
99 +if [ "$CONFIG_MODE_SKAS" != "y" ]; then
100 +   define_bool CONFIG_MODE_TT y
101 +fi
102 +
103 +bool 'Tracing thread support' CONFIG_MODE_TT
104 +if [ "$CONFIG_MODE_TT" != "y" ]; then
105 +   bool 'Statically linked binary when CONFIG_MODE_TT is disabled' CONFIG_STATIC_LINK
106 +fi
107 +bool 'Networking support' CONFIG_NET
108 +bool 'System V IPC' CONFIG_SYSVIPC
109 +bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
110 +bool 'Sysctl support' CONFIG_SYSCTL
111 +tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
112 +tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
113 +tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
114 +
115 +tristate 'Host filesystem' CONFIG_HOSTFS
116 +tristate 'Usable host filesystem' CONFIG_HUMFS
117 +
118 +if [ "$CONFIG_HOSTFS" = "y" -o "$CONFIG_HUMFS" = "y" ]; then
119 +    define_tristate CONFIG_EXTERNFS y
120 +fi
121 +
122 +tristate 'Honeypot proc filesystem' CONFIG_HPPFS
123 +bool 'Management console' CONFIG_MCONSOLE
124 +dep_bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ $CONFIG_MCONSOLE
125 +bool '2G/2G host address space split' CONFIG_HOST_2G_2G
126 +
127 +bool 'Symmetric multi-processing support' CONFIG_UML_SMP
128 +define_bool CONFIG_SMP $CONFIG_UML_SMP
129 +if [ "$CONFIG_SMP" = "y" ]; then
130 +    int  'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32
131 +fi
132 +
133 +int 'Nesting level' CONFIG_NEST_LEVEL 0
134 +int 'Kernel address space size (in .5G units)' CONFIG_KERNEL_HALF_GIGS 1
135 +bool 'Highmem support' CONFIG_HIGHMEM
136 +bool '/proc/mm' CONFIG_PROC_MM
137 +int 'Kernel stack size order' CONFIG_KERNEL_STACK_ORDER 2
138 +bool 'Real-time Clock' CONFIG_UML_REAL_TIME_CLOCK
139 +endmenu
140 +
141 +mainmenu_option next_comment
142 +comment 'Loadable module support'
143 +bool 'Enable loadable module support' CONFIG_MODULES
144 +if [ "$CONFIG_MODULES" = "y" ]; then
145 +# MODVERSIONS does not yet work in this architecture
146 +#   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
147 +    bool '  Kernel module loader' CONFIG_KMOD
148 +fi
149 +endmenu
150 +
151 +source arch/um/config_char.in
152 +
153 +source arch/um/config_block.in
154 +
155 +define_bool CONFIG_NETDEVICES $CONFIG_NET
156 +
157 +if [ "$CONFIG_NET" = "y" ]; then
158 +   source arch/um/config_net.in
159 +   source net/Config.in
160 +fi
161 +
162 +source fs/Config.in
163 +
164 +mainmenu_option next_comment
165 +comment 'SCSI support'
166 +
167 +tristate 'SCSI support' CONFIG_SCSI
168 +
169 +if [ "$CONFIG_SCSI" != "n" ]; then
170 +   source arch/um/config_scsi.in
171 +fi
172 +endmenu
173 +
174 +source drivers/md/Config.in
175 +
176 +source drivers/mtd/Config.in
177 +
178 +source lib/Config.in
179 +
180 +source crypto/Config.in
181 +
182 +mainmenu_option next_comment
183 +comment 'Kernel hacking'
184 +bool 'Debug memory allocations' CONFIG_DEBUG_SLAB
185 +bool 'Enable kernel debugging symbols' CONFIG_DEBUGSYM
186 +if [ "$CONFIG_XTERM_CHAN" = "y" ]; then
187 +   dep_bool 'Enable ptrace proxy' CONFIG_PT_PROXY $CONFIG_DEBUGSYM
188 +else 
189 +   define_bool CONFIG_PT_PROXY n
190 +fi
191 +
192 +if [ "$CONFIG_MODE_TT" = "n" ]; then
193 +   dep_bool 'Enable gprof support' CONFIG_GPROF $CONFIG_DEBUGSYM
194 +fi
195 +
196 +dep_bool 'Enable gcov support' CONFIG_GCOV $CONFIG_DEBUGSYM
197 +endmenu
198 Index: linux-2.4.29/arch/um/config_net.in
199 ===================================================================
200 --- linux-2.4.29.orig/arch/um/config_net.in     1970-01-01 03:00:00.000000000 +0300
201 +++ linux-2.4.29/arch/um/config_net.in  2005-05-03 22:28:14.000000000 +0300
202 @@ -0,0 +1,48 @@
203 +mainmenu_option next_comment
204 +comment 'Network Devices'
205 +
206 +# UML virtual driver
207 +bool 'Virtual network device' CONFIG_UML_NET
208 +
209 +dep_bool '  Ethertap transport' CONFIG_UML_NET_ETHERTAP $CONFIG_UML_NET
210 +dep_bool '  TUN/TAP transport' CONFIG_UML_NET_TUNTAP $CONFIG_UML_NET
211 +dep_bool '  SLIP transport' CONFIG_UML_NET_SLIP $CONFIG_UML_NET
212 +dep_bool '  SLiRP transport' CONFIG_UML_NET_SLIRP $CONFIG_UML_NET
213 +dep_bool '  Daemon transport' CONFIG_UML_NET_DAEMON $CONFIG_UML_NET
214 +dep_bool '  Multicast transport' CONFIG_UML_NET_MCAST $CONFIG_UML_NET
215 +dep_bool '  pcap transport' CONFIG_UML_NET_PCAP $CONFIG_UML_NET
216 +
217 +# Below are hardware-independent drivers mirrored from
218 +# drivers/net/Config.in. It would be nice if Linux
219 +# had HW independent drivers separated from the other
220 +# but it does not. Until then each non-ISA/PCI arch
221 +# needs to provide it's own menu of network drivers
222 +
223 +tristate 'Dummy net driver support' CONFIG_DUMMY
224 +tristate 'Bonding driver support' CONFIG_BONDING
225 +tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
226 +tristate 'Universal TUN/TAP device driver support' CONFIG_TUN
227 +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
228 +   if [ "$CONFIG_NETLINK" = "y" ]; then
229 +      tristate 'Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP
230 +   fi
231 +fi
232 +
233 +tristate 'PPP (point-to-point protocol) support' CONFIG_PPP
234 +if [ ! "$CONFIG_PPP" = "n" ]; then
235 +   dep_bool '  PPP multilink support (EXPERIMENTAL)' CONFIG_PPP_MULTILINK $CONFIG_EXPERIMENTAL
236 +   dep_bool '  PPP filtering' CONFIG_PPP_FILTER $CONFIG_FILTER
237 +   dep_tristate '  PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP
238 +   dep_tristate '  PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
239 +   dep_tristate '  PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
240 +   dep_tristate '  PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP
241 +   dep_tristate '  PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP $CONFIG_EXPERIMENTAL
242 +   dep_tristate '  PPP MPPE compression (encryption)' CONFIG_PPP_MPPE $CONFIG_PPP
243 +fi
244 +
245 +tristate 'SLIP (serial line) support' CONFIG_SLIP
246 +dep_bool '  CSLIP compressed headers' CONFIG_SLIP_COMPRESSED $CONFIG_SLIP
247 +dep_bool '  Keepalive and linefill' CONFIG_SLIP_SMART $CONFIG_SLIP
248 +dep_bool '  Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 $CONFIG_SLIP
249 +
250 +endmenu
251 Index: linux-2.4.29/arch/um/config.release
252 ===================================================================
253 --- linux-2.4.29.orig/arch/um/config.release    1970-01-01 03:00:00.000000000 +0300
254 +++ linux-2.4.29/arch/um/config.release 2005-05-03 22:28:14.000000000 +0300
255 @@ -0,0 +1,302 @@
256 +#
257 +# Automatically generated make config: don't edit
258 +#
259 +CONFIG_USERMODE=y
260 +# CONFIG_ISA is not set
261 +# CONFIG_SBUS is not set
262 +# CONFIG_PCI is not set
263 +CONFIG_UID16=y
264 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
265 +
266 +#
267 +# Code maturity level options
268 +#
269 +CONFIG_EXPERIMENTAL=y
270 +
271 +#
272 +# General Setup
273 +#
274 +CONFIG_NET=y
275 +CONFIG_SYSVIPC=y
276 +CONFIG_BSD_PROCESS_ACCT=y
277 +CONFIG_SYSCTL=y
278 +CONFIG_BINFMT_AOUT=y
279 +CONFIG_BINFMT_ELF=y
280 +CONFIG_BINFMT_MISC=y
281 +CONFIG_HOSTFS=y
282 +# CONFIG_HPPFS is not set
283 +CONFIG_MCONSOLE=y
284 +CONFIG_MAGIC_SYSRQ=y
285 +# CONFIG_HOST_2G_2G is not set
286 +# CONFIG_UML_SMP is not set
287 +# CONFIG_SMP is not set
288 +CONFIG_NEST_LEVEL=0
289 +CONFIG_KERNEL_HALF_GIGS=1
290 +
291 +#
292 +# Loadable module support
293 +#
294 +CONFIG_MODULES=y
295 +CONFIG_KMOD=y
296 +
297 +#
298 +# Character Devices
299 +#
300 +CONFIG_STDIO_CONSOLE=y
301 +CONFIG_SSL=y
302 +CONFIG_FD_CHAN=y
303 +# CONFIG_NULL_CHAN is not set
304 +CONFIG_PORT_CHAN=y
305 +CONFIG_PTY_CHAN=y
306 +CONFIG_TTY_CHAN=y
307 +CONFIG_XTERM_CHAN=y
308 +CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
309 +CONFIG_CON_CHAN="xterm"
310 +CONFIG_SSL_CHAN="pty"
311 +CONFIG_UNIX98_PTYS=y
312 +CONFIG_UNIX98_PTY_COUNT=256
313 +# CONFIG_WATCHDOG is not set
314 +CONFIG_UML_SOUND=y
315 +CONFIG_SOUND=y
316 +CONFIG_HOSTAUDIO=y
317 +# CONFIG_TTY_LOG is not set
318 +
319 +#
320 +# Block Devices
321 +#
322 +CONFIG_BLK_DEV_UBD=y
323 +# CONFIG_BLK_DEV_UBD_SYNC is not set
324 +CONFIG_BLK_DEV_LOOP=y
325 +CONFIG_BLK_DEV_NBD=y
326 +CONFIG_BLK_DEV_RAM=y
327 +CONFIG_BLK_DEV_RAM_SIZE=4096
328 +CONFIG_BLK_DEV_INITRD=y
329 +# CONFIG_MMAPPER is not set
330 +CONFIG_NETDEVICES=y
331 +
332 +#
333 +# Network Devices
334 +#
335 +CONFIG_UML_NET=y
336 +CONFIG_UML_NET_ETHERTAP=y
337 +CONFIG_UML_NET_TUNTAP=y
338 +CONFIG_UML_NET_SLIP=y
339 +CONFIG_UML_NET_DAEMON=y
340 +CONFIG_UML_NET_MCAST=y
341 +CONFIG_DUMMY=y
342 +CONFIG_BONDING=m
343 +CONFIG_EQUALIZER=m
344 +CONFIG_TUN=y
345 +CONFIG_PPP=m
346 +CONFIG_PPP_MULTILINK=y
347 +# CONFIG_PPP_ASYNC is not set
348 +CONFIG_PPP_SYNC_TTY=m
349 +CONFIG_PPP_DEFLATE=m
350 +CONFIG_PPP_BSDCOMP=m
351 +CONFIG_PPPOE=m
352 +CONFIG_SLIP=m
353 +
354 +#
355 +# Networking options
356 +#
357 +CONFIG_PACKET=y
358 +CONFIG_PACKET_MMAP=y
359 +# CONFIG_NETLINK_DEV is not set
360 +# CONFIG_NETFILTER is not set
361 +# CONFIG_FILTER is not set
362 +CONFIG_UNIX=y
363 +CONFIG_INET=y
364 +# CONFIG_IP_MULTICAST is not set
365 +# CONFIG_IP_ADVANCED_ROUTER is not set
366 +# CONFIG_IP_PNP is not set
367 +# CONFIG_NET_IPIP is not set
368 +# CONFIG_NET_IPGRE is not set
369 +# CONFIG_ARPD is not set
370 +# CONFIG_INET_ECN is not set
371 +# CONFIG_SYN_COOKIES is not set
372 +# CONFIG_IPV6 is not set
373 +# CONFIG_KHTTPD is not set
374 +# CONFIG_ATM is not set
375 +# CONFIG_VLAN_8021Q is not set
376 +
377 +#
378 +#  
379 +#
380 +# CONFIG_IPX is not set
381 +# CONFIG_ATALK is not set
382 +
383 +#
384 +# Appletalk devices
385 +#
386 +# CONFIG_DECNET is not set
387 +# CONFIG_BRIDGE is not set
388 +# CONFIG_X25 is not set
389 +# CONFIG_LAPB is not set
390 +# CONFIG_LLC is not set
391 +# CONFIG_NET_DIVERT is not set
392 +# CONFIG_ECONET is not set
393 +# CONFIG_WAN_ROUTER is not set
394 +# CONFIG_NET_FASTROUTE is not set
395 +# CONFIG_NET_HW_FLOWCONTROL is not set
396 +
397 +#
398 +# QoS and/or fair queueing
399 +#
400 +# CONFIG_NET_SCHED is not set
401 +
402 +#
403 +# Network testing
404 +#
405 +# CONFIG_NET_PKTGEN is not set
406 +
407 +#
408 +# File systems
409 +#
410 +CONFIG_QUOTA=y
411 +CONFIG_AUTOFS_FS=m
412 +CONFIG_AUTOFS4_FS=m
413 +CONFIG_REISERFS_FS=m
414 +# CONFIG_REISERFS_CHECK is not set
415 +# CONFIG_REISERFS_PROC_INFO is not set
416 +CONFIG_ADFS_FS=m
417 +# CONFIG_ADFS_FS_RW is not set
418 +CONFIG_AFFS_FS=m
419 +CONFIG_HFS_FS=m
420 +CONFIG_BFS_FS=m
421 +CONFIG_EXT3_FS=y
422 +CONFIG_JBD=y
423 +# CONFIG_JBD_DEBUG is not set
424 +CONFIG_FAT_FS=y
425 +CONFIG_MSDOS_FS=y
426 +CONFIG_UMSDOS_FS=y
427 +CONFIG_VFAT_FS=y
428 +CONFIG_EFS_FS=m
429 +CONFIG_CRAMFS=m
430 +CONFIG_TMPFS=y
431 +CONFIG_RAMFS=y
432 +CONFIG_ISO9660_FS=y
433 +# CONFIG_JOLIET is not set
434 +# CONFIG_ZISOFS is not set
435 +CONFIG_MINIX_FS=m
436 +CONFIG_VXFS_FS=m
437 +# CONFIG_NTFS_FS is not set
438 +CONFIG_HPFS_FS=m
439 +CONFIG_PROC_FS=y
440 +CONFIG_DEVFS_FS=y
441 +CONFIG_DEVFS_MOUNT=y
442 +# CONFIG_DEVFS_DEBUG is not set
443 +CONFIG_DEVPTS_FS=y
444 +CONFIG_QNX4FS_FS=m
445 +# CONFIG_QNX4FS_RW is not set
446 +CONFIG_ROMFS_FS=m
447 +CONFIG_EXT2_FS=y
448 +CONFIG_SYSV_FS=m
449 +CONFIG_UDF_FS=m
450 +# CONFIG_UDF_RW is not set
451 +CONFIG_UFS_FS=m
452 +# CONFIG_UFS_FS_WRITE is not set
453 +
454 +#
455 +# Network File Systems
456 +#
457 +# CONFIG_CODA_FS is not set
458 +# CONFIG_INTERMEZZO_FS is not set
459 +CONFIG_NFS_FS=y
460 +CONFIG_NFS_V3=y
461 +CONFIG_NFSD=y
462 +CONFIG_NFSD_V3=y
463 +CONFIG_SUNRPC=y
464 +CONFIG_LOCKD=y
465 +CONFIG_LOCKD_V4=y
466 +# CONFIG_SMB_FS is not set
467 +# CONFIG_NCP_FS is not set
468 +# CONFIG_ZISOFS_FS is not set
469 +CONFIG_ZLIB_FS_INFLATE=m
470 +
471 +#
472 +# Partition Types
473 +#
474 +# CONFIG_PARTITION_ADVANCED is not set
475 +CONFIG_MSDOS_PARTITION=y
476 +# CONFIG_SMB_NLS is not set
477 +CONFIG_NLS=y
478 +
479 +#
480 +# Native Language Support
481 +#
482 +CONFIG_NLS_DEFAULT="iso8859-1"
483 +# CONFIG_NLS_CODEPAGE_437 is not set
484 +# CONFIG_NLS_CODEPAGE_737 is not set
485 +# CONFIG_NLS_CODEPAGE_775 is not set
486 +# CONFIG_NLS_CODEPAGE_850 is not set
487 +# CONFIG_NLS_CODEPAGE_852 is not set
488 +# CONFIG_NLS_CODEPAGE_855 is not set
489 +# CONFIG_NLS_CODEPAGE_857 is not set
490 +# CONFIG_NLS_CODEPAGE_860 is not set
491 +# CONFIG_NLS_CODEPAGE_861 is not set
492 +# CONFIG_NLS_CODEPAGE_862 is not set
493 +# CONFIG_NLS_CODEPAGE_863 is not set
494 +# CONFIG_NLS_CODEPAGE_864 is not set
495 +# CONFIG_NLS_CODEPAGE_865 is not set
496 +# CONFIG_NLS_CODEPAGE_866 is not set
497 +# CONFIG_NLS_CODEPAGE_869 is not set
498 +# CONFIG_NLS_CODEPAGE_936 is not set
499 +# CONFIG_NLS_CODEPAGE_950 is not set
500 +# CONFIG_NLS_CODEPAGE_932 is not set
501 +# CONFIG_NLS_CODEPAGE_949 is not set
502 +# CONFIG_NLS_CODEPAGE_874 is not set
503 +# CONFIG_NLS_ISO8859_8 is not set
504 +# CONFIG_NLS_CODEPAGE_1250 is not set
505 +# CONFIG_NLS_CODEPAGE_1251 is not set
506 +# CONFIG_NLS_ISO8859_1 is not set
507 +# CONFIG_NLS_ISO8859_2 is not set
508 +# CONFIG_NLS_ISO8859_3 is not set
509 +# CONFIG_NLS_ISO8859_4 is not set
510 +# CONFIG_NLS_ISO8859_5 is not set
511 +# CONFIG_NLS_ISO8859_6 is not set
512 +# CONFIG_NLS_ISO8859_7 is not set
513 +# CONFIG_NLS_ISO8859_9 is not set
514 +# CONFIG_NLS_ISO8859_13 is not set
515 +# CONFIG_NLS_ISO8859_14 is not set
516 +# CONFIG_NLS_ISO8859_15 is not set
517 +# CONFIG_NLS_KOI8_R is not set
518 +# CONFIG_NLS_KOI8_U is not set
519 +# CONFIG_NLS_UTF8 is not set
520 +
521 +#
522 +# SCSI support
523 +#
524 +CONFIG_SCSI=y
525 +
526 +#
527 +# SCSI support type (disk, tape, CD-ROM)
528 +#
529 +# CONFIG_BLK_DEV_SD is not set
530 +# CONFIG_CHR_DEV_ST is not set
531 +# CONFIG_BLK_DEV_SR is not set
532 +# CONFIG_CHR_DEV_SG is not set
533 +
534 +#
535 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
536 +#
537 +# CONFIG_SCSI_DEBUG_QUEUES is not set
538 +# CONFIG_SCSI_MULTI_LUN is not set
539 +# CONFIG_SCSI_CONSTANTS is not set
540 +# CONFIG_SCSI_LOGGING is not set
541 +CONFIG_SCSI_DEBUG=m
542 +
543 +#
544 +# Multi-device support (RAID and LVM)
545 +#
546 +# CONFIG_MD is not set
547 +
548 +#
549 +# Memory Technology Devices (MTD)
550 +#
551 +# CONFIG_MTD is not set
552 +
553 +#
554 +# Kernel hacking
555 +#
556 +# CONFIG_DEBUG_SLAB is not set
557 +# CONFIG_DEBUGSYM is not set
558 Index: linux-2.4.29/arch/um/config_scsi.in
559 ===================================================================
560 --- linux-2.4.29.orig/arch/um/config_scsi.in    1970-01-01 03:00:00.000000000 +0300
561 +++ linux-2.4.29/arch/um/config_scsi.in 2005-05-03 22:28:14.000000000 +0300
562 @@ -0,0 +1,30 @@
563 +comment 'SCSI support type (disk, tape, CD-ROM)'
564 +
565 +dep_tristate '  SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
566 +
567 +if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then
568 +   int  'Maximum number of SCSI disks that can be loaded as modules' CONFIG_SD_EXTRA_DEVS 40
569 +fi
570 +
571 +dep_tristate '  SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
572 +
573 +dep_tristate '  SCSI CD-ROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
574 +
575 +if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
576 +   bool '    Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
577 +   int  'Maximum number of CDROM devices that can be loaded as modules' CONFIG_SR_EXTRA_DEVS 2
578 +fi
579 +dep_tristate '  SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
580 +
581 +comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
582 +
583 +#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
584 +   bool '  Enable extra checks in new queueing code' CONFIG_SCSI_DEBUG_QUEUES
585 +#fi
586 +
587 +bool '  Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
588 +  
589 +bool '  Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
590 +bool '  SCSI logging facility' CONFIG_SCSI_LOGGING
591 +
592 +dep_tristate 'SCSI debugging host simulator (EXPERIMENTAL)' CONFIG_SCSI_DEBUG $CONFIG_SCSI
593 Index: linux-2.4.29/arch/um/defconfig
594 ===================================================================
595 --- linux-2.4.29.orig/arch/um/defconfig 1970-01-01 03:00:00.000000000 +0300
596 +++ linux-2.4.29/arch/um/defconfig      2005-05-03 22:28:14.000000000 +0300
597 @@ -0,0 +1,430 @@
598 +#
599 +# Automatically generated make config: don't edit
600 +#
601 +CONFIG_USERMODE=y
602 +# CONFIG_ISA is not set
603 +# CONFIG_SBUS is not set
604 +# CONFIG_PCI is not set
605 +CONFIG_UID16=y
606 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
607 +
608 +#
609 +# Code maturity level options
610 +#
611 +CONFIG_EXPERIMENTAL=y
612 +
613 +#
614 +# General Setup
615 +#
616 +CONFIG_MODE_SKAS=y
617 +CONFIG_MODE_TT=y
618 +CONFIG_NET=y
619 +CONFIG_SYSVIPC=y
620 +CONFIG_BSD_PROCESS_ACCT=y
621 +CONFIG_SYSCTL=y
622 +CONFIG_BINFMT_AOUT=y
623 +CONFIG_BINFMT_ELF=y
624 +CONFIG_BINFMT_MISC=y
625 +CONFIG_HOSTFS=y
626 +CONFIG_HUMFS=y
627 +CONFIG_EXTERNFS=y
628 +CONFIG_HPPFS=y
629 +CONFIG_MCONSOLE=y
630 +CONFIG_MAGIC_SYSRQ=y
631 +# CONFIG_HOST_2G_2G is not set
632 +# CONFIG_UML_SMP is not set
633 +# CONFIG_SMP is not set
634 +CONFIG_NEST_LEVEL=0
635 +CONFIG_KERNEL_HALF_GIGS=1
636 +# CONFIG_HIGHMEM is not set
637 +CONFIG_PROC_MM=y
638 +CONFIG_KERNEL_STACK_ORDER=2
639 +CONFIG_UML_REAL_TIME_CLOCK=y
640 +
641 +#
642 +# Loadable module support
643 +#
644 +CONFIG_MODULES=y
645 +# CONFIG_KMOD is not set
646 +
647 +#
648 +# Character Devices
649 +#
650 +CONFIG_STDIO_CONSOLE=y
651 +CONFIG_SSL=y
652 +CONFIG_FD_CHAN=y
653 +CONFIG_NULL_CHAN=y
654 +CONFIG_PORT_CHAN=y
655 +CONFIG_PTY_CHAN=y
656 +CONFIG_TTY_CHAN=y
657 +CONFIG_XTERM_CHAN=y
658 +CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
659 +CONFIG_CON_CHAN="xterm"
660 +CONFIG_SSL_CHAN="pty"
661 +CONFIG_UNIX98_PTYS=y
662 +CONFIG_UNIX98_PTY_COUNT=256
663 +# CONFIG_WATCHDOG is not set
664 +# CONFIG_WATCHDOG_NOWAYOUT is not set
665 +# CONFIG_SOFT_WATCHDOG is not set
666 +# CONFIG_UML_WATCHDOG is not set
667 +CONFIG_UML_SOUND=y
668 +CONFIG_SOUND=y
669 +CONFIG_HOSTAUDIO=y
670 +# CONFIG_TTY_LOG is not set
671 +
672 +#
673 +# Block Devices
674 +#
675 +CONFIG_BLK_DEV_UBD=y
676 +# CONFIG_BLK_DEV_UBD_SYNC is not set
677 +# CONFIG_COW is not set
678 +CONFIG_COW_COMMON=y
679 +CONFIG_BLK_DEV_LOOP=y
680 +CONFIG_BLK_DEV_NBD=y
681 +CONFIG_BLK_DEV_RAM=y
682 +CONFIG_BLK_DEV_RAM_SIZE=4096
683 +CONFIG_BLK_DEV_INITRD=y
684 +# CONFIG_MMAPPER is not set
685 +CONFIG_NETDEVICES=y
686 +
687 +#
688 +# Network Devices
689 +#
690 +CONFIG_UML_NET=y
691 +CONFIG_UML_NET_ETHERTAP=y
692 +CONFIG_UML_NET_TUNTAP=y
693 +CONFIG_UML_NET_SLIP=y
694 +CONFIG_UML_NET_SLIRP=y
695 +CONFIG_UML_NET_DAEMON=y
696 +CONFIG_UML_NET_MCAST=y
697 +# CONFIG_UML_NET_PCAP is not set
698 +CONFIG_DUMMY=y
699 +# CONFIG_BONDING is not set
700 +# CONFIG_EQUALIZER is not set
701 +CONFIG_TUN=y
702 +CONFIG_PPP=y
703 +# CONFIG_PPP_MULTILINK is not set
704 +# CONFIG_PPP_FILTER is not set
705 +# CONFIG_PPP_ASYNC is not set
706 +# CONFIG_PPP_SYNC_TTY is not set
707 +# CONFIG_PPP_DEFLATE is not set
708 +# CONFIG_PPP_BSDCOMP is not set
709 +# CONFIG_PPPOE is not set
710 +# CONFIG_PPP_MPPE is not set
711 +CONFIG_SLIP=y
712 +# CONFIG_SLIP_COMPRESSED is not set
713 +# CONFIG_SLIP_SMART is not set
714 +# CONFIG_SLIP_MODE_SLIP6 is not set
715 +
716 +#
717 +# Networking options
718 +#
719 +CONFIG_PACKET=y
720 +CONFIG_PACKET_MMAP=y
721 +# CONFIG_NETLINK_DEV is not set
722 +# CONFIG_NETFILTER is not set
723 +# CONFIG_FILTER is not set
724 +CONFIG_UNIX=y
725 +CONFIG_INET=y
726 +# CONFIG_IP_MULTICAST is not set
727 +# CONFIG_IP_ADVANCED_ROUTER is not set
728 +# CONFIG_IP_PNP is not set
729 +# CONFIG_NET_IPIP is not set
730 +# CONFIG_NET_IPGRE is not set
731 +# CONFIG_ARPD is not set
732 +# CONFIG_INET_ECN is not set
733 +# CONFIG_SYN_COOKIES is not set
734 +# CONFIG_IPV6 is not set
735 +# CONFIG_KHTTPD is not set
736 +
737 +#
738 +#    SCTP Configuration (EXPERIMENTAL)
739 +#
740 +CONFIG_IPV6_SCTP__=y
741 +# CONFIG_IP_SCTP is not set
742 +# CONFIG_ATM is not set
743 +# CONFIG_VLAN_8021Q is not set
744 +
745 +#
746 +#  
747 +#
748 +# CONFIG_IPX is not set
749 +# CONFIG_ATALK is not set
750 +
751 +#
752 +# Appletalk devices
753 +#
754 +# CONFIG_DEV_APPLETALK is not set
755 +# CONFIG_DECNET is not set
756 +# CONFIG_BRIDGE is not set
757 +# CONFIG_X25 is not set
758 +# CONFIG_LAPB is not set
759 +# CONFIG_LLC is not set
760 +# CONFIG_NET_DIVERT is not set
761 +# CONFIG_ECONET is not set
762 +# CONFIG_WAN_ROUTER is not set
763 +# CONFIG_NET_FASTROUTE is not set
764 +# CONFIG_NET_HW_FLOWCONTROL is not set
765 +
766 +#
767 +# QoS and/or fair queueing
768 +#
769 +# CONFIG_NET_SCHED is not set
770 +
771 +#
772 +# Network testing
773 +#
774 +# CONFIG_NET_PKTGEN is not set
775 +
776 +#
777 +# File systems
778 +#
779 +CONFIG_QUOTA=y
780 +# CONFIG_QFMT_V2 is not set
781 +CONFIG_AUTOFS_FS=y
782 +CONFIG_AUTOFS4_FS=y
783 +CONFIG_REISERFS_FS=y
784 +# CONFIG_REISERFS_CHECK is not set
785 +# CONFIG_REISERFS_PROC_INFO is not set
786 +# CONFIG_ADFS_FS is not set
787 +# CONFIG_ADFS_FS_RW is not set
788 +# CONFIG_AFFS_FS is not set
789 +# CONFIG_HFS_FS is not set
790 +# CONFIG_HFSPLUS_FS is not set
791 +# CONFIG_BEFS_FS is not set
792 +# CONFIG_BEFS_DEBUG is not set
793 +# CONFIG_BFS_FS is not set
794 +CONFIG_EXT3_FS=y
795 +CONFIG_JBD=y
796 +# CONFIG_JBD_DEBUG is not set
797 +CONFIG_FAT_FS=y
798 +CONFIG_MSDOS_FS=y
799 +CONFIG_UMSDOS_FS=y
800 +CONFIG_VFAT_FS=y
801 +# CONFIG_EFS_FS is not set
802 +CONFIG_JFFS_FS=y
803 +CONFIG_JFFS_FS_VERBOSE=0
804 +CONFIG_JFFS_PROC_FS=y
805 +CONFIG_JFFS2_FS=y
806 +CONFIG_JFFS2_FS_DEBUG=0
807 +# CONFIG_CRAMFS is not set
808 +CONFIG_TMPFS=y
809 +CONFIG_RAMFS=y
810 +CONFIG_ISO9660_FS=y
811 +# CONFIG_JOLIET is not set
812 +# CONFIG_ZISOFS is not set
813 +# CONFIG_JFS_FS is not set
814 +# CONFIG_JFS_DEBUG is not set
815 +# CONFIG_JFS_STATISTICS is not set
816 +CONFIG_MINIX_FS=y
817 +# CONFIG_VXFS_FS is not set
818 +# CONFIG_NTFS_FS is not set
819 +# CONFIG_NTFS_RW is not set
820 +# CONFIG_HPFS_FS is not set
821 +CONFIG_PROC_FS=y
822 +CONFIG_DEVFS_FS=y
823 +CONFIG_DEVFS_MOUNT=y
824 +# CONFIG_DEVFS_DEBUG is not set
825 +CONFIG_DEVPTS_FS=y
826 +# CONFIG_QNX4FS_FS is not set
827 +# CONFIG_QNX4FS_RW is not set
828 +# CONFIG_ROMFS_FS is not set
829 +CONFIG_EXT2_FS=y
830 +# CONFIG_SYSV_FS is not set
831 +# CONFIG_UDF_FS is not set
832 +# CONFIG_UDF_RW is not set
833 +# CONFIG_UFS_FS is not set
834 +# CONFIG_UFS_FS_WRITE is not set
835 +# CONFIG_XFS_FS is not set
836 +# CONFIG_XFS_QUOTA is not set
837 +# CONFIG_XFS_RT is not set
838 +# CONFIG_XFS_TRACE is not set
839 +# CONFIG_XFS_DEBUG is not set
840 +
841 +#
842 +# Network File Systems
843 +#
844 +# CONFIG_CODA_FS is not set
845 +# CONFIG_INTERMEZZO_FS is not set
846 +# CONFIG_NFS_FS is not set
847 +# CONFIG_NFS_V3 is not set
848 +# CONFIG_NFS_DIRECTIO is not set
849 +# CONFIG_ROOT_NFS is not set
850 +# CONFIG_NFSD is not set
851 +# CONFIG_NFSD_V3 is not set
852 +# CONFIG_NFSD_TCP is not set
853 +# CONFIG_SUNRPC is not set
854 +# CONFIG_LOCKD is not set
855 +# CONFIG_SMB_FS is not set
856 +# CONFIG_NCP_FS is not set
857 +# CONFIG_NCPFS_PACKET_SIGNING is not set
858 +# CONFIG_NCPFS_IOCTL_LOCKING is not set
859 +# CONFIG_NCPFS_STRONG is not set
860 +# CONFIG_NCPFS_NFS_NS is not set
861 +# CONFIG_NCPFS_OS2_NS is not set
862 +# CONFIG_NCPFS_SMALLDOS is not set
863 +# CONFIG_NCPFS_NLS is not set
864 +# CONFIG_NCPFS_EXTRAS is not set
865 +# CONFIG_ZISOFS_FS is not set
866 +
867 +#
868 +# Partition Types
869 +#
870 +# CONFIG_PARTITION_ADVANCED is not set
871 +CONFIG_MSDOS_PARTITION=y
872 +# CONFIG_SMB_NLS is not set
873 +CONFIG_NLS=y
874 +
875 +#
876 +# Native Language Support
877 +#
878 +CONFIG_NLS_DEFAULT="iso8859-1"
879 +# CONFIG_NLS_CODEPAGE_437 is not set
880 +# CONFIG_NLS_CODEPAGE_737 is not set
881 +# CONFIG_NLS_CODEPAGE_775 is not set
882 +# CONFIG_NLS_CODEPAGE_850 is not set
883 +# CONFIG_NLS_CODEPAGE_852 is not set
884 +# CONFIG_NLS_CODEPAGE_855 is not set
885 +# CONFIG_NLS_CODEPAGE_857 is not set
886 +# CONFIG_NLS_CODEPAGE_860 is not set
887 +# CONFIG_NLS_CODEPAGE_861 is not set
888 +# CONFIG_NLS_CODEPAGE_862 is not set
889 +# CONFIG_NLS_CODEPAGE_863 is not set
890 +# CONFIG_NLS_CODEPAGE_864 is not set
891 +# CONFIG_NLS_CODEPAGE_865 is not set
892 +# CONFIG_NLS_CODEPAGE_866 is not set
893 +# CONFIG_NLS_CODEPAGE_869 is not set
894 +# CONFIG_NLS_CODEPAGE_936 is not set
895 +# CONFIG_NLS_CODEPAGE_950 is not set
896 +# CONFIG_NLS_CODEPAGE_932 is not set
897 +# CONFIG_NLS_CODEPAGE_949 is not set
898 +# CONFIG_NLS_CODEPAGE_874 is not set
899 +# CONFIG_NLS_ISO8859_8 is not set
900 +# CONFIG_NLS_CODEPAGE_1250 is not set
901 +# CONFIG_NLS_CODEPAGE_1251 is not set
902 +# CONFIG_NLS_ISO8859_1 is not set
903 +# CONFIG_NLS_ISO8859_2 is not set
904 +# CONFIG_NLS_ISO8859_3 is not set
905 +# CONFIG_NLS_ISO8859_4 is not set
906 +# CONFIG_NLS_ISO8859_5 is not set
907 +# CONFIG_NLS_ISO8859_6 is not set
908 +# CONFIG_NLS_ISO8859_7 is not set
909 +# CONFIG_NLS_ISO8859_9 is not set
910 +# CONFIG_NLS_ISO8859_13 is not set
911 +# CONFIG_NLS_ISO8859_14 is not set
912 +# CONFIG_NLS_ISO8859_15 is not set
913 +# CONFIG_NLS_KOI8_R is not set
914 +# CONFIG_NLS_KOI8_U is not set
915 +# CONFIG_NLS_UTF8 is not set
916 +
917 +#
918 +# SCSI support
919 +#
920 +CONFIG_SCSI=y
921 +
922 +#
923 +# SCSI support type (disk, tape, CD-ROM)
924 +#
925 +# CONFIG_BLK_DEV_SD is not set
926 +# CONFIG_CHR_DEV_ST is not set
927 +# CONFIG_BLK_DEV_SR is not set
928 +# CONFIG_CHR_DEV_SG is not set
929 +
930 +#
931 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
932 +#
933 +# CONFIG_SCSI_DEBUG_QUEUES is not set
934 +# CONFIG_SCSI_MULTI_LUN is not set
935 +# CONFIG_SCSI_CONSTANTS is not set
936 +# CONFIG_SCSI_LOGGING is not set
937 +CONFIG_SCSI_DEBUG=y
938 +
939 +#
940 +# Multi-device support (RAID and LVM)
941 +#
942 +# CONFIG_MD is not set
943 +# CONFIG_BLK_DEV_MD is not set
944 +# CONFIG_MD_LINEAR is not set
945 +# CONFIG_MD_RAID0 is not set
946 +# CONFIG_MD_RAID1 is not set
947 +# CONFIG_MD_RAID5 is not set
948 +# CONFIG_MD_MULTIPATH is not set
949 +# CONFIG_BLK_DEV_LVM is not set
950 +
951 +#
952 +# Memory Technology Devices (MTD)
953 +#
954 +CONFIG_MTD=y
955 +# CONFIG_MTD_DEBUG is not set
956 +# CONFIG_MTD_PARTITIONS is not set
957 +# CONFIG_MTD_CONCAT is not set
958 +# CONFIG_MTD_REDBOOT_PARTS is not set
959 +# CONFIG_MTD_CMDLINE_PARTS is not set
960 +
961 +#
962 +# User Modules And Translation Layers
963 +#
964 +CONFIG_MTD_CHAR=y
965 +CONFIG_MTD_BLOCK=y
966 +# CONFIG_FTL is not set
967 +# CONFIG_NFTL is not set
968 +
969 +#
970 +# RAM/ROM/Flash chip drivers
971 +#
972 +# CONFIG_MTD_CFI is not set
973 +# CONFIG_MTD_JEDECPROBE is not set
974 +# CONFIG_MTD_GEN_PROBE is not set
975 +# CONFIG_MTD_CFI_INTELEXT is not set
976 +# CONFIG_MTD_CFI_AMDSTD is not set
977 +# CONFIG_MTD_CFI_STAA is not set
978 +# CONFIG_MTD_RAM is not set
979 +# CONFIG_MTD_ROM is not set
980 +# CONFIG_MTD_ABSENT is not set
981 +# CONFIG_MTD_OBSOLETE_CHIPS is not set
982 +# CONFIG_MTD_AMDSTD is not set
983 +# CONFIG_MTD_SHARP is not set
984 +# CONFIG_MTD_JEDEC is not set
985 +
986 +#
987 +# Mapping drivers for chip access
988 +#
989 +# CONFIG_MTD_PHYSMAP is not set
990 +# CONFIG_MTD_PCI is not set
991 +# CONFIG_MTD_PCMCIA is not set
992 +
993 +#
994 +# Self-contained MTD device drivers
995 +#
996 +# CONFIG_MTD_PMC551 is not set
997 +# CONFIG_MTD_SLRAM is not set
998 +# CONFIG_MTD_MTDRAM is not set
999 +CONFIG_MTD_BLKMTD=y
1000 +
1001 +#
1002 +# Disk-On-Chip Device Drivers
1003 +#
1004 +# CONFIG_MTD_DOC1000 is not set
1005 +# CONFIG_MTD_DOC2000 is not set
1006 +# CONFIG_MTD_DOC2001 is not set
1007 +# CONFIG_MTD_DOCPROBE is not set
1008 +
1009 +#
1010 +# NAND Flash Device Drivers
1011 +#
1012 +# CONFIG_MTD_NAND is not set
1013 +
1014 +#
1015 +# Library routines
1016 +#
1017 +# CONFIG_CRC32 is not set
1018 +CONFIG_ZLIB_INFLATE=y
1019 +CONFIG_ZLIB_DEFLATE=y
1020 +
1021 +#
1022 +# Kernel hacking
1023 +#
1024 +# CONFIG_DEBUG_SLAB is not set
1025 +CONFIG_DEBUGSYM=y
1026 +CONFIG_PT_PROXY=y
1027 +# CONFIG_GCOV is not set
1028 Index: linux-2.4.29/arch/um/drivers/chan_kern.c
1029 ===================================================================
1030 --- linux-2.4.29.orig/arch/um/drivers/chan_kern.c       1970-01-01 03:00:00.000000000 +0300
1031 +++ linux-2.4.29/arch/um/drivers/chan_kern.c    2005-05-03 22:28:14.196452024 +0300
1032 @@ -0,0 +1,568 @@
1033 +/* 
1034 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
1035 + * Licensed under the GPL
1036 + */
1037 +
1038 +#include <linux/stddef.h>
1039 +#include <linux/kernel.h>
1040 +#include <linux/list.h>
1041 +#include <linux/slab.h>
1042 +#include <linux/tty.h>
1043 +#include <linux/string.h>
1044 +#include <linux/tty_flip.h>
1045 +#include <asm/irq.h>
1046 +#include "chan_kern.h"
1047 +#include "user_util.h"
1048 +#include "kern.h"
1049 +#include "irq_user.h"
1050 +#include "sigio.h"
1051 +#include "line.h"
1052 +#include "os.h"
1053 +
1054 +static void *not_configged_init(char *str, int device, struct chan_opts *opts)
1055 +{
1056 +       printk(KERN_ERR "Using a channel type which is configured out of "
1057 +              "UML\n");
1058 +       return(NULL);
1059 +}
1060 +
1061 +static int not_configged_open(int input, int output, int primary, void *data,
1062 +                             char **dev_out)
1063 +{
1064 +       printk(KERN_ERR "Using a channel type which is configured out of "
1065 +              "UML\n");
1066 +       return(-ENODEV);
1067 +}
1068 +
1069 +static void not_configged_close(int fd, void *data)
1070 +{
1071 +       printk(KERN_ERR "Using a channel type which is configured out of "
1072 +              "UML\n");
1073 +}
1074 +
1075 +static int not_configged_read(int fd, char *c_out, void *data)
1076 +{
1077 +       printk(KERN_ERR "Using a channel type which is configured out of "
1078 +              "UML\n");
1079 +       return(-EIO);
1080 +}
1081 +
1082 +static int not_configged_write(int fd, const char *buf, int len, void *data)
1083 +{
1084 +       printk(KERN_ERR "Using a channel type which is configured out of "
1085 +              "UML\n");
1086 +       return(-EIO);
1087 +}
1088 +
1089 +static int not_configged_console_write(int fd, const char *buf, int len,
1090 +                                      void *data)
1091 +{
1092 +       printk(KERN_ERR "Using a channel type which is configured out of "
1093 +              "UML\n");
1094 +       return(-EIO);
1095 +}
1096 +
1097 +static int not_configged_window_size(int fd, void *data, unsigned short *rows,
1098 +                                    unsigned short *cols)
1099 +{
1100 +       printk(KERN_ERR "Using a channel type which is configured out of "
1101 +              "UML\n");
1102 +       return(-ENODEV);
1103 +}
1104 +
1105 +static void not_configged_free(void *data)
1106 +{
1107 +       printk(KERN_ERR "Using a channel type which is configured out of "
1108 +              "UML\n");
1109 +}
1110 +
1111 +static struct chan_ops not_configged_ops = {
1112 +       .init           = not_configged_init,
1113 +       .open           = not_configged_open,
1114 +       .close          = not_configged_close,
1115 +       .read           = not_configged_read,
1116 +       .write          = not_configged_write,
1117 +       .console_write  = not_configged_console_write,
1118 +       .window_size    = not_configged_window_size,
1119 +       .free           = not_configged_free,
1120 +       .winch          = 0,
1121 +};
1122 +
1123 +void generic_close(int fd, void *unused)
1124 +{
1125 +       os_close_file(fd);
1126 +}
1127 +
1128 +int generic_read(int fd, char *c_out, void *unused)
1129 +{
1130 +       int n;
1131 +
1132 +       n = os_read_file(fd, c_out, sizeof(*c_out));
1133 +
1134 +       if(n == -EAGAIN)
1135 +               return(0);
1136 +       else if(n == 0)
1137 +               return(-EIO);
1138 +       return(n);
1139 +}
1140 +
1141 +/* XXX Trivial wrapper around os_write_file */
1142 +
1143 +int generic_write(int fd, const char *buf, int n, void *unused)
1144 +{
1145 +       return(os_write_file(fd, buf, n));
1146 +}
1147 +
1148 +int generic_window_size(int fd, void *unused, unsigned short *rows_out,
1149 +                       unsigned short *cols_out)
1150 +{
1151 +       int rows, cols;
1152 +       int ret;
1153 +
1154 +       ret = os_window_size(fd, &rows, &cols);
1155 +       if(ret < 0)
1156 +               return(ret);
1157 +
1158 +       ret = ((*rows_out != rows) || (*cols_out != cols));
1159 +
1160 +       *rows_out = rows;
1161 +       *cols_out = cols;
1162 +
1163 +       return(ret);
1164 +}
1165 +
1166 +void generic_free(void *data)
1167 +{
1168 +       kfree(data);
1169 +}
1170 +
1171 +static void tty_receive_char(struct tty_struct *tty, char ch)
1172 +{
1173 +       if(tty == NULL) return;
1174 +
1175 +       if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
1176 +               if(ch == STOP_CHAR(tty)){
1177 +                       stop_tty(tty);
1178 +                       return;
1179 +               }
1180 +               else if(ch == START_CHAR(tty)){
1181 +                       start_tty(tty);
1182 +                       return;
1183 +               }
1184 +       }
1185 +
1186 +       if((tty->flip.flag_buf_ptr == NULL) || 
1187 +          (tty->flip.char_buf_ptr == NULL))
1188 +               return;
1189 +       tty_insert_flip_char(tty, ch, TTY_NORMAL);
1190 +}
1191 +
1192 +static int open_one_chan(struct chan *chan, int input, int output, int primary)
1193 +{
1194 +       int fd;
1195 +
1196 +       if(chan->opened) return(0);
1197 +       if(chan->ops->open == NULL) fd = 0;
1198 +       else fd = (*chan->ops->open)(input, output, primary, chan->data,
1199 +                                    &chan->dev);
1200 +       if(fd < 0) return(fd);
1201 +       chan->fd = fd;
1202 +
1203 +       chan->opened = 1;
1204 +       return(0);
1205 +}
1206 +
1207 +int open_chan(struct list_head *chans)
1208 +{
1209 +       struct list_head *ele;
1210 +       struct chan *chan;
1211 +       int ret, err = 0;
1212 +
1213 +       list_for_each(ele, chans){
1214 +               chan = list_entry(ele, struct chan, list);
1215 +               ret = open_one_chan(chan, chan->input, chan->output,
1216 +                                   chan->primary);
1217 +               if(chan->primary) err = ret;
1218 +       }
1219 +       return(err);
1220 +}
1221 +
1222 +void chan_enable_winch(struct list_head *chans, void *line)
1223 +{
1224 +       struct list_head *ele;
1225 +       struct chan *chan;
1226 +
1227 +       list_for_each(ele, chans){
1228 +               chan = list_entry(ele, struct chan, list);
1229 +               if(chan->primary && chan->output && chan->ops->winch){
1230 +                       register_winch(chan->fd, line);
1231 +                       return;
1232 +               }
1233 +       }
1234 +}
1235 +
1236 +void enable_chan(struct list_head *chans, void *data)
1237 +{
1238 +       struct list_head *ele;
1239 +       struct chan *chan;
1240 +
1241 +       list_for_each(ele, chans){
1242 +               chan = list_entry(ele, struct chan, list);
1243 +               if(!chan->opened) continue;
1244 +
1245 +               line_setup_irq(chan->fd, chan->input, chan->output, data);
1246 +       }
1247 +}
1248 +
1249 +void close_chan(struct list_head *chans)
1250 +{
1251 +       struct list_head *ele;
1252 +       struct chan *chan;
1253 +
1254 +       /* Close in reverse order as open in case more than one of them
1255 +        * refers to the same device and they save and restore that device's
1256 +        * state.  Then, the first one opened will have the original state,
1257 +        * so it must be the last closed.
1258 +        */
1259 +        for(ele = chans->prev; ele != chans; ele = ele->prev){
1260 +                chan = list_entry(ele, struct chan, list);
1261 +               if(!chan->opened) continue;
1262 +               if(chan->ops->close != NULL)
1263 +                       (*chan->ops->close)(chan->fd, chan->data);
1264 +               chan->opened = 0;
1265 +               chan->fd = -1;
1266 +       }
1267 +}
1268 +
1269 +int write_chan(struct list_head *chans, const char *buf, int len, 
1270 +              int write_irq)
1271 +{
1272 +       struct list_head *ele;
1273 +       struct chan *chan;
1274 +       int n, ret = 0;
1275 +
1276 +       list_for_each(ele, chans){
1277 +               chan = list_entry(ele, struct chan, list);
1278 +               if(!chan->output || (chan->ops->write == NULL)) continue;
1279 +               n = chan->ops->write(chan->fd, buf, len, chan->data);
1280 +               if(chan->primary){
1281 +                       ret = n;
1282 +                       if((ret == -EAGAIN) || ((ret >= 0) && (ret < len))){
1283 +                               reactivate_fd(chan->fd, write_irq);
1284 +                               if(ret == -EAGAIN) ret = 0;
1285 +                       }
1286 +               }
1287 +       }
1288 +       return(ret);
1289 +}
1290 +
1291 +int console_write_chan(struct list_head *chans, const char *buf, int len)
1292 +{
1293 +       struct list_head *ele;
1294 +       struct chan *chan;
1295 +       int n, ret = 0;
1296 +
1297 +       list_for_each(ele, chans){
1298 +               chan = list_entry(ele, struct chan, list);
1299 +               if(!chan->output || (chan->ops->console_write == NULL))
1300 +                       continue;
1301 +               n = chan->ops->console_write(chan->fd, buf, len, chan->data);
1302 +               if(chan->primary) ret = n;
1303 +       }
1304 +       return(ret);
1305 +}
1306 +
1307 +int chan_window_size(struct list_head *chans, unsigned short *rows_out,
1308 +                     unsigned short *cols_out)
1309 +{
1310 +       struct list_head *ele;
1311 +       struct chan *chan;
1312 +
1313 +       list_for_each(ele, chans){
1314 +               chan = list_entry(ele, struct chan, list);
1315 +               if(chan->primary){
1316 +                       if(chan->ops->window_size == NULL) return(0);
1317 +                       return(chan->ops->window_size(chan->fd, chan->data,
1318 +                                                     rows_out, cols_out));
1319 +               }
1320 +       }
1321 +       return(0);
1322 +}
1323 +
1324 +void free_one_chan(struct chan *chan)
1325 +{
1326 +       list_del(&chan->list);
1327 +       if(chan->ops->free != NULL)
1328 +               (*chan->ops->free)(chan->data);
1329 +       free_irq_by_fd(chan->fd);
1330 +       if(chan->primary && chan->output) ignore_sigio_fd(chan->fd);
1331 +       kfree(chan);
1332 +}
1333 +
1334 +void free_chan(struct list_head *chans)
1335 +{
1336 +       struct list_head *ele, *next;
1337 +       struct chan *chan;
1338 +
1339 +       list_for_each_safe(ele, next, chans){
1340 +               chan = list_entry(ele, struct chan, list);
1341 +               free_one_chan(chan);
1342 +       }
1343 +}
1344 +
1345 +static int one_chan_config_string(struct chan *chan, char *str, int size,
1346 +                                 char **error_out)
1347 +{
1348 +       int n = 0;
1349 +
1350 +       if(chan == NULL){
1351 +               CONFIG_CHUNK(str, size, n, "none", 1);
1352 +               return(n);
1353 +       }
1354 +
1355 +       CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
1356 +
1357 +       if(chan->dev == NULL){
1358 +               CONFIG_CHUNK(str, size, n, "", 1);
1359 +               return(n);
1360 +       }
1361 +
1362 +       CONFIG_CHUNK(str, size, n, ":", 0);
1363 +       CONFIG_CHUNK(str, size, n, chan->dev, 0);
1364 +
1365 +       return(n);
1366 +}
1367 +
1368 +static int chan_pair_config_string(struct chan *in, struct chan *out, 
1369 +                                  char *str, int size, char **error_out)
1370 +{
1371 +       int n;
1372 +
1373 +       n = one_chan_config_string(in, str, size, error_out);
1374 +       str += n;
1375 +       size -= n;
1376 +
1377 +       if(in == out){
1378 +               CONFIG_CHUNK(str, size, n, "", 1);
1379 +               return(n);
1380 +       }
1381 +
1382 +       CONFIG_CHUNK(str, size, n, ",", 1);
1383 +       n = one_chan_config_string(out, str, size, error_out);
1384 +       str += n;
1385 +       size -= n;
1386 +       CONFIG_CHUNK(str, size, n, "", 1);
1387 +
1388 +       return(n);
1389 +}
1390 +
1391 +int chan_config_string(struct list_head *chans, char *str, int size, 
1392 +                      char **error_out)
1393 +{
1394 +       struct list_head *ele;
1395 +       struct chan *chan, *in = NULL, *out = NULL;
1396 +
1397 +       list_for_each(ele, chans){
1398 +               chan = list_entry(ele, struct chan, list);
1399 +               if(!chan->primary)
1400 +                       continue;
1401 +               if(chan->input)
1402 +                       in = chan;
1403 +               if(chan->output)
1404 +                       out = chan;
1405 +       }
1406 +
1407 +       return(chan_pair_config_string(in, out, str, size, error_out));
1408 +}
1409 +
1410 +struct chan_type {
1411 +       char *key;
1412 +       struct chan_ops *ops;
1413 +};
1414 +
1415 +struct chan_type chan_table[] = {
1416 +#ifdef CONFIG_FD_CHAN
1417 +       { "fd", &fd_ops },
1418 +#else
1419 +       { "fd", &not_configged_ops },
1420 +#endif
1421 +
1422 +#ifdef CONFIG_NULL_CHAN
1423 +       { "null", &null_ops },
1424 +#else
1425 +       { "null", &not_configged_ops },
1426 +#endif
1427 +
1428 +#ifdef CONFIG_PORT_CHAN
1429 +       { "port", &port_ops },
1430 +#else
1431 +       { "port", &not_configged_ops },
1432 +#endif
1433 +
1434 +#ifdef CONFIG_PTY_CHAN
1435 +       { "pty", &pty_ops },
1436 +       { "pts", &pts_ops },
1437 +#else
1438 +       { "pty", &not_configged_ops },
1439 +       { "pts", &not_configged_ops },
1440 +#endif
1441 +
1442 +#ifdef CONFIG_TTY_CHAN
1443 +       { "tty", &tty_ops },
1444 +#else
1445 +       { "tty", &not_configged_ops },
1446 +#endif
1447 +
1448 +#ifdef CONFIG_XTERM_CHAN
1449 +       { "xterm", &xterm_ops },
1450 +#else
1451 +       { "xterm", &not_configged_ops },
1452 +#endif
1453 +};
1454 +
1455 +static struct chan *parse_chan(char *str, int pri, int device, 
1456 +                              struct chan_opts *opts)
1457 +{
1458 +       struct chan_type *entry;
1459 +       struct chan_ops *ops;
1460 +       struct chan *chan;
1461 +       void *data;
1462 +       int i;
1463 +
1464 +       ops = NULL;
1465 +       data = NULL;
1466 +       for(i = 0; i < sizeof(chan_table)/sizeof(chan_table[0]); i++){
1467 +               entry = &chan_table[i];
1468 +               if(!strncmp(str, entry->key, strlen(entry->key))){
1469 +                       ops = entry->ops;
1470 +                       str += strlen(entry->key);
1471 +                       break;
1472 +               }
1473 +       }
1474 +       if(ops == NULL){
1475 +               printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n", 
1476 +                      str);
1477 +               return(NULL);
1478 +       }
1479 +       if(ops->init == NULL) return(NULL); 
1480 +       data = (*ops->init)(str, device, opts);
1481 +       if(data == NULL) return(NULL);
1482 +
1483 +       chan = kmalloc(sizeof(*chan), GFP_KERNEL);
1484 +       if(chan == NULL) return(NULL);
1485 +       *chan = ((struct chan) { .list          = LIST_HEAD_INIT(chan->list),
1486 +                                .primary       = 1,
1487 +                                .input         = 0,
1488 +                                .output        = 0,
1489 +                                .opened        = 0,
1490 +                                .fd            = -1,
1491 +                                .pri           = pri,
1492 +                                .ops           = ops,
1493 +                                .data          = data });
1494 +       return(chan);
1495 +}
1496 +
1497 +int parse_chan_pair(char *str, struct list_head *chans, int pri, int device,
1498 +                   struct chan_opts *opts)
1499 +{
1500 +       struct chan *new, *chan;
1501 +       char *in, *out;
1502 +
1503 +       if(!list_empty(chans)){
1504 +               chan = list_entry(chans->next, struct chan, list);
1505 +               if(chan->pri >= pri) return(0);
1506 +               free_chan(chans);
1507 +               INIT_LIST_HEAD(chans);
1508 +       }
1509 +
1510 +       out = strchr(str, ',');
1511 +       if(out != NULL){
1512 +               in = str;
1513 +               *out = '\0';
1514 +               out++;
1515 +               new = parse_chan(in, pri, device, opts);
1516 +               if(new == NULL) return(-1);
1517 +               new->input = 1;
1518 +               list_add(&new->list, chans);
1519 +
1520 +               new = parse_chan(out, pri, device, opts);
1521 +               if(new == NULL) return(-1);
1522 +               list_add(&new->list, chans);
1523 +               new->output = 1;
1524 +       }
1525 +       else {
1526 +               new = parse_chan(str, pri, device, opts);
1527 +               if(new == NULL) return(-1);
1528 +               list_add(&new->list, chans);
1529 +               new->input = 1;
1530 +               new->output = 1;
1531 +       }
1532 +       return(0);
1533 +}
1534 +
1535 +int chan_out_fd(struct list_head *chans)
1536 +{
1537 +       struct list_head *ele;
1538 +       struct chan *chan;
1539 +
1540 +       list_for_each(ele, chans){
1541 +               chan = list_entry(ele, struct chan, list);
1542 +               if(chan->primary && chan->output)
1543 +                       return(chan->fd);
1544 +       }
1545 +       return(-1);
1546 +}
1547 +
1548 +void chan_interrupt(struct list_head *chans, struct tq_struct *task,
1549 +                   struct tty_struct *tty, int irq, void *dev)
1550 +{
1551 +       struct list_head *ele, *next;
1552 +       struct chan *chan;
1553 +       int err;
1554 +       char c;
1555 +
1556 +       list_for_each_safe(ele, next, chans){
1557 +               chan = list_entry(ele, struct chan, list);
1558 +               if(!chan->input || (chan->ops->read == NULL)) continue;
1559 +               do {
1560 +                       if((tty != NULL) && 
1561 +                          (tty->flip.count >= TTY_FLIPBUF_SIZE)){
1562 +                               queue_task(task, &tq_timer);
1563 +                               goto out;
1564 +                       }
1565 +                       err = chan->ops->read(chan->fd, &c, chan->data);
1566 +                       if(err > 0) 
1567 +                               tty_receive_char(tty, c);
1568 +               } while(err > 0);
1569 +
1570 +               if(err == 0) reactivate_fd(chan->fd, irq);
1571 +               if(err == -EIO){
1572 +                       if(chan->primary){
1573 +                               if(tty != NULL) 
1574 +                                       tty_hangup(tty);
1575 +                               line_disable(dev, irq);
1576 +                               close_chan(chans);
1577 +                               free_chan(chans);
1578 +                               return;
1579 +                       }
1580 +                       else {
1581 +                               if(chan->ops->close != NULL)
1582 +                                       chan->ops->close(chan->fd, chan->data);
1583 +                               free_one_chan(chan);
1584 +                       }
1585 +               }
1586 +       }
1587 + out:
1588 +       if(tty) tty_flip_buffer_push(tty);
1589 +}
1590 +
1591 +/*
1592 + * Overrides for Emacs so that we follow Linus's tabbing style.
1593 + * Emacs will notice this stuff at the end of the file and automatically
1594 + * adjust the settings for this buffer only.  This must remain at the end
1595 + * of the file.
1596 + * ---------------------------------------------------------------------------
1597 + * Local variables:
1598 + * c-file-style: "linux"
1599 + * End:
1600 + */
1601 Index: linux-2.4.29/arch/um/drivers/chan_user.c
1602 ===================================================================
1603 --- linux-2.4.29.orig/arch/um/drivers/chan_user.c       1970-01-01 03:00:00.000000000 +0300
1604 +++ linux-2.4.29/arch/um/drivers/chan_user.c    2005-05-03 22:28:14.197451872 +0300
1605 @@ -0,0 +1,172 @@
1606 +/* 
1607 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
1608 + * Licensed under the GPL
1609 + */
1610 +
1611 +#include <unistd.h>
1612 +#include <stdlib.h>
1613 +#include <errno.h>
1614 +#include <termios.h>
1615 +#include <string.h>
1616 +#include <signal.h>
1617 +#include <sys/stat.h>
1618 +#include <sys/ioctl.h>
1619 +#include <sys/socket.h>
1620 +#include "kern_util.h"
1621 +#include "user_util.h"
1622 +#include "chan_user.h"
1623 +#include "user.h"
1624 +#include "helper.h"
1625 +#include "os.h"
1626 +#include "choose-mode.h"
1627 +#include "mode.h"
1628 +
1629 +static void winch_handler(int sig)
1630 +{
1631 +}
1632 +
1633 +struct winch_data {
1634 +       int pty_fd;
1635 +       int pipe_fd;
1636 +       int close_me;
1637 +};
1638 +
1639 +/* XXX This breaks horribly (by hanging UML) when moved to chan_kern.c - 
1640 + * needs investigation
1641 + */
1642 +int generic_console_write(int fd, const char *buf, int n, void *unused)
1643 +{
1644 +       struct termios save, new;
1645 +       int err;
1646 +
1647 +       if(isatty(fd)){
1648 +               tcgetattr(fd, &save);
1649 +               new = save;
1650 +               new.c_oflag |= OPOST;
1651 +               tcsetattr(fd, TCSAFLUSH, &new);
1652 +       }
1653 +       err = generic_write(fd, buf, n, NULL);
1654 +       if(isatty(fd)) tcsetattr(fd, TCSAFLUSH, &save);
1655 +       return(err);
1656 +}
1657 +
1658 +static int winch_thread(void *arg)
1659 +{
1660 +       struct winch_data *data = arg;
1661 +       sigset_t sigs;
1662 +       int pty_fd, pipe_fd;
1663 +       int count, err;
1664 +       char c = 1;
1665 +
1666 +       os_close_file(data->close_me);
1667 +       pty_fd = data->pty_fd;
1668 +       pipe_fd = data->pipe_fd;
1669 +       count = os_write_file(pipe_fd, &c, sizeof(c));
1670 +       if(count != sizeof(c))
1671 +               printk("winch_thread : failed to write synchronization "
1672 +                      "byte, err = %d\n", -count);
1673 +
1674 +       signal(SIGWINCH, winch_handler);
1675 +       sigfillset(&sigs);
1676 +       sigdelset(&sigs, SIGWINCH);
1677 +       if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
1678 +               printk("winch_thread : sigprocmask failed, errno = %d\n", 
1679 +                      errno);
1680 +               exit(1);
1681 +       }
1682 +
1683 +       if(setsid() < 0){
1684 +               printk("winch_thread : setsid failed, errno = %d\n", errno);
1685 +               exit(1);
1686 +       }
1687 +
1688 +       err = os_new_tty_pgrp(pty_fd, os_getpid());
1689 +       if(err < 0){
1690 +               printk("winch_thread : new_tty_pgrp failed, err = %d\n", -err);
1691 +               exit(1);
1692 +       }
1693 +
1694 +       count = os_read_file(pipe_fd, &c, sizeof(c));
1695 +       if(count != sizeof(c))
1696 +               printk("winch_thread : failed to read synchronization byte, "
1697 +                      "err = %d\n", -count);
1698 +
1699 +       while(1){
1700 +               pause();
1701 +
1702 +               count = os_write_file(pipe_fd, &c, sizeof(c));
1703 +               if(count != sizeof(c))
1704 +                       printk("winch_thread : write failed, err = %d\n",
1705 +                              -count);
1706 +       }
1707 +}
1708 +
1709 +static int winch_tramp(int fd, void *device_data, int *fd_out)
1710 +{
1711 +       struct winch_data data;
1712 +       unsigned long stack;
1713 +       int fds[2], pid, n, err;
1714 +       char c;
1715 +
1716 +       err = os_pipe(fds, 1, 1);
1717 +       if(err < 0){
1718 +               printk("winch_tramp : os_pipe failed, err = %d\n", -err);
1719 +               return(err);
1720 +       }
1721 +
1722 +       data = ((struct winch_data) { .pty_fd           = fd,
1723 +                                     .pipe_fd          = fds[1],
1724 +                                     .close_me         = fds[0] } );
1725 +       pid = run_helper_thread(winch_thread, &data, 0, &stack, 0);
1726 +       if(pid < 0){
1727 +               printk("fork of winch_thread failed - errno = %d\n", errno);
1728 +               return(pid);
1729 +       }
1730 +
1731 +       os_close_file(fds[1]);
1732 +       *fd_out = fds[0];
1733 +       n = os_read_file(fds[0], &c, sizeof(c));
1734 +       if(n != sizeof(c)){
1735 +               printk("winch_tramp : failed to read synchronization byte\n");
1736 +               printk("read failed, err = %d\n", -n);
1737 +               printk("fd %d will not support SIGWINCH\n", fd);
1738 +               *fd_out = -1;
1739 +       }
1740 +       return(pid);
1741 +}
1742 +
1743 +void register_winch(int fd, void *device_data)
1744 +{
1745 +       int pid, thread, thread_fd;
1746 +       int count;
1747 +       char c = 1;
1748 +
1749 +       if(!isatty(fd)) 
1750 +               return;
1751 +
1752 +       pid = tcgetpgrp(fd);
1753 +       if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, 
1754 +                            device_data) && (pid == -1)){
1755 +               thread = winch_tramp(fd, device_data, &thread_fd);
1756 +               if(fd != -1){
1757 +                       register_winch_irq(thread_fd, fd, thread, device_data);
1758 +
1759 +                       count = os_write_file(thread_fd, &c, sizeof(c));
1760 +                       if(count != sizeof(c))
1761 +                               printk("register_winch : failed to write "
1762 +                                      "synchronization byte, err = %d\n",
1763 +                                       -count);
1764 +               }
1765 +       }
1766 +}
1767 +
1768 +/*
1769 + * Overrides for Emacs so that we follow Linus's tabbing style.
1770 + * Emacs will notice this stuff at the end of the file and automatically
1771 + * adjust the settings for this buffer only.  This must remain at the end
1772 + * of the file.
1773 + * ---------------------------------------------------------------------------
1774 + * Local variables:
1775 + * c-file-style: "linux"
1776 + * End:
1777 + */
1778 Index: linux-2.4.29/arch/um/drivers/cow.h
1779 ===================================================================
1780 --- linux-2.4.29.orig/arch/um/drivers/cow.h     1970-01-01 03:00:00.000000000 +0300
1781 +++ linux-2.4.29/arch/um/drivers/cow.h  2005-05-03 22:43:32.718815400 +0300
1782 @@ -0,0 +1,41 @@
1783 +#ifndef __COW_H__
1784 +#define __COW_H__
1785 +
1786 +#include <asm/types.h>
1787 +
1788 +#if __BYTE_ORDER == __BIG_ENDIAN
1789 +# define ntohll(x) (x)
1790 +# define htonll(x) (x)
1791 +#elif __BYTE_ORDER == __LITTLE_ENDIAN
1792 +# define ntohll(x)  bswap_64(x)
1793 +# define htonll(x)  bswap_64(x)
1794 +#else
1795 +#error "__BYTE_ORDER not defined"
1796 +#endif
1797 +
1798 +extern int init_cow_file(int fd, char *cow_file, char *backing_file, 
1799 +                        int sectorsize, int alignment, int *bitmap_offset_out, 
1800 +                        unsigned long *bitmap_len_out, int *data_offset_out);
1801 +
1802 +extern int file_reader(__u64 offset, char *buf, int len, void *arg);
1803 +extern int read_cow_header(int (*reader)(__u64, char *, int, void *), 
1804 +                          void *arg, __u32 *version_out, 
1805 +                          char **backing_file_out, time_t *mtime_out, 
1806 +                          __u64 *size_out, int *sectorsize_out, 
1807 +                          __u32 *align_out, int *bitmap_offset_out);
1808 +
1809 +extern int write_cow_header(char *cow_file, int fd, char *backing_file, 
1810 +                           int sectorsize, int alignment, long long *size);
1811 +
1812 +extern void cow_sizes(int version, __u64 size, int sectorsize, int align,
1813 +                     int bitmap_offset, unsigned long *bitmap_len_out, 
1814 +                     int *data_offset_out);
1815 +
1816 +#endif
1817 +
1818 +/*
1819 + * ---------------------------------------------------------------------------
1820 + * Local variables:
1821 + * c-file-style: "linux"
1822 + * End:
1823 + */
1824 Index: linux-2.4.29/arch/um/drivers/cow_kern.c
1825 ===================================================================
1826 --- linux-2.4.29.orig/arch/um/drivers/cow_kern.c        1970-01-01 03:00:00.000000000 +0300
1827 +++ linux-2.4.29/arch/um/drivers/cow_kern.c     2005-05-03 22:28:14.000000000 +0300
1828 @@ -0,0 +1,630 @@
1829 +#define COW_MAJOR 60
1830 +#define MAJOR_NR COW_MAJOR
1831 +
1832 +#include <linux/stddef.h>
1833 +#include <linux/kernel.h>
1834 +#include <linux/ctype.h>
1835 +#include <linux/stat.h>
1836 +#include <linux/vmalloc.h>
1837 +#include <linux/blkdev.h>
1838 +#include <linux/blk.h>
1839 +#include <linux/fs.h>
1840 +#include <linux/genhd.h>
1841 +#include <linux/devfs_fs.h>
1842 +#include <asm/uaccess.h>
1843 +#include "2_5compat.h"
1844 +#include "cow.h"
1845 +#include "ubd_user.h"
1846 +
1847 +#define COW_SHIFT 4
1848 +
1849 +struct cow {
1850 +       int count;
1851 +       char *cow_path;
1852 +       dev_t cow_dev;
1853 +       struct block_device *cow_bdev;
1854 +       char *backing_path;
1855 +       dev_t backing_dev;
1856 +       struct block_device *backing_bdev;
1857 +       int sectorsize;
1858 +       unsigned long *bitmap;
1859 +       unsigned long bitmap_len;
1860 +       int bitmap_offset;
1861 +       int data_offset;
1862 +       devfs_handle_t devfs;
1863 +       struct semaphore sem;
1864 +       struct semaphore io_sem;
1865 +       atomic_t working;
1866 +       spinlock_t io_lock;
1867 +       struct buffer_head *bh;
1868 +       struct buffer_head *bhtail;
1869 +       void *end_io;
1870 +};
1871 +
1872 +#define DEFAULT_COW { \
1873 +       .count                  = 0, \
1874 +       .cow_path               = NULL, \
1875 +       .cow_dev                = 0, \
1876 +       .backing_path           = NULL, \
1877 +       .backing_dev            = 0, \
1878 +        .bitmap                        = NULL, \
1879 +       .bitmap_len             = 0, \
1880 +       .bitmap_offset          = 0, \
1881 +        .data_offset           = 0, \
1882 +       .devfs                  = NULL, \
1883 +       .working                = ATOMIC_INIT(0), \
1884 +       .io_lock                = SPIN_LOCK_UNLOCKED, \
1885 +}
1886 +
1887 +#define MAX_DEV (8)
1888 +#define MAX_MINOR (MAX_DEV << COW_SHIFT)
1889 +
1890 +struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
1891 +
1892 +/* Not modified by this driver */
1893 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
1894 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
1895 +
1896 +/* Protected by cow_lock */
1897 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
1898 +
1899 +static struct hd_struct        cow_part[MAX_MINOR] =
1900 +       { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
1901 +
1902 +/* Protected by io_request_lock */
1903 +static request_queue_t *cow_queue;
1904 +
1905 +static int cow_open(struct inode *inode, struct file *filp);
1906 +static int cow_release(struct inode * inode, struct file * file);
1907 +static int cow_ioctl(struct inode * inode, struct file * file,
1908 +                    unsigned int cmd, unsigned long arg);
1909 +static int cow_revalidate(kdev_t rdev);
1910 +
1911 +static struct block_device_operations cow_blops = {
1912 +       .open           = cow_open,
1913 +       .release        = cow_release,
1914 +       .ioctl          = cow_ioctl,
1915 +       .revalidate     = cow_revalidate,
1916 +};
1917 +
1918 +/* Initialized in an initcall, and unchanged thereafter */
1919 +devfs_handle_t cow_dir_handle;
1920 +
1921 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
1922 +{ \
1923 +       .major          = maj, \
1924 +       .major_name     = name, \
1925 +       .minor_shift    = shift, \
1926 +       .max_p          = 1 << shift, \
1927 +       .part           = parts, \
1928 +       .sizes          = bsizes, \
1929 +       .nr_real        = max, \
1930 +       .real_devices   = NULL, \
1931 +       .next           = NULL, \
1932 +       .fops           = blops, \
1933 +       .de_arr         = NULL, \
1934 +       .flags          = 0 \
1935 +}
1936 +
1937 +static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
1938 +
1939 +static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
1940 +                                                COW_SHIFT, sizes, MAX_DEV, 
1941 +                                                &cow_blops);
1942 +
1943 +static int cow_add(int n)
1944 +{
1945 +       struct cow *dev = &cow_dev[n];
1946 +       char name[sizeof("nnnnnn\0")];
1947 +       int err = -ENODEV;
1948 +
1949 +       if(dev->cow_path == NULL)
1950 +               goto out;
1951 +
1952 +       sprintf(name, "%d", n);
1953 +       dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE,
1954 +                                   MAJOR_NR, n << COW_SHIFT, S_IFBLK | 
1955 +                                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
1956 +                                   &cow_blops, NULL);
1957 +
1958 +       init_MUTEX_LOCKED(&dev->sem);
1959 +       init_MUTEX(&dev->io_sem);
1960 +
1961 +       return(0);
1962 +
1963 + out:
1964 +       return(err);
1965 +}
1966 +
1967 +/*
1968 + * Add buffer_head to back of pending list
1969 + */
1970 +static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
1971 +{
1972 +       unsigned long flags;
1973 +
1974 +       spin_lock_irqsave(&cow->io_lock, flags);
1975 +       if(cow->bhtail != NULL){
1976 +               cow->bhtail->b_reqnext = bh;
1977 +               cow->bhtail = bh;
1978 +       }
1979 +       else {
1980 +               cow->bh = bh;
1981 +               cow->bhtail = bh;
1982 +       }
1983 +       spin_unlock_irqrestore(&cow->io_lock, flags);
1984 +}
1985 +
1986 +/*
1987 + * Grab first pending buffer
1988 + */
1989 +static struct buffer_head *cow_get_bh(struct cow *cow)
1990 +{
1991 +       struct buffer_head *bh;
1992 +
1993 +       spin_lock_irq(&cow->io_lock);
1994 +       bh = cow->bh;
1995 +       if(bh != NULL){
1996 +               if(bh == cow->bhtail)
1997 +                       cow->bhtail = NULL;
1998 +               cow->bh = bh->b_reqnext;
1999 +               bh->b_reqnext = NULL;
2000 +       }
2001 +       spin_unlock_irq(&cow->io_lock);
2002 +
2003 +       return(bh);
2004 +}
2005 +
2006 +static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, 
2007 +                         struct buffer_head **cow_bh, int ncow_bh)
2008 +{
2009 +       int i;
2010 +
2011 +       if(ncow_bh > 0)
2012 +               ll_rw_block(WRITE, ncow_bh, cow_bh);
2013 +
2014 +       for(i = 0; i < ncow_bh ; i++){
2015 +               wait_on_buffer(cow_bh[i]);
2016 +               brelse(cow_bh[i]);
2017 +       }
2018 +
2019 +       ll_rw_block(WRITE, 1, &bh);
2020 +       brelse(bh);
2021 +}
2022 +
2023 +static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
2024 +{
2025 +       struct buffer_head *bh;
2026 +
2027 +       sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize;
2028 +       bh = getblk(dev->cow_dev, sector, dev->sectorsize);
2029 +       memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])),
2030 +              dev->sectorsize);
2031 +       return(bh);
2032 +}
2033 +
2034 +/* Copied from loop.c, needed to avoid deadlocking in make_request. */
2035 +
2036 +static int cow_thread(void *data)
2037 +{
2038 +       struct cow *dev = data;
2039 +       struct buffer_head *bh;
2040 +
2041 +       daemonize();
2042 +       exit_files(current);
2043 +
2044 +       sprintf(current->comm, "cow%d", dev - cow_dev);
2045 +
2046 +       spin_lock_irq(&current->sigmask_lock);
2047 +       sigfillset(&current->blocked);
2048 +       flush_signals(current);
2049 +       spin_unlock_irq(&current->sigmask_lock);
2050 +
2051 +       atomic_inc(&dev->working);
2052 +
2053 +       current->policy = SCHED_OTHER;
2054 +       current->nice = -20;
2055 +
2056 +       current->flags |= PF_NOIO;
2057 +
2058 +       /*
2059 +        * up sem, we are running
2060 +        */
2061 +       up(&dev->sem);
2062 +
2063 +       for(;;){
2064 +               int start, len, nbh, i, update_bitmap = 0;
2065 +               struct buffer_head *cow_bh[2];
2066 +
2067 +               down_interruptible(&dev->io_sem);
2068 +               /*
2069 +                * could be upped because of tear-down, not because of
2070 +                * pending work
2071 +                */
2072 +               if(!atomic_read(&dev->working))
2073 +                       break;
2074 +
2075 +               bh = cow_get_bh(dev);
2076 +               if(bh == NULL){
2077 +                       printk(KERN_ERR "cow: missing bh\n");
2078 +                       continue;
2079 +               }
2080 +
2081 +               start = bh->b_blocknr * bh->b_size / dev->sectorsize;
2082 +               len = bh->b_size / dev->sectorsize;
2083 +               for(i = 0; i < len ; i++){
2084 +                       if(ubd_test_bit(start + i, 
2085 +                                       (unsigned char *) dev->bitmap))
2086 +                               continue;
2087 +
2088 +                       update_bitmap = 1;
2089 +                       ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
2090 +               }
2091 +
2092 +               cow_bh[0] = NULL;
2093 +               cow_bh[1] = NULL;
2094 +               nbh = 0;
2095 +               if(update_bitmap){
2096 +                       cow_bh[0] = cow_new_bh(dev, start);
2097 +                       nbh++;
2098 +                       if(start / dev->sectorsize != 
2099 +                          (start + len) / dev->sectorsize){
2100 +                               cow_bh[1] = cow_new_bh(dev, start + len);
2101 +                               nbh++;
2102 +                       }
2103 +               }
2104 +               
2105 +               bh->b_dev = dev->cow_dev;
2106 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
2107 +
2108 +               cow_handle_bh(dev, bh, cow_bh, nbh);
2109 +
2110 +               /*
2111 +                * upped both for pending work and tear-down, lo_pending
2112 +                * will hit zero then
2113 +                */
2114 +               if(atomic_dec_and_test(&dev->working))
2115 +                       break;
2116 +       }
2117 +
2118 +       up(&dev->sem);
2119 +       return(0);
2120 +}
2121 +
2122 +static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
2123 +{
2124 +       struct cow *dev;
2125 +       int n, minor;
2126 +
2127 +       minor = MINOR(bh->b_rdev);
2128 +       n = minor >> COW_SHIFT;
2129 +       dev = &cow_dev[n];
2130 +
2131 +       dev->end_io = NULL;
2132 +       if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){
2133 +               bh->b_rdev = dev->cow_dev;
2134 +               bh->b_rsector += dev->data_offset / dev->sectorsize;
2135 +       }
2136 +       else if(rw == WRITE){
2137 +               bh->b_dev = dev->cow_dev;
2138 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
2139 +
2140 +               cow_add_bh(dev, bh);
2141 +               up(&dev->io_sem);
2142 +               return(0);
2143 +       }
2144 +       else {
2145 +               bh->b_rdev = dev->backing_dev;
2146 +       }
2147 +
2148 +       return(1);
2149 +}
2150 +
2151 +int cow_init(void)
2152 +{
2153 +       int i;
2154 +
2155 +       cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL);
2156 +       if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) {
2157 +               printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR);
2158 +               return -1;
2159 +       }
2160 +       read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
2161 +       blksize_size[MAJOR_NR] = blk_sizes;
2162 +       blk_size[MAJOR_NR] = sizes;
2163 +       INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
2164 +
2165 +       cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
2166 +       blk_init_queue(cow_queue, NULL);
2167 +       INIT_ELV(cow_queue, &cow_queue->elevator);
2168 +       blk_queue_make_request(cow_queue, cow_make_request);
2169 +
2170 +        add_gendisk(&cow_gendisk);
2171 +
2172 +       for(i=0;i<MAX_DEV;i++) 
2173 +               cow_add(i);
2174 +
2175 +       return(0);
2176 +}
2177 +
2178 +__initcall(cow_init);
2179 +
2180 +static int reader(__u64 start, char *buf, int count, void *arg)
2181 +{
2182 +       dev_t dev = *((dev_t *) arg);
2183 +       struct buffer_head *bh;
2184 +       __u64 block;
2185 +       int cur, offset, left, n, blocksize = get_hardsect_size(dev);
2186 +
2187 +       if(blocksize == 0)
2188 +               panic("Zero blocksize");
2189 +
2190 +       block = start / blocksize;
2191 +       offset = start % blocksize;
2192 +       left = count;
2193 +       cur = 0;
2194 +       while(left > 0){
2195 +               n = (left > blocksize) ? blocksize : left;
2196 +
2197 +               bh = bread(dev, block, (n < 512) ? 512 : n);
2198 +               if(bh == NULL)
2199 +                       return(-EIO);
2200 +
2201 +               n -= offset;
2202 +               memcpy(&buf[cur], bh->b_data + offset, n);
2203 +               block++;
2204 +               left -= n;
2205 +               cur += n;
2206 +               offset = 0;
2207 +               brelse(bh);
2208 +       }
2209 +
2210 +       return(count);
2211 +}
2212 +
2213 +static int cow_open(struct inode *inode, struct file *filp)
2214 +{
2215 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
2216 +                        unsigned long);
2217 +       mm_segment_t fs;
2218 +       struct cow *dev;
2219 +       __u64 size;
2220 +       __u32 version, align;
2221 +       time_t mtime;
2222 +       char *backing_file;
2223 +       int n, offset, err = 0;
2224 +
2225 +       n = DEVICE_NR(inode->i_rdev);
2226 +       if(n >= MAX_DEV)
2227 +               return(-ENODEV);
2228 +       dev = &cow_dev[n];
2229 +       offset = n << COW_SHIFT;
2230 +
2231 +       spin_lock(&cow_lock);
2232 +
2233 +       if(dev->count == 0){
2234 +               dev->cow_dev = name_to_kdev_t(dev->cow_path);
2235 +               if(dev->cow_dev == 0){
2236 +                       printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
2237 +                              "failed\n", dev->cow_path);
2238 +                       err = -ENODEV;
2239 +               }
2240 +
2241 +               dev->backing_dev = name_to_kdev_t(dev->backing_path);
2242 +               if(dev->backing_dev == 0){
2243 +                       printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
2244 +                              "failed\n", dev->backing_path);
2245 +                       err = -ENODEV;
2246 +               }
2247 +
2248 +               if(err) 
2249 +                       goto out;
2250 +
2251 +               dev->cow_bdev = bdget(dev->cow_dev);
2252 +               if(dev->cow_bdev == NULL){
2253 +                       printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
2254 +                              dev->cow_path);
2255 +                       err = -ENOMEM;
2256 +               }
2257 +               dev->backing_bdev = bdget(dev->backing_dev);
2258 +               if(dev->backing_bdev == NULL){
2259 +                       printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
2260 +                              dev->backing_path);
2261 +                       err = -ENOMEM;
2262 +               }
2263 +
2264 +               if(err) 
2265 +                       goto out;
2266 +
2267 +               err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, 
2268 +                                BDEV_RAW);
2269 +               if(err){
2270 +                       printk("cow_open - blkdev_get of COW device failed, "
2271 +                              "error = %d\n", err);
2272 +                       goto out;
2273 +               }
2274 +               
2275 +               err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
2276 +               if(err){
2277 +                       printk("cow_open - blkdev_get of backing device "
2278 +                              "failed, error = %d\n", err);
2279 +                       goto out;
2280 +               }
2281 +               
2282 +               err = read_cow_header(reader, &dev->cow_dev, &version, 
2283 +                                     &backing_file, &mtime, &size,
2284 +                                     &dev->sectorsize, &align, 
2285 +                                     &dev->bitmap_offset);
2286 +               if(err){
2287 +                       printk(KERN_ERR "cow_open - read_cow_header failed, "
2288 +                              "err = %d\n", err);
2289 +                       goto out;
2290 +               }
2291 +
2292 +               cow_sizes(version, size, dev->sectorsize, align, 
2293 +                         dev->bitmap_offset, &dev->bitmap_len, 
2294 +                         &dev->data_offset);
2295 +               dev->bitmap = (void *) vmalloc(dev->bitmap_len);
2296 +               if(dev->bitmap == NULL){
2297 +                       err = -ENOMEM;
2298 +                       printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
2299 +                       goto out;
2300 +               }
2301 +               flush_tlb_kernel_vm();
2302 +               
2303 +               err = reader(dev->bitmap_offset, (char *) dev->bitmap, 
2304 +                            dev->bitmap_len, &dev->cow_dev);
2305 +               if(err < 0){
2306 +                       printk(KERN_ERR "Failed to read COW bitmap\n");
2307 +                       vfree(dev->bitmap);
2308 +                       goto out;
2309 +               }
2310 +
2311 +               dev_ioctl = dev->backing_bdev->bd_op->ioctl;
2312 +               fs = get_fs();
2313 +               set_fs(KERNEL_DS);
2314 +               err = (*dev_ioctl)(inode, filp, BLKGETSIZE, 
2315 +                                  (unsigned long) &sizes[offset]);
2316 +               set_fs(fs);
2317 +               if(err){
2318 +                       printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
2319 +                              "error = %d\n", err);
2320 +                       goto out;
2321 +               }
2322 +
2323 +               kernel_thread(cow_thread, dev, 
2324 +                             CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
2325 +               down(&dev->sem);
2326 +       }
2327 +       dev->count++;
2328 + out:
2329 +       spin_unlock(&cow_lock);
2330 +       return(err);
2331 +}
2332 +
2333 +static int cow_release(struct inode * inode, struct file * file)
2334 +{
2335 +       struct cow *dev;
2336 +       int n, err;
2337 +
2338 +       n = DEVICE_NR(inode->i_rdev);
2339 +       if(n >= MAX_DEV)
2340 +               return(-ENODEV);
2341 +       dev = &cow_dev[n];
2342 +
2343 +       spin_lock(&cow_lock);
2344 +
2345 +       if(--dev->count > 0)
2346 +               goto out;
2347 +
2348 +       err = blkdev_put(dev->cow_bdev, BDEV_RAW);
2349 +       if(err)
2350 +               printk("cow_release - blkdev_put of cow device failed, "
2351 +                      "error = %d\n", err);
2352 +       bdput(dev->cow_bdev);
2353 +       dev->cow_bdev = 0;
2354 +
2355 +       err = blkdev_put(dev->backing_bdev, BDEV_RAW);
2356 +       if(err)
2357 +               printk("cow_release - blkdev_put of backing device failed, "
2358 +                      "error = %d\n", err);
2359 +       bdput(dev->backing_bdev);
2360 +       dev->backing_bdev = 0;
2361 +
2362 + out:
2363 +       spin_unlock(&cow_lock);
2364 +       return(0);
2365 +}
2366 +
2367 +static int cow_ioctl(struct inode * inode, struct file * file,
2368 +                    unsigned int cmd, unsigned long arg)
2369 +{
2370 +       struct cow *dev;
2371 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
2372 +                        unsigned long);
2373 +       int n;
2374 +
2375 +       n = DEVICE_NR(inode->i_rdev);
2376 +       if(n >= MAX_DEV)
2377 +               return(-ENODEV);
2378 +       dev = &cow_dev[n];
2379 +
2380 +       dev_ioctl = dev->backing_bdev->bd_op->ioctl;
2381 +       return((*dev_ioctl)(inode, file, cmd, arg));
2382 +}
2383 +
2384 +static int cow_revalidate(kdev_t rdev)
2385 +{
2386 +       printk(KERN_ERR "Need to implement cow_revalidate\n");
2387 +       return(0);
2388 +}
2389 +
2390 +static int parse_unit(char **ptr)
2391 +{
2392 +       char *str = *ptr, *end;
2393 +       int n = -1;
2394 +
2395 +       if(isdigit(*str)) {
2396 +               n = simple_strtoul(str, &end, 0);
2397 +               if(end == str)
2398 +                       return(-1);
2399 +               *ptr = end;
2400 +       }
2401 +       else if (('a' <= *str) && (*str <= 'h')) {
2402 +               n = *str - 'a';
2403 +               str++;
2404 +               *ptr = str;
2405 +       }
2406 +       return(n);
2407 +}
2408 +
2409 +static int cow_setup(char *str)
2410 +{
2411 +       struct cow *dev;
2412 +       char *cow_name, *backing_name;
2413 +       int unit;
2414 +
2415 +       unit = parse_unit(&str);
2416 +       if(unit < 0){
2417 +               printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
2418 +               return(1);
2419 +       }
2420 +
2421 +       if(*str != '='){
2422 +               printk(KERN_ERR "cow_setup - Missing '=' after unit "
2423 +                      "number\n");
2424 +               return(1);
2425 +       }
2426 +       str++;
2427 +
2428 +       cow_name = str;
2429 +       backing_name = strchr(str, ',');
2430 +       if(backing_name == NULL){
2431 +               printk(KERN_ERR "cow_setup - missing backing device name\n");
2432 +               return(0);
2433 +       }
2434 +       *backing_name = '\0';
2435 +       backing_name++;
2436 +
2437 +       spin_lock(&cow_lock);
2438 +
2439 +       dev = &cow_dev[unit];
2440 +       dev->cow_path = cow_name;
2441 +       dev->backing_path = backing_name;
2442 +       
2443 +       spin_unlock(&cow_lock);
2444 +       return(0);
2445 +}
2446 +
2447 +__setup("cow", cow_setup);
2448 +
2449 +/*
2450 + * Overrides for Emacs so that we follow Linus's tabbing style.
2451 + * Emacs will notice this stuff at the end of the file and automatically
2452 + * adjust the settings for this buffer only.  This must remain at the end
2453 + * of the file.
2454 + * ---------------------------------------------------------------------------
2455 + * Local variables:
2456 + * c-file-style: "linux"
2457 + * End:
2458 + */
2459 Index: linux-2.4.29/arch/um/drivers/cow_sys.h
2460 ===================================================================
2461 --- linux-2.4.29.orig/arch/um/drivers/cow_sys.h 1970-01-01 03:00:00.000000000 +0300
2462 +++ linux-2.4.29/arch/um/drivers/cow_sys.h      2005-05-03 22:43:34.768503800 +0300
2463 @@ -0,0 +1,48 @@
2464 +#ifndef __COW_SYS_H__
2465 +#define __COW_SYS_H__
2466 +
2467 +#include "kern_util.h"
2468 +#include "user_util.h"
2469 +#include "os.h"
2470 +#include "user.h"
2471 +
2472 +static inline void *cow_malloc(int size)
2473 +{
2474 +       return(um_kmalloc(size));
2475 +}
2476 +
2477 +static inline void cow_free(void *ptr)
2478 +{
2479 +       kfree(ptr);
2480 +}
2481 +
2482 +#define cow_printf printk
2483 +
2484 +static inline char *cow_strdup(char *str)
2485 +{
2486 +       return(uml_strdup(str));
2487 +}
2488 +
2489 +static inline int cow_seek_file(int fd, __u64 offset)
2490 +{
2491 +       return(os_seek_file(fd, offset));
2492 +}
2493 +
2494 +static inline int cow_file_size(char *file, __u64 *size_out)
2495 +{
2496 +       return(os_file_size(file, size_out));
2497 +}
2498 +
2499 +static inline int cow_write_file(int fd, char *buf, int size)
2500 +{
2501 +       return(os_write_file(fd, buf, size));
2502 +}
2503 +
2504 +#endif
2505 +
2506 +/*
2507 + * ---------------------------------------------------------------------------
2508 + * Local variables:
2509 + * c-file-style: "linux"
2510 + * End:
2511 + */
2512 Index: linux-2.4.29/arch/um/drivers/cow_user.c
2513 ===================================================================
2514 --- linux-2.4.29.orig/arch/um/drivers/cow_user.c        1970-01-01 03:00:00.000000000 +0300
2515 +++ linux-2.4.29/arch/um/drivers/cow_user.c     2005-05-03 22:28:14.203450960 +0300
2516 @@ -0,0 +1,375 @@
2517 +#include <stddef.h>
2518 +#include <string.h>
2519 +#include <errno.h>
2520 +#include <unistd.h>
2521 +#include <byteswap.h>
2522 +#include <sys/time.h>
2523 +#include <sys/param.h>
2524 +#include <sys/user.h>
2525 +#include <netinet/in.h>
2526 +
2527 +#include "os.h"
2528 +
2529 +#include "cow.h"
2530 +#include "cow_sys.h"
2531 +
2532 +#define PATH_LEN_V1 256
2533 +
2534 +struct cow_header_v1 {
2535 +       int magic;
2536 +       int version;
2537 +       char backing_file[PATH_LEN_V1];
2538 +       time_t mtime;
2539 +       __u64 size;
2540 +       int sectorsize;
2541 +};
2542 +
2543 +#define PATH_LEN_V2 MAXPATHLEN
2544 +
2545 +struct cow_header_v2 {
2546 +       __u32 magic;
2547 +       __u32 version;
2548 +       char backing_file[PATH_LEN_V2];
2549 +       time_t mtime;
2550 +       __u64 size;
2551 +       int sectorsize;
2552 +};
2553 +
2554 +/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in 
2555 + * case other systems have different values for MAXPATHLEN
2556 + */
2557 +#define PATH_LEN_V3 4096
2558 +
2559 +/* Changes from V2 - 
2560 + *     PATH_LEN_V3 as described above
2561 + *     Explicitly specify field bit lengths for systems with different
2562 + *             lengths for the usual C types.  Not sure whether char or
2563 + *             time_t should be changed, this can be changed later without
2564 + *             breaking compatibility
2565 + *     Add alignment field so that different alignments can be used for the
2566 + *             bitmap and data
2567 + *     Add cow_format field to allow for the possibility of different ways
2568 + *             of specifying the COW blocks.  For now, the only value is 0,
2569 + *             for the traditional COW bitmap.
2570 + *     Move the backing_file field to the end of the header.  This allows
2571 + *             for the possibility of expanding it into the padding required
2572 + *             by the bitmap alignment.
2573 + *     The bitmap and data portions of the file will be aligned as specified
2574 + *             by the alignment field.  This is to allow COW files to be
2575 + *             put on devices with restrictions on access alignments, such as
2576 + *             /dev/raw, with a 512 byte alignment restriction.  This also
2577 + *             allows the data to be more aligned more strictly than on
2578 + *             sector boundaries.  This is needed for ubd-mmap, which needs
2579 + *             the data to be page aligned.
2580 + *     Fixed (finally!) the rounding bug
2581 + */
2582 +
2583 +struct cow_header_v3 {
2584 +       __u32 magic;
2585 +       __u32 version;
2586 +       time_t mtime;
2587 +       __u64 size;
2588 +       __u32 sectorsize;
2589 +       __u32 alignment;
2590 +       __u32 cow_format;
2591 +       char backing_file[PATH_LEN_V3];
2592 +};
2593 +
2594 +/* COW format definitions - for now, we have only the usual COW bitmap */
2595 +#define COW_BITMAP 0
2596 +
2597 +union cow_header {
2598 +       struct cow_header_v1 v1;
2599 +       struct cow_header_v2 v2;
2600 +       struct cow_header_v3 v3;
2601 +};
2602 +
2603 +#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
2604 +#define COW_VERSION 3
2605 +
2606 +#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len))
2607 +#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align)
2608 +
2609 +void cow_sizes(int version, __u64 size, int sectorsize, int align, 
2610 +              int bitmap_offset, unsigned long *bitmap_len_out, 
2611 +              int *data_offset_out)
2612 +{
2613 +       if(version < 3){
2614 +               *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
2615 +
2616 +               *data_offset_out = bitmap_offset + *bitmap_len_out;
2617 +               *data_offset_out = (*data_offset_out + sectorsize - 1) / 
2618 +                       sectorsize;
2619 +               *data_offset_out *= sectorsize;
2620 +       }
2621 +       else {
2622 +               *bitmap_len_out = DIV_ROUND(size, sectorsize);
2623 +               *bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8);
2624 +
2625 +               *data_offset_out = bitmap_offset + *bitmap_len_out;
2626 +               *data_offset_out = ROUND_UP(*data_offset_out, align);
2627 +       }
2628 +}
2629 +
2630 +static int absolutize(char *to, int size, char *from)
2631 +{
2632 +       char save_cwd[256], *slash;
2633 +       int remaining;
2634 +
2635 +       if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
2636 +               cow_printf("absolutize : unable to get cwd - errno = %d\n", 
2637 +                          errno);
2638 +               return(-1);
2639 +       }
2640 +       slash = strrchr(from, '/');
2641 +       if(slash != NULL){
2642 +               *slash = '\0';
2643 +               if(chdir(from)){
2644 +                       *slash = '/';
2645 +                       cow_printf("absolutize : Can't cd to '%s' - " 
2646 +                                  "errno = %d\n", from, errno);
2647 +                       return(-1);
2648 +               }
2649 +               *slash = '/';
2650 +               if(getcwd(to, size) == NULL){
2651 +                       cow_printf("absolutize : unable to get cwd of '%s' - "
2652 +                              "errno = %d\n", from, errno);
2653 +                       return(-1);
2654 +               }
2655 +               remaining = size - strlen(to);
2656 +               if(strlen(slash) + 1 > remaining){
2657 +                       cow_printf("absolutize : unable to fit '%s' into %d "
2658 +                              "chars\n", from, size);
2659 +                       return(-1);
2660 +               }
2661 +               strcat(to, slash);
2662 +       }
2663 +       else {
2664 +               if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
2665 +                       cow_printf("absolutize : unable to fit '%s' into %d "
2666 +                              "chars\n", from, size);
2667 +                       return(-1);
2668 +               }
2669 +               strcpy(to, save_cwd);
2670 +               strcat(to, "/");
2671 +               strcat(to, from);
2672 +       }
2673 +       chdir(save_cwd);
2674 +       return(0);
2675 +}
2676 +
2677 +int write_cow_header(char *cow_file, int fd, char *backing_file, 
2678 +                    int sectorsize, int alignment, long long *size)
2679 +{
2680 +       struct cow_header_v3 *header;
2681 +       unsigned long modtime;
2682 +       int err;
2683 +
2684 +       err = cow_seek_file(fd, 0);
2685 +       if(err < 0){
2686 +               cow_printf("write_cow_header - lseek failed, err = %d\n", -err);
2687 +               goto out;
2688 +       }
2689 +
2690 +       err = -ENOMEM;
2691 +       header = cow_malloc(sizeof(*header));
2692 +       if(header == NULL){
2693 +               cow_printf("Failed to allocate COW V3 header\n");
2694 +               goto out;
2695 +       }
2696 +       header->magic = htonl(COW_MAGIC);
2697 +       header->version = htonl(COW_VERSION);
2698 +
2699 +       err = -EINVAL;
2700 +       if(strlen(backing_file) > sizeof(header->backing_file) - 1){
2701 +               cow_printf("Backing file name \"%s\" is too long - names are "
2702 +                          "limited to %d characters\n", backing_file, 
2703 +                          sizeof(header->backing_file) - 1);
2704 +               goto out_free;
2705 +       }
2706 +
2707 +       if(absolutize(header->backing_file, sizeof(header->backing_file), 
2708 +                     backing_file))
2709 +               goto out_free;
2710 +
2711 +       err = os_file_modtime(header->backing_file, &modtime);
2712 +       if(err < 0){
2713 +               cow_printf("Backing file '%s' mtime request failed, "
2714 +                          "err = %d\n", header->backing_file, -err);
2715 +               goto out_free;
2716 +       }
2717 +
2718 +       err = cow_file_size(header->backing_file, size);
2719 +       if(err < 0){
2720 +               cow_printf("Couldn't get size of backing file '%s', "
2721 +                          "err = %d\n", header->backing_file, -err);
2722 +               goto out_free;
2723 +       }
2724 +
2725 +       header->mtime = htonl(modtime);
2726 +       header->size = htonll(*size);
2727 +       header->sectorsize = htonl(sectorsize);
2728 +       header->alignment = htonl(alignment);
2729 +       header->cow_format = COW_BITMAP;
2730 +
2731 +       err = os_write_file(fd, header, sizeof(*header));
2732 +       if(err != sizeof(*header)){
2733 +               cow_printf("Write of header to new COW file '%s' failed, "
2734 +                          "err = %d\n", cow_file, -err);
2735 +               goto out_free;
2736 +       }
2737 +       err = 0;
2738 + out_free:
2739 +       cow_free(header);
2740 + out:
2741 +       return(err);
2742 +}
2743 +
2744 +int file_reader(__u64 offset, char *buf, int len, void *arg)
2745 +{
2746 +       int fd = *((int *) arg);
2747 +
2748 +       return(pread(fd, buf, len, offset));
2749 +}
2750 +
2751 +/* XXX Need to sanity-check the values read from the header */
2752 +
2753 +int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, 
2754 +                   __u32 *version_out, char **backing_file_out, 
2755 +                   time_t *mtime_out, __u64 *size_out, 
2756 +                   int *sectorsize_out, __u32 *align_out, 
2757 +                   int *bitmap_offset_out)
2758 +{
2759 +       union cow_header *header;
2760 +       char *file;
2761 +       int err, n;
2762 +       unsigned long version, magic;
2763 +
2764 +       header = cow_malloc(sizeof(*header));
2765 +       if(header == NULL){
2766 +               cow_printf("read_cow_header - Failed to allocate header\n");
2767 +               return(-ENOMEM);
2768 +       }
2769 +       err = -EINVAL;
2770 +       n = (*reader)(0, (char *) header, sizeof(*header), arg);
2771 +       if(n < offsetof(typeof(header->v1), backing_file)){
2772 +               cow_printf("read_cow_header - short header\n");
2773 +               goto out;
2774 +       }
2775 +
2776 +       magic = header->v1.magic;
2777 +       if(magic == COW_MAGIC) {
2778 +               version = header->v1.version;
2779 +       }
2780 +       else if(magic == ntohl(COW_MAGIC)){
2781 +               version = ntohl(header->v1.version);
2782 +       }
2783 +       /* No error printed because the non-COW case comes through here */
2784 +       else goto out;
2785 +
2786 +       *version_out = version;
2787 +
2788 +       if(version == 1){
2789 +               if(n < sizeof(header->v1)){
2790 +                       cow_printf("read_cow_header - failed to read V1 "
2791 +                                  "header\n");
2792 +                       goto out;
2793 +               }
2794 +               *mtime_out = header->v1.mtime;
2795 +               *size_out = header->v1.size;
2796 +               *sectorsize_out = header->v1.sectorsize;
2797 +               *bitmap_offset_out = sizeof(header->v1);
2798 +               *align_out = *sectorsize_out;
2799 +               file = header->v1.backing_file;
2800 +       }
2801 +       else if(version == 2){
2802 +               if(n < sizeof(header->v2)){
2803 +                       cow_printf("read_cow_header - failed to read V2 "
2804 +                                  "header\n");
2805 +                       goto out;
2806 +               }
2807 +               *mtime_out = ntohl(header->v2.mtime);
2808 +               *size_out = ntohll(header->v2.size);
2809 +               *sectorsize_out = ntohl(header->v2.sectorsize);
2810 +               *bitmap_offset_out = sizeof(header->v2);
2811 +               *align_out = *sectorsize_out;
2812 +               file = header->v2.backing_file;
2813 +       }
2814 +       else if(version == 3){
2815 +               if(n < sizeof(header->v3)){
2816 +                       cow_printf("read_cow_header - failed to read V2 "
2817 +                                  "header\n");
2818 +                       goto out;
2819 +               }
2820 +               *mtime_out = ntohl(header->v3.mtime);
2821 +               *size_out = ntohll(header->v3.size);
2822 +               *sectorsize_out = ntohl(header->v3.sectorsize);
2823 +               *align_out = ntohl(header->v3.alignment);
2824 +               *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out);
2825 +               file = header->v3.backing_file;
2826 +       }
2827 +       else {
2828 +               cow_printf("read_cow_header - invalid COW version\n");
2829 +               goto out;               
2830 +       }
2831 +       err = -ENOMEM;
2832 +       *backing_file_out = cow_strdup(file);
2833 +       if(*backing_file_out == NULL){
2834 +               cow_printf("read_cow_header - failed to allocate backing "
2835 +                          "file\n");
2836 +               goto out;
2837 +       }
2838 +       err = 0;
2839 + out:
2840 +       cow_free(header);
2841 +       return(err);
2842 +}
2843 +
2844 +int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
2845 +                 int alignment, int *bitmap_offset_out, 
2846 +                 unsigned long *bitmap_len_out, int *data_offset_out)
2847 +{
2848 +       __u64 size, offset;
2849 +       char zero = 0;
2850 +       int err;
2851 +
2852 +       err = write_cow_header(cow_file, fd, backing_file, sectorsize, 
2853 +                              alignment, &size);
2854 +       if(err) 
2855 +               goto out;
2856 +       
2857 +       *bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment);
2858 +       cow_sizes(COW_VERSION, size, sectorsize, alignment, *bitmap_offset_out,
2859 +                 bitmap_len_out, data_offset_out);
2860 +
2861 +       offset = *data_offset_out + size - sizeof(zero);
2862 +       err = cow_seek_file(fd, offset);
2863 +       if(err < 0){
2864 +               cow_printf("cow bitmap lseek failed : err = %d\n", -err);
2865 +               goto out;
2866 +       }
2867 +
2868 +       /* does not really matter how much we write it is just to set EOF 
2869 +        * this also sets the entire COW bitmap
2870 +        * to zero without having to allocate it 
2871 +        */
2872 +       err = cow_write_file(fd, &zero, sizeof(zero));
2873 +       if(err != sizeof(zero)){
2874 +               cow_printf("Write of bitmap to new COW file '%s' failed, "
2875 +                          "err = %d\n", cow_file, -err);
2876 +               err = -EINVAL;
2877 +               goto out;
2878 +       }
2879 +
2880 +       return(0);
2881 +
2882 + out:
2883 +       return(err);
2884 +}
2885 +
2886 +/*
2887 + * ---------------------------------------------------------------------------
2888 + * Local variables:
2889 + * c-file-style: "linux"
2890 + * End:
2891 + */
2892 Index: linux-2.4.29/arch/um/drivers/daemon.h
2893 ===================================================================
2894 --- linux-2.4.29.orig/arch/um/drivers/daemon.h  1970-01-01 03:00:00.000000000 +0300
2895 +++ linux-2.4.29/arch/um/drivers/daemon.h       2005-05-03 22:28:14.000000000 +0300
2896 @@ -0,0 +1,35 @@
2897 +/* 
2898 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
2899 + * Licensed under the GPL
2900 + */
2901 +
2902 +#include "net_user.h"
2903 +
2904 +#define SWITCH_VERSION 3
2905 +
2906 +struct daemon_data {
2907 +       char *sock_type;
2908 +       char *ctl_sock;
2909 +       void *ctl_addr;
2910 +       void *data_addr;
2911 +       void *local_addr;
2912 +       int fd;
2913 +       int control;
2914 +       void *dev;
2915 +};
2916 +
2917 +extern struct net_user_info daemon_user_info;
2918 +
2919 +extern int daemon_user_write(int fd, void *buf, int len, 
2920 +                            struct daemon_data *pri);
2921 +
2922 +/*
2923 + * Overrides for Emacs so that we follow Linus's tabbing style.
2924 + * Emacs will notice this stuff at the end of the file and automatically
2925 + * adjust the settings for this buffer only.  This must remain at the end
2926 + * of the file.
2927 + * ---------------------------------------------------------------------------
2928 + * Local variables:
2929 + * c-file-style: "linux"
2930 + * End:
2931 + */
2932 Index: linux-2.4.29/arch/um/drivers/daemon_kern.c
2933 ===================================================================
2934 --- linux-2.4.29.orig/arch/um/drivers/daemon_kern.c     1970-01-01 03:00:00.000000000 +0300
2935 +++ linux-2.4.29/arch/um/drivers/daemon_kern.c  2005-05-03 22:28:14.000000000 +0300
2936 @@ -0,0 +1,113 @@
2937 +/*
2938 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
2939 + * James Leu (jleu@mindspring.net).
2940 + * Copyright (C) 2001 by various other people who didn't put their name here.
2941 + * Licensed under the GPL.
2942 + */
2943 +
2944 +#include "linux/kernel.h"
2945 +#include "linux/init.h"
2946 +#include "linux/netdevice.h"
2947 +#include "linux/etherdevice.h"
2948 +#include "net_kern.h"
2949 +#include "net_user.h"
2950 +#include "daemon.h"
2951 +
2952 +struct daemon_init {
2953 +       char *sock_type;
2954 +       char *ctl_sock;
2955 +};
2956 +
2957 +void daemon_init(struct net_device *dev, void *data)
2958 +{
2959 +       struct uml_net_private *pri;
2960 +       struct daemon_data *dpri;
2961 +       struct daemon_init *init = data;
2962 +
2963 +       init_etherdev(dev, 0);
2964 +       pri = dev->priv;
2965 +       dpri = (struct daemon_data *) pri->user;
2966 +       *dpri = ((struct daemon_data)
2967 +               { .sock_type            = init->sock_type,
2968 +                 .ctl_sock             = init->ctl_sock,
2969 +                 .ctl_addr             = NULL,
2970 +                 .data_addr            = NULL,
2971 +                 .local_addr           = NULL,
2972 +                 .fd                   = -1,
2973 +                 .control              = -1,
2974 +                 .dev                  = dev });
2975 +
2976 +       printk("daemon backend (uml_switch version %d) - %s:%s", 
2977 +              SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
2978 +       printk("\n");
2979 +}
2980 +
2981 +static int daemon_read(int fd, struct sk_buff **skb, 
2982 +                      struct uml_net_private *lp)
2983 +{
2984 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
2985 +       if(*skb == NULL) return(-ENOMEM);
2986 +       return(net_recvfrom(fd, (*skb)->mac.raw, 
2987 +                           (*skb)->dev->mtu + ETH_HEADER_OTHER));
2988 +}
2989 +
2990 +static int daemon_write(int fd, struct sk_buff **skb,
2991 +                       struct uml_net_private *lp)
2992 +{
2993 +       return(daemon_user_write(fd, (*skb)->data, (*skb)->len, 
2994 +                                (struct daemon_data *) &lp->user));
2995 +}
2996 +
2997 +static struct net_kern_info daemon_kern_info = {
2998 +       .init                   = daemon_init,
2999 +       .protocol               = eth_protocol,
3000 +       .read                   = daemon_read,
3001 +       .write                  = daemon_write,
3002 +};
3003 +
3004 +int daemon_setup(char *str, char **mac_out, void *data)
3005 +{
3006 +       struct daemon_init *init = data;
3007 +       char *remain;
3008 +
3009 +       *init = ((struct daemon_init)
3010 +               { .sock_type            = "unix",
3011 +                 .ctl_sock             = "/tmp/uml.ctl" });
3012 +       
3013 +       remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
3014 +                              NULL);
3015 +       if(remain != NULL)
3016 +               printk(KERN_WARNING "daemon_setup : Ignoring data socket "
3017 +                      "specification\n");
3018 +       
3019 +       return(1);
3020 +}
3021 +
3022 +static struct transport daemon_transport = {
3023 +       .list           = LIST_HEAD_INIT(daemon_transport.list),
3024 +       .name           = "daemon",
3025 +       .setup          = daemon_setup,
3026 +       .user           = &daemon_user_info,
3027 +       .kern           = &daemon_kern_info,
3028 +       .private_size   = sizeof(struct daemon_data),
3029 +       .setup_size     = sizeof(struct daemon_init),
3030 +};
3031 +
3032 +static int register_daemon(void)
3033 +{
3034 +       register_transport(&daemon_transport);
3035 +       return(1);
3036 +}
3037 +
3038 +__initcall(register_daemon);
3039 +
3040 +/*
3041 + * Overrides for Emacs so that we follow Linus's tabbing style.
3042 + * Emacs will notice this stuff at the end of the file and automatically
3043 + * adjust the settings for this buffer only.  This must remain at the end
3044 + * of the file.
3045 + * ---------------------------------------------------------------------------
3046 + * Local variables:
3047 + * c-file-style: "linux"
3048 + * End:
3049 + */
3050 Index: linux-2.4.29/arch/um/drivers/daemon_user.c
3051 ===================================================================
3052 --- linux-2.4.29.orig/arch/um/drivers/daemon_user.c     1970-01-01 03:00:00.000000000 +0300
3053 +++ linux-2.4.29/arch/um/drivers/daemon_user.c  2005-05-03 22:28:14.000000000 +0300
3054 @@ -0,0 +1,197 @@
3055 +/*
3056 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
3057 + * James Leu (jleu@mindspring.net).
3058 + * Copyright (C) 2001 by various other people who didn't put their name here.
3059 + * Licensed under the GPL.
3060 + */
3061 +
3062 +#include <errno.h>
3063 +#include <unistd.h>
3064 +#include <stdint.h>
3065 +#include <sys/socket.h>
3066 +#include <sys/un.h>
3067 +#include <sys/time.h>
3068 +#include "net_user.h"
3069 +#include "daemon.h"
3070 +#include "kern_util.h"
3071 +#include "user_util.h"
3072 +#include "user.h"
3073 +#include "os.h"
3074 +
3075 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
3076 +
3077 +enum request_type { REQ_NEW_CONTROL };
3078 +
3079 +#define SWITCH_MAGIC 0xfeedface
3080 +
3081 +struct request_v3 {
3082 +       uint32_t magic;
3083 +       uint32_t version;
3084 +       enum request_type type;
3085 +       struct sockaddr_un sock;
3086 +};
3087 +
3088 +static struct sockaddr_un *new_addr(void *name, int len)
3089 +{
3090 +       struct sockaddr_un *sun;
3091 +
3092 +       sun = um_kmalloc(sizeof(struct sockaddr_un));
3093 +       if(sun == NULL){
3094 +               printk("new_addr: allocation of sockaddr_un failed\n");
3095 +               return(NULL);
3096 +       }
3097 +       sun->sun_family = AF_UNIX;
3098 +       memcpy(sun->sun_path, name, len);
3099 +       return(sun);
3100 +}
3101 +
3102 +static int connect_to_switch(struct daemon_data *pri)
3103 +{
3104 +       struct sockaddr_un *ctl_addr = pri->ctl_addr;
3105 +       struct sockaddr_un *local_addr = pri->local_addr;
3106 +       struct sockaddr_un *sun;
3107 +       struct request_v3 req;
3108 +       int fd, n, err;
3109 +
3110 +       pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
3111 +       if(pri->control < 0){
3112 +               printk("daemon_open : control socket failed, errno = %d\n", 
3113 +                      errno);          
3114 +               return(-errno);
3115 +       }
3116 +
3117 +       if(connect(pri->control, (struct sockaddr *) ctl_addr, 
3118 +                  sizeof(*ctl_addr)) < 0){
3119 +               printk("daemon_open : control connect failed, errno = %d\n",
3120 +                      errno);
3121 +               err = -errno;
3122 +               goto out;
3123 +       }
3124 +
3125 +       fd = socket(AF_UNIX, SOCK_DGRAM, 0);
3126 +       if(fd < 0){
3127 +               printk("daemon_open : data socket failed, errno = %d\n", 
3128 +                      errno);
3129 +               err = -errno;
3130 +               goto out;
3131 +       }
3132 +       if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){
3133 +               printk("daemon_open : data bind failed, errno = %d\n", 
3134 +                      errno);
3135 +               err = -errno;
3136 +               goto out_close;
3137 +       }
3138 +
3139 +       sun = um_kmalloc(sizeof(struct sockaddr_un));
3140 +       if(sun == NULL){
3141 +               printk("new_addr: allocation of sockaddr_un failed\n");
3142 +               err = -ENOMEM;
3143 +               goto out_close;
3144 +       }
3145 +
3146 +       req.magic = SWITCH_MAGIC;
3147 +       req.version = SWITCH_VERSION;
3148 +       req.type = REQ_NEW_CONTROL;
3149 +       req.sock = *local_addr;
3150 +       n = os_write_file(pri->control, &req, sizeof(req));
3151 +       if(n != sizeof(req)){
3152 +               printk("daemon_open : control setup request failed, err = %d\n",
3153 +                      -n);
3154 +               err = -ENOTCONN;
3155 +               goto out;               
3156 +       }
3157 +
3158 +       n = os_read_file(pri->control, sun, sizeof(*sun));
3159 +       if(n != sizeof(*sun)){
3160 +               printk("daemon_open : read of data socket failed, err = %d\n", 
3161 +                      -n);
3162 +               err = -ENOTCONN;
3163 +               goto out_close;         
3164 +       }
3165 +
3166 +       pri->data_addr = sun;
3167 +       return(fd);
3168 +
3169 + out_close:
3170 +       os_close_file(fd);
3171 + out:
3172 +       os_close_file(pri->control);
3173 +       return(err);
3174 +}
3175 +
3176 +static void daemon_user_init(void *data, void *dev)
3177 +{
3178 +       struct daemon_data *pri = data;
3179 +       struct timeval tv;
3180 +       struct {
3181 +               char zero;
3182 +               int pid;
3183 +               int usecs;
3184 +       } name;
3185 +
3186 +       if(!strcmp(pri->sock_type, "unix"))
3187 +               pri->ctl_addr = new_addr(pri->ctl_sock, 
3188 +                                        strlen(pri->ctl_sock) + 1);
3189 +       name.zero = 0;
3190 +       name.pid = os_getpid();
3191 +       gettimeofday(&tv, NULL);
3192 +       name.usecs = tv.tv_usec;
3193 +       pri->local_addr = new_addr(&name, sizeof(name));
3194 +       pri->dev = dev;
3195 +       pri->fd = connect_to_switch(pri);
3196 +       if(pri->fd < 0){
3197 +               kfree(pri->local_addr);
3198 +               pri->local_addr = NULL;
3199 +       }
3200 +}
3201 +
3202 +static int daemon_open(void *data)
3203 +{
3204 +       struct daemon_data *pri = data;
3205 +       return(pri->fd);
3206 +}
3207 +
3208 +static void daemon_remove(void *data)
3209 +{
3210 +       struct daemon_data *pri = data;
3211 +
3212 +       os_close_file(pri->fd);
3213 +       os_close_file(pri->control);
3214 +       if(pri->data_addr != NULL) kfree(pri->data_addr);
3215 +       if(pri->ctl_addr != NULL) kfree(pri->ctl_addr);
3216 +       if(pri->local_addr != NULL) kfree(pri->local_addr);
3217 +}
3218 +
3219 +int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
3220 +{
3221 +       struct sockaddr_un *data_addr = pri->data_addr;
3222 +
3223 +       return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
3224 +}
3225 +
3226 +static int daemon_set_mtu(int mtu, void *data)
3227 +{
3228 +       return(mtu);
3229 +}
3230 +
3231 +struct net_user_info daemon_user_info = {
3232 +       .init           = daemon_user_init,
3233 +       .open           = daemon_open,
3234 +       .close          = NULL,
3235 +       .remove         = daemon_remove,
3236 +       .set_mtu        = daemon_set_mtu,
3237 +       .add_address    = NULL,
3238 +       .delete_address = NULL,
3239 +       .max_packet     = MAX_PACKET - ETH_HEADER_OTHER
3240 +};
3241 +
3242 +/*
3243 + * Overrides for Emacs so that we follow Linus's tabbing style.
3244 + * Emacs will notice this stuff at the end of the file and automatically
3245 + * adjust the settings for this buffer only.  This must remain at the end
3246 + * of the file.
3247 + * ---------------------------------------------------------------------------
3248 + * Local variables:
3249 + * c-file-style: "linux"
3250 + * End:
3251 + */
3252 Index: linux-2.4.29/arch/um/drivers/fd.c
3253 ===================================================================
3254 --- linux-2.4.29.orig/arch/um/drivers/fd.c      1970-01-01 03:00:00.000000000 +0300
3255 +++ linux-2.4.29/arch/um/drivers/fd.c   2005-05-03 22:28:14.208450200 +0300
3256 @@ -0,0 +1,108 @@
3257 +/* 
3258 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
3259 + * Licensed under the GPL
3260 + */
3261 +
3262 +#include <stdio.h>
3263 +#include <stdlib.h>
3264 +#include <unistd.h>
3265 +#include <termios.h>
3266 +#include <errno.h>
3267 +#include "user.h"
3268 +#include "user_util.h"
3269 +#include "chan_user.h"
3270 +
3271 +struct fd_chan {
3272 +       int fd;
3273 +       int raw;
3274 +       struct termios tt;
3275 +       char str[sizeof("1234567890\0")];
3276 +};
3277 +
3278 +void *fd_init(char *str, int device, struct chan_opts *opts)
3279 +{
3280 +       struct fd_chan *data;
3281 +       char *end;
3282 +       int n;
3283 +
3284 +       if(*str != ':'){
3285 +               printk("fd_init : channel type 'fd' must specify a file "
3286 +                      "descriptor\n");
3287 +               return(NULL);
3288 +       }
3289 +       str++;
3290 +       n = strtoul(str, &end, 0);
3291 +       if((*end != '\0') || (end == str)){
3292 +               printk("fd_init : couldn't parse file descriptor '%s'\n", str);
3293 +               return(NULL);
3294 +       }
3295 +       data = um_kmalloc(sizeof(*data));
3296 +       if(data == NULL) return(NULL);
3297 +       *data = ((struct fd_chan) { .fd         = n,
3298 +                                   .raw        = opts->raw });
3299 +       return(data);
3300 +}
3301 +
3302 +int fd_open(int input, int output, int primary, void *d, char **dev_out)
3303 +{
3304 +       struct fd_chan *data = d;
3305 +       int err;
3306 +
3307 +       if(data->raw && isatty(data->fd)){
3308 +               CATCH_EINTR(err = tcgetattr(data->fd, &data->tt));
3309 +               if(err)
3310 +                       return(err);
3311 +
3312 +               err = raw(data->fd);
3313 +               if(err)
3314 +                       return(err);
3315 +       }
3316 +       sprintf(data->str, "%d", data->fd);
3317 +       *dev_out = data->str;
3318 +       return(data->fd);
3319 +}
3320 +
3321 +void fd_close(int fd, void *d)
3322 +{
3323 +       struct fd_chan *data = d;
3324 +       int err;
3325 +
3326 +       if(data->raw && isatty(fd)){
3327 +               CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt));
3328 +               if(err)
3329 +                       printk("Failed to restore terminal state - " 
3330 +                              "errno = %d\n", -err);
3331 +               data->raw = 0;
3332 +       }
3333 +}
3334 +
3335 +int fd_console_write(int fd, const char *buf, int n, void *d)
3336 +{
3337 +       struct fd_chan *data = d;
3338 +
3339 +       return(generic_console_write(fd, buf, n, &data->tt));
3340 +}
3341 +
3342 +struct chan_ops fd_ops = {
3343 +       .type           = "fd",
3344 +       .init           = fd_init,
3345 +       .open           = fd_open,
3346 +       .close          = fd_close,
3347 +       .read           = generic_read,
3348 +       .write          = generic_write,
3349 +       .console_write  = fd_console_write,
3350 +       .window_size    = generic_window_size,
3351 +       .free           = generic_free,
3352 +       .winch          = 1,
3353 +};
3354 +
3355 +/*
3356 + * Overrides for Emacs so that we follow Linus's tabbing style.
3357 + * Emacs will notice this stuff at the end of the file and automatically
3358 + * adjust the settings for this buffer only.  This must remain at the end
3359 + * of the file.
3360 + * ---------------------------------------------------------------------------
3361 + * Local variables:
3362 + * c-file-style: "linux"
3363 + * End:
3364 + */
3365 Index: linux-2.4.29/arch/um/drivers/harddog_kern.c
3366 ===================================================================
3367 --- linux-2.4.29.orig/arch/um/drivers/harddog_kern.c    1970-01-01 03:00:00.000000000 +0300
3368 +++ linux-2.4.29/arch/um/drivers/harddog_kern.c 2005-05-03 22:28:14.000000000 +0300
3369 @@ -0,0 +1,194 @@
3370 +/* UML hardware watchdog, shamelessly stolen from:
3371 + *
3372 + *     SoftDog 0.05:   A Software Watchdog Device
3373 + *
3374 + *     (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
3375 + *                             http://www.redhat.com
3376 + *
3377 + *     This program is free software; you can redistribute it and/or
3378 + *     modify it under the terms of the GNU General Public License
3379 + *     as published by the Free Software Foundation; either version
3380 + *     2 of the License, or (at your option) any later version.
3381 + *     
3382 + *     Neither Alan Cox nor CymruNet Ltd. admit liability nor provide 
3383 + *     warranty for any of this software. This material is provided 
3384 + *     "AS-IS" and at no charge.       
3385 + *
3386 + *     (c) Copyright 1995    Alan Cox <alan@lxorguk.ukuu.org.uk>
3387 + *
3388 + *     Software only watchdog driver. Unlike its big brother the WDT501P
3389 + *     driver this won't always recover a failed machine.
3390 + *
3391 + *  03/96: Angelo Haritsis <ah@doc.ic.ac.uk> :
3392 + *     Modularised.
3393 + *     Added soft_margin; use upon insmod to change the timer delay.
3394 + *     NB: uses same minor as wdt (WATCHDOG_MINOR); we could use separate
3395 + *         minors.
3396 + *
3397 + *  19980911 Alan Cox
3398 + *     Made SMP safe for 2.3.x
3399 + *
3400 + *  20011127 Joel Becker (jlbec@evilplan.org>
3401 + *     Added soft_noboot; Allows testing the softdog trigger without 
3402 + *     requiring a recompile.
3403 + *     Added WDIOC_GETTIMEOUT and WDIOC_SETTIMOUT.
3404 + */
3405
3406 +#include <linux/module.h>
3407 +#include <linux/config.h>
3408 +#include <linux/types.h>
3409 +#include <linux/kernel.h>
3410 +#include <linux/fs.h>
3411 +#include <linux/mm.h>
3412 +#include <linux/miscdevice.h>
3413 +#include <linux/watchdog.h>
3414 +#include <linux/reboot.h>
3415 +#include <linux/smp_lock.h>
3416 +#include <linux/init.h>
3417 +#include <asm/uaccess.h>
3418 +#include "helper.h"
3419 +#include "mconsole.h"
3420 +
3421 +MODULE_LICENSE("GPL");
3422 +
3423 +/* Locked by the BKL in harddog_open and harddog_release */
3424 +static int timer_alive;
3425 +static int harddog_in_fd = -1;
3426 +static int harddog_out_fd = -1;
3427 +
3428 +/*
3429 + *     Allow only one person to hold it open
3430 + */
3431
3432 +extern int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock);
3433 +
3434 +static int harddog_open(struct inode *inode, struct file *file)
3435 +{
3436 +       int err;
3437 +       char *sock = NULL;
3438 +
3439 +       lock_kernel();
3440 +       if(timer_alive)
3441 +               return -EBUSY;
3442 +#ifdef CONFIG_HARDDOG_NOWAYOUT  
3443 +       MOD_INC_USE_COUNT;
3444 +#endif
3445 +
3446 +#ifdef CONFIG_MCONSOLE
3447 +       sock = mconsole_notify_socket();
3448 +#endif
3449 +       err = start_watchdog(&harddog_in_fd, &harddog_out_fd, sock);
3450 +       if(err) return(err);
3451 +
3452 +       timer_alive = 1;
3453 +       unlock_kernel();
3454 +       return 0;
3455 +}
3456 +
3457 +extern void stop_watchdog(int in_fd, int out_fd);
3458 +
3459 +static int harddog_release(struct inode *inode, struct file *file)
3460 +{
3461 +       /*
3462 +        *      Shut off the timer.
3463 +        */
3464 +       lock_kernel();
3465 +
3466 +       stop_watchdog(harddog_in_fd, harddog_out_fd);
3467 +       harddog_in_fd = -1;
3468 +       harddog_out_fd = -1;
3469 +
3470 +       timer_alive=0;
3471 +       unlock_kernel();
3472 +       return 0;
3473 +}
3474 +
3475 +extern int ping_watchdog(int fd);
3476 +
3477 +static ssize_t harddog_write(struct file *file, const char *data, size_t len,
3478 +                            loff_t *ppos)
3479 +{
3480 +       /*  Can't seek (pwrite) on this device  */
3481 +       if (ppos != &file->f_pos)
3482 +               return -ESPIPE;
3483 +
3484 +       /*
3485 +        *      Refresh the timer.
3486 +        */
3487 +       if(len)
3488 +               return(ping_watchdog(harddog_out_fd));
3489 +       return 0;
3490 +}
3491 +
3492 +static int harddog_ioctl(struct inode *inode, struct file *file,
3493 +                        unsigned int cmd, unsigned long arg)
3494 +{
3495 +       static struct watchdog_info ident = {
3496 +               WDIOF_SETTIMEOUT,
3497 +               0,
3498 +               "UML Hardware Watchdog"
3499 +       };
3500 +       switch (cmd) {
3501 +               default:
3502 +                       return -ENOTTY;
3503 +               case WDIOC_GETSUPPORT:
3504 +                       if(copy_to_user((struct harddog_info *)arg, &ident,
3505 +                                       sizeof(ident)))
3506 +                               return -EFAULT;
3507 +                       return 0;
3508 +               case WDIOC_GETSTATUS:
3509 +               case WDIOC_GETBOOTSTATUS:
3510 +                       return put_user(0,(int *)arg);
3511 +               case WDIOC_KEEPALIVE:
3512 +                       return(ping_watchdog(harddog_out_fd));
3513 +       }
3514 +}
3515 +
3516 +static struct file_operations harddog_fops = {
3517 +       .owner          = THIS_MODULE,
3518 +       .write          = harddog_write,
3519 +       .ioctl          = harddog_ioctl,
3520 +       .open           = harddog_open,
3521 +       .release        = harddog_release,
3522 +};
3523 +
3524 +static struct miscdevice harddog_miscdev = {
3525 +       .minor          = WATCHDOG_MINOR,
3526 +       .name           = "watchdog",
3527 +       .fops           = &harddog_fops,
3528 +};
3529 +
3530 +static char banner[] __initdata = KERN_INFO "UML Watchdog Timer\n";
3531 +
3532 +static int __init harddog_init(void)
3533 +{
3534 +       int ret;
3535 +
3536 +       ret = misc_register(&harddog_miscdev);
3537 +
3538 +       if (ret)
3539 +               return ret;
3540 +
3541 +       printk(banner);
3542 +
3543 +       return(0);
3544 +}
3545 +
3546 +static void __exit harddog_exit(void)
3547 +{
3548 +       misc_deregister(&harddog_miscdev);
3549 +}
3550 +
3551 +module_init(harddog_init);
3552 +module_exit(harddog_exit);
3553 +
3554 +/*
3555 + * Overrides for Emacs so that we follow Linus's tabbing style.
3556 + * Emacs will notice this stuff at the end of the file and automatically
3557 + * adjust the settings for this buffer only.  This must remain at the end
3558 + * of the file.
3559 + * ---------------------------------------------------------------------------
3560 + * Local variables:
3561 + * c-file-style: "linux"
3562 + * End:
3563 + */
3564 Index: linux-2.4.29/arch/um/drivers/harddog_user.c
3565 ===================================================================
3566 --- linux-2.4.29.orig/arch/um/drivers/harddog_user.c    1970-01-01 03:00:00.000000000 +0300
3567 +++ linux-2.4.29/arch/um/drivers/harddog_user.c 2005-05-03 22:28:14.000000000 +0300
3568 @@ -0,0 +1,143 @@
3569 +/* 
3570 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3571 + * Licensed under the GPL
3572 + */
3573 +
3574 +#include <stdio.h>
3575 +#include <unistd.h>
3576 +#include <errno.h>
3577 +#include "user_util.h"
3578 +#include "user.h"
3579 +#include "helper.h"
3580 +#include "mconsole.h"
3581 +#include "os.h"
3582 +#include "choose-mode.h"
3583 +#include "mode.h"
3584 +
3585 +struct dog_data {
3586 +       int stdin;
3587 +       int stdout;
3588 +       int close_me[2];
3589 +};
3590 +
3591 +static void pre_exec(void *d)
3592 +{
3593 +       struct dog_data *data = d;
3594 +
3595 +       dup2(data->stdin, 0);
3596 +       dup2(data->stdout, 1);
3597 +       dup2(data->stdout, 2);
3598 +       os_close_file(data->stdin);
3599 +       os_close_file(data->stdout);
3600 +       os_close_file(data->close_me[0]);
3601 +       os_close_file(data->close_me[1]);
3602 +}
3603 +
3604 +int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
3605 +{
3606 +       struct dog_data data;
3607 +       int in_fds[2], out_fds[2], pid, n, err;
3608 +       char pid_buf[sizeof("nnnnn\0")], c;
3609 +       char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL };
3610 +       char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL, 
3611 +                                 NULL };
3612 +       char **args = NULL;
3613 +
3614 +       err = os_pipe(in_fds, 1, 0);
3615 +       if(err < 0){
3616 +               printk("harddog_open - os_pipe failed, err = %d\n", -err);
3617 +               goto out;
3618 +       }
3619 +
3620 +       err = os_pipe(out_fds, 1, 0);
3621 +       if(err < 0){
3622 +               printk("harddog_open - os_pipe failed, err = %d\n", -err);
3623 +               goto out_close_in;
3624 +       }
3625 +
3626 +       data.stdin = out_fds[0];
3627 +       data.stdout = in_fds[1];
3628 +       data.close_me[0] = out_fds[1];
3629 +       data.close_me[1] = in_fds[0];
3630 +
3631 +       if(sock != NULL){
3632 +               mconsole_args[2] = sock;
3633 +               args = mconsole_args;
3634 +       }
3635 +       else {
3636 +               /* XXX The os_getpid() is not SMP correct */
3637 +               sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid()));
3638 +               args = pid_args;
3639 +       }
3640 +
3641 +       pid = run_helper(pre_exec, &data, args, NULL);
3642 +
3643 +       os_close_file(out_fds[0]);
3644 +       os_close_file(in_fds[1]);
3645 +
3646 +       if(pid < 0){
3647 +               err = -pid;
3648 +               printk("harddog_open - run_helper failed, errno = %d\n", -err);
3649 +               goto out_close_out;
3650 +       }
3651 +
3652 +       n = os_read_file(in_fds[0], &c, sizeof(c));
3653 +       if(n == 0){
3654 +               printk("harddog_open - EOF on watchdog pipe\n");
3655 +               helper_wait(pid);
3656 +               err = -EIO;
3657 +               goto out_close_out;
3658 +       }
3659 +       else if(n < 0){
3660 +               printk("harddog_open - read of watchdog pipe failed, "
3661 +                      "err = %d\n", -n);
3662 +               helper_wait(pid);
3663 +               err = n;
3664 +               goto out_close_out;
3665 +       }
3666 +       *in_fd_ret = in_fds[0];
3667 +       *out_fd_ret = out_fds[1];
3668 +       return(0);
3669 +
3670 + out_close_in:
3671 +       os_close_file(in_fds[0]);
3672 +       os_close_file(in_fds[1]);
3673 + out_close_out:
3674 +       os_close_file(out_fds[0]);
3675 +       os_close_file(out_fds[1]);
3676 + out:
3677 +       return(err);
3678 +}
3679 +
3680 +void stop_watchdog(int in_fd, int out_fd)
3681 +{
3682 +       os_close_file(in_fd);
3683 +       os_close_file(out_fd);
3684 +}
3685 +
3686 +int ping_watchdog(int fd)
3687 +{
3688 +       int n;
3689 +       char c = '\n';
3690 +
3691 +       n = os_write_file(fd, &c, sizeof(c));
3692 +       if(n != sizeof(c)){
3693 +               printk("ping_watchdog - write failed, err = %d\n", -n);
3694 +               if(n < 0) 
3695 +                       return(n);
3696 +               return(-EIO);
3697 +       }
3698 +       return 1;
3699 +
3700 +}
3701 +
3702 +/*
3703 + * Overrides for Emacs so that we follow Linus's tabbing style.
3704 + * Emacs will notice this stuff at the end of the file and automatically
3705 + * adjust the settings for this buffer only.  This must remain at the end
3706 + * of the file.
3707 + * ---------------------------------------------------------------------------
3708 + * Local variables:
3709 + * c-file-style: "linux"
3710 + * End:
3711 + */
3712 Index: linux-2.4.29/arch/um/drivers/hostaudio_kern.c
3713 ===================================================================
3714 --- linux-2.4.29.orig/arch/um/drivers/hostaudio_kern.c  1970-01-01 03:00:00.000000000 +0300
3715 +++ linux-2.4.29/arch/um/drivers/hostaudio_kern.c       2005-05-03 22:28:14.000000000 +0300
3716 @@ -0,0 +1,352 @@
3717 +/* 
3718 + * Copyright (C) 2002 Steve Schmidtke 
3719 + * Licensed under the GPL
3720 + */
3721 +
3722 +#include "linux/config.h"
3723 +#include "linux/module.h"
3724 +#include "linux/init.h"
3725 +#include "linux/slab.h"
3726 +#include "linux/fs.h"
3727 +#include "linux/sound.h"
3728 +#include "linux/soundcard.h"
3729 +#include "asm/uaccess.h"
3730 +#include "kern_util.h"
3731 +#include "init.h"
3732 +#include "os.h"
3733 +
3734 +struct hostaudio_state {
3735 +       int fd;
3736 +};
3737 +
3738 +struct hostmixer_state {
3739 +       int fd;
3740 +};
3741 +
3742 +#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
3743 +#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
3744 +
3745 +/* Only changed from linux_main at boot time */
3746 +char *dsp = HOSTAUDIO_DEV_DSP;
3747 +char *mixer = HOSTAUDIO_DEV_MIXER;
3748 +
3749 +#define DSP_HELP \
3750 +"    This is used to specify the host dsp device to the hostaudio driver.\n" \
3751 +"    The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
3752 +
3753 +#define MIXER_HELP \
3754 +"    This is used to specify the host mixer device to the hostaudio driver.\n"\
3755 +"    The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
3756 +
3757 +#ifndef MODULE
3758 +static int set_dsp(char *name, int *add)
3759 +{
3760 +       dsp = name;
3761 +       return(0);
3762 +}
3763 +
3764 +__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
3765 +
3766 +static int set_mixer(char *name, int *add)
3767 +{
3768 +       mixer = name;
3769 +       return(0);
3770 +}
3771 +
3772 +__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
3773 +
3774 +#else /*MODULE*/
3775 +
3776 +MODULE_PARM(dsp, "s");
3777 +MODULE_PARM_DESC(dsp, DSP_HELP);
3778 +
3779 +MODULE_PARM(mixer, "s");
3780 +MODULE_PARM_DESC(mixer, MIXER_HELP);
3781 +
3782 +#endif
3783 +
3784 +/* /dev/dsp file operations */
3785 +
3786 +static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count, 
3787 +                             loff_t *ppos)
3788 +{
3789 +        struct hostaudio_state *state = file->private_data;
3790 +       void *kbuf;
3791 +       int err;
3792 +
3793 +#ifdef DEBUG
3794 +        printk("hostaudio: read called, count = %d\n", count);
3795 +#endif
3796 +
3797 +       kbuf = kmalloc(count, GFP_KERNEL);
3798 +       if(kbuf == NULL)
3799 +               return(-ENOMEM);
3800 +
3801 +       err = os_read_file(state->fd, kbuf, count);
3802 +       if(err < 0)
3803 +               goto out;
3804 +
3805 +       if(copy_to_user(buffer, kbuf, err))
3806 +               err = -EFAULT;
3807 +
3808 + out:
3809 +       kfree(kbuf);
3810 +       return(err);
3811 +}
3812 +
3813 +static ssize_t hostaudio_write(struct file *file, const char *buffer, 
3814 +                              size_t count, loff_t *ppos)
3815 +{
3816 +        struct hostaudio_state *state = file->private_data;
3817 +       void *kbuf;
3818 +       int err;
3819 +
3820 +#ifdef DEBUG
3821 +        printk("hostaudio: write called, count = %d\n", count);
3822 +#endif
3823 +
3824 +       kbuf = kmalloc(count, GFP_KERNEL);
3825 +       if(kbuf == NULL)
3826 +               return(-ENOMEM);
3827 +
3828 +       err = -EFAULT;
3829 +       if(copy_from_user(kbuf, buffer, count))
3830 +               goto out;
3831 +
3832 +       err = os_write_file(state->fd, kbuf, count);
3833 +       if(err < 0)
3834 +               goto out;
3835 +       *ppos += err;
3836 +
3837 + out:
3838 +       kfree(kbuf);
3839 +       return(err);
3840 +}
3841 +
3842 +static unsigned int hostaudio_poll(struct file *file, 
3843 +                                  struct poll_table_struct *wait)
3844 +{
3845 +        unsigned int mask = 0;
3846 +
3847 +#ifdef DEBUG
3848 +        printk("hostaudio: poll called (unimplemented)\n");
3849 +#endif
3850 +
3851 +        return(mask);
3852 +}
3853 +
3854 +static int hostaudio_ioctl(struct inode *inode, struct file *file, 
3855 +                          unsigned int cmd, unsigned long arg)
3856 +{
3857 +        struct hostaudio_state *state = file->private_data;
3858 +       unsigned long data = 0;
3859 +       int err;
3860 +
3861 +#ifdef DEBUG
3862 +        printk("hostaudio: ioctl called, cmd = %u\n", cmd);
3863 +#endif
3864 +       switch(cmd){
3865 +       case SNDCTL_DSP_SPEED:
3866 +       case SNDCTL_DSP_STEREO:
3867 +       case SNDCTL_DSP_GETBLKSIZE:
3868 +       case SNDCTL_DSP_CHANNELS:
3869 +       case SNDCTL_DSP_SUBDIVIDE:
3870 +       case SNDCTL_DSP_SETFRAGMENT:
3871 +               if(get_user(data, (int *) arg))
3872 +                       return(-EFAULT);
3873 +               break;
3874 +       default:
3875 +               break;
3876 +       }
3877 +
3878 +       err = os_ioctl_generic(state->fd, cmd, (unsigned long) &data);
3879 +
3880 +       switch(cmd){
3881 +       case SNDCTL_DSP_SPEED:
3882 +       case SNDCTL_DSP_STEREO:
3883 +       case SNDCTL_DSP_GETBLKSIZE:
3884 +       case SNDCTL_DSP_CHANNELS:
3885 +       case SNDCTL_DSP_SUBDIVIDE:
3886 +       case SNDCTL_DSP_SETFRAGMENT:
3887 +               if(put_user(data, (int *) arg))
3888 +                       return(-EFAULT);
3889 +               break;
3890 +       default:
3891 +               break;
3892 +       }
3893 +
3894 +       return(err);
3895 +}
3896 +
3897 +static int hostaudio_open(struct inode *inode, struct file *file)
3898 +{
3899 +        struct hostaudio_state *state;
3900 +        int r = 0, w = 0;
3901 +        int ret;
3902 +
3903 +#ifdef DEBUG
3904 +        printk("hostaudio: open called (host: %s)\n", dsp);
3905 +#endif
3906 +
3907 +        state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
3908 +        if(state == NULL) 
3909 +               return(-ENOMEM);
3910 +
3911 +        if(file->f_mode & FMODE_READ) r = 1;
3912 +        if(file->f_mode & FMODE_WRITE) w = 1;
3913 +
3914 +       ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
3915 +        if(ret < 0){
3916 +               kfree(state);
3917 +               return(ret);
3918 +        }
3919 +
3920 +       state->fd = ret;
3921 +        file->private_data = state;
3922 +        return(0);
3923 +}
3924 +
3925 +static int hostaudio_release(struct inode *inode, struct file *file)
3926 +{
3927 +        struct hostaudio_state *state = file->private_data;
3928 +
3929 +#ifdef DEBUG
3930 +        printk("hostaudio: release called\n");
3931 +#endif
3932 +
3933 +       os_close_file(state->fd);
3934 +        kfree(state);
3935 +
3936 +        return(0);
3937 +}
3938 +
3939 +/* /dev/mixer file operations */
3940 +
3941 +static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file, 
3942 +                                 unsigned int cmd, unsigned long arg)
3943 +{
3944 +        struct hostmixer_state *state = file->private_data;
3945 +
3946 +#ifdef DEBUG
3947 +        printk("hostmixer: ioctl called\n");
3948 +#endif
3949 +
3950 +       return(os_ioctl_generic(state->fd, cmd, arg));
3951 +}
3952 +
3953 +static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
3954 +{
3955 +        struct hostmixer_state *state;
3956 +        int r = 0, w = 0;
3957 +        int ret;
3958 +
3959 +#ifdef DEBUG
3960 +        printk("hostmixer: open called (host: %s)\n", mixer);
3961 +#endif
3962 +
3963 +        state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL);
3964 +        if(state == NULL) return(-ENOMEM);
3965 +
3966 +        if(file->f_mode & FMODE_READ) r = 1;
3967 +        if(file->f_mode & FMODE_WRITE) w = 1;
3968 +
3969 +       ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
3970 +        
3971 +        if(ret < 0){
3972 +               printk("hostaudio_open_mixdev failed to open '%s', err = %d\n",
3973 +                      dsp, -ret);
3974 +               kfree(state);
3975 +               return(ret);
3976 +        }
3977 +
3978 +        file->private_data = state;
3979 +        return(0);
3980 +}
3981 +
3982 +static int hostmixer_release(struct inode *inode, struct file *file)
3983 +{
3984 +        struct hostmixer_state *state = file->private_data;
3985 +
3986 +#ifdef DEBUG
3987 +        printk("hostmixer: release called\n");
3988 +#endif
3989 +
3990 +       os_close_file(state->fd);
3991 +        kfree(state);
3992 +
3993 +        return(0);
3994 +}
3995 +
3996 +
3997 +/* kernel module operations */
3998 +
3999 +static struct file_operations hostaudio_fops = {
4000 +        .owner          = THIS_MODULE,
4001 +        .llseek         = no_llseek,
4002 +        .read           = hostaudio_read,
4003 +        .write          = hostaudio_write,
4004 +        .poll           = hostaudio_poll,
4005 +        .ioctl          = hostaudio_ioctl,
4006 +        .mmap           = NULL,
4007 +        .open           = hostaudio_open,
4008 +        .release        = hostaudio_release,
4009 +};
4010 +
4011 +static struct file_operations hostmixer_fops = {
4012 +        .owner          = THIS_MODULE,
4013 +        .llseek         = no_llseek,
4014 +        .ioctl          = hostmixer_ioctl_mixdev,
4015 +        .open           = hostmixer_open_mixdev,
4016 +        .release        = hostmixer_release,
4017 +};
4018 +
4019 +struct {
4020 +       int dev_audio;
4021 +       int dev_mixer;
4022 +} module_data;
4023 +
4024 +MODULE_AUTHOR("Steve Schmidtke");
4025 +MODULE_DESCRIPTION("UML Audio Relay");
4026 +MODULE_LICENSE("GPL");
4027 +
4028 +static int __init hostaudio_init_module(void)
4029 +{
4030 +        printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
4031 +              dsp, mixer);
4032 +
4033 +       module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
4034 +        if(module_data.dev_audio < 0){
4035 +                printk(KERN_ERR "hostaudio: couldn't register DSP device!\n");
4036 +                return -ENODEV;
4037 +        }
4038 +
4039 +       module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1);
4040 +        if(module_data.dev_mixer < 0){
4041 +                printk(KERN_ERR "hostmixer: couldn't register mixer "
4042 +                      "device!\n");
4043 +                unregister_sound_dsp(module_data.dev_audio);
4044 +                return -ENODEV;
4045 +        }
4046 +
4047 +        return 0;
4048 +}
4049 +
4050 +static void __exit hostaudio_cleanup_module (void)
4051 +{
4052 +       unregister_sound_mixer(module_data.dev_mixer);
4053 +       unregister_sound_dsp(module_data.dev_audio);
4054 +}
4055 +
4056 +module_init(hostaudio_init_module);
4057 +module_exit(hostaudio_cleanup_module);
4058 +
4059 +/*
4060 + * Overrides for Emacs so that we follow Linus's tabbing style.
4061 + * Emacs will notice this stuff at the end of the file and automatically
4062 + * adjust the settings for this buffer only.  This must remain at the end
4063 + * of the file.
4064 + * ---------------------------------------------------------------------------
4065 + * Local variables:
4066 + * c-file-style: "linux"
4067 + * End:
4068 + */
4069 Index: linux-2.4.29/arch/um/drivers/line.c
4070 ===================================================================
4071 --- linux-2.4.29.orig/arch/um/drivers/line.c    1970-01-01 03:00:00.000000000 +0300
4072 +++ linux-2.4.29/arch/um/drivers/line.c 2005-05-03 22:28:14.214449288 +0300
4073 @@ -0,0 +1,610 @@
4074 +/* 
4075 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4076 + * Licensed under the GPL
4077 + */
4078 +
4079 +#include "linux/sched.h"
4080 +#include "linux/slab.h"
4081 +#include "linux/list.h"
4082 +#include "linux/devfs_fs_kernel.h"
4083 +#include "asm/irq.h"
4084 +#include "asm/uaccess.h"
4085 +#include "chan_kern.h"
4086 +#include "irq_user.h"
4087 +#include "line.h"
4088 +#include "kern.h"
4089 +#include "user_util.h"
4090 +#include "kern_util.h"
4091 +#include "os.h"
4092 +#include "irq_kern.h"
4093 +
4094 +#define LINE_BUFSIZE 4096
4095 +
4096 +static void line_interrupt(int irq, void *data, struct pt_regs *unused)
4097 +{
4098 +       struct line *dev = data;
4099 +
4100 +       if(dev->count > 0) 
4101 +               chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, 
4102 +                              dev);
4103 +}
4104 +
4105 +static void line_timer_cb(void *arg)
4106 +{
4107 +       struct line *dev = arg;
4108 +
4109 +       line_interrupt(dev->driver->read_irq, dev, NULL);
4110 +}
4111 +
4112 +static int write_room(struct line *dev)
4113 +{
4114 +       int n;
4115 +
4116 +       if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
4117 +
4118 +       n = dev->head - dev->tail;
4119 +       if(n <= 0) n = LINE_BUFSIZE + n;
4120 +       return(n - 1);
4121 +}
4122 +
4123 +static int buffer_data(struct line *line, const char *buf, int len)
4124 +{
4125 +       int end, room;
4126 +
4127 +       if(line->buffer == NULL){
4128 +               line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
4129 +               if(line->buffer == NULL){
4130 +                       printk("buffer_data - atomic allocation failed\n");
4131 +                       return(0);
4132 +               }
4133 +               line->head = line->buffer;
4134 +               line->tail = line->buffer;
4135 +       }
4136 +
4137 +       room = write_room(line);
4138 +       len = (len > room) ? room : len;
4139 +
4140 +       end = line->buffer + LINE_BUFSIZE - line->tail;
4141 +       if(len < end){
4142 +               memcpy(line->tail, buf, len);
4143 +               line->tail += len;
4144 +       }
4145 +       else {
4146 +               memcpy(line->tail, buf, end);
4147 +               buf += end;
4148 +               len -= end;
4149 +               memcpy(line->buffer, buf, len);
4150 +               line->tail = line->buffer + len;
4151 +       }
4152 +
4153 +       return(len);
4154 +}
4155 +
4156 +static int flush_buffer(struct line *line)
4157 +{
4158 +       int n, count;
4159 +
4160 +       if((line->buffer == NULL) || (line->head == line->tail)) return(1);
4161 +
4162 +       if(line->tail < line->head){
4163 +               count = line->buffer + LINE_BUFSIZE - line->head;
4164 +               n = write_chan(&line->chan_list, line->head, count,
4165 +                              line->driver->write_irq);
4166 +               if(n < 0) return(n);
4167 +               if(n == count) line->head = line->buffer;
4168 +               else {
4169 +                       line->head += n;
4170 +                       return(0);
4171 +               }
4172 +       }
4173 +
4174 +       count = line->tail - line->head;
4175 +       n = write_chan(&line->chan_list, line->head, count, 
4176 +                      line->driver->write_irq);
4177 +       if(n < 0) return(n);
4178 +
4179 +       line->head += n;
4180 +       return(line->head == line->tail);
4181 +}
4182 +
4183 +int line_write(struct line *lines, struct tty_struct *tty, int from_user,
4184 +              const char *buf, int len)
4185 +{
4186 +       struct line *line;
4187 +       char *new;
4188 +       unsigned long flags;
4189 +       int n, err, i, ret = 0;
4190 +
4191 +       if(tty->stopped) return 0;
4192 +
4193 +       if(from_user){
4194 +               new = kmalloc(len, GFP_KERNEL);
4195 +               if(new == NULL)
4196 +                       return(0);
4197 +               n = copy_from_user(new, buf, len);
4198 +               buf = new;
4199 +               if(n == len){
4200 +                       len = -EFAULT;
4201 +                       goto out_free;
4202 +               }
4203 +
4204 +               len -= n;
4205 +       }
4206 +
4207 +       i = minor(tty->device) - tty->driver.minor_start;
4208 +       line = &lines[i];
4209 +
4210 +       down(&line->sem);
4211 +       if(line->head != line->tail){
4212 +               local_irq_save(flags);
4213 +               ret += buffer_data(line, buf, len);
4214 +               err = flush_buffer(line);
4215 +               local_irq_restore(flags);
4216 +               if(err <= 0)
4217 +                       goto out_up;
4218 +       }
4219 +       else {
4220 +               n = write_chan(&line->chan_list, buf, len, 
4221 +                              line->driver->write_irq);
4222 +               if(n < 0){
4223 +                       ret = n;
4224 +                       goto out_up;
4225 +               }
4226 +
4227 +               len -= n;
4228 +               ret += n;
4229 +               if(len > 0)
4230 +                       ret += buffer_data(line, buf + n, len);
4231 +       }
4232 + out_up:
4233 +       up(&line->sem);
4234 +
4235 + out_free:
4236 +       if(from_user)
4237 +               kfree(buf);
4238 +       return(ret);
4239 +}
4240 +
4241 +static void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
4242 +{
4243 +       struct line *dev = data;
4244 +       struct tty_struct *tty = dev->tty;
4245 +       int err;
4246 +
4247 +       err = flush_buffer(dev);
4248 +       if(err == 0) return;
4249 +       else if(err < 0){
4250 +               dev->head = dev->buffer;
4251 +               dev->tail = dev->buffer;
4252 +       }
4253 +
4254 +       if(tty == NULL) return;
4255 +
4256 +       if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
4257 +          (tty->ldisc.write_wakeup != NULL))
4258 +               (tty->ldisc.write_wakeup)(tty);
4259 +       
4260 +       /* BLOCKING mode
4261 +        * In blocking mode, everything sleeps on tty->write_wait.
4262 +        * Sleeping in the console driver would break non-blocking
4263 +        * writes.
4264 +        */
4265 +
4266 +       if (waitqueue_active(&tty->write_wait))
4267 +               wake_up_interruptible(&tty->write_wait);
4268 +
4269 +}
4270 +
4271 +int line_setup_irq(int fd, int input, int output, void *data)
4272 +{
4273 +       struct line *line = data;
4274 +       struct line_driver *driver = line->driver;
4275 +       int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
4276 +
4277 +       if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ, 
4278 +                                      line_interrupt, flags, 
4279 +                                      driver->read_irq_name, line);
4280 +       if(err) return(err);
4281 +       if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, 
4282 +                                       line_write_interrupt, flags, 
4283 +                                       driver->write_irq_name, line);
4284 +       line->have_irq = 1;
4285 +       return(err);
4286 +}
4287 +
4288 +void line_disable(struct line *line, int current_irq)
4289 +{
4290 +       if(!line->have_irq) return;
4291 +
4292 +       if(line->driver->read_irq == current_irq)
4293 +               free_irq_later(line->driver->read_irq, line);
4294 +       else
4295 +               free_irq(line->driver->read_irq, line);
4296 +
4297 +       if(line->driver->write_irq == current_irq)
4298 +               free_irq_later(line->driver->write_irq, line);
4299 +       else
4300 +               free_irq(line->driver->write_irq, line);
4301 +
4302 +       line->have_irq = 0;
4303 +}
4304 +
4305 +int line_open(struct line *lines, struct tty_struct *tty,
4306 +             struct chan_opts *opts)
4307 +{
4308 +       struct line *line;
4309 +       int n, err = 0;
4310 +
4311 +       if(tty == NULL) n = 0;
4312 +       else n = minor(tty->device) - tty->driver.minor_start;
4313 +       line = &lines[n];
4314 +
4315 +       down(&line->sem);
4316 +       if(line->count == 0){
4317 +               if(!line->valid){
4318 +                       err = -ENODEV;
4319 +                       goto out;
4320 +               }
4321 +               if(list_empty(&line->chan_list)){
4322 +                       err = parse_chan_pair(line->init_str, &line->chan_list,
4323 +                                             line->init_pri, n, opts);
4324 +                       if(err) goto out;
4325 +                       err = open_chan(&line->chan_list);
4326 +                       if(err) goto out;
4327 +               }
4328 +               enable_chan(&line->chan_list, line);
4329 +               INIT_TQUEUE(&line->task, line_timer_cb, line);
4330 +       }
4331 +
4332 +       if(!line->sigio){
4333 +               chan_enable_winch(&line->chan_list, line);
4334 +               line->sigio = 1;
4335 +       }
4336 +
4337 +       /* This is outside the if because the initial console is opened
4338 +        * with tty == NULL
4339 +        */
4340 +       line->tty = tty;
4341 +
4342 +       if(tty != NULL){
4343 +               tty->driver_data = line;
4344 +               chan_window_size(&line->chan_list, &tty->winsize.ws_row, 
4345 +                                &tty->winsize.ws_col);
4346 +       }
4347 +
4348 +       line->count++;
4349 + out:
4350 +       up(&line->sem);
4351 +       return(err);
4352 +}
4353 +
4354 +void line_close(struct line *lines, struct tty_struct *tty)
4355 +{
4356 +       struct line *line;
4357 +       int n;
4358 +
4359 +       if(tty == NULL) n = 0;
4360 +       else n = minor(tty->device) - tty->driver.minor_start;
4361 +       line = &lines[n];
4362 +
4363 +       down(&line->sem);
4364 +       line->count--;
4365 +
4366 +       /* I don't like this, but I can't think of anything better.  What's
4367 +        * going on is that the tty is in the process of being closed for
4368 +        * the last time.  Its count hasn't been dropped yet, so it's still
4369 +        * at 1.  This may happen when line->count != 0 because of the initial
4370 +        * console open (without a tty) bumping it up to 1.
4371 +        */
4372 +       if((line->tty != NULL) && (line->tty->count == 1))
4373 +               line->tty = NULL;
4374 +       if(line->count == 0)
4375 +               line_disable(line, -1);
4376 +       up(&line->sem);
4377 +}
4378 +
4379 +void close_lines(struct line *lines, int nlines)
4380 +{
4381 +       int i;
4382 +
4383 +       for(i = 0; i < nlines; i++)
4384 +               close_chan(&lines[i].chan_list);
4385 +}
4386 +
4387 +int line_setup(struct line *lines, int num, char *init, int all_allowed)
4388 +{
4389 +       int i, n;
4390 +       char *end;
4391 +
4392 +       if(*init == '=') n = -1;
4393 +       else {
4394 +               n = simple_strtoul(init, &end, 0);
4395 +               if(*end != '='){
4396 +                       printk(KERN_ERR "line_setup failed to parse \"%s\"\n", 
4397 +                              init);
4398 +                       return(0);
4399 +               }
4400 +               init = end;
4401 +       }
4402 +       init++;
4403 +       if((n >= 0) && (n >= num)){
4404 +               printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
4405 +                      n, num);
4406 +               return(0);
4407 +       }
4408 +       else if(n >= 0){
4409 +               if(lines[n].count > 0){
4410 +                       printk("line_setup - device %d is open\n", n);
4411 +                       return(0);
4412 +               }
4413 +               if(lines[n].init_pri <= INIT_ONE){
4414 +                       lines[n].init_pri = INIT_ONE;
4415 +                       if(!strcmp(init, "none")) lines[n].valid = 0;
4416 +                       else {
4417 +                               lines[n].init_str = init;
4418 +                               lines[n].valid = 1;
4419 +                       }       
4420 +               }
4421 +       }
4422 +       else if(!all_allowed){
4423 +               printk("line_setup - can't configure all devices from "
4424 +                      "mconsole\n");
4425 +               return(0);
4426 +       }
4427 +       else {
4428 +               for(i = 0; i < num; i++){
4429 +                       if(lines[i].init_pri <= INIT_ALL){
4430 +                               lines[i].init_pri = INIT_ALL;
4431 +                               if(!strcmp(init, "none")) lines[i].valid = 0;
4432 +                               else {
4433 +                                       lines[i].init_str = init;
4434 +                                       lines[i].valid = 1;
4435 +                               }
4436 +                       }
4437 +               }
4438 +       }
4439 +       return(1);
4440 +}
4441 +
4442 +int line_config(struct line *lines, int num, char *str)
4443 +{
4444 +       char *new = uml_strdup(str);
4445 +
4446 +       if(new == NULL){
4447 +               printk("line_config - uml_strdup failed\n");
4448 +               return(-ENOMEM);
4449 +       }
4450 +       return(!line_setup(lines, num, new, 0));
4451 +}
4452 +
4453 +int line_get_config(char *name, struct line *lines, int num, char *str, 
4454 +                   int size, char **error_out)
4455 +{
4456 +       struct line *line;
4457 +       char *end;
4458 +       int dev, n = 0;
4459 +
4460 +       dev = simple_strtoul(name, &end, 0);
4461 +       if((*end != '\0') || (end == name)){
4462 +               *error_out = "line_get_config failed to parse device number";
4463 +               return(0);
4464 +       }
4465 +
4466 +       if((dev < 0) || (dev >= num)){
4467 +               *error_out = "device number of of range";
4468 +               return(0);
4469 +       }
4470 +
4471 +       line = &lines[dev];
4472 +
4473 +       down(&line->sem);
4474 +       if(!line->valid)
4475 +               CONFIG_CHUNK(str, size, n, "none", 1);
4476 +       else if(line->count == 0)
4477 +               CONFIG_CHUNK(str, size, n, line->init_str, 1);
4478 +       else n = chan_config_string(&line->chan_list, str, size, error_out);
4479 +       up(&line->sem);
4480 +
4481 +       return(n);
4482 +}
4483 +
4484 +int line_remove(struct line *lines, int num, char *str)
4485 +{
4486 +       char config[sizeof("conxxxx=none\0")];
4487 +
4488 +       sprintf(config, "%s=none", str);
4489 +       return(!line_setup(lines, num, config, 0));
4490 +}
4491 +
4492 +static int line_write_room(struct tty_struct *tty)
4493 +{
4494 +       struct line *dev = tty->driver_data;
4495 +
4496 +       return(write_room(dev));
4497 +}
4498 +
4499 +void line_register_devfs(struct lines *set, struct line_driver *line_driver, 
4500 +                        struct tty_driver *driver, struct line *lines,
4501 +                        int nlines)
4502 +{
4503 +       int err, i, n;
4504 +       char *from, *to;
4505 +
4506 +       driver->driver_name = line_driver->name;
4507 +       driver->name = line_driver->devfs_name;
4508 +       driver->major = line_driver->major;
4509 +       driver->minor_start = line_driver->minor_start;
4510 +       driver->type = line_driver->type;
4511 +       driver->subtype = line_driver->subtype;
4512 +       driver->magic = TTY_DRIVER_MAGIC;
4513 +       driver->flags = TTY_DRIVER_REAL_RAW;
4514 +
4515 +       n = set->num;
4516 +       driver->num = n;
4517 +       driver->table = kmalloc(n * sizeof(driver->table[0]), GFP_KERNEL);
4518 +       driver->termios = kmalloc(n * sizeof(driver->termios[0]), GFP_KERNEL);
4519 +       driver->termios_locked = kmalloc(n * sizeof(driver->termios_locked[0]),
4520 +                                        GFP_KERNEL);
4521 +       if((driver->table == NULL) || (driver->termios == NULL) ||
4522 +          (driver->termios_locked == NULL))
4523 +               panic("Failed to allocate driver table");
4524 +
4525 +       memset(driver->table, 0, n * sizeof(driver->table[0]));
4526 +       memset(driver->termios, 0, n * sizeof(driver->termios[0]));
4527 +       memset(driver->termios_locked, 0, 
4528 +              n * sizeof(driver->termios_locked[0]));
4529 +
4530 +       driver->write_room = line_write_room;
4531 +       driver->init_termios = tty_std_termios;
4532 +
4533 +       if (tty_register_driver(driver))
4534 +               panic("line_register_devfs : Couldn't register driver\n");
4535 +
4536 +       from = line_driver->symlink_from;
4537 +       to = line_driver->symlink_to;
4538 +       err = devfs_mk_symlink(NULL, from, 0, to, NULL, NULL);
4539 +       if(err) printk("Symlink creation from /dev/%s to /dev/%s "
4540 +                      "returned %d\n", from, to, err);
4541 +
4542 +       for(i = 0; i < nlines; i++){
4543 +               if(!lines[i].valid) 
4544 +                       tty_unregister_devfs(driver, driver->minor_start + i);
4545 +       }
4546 +
4547 +       mconsole_register_dev(&line_driver->mc);
4548 +}
4549 +
4550 +void lines_init(struct line *lines, int nlines)
4551 +{
4552 +       struct line *line;
4553 +       int i;
4554 +
4555 +       for(i = 0; i < nlines; i++){
4556 +               line = &lines[i];
4557 +               INIT_LIST_HEAD(&line->chan_list);
4558 +               sema_init(&line->sem, 1);
4559 +               if(line->init_str != NULL){
4560 +                       line->init_str = uml_strdup(line->init_str);
4561 +                       if(line->init_str == NULL)
4562 +                               printk("lines_init - uml_strdup returned "
4563 +                                      "NULL\n");
4564 +               }
4565 +       }
4566 +}
4567 +
4568 +struct winch {
4569 +       struct list_head list;
4570 +       int fd;
4571 +       int tty_fd;
4572 +       int pid;
4573 +       struct line *line;
4574 +};
4575 +
4576 +void winch_interrupt(int irq, void *data, struct pt_regs *unused)
4577 +{
4578 +       struct winch *winch = data;
4579 +       struct tty_struct *tty;
4580 +       int err;
4581 +       char c;
4582 +
4583 +       if(winch->fd != -1){
4584 +               err = generic_read(winch->fd, &c, NULL);
4585 +               if(err < 0){
4586 +                       if(err != -EAGAIN){
4587 +                               printk("winch_interrupt : read failed, "
4588 +                                      "errno = %d\n", -err);
4589 +                               printk("fd %d is losing SIGWINCH support\n", 
4590 +                                      winch->tty_fd);
4591 +                               return;
4592 +                       }
4593 +                       goto out;
4594 +               }
4595 +       }
4596 +       tty = winch->line->tty;
4597 +       if(tty != NULL){
4598 +               chan_window_size(&winch->line->chan_list, 
4599 +                                &tty->winsize.ws_row, 
4600 +                                &tty->winsize.ws_col);
4601 +               kill_pg(tty->pgrp, SIGWINCH, 1);
4602 +       }
4603 + out:
4604 +       if(winch->fd != -1)
4605 +               reactivate_fd(winch->fd, WINCH_IRQ);
4606 +}
4607 +
4608 +DECLARE_MUTEX(winch_handler_sem);
4609 +LIST_HEAD(winch_handlers);
4610 +
4611 +void register_winch_irq(int fd, int tty_fd, int pid, void *line)
4612 +{
4613 +       struct winch *winch;
4614 +
4615 +       down(&winch_handler_sem);
4616 +       winch = kmalloc(sizeof(*winch), GFP_KERNEL);
4617 +       if(winch == NULL){
4618 +               printk("register_winch_irq - kmalloc failed\n");
4619 +               goto out;
4620 +       }
4621 +       *winch = ((struct winch) { .list        = LIST_HEAD_INIT(winch->list),
4622 +                                  .fd          = fd,
4623 +                                  .tty_fd      = tty_fd,
4624 +                                  .pid         = pid,
4625 +                                  .line        = line });
4626 +       list_add(&winch->list, &winch_handlers);
4627 +       if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 
4628 +                         SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
4629 +                         "winch", winch) < 0)
4630 +               printk("register_winch_irq - failed to register IRQ\n");
4631 + out:
4632 +       up(&winch_handler_sem);
4633 +}
4634 +
4635 +static void winch_cleanup(void)
4636 +{
4637 +       struct list_head *ele;
4638 +       struct winch *winch;
4639 +
4640 +       list_for_each(ele, &winch_handlers){
4641 +               winch = list_entry(ele, struct winch, list);
4642 +               if(winch->fd != -1){
4643 +                       deactivate_fd(winch->fd, WINCH_IRQ);
4644 +                       os_close_file(winch->fd);
4645 +               }
4646 +               if(winch->pid != -1) 
4647 +                       os_kill_process(winch->pid, 1);
4648 +       }
4649 +}
4650 +
4651 +__uml_exitcall(winch_cleanup);
4652 +
4653 +char *add_xterm_umid(char *base)
4654 +{
4655 +       char *umid, *title;
4656 +       int len;
4657 +
4658 +       umid = get_umid(1);
4659 +       if(umid == NULL) return(base);
4660 +       
4661 +       len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
4662 +       title = kmalloc(len, GFP_KERNEL);
4663 +       if(title == NULL){
4664 +               printk("Failed to allocate buffer for xterm title\n");
4665 +               return(base);
4666 +       }
4667 +
4668 +       strncpy(title, base, len);
4669 +       len -= strlen(title);
4670 +       snprintf(&title[strlen(title)], len, " (%s)", umid);
4671 +       return(title);
4672 +}
4673 +
4674 +/*
4675 + * Overrides for Emacs so that we follow Linus's tabbing style.
4676 + * Emacs will notice this stuff at the end of the file and automatically
4677 + * adjust the settings for this buffer only.  This must remain at the end
4678 + * of the file.
4679 + * ---------------------------------------------------------------------------
4680 + * Local variables:
4681 + * c-file-style: "linux"
4682 + * End:
4683 + */
4684 Index: linux-2.4.29/arch/um/drivers/Makefile
4685 ===================================================================
4686 --- linux-2.4.29.orig/arch/um/drivers/Makefile  1970-01-01 03:00:00.000000000 +0300
4687 +++ linux-2.4.29/arch/um/drivers/Makefile       2005-05-03 22:28:14.215449136 +0300
4688 @@ -0,0 +1,97 @@
4689 +# 
4690 +# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
4691 +# Licensed under the GPL
4692 +#
4693 +
4694 +O_TARGET := built-in.o 
4695 +
4696 +CHAN_OBJS := chan_kern.o chan_user.o line.o 
4697 +
4698 +list-multi := slip.o slirp.o daemon.o mcast.o mconsole.o net.o ubd.o \
4699 +       hostaudio.o pcap.o port.o harddog.o
4700 +
4701 +slip-objs := slip_kern.o slip_user.o
4702 +slirp-objs := slirp_kern.o slirp_user.o
4703 +daemon-objs := daemon_kern.o daemon_user.o
4704 +mcast-objs := mcast_kern.o mcast_user.o
4705 +pcap-objs := pcap_kern.o pcap_user.o
4706 +pcap-libs := -lpcap -L/usr/lib
4707 +net-objs := net_kern.o net_user.o
4708 +mconsole-objs := mconsole_kern.o mconsole_user.o
4709 +hostaudio-objs := hostaudio_kern.o
4710 +ubd-objs := ubd_kern.o ubd_user.o
4711 +port-objs := port_kern.o port_user.o
4712 +harddog-objs := harddog_kern.o harddog_user.o
4713 +
4714 +export-objs := mconsole_kern.o
4715 +
4716 +obj-y = 
4717 +obj-$(CONFIG_SSL) += ssl.o 
4718 +obj-$(CONFIG_UML_NET_SLIP) += slip.o
4719 +obj-$(CONFIG_UML_NET_SLIRP) += slirp.o
4720 +obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 
4721 +obj-$(CONFIG_UML_NET_MCAST) += mcast.o 
4722 +obj-$(CONFIG_UML_NET_PCAP) += pcap.o 
4723 +obj-$(CONFIG_UML_NET) += net.o 
4724 +obj-$(CONFIG_MCONSOLE) += mconsole.o
4725 +obj-$(CONFIG_MMAPPER) += mmapper_kern.o 
4726 +obj-$(CONFIG_BLK_DEV_UBD) += ubd.o 
4727 +obj-$(CONFIG_HOSTAUDIO) += hostaudio.o
4728 +obj-$(CONFIG_FD_CHAN) += fd.o 
4729 +obj-$(CONFIG_NULL_CHAN) += null.o 
4730 +obj-$(CONFIG_PORT_CHAN) += port.o
4731 +obj-$(CONFIG_PTY_CHAN) += pty.o
4732 +obj-$(CONFIG_TTY_CHAN) += tty.o 
4733 +obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
4734 +obj-$(CONFIG_UML_WATCHDOG) += harddog.o
4735 +obj-$(CONFIG_COW) += cow_kern.o
4736 +obj-$(CONFIG_COW_COMMON) += cow_user.o
4737 +
4738 +CFLAGS_pcap_user.o = -I/usr/include/pcap
4739 +
4740 +obj-y += stdio_console.o $(CHAN_OBJS)
4741 +
4742 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
4743 +
4744 +USER_OBJS = $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
4745 +       null.o pty.o tty.o xterm.o
4746 +
4747 +include $(TOPDIR)/Rules.make
4748 +
4749 +$(USER_OBJS) : %.o: %.c
4750 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
4751 +
4752 +clean:
4753 +
4754 +modules:
4755 +
4756 +fastdep:
4757 +
4758 +dep:
4759 +
4760 +archmrproper:
4761 +
4762 +daemon.o : $(daemon-objs)
4763 +
4764 +slip.o : $(slip-objs)
4765 +
4766 +slirp.o : $(slirp-objs)
4767 +
4768 +mcast.o : $(mcast-objs)
4769 +
4770 +pcap.o : $(pcap-objs)
4771 +
4772 +mconsole.o : $(mconsole-objs)
4773 +
4774 +net.o : $(net-objs)
4775 +
4776 +hostaudio.o : $(hostaudio-objs)
4777 +
4778 +ubd.o : $(ubd-objs)
4779 +
4780 +port.o : $(port-objs)
4781 +
4782 +harddog.o : $(harddog-objs)
4783 +
4784 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
4785 +       $(LD) -r -o $@ $($(patsubst %.o,%,$@)-objs) $($(patsubst %.o,%,$@)-libs)
4786 Index: linux-2.4.29/arch/um/drivers/mcast.h
4787 ===================================================================
4788 --- linux-2.4.29.orig/arch/um/drivers/mcast.h   1970-01-01 03:00:00.000000000 +0300
4789 +++ linux-2.4.29/arch/um/drivers/mcast.h        2005-05-03 22:28:14.000000000 +0300
4790 @@ -0,0 +1,30 @@
4791 +/* 
4792 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
4793 + * Licensed under the GPL
4794 + */
4795 +
4796 +#include "net_user.h"
4797 +
4798 +struct mcast_data {
4799 +       char *addr;
4800 +       unsigned short port;
4801 +       void *mcast_addr;
4802 +       int ttl;
4803 +       void *dev;
4804 +};
4805 +
4806 +extern struct net_user_info mcast_user_info;
4807 +
4808 +extern int mcast_user_write(int fd, void *buf, int len, 
4809 +                           struct mcast_data *pri);
4810 +
4811 +/*
4812 + * Overrides for Emacs so that we follow Linus's tabbing style.
4813 + * Emacs will notice this stuff at the end of the file and automatically
4814 + * adjust the settings for this buffer only.  This must remain at the end
4815 + * of the file.
4816 + * ---------------------------------------------------------------------------
4817 + * Local variables:
4818 + * c-file-style: "linux"
4819 + * End:
4820 + */
4821 Index: linux-2.4.29/arch/um/drivers/mcast_kern.c
4822 ===================================================================
4823 --- linux-2.4.29.orig/arch/um/drivers/mcast_kern.c      1970-01-01 03:00:00.000000000 +0300
4824 +++ linux-2.4.29/arch/um/drivers/mcast_kern.c   2005-05-03 22:28:14.000000000 +0300
4825 @@ -0,0 +1,145 @@
4826 +/*
4827 + * user-mode-linux networking multicast transport
4828 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4829 + *
4830 + * based on the existing uml-networking code, which is
4831 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
4832 + * James Leu (jleu@mindspring.net).
4833 + * Copyright (C) 2001 by various other people who didn't put their name here.
4834 + *
4835 + * Licensed under the GPL.
4836 + */
4837 +
4838 +#include "linux/kernel.h"
4839 +#include "linux/init.h"
4840 +#include "linux/netdevice.h"
4841 +#include "linux/etherdevice.h"
4842 +#include "linux/in.h"
4843 +#include "linux/inet.h"
4844 +#include "net_kern.h"
4845 +#include "net_user.h"
4846 +#include "mcast.h"
4847 +
4848 +struct mcast_init {
4849 +       char *addr;
4850 +       int port;
4851 +       int ttl;
4852 +};
4853 +
4854 +void mcast_init(struct net_device *dev, void *data)
4855 +{
4856 +       struct uml_net_private *pri;
4857 +       struct mcast_data *dpri;
4858 +       struct mcast_init *init = data;
4859 +
4860 +       init_etherdev(dev, 0);
4861 +       pri = dev->priv;
4862 +       dpri = (struct mcast_data *) pri->user;
4863 +       *dpri = ((struct mcast_data)
4864 +               { .addr         = init->addr,
4865 +                 .port         = init->port,
4866 +                 .ttl          = init->ttl,
4867 +                 .mcast_addr   = NULL,
4868 +                 .dev          = dev });
4869 +       printk("mcast backend ");
4870 +       printk("multicast adddress: %s:%u, TTL:%u ",
4871 +              dpri->addr, dpri->port, dpri->ttl);
4872 +
4873 +       printk("\n");
4874 +}
4875 +
4876 +static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
4877 +{
4878 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
4879 +       if(*skb == NULL) return(-ENOMEM);
4880 +       return(net_recvfrom(fd, (*skb)->mac.raw, 
4881 +                           (*skb)->dev->mtu + ETH_HEADER_OTHER));
4882 +}
4883 +
4884 +static int mcast_write(int fd, struct sk_buff **skb,
4885 +                       struct uml_net_private *lp)
4886 +{
4887 +       return mcast_user_write(fd, (*skb)->data, (*skb)->len, 
4888 +                                (struct mcast_data *) &lp->user);
4889 +}
4890 +
4891 +static struct net_kern_info mcast_kern_info = {
4892 +       .init                   = mcast_init,
4893 +       .protocol               = eth_protocol,
4894 +       .read                   = mcast_read,
4895 +       .write                  = mcast_write,
4896 +};
4897 +
4898 +int mcast_setup(char *str, char **mac_out, void *data)
4899 +{
4900 +       struct mcast_init *init = data;
4901 +       char *port_str = NULL, *ttl_str = NULL, *remain;
4902 +       char *last;
4903 +       int n;
4904 +
4905 +       *init = ((struct mcast_init)
4906 +               { .addr         = "239.192.168.1",
4907 +                 .port         = 1102,
4908 +                 .ttl          = 1 });
4909 +
4910 +       remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
4911 +                              NULL);
4912 +       if(remain != NULL){
4913 +               printk(KERN_ERR "mcast_setup - Extra garbage on "
4914 +                      "specification : '%s'\n", remain);
4915 +               return(0);
4916 +       }
4917 +       
4918 +       if(port_str != NULL){
4919 +               n = simple_strtoul(port_str, &last, 10);
4920 +               if((*last != '\0') || (last == port_str)){
4921 +                       printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", 
4922 +                              port_str);
4923 +                       return(0);
4924 +               }
4925 +               init->port = htons(n);
4926 +       }
4927 +
4928 +       if(ttl_str != NULL){
4929 +               init->ttl = simple_strtoul(ttl_str, &last, 10);
4930 +               if((*last != '\0') || (last == ttl_str)){
4931 +                       printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n", 
4932 +                              ttl_str);
4933 +                       return(0);
4934 +               }
4935 +       }
4936 +
4937 +       printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
4938 +              init->port, init->ttl);
4939 +
4940 +       return(1);
4941 +}
4942 +
4943 +static struct transport mcast_transport = {
4944 +       .list           = LIST_HEAD_INIT(mcast_transport.list),
4945 +       .name           = "mcast",
4946 +       .setup          = mcast_setup,
4947 +       .user           = &mcast_user_info,
4948 +       .kern           = &mcast_kern_info,
4949 +       .private_size   = sizeof(struct mcast_data),
4950 +       .setup_size     = sizeof(struct mcast_init),
4951 +};
4952 +
4953 +static int register_mcast(void)
4954 +{
4955 +       register_transport(&mcast_transport);
4956 +       return(1);
4957 +}
4958 +
4959 +__initcall(register_mcast);
4960 +
4961 +/*
4962 + * Overrides for Emacs so that we follow Linus's tabbing style.
4963 + * Emacs will notice this stuff at the end of the file and automatically
4964 + * adjust the settings for this buffer only.  This must remain at the end
4965 + * of the file.
4966 + * ---------------------------------------------------------------------------
4967 + * Local variables:
4968 + * c-file-style: "linux"
4969 + * End:
4970 + */
4971 Index: linux-2.4.29/arch/um/drivers/mcast_user.c
4972 ===================================================================
4973 --- linux-2.4.29.orig/arch/um/drivers/mcast_user.c      1970-01-01 03:00:00.000000000 +0300
4974 +++ linux-2.4.29/arch/um/drivers/mcast_user.c   2005-05-03 22:28:14.000000000 +0300
4975 @@ -0,0 +1,177 @@
4976 +/*
4977 + * user-mode-linux networking multicast transport
4978 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4979 + *
4980 + * based on the existing uml-networking code, which is
4981 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
4982 + * James Leu (jleu@mindspring.net).
4983 + * Copyright (C) 2001 by various other people who didn't put their name here.
4984 + *
4985 + * Licensed under the GPL.
4986 + *
4987 + */
4988 +
4989 +#include <errno.h>
4990 +#include <unistd.h>
4991 +#include <linux/inet.h>
4992 +#include <sys/socket.h>
4993 +#include <sys/un.h>
4994 +#include <sys/time.h>
4995 +#include <netinet/in.h>
4996 +#include "net_user.h"
4997 +#include "mcast.h"
4998 +#include "kern_util.h"
4999 +#include "user_util.h"
5000 +#include "user.h"
5001 +#include "os.h"
5002 +
5003 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
5004 +
5005 +static struct sockaddr_in *new_addr(char *addr, unsigned short port)
5006 +{
5007 +       struct sockaddr_in *sin;
5008 +
5009 +       sin = um_kmalloc(sizeof(struct sockaddr_in));
5010 +       if(sin == NULL){
5011 +               printk("new_addr: allocation of sockaddr_in failed\n");
5012 +               return(NULL);
5013 +       }
5014 +       sin->sin_family = AF_INET;
5015 +       sin->sin_addr.s_addr = in_aton(addr);
5016 +       sin->sin_port = port;
5017 +       return(sin);
5018 +}
5019 +
5020 +static void mcast_user_init(void *data, void *dev)
5021 +{
5022 +       struct mcast_data *pri = data;
5023 +
5024 +       pri->mcast_addr = new_addr(pri->addr, pri->port);
5025 +       pri->dev = dev;
5026 +}
5027 +
5028 +static int mcast_open(void *data)
5029 +{
5030 +       struct mcast_data *pri = data;
5031 +       struct sockaddr_in *sin = pri->mcast_addr;
5032 +       struct ip_mreq mreq;
5033 +       int fd, yes = 1;
5034 +
5035 +
5036 +       if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) {
5037 +               fd = -EINVAL;
5038 +               goto out;
5039 +       }
5040 +
5041 +       fd = socket(AF_INET, SOCK_DGRAM, 0);
5042 +       if (fd < 0){
5043 +               printk("mcast_open : data socket failed, errno = %d\n", 
5044 +                      errno);
5045 +               fd = -ENOMEM;
5046 +               goto out;
5047 +       }
5048 +
5049 +       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
5050 +               printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
5051 +                       errno);
5052 +               os_close_file(fd);
5053 +               fd = -EINVAL;
5054 +               goto out;
5055 +       }
5056 +
5057 +       /* set ttl according to config */
5058 +       if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
5059 +                      sizeof(pri->ttl)) < 0) {
5060 +               printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
5061 +                       errno);
5062 +               os_close_file(fd);
5063 +               fd = -EINVAL;
5064 +               goto out;
5065 +       }
5066 +
5067 +       /* set LOOP, so data does get fed back to local sockets */
5068 +       if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
5069 +               printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
5070 +                       errno);
5071 +               os_close_file(fd);
5072 +               fd = -EINVAL;
5073 +               goto out;
5074 +       }
5075 +
5076 +       /* bind socket to mcast address */
5077 +       if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
5078 +               printk("mcast_open : data bind failed, errno = %d\n", errno);
5079 +               os_close_file(fd);
5080 +               fd = -EINVAL;
5081 +               goto out;
5082 +       }               
5083 +       
5084 +       /* subscribe to the multicast group */
5085 +       mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
5086 +       mreq.imr_interface.s_addr = 0;
5087 +       if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, 
5088 +                      &mreq, sizeof(mreq)) < 0) {
5089 +               printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n",
5090 +                       errno);
5091 +               printk("There appears not to be a multicast-capable network "
5092 +                      "interface on the host.\n");
5093 +               printk("eth0 should be configured in order to use the "
5094 +                      "multicast transport.\n");
5095 +               os_close_file(fd);
5096 +               fd = -EINVAL;
5097 +       }
5098 +
5099 + out:
5100 +       return(fd);
5101 +}
5102 +
5103 +static void mcast_close(int fd, void *data)
5104 +{
5105 +       struct ip_mreq mreq;
5106 +       struct mcast_data *pri = data;
5107 +       struct sockaddr_in *sin = pri->mcast_addr;
5108 +
5109 +       mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
5110 +       mreq.imr_interface.s_addr = 0;
5111 +       if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
5112 +                      &mreq, sizeof(mreq)) < 0) {
5113 +               printk("mcast_open: IP_DROP_MEMBERSHIP failed, error = %d\n",
5114 +                       errno);
5115 +       }
5116 +
5117 +       os_close_file(fd);
5118 +}
5119 +
5120 +int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
5121 +{
5122 +       struct sockaddr_in *data_addr = pri->mcast_addr;
5123 +
5124 +       return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
5125 +}
5126 +
5127 +static int mcast_set_mtu(int mtu, void *data)
5128 +{
5129 +       return(mtu);
5130 +}
5131 +
5132 +struct net_user_info mcast_user_info = {
5133 +       .init           = mcast_user_init,
5134 +       .open           = mcast_open,
5135 +       .close          = mcast_close,
5136 +       .remove         = NULL,
5137 +       .set_mtu        = mcast_set_mtu,
5138 +       .add_address    = NULL,
5139 +       .delete_address = NULL,
5140 +       .max_packet     = MAX_PACKET - ETH_HEADER_OTHER
5141 +};
5142 +
5143 +/*
5144 + * Overrides for Emacs so that we follow Linus's tabbing style.
5145 + * Emacs will notice this stuff at the end of the file and automatically
5146 + * adjust the settings for this buffer only.  This must remain at the end
5147 + * of the file.
5148 + * ---------------------------------------------------------------------------
5149 + * Local variables:
5150 + * c-file-style: "linux"
5151 + * End:
5152 + */
5153 Index: linux-2.4.29/arch/um/drivers/mconsole_kern.c
5154 ===================================================================
5155 --- linux-2.4.29.orig/arch/um/drivers/mconsole_kern.c   1970-01-01 03:00:00.000000000 +0300
5156 +++ linux-2.4.29/arch/um/drivers/mconsole_kern.c        2005-05-03 22:28:14.222448072 +0300
5157 @@ -0,0 +1,560 @@
5158 +/*
5159 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
5160 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
5161 + * Licensed under the GPL
5162 + */
5163 +
5164 +#include "linux/kernel.h"
5165 +#include "linux/slab.h"
5166 +#include "linux/init.h"
5167 +#include "linux/notifier.h"
5168 +#include "linux/reboot.h"
5169 +#include "linux/utsname.h"
5170 +#include "linux/ctype.h"
5171 +#include "linux/interrupt.h"
5172 +#include "linux/sysrq.h"
5173 +#include "linux/tqueue.h"
5174 +#include "linux/module.h"
5175 +#include "linux/file.h"
5176 +#include "linux/fs.h"
5177 +#include "linux/proc_fs.h"
5178 +#include "asm/irq.h"
5179 +#include "asm/uaccess.h"
5180 +#include "user_util.h"
5181 +#include "kern_util.h"
5182 +#include "kern.h"
5183 +#include "mconsole.h"
5184 +#include "mconsole_kern.h"
5185 +#include "irq_user.h"
5186 +#include "init.h"
5187 +#include "os.h"
5188 +#include "umid.h"
5189 +#include "irq_kern.h"
5190 +
5191 +static int do_unlink_socket(struct notifier_block *notifier, 
5192 +                           unsigned long what, void *data)
5193 +{
5194 +       return(mconsole_unlink_socket());
5195 +}
5196 +
5197 +
5198 +static struct notifier_block reboot_notifier = {
5199 +       .notifier_call          = do_unlink_socket,
5200 +       .priority               = 0,
5201 +};
5202 +
5203 +/* Safe without explicit locking for now.  Tasklets provide their own 
5204 + * locking, and the interrupt handler is safe because it can't interrupt
5205 + * itself and it can only happen on CPU 0.
5206 + */
5207 +
5208 +LIST_HEAD(mc_requests);
5209 +
5210 +static void mc_task_proc(void *unused)
5211 +{
5212 +       struct mconsole_entry *req;
5213 +       unsigned long flags;
5214 +
5215 +       while(!list_empty(&mc_requests)){
5216 +               local_irq_save(flags);
5217 +               req = list_entry(mc_requests.next, struct mconsole_entry, 
5218 +                                list);
5219 +               list_del(&req->list);
5220 +               local_irq_restore(flags);
5221 +               req->request.cmd->handler(&req->request);
5222 +               kfree(req);
5223 +       }
5224 +}
5225 +
5226 +struct tq_struct mconsole_task = {
5227 +       .routine        = mc_task_proc,
5228 +       .data           = NULL
5229 +};
5230 +
5231 +static void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
5232 +{
5233 +       int fd;
5234 +       struct mconsole_entry *new;
5235 +       struct mc_request req;
5236 +
5237 +       fd = (int) dev_id;
5238 +       while (mconsole_get_request(fd, &req)){
5239 +               if(req.cmd->context == MCONSOLE_INTR) 
5240 +                       (*req.cmd->handler)(&req);
5241 +               else {
5242 +                       new = kmalloc(sizeof(*new), GFP_ATOMIC);
5243 +                       if(new == NULL)
5244 +                               mconsole_reply(&req, "Out of memory", 1, 0);
5245 +                       else {
5246 +                               new->request = req;
5247 +                               list_add(&new->list, &mc_requests);
5248 +                       }
5249 +               }
5250 +       }
5251 +
5252 +       if(!list_empty(&mc_requests))
5253 +               schedule_task(&mconsole_task);
5254 +       reactivate_fd(fd, MCONSOLE_IRQ);
5255 +}
5256 +
5257 +void mconsole_version(struct mc_request *req)
5258 +{
5259 +       char version[256];
5260 +
5261 +       sprintf(version, "%s %s %s %s %s", system_utsname.sysname, 
5262 +               system_utsname.nodename, system_utsname.release, 
5263 +               system_utsname.version, system_utsname.machine);
5264 +       mconsole_reply(req, version, 0, 0);
5265 +}
5266 +
5267 +void mconsole_log(struct mc_request *req)
5268 +{
5269 +       int len;
5270 +       char *ptr = req->request.data;
5271 +       
5272 +       ptr += strlen("log ");
5273 +
5274 +       len = req->len - (ptr - req->request.data);
5275 +       printk("%.*s", len, ptr);
5276 +       mconsole_reply(req, "", 0, 0);
5277 +}
5278 +
5279 +void mconsole_proc(struct mc_request *req)
5280 +{
5281 +       struct nameidata nd;
5282 +       struct file_system_type *proc;
5283 +       struct super_block *super;
5284 +       struct file *file;
5285 +       int n, err;
5286 +       char *ptr = req->request.data, *buf;
5287 +       
5288 +       ptr += strlen("proc");
5289 +       while(isspace(*ptr)) ptr++;
5290 +
5291 +       proc = get_fs_type("proc");
5292 +       if(proc == NULL){
5293 +               mconsole_reply(req, "procfs not registered", 1, 0);
5294 +               goto out;
5295 +       }
5296 +
5297 +       super = get_anon_super(proc, NULL, NULL);
5298 +       if(super == NULL){
5299 +               mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
5300 +               goto out_put;
5301 +       }
5302 +
5303 +       if(super->s_root == NULL){
5304 +               super = (*proc->read_super)(super, NULL, 0);
5305 +               if(super == NULL){
5306 +                       mconsole_reply(req, "Failed to read superblock", 1, 0);
5307 +                       goto out_put;
5308 +               }
5309 +       }
5310 +       up_write(&super->s_umount);
5311 +
5312 +       nd.dentry = super->s_root;
5313 +       nd.mnt = NULL;
5314 +       nd.flags = O_RDONLY + 1;
5315 +       nd.last_type = LAST_ROOT;
5316 +
5317 +       err = link_path_walk(ptr, &nd);
5318 +       if(err){
5319 +               mconsole_reply(req, "Failed to look up file", 1, 0);
5320 +               goto out_kill;
5321 +       }
5322 +
5323 +       file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
5324 +       if(IS_ERR(file)){
5325 +               mconsole_reply(req, "Failed to open file", 1, 0);
5326 +               goto out_kill;
5327 +       }
5328 +
5329 +       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
5330 +       if(buf == NULL){
5331 +               mconsole_reply(req, "Failed to allocate buffer", 1, 0);
5332 +               goto out_fput;
5333 +       }
5334 +
5335 +       if((file->f_op != NULL) && (file->f_op->read != NULL)){
5336 +               do {
5337 +                       n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, 
5338 +                                               &file->f_pos);
5339 +                       if(n >= 0){
5340 +                               buf[n] = '\0';
5341 +                               mconsole_reply(req, buf, 0, (n > 0));
5342 +                       }
5343 +                       else {
5344 +                               mconsole_reply(req, "Read of file failed", 
5345 +                                              1, 0);
5346 +                               goto out_free;
5347 +                       }
5348 +               } while(n > 0);
5349 +       }
5350 +       else mconsole_reply(req, "", 0, 0);
5351 +
5352 + out_free:
5353 +       kfree(buf);
5354 + out_fput:
5355 +       fput(file);
5356 + out_kill:
5357 +       kill_super(super);
5358 + out_put:
5359 +       /* put_filesystem(proc); */
5360 + out: ;
5361 +}
5362 +
5363 +#define UML_MCONSOLE_HELPTEXT \
5364 +"Commands: \n\
5365 +    version - Get kernel version \n\
5366 +    help - Print this message \n\
5367 +    halt - Halt UML \n\
5368 +    reboot - Reboot UML \n\
5369 +    config <dev>=<config> - Add a new device to UML;  \n\
5370 +       same syntax as command line \n\
5371 +    config <dev> - Query the configuration of a device \n\
5372 +    remove <dev> - Remove a device from UML \n\
5373 +    sysrq <letter> - Performs the SysRq action controlled by the letter \n\
5374 +    cad - invoke the Ctl-Alt-Del handler \n\
5375 +    stop - pause the UML; it will do nothing until it receives a 'go' \n\
5376 +    go - continue the UML after a 'stop' \n\
5377 +    log <string> - make UML enter <string> into the kernel log\n\
5378 +    proc <file> - returns the contents of the UML's /proc/<file>\n\
5379 +"
5380 +
5381 +void mconsole_help(struct mc_request *req)
5382 +{
5383 +       mconsole_reply(req, UML_MCONSOLE_HELPTEXT, 0, 0);
5384 +}
5385 +
5386 +void mconsole_halt(struct mc_request *req)
5387 +{
5388 +       mconsole_reply(req, "", 0, 0);
5389 +       machine_halt();
5390 +}
5391 +
5392 +void mconsole_reboot(struct mc_request *req)
5393 +{
5394 +       mconsole_reply(req, "", 0, 0);
5395 +       machine_restart(NULL);
5396 +}
5397 +
5398 +extern void ctrl_alt_del(void);
5399 +
5400 +void mconsole_cad(struct mc_request *req)
5401 +{
5402 +       mconsole_reply(req, "", 0, 0);
5403 +       ctrl_alt_del();
5404 +}
5405 +
5406 +void mconsole_go(struct mc_request *req)
5407 +{
5408 +       mconsole_reply(req, "Not stopped", 1, 0);
5409 +}
5410 +
5411 +void mconsole_stop(struct mc_request *req)
5412 +{
5413 +       deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
5414 +       os_set_fd_block(req->originating_fd, 1);
5415 +       mconsole_reply(req, "", 0, 0);
5416 +       while(mconsole_get_request(req->originating_fd, req)){
5417 +               if(req->cmd->handler == mconsole_go) break;
5418 +               (*req->cmd->handler)(req);
5419 +       }
5420 +       os_set_fd_block(req->originating_fd, 0);
5421 +       reactivate_fd(req->originating_fd, MCONSOLE_IRQ);
5422 +       mconsole_reply(req, "", 0, 0);
5423 +}
5424 +
5425 +/* This list is populated by __initcall routines. */
5426 +
5427 +LIST_HEAD(mconsole_devices);
5428 +
5429 +void mconsole_register_dev(struct mc_device *new)
5430 +{
5431 +       list_add(&new->list, &mconsole_devices);
5432 +}
5433 +
5434 +static struct mc_device *mconsole_find_dev(char *name)
5435 +{
5436 +       struct list_head *ele;
5437 +       struct mc_device *dev;
5438 +
5439 +       list_for_each(ele, &mconsole_devices){
5440 +               dev = list_entry(ele, struct mc_device, list);
5441 +               if(!strncmp(name, dev->name, strlen(dev->name)))
5442 +                       return(dev);
5443 +       }
5444 +       return(NULL);
5445 +}
5446 +
5447 +#define CONFIG_BUF_SIZE 64
5448 +
5449 +static void mconsole_get_config(int (*get_config)(char *, char *, int, 
5450 +                                                 char **),
5451 +                               struct mc_request *req, char *name)
5452 +{
5453 +       char default_buf[CONFIG_BUF_SIZE], *error, *buf;
5454 +       int n, size;
5455 +
5456 +       if(get_config == NULL){
5457 +               mconsole_reply(req, "No get_config routine defined", 1, 0);
5458 +               return;
5459 +       }
5460 +
5461 +       error = NULL;
5462 +       size = sizeof(default_buf)/sizeof(default_buf[0]);
5463 +       buf = default_buf;
5464 +
5465 +       while(1){
5466 +               n = (*get_config)(name, buf, size, &error);
5467 +               if(error != NULL){
5468 +                       mconsole_reply(req, error, 1, 0);
5469 +                       goto out;
5470 +               }
5471 +
5472 +               if(n <= size){
5473 +                       mconsole_reply(req, buf, 0, 0);
5474 +                       goto out;
5475 +               }
5476 +
5477 +               if(buf != default_buf)
5478 +                       kfree(buf);
5479 +
5480 +               size = n;
5481 +               buf = kmalloc(size, GFP_KERNEL);
5482 +               if(buf == NULL){
5483 +                       mconsole_reply(req, "Failed to allocate buffer", 1, 0);
5484 +                       return;
5485 +               }
5486 +       }
5487 + out:
5488 +       if(buf != default_buf)
5489 +               kfree(buf);
5490 +       
5491 +}
5492 +
5493 +void mconsole_config(struct mc_request *req)
5494 +{
5495 +       struct mc_device *dev;
5496 +       char *ptr = req->request.data, *name;
5497 +       int err;
5498 +
5499 +       ptr += strlen("config");
5500 +       while(isspace(*ptr)) ptr++;
5501 +       dev = mconsole_find_dev(ptr);
5502 +       if(dev == NULL){
5503 +               mconsole_reply(req, "Bad configuration option", 1, 0);
5504 +               return;
5505 +       }
5506 +
5507 +       name = &ptr[strlen(dev->name)];
5508 +       ptr = name;
5509 +       while((*ptr != '=') && (*ptr != '\0'))
5510 +               ptr++;
5511 +
5512 +       if(*ptr == '='){
5513 +               err = (*dev->config)(name);
5514 +               mconsole_reply(req, "", err, 0);
5515 +       }
5516 +       else mconsole_get_config(dev->get_config, req, name);
5517 +}
5518 +
5519 +void mconsole_remove(struct mc_request *req)
5520 +{
5521 +       struct mc_device *dev;  
5522 +       char *ptr = req->request.data;
5523 +       int err;
5524 +
5525 +       ptr += strlen("remove");
5526 +       while(isspace(*ptr)) ptr++;
5527 +       dev = mconsole_find_dev(ptr);
5528 +       if(dev == NULL){
5529 +               mconsole_reply(req, "Bad remove option", 1, 0);
5530 +               return;
5531 +       }
5532 +       err = (*dev->remove)(&ptr[strlen(dev->name)]);
5533 +       mconsole_reply(req, "", err, 0);
5534 +}
5535 +
5536 +#ifdef CONFIG_MAGIC_SYSRQ
5537 +void mconsole_sysrq(struct mc_request *req)
5538 +{
5539 +       char *ptr = req->request.data;
5540 +
5541 +       ptr += strlen("sysrq");
5542 +       while(isspace(*ptr)) ptr++;
5543 +
5544 +       mconsole_reply(req, "", 0, 0);
5545 +       handle_sysrq(*ptr, &current->thread.regs, NULL, NULL);
5546 +}
5547 +#else
5548 +void mconsole_sysrq(struct mc_request *req)
5549 +{
5550 +       mconsole_reply(req, "Sysrq not compiled in", 1, 0);
5551 +}
5552 +#endif
5553 +
5554 +/* Changed by mconsole_setup, which is __setup, and called before SMP is
5555 + * active.
5556 + */
5557 +static char *notify_socket = NULL; 
5558 +
5559 +int mconsole_init(void)
5560 +{
5561 +       int err, sock;
5562 +       char file[256];
5563 +
5564 +       if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
5565 +       snprintf(mconsole_socket_name, sizeof(file), "%s", file);
5566 +
5567 +       sock = os_create_unix_socket(file, sizeof(file), 1);
5568 +       if (sock < 0){
5569 +               printk("Failed to initialize management console\n");
5570 +               return(1);
5571 +       }
5572 +
5573 +       register_reboot_notifier(&reboot_notifier);
5574 +
5575 +       err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
5576 +                            SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
5577 +                            "mconsole", (void *)sock);
5578 +       if (err){
5579 +               printk("Failed to get IRQ for management console\n");
5580 +               return(1);
5581 +       }
5582 +
5583 +       if(notify_socket != NULL){
5584 +               notify_socket = uml_strdup(notify_socket);
5585 +               if(notify_socket != NULL)
5586 +                       mconsole_notify(notify_socket, MCONSOLE_SOCKET,
5587 +                                       mconsole_socket_name, 
5588 +                                       strlen(mconsole_socket_name) + 1);
5589 +               else printk(KERN_ERR "mconsole_setup failed to strdup "
5590 +                           "string\n");
5591 +       }
5592 +
5593 +       printk("mconsole (version %d) initialized on %s\n", 
5594 +              MCONSOLE_VERSION, mconsole_socket_name);
5595 +       return(0);
5596 +}
5597 +
5598 +__initcall(mconsole_init);
5599 +
5600 +static int write_proc_mconsole(struct file *file, const char *buffer,
5601 +                              unsigned long count, void *data)
5602 +{
5603 +       char *buf;
5604 +
5605 +       buf = kmalloc(count + 1, GFP_KERNEL);
5606 +       if(buf == NULL) 
5607 +               return(-ENOMEM);
5608 +
5609 +       if(copy_from_user(buf, buffer, count)){
5610 +               count = -EFAULT;
5611 +               goto out;
5612 +       }
5613 +
5614 +       buf[count] = '\0';
5615 +
5616 +       mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
5617 + out:
5618 +       kfree(buf);
5619 +       return(count);
5620 +}
5621 +
5622 +static int create_proc_mconsole(void)
5623 +{
5624 +       struct proc_dir_entry *ent;
5625 +
5626 +       if(notify_socket == NULL) return(0);
5627 +
5628 +       ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
5629 +       if(ent == NULL){
5630 +               printk("create_proc_mconsole : create_proc_entry failed\n");
5631 +               return(0);
5632 +       }
5633 +
5634 +       ent->read_proc = NULL;
5635 +       ent->write_proc = write_proc_mconsole;
5636 +       return(0);
5637 +}
5638 +
5639 +static spinlock_t notify_spinlock = SPIN_LOCK_UNLOCKED;
5640 +
5641 +void lock_notify(void)
5642 +{
5643 +       spin_lock(&notify_spinlock);
5644 +}
5645 +
5646 +void unlock_notify(void)
5647 +{
5648 +       spin_unlock(&notify_spinlock);
5649 +}
5650 +
5651 +__initcall(create_proc_mconsole);
5652 +
5653 +#define NOTIFY "=notify:"
5654 +
5655 +static int mconsole_setup(char *str)
5656 +{
5657 +       if(!strncmp(str, NOTIFY, strlen(NOTIFY))){
5658 +               str += strlen(NOTIFY);
5659 +               notify_socket = str;
5660 +       }
5661 +       else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str);
5662 +       return(1);
5663 +}
5664 +
5665 +__setup("mconsole", mconsole_setup);
5666 +
5667 +__uml_help(mconsole_setup,
5668 +"mconsole=notify:<socket>\n"
5669 +"    Requests that the mconsole driver send a message to the named Unix\n"
5670 +"    socket containing the name of the mconsole socket.  This also serves\n"
5671 +"    to notify outside processes when UML has booted far enough to respond\n"
5672 +"    to mconsole requests.\n\n"
5673 +);
5674 +
5675 +static int notify_panic(struct notifier_block *self, unsigned long unused1,
5676 +                       void *ptr)
5677 +{
5678 +       char *message = ptr;
5679 +
5680 +       if(notify_socket == NULL) return(0);
5681 +
5682 +       mconsole_notify(notify_socket, MCONSOLE_PANIC, message, 
5683 +                       strlen(message) + 1);
5684 +       return(0);
5685 +}
5686 +
5687 +static struct notifier_block panic_exit_notifier = {
5688 +       .notifier_call          = notify_panic,
5689 +       .next                   = NULL,
5690 +       .priority               = 1
5691 +};
5692 +
5693 +static int add_notifier(void)
5694 +{
5695 +       notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
5696 +       return(0);
5697 +}
5698 +
5699 +__initcall(add_notifier);
5700 +
5701 +char *mconsole_notify_socket(void)
5702 +{
5703 +       return(notify_socket);
5704 +}
5705 +
5706 +EXPORT_SYMBOL(mconsole_notify_socket);
5707 +
5708 +/*
5709 + * Overrides for Emacs so that we follow Linus's tabbing style.
5710 + * Emacs will notice this stuff at the end of the file and automatically
5711 + * adjust the settings for this buffer only.  This must remain at the end
5712 + * of the file.
5713 + * ---------------------------------------------------------------------------
5714 + * Local variables:
5715 + * c-file-style: "linux"
5716 + * End:
5717 + */
5718 Index: linux-2.4.29/arch/um/drivers/mconsole_user.c
5719 ===================================================================
5720 --- linux-2.4.29.orig/arch/um/drivers/mconsole_user.c   1970-01-01 03:00:00.000000000 +0300
5721 +++ linux-2.4.29/arch/um/drivers/mconsole_user.c        2005-05-03 22:28:14.223447920 +0300
5722 @@ -0,0 +1,215 @@
5723 +/*
5724 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
5725 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
5726 + * Licensed under the GPL
5727 + */
5728 +
5729 +#include <stdio.h>
5730 +#include <stdlib.h>
5731 +#include <errno.h>
5732 +#include <signal.h>
5733 +#include <sys/socket.h>
5734 +#include <sys/types.h>
5735 +#include <sys/uio.h>
5736 +#include <sys/un.h>
5737 +#include <unistd.h>
5738 +#include "user.h"
5739 +#include "mconsole.h"
5740 +#include "umid.h"
5741 +
5742 +static struct mconsole_command commands[] = {
5743 +       { "version", mconsole_version, MCONSOLE_INTR },
5744 +       { "halt", mconsole_halt, MCONSOLE_PROC },
5745 +       { "reboot", mconsole_reboot, MCONSOLE_PROC },
5746 +       { "config", mconsole_config, MCONSOLE_PROC },
5747 +       { "remove", mconsole_remove, MCONSOLE_PROC },
5748 +       { "sysrq", mconsole_sysrq, MCONSOLE_INTR },
5749 +       { "help", mconsole_help, MCONSOLE_INTR },
5750 +       { "cad", mconsole_cad, MCONSOLE_INTR },
5751 +       { "stop", mconsole_stop, MCONSOLE_PROC },
5752 +       { "go", mconsole_go, MCONSOLE_INTR },
5753 +       { "log", mconsole_log, MCONSOLE_INTR },
5754 +       { "proc", mconsole_proc, MCONSOLE_PROC },
5755 +};
5756 +
5757 +/* Initialized in mconsole_init, which is an initcall */
5758 +char mconsole_socket_name[256];
5759 +
5760 +int mconsole_reply_v0(struct mc_request *req, char *reply)
5761 +{
5762 +        struct iovec iov;
5763 +        struct msghdr msg;
5764 +
5765 +        iov.iov_base = reply;
5766 +        iov.iov_len = strlen(reply);
5767 +
5768 +        msg.msg_name = &(req->origin);
5769 +        msg.msg_namelen = req->originlen;
5770 +        msg.msg_iov = &iov;
5771 +        msg.msg_iovlen = 1;
5772 +        msg.msg_control = NULL;
5773 +        msg.msg_controllen = 0;
5774 +        msg.msg_flags = 0;
5775 +
5776 +        return sendmsg(req->originating_fd, &msg, 0);
5777 +}
5778 +
5779 +static struct mconsole_command *mconsole_parse(struct mc_request *req)
5780 +{
5781 +       struct mconsole_command *cmd;
5782 +       int i;
5783 +
5784 +       for(i=0;i<sizeof(commands)/sizeof(commands[0]);i++){
5785 +               cmd = &commands[i];
5786 +               if(!strncmp(req->request.data, cmd->command, 
5787 +                           strlen(cmd->command))){
5788 +                       return(cmd);
5789 +               }
5790 +       }
5791 +       return(NULL);
5792 +}
5793 +
5794 +#define MIN(a,b) ((a)<(b) ? (a):(b))
5795 +
5796 +#define STRINGX(x) #x
5797 +#define STRING(x) STRINGX(x)
5798 +
5799 +int mconsole_get_request(int fd, struct mc_request *req)
5800 +{
5801 +       int len;
5802 +
5803 +       req->originlen = sizeof(req->origin);
5804 +       req->len = recvfrom(fd, &req->request, sizeof(req->request), 0,
5805 +                           (struct sockaddr *) req->origin, &req->originlen);
5806 +       if (req->len < 0)
5807 +               return 0;
5808 +
5809 +       req->originating_fd = fd;
5810 +
5811 +       if(req->request.magic != MCONSOLE_MAGIC){
5812 +               /* Unversioned request */
5813 +               len = MIN(sizeof(req->request.data) - 1, 
5814 +                         strlen((char *) &req->request));
5815 +               memmove(req->request.data, &req->request, len);
5816 +               req->request.data[len] = '\0';
5817 +
5818 +               req->request.magic = MCONSOLE_MAGIC;
5819 +               req->request.version = 0;
5820 +               req->request.len = len;
5821 +
5822 +               mconsole_reply_v0(req, "ERR Version 0 mconsole clients are "
5823 +                                 "not supported by this driver");
5824 +               return(0);
5825 +       }
5826 +
5827 +       if(req->request.len >= MCONSOLE_MAX_DATA){
5828 +               mconsole_reply(req, "Request too large", 1, 0);
5829 +               return(0);
5830 +       }
5831 +       if(req->request.version != MCONSOLE_VERSION){
5832 +               mconsole_reply(req, "This driver only supports version " 
5833 +                               STRING(MCONSOLE_VERSION) " clients", 1, 0);
5834 +       }
5835 +       
5836 +       req->request.data[req->request.len] = '\0';
5837 +       req->cmd = mconsole_parse(req);
5838 +       if(req->cmd == NULL){
5839 +               mconsole_reply(req, "Unknown command", 1, 0);
5840 +               return(0);
5841 +       }
5842 +
5843 +       return(1);
5844 +}
5845 +
5846 +int mconsole_reply(struct mc_request *req, char *str, int err, int more)
5847 +{
5848 +       struct mconsole_reply reply;
5849 +       int total, len, n;
5850 +
5851 +       total = strlen(str);
5852 +       do {
5853 +               reply.err = err;
5854 +
5855 +               /* err can only be true on the first packet */
5856 +               err = 0;
5857 +
5858 +               len = MIN(total, MCONSOLE_MAX_DATA - 1);
5859 +
5860 +               if(len == total) reply.more = more;
5861 +               else reply.more = 1;
5862 +
5863 +               memcpy(reply.data, str, len);
5864 +               reply.data[len] = '\0';
5865 +               total -= len;
5866 +               str += len;
5867 +               reply.len = len + 1;
5868 +
5869 +               len = sizeof(reply) + reply.len - sizeof(reply.data);
5870 +
5871 +               n = sendto(req->originating_fd, &reply, len, 0,
5872 +                          (struct sockaddr *) req->origin, req->originlen);
5873 +
5874 +               if(n < 0) return(-errno);
5875 +       } while(total > 0);
5876 +       return(0);
5877 +}
5878 +
5879 +int mconsole_unlink_socket(void)
5880 +{
5881 +       unlink(mconsole_socket_name);
5882 +       return 0;
5883 +}
5884 +
5885 +static int notify_sock = -1;
5886 +
5887 +int mconsole_notify(char *sock_name, int type, const void *data, int len)
5888 +{
5889 +       struct sockaddr_un target;
5890 +       struct mconsole_notify packet;
5891 +       int n, err = 0;
5892 +
5893 +       lock_notify();
5894 +       if(notify_sock < 0){
5895 +               notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0);
5896 +               if(notify_sock < 0){
5897 +                       printk("mconsole_notify - socket failed, errno = %d\n",
5898 +                              errno);
5899 +                       err = -errno;
5900 +               }
5901 +       }
5902 +       unlock_notify();
5903 +       
5904 +       if(err)
5905 +               return(err);
5906 +
5907 +       target.sun_family = AF_UNIX;
5908 +       strcpy(target.sun_path, sock_name);
5909 +
5910 +       packet.magic = MCONSOLE_MAGIC;
5911 +       packet.version = MCONSOLE_VERSION;
5912 +       packet.type = type;
5913 +       len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len;
5914 +       packet.len = len;
5915 +       memcpy(packet.data, data, len);
5916 +
5917 +       err = 0;
5918 +       len = sizeof(packet) + packet.len - sizeof(packet.data);
5919 +       n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target, 
5920 +                  sizeof(target));
5921 +       if(n < 0){
5922 +               printk("mconsole_notify - sendto failed, errno = %d\n", errno);
5923 +               err = -errno;
5924 +       }
5925 +       return(err);
5926 +}
5927 +
5928 +/*
5929 + * Overrides for Emacs so that we follow Linus's tabbing style.
5930 + * Emacs will notice this stuff at the end of the file and automatically
5931 + * adjust the settings for this buffer only.  This must remain at the end
5932 + * of the file.
5933 + * ---------------------------------------------------------------------------
5934 + * Local variables:
5935 + * c-file-style: "linux"
5936 + * End:
5937 + */
5938 Index: linux-2.4.29/arch/um/drivers/mmapper_kern.c
5939 ===================================================================
5940 --- linux-2.4.29.orig/arch/um/drivers/mmapper_kern.c    1970-01-01 03:00:00.000000000 +0300
5941 +++ linux-2.4.29/arch/um/drivers/mmapper_kern.c 2005-05-03 22:28:14.000000000 +0300
5942 @@ -0,0 +1,151 @@
5943 +/*
5944 + * arch/um/drivers/mmapper_kern.c
5945 + *
5946 + * BRIEF MODULE DESCRIPTION
5947 + *
5948 + * Copyright (C) 2000 RidgeRun, Inc.
5949 + * Author: RidgeRun, Inc.
5950 + *         Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
5951 + *
5952 + */
5953 +#include <linux/kdev_t.h>
5954 +#include <linux/time.h>
5955 +#include <linux/devfs_fs_kernel.h>
5956 +#include <linux/module.h>
5957 +#include <linux/mm.h> 
5958 +#include <linux/slab.h>
5959 +#include <linux/init.h> 
5960 +#include <asm/uaccess.h>
5961 +#include <asm/irq.h>
5962 +#include <asm/smplock.h>
5963 +#include <asm/pgtable.h>
5964 +#include "mem_user.h"
5965 +#include "user_util.h"
5966
5967 +/* These are set in mmapper_init, which is called at boot time */
5968 +static unsigned long mmapper_size;
5969 +static unsigned long p_buf = 0;
5970 +static char *v_buf = NULL;
5971 +
5972 +static ssize_t
5973 +mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos)
5974 +{
5975 +       if(*ppos > mmapper_size)
5976 +               return -EINVAL;
5977 +
5978 +       if(count + *ppos > mmapper_size)
5979 +               count = count + *ppos - mmapper_size;
5980 +
5981 +       if(count < 0)
5982 +               return -EINVAL;
5983
5984 +       copy_to_user(buf,&v_buf[*ppos],count);
5985 +       
5986 +       return count;
5987 +}
5988 +
5989 +static ssize_t
5990 +mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
5991 +{
5992 +       if(*ppos > mmapper_size)
5993 +               return -EINVAL;
5994 +
5995 +       if(count + *ppos > mmapper_size)
5996 +               count = count + *ppos - mmapper_size;
5997 +
5998 +       if(count < 0)
5999 +               return -EINVAL;
6000 +
6001 +       copy_from_user(&v_buf[*ppos],buf,count);
6002 +       
6003 +       return count;
6004 +}
6005 +
6006 +static int 
6007 +mmapper_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
6008 +        unsigned long arg)
6009 +{
6010 +       return(-ENOIOCTLCMD);
6011 +}
6012 +
6013 +static int 
6014 +mmapper_mmap(struct file *file, struct vm_area_struct * vma)
6015 +{
6016 +       int ret = -EINVAL;
6017 +       int size;
6018 +
6019 +       lock_kernel();
6020 +       if (vma->vm_pgoff != 0)
6021 +               goto out;
6022 +       
6023 +       size = vma->vm_end - vma->vm_start;
6024 +       if(size > mmapper_size) return(-EFAULT);
6025 +
6026 +       /* XXX A comment above remap_page_range says it should only be
6027 +        * called when the mm semaphore is held
6028 +        */
6029 +       if (remap_page_range(vma->vm_start, p_buf, size, vma->vm_page_prot))
6030 +               goto out;
6031 +       ret = 0;
6032 +out:
6033 +       unlock_kernel();
6034 +       return ret;
6035 +}
6036 +
6037 +static int
6038 +mmapper_open(struct inode *inode, struct file *file)
6039 +{
6040 +       return 0;
6041 +}
6042 +
6043 +static int 
6044 +mmapper_release(struct inode *inode, struct file *file)
6045 +{
6046 +       return 0;
6047 +}
6048 +
6049 +static struct file_operations mmapper_fops = {
6050 +       .owner          = THIS_MODULE,
6051 +       .read           = mmapper_read,
6052 +       .write          = mmapper_write,
6053 +       .ioctl          = mmapper_ioctl,
6054 +       .mmap           = mmapper_mmap,
6055 +       .open           = mmapper_open,
6056 +       .release        = mmapper_release,
6057 +};
6058 +
6059 +static int __init mmapper_init(void)
6060 +{
6061 +       printk(KERN_INFO "Mapper v0.1\n");
6062 +
6063 +       v_buf = (char *) find_iomem("mmapper", &mmapper_size);
6064 +       if(mmapper_size == 0){
6065 +               printk(KERN_ERR "mmapper_init - find_iomem failed\n");
6066 +               return(0);
6067 +       }
6068 +
6069 +       p_buf = __pa(v_buf);
6070 +
6071 +       devfs_register (NULL, "mmapper", DEVFS_FL_DEFAULT, 
6072 +                       30, 0, S_IFCHR | S_IRUGO | S_IWUGO, 
6073 +                       &mmapper_fops, NULL); 
6074 +       devfs_mk_symlink(NULL, "mmapper0", DEVFS_FL_DEFAULT, "mmapper",
6075 +                        NULL, NULL);
6076 +       return(0);
6077 +}
6078 +
6079 +static void mmapper_exit(void)
6080 +{
6081 +}
6082 +
6083 +module_init(mmapper_init);
6084 +module_exit(mmapper_exit);
6085 +
6086 +MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>");
6087 +MODULE_DESCRIPTION("DSPLinux simulator mmapper driver");
6088 +/*
6089 + * ---------------------------------------------------------------------------
6090 + * Local variables:
6091 + * c-file-style: "linux"
6092 + * End:
6093 + */
6094 Index: linux-2.4.29/arch/um/drivers/net_kern.c
6095 ===================================================================
6096 --- linux-2.4.29.orig/arch/um/drivers/net_kern.c        1970-01-01 03:00:00.000000000 +0300
6097 +++ linux-2.4.29/arch/um/drivers/net_kern.c     2005-05-03 22:28:14.228447160 +0300
6098 @@ -0,0 +1,903 @@
6099 +/*
6100 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
6101 + * James Leu (jleu@mindspring.net).
6102 + * Copyright (C) 2001 by various other people who didn't put their name here.
6103 + * Licensed under the GPL.
6104 + */
6105 +
6106 +#include "linux/config.h"
6107 +#include "linux/kernel.h"
6108 +#include "linux/netdevice.h"
6109 +#include "linux/rtnetlink.h"
6110 +#include "linux/skbuff.h"
6111 +#include "linux/socket.h"
6112 +#include "linux/spinlock.h"
6113 +#include "linux/module.h"
6114 +#include "linux/init.h"
6115 +#include "linux/etherdevice.h"
6116 +#include "linux/list.h"
6117 +#include "linux/inetdevice.h"
6118 +#include "linux/ctype.h"
6119 +#include "linux/bootmem.h"
6120 +#include "linux/ethtool.h"
6121 +#include "asm/uaccess.h"
6122 +#include "user_util.h"
6123 +#include "kern_util.h"
6124 +#include "net_kern.h"
6125 +#include "net_user.h"
6126 +#include "mconsole_kern.h"
6127 +#include "init.h"
6128 +#include "irq_user.h"
6129 +#include "irq_kern.h"
6130 +
6131 +static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
6132 +LIST_HEAD(opened);
6133 +
6134 +static int uml_net_rx(struct net_device *dev)
6135 +{
6136 +       struct uml_net_private *lp = dev->priv;
6137 +       int pkt_len;
6138 +       struct sk_buff *skb;
6139 +
6140 +       /* If we can't allocate memory, try again next round. */
6141 +       skb = dev_alloc_skb(dev->mtu);
6142 +       if (skb == NULL) {
6143 +               lp->stats.rx_dropped++;
6144 +               return 0;
6145 +       }
6146 +
6147 +       skb->dev = dev;
6148 +       skb_put(skb, dev->mtu);
6149 +       skb->mac.raw = skb->data;
6150 +       pkt_len = (*lp->read)(lp->fd, &skb, lp);
6151 +
6152 +       if (pkt_len > 0) {
6153 +               skb_trim(skb, pkt_len);
6154 +               skb->protocol = (*lp->protocol)(skb);
6155 +               netif_rx(skb);
6156 +
6157 +               lp->stats.rx_bytes += skb->len;
6158 +               lp->stats.rx_packets++;
6159 +               return pkt_len;
6160 +       }
6161 +
6162 +       kfree_skb(skb);
6163 +       return pkt_len;
6164 +}
6165 +
6166 +void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6167 +{
6168 +       struct net_device *dev = dev_id;
6169 +       struct uml_net_private *lp = dev->priv;
6170 +       int err;
6171 +
6172 +       if(!netif_running(dev))
6173 +               return;
6174 +
6175 +       spin_lock(&lp->lock);
6176 +       while((err = uml_net_rx(dev)) > 0) ;
6177 +       if(err < 0) {
6178 +               printk(KERN_ERR 
6179 +                      "Device '%s' read returned %d, shutting it down\n", 
6180 +                      dev->name, err);
6181 +               dev_close(dev);
6182 +               goto out;
6183 +       }
6184 +       reactivate_fd(lp->fd, UM_ETH_IRQ);
6185 +
6186 + out:
6187 +       spin_unlock(&lp->lock);
6188 +}
6189 +
6190 +static int uml_net_open(struct net_device *dev)
6191 +{
6192 +       struct uml_net_private *lp = dev->priv;
6193 +       char addr[sizeof("255.255.255.255\0")];
6194 +       int err;
6195 +
6196 +       spin_lock(&lp->lock);
6197 +
6198 +       if(lp->fd >= 0){
6199 +               err = -ENXIO;
6200 +               goto out;
6201 +       }
6202 +
6203 +       if(!lp->have_mac){
6204 +               dev_ip_addr(dev, addr, &lp->mac[2]);
6205 +               set_ether_mac(dev, lp->mac);
6206 +       }
6207 +
6208 +       lp->fd = (*lp->open)(&lp->user);
6209 +       if(lp->fd < 0){
6210 +               err = lp->fd;
6211 +               goto out;
6212 +       }
6213 +
6214 +       err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
6215 +                            SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
6216 +       if(err != 0){
6217 +               printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
6218 +               if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6219 +               lp->fd = -1;
6220 +               err = -ENETUNREACH;
6221 +       }
6222 +
6223 +       lp->tl.data = (unsigned long) &lp->user;
6224 +       netif_start_queue(dev);
6225 +
6226 +       spin_lock(&opened_lock);
6227 +       list_add(&lp->list, &opened);
6228 +       spin_unlock(&opened_lock);
6229 +        /* clear buffer - it can happen that the host side of the interface
6230 +         * is full when we get here.  In this case, new data is never queued,
6231 +         * SIGIOs never arrive, and the net never works.
6232 +         */
6233 +       while((err = uml_net_rx(dev)) > 0) ;
6234 +
6235 +       MOD_INC_USE_COUNT;
6236 + out:
6237 +       spin_unlock(&lp->lock);
6238 +       return(err);
6239 +}
6240 +
6241 +static int uml_net_close(struct net_device *dev)
6242 +{
6243 +       struct uml_net_private *lp = dev->priv;
6244 +       
6245 +       netif_stop_queue(dev);
6246 +       spin_lock(&lp->lock);
6247 +
6248 +       free_irq(dev->irq, dev);
6249 +       if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6250 +       lp->fd = -1;
6251 +       spin_lock(&opened_lock);
6252 +       list_del(&lp->list);
6253 +       spin_unlock(&opened_lock);
6254 +
6255 +       MOD_DEC_USE_COUNT;
6256 +       spin_unlock(&lp->lock);
6257 +       return 0;
6258 +}
6259 +
6260 +static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
6261 +{
6262 +       struct uml_net_private *lp = dev->priv;
6263 +       unsigned long flags;
6264 +       int len;
6265 +
6266 +       netif_stop_queue(dev);
6267 +
6268 +       spin_lock_irqsave(&lp->lock, flags);
6269 +
6270 +       len = (*lp->write)(lp->fd, &skb, lp);
6271 +
6272 +       if(len == skb->len) {
6273 +               lp->stats.tx_packets++;
6274 +               lp->stats.tx_bytes += skb->len;
6275 +               dev->trans_start = jiffies;
6276 +               netif_start_queue(dev);
6277 +
6278 +               /* this is normally done in the interrupt when tx finishes */
6279 +               netif_wake_queue(dev);
6280 +       } 
6281 +       else if(len == 0){
6282 +               netif_start_queue(dev);
6283 +               lp->stats.tx_dropped++;
6284 +       }
6285 +       else {
6286 +               netif_start_queue(dev);
6287 +               printk(KERN_ERR "uml_net_start_xmit: failed(%d)\n", len);
6288 +       }
6289 +
6290 +       spin_unlock_irqrestore(&lp->lock, flags);
6291 +
6292 +       dev_kfree_skb(skb);
6293 +
6294 +       return 0;
6295 +}
6296 +
6297 +static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
6298 +{
6299 +       struct uml_net_private *lp = dev->priv;
6300 +       return &lp->stats;
6301 +}
6302 +
6303 +static void uml_net_set_multicast_list(struct net_device *dev)
6304 +{
6305 +       if (dev->flags & IFF_PROMISC) return;
6306 +       else if (dev->mc_count) dev->flags |= IFF_ALLMULTI;
6307 +       else dev->flags &= ~IFF_ALLMULTI;
6308 +}
6309 +
6310 +static void uml_net_tx_timeout(struct net_device *dev)
6311 +{
6312 +       dev->trans_start = jiffies;
6313 +       netif_wake_queue(dev);
6314 +}
6315 +
6316 +static int uml_net_set_mac(struct net_device *dev, void *addr)
6317 +{
6318 +       struct uml_net_private *lp = dev->priv;
6319 +       struct sockaddr *hwaddr = addr;
6320 +
6321 +       spin_lock(&lp->lock);
6322 +       memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
6323 +       spin_unlock(&lp->lock);
6324 +
6325 +       return(0);
6326 +}
6327 +
6328 +static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
6329 +{
6330 +       struct uml_net_private *lp = dev->priv;
6331 +       int err = 0;
6332 +
6333 +       spin_lock(&lp->lock);
6334 +
6335 +       new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
6336 +       if(new_mtu < 0){
6337 +               err = new_mtu;
6338 +               goto out;
6339 +       }
6340 +
6341 +       dev->mtu = new_mtu;
6342 +
6343 + out:
6344 +       spin_unlock(&lp->lock);
6345 +       return err;
6346 +}
6347 +
6348 +static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6349 +{
6350 +       static const struct ethtool_drvinfo info = {
6351 +               .cmd     = ETHTOOL_GDRVINFO,
6352 +               .driver  = "uml virtual ethernet",
6353 +               .version = "42",
6354 +       };
6355 +       void *useraddr;
6356 +       u32 ethcmd;
6357 +
6358 +       switch (cmd) {
6359 +       case SIOCETHTOOL:
6360 +               useraddr = ifr->ifr_data;
6361 +               if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
6362 +                       return -EFAULT;
6363 +               switch (ethcmd) {
6364 +               case ETHTOOL_GDRVINFO:
6365 +                       if (copy_to_user(useraddr, &info, sizeof(info)))
6366 +                               return -EFAULT;
6367 +                       return 0;
6368 +               default:
6369 +                       return -EOPNOTSUPP;
6370 +               }
6371 +       default:
6372 +               return -EINVAL;
6373 +       }
6374 +}
6375 +
6376 +void uml_net_user_timer_expire(unsigned long _conn)
6377 +{
6378 +#ifdef undef
6379 +       struct connection *conn = (struct connection *)_conn;
6380 +
6381 +       dprintk(KERN_INFO "uml_net_user_timer_expire [%p]\n", conn);
6382 +       do_connect(conn);
6383 +#endif
6384 +}
6385 +
6386 +/*
6387 + * default do nothing hard header packet routines for struct net_device init.
6388 + * real ethernet transports will overwrite with real routines.
6389 + */
6390 +static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
6391 +                 unsigned short type, void *daddr, void *saddr, unsigned len)
6392 +{
6393 +       return(0); /* no change */
6394 +}
6395 +
6396 +static int uml_net_rebuild_header(struct sk_buff *skb)
6397 +{
6398 +       return(0); /* ignore */ 
6399 +}
6400 +
6401 +static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
6402 +{
6403 +       return(-1); /* fail */
6404 +}
6405 +
6406 +static void uml_net_header_cache_update(struct hh_cache *hh,
6407 +                 struct net_device *dev, unsigned char * haddr)
6408 +{
6409 +       /* ignore */
6410 +}
6411 +
6412 +static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
6413 +{
6414 +       return(0); /* nothing */
6415 +}
6416 +
6417 +static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
6418 +static struct list_head devices = LIST_HEAD_INIT(devices);
6419 +
6420 +static int eth_configure(int n, void *init, char *mac,
6421 +                        struct transport *transport)
6422 +{
6423 +       struct uml_net *device;
6424 +       struct net_device *dev;
6425 +       struct uml_net_private *lp;
6426 +       int save, err, size;
6427 +
6428 +       size = transport->private_size + sizeof(struct uml_net_private) + 
6429 +               sizeof(((struct uml_net_private *) 0)->user);
6430 +
6431 +       device = kmalloc(sizeof(*device), GFP_KERNEL);
6432 +       if(device == NULL){
6433 +               printk(KERN_ERR "eth_configure failed to allocate uml_net\n");
6434 +               return(1);
6435 +       }
6436 +
6437 +       *device = ((struct uml_net) { .list     = LIST_HEAD_INIT(device->list),
6438 +                                     .dev      = NULL,
6439 +                                     .index    = n,
6440 +                                     .mac      = { [ 0 ... 5 ] = 0 },
6441 +                                     .have_mac = 0 });
6442 +
6443 +       spin_lock(&devices_lock);
6444 +       list_add(&device->list, &devices);
6445 +       spin_unlock(&devices_lock);
6446 +
6447 +       if(setup_etheraddr(mac, device->mac))
6448 +               device->have_mac = 1;
6449 +
6450 +       printk(KERN_INFO "Netdevice %d ", n);
6451 +       if(device->have_mac) printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
6452 +                                   device->mac[0], device->mac[1], 
6453 +                                   device->mac[2], device->mac[3], 
6454 +                                   device->mac[4], device->mac[5]);
6455 +       printk(": ");
6456 +       dev = kmalloc(sizeof(*dev) + size, GFP_KERNEL);
6457 +       if(dev == NULL){
6458 +               printk(KERN_ERR "eth_configure: failed to allocate device\n");
6459 +               return(1);
6460 +       }
6461 +       memset(dev, 0, sizeof(*dev) + size);
6462 +
6463 +       snprintf(dev->name, sizeof(dev->name), "eth%d", n);
6464 +       dev->priv = (void *) &dev[1];
6465 +       device->dev = dev;
6466 +
6467 +        dev->hard_header = uml_net_hard_header;
6468 +        dev->rebuild_header = uml_net_rebuild_header;
6469 +        dev->hard_header_cache = uml_net_header_cache;
6470 +        dev->header_cache_update= uml_net_header_cache_update;
6471 +        dev->hard_header_parse = uml_net_header_parse;
6472 +
6473 +       (*transport->kern->init)(dev, init);
6474 +
6475 +       dev->mtu = transport->user->max_packet;
6476 +       dev->open = uml_net_open;
6477 +       dev->hard_start_xmit = uml_net_start_xmit;
6478 +       dev->stop = uml_net_close;
6479 +       dev->get_stats = uml_net_get_stats;
6480 +       dev->set_multicast_list = uml_net_set_multicast_list;
6481 +       dev->tx_timeout = uml_net_tx_timeout;
6482 +       dev->set_mac_address = uml_net_set_mac;
6483 +       dev->change_mtu = uml_net_change_mtu;
6484 +       dev->do_ioctl = uml_net_ioctl;
6485 +       dev->watchdog_timeo = (HZ >> 1);
6486 +       dev->irq = UM_ETH_IRQ;
6487 +
6488 +       rtnl_lock();
6489 +       err = register_netdevice(dev);
6490 +       rtnl_unlock();
6491 +       if(err)
6492 +               return(1);
6493 +       lp = dev->priv;
6494 +
6495 +       /* lp.user is the first four bytes of the transport data, which
6496 +        * has already been initialized.  This structure assignment will
6497 +        * overwrite that, so we make sure that .user gets overwritten with
6498 +        * what it already has.
6499 +        */
6500 +       save = lp->user[0];
6501 +       *lp = ((struct uml_net_private) 
6502 +               { .list                 = LIST_HEAD_INIT(lp->list),
6503 +                 .lock                 = SPIN_LOCK_UNLOCKED,
6504 +                 .dev                  = dev,
6505 +                 .fd                   = -1,
6506 +                 .mac                  = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
6507 +                 .have_mac             = device->have_mac,
6508 +                 .protocol             = transport->kern->protocol,
6509 +                 .open                 = transport->user->open,
6510 +                 .close                = transport->user->close,
6511 +                 .remove               = transport->user->remove,
6512 +                 .read                 = transport->kern->read,
6513 +                 .write                = transport->kern->write,
6514 +                 .add_address          = transport->user->add_address,
6515 +                 .delete_address       = transport->user->delete_address,
6516 +                 .set_mtu              = transport->user->set_mtu,
6517 +                 .user                 = { save } });
6518 +       init_timer(&lp->tl);
6519 +       lp->tl.function = uml_net_user_timer_expire;
6520 +       memset(&lp->stats, 0, sizeof(lp->stats));
6521 +       if(lp->have_mac) memcpy(lp->mac, device->mac, sizeof(lp->mac));
6522 +
6523 +       if(transport->user->init) 
6524 +               (*transport->user->init)(&lp->user, dev);
6525 +
6526 +       if(device->have_mac)
6527 +               set_ether_mac(dev, device->mac);
6528 +       return(0);
6529 +}
6530 +
6531 +static struct uml_net *find_device(int n)
6532 +{
6533 +       struct uml_net *device;
6534 +       struct list_head *ele;
6535 +
6536 +       spin_lock(&devices_lock);
6537 +       list_for_each(ele, &devices){
6538 +               device = list_entry(ele, struct uml_net, list);
6539 +               if(device->index == n)
6540 +                       goto out;
6541 +       }
6542 +       device = NULL;
6543 + out:
6544 +       spin_unlock(&devices_lock);
6545 +       return(device);
6546 +}
6547 +
6548 +static int eth_parse(char *str, int *index_out, char **str_out)
6549 +{
6550 +       char *end;
6551 +       int n;
6552 +
6553 +       n = simple_strtoul(str, &end, 0);
6554 +       if(end == str){
6555 +               printk(KERN_ERR "eth_setup: Failed to parse '%s'\n", str);
6556 +               return(1);
6557 +       }
6558 +       if(n < 0){
6559 +               printk(KERN_ERR "eth_setup: device %d is negative\n", n);
6560 +               return(1);
6561 +       }
6562 +       str = end;
6563 +       if(*str != '='){
6564 +               printk(KERN_ERR 
6565 +                      "eth_setup: expected '=' after device number\n");
6566 +               return(1);
6567 +       }
6568 +       str++;
6569 +       if(find_device(n)){
6570 +               printk(KERN_ERR "eth_setup: Device %d already configured\n",
6571 +                      n);
6572 +               return(1);
6573 +       }
6574 +       if(index_out) *index_out = n;
6575 +       *str_out = str;
6576 +       return(0);
6577 +}
6578 +
6579 +struct eth_init {
6580 +       struct list_head list;
6581 +       char *init;
6582 +       int index;
6583 +};
6584 +
6585 +/* Filled in at boot time.  Will need locking if the transports become
6586 + * modular.
6587 + */
6588 +struct list_head transports = LIST_HEAD_INIT(transports);
6589 +
6590 +/* Filled in during early boot */
6591 +struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
6592 +
6593 +static int check_transport(struct transport *transport, char *eth, int n,
6594 +                          void **init_out, char **mac_out)
6595 +{
6596 +       int len;
6597 +
6598 +       len = strlen(transport->name);
6599 +       if(strncmp(eth, transport->name, len))
6600 +               return(0);
6601 +
6602 +       eth += len;
6603 +       if(*eth == ',')
6604 +               eth++;
6605 +       else if(*eth != '\0')
6606 +               return(0);
6607 +
6608 +       *init_out = kmalloc(transport->setup_size, GFP_KERNEL);
6609 +       if(*init_out == NULL)
6610 +               return(1);
6611 +
6612 +       if(!transport->setup(eth, mac_out, *init_out)){
6613 +               kfree(*init_out);
6614 +               *init_out = NULL;
6615 +       }
6616 +       return(1);
6617 +}
6618 +
6619 +void register_transport(struct transport *new)
6620 +{
6621 +       struct list_head *ele, *next;
6622 +       struct eth_init *eth;
6623 +       void *init;
6624 +       char *mac = NULL;
6625 +       int match;
6626 +
6627 +       list_add(&new->list, &transports);
6628 +
6629 +       list_for_each_safe(ele, next, &eth_cmd_line){
6630 +               eth = list_entry(ele, struct eth_init, list);
6631 +               match = check_transport(new, eth->init, eth->index, &init,
6632 +                                       &mac);
6633 +               if(!match)
6634 +                       continue;
6635 +               else if(init != NULL){
6636 +                       eth_configure(eth->index, init, mac, new);
6637 +                       kfree(init);
6638 +               }
6639 +               list_del(&eth->list);
6640 +       }
6641 +}
6642 +
6643 +static int eth_setup_common(char *str, int index)
6644 +{
6645 +       struct list_head *ele;
6646 +       struct transport *transport;
6647 +       void *init;
6648 +       char *mac = NULL;
6649 +
6650 +       list_for_each(ele, &transports){
6651 +               transport = list_entry(ele, struct transport, list);
6652 +               if(!check_transport(transport, str, index, &init, &mac))
6653 +                       continue;
6654 +               if(init != NULL){
6655 +                       eth_configure(index, init, mac, transport);
6656 +                       kfree(init);
6657 +               }
6658 +               return(1);
6659 +       }
6660 +       return(0);
6661 +}
6662 +
6663 +static int eth_setup(char *str)
6664 +{
6665 +       struct eth_init *new;
6666 +       int n, err;
6667 +
6668 +       err = eth_parse(str, &n, &str);
6669 +       if(err) return(1);
6670 +
6671 +       new = alloc_bootmem(sizeof(new));
6672 +       if(new == NULL){
6673 +               printk("eth_init : alloc_bootmem failed\n");
6674 +               return(1);
6675 +       }
6676 +       *new = ((struct eth_init) { .list       = LIST_HEAD_INIT(new->list),
6677 +                                   .index      = n,
6678 +                                   .init       = str });
6679 +       list_add_tail(&new->list, &eth_cmd_line);
6680 +       return(1);
6681 +}
6682 +
6683 +__setup("eth", eth_setup);
6684 +__uml_help(eth_setup,
6685 +"eth[0-9]+=<transport>,<options>\n"
6686 +"    Configure a network device.\n\n"
6687 +);
6688 +
6689 +static int eth_init(void)
6690 +{
6691 +       struct list_head *ele, *next;
6692 +       struct eth_init *eth;
6693 +
6694 +       list_for_each_safe(ele, next, &eth_cmd_line){
6695 +               eth = list_entry(ele, struct eth_init, list);
6696 +
6697 +               if(eth_setup_common(eth->init, eth->index))
6698 +                       list_del(&eth->list);
6699 +       }
6700 +       
6701 +       return(1);
6702 +}
6703 +
6704 +__initcall(eth_init);
6705 +
6706 +static int net_config(char *str)
6707 +{
6708 +       int n, err;
6709 +
6710 +       err = eth_parse(str, &n, &str);
6711 +       if(err) return(err);
6712 +
6713 +       str = uml_strdup(str);
6714 +       if(str == NULL){
6715 +               printk(KERN_ERR "net_config failed to strdup string\n");
6716 +               return(-1);
6717 +       }
6718 +       err = !eth_setup_common(str, n);
6719 +       if(err) 
6720 +               kfree(str);
6721 +       return(err);
6722 +}
6723 +
6724 +static int net_remove(char *str)
6725 +{
6726 +       struct uml_net *device;
6727 +       struct net_device *dev;
6728 +       struct uml_net_private *lp;
6729 +       char *end;
6730 +       int n;
6731 +
6732 +       n = simple_strtoul(str, &end, 0);
6733 +       if((*end != '\0') || (end == str))
6734 +               return(-1);
6735 +
6736 +       device = find_device(n);
6737 +       if(device == NULL)
6738 +               return(0);
6739 +
6740 +       dev = device->dev;
6741 +       lp = dev->priv;
6742 +       if(lp->fd > 0) return(-1);
6743 +       if(lp->remove != NULL) (*lp->remove)(&lp->user);
6744 +       unregister_netdev(dev);
6745 +
6746 +       list_del(&device->list);
6747 +       kfree(device);
6748 +       return(0);
6749 +}
6750 +
6751 +static struct mc_device net_mc = {
6752 +       .name           = "eth",
6753 +       .config         = net_config,
6754 +       .get_config     = NULL,
6755 +       .remove         = net_remove,
6756 +};
6757 +
6758 +static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
6759 +                             void *ptr)
6760 +{
6761 +       struct in_ifaddr *ifa = ptr;
6762 +       u32 addr = ifa->ifa_address;
6763 +       u32 netmask = ifa->ifa_mask;
6764 +       struct net_device *dev = ifa->ifa_dev->dev;
6765 +       struct uml_net_private *lp;
6766 +       void (*proc)(unsigned char *, unsigned char *, void *);
6767 +       unsigned char addr_buf[4], netmask_buf[4];
6768 +
6769 +       if(dev->open != uml_net_open) return(NOTIFY_DONE);
6770 +
6771 +       lp = dev->priv;
6772 +
6773 +       proc = NULL;
6774 +       switch (event){
6775 +       case NETDEV_UP:
6776 +               proc = lp->add_address;
6777 +               break;
6778 +       case NETDEV_DOWN:
6779 +               proc = lp->delete_address;
6780 +               break;
6781 +       }
6782 +       if(proc != NULL){
6783 +               addr_buf[0] = addr & 0xff;
6784 +               addr_buf[1] = (addr >> 8) & 0xff;
6785 +               addr_buf[2] = (addr >> 16) & 0xff;
6786 +               addr_buf[3] = addr >> 24;
6787 +               netmask_buf[0] = netmask & 0xff;
6788 +               netmask_buf[1] = (netmask >> 8) & 0xff;
6789 +               netmask_buf[2] = (netmask >> 16) & 0xff;
6790 +               netmask_buf[3] = netmask >> 24;
6791 +               (*proc)(addr_buf, netmask_buf, &lp->user);
6792 +       }
6793 +       return(NOTIFY_DONE);
6794 +}
6795 +
6796 +struct notifier_block uml_inetaddr_notifier = {
6797 +       .notifier_call          = uml_inetaddr_event,
6798 +};
6799 +
6800 +static int uml_net_init(void)
6801 +{
6802 +       struct list_head *ele;
6803 +       struct uml_net_private *lp;     
6804 +       struct in_device *ip;
6805 +       struct in_ifaddr *in;
6806 +
6807 +       mconsole_register_dev(&net_mc);
6808 +       register_inetaddr_notifier(&uml_inetaddr_notifier);
6809 +
6810 +       /* Devices may have been opened already, so the uml_inetaddr_notifier
6811 +        * didn't get a chance to run for them.  This fakes it so that
6812 +        * addresses which have already been set up get handled properly.
6813 +        */
6814 +       list_for_each(ele, &opened){
6815 +               lp = list_entry(ele, struct uml_net_private, list);
6816 +               ip = lp->dev->ip_ptr;
6817 +               if(ip == NULL) continue;
6818 +               in = ip->ifa_list;
6819 +               while(in != NULL){
6820 +                       uml_inetaddr_event(NULL, NETDEV_UP, in);
6821 +                       in = in->ifa_next;
6822 +               }
6823 +       }       
6824 +
6825 +       return(0);
6826 +}
6827 +
6828 +__initcall(uml_net_init);
6829 +
6830 +static void close_devices(void)
6831 +{
6832 +       struct list_head *ele;
6833 +       struct uml_net_private *lp;     
6834 +
6835 +       list_for_each(ele, &opened){
6836 +               lp = list_entry(ele, struct uml_net_private, list);
6837 +               if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6838 +               if(lp->remove != NULL) (*lp->remove)(&lp->user);
6839 +       }
6840 +}
6841 +
6842 +__uml_exitcall(close_devices);
6843 +
6844 +int setup_etheraddr(char *str, unsigned char *addr)
6845 +{
6846 +       char *end;
6847 +       int i;
6848 +
6849 +       if(str == NULL)
6850 +               return(0);
6851 +       for(i=0;i<6;i++){
6852 +               addr[i] = simple_strtoul(str, &end, 16);
6853 +               if((end == str) ||
6854 +                  ((*end != ':') && (*end != ',') && (*end != '\0'))){
6855 +                       printk(KERN_ERR 
6856 +                              "setup_etheraddr: failed to parse '%s' "
6857 +                              "as an ethernet address\n", str);
6858 +                       return(0);
6859 +               }
6860 +               str = end + 1;
6861 +       }
6862 +       if(addr[0] & 1){
6863 +               printk(KERN_ERR 
6864 +                      "Attempt to assign a broadcast ethernet address to a "
6865 +                      "device disallowed\n");
6866 +               return(0);
6867 +       }
6868 +       return(1);
6869 +}
6870 +
6871 +void dev_ip_addr(void *d, char *buf, char *bin_buf)
6872 +{
6873 +       struct net_device *dev = d;
6874 +       struct in_device *ip = dev->ip_ptr;
6875 +       struct in_ifaddr *in;
6876 +       u32 addr;
6877 +
6878 +       if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
6879 +               printk(KERN_WARNING "dev_ip_addr - device not assigned an "
6880 +                      "IP address\n");
6881 +               return;
6882 +       }
6883 +       addr = in->ifa_address;
6884 +       sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff, 
6885 +               (addr >> 16) & 0xff, addr >> 24);
6886 +       if(bin_buf){
6887 +               bin_buf[0] = addr & 0xff;
6888 +               bin_buf[1] = (addr >> 8) & 0xff;
6889 +               bin_buf[2] = (addr >> 16) & 0xff;
6890 +               bin_buf[3] = addr >> 24;
6891 +       }
6892 +}
6893 +
6894 +void set_ether_mac(void *d, unsigned char *addr)
6895 +{
6896 +       struct net_device *dev = d;
6897 +
6898 +       memcpy(dev->dev_addr, addr, ETH_ALEN);  
6899 +}
6900 +
6901 +struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
6902 +{
6903 +       if((skb != NULL) && (skb_tailroom(skb) < extra)){
6904 +               struct sk_buff *skb2;
6905 +
6906 +               skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
6907 +               dev_kfree_skb(skb);
6908 +               skb = skb2;
6909 +       }
6910 +       if(skb != NULL) skb_put(skb, extra);
6911 +       return(skb);
6912 +}
6913 +
6914 +void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *, 
6915 +                                       void *), 
6916 +                   void *arg)
6917 +{
6918 +       struct net_device *dev = d;
6919 +       struct in_device *ip = dev->ip_ptr;
6920 +       struct in_ifaddr *in;
6921 +       unsigned char address[4], netmask[4];
6922 +
6923 +       if(ip == NULL) return;
6924 +       in = ip->ifa_list;
6925 +       while(in != NULL){
6926 +               address[0] = in->ifa_address & 0xff;
6927 +               address[1] = (in->ifa_address >> 8) & 0xff;
6928 +               address[2] = (in->ifa_address >> 16) & 0xff;
6929 +               address[3] = in->ifa_address >> 24;
6930 +               netmask[0] = in->ifa_mask & 0xff;
6931 +               netmask[1] = (in->ifa_mask >> 8) & 0xff;
6932 +               netmask[2] = (in->ifa_mask >> 16) & 0xff;
6933 +               netmask[3] = in->ifa_mask >> 24;
6934 +               (*cb)(address, netmask, arg);
6935 +               in = in->ifa_next;
6936 +       }
6937 +}
6938 +
6939 +int dev_netmask(void *d, void *m)
6940 +{
6941 +       struct net_device *dev = d;
6942 +       struct in_device *ip = dev->ip_ptr;
6943 +       struct in_ifaddr *in;
6944 +       __u32 *mask_out = m;
6945 +
6946 +       if(ip == NULL) 
6947 +               return(1);
6948 +
6949 +       in = ip->ifa_list;
6950 +       if(in == NULL) 
6951 +               return(1);
6952 +
6953 +       *mask_out = in->ifa_mask;
6954 +       return(0);
6955 +}
6956 +
6957 +void *get_output_buffer(int *len_out)
6958 +{
6959 +       void *ret;
6960 +
6961 +       ret = (void *) __get_free_pages(GFP_KERNEL, 0);
6962 +       if(ret) *len_out = PAGE_SIZE;
6963 +       else *len_out = 0;
6964 +       return(ret);
6965 +}
6966 +
6967 +void free_output_buffer(void *buffer)
6968 +{
6969 +       free_pages((unsigned long) buffer, 0);
6970 +}
6971 +
6972 +int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out, 
6973 +                    char **gate_addr)
6974 +{
6975 +       char *remain;
6976 +
6977 +       remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL);
6978 +       if(remain != NULL){
6979 +               printk("tap_setup_common - Extra garbage on specification : "
6980 +                      "'%s'\n", remain);
6981 +               return(1);
6982 +       }
6983 +
6984 +       return(0);
6985 +}
6986 +
6987 +unsigned short eth_protocol(struct sk_buff *skb)
6988 +{
6989 +       return(eth_type_trans(skb, skb->dev));
6990 +}
6991 +
6992 +/*
6993 + * Overrides for Emacs so that we follow Linus's tabbing style.
6994 + * Emacs will notice this stuff at the end of the file and automatically
6995 + * adjust the settings for this buffer only.  This must remain at the end
6996 + * of the file.
6997 + * ---------------------------------------------------------------------------
6998 + * Local variables:
6999 + * c-file-style: "linux"
7000 + * End:
7001 + */
7002 Index: linux-2.4.29/arch/um/drivers/net_user.c
7003 ===================================================================
7004 --- linux-2.4.29.orig/arch/um/drivers/net_user.c        1970-01-01 03:00:00.000000000 +0300
7005 +++ linux-2.4.29/arch/um/drivers/net_user.c     2005-05-03 22:28:14.229447008 +0300
7006 @@ -0,0 +1,253 @@
7007 +/* 
7008 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7009 + * Licensed under the GPL
7010 + */
7011 +
7012 +#include <stddef.h>
7013 +#include <stdarg.h>
7014 +#include <unistd.h>
7015 +#include <stdio.h>
7016 +#include <errno.h>
7017 +#include <stdlib.h>
7018 +#include <string.h>
7019 +#include <sys/socket.h>
7020 +#include <sys/wait.h>
7021 +#include "user.h"
7022 +#include "user_util.h"
7023 +#include "kern_util.h"
7024 +#include "net_user.h"
7025 +#include "helper.h"
7026 +#include "os.h"
7027 +
7028 +int tap_open_common(void *dev, char *gate_addr)
7029 +{
7030 +       int tap_addr[4];
7031 +
7032 +       if(gate_addr == NULL) return(0);
7033 +       if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], 
7034 +                 &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
7035 +               printk("Invalid tap IP address - '%s'\n", gate_addr);
7036 +               return(-EINVAL);
7037 +       }
7038 +       return(0);
7039 +}
7040 +
7041 +void tap_check_ips(char *gate_addr, char *eth_addr)
7042 +{
7043 +       int tap_addr[4];
7044 +
7045 +       if((gate_addr != NULL) && 
7046 +          (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], 
7047 +                  &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
7048 +          (eth_addr[0] == tap_addr[0]) && 
7049 +          (eth_addr[1] == tap_addr[1]) && 
7050 +          (eth_addr[2] == tap_addr[2]) && 
7051 +          (eth_addr[3] == tap_addr[3])){
7052 +               printk("The tap IP address and the UML eth IP address"
7053 +                      " must be different\n");
7054 +       }
7055 +}
7056 +
7057 +void read_output(int fd, char *output, int len)
7058 +{
7059 +       int remain, n, actual;
7060 +       char c;
7061 +
7062 +       if(output == NULL){
7063 +               output = &c;
7064 +               len = sizeof(c);
7065 +       }
7066 +               
7067 +       *output = '\0';
7068 +       n = os_read_file(fd, &remain, sizeof(remain));
7069 +       if(n != sizeof(remain)){
7070 +               printk("read_output - read of length failed, err = %d\n", -n);
7071 +               return;
7072 +       }
7073 +
7074 +       while(remain != 0){
7075 +               n = (remain < len) ? remain : len;
7076 +               actual = os_read_file(fd, output, n);
7077 +               if(actual != n){
7078 +                       printk("read_output - read of data failed, "
7079 +                              "err = %d\n", -actual);
7080 +                       return;
7081 +               }
7082 +               remain -= actual;
7083 +       }
7084 +       return;
7085 +}
7086 +
7087 +int net_read(int fd, void *buf, int len)
7088 +{
7089 +       int n;
7090 +
7091 +       n = os_read_file(fd,  buf,  len);
7092 +
7093 +       if(n == -EAGAIN) 
7094 +               return(0);
7095 +       else if(n == 0) 
7096 +               return(-ENOTCONN);
7097 +       return(n);
7098 +}
7099 +
7100 +int net_recvfrom(int fd, void *buf, int len)
7101 +{
7102 +       int n;
7103 +
7104 +       while(((n = recvfrom(fd,  buf,  len, 0, NULL, NULL)) < 0) && 
7105 +             (errno == EINTR)) ;
7106 +
7107 +       if(n < 0){
7108 +               if(errno == EAGAIN) return(0);
7109 +               return(-errno);
7110 +       }
7111 +       else if(n == 0) return(-ENOTCONN);
7112 +       return(n);
7113 +}
7114 +
7115 +int net_write(int fd, void *buf, int len)
7116 +{
7117 +       int n;
7118 +
7119 +       n = os_write_file(fd, buf, len);
7120 +
7121 +       if(n == -EAGAIN) 
7122 +               return(0);
7123 +       else if(n == 0) 
7124 +               return(-ENOTCONN);
7125 +       return(n);
7126 +}
7127 +
7128 +int net_send(int fd, void *buf, int len)
7129 +{
7130 +       int n;
7131 +
7132 +       while(((n = send(fd, buf, len, 0)) < 0) && (errno == EINTR)) ;
7133 +       if(n < 0){
7134 +               if(errno == EAGAIN) return(0);
7135 +               return(-errno);
7136 +       }
7137 +       else if(n == 0) return(-ENOTCONN);
7138 +       return(n);      
7139 +}
7140 +
7141 +int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
7142 +{
7143 +       int n;
7144 +
7145 +       while(((n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
7146 +                          sock_len)) < 0) && (errno == EINTR)) ;
7147 +       if(n < 0){
7148 +               if(errno == EAGAIN) return(0);
7149 +               return(-errno);
7150 +       }
7151 +       else if(n == 0) return(-ENOTCONN);
7152 +       return(n);      
7153 +}
7154 +
7155 +struct change_pre_exec_data {
7156 +       int close_me;
7157 +       int stdout;
7158 +};
7159 +
7160 +static void change_pre_exec(void *arg)
7161 +{
7162 +       struct change_pre_exec_data *data = arg;
7163 +
7164 +       os_close_file(data->close_me);
7165 +       dup2(data->stdout, 1);
7166 +}
7167 +
7168 +static int change_tramp(char **argv, char *output, int output_len)
7169 +{
7170 +       int pid, fds[2], err;
7171 +       struct change_pre_exec_data pe_data;
7172 +
7173 +       err = os_pipe(fds, 1, 0);
7174 +       if(err < 0){
7175 +               printk("change_tramp - pipe failed, err = %d\n", -err);
7176 +               return(err);
7177 +       }
7178 +       pe_data.close_me = fds[0];
7179 +       pe_data.stdout = fds[1];
7180 +       pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
7181 +
7182 +       read_output(fds[0], output, output_len);
7183 +       os_close_file(fds[0]);
7184 +       os_close_file(fds[1]);
7185 +       CATCH_EINTR(waitpid(pid, NULL, 0));     
7186 +       return(pid);
7187 +}
7188 +
7189 +static void change(char *dev, char *what, unsigned char *addr,
7190 +                  unsigned char *netmask)
7191 +{
7192 +       char addr_buf[sizeof("255.255.255.255\0")];
7193 +       char netmask_buf[sizeof("255.255.255.255\0")];
7194 +       char version[sizeof("nnnnn\0")];
7195 +       char *argv[] = { "uml_net", version, what, dev, addr_buf, 
7196 +                        netmask_buf, NULL };
7197 +       char *output;
7198 +       int output_len, pid;
7199 +
7200 +       sprintf(version, "%d", UML_NET_VERSION);
7201 +       sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
7202 +       sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1], 
7203 +               netmask[2], netmask[3]);
7204 +
7205 +       output_len = page_size();
7206 +       output = um_kmalloc(output_len);
7207 +       if(output == NULL)
7208 +               printk("change : failed to allocate output buffer\n");
7209 +
7210 +       pid = change_tramp(argv, output, output_len);
7211 +       if(pid < 0) return;
7212 +
7213 +       if(output != NULL){
7214 +               printk("%s", output);
7215 +               kfree(output);
7216 +       }
7217 +}
7218 +
7219 +void open_addr(unsigned char *addr, unsigned char *netmask, void *arg)
7220 +{
7221 +       change(arg, "add", addr, netmask);
7222 +}
7223 +
7224 +void close_addr(unsigned char *addr, unsigned char *netmask, void *arg)
7225 +{
7226 +       change(arg, "del", addr, netmask);
7227 +}
7228 +
7229 +char *split_if_spec(char *str, ...)
7230 +{
7231 +       char **arg, *end;
7232 +       va_list ap;
7233 +
7234 +       va_start(ap, str);
7235 +       while((arg = va_arg(ap, char **)) != NULL){
7236 +               if(*str == '\0')
7237 +                       return(NULL);
7238 +               end = strchr(str, ',');
7239 +               if(end != str)
7240 +                       *arg = str;
7241 +               if(end == NULL)
7242 +                       return(NULL);
7243 +               *end++ = '\0';
7244 +               str = end;
7245 +       }
7246 +       va_end(ap);
7247 +       return(str);
7248 +}
7249 +
7250 +/*
7251 + * Overrides for Emacs so that we follow Linus's tabbing style.
7252 + * Emacs will notice this stuff at the end of the file and automatically
7253 + * adjust the settings for this buffer only.  This must remain at the end
7254 + * of the file.
7255 + * ---------------------------------------------------------------------------
7256 + * Local variables:
7257 + * c-file-style: "linux"
7258 + * End:
7259 + */
7260 Index: linux-2.4.29/arch/um/drivers/null.c
7261 ===================================================================
7262 --- linux-2.4.29.orig/arch/um/drivers/null.c    1970-01-01 03:00:00.000000000 +0300
7263 +++ linux-2.4.29/arch/um/drivers/null.c 2005-05-03 22:28:14.230446856 +0300
7264 @@ -0,0 +1,55 @@
7265 +/* 
7266 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7267 + * Licensed under the GPL
7268 + */
7269 +
7270 +#include <stdlib.h>
7271 +#include <errno.h>
7272 +#include "chan_user.h"
7273 +#include "os.h"
7274 +
7275 +static int null_chan;
7276 +
7277 +void *null_init(char *str, int device, struct chan_opts *opts)
7278 +{
7279 +       return(&null_chan);
7280 +}
7281 +
7282 +int null_open(int input, int output, int primary, void *d, char **dev_out)
7283 +{
7284 +       *dev_out = NULL;
7285 +       return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0));
7286 +}
7287 +
7288 +int null_read(int fd, char *c_out, void *unused)
7289 +{
7290 +       return(-ENODEV);
7291 +}
7292 +
7293 +void null_free(void *data)
7294 +{
7295 +}
7296 +
7297 +struct chan_ops null_ops = {
7298 +       .type           = "null",
7299 +       .init           = null_init,
7300 +       .open           = null_open,
7301 +       .close          = generic_close,
7302 +       .read           = null_read,
7303 +       .write          = generic_write,
7304 +       .console_write  = generic_console_write,
7305 +       .window_size    = generic_window_size,
7306 +       .free           = null_free,
7307 +       .winch          = 0,
7308 +};
7309 +
7310 +/*
7311 + * Overrides for Emacs so that we follow Linus's tabbing style.
7312 + * Emacs will notice this stuff at the end of the file and automatically
7313 + * adjust the settings for this buffer only.  This must remain at the end
7314 + * of the file.
7315 + * ---------------------------------------------------------------------------
7316 + * Local variables:
7317 + * c-file-style: "linux"
7318 + * End:
7319 + */
7320 Index: linux-2.4.29/arch/um/drivers/pcap_kern.c
7321 ===================================================================
7322 --- linux-2.4.29.orig/arch/um/drivers/pcap_kern.c       1970-01-01 03:00:00.000000000 +0300
7323 +++ linux-2.4.29/arch/um/drivers/pcap_kern.c    2005-05-03 22:28:14.000000000 +0300
7324 @@ -0,0 +1,127 @@
7325 +/*
7326 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
7327 + * Licensed under the GPL.
7328 + */
7329 +
7330 +#include "linux/init.h"
7331 +#include "linux/netdevice.h"
7332 +#include "linux/etherdevice.h"
7333 +#include "net_kern.h"
7334 +#include "net_user.h"
7335 +#include "pcap_user.h"
7336 +
7337 +struct pcap_init {
7338 +       char *host_if;
7339 +       int promisc;
7340 +       int optimize;
7341 +       char *filter;
7342 +};
7343 +
7344 +void pcap_init(struct net_device *dev, void *data)
7345 +{
7346 +       struct uml_net_private *pri;
7347 +       struct pcap_data *ppri;
7348 +       struct pcap_init *init = data;
7349 +
7350 +       init_etherdev(dev, 0);
7351 +       pri = dev->priv;
7352 +       ppri = (struct pcap_data *) pri->user;
7353 +       *ppri = ((struct pcap_data)
7354 +               { .host_if      = init->host_if,
7355 +                 .promisc      = init->promisc,
7356 +                 .optimize     = init->optimize,
7357 +                 .filter       = init->filter,
7358 +                 .compiled     = NULL,
7359 +                 .pcap         = NULL });
7360 +}
7361 +
7362 +static int pcap_read(int fd, struct sk_buff **skb, 
7363 +                      struct uml_net_private *lp)
7364 +{
7365 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
7366 +       if(*skb == NULL) return(-ENOMEM);
7367 +       return(pcap_user_read(fd, (*skb)->mac.raw, 
7368 +                             (*skb)->dev->mtu + ETH_HEADER_OTHER,
7369 +                             (struct pcap_data *) &lp->user));
7370 +}
7371 +
7372 +static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
7373 +{
7374 +       return(-EPERM);
7375 +}
7376 +
7377 +static struct net_kern_info pcap_kern_info = {
7378 +       .init                   = pcap_init,
7379 +       .protocol               = eth_protocol,
7380 +       .read                   = pcap_read,
7381 +       .write                  = pcap_write,
7382 +};
7383 +
7384 +int pcap_setup(char *str, char **mac_out, void *data)
7385 +{
7386 +       struct pcap_init *init = data;
7387 +       char *remain, *host_if = NULL, *options[2] = { NULL, NULL };
7388 +       int i;
7389 +
7390 +       *init = ((struct pcap_init)
7391 +               { .host_if      = "eth0",
7392 +                 .promisc      = 1,
7393 +                 .optimize     = 0,
7394 +                 .filter       = NULL });
7395 +
7396 +       remain = split_if_spec(str, &host_if, &init->filter, 
7397 +                              &options[0], &options[1], NULL);
7398 +       if(remain != NULL){
7399 +               printk(KERN_ERR "pcap_setup - Extra garbage on "
7400 +                      "specification : '%s'\n", remain);
7401 +               return(0);
7402 +       }
7403 +
7404 +       if(host_if != NULL)
7405 +               init->host_if = host_if;
7406 +
7407 +       for(i = 0; i < sizeof(options)/sizeof(options[0]); i++){
7408 +               if(options[i] == NULL)
7409 +                       continue;
7410 +               if(!strcmp(options[i], "promisc"))
7411 +                       init->promisc = 1;
7412 +               else if(!strcmp(options[i], "nopromisc"))
7413 +                       init->promisc = 0;
7414 +               else if(!strcmp(options[i], "optimize"))
7415 +                       init->optimize = 1;
7416 +               else if(!strcmp(options[i], "nooptimize"))
7417 +                       init->optimize = 0;
7418 +               else printk("pcap_setup : bad option - '%s'\n", options[i]);
7419 +       }
7420 +
7421 +       return(1);
7422 +}
7423 +
7424 +static struct transport pcap_transport = {
7425 +       .list           = LIST_HEAD_INIT(pcap_transport.list),
7426 +       .name           = "pcap",
7427 +       .setup          = pcap_setup,
7428 +       .user           = &pcap_user_info,
7429 +       .kern           = &pcap_kern_info,
7430 +       .private_size   = sizeof(struct pcap_data),
7431 +       .setup_size     = sizeof(struct pcap_init),
7432 +};
7433 +
7434 +static int register_pcap(void)
7435 +{
7436 +       register_transport(&pcap_transport);
7437 +       return(1);
7438 +}
7439 +
7440 +__initcall(register_pcap);
7441 +
7442 +/*
7443 + * Overrides for Emacs so that we follow Linus's tabbing style.
7444 + * Emacs will notice this stuff at the end of the file and automatically
7445 + * adjust the settings for this buffer only.  This must remain at the end
7446 + * of the file.
7447 + * ---------------------------------------------------------------------------
7448 + * Local variables:
7449 + * c-file-style: "linux"
7450 + * End:
7451 + */
7452 Index: linux-2.4.29/arch/um/drivers/pcap_user.c
7453 ===================================================================
7454 --- linux-2.4.29.orig/arch/um/drivers/pcap_user.c       1970-01-01 03:00:00.000000000 +0300
7455 +++ linux-2.4.29/arch/um/drivers/pcap_user.c    2005-05-03 22:28:14.000000000 +0300
7456 @@ -0,0 +1,143 @@
7457 +/*
7458 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
7459 + * Licensed under the GPL.
7460 + */
7461 +
7462 +#include <unistd.h>
7463 +#include <stdlib.h>
7464 +#include <string.h>
7465 +#include <errno.h>
7466 +#include <pcap.h>
7467 +#include <asm/types.h>
7468 +#include "net_user.h"
7469 +#include "pcap_user.h"
7470 +#include "user.h"
7471 +
7472 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
7473 +
7474 +#define PCAP_FD(p) (*(int *)(p))
7475 +
7476 +static void pcap_user_init(void *data, void *dev)
7477 +{
7478 +       struct pcap_data *pri = data;
7479 +       pcap_t *p;
7480 +       char errors[PCAP_ERRBUF_SIZE];
7481 +
7482 +       p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors);
7483 +       if(p == NULL){
7484 +               printk("pcap_user_init : pcap_open_live failed - '%s'\n", 
7485 +                      errors);
7486 +               return;
7487 +       }
7488 +
7489 +       pri->dev = dev;
7490 +       pri->pcap = p;
7491 +}
7492 +
7493 +static int pcap_open(void *data)
7494 +{
7495 +       struct pcap_data *pri = data;
7496 +       __u32 netmask;
7497 +       int err;
7498 +
7499 +       if(pri->pcap == NULL)
7500 +               return(-ENODEV);
7501 +
7502 +       if(pri->filter != NULL){
7503 +               err = dev_netmask(pri->dev, &netmask);
7504 +               if(err < 0){
7505 +                       printk("pcap_open : dev_netmask failed\n");
7506 +                       return(-EIO);
7507 +               }
7508 +
7509 +               pri->compiled = um_kmalloc(sizeof(struct bpf_program));
7510 +               if(pri->compiled == NULL){
7511 +                       printk("pcap_open : kmalloc failed\n");
7512 +                       return(-ENOMEM);
7513 +               }
7514 +               
7515 +               err = pcap_compile(pri->pcap, 
7516 +                                  (struct bpf_program *) pri->compiled, 
7517 +                                  pri->filter, pri->optimize, netmask);
7518 +               if(err < 0){
7519 +                       printk("pcap_open : pcap_compile failed - '%s'\n", 
7520 +                              pcap_geterr(pri->pcap));
7521 +                       return(-EIO);
7522 +               }
7523 +
7524 +               err = pcap_setfilter(pri->pcap, pri->compiled);
7525 +               if(err < 0){
7526 +                       printk("pcap_open : pcap_setfilter failed - '%s'\n", 
7527 +                              pcap_geterr(pri->pcap));
7528 +                       return(-EIO);
7529 +               }
7530 +       }
7531 +       
7532 +       return(PCAP_FD(pri->pcap));
7533 +}
7534 +
7535 +static void pcap_remove(void *data)
7536 +{
7537 +       struct pcap_data *pri = data;
7538 +
7539 +       if(pri->compiled != NULL)
7540 +               pcap_freecode(pri->compiled);
7541 +
7542 +       pcap_close(pri->pcap);
7543 +}
7544 +
7545 +struct pcap_handler_data {
7546 +       char *buffer;
7547 +       int len;
7548 +};
7549 +
7550 +static void handler(u_char *data, const struct pcap_pkthdr *header, 
7551 +                   const u_char *packet)
7552 +{
7553 +       int len;
7554 +
7555 +       struct pcap_handler_data *hdata = (struct pcap_handler_data *) data;
7556 +
7557 +       len = hdata->len < header->caplen ? hdata->len : header->caplen;
7558 +       memcpy(hdata->buffer, packet, len);
7559 +       hdata->len = len;
7560 +}
7561 +
7562 +int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
7563 +{
7564 +       struct pcap_handler_data hdata = ((struct pcap_handler_data)
7565 +                                         { .buffer     = buffer,
7566 +                                           .len        = len });
7567 +       int n;
7568 +
7569 +       n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
7570 +       if(n < 0){
7571 +               printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap));
7572 +               return(-EIO);
7573 +       }
7574 +       else if(n == 0) 
7575 +               return(0);
7576 +       return(hdata.len);
7577 +}
7578 +
7579 +struct net_user_info pcap_user_info = {
7580 +       .init           = pcap_user_init,
7581 +       .open           = pcap_open,
7582 +       .close          = NULL,
7583 +       .remove         = pcap_remove,
7584 +       .set_mtu        = NULL,
7585 +       .add_address    = NULL,
7586 +       .delete_address = NULL,
7587 +       .max_packet     = MAX_PACKET - ETH_HEADER_OTHER
7588 +};
7589 +
7590 +/*
7591 + * Overrides for Emacs so that we follow Linus's tabbing style.
7592 + * Emacs will notice this stuff at the end of the file and automatically
7593 + * adjust the settings for this buffer only.  This must remain at the end
7594 + * of the file.
7595 + * ---------------------------------------------------------------------------
7596 + * Local variables:
7597 + * c-file-style: "linux"
7598 + * End:
7599 + */
7600 Index: linux-2.4.29/arch/um/drivers/pcap_user.h
7601 ===================================================================
7602 --- linux-2.4.29.orig/arch/um/drivers/pcap_user.h       1970-01-01 03:00:00.000000000 +0300
7603 +++ linux-2.4.29/arch/um/drivers/pcap_user.h    2005-05-03 22:28:14.000000000 +0300
7604 @@ -0,0 +1,31 @@
7605 +/* 
7606 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7607 + * Licensed under the GPL
7608 + */
7609 +
7610 +#include "net_user.h"
7611 +
7612 +struct pcap_data {
7613 +       char *host_if;
7614 +       int promisc;
7615 +       int optimize;
7616 +       char *filter;
7617 +       void *compiled;
7618 +       void *pcap;
7619 +       void *dev;
7620 +};
7621 +
7622 +extern struct net_user_info pcap_user_info;
7623 +
7624 +extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
7625 +
7626 +/*
7627 + * Overrides for Emacs so that we follow Linus's tabbing style.
7628 + * Emacs will notice this stuff at the end of the file and automatically
7629 + * adjust the settings for this buffer only.  This must remain at the end
7630 + * of the file.
7631 + * ---------------------------------------------------------------------------
7632 + * Local variables:
7633 + * c-file-style: "linux"
7634 + * End:
7635 + */
7636 Index: linux-2.4.29/arch/um/drivers/port.h
7637 ===================================================================
7638 --- linux-2.4.29.orig/arch/um/drivers/port.h    1970-01-01 03:00:00.000000000 +0300
7639 +++ linux-2.4.29/arch/um/drivers/port.h 2005-05-03 22:28:14.234446248 +0300
7640 @@ -0,0 +1,30 @@
7641 +/* 
7642 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
7643 + * Licensed under the GPL
7644 + */
7645 +
7646 +#ifndef __PORT_H__
7647 +#define __PORT_H__
7648 +
7649 +extern void *port_data(int port);
7650 +extern int port_wait(void *data);
7651 +extern void port_kern_close(void *d);
7652 +extern int port_connection(int fd, int *socket_out, int *pid_out);
7653 +extern int port_listen_fd(int port);
7654 +extern void port_read(int fd, void *data);
7655 +extern void port_kern_free(void *d);
7656 +extern int port_rcv_fd(int fd);
7657 +extern void port_remove_dev(void *d);
7658 +
7659 +#endif
7660 +
7661 +/*
7662 + * Overrides for Emacs so that we follow Linus's tabbing style.
7663 + * Emacs will notice this stuff at the end of the file and automatically
7664 + * adjust the settings for this buffer only.  This must remain at the end
7665 + * of the file.
7666 + * ---------------------------------------------------------------------------
7667 + * Local variables:
7668 + * c-file-style: "linux"
7669 + * End:
7670 + */
7671 Index: linux-2.4.29/arch/um/drivers/port_kern.c
7672 ===================================================================
7673 --- linux-2.4.29.orig/arch/um/drivers/port_kern.c       1970-01-01 03:00:00.000000000 +0300
7674 +++ linux-2.4.29/arch/um/drivers/port_kern.c    2005-05-03 22:28:14.235446096 +0300
7675 @@ -0,0 +1,303 @@
7676 +/* 
7677 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7678 + * Licensed under the GPL
7679 + */
7680 +
7681 +#include "linux/list.h"
7682 +#include "linux/sched.h"
7683 +#include "linux/slab.h"
7684 +#include "linux/irq.h"
7685 +#include "linux/spinlock.h"
7686 +#include "linux/errno.h"
7687 +#include "asm/semaphore.h"
7688 +#include "asm/errno.h"
7689 +#include "kern_util.h"
7690 +#include "kern.h"
7691 +#include "irq_user.h"
7692 +#include "irq_kern.h"
7693 +#include "port.h"
7694 +#include "init.h"
7695 +#include "os.h"
7696 +
7697 +struct port_list {
7698 +       struct list_head list;
7699 +       int has_connection;
7700 +       struct semaphore sem;
7701 +       int port;
7702 +       int fd;
7703 +       spinlock_t lock;
7704 +       struct list_head pending;
7705 +       struct list_head connections;
7706 +};
7707 +
7708 +struct port_dev {
7709 +       struct port_list *port;
7710 +       int helper_pid;
7711 +       int telnetd_pid;
7712 +};
7713 +
7714 +struct connection {
7715 +       struct list_head list;
7716 +       int fd;
7717 +       int helper_pid;
7718 +       int socket[2];
7719 +       int telnetd_pid;
7720 +       struct port_list *port;
7721 +};
7722 +
7723 +static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
7724 +{
7725 +       struct connection *conn = data;
7726 +       int fd;
7727 +
7728 +       fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
7729 +       if(fd < 0){
7730 +               if(fd == -EAGAIN)
7731 +                       return;
7732 +
7733 +               printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 
7734 +                      -fd);
7735 +               os_close_file(conn->fd);
7736 +       }
7737 +
7738 +       list_del(&conn->list);
7739 +
7740 +       conn->fd = fd;
7741 +       list_add(&conn->list, &conn->port->connections);
7742 +
7743 +       up(&conn->port->sem);
7744 +}
7745 +
7746 +static int port_accept(struct port_list *port)
7747 +{
7748 +       struct connection *conn;
7749 +       int fd, socket[2], pid, ret = 0;
7750 +
7751 +       fd = port_connection(port->fd, socket, &pid);
7752 +       if(fd < 0){
7753 +               if(fd != -EAGAIN)
7754 +                       printk(KERN_ERR "port_accept : port_connection "
7755 +                              "returned %d\n", -fd);
7756 +               goto out;
7757 +       }
7758 +
7759 +       conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
7760 +       if(conn == NULL){
7761 +               printk(KERN_ERR "port_accept : failed to allocate "
7762 +                      "connection\n");
7763 +               goto out_close;
7764 +       }
7765 +       *conn = ((struct connection) 
7766 +               { .list         = LIST_HEAD_INIT(conn->list),
7767 +                 .fd           = fd,
7768 +                 .socket       = { socket[0], socket[1] },
7769 +                 .telnetd_pid  = pid,
7770 +                 .port         = port });
7771 +
7772 +       if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, 
7773 +                         SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
7774 +                         "telnetd", conn)){
7775 +               printk(KERN_ERR "port_accept : failed to get IRQ for "
7776 +                      "telnetd\n");
7777 +               goto out_free;
7778 +       }
7779 +
7780 +       list_add(&conn->list, &port->pending);
7781 +       return(1);
7782 +
7783 + out_free:
7784 +       kfree(conn);
7785 + out_close:
7786 +       os_close_file(fd);
7787 +       if(pid != -1) 
7788 +               os_kill_process(pid, 1);
7789 + out:
7790 +       return(ret);
7791 +} 
7792 +
7793 +DECLARE_MUTEX(ports_sem);
7794 +struct list_head ports = LIST_HEAD_INIT(ports);
7795 +
7796 +void port_task_proc(void *unused)
7797 +{
7798 +       struct port_list *port;
7799 +       struct list_head *ele;
7800 +       unsigned long flags;
7801 +
7802 +       save_flags(flags);
7803 +       list_for_each(ele, &ports){
7804 +               port = list_entry(ele, struct port_list, list);
7805 +               if(!port->has_connection)
7806 +                       continue;
7807 +               reactivate_fd(port->fd, ACCEPT_IRQ);
7808 +               while(port_accept(port)) ;
7809 +               port->has_connection = 0;
7810 +       }
7811 +       restore_flags(flags);
7812 +}
7813 +
7814 +struct tq_struct port_task = {
7815 +       .routine        = port_task_proc,
7816 +       .data           = NULL
7817 +};
7818 +
7819 +static void port_interrupt(int irq, void *data, struct pt_regs *regs)
7820 +{
7821 +       struct port_list *port = data;
7822 +
7823 +       port->has_connection = 1;
7824 +       schedule_task(&port_task);
7825 +} 
7826 +
7827 +void *port_data(int port_num)
7828 +{
7829 +       struct list_head *ele;
7830 +       struct port_list *port;
7831 +       struct port_dev *dev = NULL;
7832 +       int fd;
7833 +
7834 +       down(&ports_sem);
7835 +       list_for_each(ele, &ports){
7836 +               port = list_entry(ele, struct port_list, list);
7837 +               if(port->port == port_num) goto found;
7838 +       }
7839 +       port = kmalloc(sizeof(struct port_list), GFP_KERNEL);
7840 +       if(port == NULL){
7841 +               printk(KERN_ERR "Allocation of port list failed\n");
7842 +               goto out;
7843 +       }
7844 +
7845 +       fd = port_listen_fd(port_num);
7846 +       if(fd < 0){
7847 +               printk(KERN_ERR "binding to port %d failed, errno = %d\n",
7848 +                      port_num, -fd);
7849 +               goto out_free;
7850 +       }
7851 +       if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, 
7852 +                         SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "port",
7853 +                         port)){
7854 +               printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
7855 +               goto out_close;
7856 +       }
7857 +
7858 +       *port = ((struct port_list) 
7859 +               { .list                 = LIST_HEAD_INIT(port->list),
7860 +                 .has_connection       = 0,
7861 +                 .sem                  = __SEMAPHORE_INITIALIZER(port->sem, 
7862 +                                                                 0),
7863 +                 .lock                 = SPIN_LOCK_UNLOCKED,
7864 +                 .port                 = port_num,
7865 +                 .fd                   = fd,
7866 +                 .pending              = LIST_HEAD_INIT(port->pending),
7867 +                 .connections          = LIST_HEAD_INIT(port->connections) });
7868 +       list_add(&port->list, &ports);
7869 +
7870 + found:
7871 +       dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL);
7872 +       if(dev == NULL){
7873 +               printk(KERN_ERR "Allocation of port device entry failed\n");
7874 +               goto out;
7875 +       }
7876 +
7877 +       *dev = ((struct port_dev) { .port               = port,
7878 +                                   .helper_pid         = -1,
7879 +                                   .telnetd_pid        = -1 });
7880 +       goto out;
7881 +
7882 + out_free:
7883 +       kfree(port);
7884 + out_close:
7885 +       os_close_file(fd);
7886 + out:
7887 +       up(&ports_sem);
7888 +       return(dev);
7889 +}
7890 +
7891 +int port_wait(void *data)
7892 +{
7893 +       struct port_dev *dev = data;
7894 +       struct connection *conn;
7895 +       struct port_list *port = dev->port;
7896 +       int fd;
7897 +
7898 +       while(1){
7899 +               if(down_interruptible(&port->sem))
7900 +                       return(-ERESTARTSYS);
7901 +
7902 +               spin_lock(&port->lock);
7903 +
7904 +               conn = list_entry(port->connections.next, struct connection, 
7905 +                                 list);
7906 +               list_del(&conn->list);
7907 +               spin_unlock(&port->lock);
7908 +
7909 +               os_shutdown_socket(conn->socket[0], 1, 1);
7910 +               os_close_file(conn->socket[0]);
7911 +               os_shutdown_socket(conn->socket[1], 1, 1);
7912 +               os_close_file(conn->socket[1]); 
7913 +
7914 +               /* This is done here because freeing an IRQ can't be done
7915 +                * within the IRQ handler.  So, pipe_interrupt always ups
7916 +                * the semaphore regardless of whether it got a successful
7917 +                * connection.  Then we loop here throwing out failed 
7918 +                * connections until a good one is found.
7919 +                */
7920 +               free_irq(TELNETD_IRQ, conn);
7921 +
7922 +               if(conn->fd >= 0) break;
7923 +               os_close_file(conn->fd);
7924 +               kfree(conn);
7925 +       }
7926 +
7927 +       fd = conn->fd;
7928 +       dev->helper_pid = conn->helper_pid;
7929 +       dev->telnetd_pid = conn->telnetd_pid;
7930 +       kfree(conn);
7931 +
7932 +       return(fd);
7933 +}
7934 +
7935 +void port_remove_dev(void *d)
7936 +{
7937 +       struct port_dev *dev = d;
7938 +
7939 +       if(dev->helper_pid != -1)
7940 +               os_kill_process(dev->helper_pid, 0);
7941 +       if(dev->telnetd_pid != -1)
7942 +               os_kill_process(dev->telnetd_pid, 1);
7943 +       dev->helper_pid = -1;
7944 +       dev->telnetd_pid = -1;
7945 +}
7946 +
7947 +void port_kern_free(void *d)
7948 +{
7949 +       struct port_dev *dev = d;
7950 +
7951 +       port_remove_dev(dev);
7952 +       kfree(dev);
7953 +}
7954 +
7955 +static void free_port(void)
7956 +{
7957 +       struct list_head *ele;
7958 +       struct port_list *port;
7959 +
7960 +       list_for_each(ele, &ports){
7961 +               port = list_entry(ele, struct port_list, list);
7962 +               free_irq_by_fd(port->fd);
7963 +               os_close_file(port->fd);
7964 +       }
7965 +}
7966 +
7967 +__uml_exitcall(free_port);
7968 +
7969 +/*
7970 + * Overrides for Emacs so that we follow Linus's tabbing style.
7971 + * Emacs will notice this stuff at the end of the file and automatically
7972 + * adjust the settings for this buffer only.  This must remain at the end
7973 + * of the file.
7974 + * ---------------------------------------------------------------------------
7975 + * Local variables:
7976 + * c-file-style: "linux"
7977 + * End:
7978 + */
7979 Index: linux-2.4.29/arch/um/drivers/port_user.c
7980 ===================================================================
7981 --- linux-2.4.29.orig/arch/um/drivers/port_user.c       1970-01-01 03:00:00.000000000 +0300
7982 +++ linux-2.4.29/arch/um/drivers/port_user.c    2005-05-03 22:28:14.237445792 +0300
7983 @@ -0,0 +1,224 @@
7984 +/* 
7985 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
7986 + * Licensed under the GPL
7987 + */
7988 +
7989 +#include <stdio.h>
7990 +#include <stddef.h>
7991 +#include <stdlib.h>
7992 +#include <string.h>
7993 +#include <errno.h>
7994 +#include <unistd.h>
7995 +#include <termios.h>
7996 +#include <sys/socket.h>
7997 +#include <sys/un.h>
7998 +#include <netinet/in.h>
7999 +#include "user_util.h"
8000 +#include "kern_util.h"
8001 +#include "user.h"
8002 +#include "chan_user.h"
8003 +#include "port.h"
8004 +#include "helper.h"
8005 +#include "os.h"
8006 +
8007 +struct port_chan {
8008 +       int raw;
8009 +       struct termios tt;
8010 +       void *kernel_data;
8011 +       char dev[sizeof("32768\0")];
8012 +};
8013 +
8014 +void *port_init(char *str, int device, struct chan_opts *opts)
8015 +{
8016 +       struct port_chan *data;
8017 +       void *kern_data;
8018 +       char *end;
8019 +       int port;
8020 +
8021 +       if(*str != ':'){
8022 +               printk("port_init : channel type 'port' must specify a "
8023 +                      "port number\n");
8024 +               return(NULL);
8025 +       }
8026 +       str++;
8027 +       port = strtoul(str, &end, 0);
8028 +       if((*end != '\0') || (end == str)){
8029 +               printk("port_init : couldn't parse port '%s'\n", str);
8030 +               return(NULL);
8031 +       }
8032 +
8033 +       kern_data = port_data(port);
8034 +       if(kern_data == NULL) 
8035 +               return(NULL);
8036 +
8037 +       data = um_kmalloc(sizeof(*data));
8038 +       if(data == NULL) 
8039 +               goto err;
8040 +
8041 +       *data = ((struct port_chan) { .raw              = opts->raw,
8042 +                                     .kernel_data      = kern_data });
8043 +       sprintf(data->dev, "%d", port);
8044 +
8045 +       return(data);
8046 + err:
8047 +       port_kern_free(kern_data);
8048 +       return(NULL);
8049 +}
8050 +
8051 +void port_free(void *d)
8052 +{
8053 +       struct port_chan *data = d;
8054 +
8055 +       port_kern_free(data->kernel_data);
8056 +       kfree(data);
8057 +}
8058 +
8059 +int port_open(int input, int output, int primary, void *d, char **dev_out)
8060 +{
8061 +       struct port_chan *data = d;
8062 +       int fd, err;
8063 +
8064 +       fd = port_wait(data->kernel_data);
8065 +       if((fd >= 0) && data->raw){
8066 +               CATCH_EINTR(err = tcgetattr(fd, &data->tt));
8067 +               if(err)
8068 +                       return(err);
8069 +
8070 +               err = raw(fd);
8071 +               if(err)
8072 +                       return(err);
8073 +       }
8074 +       *dev_out = data->dev;
8075 +       return(fd);
8076 +}
8077 +
8078 +void port_close(int fd, void *d)
8079 +{
8080 +       struct port_chan *data = d;
8081 +
8082 +       port_remove_dev(data->kernel_data);
8083 +       os_close_file(fd);
8084 +}
8085 +
8086 +int port_console_write(int fd, const char *buf, int n, void *d)
8087 +{
8088 +       struct port_chan *data = d;
8089 +
8090 +       return(generic_console_write(fd, buf, n, &data->tt));
8091 +}
8092 +
8093 +struct chan_ops port_ops = {
8094 +       .type           = "port",
8095 +       .init           = port_init,
8096 +       .open           = port_open,
8097 +       .close          = port_close,
8098 +       .read           = generic_read,
8099 +       .write          = generic_write,
8100 +       .console_write  = port_console_write,
8101 +       .window_size    = generic_window_size,
8102 +       .free           = port_free,
8103 +       .winch          = 1,
8104 +};
8105 +
8106 +int port_listen_fd(int port)
8107 +{
8108 +       struct sockaddr_in addr;
8109 +       int fd, err, arg;
8110 +
8111 +       fd = socket(PF_INET, SOCK_STREAM, 0);
8112 +       if(fd == -1) 
8113 +               return(-errno);
8114 +
8115 +       arg = 1;
8116 +       if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0){
8117 +               err = -errno;
8118 +               goto out;
8119 +       }
8120 +
8121 +       addr.sin_family = AF_INET;
8122 +       addr.sin_port = htons(port);
8123 +       addr.sin_addr.s_addr = htonl(INADDR_ANY);
8124 +       if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){
8125 +               err = -errno;
8126 +               goto out;
8127 +       }
8128 +  
8129 +       if(listen(fd, 1) < 0){
8130 +               err = -errno;
8131 +               goto out;
8132 +       }
8133 +
8134 +       err = os_set_fd_block(fd, 0);
8135 +       if(err < 0)
8136 +               goto out;
8137 +
8138 +       return(fd);
8139 + out:
8140 +       os_close_file(fd);
8141 +       return(err);
8142 +}
8143 +
8144 +struct port_pre_exec_data {
8145 +       int sock_fd;
8146 +       int pipe_fd;
8147 +};
8148 +
8149 +void port_pre_exec(void *arg)
8150 +{
8151 +       struct port_pre_exec_data *data = arg;
8152 +
8153 +       dup2(data->sock_fd, 0);
8154 +       dup2(data->sock_fd, 1);
8155 +       dup2(data->sock_fd, 2);
8156 +       os_close_file(data->sock_fd);
8157 +       dup2(data->pipe_fd, 3);
8158 +       os_shutdown_socket(3, 1, 0);
8159 +       os_close_file(data->pipe_fd);
8160 +}
8161 +
8162 +int port_connection(int fd, int *socket, int *pid_out)
8163 +{
8164 +       int new, err;
8165 +       char *argv[] = { "/usr/sbin/in.telnetd", "-L", 
8166 +                        "/usr/lib/uml/port-helper", NULL };
8167 +       struct port_pre_exec_data data;
8168 +
8169 +       new = os_accept_connection(fd);
8170 +       if(new < 0)
8171 +               return(new);
8172 +
8173 +       err = os_pipe(socket, 0, 0);
8174 +       if(err < 0) 
8175 +               goto out_close;
8176 +
8177 +       data = ((struct port_pre_exec_data)
8178 +               { .sock_fd              = new,
8179 +                 .pipe_fd              = socket[1] });
8180 +
8181 +       err = run_helper(port_pre_exec, &data, argv, NULL);
8182 +       if(err < 0) 
8183 +               goto out_shutdown;
8184 +
8185 +       *pid_out = err;
8186 +       return(new);
8187 +
8188 + out_shutdown:
8189 +       os_shutdown_socket(socket[0], 1, 1);
8190 +       os_close_file(socket[0]);
8191 +       os_shutdown_socket(socket[1], 1, 1);    
8192 +       os_close_file(socket[1]);
8193 + out_close:
8194 +       os_close_file(new);
8195 +       return(err);
8196 +}
8197 +
8198 +/*
8199 + * Overrides for Emacs so that we follow Linus's tabbing style.
8200 + * Emacs will notice this stuff at the end of the file and automatically
8201 + * adjust the settings for this buffer only.  This must remain at the end
8202 + * of the file.
8203 + * ---------------------------------------------------------------------------
8204 + * Local variables:
8205 + * c-file-style: "linux"
8206 + * End:
8207 + */
8208 Index: linux-2.4.29/arch/um/drivers/pty.c
8209 ===================================================================
8210 --- linux-2.4.29.orig/arch/um/drivers/pty.c     1970-01-01 03:00:00.000000000 +0300
8211 +++ linux-2.4.29/arch/um/drivers/pty.c  2005-05-03 22:28:14.238445640 +0300
8212 @@ -0,0 +1,159 @@
8213 +/* 
8214 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
8215 + * Licensed under the GPL
8216 + */
8217 +
8218 +#include <stdio.h>
8219 +#include <unistd.h>
8220 +#include <string.h>
8221 +#include <errno.h>
8222 +#include <termios.h>
8223 +#include "chan_user.h"
8224 +#include "user.h"
8225 +#include "user_util.h"
8226 +#include "kern_util.h"
8227 +#include "os.h"
8228 +
8229 +struct pty_chan {
8230 +       void (*announce)(char *dev_name, int dev);
8231 +       int dev;
8232 +       int raw;
8233 +       struct termios tt;
8234 +       char dev_name[sizeof("/dev/pts/0123456\0")];
8235 +};
8236 +
8237 +void *pty_chan_init(char *str, int device, struct chan_opts *opts)
8238 +{
8239 +       struct pty_chan *data;
8240 +
8241 +       data = um_kmalloc(sizeof(*data));
8242 +       if(data == NULL) return(NULL);
8243 +       *data = ((struct pty_chan) { .announce          = opts->announce, 
8244 +                                    .dev               = device,
8245 +                                    .raw               = opts->raw });
8246 +       return(data);
8247 +}
8248 +
8249 +int pts_open(int input, int output, int primary, void *d, char **dev_out)
8250 +{
8251 +       struct pty_chan *data = d;
8252 +       char *dev;
8253 +       int fd, err;
8254 +
8255 +       fd = get_pty();
8256 +       if(fd < 0){
8257 +               printk("open_pts : Failed to open pts\n");
8258 +               return(-errno);
8259 +       }
8260 +       if(data->raw){
8261 +               CATCH_EINTR(err = tcgetattr(fd, &data->tt));
8262 +               if(err)
8263 +                       return(err);
8264 +
8265 +               err = raw(fd);
8266 +               if(err)
8267 +                       return(err);
8268 +       }
8269 +
8270 +       dev = ptsname(fd);
8271 +       sprintf(data->dev_name, "%s", dev);
8272 +       *dev_out = data->dev_name;
8273 +       if(data->announce) (*data->announce)(dev, data->dev);
8274 +       return(fd);
8275 +}
8276 +
8277 +int getmaster(char *line)
8278 +{
8279 +       char *pty, *bank, *cp;
8280 +       int master, err;
8281 +
8282 +       pty = &line[strlen("/dev/ptyp")];
8283 +       for (bank = "pqrs"; *bank; bank++) {
8284 +               line[strlen("/dev/pty")] = *bank;
8285 +               *pty = '0';
8286 +               if (os_stat_file(line, NULL) < 0)
8287 +                       break;
8288 +               for (cp = "0123456789abcdef"; *cp; cp++) {
8289 +                       *pty = *cp;
8290 +                       master = os_open_file(line, of_rdwr(OPENFLAGS()), 0);
8291 +                       if (master >= 0) {
8292 +                               char *tp = &line[strlen("/dev/")];
8293 +
8294 +                               /* verify slave side is usable */
8295 +                               *tp = 't';
8296 +                               err = os_access(line, OS_ACC_RW_OK);
8297 +                               *tp = 'p';
8298 +                               if(err == 0) return(master);
8299 +                               (void) os_close_file(master);
8300 +                       }
8301 +               }
8302 +       }
8303 +       return(-1);
8304 +}
8305 +
8306 +int pty_open(int input, int output, int primary, void *d, char **dev_out)
8307 +{
8308 +       struct pty_chan *data = d;
8309 +       int fd, err;
8310 +       char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
8311 +
8312 +       fd = getmaster(dev);
8313 +       if(fd < 0) 
8314 +               return(-errno);
8315 +       
8316 +       if(data->raw){
8317 +               err = raw(fd);
8318 +               if(err)
8319 +                       return(err);
8320 +       }
8321 +       
8322 +       if(data->announce) (*data->announce)(dev, data->dev);
8323 +
8324 +       sprintf(data->dev_name, "%s", dev);
8325 +       *dev_out = data->dev_name;
8326 +       return(fd);
8327 +}
8328 +
8329 +int pty_console_write(int fd, const char *buf, int n, void *d)
8330 +{
8331 +       struct pty_chan *data = d;
8332 +
8333 +       return(generic_console_write(fd, buf, n, &data->tt));
8334 +}
8335 +
8336 +struct chan_ops pty_ops = {
8337 +       .type           = "pty",
8338 +       .init           = pty_chan_init,
8339 +       .open           = pty_open,
8340 +       .close          = generic_close,
8341 +       .read           = generic_read,
8342 +       .write          = generic_write,
8343 +       .console_write  = pty_console_write,
8344 +       .window_size    = generic_window_size,
8345 +       .free           = generic_free,
8346 +       .winch          = 0,
8347 +};
8348 +
8349 +struct chan_ops pts_ops = {
8350 +       .type           = "pts",
8351 +       .init           = pty_chan_init,
8352 +       .open           = pts_open,
8353 +       .close          = generic_close,
8354 +       .read           = generic_read,
8355 +       .write          = generic_write,
8356 +       .console_write  = pty_console_write,
8357 +       .window_size    = generic_window_size,
8358 +       .free           = generic_free,
8359 +       .winch          = 0,
8360 +};
8361 +
8362 +/*
8363 + * Overrides for Emacs so that we follow Linus's tabbing style.
8364 + * Emacs will notice this stuff at the end of the file and automatically
8365 + * adjust the settings for this buffer only.  This must remain at the end
8366 + * of the file.
8367 + * ---------------------------------------------------------------------------
8368 + * Local variables:
8369 + * c-file-style: "linux"
8370 + * End:
8371 + */
8372 Index: linux-2.4.29/arch/um/drivers/slip.h
8373 ===================================================================
8374 --- linux-2.4.29.orig/arch/um/drivers/slip.h    1970-01-01 03:00:00.000000000 +0300
8375 +++ linux-2.4.29/arch/um/drivers/slip.h 2005-05-03 22:28:14.000000000 +0300
8376 @@ -0,0 +1,39 @@
8377 +#ifndef __UM_SLIP_H
8378 +#define __UM_SLIP_H
8379 +
8380 +#define BUF_SIZE 1500
8381 + /* two bytes each for a (pathological) max packet of escaped chars +  * 
8382 +  * terminating END char + initial END char                            */
8383 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8384 +
8385 +struct slip_data {
8386 +       void *dev;
8387 +       char name[sizeof("slnnnnn\0")];
8388 +       char *addr;
8389 +       char *gate_addr;
8390 +       int slave;
8391 +       char ibuf[ENC_BUF_SIZE];
8392 +       char obuf[ENC_BUF_SIZE];
8393 +       int more; /* more data: do not read fd until ibuf has been drained */
8394 +       int pos;
8395 +       int esc;
8396 +};
8397 +
8398 +extern struct net_user_info slip_user_info;
8399 +
8400 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
8401 +extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri);
8402 +extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri);
8403 +
8404 +#endif
8405 +
8406 +/*
8407 + * Overrides for Emacs so that we follow Linus's tabbing style.
8408 + * Emacs will notice this stuff at the end of the file and automatically
8409 + * adjust the settings for this buffer only.  This must remain at the end
8410 + * of the file.
8411 + * ---------------------------------------------------------------------------
8412 + * Local variables:
8413 + * c-file-style: "linux"
8414 + * End:
8415 + */
8416 Index: linux-2.4.29/arch/um/drivers/slip_kern.c
8417 ===================================================================
8418 --- linux-2.4.29.orig/arch/um/drivers/slip_kern.c       1970-01-01 03:00:00.000000000 +0300
8419 +++ linux-2.4.29/arch/um/drivers/slip_kern.c    2005-05-03 22:28:14.000000000 +0300
8420 @@ -0,0 +1,109 @@
8421 +#include "linux/config.h"
8422 +#include "linux/kernel.h"
8423 +#include "linux/stddef.h"
8424 +#include "linux/init.h"
8425 +#include "linux/netdevice.h"
8426 +#include "linux/if_arp.h"
8427 +#include "net_kern.h"
8428 +#include "net_user.h"
8429 +#include "kern.h"
8430 +#include "slip.h"
8431 +
8432 +struct slip_init {
8433 +       char *gate_addr;
8434 +};
8435 +
8436 +void slip_init(struct net_device *dev, void *data)
8437 +{
8438 +       struct uml_net_private *private;
8439 +       struct slip_data *spri;
8440 +       struct slip_init *init = data;
8441 +
8442 +       private = dev->priv;
8443 +       spri = (struct slip_data *) private->user;
8444 +       *spri = ((struct slip_data)
8445 +               { .name         = { '\0' },
8446 +                 .addr         = NULL,
8447 +                 .gate_addr    = init->gate_addr,
8448 +                 .slave        = -1,
8449 +                 .ibuf         = { '\0' },
8450 +                 .obuf         = { '\0' },
8451 +                 .pos          = 0,
8452 +                 .esc          = 0,
8453 +                 .dev          = dev });
8454 +
8455 +       dev->init = NULL;
8456 +       dev->hard_header_len = 0;
8457 +       dev->addr_len = 4;
8458 +       dev->type = ARPHRD_ETHER;
8459 +       dev->tx_queue_len = 256;
8460 +       dev->flags = IFF_NOARP;
8461 +       printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr);
8462 +}
8463 +
8464 +static unsigned short slip_protocol(struct sk_buff *skbuff)
8465 +{
8466 +       return(htons(ETH_P_IP));
8467 +}
8468 +
8469 +static int slip_read(int fd, struct sk_buff **skb, 
8470 +                      struct uml_net_private *lp)
8471 +{
8472 +       return(slip_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, 
8473 +                             (struct slip_data *) &lp->user));
8474 +}
8475 +
8476 +static int slip_write(int fd, struct sk_buff **skb,
8477 +                     struct uml_net_private *lp)
8478 +{
8479 +       return(slip_user_write(fd, (*skb)->data, (*skb)->len, 
8480 +                              (struct slip_data *) &lp->user));
8481 +}
8482 +
8483 +struct net_kern_info slip_kern_info = {
8484 +       .init                   = slip_init,
8485 +       .protocol               = slip_protocol,
8486 +       .read                   = slip_read,
8487 +       .write                  = slip_write,
8488 +};
8489 +
8490 +static int slip_setup(char *str, char **mac_out, void *data)
8491 +{
8492 +       struct slip_init *init = data;
8493 +
8494 +       *init = ((struct slip_init)
8495 +               { .gate_addr            = NULL });
8496 +
8497 +       if(str[0] != '\0') 
8498 +               init->gate_addr = str;
8499 +       return(1);
8500 +}
8501 +
8502 +static struct transport slip_transport = {
8503 +       .list           = LIST_HEAD_INIT(slip_transport.list),
8504 +       .name           = "slip",
8505 +       .setup          = slip_setup,
8506 +       .user           = &slip_user_info,
8507 +       .kern           = &slip_kern_info,
8508 +       .private_size   = sizeof(struct slip_data),
8509 +       .setup_size     = sizeof(struct slip_init),
8510 +};
8511 +
8512 +static int register_slip(void)
8513 +{
8514 +       register_transport(&slip_transport);
8515 +       return(1);
8516 +}
8517 +
8518 +__initcall(register_slip);
8519 +
8520 +/*
8521 + * Overrides for Emacs so that we follow Linus's tabbing style.
8522 + * Emacs will notice this stuff at the end of the file and automatically
8523 + * adjust the settings for this buffer only.  This must remain at the end
8524 + * of the file.
8525 + * ---------------------------------------------------------------------------
8526 + * Local variables:
8527 + * c-file-style: "linux"
8528 + * End:
8529 + */
8530 Index: linux-2.4.29/arch/um/drivers/slip_proto.h
8531 ===================================================================
8532 --- linux-2.4.29.orig/arch/um/drivers/slip_proto.h      1970-01-01 03:00:00.000000000 +0300
8533 +++ linux-2.4.29/arch/um/drivers/slip_proto.h   2005-05-03 22:28:14.000000000 +0300
8534 @@ -0,0 +1,93 @@
8535 +/* 
8536 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
8537 + * Licensed under the GPL
8538 + */
8539 +
8540 +#ifndef __UM_SLIP_PROTO_H__
8541 +#define __UM_SLIP_PROTO_H__
8542 +
8543 +/* SLIP protocol characters. */
8544 +#define SLIP_END             0300      /* indicates end of frame       */
8545 +#define SLIP_ESC             0333      /* indicates byte stuffing      */
8546 +#define SLIP_ESC_END         0334      /* ESC ESC_END means END 'data' */
8547 +#define SLIP_ESC_ESC         0335      /* ESC ESC_ESC means ESC 'data' */
8548 +
8549 +static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc)
8550 +{
8551 +       int ret;
8552 +
8553 +       switch(c){
8554 +       case SLIP_END:
8555 +               *esc = 0;
8556 +               ret=*pos;
8557 +               *pos=0;
8558 +               return(ret);
8559 +       case SLIP_ESC:
8560 +               *esc = 1;
8561 +               return(0);
8562 +       case SLIP_ESC_ESC:
8563 +               if(*esc){
8564 +                       *esc = 0;
8565 +                       c = SLIP_ESC;
8566 +               }
8567 +               break;
8568 +       case SLIP_ESC_END:
8569 +               if(*esc){
8570 +                       *esc = 0;
8571 +                       c = SLIP_END;
8572 +               }
8573 +               break;
8574 +       }
8575 +       buf[(*pos)++] = c;
8576 +       return(0);
8577 +}
8578 +
8579 +static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
8580 +{
8581 +       unsigned char *ptr = d;
8582 +       unsigned char c;
8583 +
8584 +       /*
8585 +        * Send an initial END character to flush out any
8586 +        * data that may have accumulated in the receiver
8587 +        * due to line noise.
8588 +        */
8589 +
8590 +       *ptr++ = SLIP_END;
8591 +
8592 +       /*
8593 +        * For each byte in the packet, send the appropriate
8594 +        * character sequence, according to the SLIP protocol.
8595 +        */
8596 +
8597 +       while (len-- > 0) {
8598 +               switch(c = *s++) {
8599 +               case SLIP_END:
8600 +                       *ptr++ = SLIP_ESC;
8601 +                       *ptr++ = SLIP_ESC_END;
8602 +                       break;
8603 +               case SLIP_ESC:
8604 +                       *ptr++ = SLIP_ESC;
8605 +                       *ptr++ = SLIP_ESC_ESC;
8606 +                       break;
8607 +               default:
8608 +                       *ptr++ = c;
8609 +                       break;
8610 +               }
8611 +       }
8612 +       *ptr++ = SLIP_END;
8613 +       return (ptr - d);
8614 +}
8615 +
8616 +#endif
8617 +
8618 +/*
8619 + * Overrides for Emacs so that we follow Linus's tabbing style.
8620 + * Emacs will notice this stuff at the end of the file and automatically
8621 + * adjust the settings for this buffer only.  This must remain at the end
8622 + * of the file.
8623 + * ---------------------------------------------------------------------------
8624 + * Local variables:
8625 + * c-file-style: "linux"
8626 + * End:
8627 + */
8628 Index: linux-2.4.29/arch/um/drivers/slip_user.c
8629 ===================================================================
8630 --- linux-2.4.29.orig/arch/um/drivers/slip_user.c       1970-01-01 03:00:00.000000000 +0300
8631 +++ linux-2.4.29/arch/um/drivers/slip_user.c    2005-05-03 22:28:14.000000000 +0300
8632 @@ -0,0 +1,276 @@
8633 +#include <stdio.h>
8634 +#include <stdlib.h>
8635 +#include <unistd.h>
8636 +#include <stddef.h>
8637 +#include <sched.h>
8638 +#include <string.h>
8639 +#include <errno.h>
8640 +#include <sys/termios.h>
8641 +#include <sys/wait.h>
8642 +#include <sys/signal.h>
8643 +#include "user_util.h"
8644 +#include "kern_util.h"
8645 +#include "user.h"
8646 +#include "net_user.h"
8647 +#include "slip.h"
8648 +#include "slip_proto.h"
8649 +#include "helper.h"
8650 +#include "os.h"
8651 +
8652 +void slip_user_init(void *data, void *dev)
8653 +{
8654 +       struct slip_data *pri = data;
8655 +
8656 +       pri->dev = dev;
8657 +}
8658 +
8659 +static int set_up_tty(int fd)
8660 +{
8661 +       int i;
8662 +       struct termios tios;
8663 +
8664 +       if (tcgetattr(fd, &tios) < 0) {
8665 +               printk("could not get initial terminal attributes\n");
8666 +               return(-1);
8667 +       }
8668 +
8669 +       tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
8670 +       tios.c_iflag = IGNBRK | IGNPAR;
8671 +       tios.c_oflag = 0;
8672 +       tios.c_lflag = 0;
8673 +       for (i = 0; i < NCCS; i++)
8674 +               tios.c_cc[i] = 0;
8675 +       tios.c_cc[VMIN] = 1;
8676 +       tios.c_cc[VTIME] = 0;
8677 +
8678 +       cfsetospeed(&tios, B38400);
8679 +       cfsetispeed(&tios, B38400);
8680 +
8681 +       if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
8682 +               printk("failed to set terminal attributes\n");
8683 +               return(-1);
8684 +       }
8685 +       return(0);
8686 +}
8687 +
8688 +struct slip_pre_exec_data {
8689 +       int stdin;
8690 +       int stdout;
8691 +       int close_me;
8692 +};
8693 +
8694 +static void slip_pre_exec(void *arg)
8695 +{
8696 +       struct slip_pre_exec_data *data = arg;
8697 +
8698 +       if(data->stdin >= 0) dup2(data->stdin, 0);
8699 +       dup2(data->stdout, 1);
8700 +       if(data->close_me >= 0) os_close_file(data->close_me);
8701 +}
8702 +
8703 +static int slip_tramp(char **argv, int fd)
8704 +{
8705 +       struct slip_pre_exec_data pe_data;
8706 +       char *output;
8707 +       int status, pid, fds[2], err, output_len;
8708 +
8709 +       err = os_pipe(fds, 1, 0);
8710 +       if(err < 0){
8711 +               printk("slip_tramp : pipe failed, err = %d\n", -err);
8712 +               return(err);
8713 +       }
8714 +
8715 +       err = 0;
8716 +       pe_data.stdin = fd;
8717 +       pe_data.stdout = fds[1];
8718 +       pe_data.close_me = fds[0];
8719 +       pid = run_helper(slip_pre_exec, &pe_data, argv, NULL);
8720 +
8721 +       if(pid < 0) err = pid;
8722 +       else {
8723 +               output_len = page_size();
8724 +               output = um_kmalloc(output_len);
8725 +               if(output == NULL)
8726 +                       printk("slip_tramp : failed to allocate output "
8727 +                              "buffer\n");
8728 +
8729 +               os_close_file(fds[1]);
8730 +               read_output(fds[0], output, output_len);
8731 +               if(output != NULL){
8732 +                       printk("%s", output);
8733 +                       kfree(output);
8734 +               }
8735 +               CATCH_EINTR(err = waitpid(pid, &status, 0));
8736 +               if(err < 0)
8737 +                       err = errno;
8738 +               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
8739 +                       printk("'%s' didn't exit with status 0\n", argv[0]);
8740 +                       err = -EINVAL;
8741 +               }
8742 +       }
8743 +       return(err);
8744 +}
8745 +
8746 +static int slip_open(void *data)
8747 +{
8748 +       struct slip_data *pri = data;
8749 +       char version_buf[sizeof("nnnnn\0")];
8750 +       char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
8751 +       char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf, 
8752 +                        NULL };
8753 +       int sfd, mfd, err;
8754 +
8755 +       mfd = get_pty();
8756 +       if(mfd < 0){
8757 +               printk("umn : Failed to open pty, err = %d\n", -mfd);
8758 +               return(mfd);
8759 +       }
8760 +       sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
8761 +       if(sfd < 0){
8762 +               printk("Couldn't open tty for slip line, err = %d\n", -sfd);
8763 +               return(sfd);
8764 +       }
8765 +       if(set_up_tty(sfd)) return(-1);
8766 +       pri->slave = sfd;
8767 +       pri->pos = 0;
8768 +       pri->esc = 0;
8769 +       if(pri->gate_addr != NULL){
8770 +               sprintf(version_buf, "%d", UML_NET_VERSION);
8771 +               strcpy(gate_buf, pri->gate_addr);
8772 +
8773 +               err = slip_tramp(argv, sfd);
8774 +
8775 +               if(err < 0){
8776 +                       printk("slip_tramp failed - err = %d\n", -err);
8777 +                       return(err);
8778 +               }
8779 +               err = os_get_ifname(pri->slave, pri->name);
8780 +               if(err < 0){
8781 +                       printk("get_ifname failed, err = %d\n", -err);
8782 +                       return(err);
8783 +               }
8784 +               iter_addresses(pri->dev, open_addr, pri->name);
8785 +       }
8786 +       else {
8787 +               err = os_set_slip(sfd);
8788 +               if(err < 0){
8789 +                       printk("Failed to set slip discipline encapsulation - "
8790 +                              "err = %d\n", -err);
8791 +                       return(err);
8792 +               }
8793 +       }
8794 +       return(mfd);
8795 +}
8796 +
8797 +static void slip_close(int fd, void *data)
8798 +{
8799 +       struct slip_data *pri = data;
8800 +       char version_buf[sizeof("nnnnn\0")];
8801 +       char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name, 
8802 +                        NULL };
8803 +       int err;
8804 +
8805 +       if(pri->gate_addr != NULL)
8806 +               iter_addresses(pri->dev, close_addr, pri->name);
8807 +
8808 +       sprintf(version_buf, "%d", UML_NET_VERSION);
8809 +
8810 +       err = slip_tramp(argv, -1);
8811 +
8812 +       if(err != 0)
8813 +               printk("slip_tramp failed - errno = %d\n", -err);
8814 +       os_close_file(fd);
8815 +       os_close_file(pri->slave);
8816 +       pri->slave = -1;
8817 +}
8818 +
8819 +int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
8820 +{
8821 +       int i, n, size, start;
8822 +
8823 +       if(pri->more>0) {
8824 +               i = 0;
8825 +               while(i < pri->more) {
8826 +                       size = slip_unesc(pri->ibuf[i++],
8827 +                                       pri->ibuf, &pri->pos, &pri->esc);
8828 +                       if(size){
8829 +                               memcpy(buf, pri->ibuf, size);
8830 +                               memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
8831 +                               pri->more=pri->more-i; 
8832 +                               return(size);
8833 +                       }
8834 +               }
8835 +               pri->more=0;
8836 +       }
8837 +
8838 +       n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
8839 +       if(n <= 0) return(n);
8840 +
8841 +       start = pri->pos;
8842 +       for(i = 0; i < n; i++){
8843 +               size = slip_unesc(pri->ibuf[start + i],
8844 +                               pri->ibuf, &pri->pos, &pri->esc);
8845 +               if(size){
8846 +                       memcpy(buf, pri->ibuf, size);
8847 +                       memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
8848 +                       pri->more=n-(i+1); 
8849 +                       return(size);
8850 +               }
8851 +       }
8852 +       return(0);
8853 +}
8854 +
8855 +int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
8856 +{
8857 +       int actual, n;
8858 +
8859 +       actual = slip_esc(buf, pri->obuf, len);
8860 +       n = net_write(fd, pri->obuf, actual);
8861 +       if(n < 0) return(n);
8862 +       else return(len);
8863 +}
8864 +
8865 +static int slip_set_mtu(int mtu, void *data)
8866 +{
8867 +       return(mtu);
8868 +}
8869 +
8870 +static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
8871 +                         void *data)
8872 +{
8873 +       struct slip_data *pri = data;
8874 +
8875 +       if(pri->slave < 0) return;
8876 +       open_addr(addr, netmask, pri->name);
8877 +}
8878 +
8879 +static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
8880 +                           void *data)
8881 +{
8882 +       struct slip_data *pri = data;
8883 +
8884 +       if(pri->slave < 0) return;
8885 +       close_addr(addr, netmask, pri->name);
8886 +}
8887 +
8888 +struct net_user_info slip_user_info = {
8889 +       .init           = slip_user_init,
8890 +       .open           = slip_open,
8891 +       .close          = slip_close,
8892 +       .remove         = NULL,
8893 +       .set_mtu        = slip_set_mtu,
8894 +       .add_address    = slip_add_addr,
8895 +       .delete_address = slip_del_addr,
8896 +       .max_packet     = BUF_SIZE
8897 +};
8898 +
8899 +/*
8900 + * Overrides for Emacs so that we follow Linus's tabbing style.
8901 + * Emacs will notice this stuff at the end of the file and automatically
8902 + * adjust the settings for this buffer only.  This must remain at the end
8903 + * of the file.
8904 + * ---------------------------------------------------------------------------
8905 + * Local variables:
8906 + * c-file-style: "linux"
8907 + * End:
8908 + */
8909 Index: linux-2.4.29/arch/um/drivers/slirp.h
8910 ===================================================================
8911 --- linux-2.4.29.orig/arch/um/drivers/slirp.h   1970-01-01 03:00:00.000000000 +0300
8912 +++ linux-2.4.29/arch/um/drivers/slirp.h        2005-05-03 22:28:14.000000000 +0300
8913 @@ -0,0 +1,51 @@
8914 +#ifndef __UM_SLIRP_H
8915 +#define __UM_SLIRP_H
8916 +
8917 +#define BUF_SIZE 1500
8918 + /* two bytes each for a (pathological) max packet of escaped chars +  * 
8919 +  * terminating END char + initial END char                            */
8920 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8921 +
8922 +#define SLIRP_MAX_ARGS 100
8923 +/*
8924 + * XXX this next definition is here because I don't understand why this
8925 + * initializer doesn't work in slirp_kern.c:
8926 + *
8927 + *   argv :  { init->argv[ 0 ... SLIRP_MAX_ARGS-1 ] },
8928 + *
8929 + * or why I can't typecast like this:
8930 + *
8931 + *   argv :  (char* [SLIRP_MAX_ARGS])(init->argv), 
8932 + */
8933 +struct arg_list_dummy_wrapper { char *argv[SLIRP_MAX_ARGS]; };
8934 +
8935 +struct slirp_data {
8936 +       void *dev;
8937 +       struct arg_list_dummy_wrapper argw;
8938 +       int pid;
8939 +       int slave;
8940 +       char ibuf[ENC_BUF_SIZE];
8941 +       char obuf[ENC_BUF_SIZE];
8942 +       int more; /* more data: do not read fd until ibuf has been drained */
8943 +       int pos;
8944 +       int esc;
8945 +};
8946 +
8947 +extern struct net_user_info slirp_user_info;
8948 +
8949 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
8950 +extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri);
8951 +extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri);
8952 +
8953 +#endif
8954 +
8955 +/*
8956 + * Overrides for Emacs so that we follow Linus's tabbing style.
8957 + * Emacs will notice this stuff at the end of the file and automatically
8958 + * adjust the settings for this buffer only.  This must remain at the end
8959 + * of the file.
8960 + * ---------------------------------------------------------------------------
8961 + * Local variables:
8962 + * c-file-style: "linux"
8963 + * End:
8964 + */
8965 Index: linux-2.4.29/arch/um/drivers/slirp_kern.c
8966 ===================================================================
8967 --- linux-2.4.29.orig/arch/um/drivers/slirp_kern.c      1970-01-01 03:00:00.000000000 +0300
8968 +++ linux-2.4.29/arch/um/drivers/slirp_kern.c   2005-05-03 22:28:14.000000000 +0300
8969 @@ -0,0 +1,132 @@
8970 +#include "linux/kernel.h"
8971 +#include "linux/stddef.h"
8972 +#include "linux/init.h"
8973 +#include "linux/netdevice.h"
8974 +#include "linux/if_arp.h"
8975 +#include "net_kern.h"
8976 +#include "net_user.h"
8977 +#include "kern.h"
8978 +#include "slirp.h"
8979 +
8980 +struct slirp_init {
8981 +       struct arg_list_dummy_wrapper argw;  /* XXX should be simpler... */
8982 +};
8983 +
8984 +void slirp_init(struct net_device *dev, void *data)
8985 +{
8986 +       struct uml_net_private *private;
8987 +       struct slirp_data *spri;
8988 +       struct slirp_init *init = data;
8989 +       int i;
8990 +
8991 +       private = dev->priv;
8992 +       spri = (struct slirp_data *) private->user;
8993 +       *spri = ((struct slirp_data)
8994 +               { .argw         = init->argw,
8995 +                 .pid          = -1,
8996 +                 .slave        = -1,
8997 +                 .ibuf         = { '\0' },
8998 +                 .obuf         = { '\0' },
8999 +                 .pos          = 0,
9000 +                 .esc          = 0,
9001 +                 .dev          = dev });
9002 +
9003 +       dev->init = NULL;
9004 +       dev->hard_header_len = 0;
9005 +       dev->addr_len = 4;
9006 +       dev->type = ARPHRD_ETHER;
9007 +       dev->tx_queue_len = 256;
9008 +       dev->flags = IFF_NOARP;
9009 +       printk("SLIRP backend - command line:");
9010 +       for(i=0;spri->argw.argv[i]!=NULL;i++) {
9011 +               printk(" '%s'",spri->argw.argv[i]);
9012 +       }
9013 +       printk("\n");
9014 +}
9015 +
9016 +static unsigned short slirp_protocol(struct sk_buff *skbuff)
9017 +{
9018 +       return(htons(ETH_P_IP));
9019 +}
9020 +
9021 +static int slirp_read(int fd, struct sk_buff **skb, 
9022 +                      struct uml_net_private *lp)
9023 +{
9024 +       return(slirp_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, 
9025 +                             (struct slirp_data *) &lp->user));
9026 +}
9027 +
9028 +static int slirp_write(int fd, struct sk_buff **skb,
9029 +                     struct uml_net_private *lp)
9030 +{
9031 +       return(slirp_user_write(fd, (*skb)->data, (*skb)->len, 
9032 +                              (struct slirp_data *) &lp->user));
9033 +}
9034 +
9035 +struct net_kern_info slirp_kern_info = {
9036 +       .init                   = slirp_init,
9037 +       .protocol               = slirp_protocol,
9038 +       .read                   = slirp_read,
9039 +       .write                  = slirp_write,
9040 +};
9041 +
9042 +static int slirp_setup(char *str, char **mac_out, void *data)
9043 +{
9044 +       struct slirp_init *init = data;
9045 +       int i=0;
9046 +
9047 +       *init = ((struct slirp_init)
9048 +               { argw :                { { "slirp", NULL  } } });
9049 +
9050 +       str = split_if_spec(str, mac_out, NULL);
9051 +
9052 +       if(str == NULL) { /* no command line given after MAC addr */
9053 +               return(1);
9054 +       }
9055 +
9056 +       do {
9057 +               if(i>=SLIRP_MAX_ARGS-1) {
9058 +                       printk("slirp_setup: truncating slirp arguments\n");
9059 +                       break;
9060 +               }
9061 +               init->argw.argv[i++] = str;
9062 +               while(*str && *str!=',') {
9063 +                       if(*str=='_') *str=' ';
9064 +                       str++;
9065 +               }
9066 +               if(*str!=',')
9067 +                       break;
9068 +               *str++='\0';
9069 +       } while(1);
9070 +       init->argw.argv[i]=NULL;
9071 +       return(1);
9072 +}
9073 +
9074 +static struct transport slirp_transport = {
9075 +       .list           = LIST_HEAD_INIT(slirp_transport.list),
9076 +       .name           = "slirp",
9077 +       .setup          = slirp_setup,
9078 +       .user           = &slirp_user_info,
9079 +       .kern           = &slirp_kern_info,
9080 +       .private_size   = sizeof(struct slirp_data),
9081 +       .setup_size     = sizeof(struct slirp_init),
9082 +};
9083 +
9084 +static int register_slirp(void)
9085 +{
9086 +       register_transport(&slirp_transport);
9087 +       return(1);
9088 +}
9089 +
9090 +__initcall(register_slirp);
9091 +
9092 +/*
9093 + * Overrides for Emacs so that we follow Linus's tabbing style.
9094 + * Emacs will notice this stuff at the end of the file and automatically
9095 + * adjust the settings for this buffer only.  This must remain at the end
9096 + * of the file.
9097 + * ---------------------------------------------------------------------------
9098 + * Local variables:
9099 + * c-file-style: "linux"
9100 + * End:
9101 + */
9102 Index: linux-2.4.29/arch/um/drivers/slirp_user.c
9103 ===================================================================
9104 --- linux-2.4.29.orig/arch/um/drivers/slirp_user.c      1970-01-01 03:00:00.000000000 +0300
9105 +++ linux-2.4.29/arch/um/drivers/slirp_user.c   2005-05-03 22:28:14.000000000 +0300
9106 @@ -0,0 +1,201 @@
9107 +#include <stdio.h>
9108 +#include <stdlib.h>
9109 +#include <unistd.h>
9110 +#include <stddef.h>
9111 +#include <sched.h>
9112 +#include <string.h>
9113 +#include <errno.h>
9114 +#include <sys/wait.h>
9115 +#include <sys/signal.h>
9116 +#include "user_util.h"
9117 +#include "kern_util.h"
9118 +#include "user.h"
9119 +#include "net_user.h"
9120 +#include "slirp.h"
9121 +#include "slip_proto.h"
9122 +#include "helper.h"
9123 +#include "os.h"
9124 +
9125 +void slirp_user_init(void *data, void *dev)
9126 +{
9127 +       struct slirp_data *pri = data;
9128 +
9129 +       pri->dev = dev;
9130 +}
9131 +
9132 +struct slirp_pre_exec_data {
9133 +       int stdin;
9134 +       int stdout;
9135 +};
9136 +
9137 +static void slirp_pre_exec(void *arg)
9138 +{
9139 +       struct slirp_pre_exec_data *data = arg;
9140 +
9141 +       if(data->stdin != -1) dup2(data->stdin, 0);
9142 +       if(data->stdout != -1) dup2(data->stdout, 1);
9143 +}
9144 +
9145 +static int slirp_tramp(char **argv, int fd)
9146 +{
9147 +       struct slirp_pre_exec_data pe_data;
9148 +       int pid;
9149 +
9150 +       pe_data.stdin = fd;
9151 +       pe_data.stdout = fd;
9152 +       pid = run_helper(slirp_pre_exec, &pe_data, argv, NULL);
9153 +
9154 +       return(pid);
9155 +}
9156 +
9157 +/* XXX This is just a trivial wrapper around os_pipe */ 
9158 +static int slirp_datachan(int *mfd, int *sfd)
9159 +{
9160 +       int fds[2], err;
9161 +
9162 +       err = os_pipe(fds, 1, 1);
9163 +       if(err < 0){
9164 +               printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
9165 +               return(err);
9166 +       }
9167 +
9168 +       *mfd = fds[0];
9169 +       *sfd = fds[1];
9170 +       return(0);
9171 +}
9172 +
9173 +static int slirp_open(void *data)
9174 +{
9175 +       struct slirp_data *pri = data;
9176 +       int sfd, mfd, pid, err;
9177 +
9178 +       err = slirp_datachan(&mfd, &sfd);
9179 +       if(err)
9180 +               return(err);
9181 +
9182 +       pid = slirp_tramp(pri->argw.argv, sfd);
9183 +
9184 +       if(pid < 0){
9185 +               printk("slirp_tramp failed - errno = %d\n", -pid);
9186 +               os_close_file(sfd);     
9187 +               os_close_file(mfd);     
9188 +               return(pid);
9189 +       }
9190 +
9191 +       pri->slave = sfd;
9192 +       pri->pos = 0;
9193 +       pri->esc = 0;
9194 +
9195 +       pri->pid = pid;
9196 +
9197 +       return(mfd);
9198 +}
9199 +
9200 +static void slirp_close(int fd, void *data)
9201 +{
9202 +       struct slirp_data *pri = data;
9203 +       int status,err;
9204 +
9205 +       os_close_file(fd);
9206 +       os_close_file(pri->slave);
9207 +
9208 +       pri->slave = -1;
9209 +
9210 +       if(pri->pid<1) {
9211 +               printk("slirp_close: no child process to shut down\n");
9212 +               return;
9213 +       }
9214 +
9215 +#if 0
9216 +       if(kill(pri->pid, SIGHUP)<0) {
9217 +               printk("slirp_close: sending hangup to %d failed (%d)\n",
9218 +                       pri->pid, errno);
9219 +       }
9220 +#endif
9221 +
9222 +       CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG));
9223 +       if(err < 0) {
9224 +               printk("slirp_close: waitpid returned %d\n", errno);
9225 +               return;
9226 +       }
9227 +
9228 +       if(err == 0) {
9229 +               printk("slirp_close: process %d has not exited\n");
9230 +               return;
9231 +       }
9232 +
9233 +       pri->pid = -1;
9234 +}
9235 +
9236 +int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
9237 +{
9238 +       int i, n, size, start;
9239 +
9240 +       if(pri->more>0) {
9241 +               i = 0;
9242 +               while(i < pri->more) {
9243 +                       size = slip_unesc(pri->ibuf[i++],
9244 +                                       pri->ibuf,&pri->pos,&pri->esc);
9245 +                       if(size){
9246 +                               memcpy(buf, pri->ibuf, size);
9247 +                               memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
9248 +                               pri->more=pri->more-i; 
9249 +                               return(size);
9250 +                       }
9251 +               }
9252 +               pri->more=0;
9253 +       }
9254 +
9255 +       n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
9256 +       if(n <= 0) return(n);
9257 +
9258 +       start = pri->pos;
9259 +       for(i = 0; i < n; i++){
9260 +               size = slip_unesc(pri->ibuf[start + i],
9261 +                               pri->ibuf,&pri->pos,&pri->esc);
9262 +               if(size){
9263 +                       memcpy(buf, pri->ibuf, size);
9264 +                       memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
9265 +                       pri->more=n-(i+1); 
9266 +                       return(size);
9267 +               }
9268 +       }
9269 +       return(0);
9270 +}
9271 +
9272 +int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
9273 +{
9274 +       int actual, n;
9275 +
9276 +       actual = slip_esc(buf, pri->obuf, len);
9277 +       n = net_write(fd, pri->obuf, actual);
9278 +       if(n < 0) return(n);
9279 +       else return(len);
9280 +}
9281 +
9282 +static int slirp_set_mtu(int mtu, void *data)
9283 +{
9284 +       return(mtu);
9285 +}
9286 +
9287 +struct net_user_info slirp_user_info = {
9288 +       .init           = slirp_user_init,
9289 +       .open           = slirp_open,
9290 +       .close          = slirp_close,
9291 +       .remove         = NULL,
9292 +       .set_mtu        = slirp_set_mtu,
9293 +       .add_address    = NULL,
9294 +       .delete_address = NULL,
9295 +       .max_packet     = BUF_SIZE
9296 +};
9297 +
9298 +/*
9299 + * Overrides for Emacs so that we follow Linus's tabbing style.
9300 + * Emacs will notice this stuff at the end of the file and automatically
9301 + * adjust the settings for this buffer only.  This must remain at the end
9302 + * of the file.
9303 + * ---------------------------------------------------------------------------
9304 + * Local variables:
9305 + * c-file-style: "linux"
9306 + * End:
9307 + */
9308 Index: linux-2.4.29/arch/um/drivers/ssl.c
9309 ===================================================================
9310 --- linux-2.4.29.orig/arch/um/drivers/ssl.c     1970-01-01 03:00:00.000000000 +0300
9311 +++ linux-2.4.29/arch/um/drivers/ssl.c  2005-05-03 22:28:14.247444272 +0300
9312 @@ -0,0 +1,300 @@
9313 +/* 
9314 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
9315 + * Licensed under the GPL
9316 + */
9317 +
9318 +#include "linux/config.h"
9319 +#include "linux/fs.h"
9320 +#include "linux/tty.h"
9321 +#include "linux/tty_driver.h"
9322 +#include "linux/major.h"
9323 +#include "linux/mm.h"
9324 +#include "linux/init.h"
9325 +#include "linux/console.h"
9326 +#include "asm/termbits.h"
9327 +#include "asm/irq.h"
9328 +#include "line.h"
9329 +#include "ssl.h"
9330 +#include "chan_kern.h"
9331 +#include "user_util.h"
9332 +#include "kern_util.h"
9333 +#include "kern.h"
9334 +#include "init.h"
9335 +#include "irq_user.h"
9336 +#include "mconsole_kern.h"
9337 +#include "2_5compat.h"
9338 +
9339 +static int ssl_version = 1;
9340 +
9341 +/* Referenced only by tty_driver below - presumably it's locked correctly
9342 + * by the tty driver.
9343 + */
9344 +static int ssl_refcount = 0;
9345 +
9346 +static struct tty_driver ssl_driver;
9347 +
9348 +#define NR_PORTS 64
9349 +
9350 +void ssl_announce(char *dev_name, int dev)
9351 +{
9352 +       printk(KERN_INFO "Serial line %d assigned device '%s'\n", dev,
9353 +              dev_name);
9354 +}
9355 +
9356 +static struct chan_opts opts = {
9357 +       .announce       = ssl_announce,
9358 +       .xterm_title    = "Serial Line #%d",
9359 +       .raw            = 1,
9360 +       .tramp_stack    = 0,
9361 +       .in_kernel      = 1,
9362 +};
9363 +
9364 +static int ssl_config(char *str);
9365 +static int ssl_get_config(char *dev, char *str, int size, char **error_out);
9366 +static int ssl_remove(char *str);
9367 +
9368 +static struct line_driver driver = {
9369 +       .name                   = "UML serial line",
9370 +       .devfs_name             = "tts/%d",
9371 +       .major                  = TTY_MAJOR,
9372 +       .minor_start            = 64,
9373 +       .type                   = TTY_DRIVER_TYPE_SERIAL,
9374 +       .subtype                = 0,
9375 +       .read_irq               = SSL_IRQ,
9376 +       .read_irq_name          = "ssl",
9377 +       .write_irq              = SSL_WRITE_IRQ,
9378 +       .write_irq_name         = "ssl-write",
9379 +       .symlink_from           = "serial",
9380 +       .symlink_to             = "tts",
9381 +       .mc  = {
9382 +               .name           = "ssl",
9383 +               .config         = ssl_config,
9384 +               .get_config     = ssl_get_config,
9385 +               .remove         = ssl_remove,
9386 +       },
9387 +};
9388 +
9389 +/* The array is initialized by line_init, which is an initcall.  The 
9390 + * individual elements are protected by individual semaphores.
9391 + */
9392 +static struct line serial_lines[NR_PORTS] =
9393 +       { [0 ... NR_PORTS - 1] = LINE_INIT(CONFIG_SSL_CHAN, &driver) };
9394 +
9395 +static struct lines lines = LINES_INIT(NR_PORTS);
9396 +
9397 +static int ssl_config(char *str)
9398 +{
9399 +       return(line_config(serial_lines, 
9400 +                          sizeof(serial_lines)/sizeof(serial_lines[0]), str));
9401 +}
9402 +
9403 +static int ssl_get_config(char *dev, char *str, int size, char **error_out)
9404 +{
9405 +       return(line_get_config(dev, serial_lines, 
9406 +                              sizeof(serial_lines)/sizeof(serial_lines[0]), 
9407 +                              str, size, error_out));
9408 +}
9409 +
9410 +static int ssl_remove(char *str)
9411 +{
9412 +       return(line_remove(serial_lines, 
9413 +                          sizeof(serial_lines)/sizeof(serial_lines[0]), str));
9414 +}
9415 +
9416 +int ssl_open(struct tty_struct *tty, struct file *filp)
9417 +{
9418 +       return(line_open(serial_lines, tty, &opts));
9419 +}
9420 +
9421 +static void ssl_close(struct tty_struct *tty, struct file * filp)
9422 +{
9423 +       line_close(serial_lines, tty);
9424 +}
9425 +
9426 +static int ssl_write(struct tty_struct * tty, int from_user,
9427 +                    const unsigned char *buf, int count)
9428 +{
9429 +       return(line_write(serial_lines, tty, from_user, buf, count));
9430 +}
9431 +
9432 +static void ssl_put_char(struct tty_struct *tty, unsigned char ch)
9433 +{
9434 +       line_write(serial_lines, tty, 0, &ch, sizeof(ch));
9435 +}
9436 +
9437 +static void ssl_flush_chars(struct tty_struct *tty)
9438 +{
9439 +       return;
9440 +}
9441 +
9442 +static int ssl_chars_in_buffer(struct tty_struct *tty)
9443 +{
9444 +       return(0);
9445 +}
9446 +
9447 +static void ssl_flush_buffer(struct tty_struct *tty)
9448 +{
9449 +       return;
9450 +}
9451 +
9452 +static int ssl_ioctl(struct tty_struct *tty, struct file * file,
9453 +                    unsigned int cmd, unsigned long arg)
9454 +{
9455 +       int ret;
9456 +
9457 +       ret = 0;
9458 +       switch(cmd){
9459 +       case TCGETS:
9460 +       case TCSETS:
9461 +       case TCFLSH:
9462 +       case TCSETSF:
9463 +       case TCSETSW:
9464 +       case TCGETA:
9465 +       case TIOCMGET:
9466 +       case TCSBRK:
9467 +       case TCSBRKP:
9468 +       case TIOCMSET:
9469 +               ret = -ENOIOCTLCMD;
9470 +               break;
9471 +       default:
9472 +               printk(KERN_ERR 
9473 +                      "Unimplemented ioctl in ssl_ioctl : 0x%x\n", cmd);
9474 +               ret = -ENOIOCTLCMD;
9475 +               break;
9476 +       }
9477 +       return(ret);
9478 +}
9479 +
9480 +static void ssl_throttle(struct tty_struct * tty)
9481 +{
9482 +       printk(KERN_ERR "Someone should implement ssl_throttle\n");
9483 +}
9484 +
9485 +static void ssl_unthrottle(struct tty_struct * tty)
9486 +{
9487 +       printk(KERN_ERR "Someone should implement ssl_unthrottle\n");
9488 +}
9489 +
9490 +static void ssl_set_termios(struct tty_struct *tty, 
9491 +                           struct termios *old_termios)
9492 +{
9493 +}
9494 +
9495 +static void ssl_stop(struct tty_struct *tty)
9496 +{
9497 +       printk(KERN_ERR "Someone should implement ssl_stop\n");
9498 +}
9499 +
9500 +static void ssl_start(struct tty_struct *tty)
9501 +{
9502 +       printk(KERN_ERR "Someone should implement ssl_start\n");
9503 +}
9504 +
9505 +void ssl_hangup(struct tty_struct *tty)
9506 +{
9507 +}
9508 +
9509 +static struct tty_driver ssl_driver = {
9510 +       .refcount               = &ssl_refcount,
9511 +       .open                   = ssl_open,
9512 +       .close                  = ssl_close,
9513 +       .write                  = ssl_write,
9514 +       .put_char               = ssl_put_char,
9515 +       .flush_chars            = ssl_flush_chars,
9516 +       .chars_in_buffer        = ssl_chars_in_buffer,
9517 +       .flush_buffer           = ssl_flush_buffer,
9518 +       .ioctl                  = ssl_ioctl,
9519 +       .throttle               = ssl_throttle,
9520 +       .unthrottle             = ssl_unthrottle,
9521 +       .set_termios            = ssl_set_termios,
9522 +       .stop                   = ssl_stop,
9523 +       .start                  = ssl_start,
9524 +       .hangup                 = ssl_hangup
9525 +};
9526 +
9527 +/* Changed by ssl_init and referenced by ssl_exit, which are both serialized
9528 + * by being an initcall and exitcall, respectively.
9529 + */
9530 +static int ssl_init_done = 0;
9531 +
9532 +static void ssl_console_write(struct console *c, const char *string, 
9533 +                             unsigned len)
9534 +{
9535 +       struct line *line = &serial_lines[c->index];
9536 +       if(ssl_init_done)
9537 +               down(&line->sem);
9538 +       console_write_chan(&line->chan_list, string, len);
9539 +       if(ssl_init_done)
9540 +               up(&line->sem);
9541 +}
9542 +
9543 +static kdev_t ssl_console_device(struct console *c)
9544 +{
9545 +       return mk_kdev(TTY_MAJOR, c->index);
9546 +}
9547 +
9548 +static int ssl_console_setup(struct console *co, char *options)
9549 +{
9550 +       return(0);
9551 +}
9552 +
9553 +static struct console ssl_cons = {
9554 +       name:           "ttyS",
9555 +       write:          ssl_console_write,
9556 +       device:         ssl_console_device,
9557 +       setup:          ssl_console_setup,
9558 +       flags:          CON_PRINTBUFFER,
9559 +       index:          -1,
9560 +};
9561 +
9562 +int ssl_init(void)
9563 +{
9564 +       char *new_title;
9565 +
9566 +       printk(KERN_INFO "Initializing software serial port version %d\n", 
9567 +              ssl_version);
9568 +
9569 +       line_register_devfs(&lines, &driver, &ssl_driver, serial_lines, 
9570 +                           sizeof(serial_lines)/sizeof(serial_lines[0]));
9571 +
9572 +       lines_init(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]));
9573 +
9574 +       new_title = add_xterm_umid(opts.xterm_title);
9575 +       if(new_title != NULL) opts.xterm_title = new_title;
9576 +
9577 +       register_console(&ssl_cons);
9578 +       ssl_init_done = 1;
9579 +       return(0);
9580 +}
9581 +
9582 +__initcall(ssl_init);
9583 +
9584 +static int ssl_chan_setup(char *str)
9585 +{
9586 +       return(line_setup(serial_lines, 
9587 +                         sizeof(serial_lines)/sizeof(serial_lines[0]), 
9588 +                         str, 1));
9589 +}
9590 +
9591 +__setup("ssl", ssl_chan_setup);
9592 +__channel_help(ssl_chan_setup, "ssl");
9593 +
9594 +static void ssl_exit(void)
9595 +{
9596 +       if(!ssl_init_done) return;
9597 +       close_lines(serial_lines, 
9598 +                   sizeof(serial_lines)/sizeof(serial_lines[0]));
9599 +}
9600 +
9601 +__uml_exitcall(ssl_exit);
9602 +
9603 +/*
9604 + * Overrides for Emacs so that we follow Linus's tabbing style.
9605 + * Emacs will notice this stuff at the end of the file and automatically
9606 + * adjust the settings for this buffer only.  This must remain at the end
9607 + * of the file.
9608 + * ---------------------------------------------------------------------------
9609 + * Local variables:
9610 + * c-file-style: "linux"
9611 + * End:
9612 + */
9613 Index: linux-2.4.29/arch/um/drivers/ssl.h
9614 ===================================================================
9615 --- linux-2.4.29.orig/arch/um/drivers/ssl.h     1970-01-01 03:00:00.000000000 +0300
9616 +++ linux-2.4.29/arch/um/drivers/ssl.h  2005-05-03 22:28:14.248444120 +0300
9617 @@ -0,0 +1,23 @@
9618 +/* 
9619 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9620 + * Licensed under the GPL
9621 + */
9622 +
9623 +#ifndef __SSL_H__
9624 +#define __SSL_H__
9625 +
9626 +extern int ssl_read(int fd, int line);
9627 +extern void ssl_receive_char(int line, char ch);
9628 +
9629 +#endif
9630 +
9631 +/*
9632 + * Overrides for Emacs so that we follow Linus's tabbing style.
9633 + * Emacs will notice this stuff at the end of the file and automatically
9634 + * adjust the settings for this buffer only.  This must remain at the end
9635 + * of the file.
9636 + * ---------------------------------------------------------------------------
9637 + * Local variables:
9638 + * c-file-style: "linux"
9639 + * End:
9640 + */
9641 Index: linux-2.4.29/arch/um/drivers/stdio_console.c
9642 ===================================================================
9643 --- linux-2.4.29.orig/arch/um/drivers/stdio_console.c   1970-01-01 03:00:00.000000000 +0300
9644 +++ linux-2.4.29/arch/um/drivers/stdio_console.c        2005-05-03 22:28:14.249443968 +0300
9645 @@ -0,0 +1,258 @@
9646 +/* 
9647 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
9648 + * Licensed under the GPL
9649 + */
9650 +
9651 +#include "linux/config.h"
9652 +#include "linux/posix_types.h"
9653 +#include "linux/tty.h"
9654 +#include "linux/tty_flip.h"
9655 +#include "linux/types.h"
9656 +#include "linux/major.h"
9657 +#include "linux/kdev_t.h"
9658 +#include "linux/console.h"
9659 +#include "linux/string.h"
9660 +#include "linux/sched.h"
9661 +#include "linux/list.h"
9662 +#include "linux/init.h"
9663 +#include "linux/interrupt.h"
9664 +#include "linux/slab.h"
9665 +#include "asm/current.h"
9666 +#include "asm/softirq.h"
9667 +#include "asm/hardirq.h"
9668 +#include "asm/irq.h"
9669 +#include "stdio_console.h"
9670 +#include "line.h"
9671 +#include "chan_kern.h"
9672 +#include "user_util.h"
9673 +#include "kern_util.h"
9674 +#include "irq_user.h"
9675 +#include "mconsole_kern.h"
9676 +#include "init.h"
9677 +#include "2_5compat.h"
9678 +
9679 +#define MAX_TTYS (8)
9680 +
9681 +/* Referenced only by tty_driver below - presumably it's locked correctly
9682 + * by the tty driver.
9683 + */
9684 +
9685 +static struct tty_driver console_driver;
9686 +
9687 +static int console_refcount = 0;
9688 +
9689 +static struct chan_ops init_console_ops = {
9690 +       .type           = "you shouldn't see this",
9691 +       .init           = NULL,
9692 +       .open           = NULL,
9693 +       .close          = NULL,
9694 +       .read           = NULL,
9695 +       .write          = NULL,
9696 +       .console_write  = generic_write,
9697 +       .window_size    = NULL,
9698 +       .free           = NULL,
9699 +       .winch          = 0,
9700 +};
9701 +
9702 +static struct chan init_console_chan = {
9703 +       .list           = { },
9704 +       .primary        = 1,
9705 +       .input          = 0,
9706 +       .output         = 1,
9707 +       .opened         = 1,
9708 +       .fd             = 1,
9709 +       .pri            = INIT_STATIC,
9710 +       .ops            = &init_console_ops,
9711 +       .data           = NULL
9712 +};
9713 +
9714 +void stdio_announce(char *dev_name, int dev)
9715 +{
9716 +       printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
9717 +              dev_name);
9718 +}
9719 +
9720 +static struct chan_opts opts = {
9721 +       .announce       = stdio_announce,
9722 +       .xterm_title    = "Virtual Console #%d",
9723 +       .raw            = 1,
9724 +       .tramp_stack    = 0,
9725 +       .in_kernel      = 1,
9726 +};
9727 +
9728 +static int con_config(char *str);
9729 +static int con_get_config(char *dev, char *str, int size, char **error_out);
9730 +static int con_remove(char *str);
9731 +
9732 +static struct line_driver driver = {
9733 +       .name                   = "UML console",
9734 +       .devfs_name             = "vc/%d",
9735 +       .major                  = TTY_MAJOR,
9736 +       .minor_start            = 0,
9737 +       .type                   = TTY_DRIVER_TYPE_CONSOLE,
9738 +       .subtype                = SYSTEM_TYPE_CONSOLE,
9739 +       .read_irq               = CONSOLE_IRQ,
9740 +       .read_irq_name          = "console",
9741 +       .write_irq              = CONSOLE_WRITE_IRQ,
9742 +       .write_irq_name         = "console-write",
9743 +       .symlink_from           = "ttys",
9744 +       .symlink_to             = "vc",
9745 +       .mc  = {
9746 +               .name           = "con",
9747 +               .config         = con_config,
9748 +               .get_config     = con_get_config,
9749 +               .remove         = con_remove,
9750 +       },
9751 +};
9752 +
9753 +static struct lines console_lines = LINES_INIT(MAX_TTYS);
9754 +
9755 +/* The array is initialized by line_init, which is an initcall.  The 
9756 + * individual elements are protected by individual semaphores.
9757 + */
9758 +struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
9759 +                             [ 1 ... MAX_TTYS - 1 ] = 
9760 +                             LINE_INIT(CONFIG_CON_CHAN, &driver) };
9761 +
9762 +static int con_config(char *str)
9763 +{
9764 +       return(line_config(vts, sizeof(vts)/sizeof(vts[0]), str));
9765 +}
9766 +
9767 +static int con_get_config(char *dev, char *str, int size, char **error_out)
9768 +{
9769 +       return(line_get_config(dev, vts, sizeof(vts)/sizeof(vts[0]), str, 
9770 +                              size, error_out));
9771 +}
9772 +
9773 +static int con_remove(char *str)
9774 +{
9775 +       return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str));
9776 +}
9777 +
9778 +static int open_console(struct tty_struct *tty)
9779 +{
9780 +       return(line_open(vts, tty, &opts));
9781 +}
9782 +
9783 +static int con_open(struct tty_struct *tty, struct file *filp)
9784 +{
9785 +       return(open_console(tty));
9786 +}
9787 +
9788 +static void con_close(struct tty_struct *tty, struct file *filp)
9789 +{
9790 +       line_close(vts, tty);
9791 +}
9792 +
9793 +static int con_write(struct tty_struct *tty, int from_user, 
9794 +                    const unsigned char *buf, int count)
9795 +{
9796 +        return(line_write(vts, tty, from_user, buf, count));
9797 +}
9798 +
9799 +static void set_termios(struct tty_struct *tty, struct termios * old)
9800 +{
9801 +}
9802 +
9803 +static int chars_in_buffer(struct tty_struct *tty)
9804 +{
9805 +       return(0);
9806 +}
9807 +
9808 +static int con_init_done = 0;
9809 +
9810 +int stdio_init(void)
9811 +{
9812 +       char *new_title;
9813 +
9814 +       printk(KERN_INFO "Initializing stdio console driver\n");
9815 +
9816 +       line_register_devfs(&console_lines, &driver, &console_driver, vts, 
9817 +                           sizeof(vts)/sizeof(vts[0]));
9818 +
9819 +       lines_init(vts, sizeof(vts)/sizeof(vts[0]));
9820 +
9821 +       new_title = add_xterm_umid(opts.xterm_title);
9822 +       if(new_title != NULL) opts.xterm_title = new_title;
9823 +
9824 +       open_console(NULL);
9825 +       con_init_done = 1;
9826 +       return(0);
9827 +}
9828 +
9829 +__initcall(stdio_init);
9830 +
9831 +static void console_write(struct console *console, const char *string, 
9832 +                         unsigned len)
9833 +{
9834 +       struct line *line = &vts[console->index];
9835 +
9836 +       if(con_init_done)
9837 +               down(&line->sem);
9838 +       console_write_chan(&line->chan_list, string, len);
9839 +       if(con_init_done)
9840 +               up(&line->sem);
9841 +}
9842 +
9843 +static struct tty_driver console_driver = {
9844 +       .refcount               = &console_refcount,
9845 +       .open                   = con_open,
9846 +       .close                  = con_close,
9847 +       .write                  = con_write,
9848 +       .chars_in_buffer        = chars_in_buffer,
9849 +       .set_termios            = set_termios
9850 +};
9851 +
9852 +static kdev_t console_device(struct console *c)
9853 +{
9854 +       return mk_kdev(TTY_MAJOR, c->index);
9855 +}
9856 +
9857 +static int console_setup(struct console *co, char *options)
9858 +{
9859 +       return(0);
9860 +}
9861 +
9862 +static struct console stdiocons = {
9863 +       name:           "tty",
9864 +       write:          console_write,
9865 +       device:         console_device,
9866 +       setup:          console_setup,
9867 +       flags:          CON_PRINTBUFFER,
9868 +       index:          -1,
9869 +};
9870 +
9871 +void stdio_console_init(void)
9872 +{
9873 +       INIT_LIST_HEAD(&vts[0].chan_list);
9874 +       list_add(&init_console_chan.list, &vts[0].chan_list);
9875 +       register_console(&stdiocons);
9876 +}
9877 +
9878 +static int console_chan_setup(char *str)
9879 +{
9880 +       return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
9881 +}
9882 +
9883 +__setup("con", console_chan_setup);
9884 +__channel_help(console_chan_setup, "con");
9885 +
9886 +static void console_exit(void)
9887 +{
9888 +       if(!con_init_done) return;
9889 +       close_lines(vts, sizeof(vts)/sizeof(vts[0]));
9890 +}
9891 +
9892 +__uml_exitcall(console_exit);
9893 +
9894 +/*
9895 + * Overrides for Emacs so that we follow Linus's tabbing style.
9896 + * Emacs will notice this stuff at the end of the file and automatically
9897 + * adjust the settings for this buffer only.  This must remain at the end
9898 + * of the file.
9899 + * ---------------------------------------------------------------------------
9900 + * Local variables:
9901 + * c-file-style: "linux"
9902 + * End:
9903 + */
9904 Index: linux-2.4.29/arch/um/drivers/stdio_console.h
9905 ===================================================================
9906 --- linux-2.4.29.orig/arch/um/drivers/stdio_console.h   1970-01-01 03:00:00.000000000 +0300
9907 +++ linux-2.4.29/arch/um/drivers/stdio_console.h        2005-05-03 22:28:14.250443816 +0300
9908 @@ -0,0 +1,21 @@
9909 +/* 
9910 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9911 + * Licensed under the GPL
9912 + */
9913 +
9914 +#ifndef __STDIO_CONSOLE_H
9915 +#define __STDIO_CONSOLE_H
9916 +
9917 +extern void save_console_flags(void);
9918 +#endif
9919 +
9920 +/*
9921 + * Overrides for Emacs so that we follow Linus's tabbing style.
9922 + * Emacs will notice this stuff at the end of the file and automatically
9923 + * adjust the settings for this buffer only.  This must remain at the end
9924 + * of the file.
9925 + * ---------------------------------------------------------------------------
9926 + * Local variables:
9927 + * c-file-style: "linux"
9928 + * End:
9929 + */
9930 Index: linux-2.4.29/arch/um/drivers/tty.c
9931 ===================================================================
9932 --- linux-2.4.29.orig/arch/um/drivers/tty.c     1970-01-01 03:00:00.000000000 +0300
9933 +++ linux-2.4.29/arch/um/drivers/tty.c  2005-05-03 22:28:14.251443664 +0300
9934 @@ -0,0 +1,91 @@
9935 +/* 
9936 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
9937 + * Licensed under the GPL
9938 + */
9939 +
9940 +#include <stdio.h>
9941 +#include <termios.h>
9942 +#include <errno.h>
9943 +#include <unistd.h>
9944 +#include "chan_user.h"
9945 +#include "user_util.h"
9946 +#include "user.h"
9947 +#include "os.h"
9948 +
9949 +struct tty_chan {
9950 +       char *dev;
9951 +       int raw;
9952 +       struct termios tt;
9953 +};
9954 +
9955 +void *tty_chan_init(char *str, int device, struct chan_opts *opts)
9956 +{
9957 +       struct tty_chan *data;
9958 +
9959 +       if(*str != ':'){
9960 +               printk("tty_init : channel type 'tty' must specify "
9961 +                      "a device\n");
9962 +               return(NULL);
9963 +       }
9964 +       str++;
9965 +
9966 +       data = um_kmalloc(sizeof(*data)); 
9967 +       if(data == NULL) 
9968 +               return(NULL);
9969 +       *data = ((struct tty_chan) { .dev       = str,
9970 +                                    .raw       = opts->raw });
9971 +                                    
9972 +       return(data);
9973 +}
9974 +
9975 +int tty_open(int input, int output, int primary, void *d, char **dev_out)
9976 +{
9977 +       struct tty_chan *data = d;
9978 +       int fd, err;
9979 +
9980 +       fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0);
9981 +       if(fd < 0) return(fd);
9982 +       if(data->raw){
9983 +               CATCH_EINTR(err = tcgetattr(fd, &data->tt));
9984 +               if(err)
9985 +                       return(err);
9986 +
9987 +               err = raw(fd);
9988 +               if(err)
9989 +                       return(err);
9990 +       }
9991 +
9992 +       *dev_out = data->dev;
9993 +       return(fd);
9994 +}
9995 +
9996 +int tty_console_write(int fd, const char *buf, int n, void *d)
9997 +{
9998 +       struct tty_chan *data = d;
9999 +
10000 +       return(generic_console_write(fd, buf, n, &data->tt));
10001 +}
10002 +
10003 +struct chan_ops tty_ops = {
10004 +       .type           = "tty",
10005 +       .init           = tty_chan_init,
10006 +       .open           = tty_open,
10007 +       .close          = generic_close,
10008 +       .read           = generic_read,
10009 +       .write          = generic_write,
10010 +       .console_write  = tty_console_write,
10011 +       .window_size    = generic_window_size,
10012 +       .free           = generic_free,
10013 +       .winch          = 0,
10014 +};
10015 +
10016 +/*
10017 + * Overrides for Emacs so that we follow Linus's tabbing style.
10018 + * Emacs will notice this stuff at the end of the file and automatically
10019 + * adjust the settings for this buffer only.  This must remain at the end
10020 + * of the file.
10021 + * ---------------------------------------------------------------------------
10022 + * Local variables:
10023 + * c-file-style: "linux"
10024 + * End:
10025 + */
10026 Index: linux-2.4.29/arch/um/drivers/ubd_kern.c
10027 ===================================================================
10028 --- linux-2.4.29.orig/arch/um/drivers/ubd_kern.c        1970-01-01 03:00:00.000000000 +0300
10029 +++ linux-2.4.29/arch/um/drivers/ubd_kern.c     2005-05-03 22:28:14.257442752 +0300
10030 @@ -0,0 +1,1380 @@
10031 +/* 
10032 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
10033 + * Licensed under the GPL
10034 + */
10035 +
10036 +/* 2001-09-28...2002-04-17
10037 + * Partition stuff by James_McMechan@hotmail.com
10038 + * old style ubd by setting UBD_SHIFT to 0
10039 + */
10040 +
10041 +#define MAJOR_NR UBD_MAJOR
10042 +#define UBD_SHIFT 4
10043 +
10044 +#include "linux/config.h"
10045 +#include "linux/blk.h"
10046 +#include "linux/blkdev.h"
10047 +#include "linux/hdreg.h"
10048 +#include "linux/init.h"
10049 +#include "linux/devfs_fs_kernel.h"
10050 +#include "linux/cdrom.h"
10051 +#include "linux/proc_fs.h"
10052 +#include "linux/ctype.h"
10053 +#include "linux/capability.h"
10054 +#include "linux/mm.h"
10055 +#include "linux/vmalloc.h"
10056 +#include "linux/blkpg.h"
10057 +#include "linux/genhd.h"
10058 +#include "linux/spinlock.h"
10059 +#include "asm/segment.h"
10060 +#include "asm/uaccess.h"
10061 +#include "asm/irq.h"
10062 +#include "asm/types.h"
10063 +#include "user_util.h"
10064 +#include "mem_user.h"
10065 +#include "kern_util.h"
10066 +#include "kern.h"
10067 +#include "mconsole_kern.h"
10068 +#include "init.h"
10069 +#include "irq_user.h"
10070 +#include "irq_kern.h"
10071 +#include "ubd_user.h"
10072 +#include "2_5compat.h"
10073 +#include "os.h"
10074 +#include "mem.h"
10075 +#include "mem_kern.h"
10076 +
10077 +static int ubd_open(struct inode * inode, struct file * filp);
10078 +static int ubd_release(struct inode * inode, struct file * file);
10079 +static int ubd_ioctl(struct inode * inode, struct file * file,
10080 +                    unsigned int cmd, unsigned long arg);
10081 +static int ubd_revalidate(kdev_t rdev);
10082 +static int ubd_revalidate1(kdev_t rdev);
10083 +
10084 +#define MAX_DEV (8)
10085 +#define MAX_MINOR (MAX_DEV << UBD_SHIFT)
10086 +
10087 +/* Changed in early boot */
10088 +static int ubd_do_mmap = 0;
10089 +#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
10090 +
10091 +/* Not modified by this driver */
10092 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
10093 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
10094 +
10095 +/* Protected by ubd_lock */
10096 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
10097 +
10098 +static struct block_device_operations ubd_blops = {
10099 +        .open          = ubd_open,
10100 +        .release       = ubd_release,
10101 +        .ioctl         = ubd_ioctl,
10102 +        .revalidate    = ubd_revalidate,
10103 +};
10104 +
10105 +/* Protected by ubd_lock, except in prepare_request and ubd_ioctl because 
10106 + * the block layer should ensure that the device is idle before closing it.
10107 + */
10108 +static struct hd_struct        ubd_part[MAX_MINOR] =
10109 +       { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
10110 +
10111 +/* Protected by io_request_lock */
10112 +static request_queue_t *ubd_queue;
10113 +
10114 +/* Protected by ubd_lock */
10115 +static int fake_major = MAJOR_NR;
10116 +
10117 +static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
10118 +
10119 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
10120 +{ \
10121 +       .major          = maj, \
10122 +       .major_name     = name, \
10123 +       .minor_shift    = shift, \
10124 +       .max_p          = 1 << shift, \
10125 +       .part           = parts, \
10126 +       .sizes          = bsizes, \
10127 +       .nr_real        = max, \
10128 +       .real_devices   = NULL, \
10129 +       .next           = NULL, \
10130 +       .fops           = blops, \
10131 +       .de_arr         = NULL, \
10132 +       .flags          = 0 \
10133 +}
10134 +
10135 +static struct gendisk ubd_gendisk = INIT_GENDISK(MAJOR_NR, "ubd", ubd_part,
10136 +                                                UBD_SHIFT, sizes, MAX_DEV, 
10137 +                                                &ubd_blops);
10138 +static struct gendisk fake_gendisk = INIT_GENDISK(0, "ubd", ubd_part, 
10139 +                                                 UBD_SHIFT, sizes, MAX_DEV, 
10140 +                                                 &ubd_blops);
10141 +
10142 +#ifdef CONFIG_BLK_DEV_UBD_SYNC
10143 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
10144 +                                        .cl = 1 })
10145 +#else
10146 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \
10147 +                                        .cl = 1 })
10148 +#endif
10149 +
10150 +/* Not protected - changed only in ubd_setup_common and then only to
10151 + * to enable O_SYNC.
10152 + */
10153 +static struct openflags global_openflags = OPEN_FLAGS;
10154 +
10155 +struct cow {
10156 +       char *file;
10157 +       int fd;
10158 +       unsigned long *bitmap;
10159 +       unsigned long bitmap_len;
10160 +       int bitmap_offset;
10161 +        int data_offset;
10162 +};
10163 +
10164 +struct ubd {
10165 +       char *file;
10166 +       int count;
10167 +       int fd;
10168 +       __u64 size;
10169 +       struct openflags boot_openflags;
10170 +       struct openflags openflags;
10171 +       devfs_handle_t devfs;
10172 +       int no_cow;
10173 +       struct cow cow;
10174 +
10175 +       int map_writes;
10176 +       int map_reads;
10177 +       int nomap_writes;
10178 +       int nomap_reads;
10179 +       int write_maps;
10180 +};
10181 +
10182 +#define DEFAULT_COW { \
10183 +       .file                   = NULL, \
10184 +        .fd                    = -1, \
10185 +        .bitmap                        = NULL, \
10186 +       .bitmap_offset          = 0, \
10187 +        .data_offset           = 0, \
10188 +}
10189 +
10190 +#define DEFAULT_UBD { \
10191 +       .file                   = NULL, \
10192 +       .count                  = 0, \
10193 +       .fd                     = -1, \
10194 +       .size                   = -1, \
10195 +       .boot_openflags         = OPEN_FLAGS, \
10196 +       .openflags              = OPEN_FLAGS, \
10197 +       .devfs                  = NULL, \
10198 +       .no_cow                 = 0, \
10199 +        .cow                   = DEFAULT_COW, \
10200 +       .map_writes             = 0, \
10201 +       .map_reads              = 0, \
10202 +       .nomap_writes           = 0, \
10203 +       .nomap_reads            = 0, \
10204 +       .write_maps             = 0, \
10205 +}
10206 +
10207 +struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
10208 +
10209 +static int ubd0_init(void)
10210 +{
10211 +       struct ubd *dev = &ubd_dev[0];
10212 +
10213 +       if(dev->file == NULL)
10214 +               dev->file = "root_fs";
10215 +       return(0);
10216 +}
10217 +
10218 +__initcall(ubd0_init);
10219 +
10220 +/* Only changed by fake_ide_setup which is a setup */
10221 +static int fake_ide = 0;
10222 +static struct proc_dir_entry *proc_ide_root = NULL;
10223 +static struct proc_dir_entry *proc_ide = NULL;
10224 +
10225 +static void make_proc_ide(void)
10226 +{
10227 +       proc_ide_root = proc_mkdir("ide", 0);
10228 +       proc_ide = proc_mkdir("ide0", proc_ide_root);
10229 +}
10230 +
10231 +static int proc_ide_read_media(char *page, char **start, off_t off, int count,
10232 +                              int *eof, void *data)
10233 +{
10234 +       int len;
10235 +
10236 +       strcpy(page, "disk\n");
10237 +       len = strlen("disk\n");
10238 +       len -= off;
10239 +       if (len < count){
10240 +               *eof = 1;
10241 +               if (len <= 0) return 0;
10242 +       }
10243 +       else len = count;
10244 +       *start = page + off;
10245 +       return len;
10246 +}
10247 +
10248 +static void make_ide_entries(char *dev_name)
10249 +{
10250 +       struct proc_dir_entry *dir, *ent;
10251 +       char name[64];
10252 +
10253 +       if(!fake_ide) return;
10254 +
10255 +       /* Without locking this could race if a UML was booted with no 
10256 +        * disks and then two mconsole requests which add disks came in 
10257 +        * at the same time.
10258 +        */
10259 +       spin_lock(&ubd_lock);
10260 +       if(proc_ide_root == NULL) make_proc_ide();
10261 +       spin_unlock(&ubd_lock);
10262 +
10263 +       dir = proc_mkdir(dev_name, proc_ide);
10264 +       if(!dir) return;
10265 +
10266 +       ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir);
10267 +       if(!ent) return;
10268 +       ent->nlink = 1;
10269 +       ent->data = NULL;
10270 +       ent->read_proc = proc_ide_read_media;
10271 +       ent->write_proc = NULL;
10272 +       sprintf(name,"ide0/%s", dev_name);
10273 +       proc_symlink(dev_name, proc_ide_root, name);
10274 +}
10275 +
10276 +static int fake_ide_setup(char *str)
10277 +{
10278 +       fake_ide = 1;
10279 +       return(1);
10280 +}
10281 +
10282 +__setup("fake_ide", fake_ide_setup);
10283 +
10284 +__uml_help(fake_ide_setup,
10285 +"fake_ide\n"
10286 +"    Create ide0 entries that map onto ubd devices.\n\n"
10287 +);
10288 +
10289 +static int parse_unit(char **ptr)
10290 +{
10291 +       char *str = *ptr, *end;
10292 +       int n = -1;
10293 +
10294 +       if(isdigit(*str)) {
10295 +               n = simple_strtoul(str, &end, 0);
10296 +               if(end == str)
10297 +                       return(-1);
10298 +               *ptr = end;
10299 +       }
10300 +       else if (('a' <= *str) && (*str <= 'h')) {
10301 +               n = *str - 'a';
10302 +               str++;
10303 +               *ptr = str;
10304 +       }
10305 +       return(n);
10306 +}
10307 +
10308 +static int ubd_setup_common(char *str, int *index_out)
10309 +{
10310 +       struct openflags flags = global_openflags;
10311 +       struct ubd *dev;
10312 +       char *backing_file;
10313 +       int n, err;
10314 +
10315 +       if(index_out) *index_out = -1;
10316 +       n = *str;
10317 +       if(n == '='){
10318 +               char *end;
10319 +               int major;
10320 +
10321 +               str++;
10322 +               if(!strcmp(str, "mmap")){
10323 +                       CHOOSE_MODE(printk("mmap not supported by the ubd "
10324 +                                          "driver in tt mode\n"),
10325 +                                   ubd_do_mmap = 1);
10326 +                       return(0);
10327 +               }
10328 +
10329 +               if(!strcmp(str, "sync")){
10330 +                       global_openflags.s = 1;
10331 +                       return(0);
10332 +               }
10333 +               major = simple_strtoul(str, &end, 0);
10334 +               if((*end != '\0') || (end == str)){
10335 +                       printk(KERN_ERR 
10336 +                              "ubd_setup : didn't parse major number\n");
10337 +                       return(1);
10338 +               }
10339 +
10340 +               err = 1;
10341 +               spin_lock(&ubd_lock);
10342 +               if(fake_major != MAJOR_NR){
10343 +                       printk(KERN_ERR "Can't assign a fake major twice\n");
10344 +                       goto out1;
10345 +               }
10346 +
10347 +               fake_gendisk.major = major;
10348 +               fake_major = major;
10349 +       
10350 +               printk(KERN_INFO "Setting extra ubd major number to %d\n",
10351 +                      major);
10352 +               err = 0;
10353 +       out1:
10354 +               spin_unlock(&ubd_lock);
10355 +               return(err);
10356 +       }
10357 +
10358 +       n = parse_unit(&str);
10359 +       if(n < 0){
10360 +               printk(KERN_ERR "ubd_setup : couldn't parse unit number "
10361 +                      "'%s'\n", str);
10362 +               return(1);
10363 +       }
10364 +
10365 +       if(n >= MAX_DEV){
10366 +               printk(KERN_ERR "ubd_setup : index %d out of range "
10367 +                      "(%d devices)\n", n, MAX_DEV);   
10368 +               return(1);
10369 +       }
10370 +
10371 +       err = 1;
10372 +       spin_lock(&ubd_lock);
10373 +
10374 +       dev = &ubd_dev[n];
10375 +       if(dev->file != NULL){
10376 +               printk(KERN_ERR "ubd_setup : device already configured\n");
10377 +               goto out2;
10378 +       }
10379 +
10380 +       if(index_out) *index_out = n;
10381 +
10382 +       if(*str == 'r'){
10383 +               flags.w = 0;
10384 +               str++;
10385 +       }
10386 +       if(*str == 's'){
10387 +               flags.s = 1;
10388 +               str++;
10389 +       }
10390 +       if(*str == 'd'){
10391 +               dev->no_cow = 1;
10392 +               str++;
10393 +       }
10394 +
10395 +       if(*str++ != '='){
10396 +               printk(KERN_ERR "ubd_setup : Expected '='\n");
10397 +               goto out2;
10398 +       }
10399 +
10400 +       err = 0;
10401 +       backing_file = strchr(str, ',');
10402 +       if(backing_file){
10403 +               if(dev->no_cow)
10404 +                       printk(KERN_ERR "Can't specify both 'd' and a "
10405 +                              "cow file\n");
10406 +               else {
10407 +                       *backing_file = '\0';
10408 +                       backing_file++;
10409 +               }
10410 +       }
10411 +       dev->file = str;
10412 +       dev->cow.file = backing_file;
10413 +       dev->boot_openflags = flags;
10414 + out2:
10415 +       spin_unlock(&ubd_lock);
10416 +       return(err);
10417 +}
10418 +
10419 +static int ubd_setup(char *str)
10420 +{
10421 +       ubd_setup_common(str, NULL);
10422 +       return(1);
10423 +}
10424 +
10425 +__setup("ubd", ubd_setup);
10426 +__uml_help(ubd_setup,
10427 +"ubd<n>=<filename>\n"
10428 +"    This is used to associate a device with a file in the underlying\n"
10429 +"    filesystem. Usually, there is a filesystem in the file, but \n"
10430 +"    that's not required. Swap devices containing swap files can be\n"
10431 +"    specified like this. Also, a file which doesn't contain a\n"
10432 +"    filesystem can have its contents read in the virtual \n"
10433 +"    machine by running dd on the device. n must be in the range\n"
10434 +"    0 to 7. Appending an 'r' to the number will cause that device\n"
10435 +"    to be mounted read-only. For example ubd1r=./ext_fs. Appending\n"
10436 +"    an 's' (has to be _after_ 'r', if there is one) will cause data\n"
10437 +"    to be written to disk on the host immediately.\n\n"
10438 +);
10439 +
10440 +static int fakehd(char *str)
10441 +{
10442 +       printk(KERN_INFO 
10443 +              "fakehd : Changing ubd_gendisk.major_name to \"hd\".\n");
10444 +       ubd_gendisk.major_name = "hd";
10445 +       return(1);
10446 +}
10447 +
10448 +__setup("fakehd", fakehd);
10449 +__uml_help(fakehd,
10450 +"fakehd\n"
10451 +"    Change the ubd device name to \"hd\".\n\n"
10452 +);
10453 +
10454 +static void do_ubd_request(request_queue_t * q);
10455 +
10456 +/* Only changed by ubd_init, which is an initcall. */
10457 +int thread_fd = -1;
10458 +
10459 +/* Changed by ubd_handler, which is serialized because interrupts only
10460 + * happen on CPU 0.
10461 + */
10462 +int intr_count = 0;
10463 +
10464 +static void ubd_finish(int error)
10465 +{
10466 +       int nsect;
10467 +
10468 +       if(error){
10469 +               end_request(0);
10470 +               return;
10471 +       }
10472 +       nsect = CURRENT->current_nr_sectors;
10473 +       CURRENT->sector += nsect;
10474 +       CURRENT->buffer += nsect << 9;
10475 +       CURRENT->errors = 0;
10476 +       CURRENT->nr_sectors -= nsect;
10477 +       CURRENT->current_nr_sectors = 0;
10478 +       end_request(1);
10479 +}
10480 +
10481 +static void ubd_handler(void)
10482 +{
10483 +       struct io_thread_req req;
10484 +       int n, err;
10485 +
10486 +       DEVICE_INTR = NULL;
10487 +       intr_count++;
10488 +       n = read_ubd_fs(thread_fd, &req, sizeof(req));
10489 +       if(n != sizeof(req)){
10490 +               printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
10491 +                      "err = %d\n", os_getpid(), -n);
10492 +               spin_lock(&io_request_lock);
10493 +               end_request(0);
10494 +               spin_unlock(&io_request_lock);
10495 +               return;
10496 +       }
10497 +        
10498 +        if((req.op != UBD_MMAP) && 
10499 +          ((req.offset != ((__u64) (CURRENT->sector)) << 9) ||
10500 +           (req.length != (CURRENT->current_nr_sectors) << 9)))
10501 +               panic("I/O op mismatch");
10502 +
10503 +       if(req.map_fd != -1){
10504 +               err = physmem_subst_mapping(req.buffer, req.map_fd, 
10505 +                                           req.map_offset, 1);
10506 +               if(err)
10507 +                       printk("ubd_handler - physmem_subst_mapping failed, "
10508 +                              "err = %d\n", -err);
10509 +       }
10510 +
10511 +       spin_lock(&io_request_lock);
10512 +       ubd_finish(req.error);
10513 +       reactivate_fd(thread_fd, UBD_IRQ);      
10514 +       do_ubd_request(ubd_queue);
10515 +       spin_unlock(&io_request_lock);
10516 +}
10517 +
10518 +static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
10519 +{
10520 +       ubd_handler();
10521 +}
10522 +
10523 +/* Only changed by ubd_init, which is an initcall. */
10524 +static int io_pid = -1;
10525 +
10526 +void kill_io_thread(void)
10527 +{
10528 +       if(io_pid != -1)
10529 +               os_kill_process(io_pid, 1);
10530 +}
10531 +
10532 +__uml_exitcall(kill_io_thread);
10533 +
10534 +/* Initialized in an initcall, and unchanged thereafter */
10535 +devfs_handle_t ubd_dir_handle;
10536 +
10537 +static int ubd_add(int n)
10538 +{
10539 +       struct ubd *dev = &ubd_dev[n];
10540 +       char name[sizeof("nnnnnn\0")], dev_name[sizeof("ubd0x")];
10541 +       int err = -EISDIR;
10542 +
10543 +       if(dev->file == NULL)
10544 +               goto out;
10545 +
10546 +       err = ubd_revalidate1(MKDEV(MAJOR_NR, n << UBD_SHIFT));
10547 +       if(err)
10548 +               goto out;
10549 +
10550 +       if(dev->cow.file == NULL)
10551 +               blk_sizes[n] = UBD_MMAP_BLOCK_SIZE;
10552 +
10553 +       sprintf(name, "%d", n);
10554 +       dev->devfs = devfs_register(ubd_dir_handle, name, DEVFS_FL_REMOVABLE,
10555 +                                   MAJOR_NR, n << UBD_SHIFT, S_IFBLK | 
10556 +                                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
10557 +                                   &ubd_blops, NULL);
10558 +
10559 +#if 0 /* 2.5 ... */
10560 +       sprintf(disk->disk_name, "ubd%c", 'a' + unit);
10561 +#endif
10562 +
10563 +       sprintf(dev_name, "%s%c", ubd_gendisk.major_name, 
10564 +                    n + 'a');
10565 +
10566 +       make_ide_entries(dev_name);
10567 +       return(0);
10568 +
10569 + out:
10570 +       return(err);
10571 +}
10572 +
10573 +static int ubd_config(char *str)
10574 +{
10575 +       int n, err;
10576 +
10577 +       str = uml_strdup(str);
10578 +       if(str == NULL){
10579 +               printk(KERN_ERR "ubd_config failed to strdup string\n");
10580 +               return(1);
10581 +       }
10582 +       err = ubd_setup_common(str, &n);
10583 +       if(err){
10584 +               kfree(str);
10585 +               return(-1);
10586 +       }
10587 +       if(n == -1) return(0);
10588 +
10589 +       spin_lock(&ubd_lock);
10590 +       err = ubd_add(n);
10591 +       if(err)
10592 +               ubd_dev[n].file = NULL;
10593 +       spin_unlock(&ubd_lock);
10594 +
10595 +       return(err);
10596 +}
10597 +
10598 +static int ubd_get_config(char *name, char *str, int size, char **error_out)
10599 +{
10600 +       struct ubd *dev;
10601 +       char *end;
10602 +       int n, len = 0;
10603 +
10604 +       n = simple_strtoul(name, &end, 0);
10605 +       if((*end != '\0') || (end == name)){
10606 +               *error_out = "ubd_get_config : didn't parse device number";
10607 +               return(-1);
10608 +       }
10609 +
10610 +       if((n >= MAX_DEV) || (n < 0)){
10611 +               *error_out = "ubd_get_config : device number out of range";
10612 +               return(-1);
10613 +       }
10614 +
10615 +       dev = &ubd_dev[n];
10616 +       spin_lock(&ubd_lock);
10617 +
10618 +       if(dev->file == NULL){
10619 +               CONFIG_CHUNK(str, size, len, "", 1);
10620 +               goto out;
10621 +       }
10622 +
10623 +       CONFIG_CHUNK(str, size, len, dev->file, 0);
10624 +
10625 +       if(dev->cow.file != NULL){
10626 +               CONFIG_CHUNK(str, size, len, ",", 0);
10627 +               CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
10628 +       }
10629 +       else CONFIG_CHUNK(str, size, len, "", 1);
10630 +
10631 + out:
10632 +       spin_unlock(&ubd_lock);
10633 +       return(len);
10634 +}
10635 +
10636 +static int ubd_remove(char *str)
10637 +{
10638 +       struct ubd *dev;
10639 +       int n, err = -ENODEV;
10640 +
10641 +       if(isdigit(*str)){
10642 +               char *end;
10643 +               n = simple_strtoul(str, &end, 0);
10644 +               if ((*end != '\0') || (end == str)) 
10645 +                       return(err);
10646 +       }
10647 +       else if (('a' <= *str) && (*str <= 'h'))
10648 +               n = *str - 'a';
10649 +       else
10650 +               return(err);    /* it should be a number 0-7/a-h */
10651 +
10652 +       if((n < 0) || (n >= MAX_DEV))
10653 +               return(err);
10654 +
10655 +       dev = &ubd_dev[n];
10656 +
10657 +       spin_lock(&ubd_lock);
10658 +       err = 0;
10659 +       if(dev->file == NULL)
10660 +               goto out;
10661 +       err = -1;
10662 +       if(dev->count > 0)
10663 +               goto out;
10664 +       if(dev->devfs != NULL) 
10665 +               devfs_unregister(dev->devfs);
10666 +
10667 +       *dev = ((struct ubd) DEFAULT_UBD);
10668 +       err = 0;
10669 + out:
10670 +       spin_unlock(&ubd_lock);
10671 +       return(err);
10672 +}
10673 +
10674 +static struct mc_device ubd_mc = {
10675 +       .name           = "ubd",
10676 +       .config         = ubd_config,
10677 +       .get_config     = ubd_get_config,
10678 +       .remove         = ubd_remove,
10679 +};
10680 +
10681 +static int ubd_mc_init(void)
10682 +{
10683 +       mconsole_register_dev(&ubd_mc);
10684 +       return(0);
10685 +}
10686 +
10687 +__initcall(ubd_mc_init);
10688 +
10689 +static request_queue_t *ubd_get_queue(kdev_t device)
10690 +{
10691 +       return(ubd_queue);
10692 +}
10693 +
10694 +int ubd_init(void)
10695 +{
10696 +       unsigned long stack;
10697 +        int i, err;
10698 +
10699 +       ubd_dir_handle = devfs_mk_dir (NULL, "ubd", NULL);
10700 +       if (devfs_register_blkdev(MAJOR_NR, "ubd", &ubd_blops)) {
10701 +               printk(KERN_ERR "ubd: unable to get major %d\n", MAJOR_NR);
10702 +               return -1;
10703 +       }
10704 +       read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
10705 +       blksize_size[MAJOR_NR] = blk_sizes;
10706 +       blk_size[MAJOR_NR] = sizes;
10707 +       INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
10708 +
10709 +       ubd_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
10710 +       blk_init_queue(ubd_queue, DEVICE_REQUEST);
10711 +       INIT_ELV(ubd_queue, &ubd_queue->elevator);
10712 +
10713 +        add_gendisk(&ubd_gendisk);
10714 +       if (fake_major != MAJOR_NR){
10715 +               /* major number 0 is used to auto select */
10716 +               err = devfs_register_blkdev(fake_major, "fake", &ubd_blops);
10717 +               if(fake_major == 0){
10718 +               /* auto device number case */
10719 +                       fake_major = err;
10720 +                       if(err == 0)
10721 +                               return(-ENODEV);
10722 +               } 
10723 +               else if (err){
10724 +                       /* not auto so normal error */
10725 +                       printk(KERN_ERR "ubd: error %d getting major %d\n", 
10726 +                              -err, fake_major);
10727 +                       return(-ENODEV);
10728 +               }
10729 +
10730 +               blk_dev[fake_major].queue = ubd_get_queue;
10731 +               read_ahead[fake_major] = 8;     /* 8 sector (4kB) read-ahead */
10732 +               blksize_size[fake_major] = blk_sizes;
10733 +               blk_size[fake_major] = sizes;
10734 +               INIT_HARDSECT(hardsect_size, fake_major, hardsect_sizes);
10735 +                add_gendisk(&fake_gendisk);
10736 +       }
10737 +
10738 +       for(i=0;i<MAX_DEV;i++) 
10739 +               ubd_add(i);
10740 +
10741 +       if(global_openflags.s){
10742 +               printk(KERN_INFO "ubd : Synchronous mode\n");
10743 +               return(0);
10744 +       }
10745 +       stack = alloc_stack(0, 0);
10746 +       io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), 
10747 +                                &thread_fd);
10748 +       if(io_pid < 0){
10749 +               io_pid = -1;
10750 +               printk(KERN_ERR 
10751 +                      "ubd : Failed to start I/O thread (errno = %d) - "
10752 +                      "falling back to synchronous I/O\n", -io_pid);
10753 +               return(0);
10754 +       }
10755 +       err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 
10756 +                            SA_INTERRUPT, "ubd", ubd_dev);
10757 +       if(err != 0) 
10758 +               printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
10759 +       return(err);
10760 +}
10761 +
10762 +__initcall(ubd_init);
10763 +
10764 +static void ubd_close(struct ubd *dev)
10765 +{
10766 +       if(ubd_do_mmap)
10767 +               physmem_forget_descriptor(dev->fd);
10768 +       os_close_file(dev->fd);
10769 +       if(dev->cow.file != NULL)
10770 +               return;
10771 +
10772 +       if(ubd_do_mmap)
10773 +               physmem_forget_descriptor(dev->cow.fd);
10774 +       os_close_file(dev->cow.fd);
10775 +       vfree(dev->cow.bitmap);
10776 +       dev->cow.bitmap = NULL;
10777 +}
10778 +
10779 +static int ubd_open_dev(struct ubd *dev)
10780 +{
10781 +       struct openflags flags;
10782 +       char **back_ptr;
10783 +       int err, create_cow, *create_ptr;
10784 +
10785 +       dev->openflags = dev->boot_openflags;
10786 +       create_cow = 0;
10787 +       create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
10788 +       back_ptr = dev->no_cow ? NULL : &dev->cow.file;
10789 +       dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
10790 +                               &dev->cow.bitmap_offset, &dev->cow.bitmap_len, 
10791 +                               &dev->cow.data_offset, create_ptr);
10792 +
10793 +       if((dev->fd == -ENOENT) && create_cow){
10794 +               dev->fd = create_cow_file(dev->file, dev->cow.file, 
10795 +                                         dev->openflags, 1 << 9, PAGE_SIZE,
10796 +                                         &dev->cow.bitmap_offset, 
10797 +                                         &dev->cow.bitmap_len,
10798 +                                         &dev->cow.data_offset);
10799 +               if(dev->fd >= 0){
10800 +                       printk(KERN_INFO "Creating \"%s\" as COW file for "
10801 +                              "\"%s\"\n", dev->file, dev->cow.file);
10802 +               }
10803 +       }
10804 +
10805 +       if(dev->fd < 0) return(dev->fd);
10806 +
10807 +       if(dev->cow.file != NULL){
10808 +               err = -ENOMEM;
10809 +               dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
10810 +               if(dev->cow.bitmap == NULL){
10811 +                       printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
10812 +                       goto error;
10813 +               }
10814 +               flush_tlb_kernel_vm();
10815 +
10816 +               err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 
10817 +                                     dev->cow.bitmap_offset, 
10818 +                                     dev->cow.bitmap_len);
10819 +               if(err < 0) 
10820 +                       goto error;
10821 +
10822 +               flags = dev->openflags;
10823 +               flags.w = 0;
10824 +               err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL, 
10825 +                                   NULL, NULL);
10826 +               if(err < 0) goto error;
10827 +               dev->cow.fd = err;
10828 +       }
10829 +       return(0);
10830 + error:
10831 +       os_close_file(dev->fd);
10832 +       return(err);
10833 +}
10834 +
10835 +static int ubd_file_size(struct ubd *dev, __u64 *size_out)
10836 +{
10837 +       char *file;
10838 +
10839 +       file = dev->cow.file ? dev->cow.file : dev->file;
10840 +       return(os_file_size(file, size_out));
10841 +}
10842 +
10843 +static int ubd_open(struct inode *inode, struct file *filp)
10844 +{
10845 +       struct ubd *dev;
10846 +       int n, offset, err = 0;
10847 +
10848 +       n = DEVICE_NR(inode->i_rdev);
10849 +       dev = &ubd_dev[n];
10850 +       if(n >= MAX_DEV)
10851 +               return -ENODEV;
10852 +
10853 +       spin_lock(&ubd_lock);
10854 +       offset = n << UBD_SHIFT;
10855 +
10856 +       if(dev->count == 0){
10857 +               err = ubd_open_dev(dev);
10858 +               if(err){
10859 +                       printk(KERN_ERR "ubd%d: Can't open \"%s\": "
10860 +                              "errno = %d\n", n, dev->file, -err);
10861 +                       goto out;
10862 +               }
10863 +               err = ubd_file_size(dev, &dev->size);
10864 +               if(err < 0)
10865 +                       goto out;
10866 +               sizes[offset] = dev->size / BLOCK_SIZE;
10867 +               ubd_part[offset].nr_sects = dev->size / hardsect_sizes[offset];
10868 +       }
10869 +       dev->count++;
10870 +       if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
10871 +               if(--dev->count == 0) ubd_close(dev);
10872 +               err = -EROFS;
10873 +       }
10874 + out:
10875 +       spin_unlock(&ubd_lock);
10876 +       return(err);
10877 +}
10878 +
10879 +static int ubd_release(struct inode * inode, struct file * file)
10880 +{
10881 +        int n, offset;
10882 +
10883 +       n =  DEVICE_NR(inode->i_rdev);
10884 +       offset = n << UBD_SHIFT;
10885 +       if(n >= MAX_DEV)
10886 +               return -ENODEV;
10887 +
10888 +       spin_lock(&ubd_lock);
10889 +       if(--ubd_dev[n].count == 0)
10890 +               ubd_close(&ubd_dev[n]);
10891 +       spin_unlock(&ubd_lock);
10892 +
10893 +       return(0);
10894 +}
10895 +
10896 +static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, 
10897 +                         __u64 *cow_offset, unsigned long *bitmap, 
10898 +                         __u64 bitmap_offset, unsigned long *bitmap_words,
10899 +                         __u64 bitmap_len)
10900 +{
10901 +       __u64 sector = io_offset >> 9;
10902 +       int i, update_bitmap = 0;
10903 +
10904 +       for(i = 0; i < length >> 9; i++){
10905 +               if(cow_mask != NULL)
10906 +                       ubd_set_bit(i, (unsigned char *) cow_mask);
10907 +               if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
10908 +                       continue;
10909 +
10910 +               update_bitmap = 1;
10911 +               ubd_set_bit(sector + i, (unsigned char *) bitmap);
10912 +       }
10913 +
10914 +       if(!update_bitmap)
10915 +               return;
10916 +
10917 +       *cow_offset = sector / (sizeof(unsigned long) * 8);
10918 +
10919 +       /* This takes care of the case where we're exactly at the end of the
10920 +        * device, and *cow_offset + 1 is off the end.  So, just back it up
10921 +        * by one word.  Thanks to Lynn Kerby for the fix and James McMechan
10922 +        * for the original diagnosis.
10923 +        */
10924 +       if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) / 
10925 +                          sizeof(unsigned long) - 1))
10926 +               (*cow_offset)--;
10927 +
10928 +       bitmap_words[0] = bitmap[*cow_offset];
10929 +       bitmap_words[1] = bitmap[*cow_offset + 1];
10930 +
10931 +       *cow_offset *= sizeof(unsigned long);
10932 +       *cow_offset += bitmap_offset;
10933 +}
10934 +
10935 +static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, 
10936 +                      __u64 bitmap_offset, __u64 bitmap_len)
10937 +{
10938 +       __u64 sector = req->offset >> 9;
10939 +        int i;
10940 +
10941 +       if(req->length > (sizeof(req->sector_mask) * 8) << 9)
10942 +               panic("Operation too long");
10943 +
10944 +       if(req->op == UBD_READ) {
10945 +               for(i = 0; i < req->length >> 9; i++){
10946 +                       if(ubd_test_bit(sector + i, (unsigned char *) bitmap)){
10947 +                               ubd_set_bit(i, (unsigned char *) 
10948 +                                           &req->sector_mask);
10949 +                       }
10950 +                }
10951 +        } 
10952 +        else cowify_bitmap(req->offset, req->length, &req->sector_mask,
10953 +                          &req->cow_offset, bitmap, bitmap_offset, 
10954 +                          req->bitmap_words, bitmap_len);
10955 +}
10956 +
10957 +static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
10958 +{
10959 +       __u64 sector;
10960 +       unsigned char *bitmap;
10961 +       int bit, i;
10962 +
10963 +       /* mmap must have been requested on the command line */
10964 +       if(!ubd_do_mmap)
10965 +               return(-1);
10966 +
10967 +       /* The buffer must be page aligned */
10968 +       if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
10969 +               return(-1);
10970 +
10971 +       /* The request must be a page long */
10972 +       if((req->current_nr_sectors << 9) != PAGE_SIZE)
10973 +               return(-1);
10974 +
10975 +       if(dev->cow.file == NULL)
10976 +               return(dev->fd);
10977 +
10978 +       sector = offset >> 9;
10979 +       bitmap = (unsigned char *) dev->cow.bitmap;
10980 +       bit = ubd_test_bit(sector, bitmap);
10981 +
10982 +       for(i = 1; i < req->current_nr_sectors; i++){
10983 +               if(ubd_test_bit(sector + i, bitmap) != bit)
10984 +                       return(-1);
10985 +       }
10986 +
10987 +       if(bit || (req->cmd == WRITE))
10988 +               offset += dev->cow.data_offset;
10989 +
10990 +       /* The data on disk must be page aligned */
10991 +       if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
10992 +               return(-1);
10993 +
10994 +       return(bit ? dev->fd : dev->cow.fd);
10995 +}
10996 +
10997 +static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset, 
10998 +                               struct request *req, 
10999 +                               struct io_thread_req *io_req)
11000 +{
11001 +       int err;
11002 +
11003 +       if(req->cmd == WRITE){
11004 +               /* Writes are almost no-ops since the new data is already in the
11005 +                * host page cache
11006 +                */
11007 +               dev->map_writes++;
11008 +               if(dev->cow.file != NULL)
11009 +                       cowify_bitmap(io_req->offset, io_req->length, 
11010 +                                     &io_req->sector_mask, &io_req->cow_offset,
11011 +                                     dev->cow.bitmap, dev->cow.bitmap_offset,
11012 +                                     io_req->bitmap_words, 
11013 +                                     dev->cow.bitmap_len);
11014 +       }
11015 +       else {
11016 +               int w;
11017 +
11018 +               if((dev->cow.file != NULL) && (fd == dev->cow.fd))
11019 +                       w = 0;
11020 +               else w = dev->openflags.w;
11021 +
11022 +               if((dev->cow.file != NULL) && (fd == dev->fd))
11023 +                       offset += dev->cow.data_offset;
11024 +
11025 +               err = physmem_subst_mapping(req->buffer, fd, offset, w);
11026 +               if(err){
11027 +                       printk("physmem_subst_mapping failed, err = %d\n", 
11028 +                              -err);
11029 +                       return(1);
11030 +               }
11031 +               dev->map_reads++;
11032 +       }
11033 +       io_req->op = UBD_MMAP;
11034 +       io_req->buffer = req->buffer;
11035 +       return(0);
11036 +}
11037 +
11038 +static int prepare_request(struct request *req, struct io_thread_req *io_req)
11039 +{
11040 +       struct ubd *dev;
11041 +       __u64 offset;
11042 +       int minor, n, len, fd;
11043 +
11044 +       if(req->rq_status == RQ_INACTIVE) return(1);
11045 +
11046 +       minor = MINOR(req->rq_dev);
11047 +       n = minor >> UBD_SHIFT;
11048 +       dev = &ubd_dev[n];
11049 +
11050 +       if(IS_WRITE(req) && !dev->openflags.w){
11051 +               printk("Write attempted on readonly ubd device %d\n", n);
11052 +               end_request(0);
11053 +               return(1);
11054 +       }
11055 +
11056 +        req->sector += ubd_part[minor].start_sect;
11057 +       offset = ((__u64) req->sector) << 9;
11058 +       len = req->current_nr_sectors << 9;
11059 +
11060 +       io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
11061 +       io_req->fds[1] = dev->fd;
11062 +       io_req->map_fd = -1;
11063 +       io_req->cow_offset = -1;
11064 +       io_req->offset = offset;
11065 +       io_req->length = len;
11066 +       io_req->error = 0;
11067 +       io_req->sector_mask = 0;
11068 +
11069 +       fd = mmap_fd(req, dev, io_req->offset);
11070 +       if(fd > 0){
11071 +               /* If mmapping is otherwise OK, but the first access to the 
11072 +                * page is a write, then it's not mapped in yet.  So we have 
11073 +                * to write the data to disk first, then we can map the disk
11074 +                * page in and continue normally from there.
11075 +                */
11076 +               if((req->cmd == WRITE) && !is_remapped(req->buffer, dev->fd, io_req->offset + dev->cow.data_offset)){
11077 +                       io_req->map_fd = dev->fd;
11078 +                       io_req->map_offset = io_req->offset + 
11079 +                               dev->cow.data_offset;
11080 +                       dev->write_maps++;
11081 +               }
11082 +               else return(prepare_mmap_request(dev, fd, io_req->offset, req, 
11083 +                                                io_req));
11084 +       }
11085 +
11086 +       if(req->cmd == READ)
11087 +               dev->nomap_reads++;
11088 +       else dev->nomap_writes++;
11089 +
11090 +       io_req->op = (req->cmd == READ) ? UBD_READ : UBD_WRITE;
11091 +       io_req->offsets[0] = 0;
11092 +       io_req->offsets[1] = dev->cow.data_offset;
11093 +       io_req->buffer = req->buffer;
11094 +       io_req->sectorsize = 1 << 9;
11095 +
11096 +        if(dev->cow.file != NULL) 
11097 +               cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
11098 +                          dev->cow.bitmap_len);
11099 +       return(0);
11100 +}
11101 +
11102 +static void do_ubd_request(request_queue_t *q)
11103 +{
11104 +       struct io_thread_req io_req;
11105 +       struct request *req;
11106 +       int err, n;
11107 +
11108 +       if(thread_fd == -1){
11109 +               while(!list_empty(&q->queue_head)){
11110 +                       req = blkdev_entry_next_request(&q->queue_head);
11111 +                       err = prepare_request(req, &io_req);
11112 +                       if(!err){
11113 +                               do_io(&io_req);
11114 +                               ubd_finish(io_req.error);
11115 +                       }
11116 +               }
11117 +       }
11118 +       else {
11119 +               if(DEVICE_INTR || list_empty(&q->queue_head)) return;
11120 +               req = blkdev_entry_next_request(&q->queue_head);
11121 +               err = prepare_request(req, &io_req);
11122 +               if(!err){
11123 +                       SET_INTR(ubd_handler);
11124 +                       n = write_ubd_fs(thread_fd, (char *) &io_req, 
11125 +                                        sizeof(io_req));
11126 +                       if(n != sizeof(io_req))
11127 +                               printk("write to io thread failed, "
11128 +                                      "errno = %d\n", -n);
11129 +               }
11130 +       }
11131 +}
11132 +
11133 +static int ubd_ioctl(struct inode * inode, struct file * file,
11134 +                    unsigned int cmd, unsigned long arg)
11135 +{
11136 +       struct hd_geometry *loc = (struct hd_geometry *) arg;
11137 +       struct ubd *dev;
11138 +       int n, minor, err;
11139 +       struct hd_driveid ubd_id = {
11140 +               .cyls           = 0,
11141 +               .heads          = 128,
11142 +               .sectors        = 32,
11143 +       };
11144 +       
11145 +        if(!inode) return(-EINVAL);
11146 +       minor = MINOR(inode->i_rdev);
11147 +       n = minor >> UBD_SHIFT;
11148 +       if(n >= MAX_DEV)
11149 +               return(-EINVAL);
11150 +       dev = &ubd_dev[n];
11151 +       switch (cmd) {
11152 +               struct hd_geometry g;
11153 +               struct cdrom_volctrl volume;
11154 +       case HDIO_GETGEO:
11155 +               if(!loc) return(-EINVAL);
11156 +               g.heads = 128;
11157 +               g.sectors = 32;
11158 +               g.cylinders = dev->size / (128 * 32 * hardsect_sizes[minor]);
11159 +               g.start = ubd_part[minor].start_sect;
11160 +               return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
11161 +       case BLKGETSIZE:   /* Return device size */
11162 +               if(!arg) return(-EINVAL);
11163 +               err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
11164 +               if(err)
11165 +                       return(err);
11166 +               put_user(ubd_part[minor].nr_sects, (long *) arg);
11167 +               return(0);
11168 +       case BLKRRPART: /* Re-read partition tables */
11169 +               return(ubd_revalidate(inode->i_rdev));
11170 +
11171 +       case HDIO_GET_IDENTITY:
11172 +               ubd_id.cyls = dev->size / (128 * 32 * hardsect_sizes[minor]);
11173 +               if(copy_to_user((char *) arg, (char *) &ubd_id, 
11174 +                                sizeof(ubd_id)))
11175 +                       return(-EFAULT);
11176 +               return(0);
11177 +               
11178 +       case CDROMVOLREAD:
11179 +               if(copy_from_user(&volume, (char *) arg, sizeof(volume)))
11180 +                       return(-EFAULT);
11181 +               volume.channel0 = 255;
11182 +               volume.channel1 = 255;
11183 +               volume.channel2 = 255;
11184 +               volume.channel3 = 255;
11185 +               if(copy_to_user((char *) arg, &volume, sizeof(volume)))
11186 +                       return(-EFAULT);
11187 +               return(0);
11188 +
11189 +       default:
11190 +               return blk_ioctl(inode->i_rdev, cmd, arg);
11191 +       }
11192 +}
11193 +
11194 +static int ubd_revalidate1(kdev_t rdev)
11195 +{
11196 +       int i, n, offset, err = 0, pcount = 1 << UBD_SHIFT;
11197 +       struct ubd *dev;
11198 +       struct hd_struct *part;
11199 +
11200 +       n = DEVICE_NR(rdev);
11201 +       offset = n << UBD_SHIFT;
11202 +       dev = &ubd_dev[n];
11203 +
11204 +       part = &ubd_part[offset];
11205 +
11206 +       /* clear all old partition counts */
11207 +       for(i = 1; i < pcount; i++) {
11208 +               part[i].start_sect = 0;
11209 +               part[i].nr_sects = 0;
11210 +       }
11211 +
11212 +       /* If it already has been opened we can check the partitions 
11213 +        * directly 
11214 +        */
11215 +       if(dev->count){
11216 +               part->start_sect = 0;
11217 +               register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount, 
11218 +                             &ubd_blops, part->nr_sects);
11219 +       } 
11220 +       else if(dev->file){
11221 +               err = ubd_open_dev(dev);
11222 +               if(err){
11223 +                       printk(KERN_ERR "unable to open %s for validation\n",
11224 +                              dev->file);
11225 +                       goto out;
11226 +               }
11227 +
11228 +               /* have to recompute sizes since we opened it */
11229 +               err = ubd_file_size(dev, &dev->size);
11230 +               if(err < 0) {
11231 +                       ubd_close(dev);
11232 +                       goto out;
11233 +               }
11234 +               part->start_sect = 0;
11235 +               part->nr_sects = dev->size / hardsect_sizes[offset];
11236 +               register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount, 
11237 +                             &ubd_blops, part->nr_sects);
11238 +
11239 +               /* we are done so close it */
11240 +               ubd_close(dev);
11241 +       } 
11242 +       else err = -ENODEV;
11243 + out:
11244 +       return(err);
11245 +}
11246 +
11247 +static int ubd_revalidate(kdev_t rdev)
11248 +{
11249 +       int err;
11250 +
11251 +       spin_lock(&ubd_lock);
11252 +       err = ubd_revalidate1(rdev);
11253 +       spin_unlock(&ubd_lock);
11254 +       return(err);
11255 +}
11256 +
11257 +static int ubd_check_remapped(int fd, unsigned long address, int is_write,
11258 +                             __u64 offset, int is_user)
11259 +{
11260 +       __u64 bitmap_offset;
11261 +       unsigned long new_bitmap[2];
11262 +       int i, err, n;
11263 +
11264 +       /* This can only fix kernelspace faults */
11265 +       if(is_user)
11266 +               return(0);
11267 +
11268 +       /* ubd-mmap is only enabled in skas mode */
11269 +       if(CHOOSE_MODE(1, 0))
11270 +               return(0);
11271 +
11272 +       /* If it's not a write access, we can't do anything about it */
11273 +       if(!is_write)
11274 +               return(0);
11275 +
11276 +       /* We have a write */
11277 +       for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
11278 +               struct ubd *dev = &ubd_dev[i];
11279 +
11280 +               if((dev->fd != fd) && (dev->cow.fd != fd))
11281 +                       continue;
11282 +
11283 +               /* It's a write to a ubd device */
11284 +
11285 +               if(!dev->openflags.w){
11286 +                       /* It's a write access on a read-only device - probably
11287 +                        * shouldn't happen.  If the kernel is trying to change
11288 +                        * something with no intention of writing it back out,
11289 +                        * then this message will clue us in that this needs
11290 +                        * fixing
11291 +                        */
11292 +                       printk("Write access to mapped page from readonly ubd "
11293 +                              "device %d\n", i);
11294 +                       return(0);
11295 +               }
11296 +
11297 +               /* It's a write to a writeable ubd device - it must be COWed
11298 +                * because, otherwise, the page would have been mapped in 
11299 +                * writeable
11300 +                */
11301 +
11302 +               if(!dev->cow.file)
11303 +                       panic("Write fault on writeable non-COW ubd device %d",
11304 +                             i);
11305 +
11306 +               /* It should also be an access to the backing file since the 
11307 +                * COW pages should be mapped in read-write
11308 +                */
11309 +
11310 +               if(fd == dev->fd)
11311 +                       panic("Write fault on a backing page of ubd "
11312 +                             "device %d\n", i);
11313 +
11314 +               /* So, we do the write, copying the backing data to the COW 
11315 +                * file... 
11316 +                */
11317 +
11318 +               err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
11319 +               if(err < 0)
11320 +                       panic("Couldn't seek to %lld in COW file of ubd "
11321 +                             "device %d, err = %d", 
11322 +                             offset + dev->cow.data_offset, i, -err);
11323 +
11324 +               n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
11325 +               if(n != PAGE_SIZE)
11326 +                       panic("Couldn't copy data to COW file of ubd "
11327 +                             "device %d, err = %d", i, -n);
11328 +
11329 +               /* ... updating the COW bitmap... */
11330 +
11331 +               cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset, 
11332 +                             dev->cow.bitmap, dev->cow.bitmap_offset, 
11333 +                             new_bitmap, dev->cow.bitmap_len);
11334 +
11335 +               err = os_seek_file(dev->fd, bitmap_offset);
11336 +               if(err < 0)
11337 +                       panic("Couldn't seek to %lld in COW file of ubd "
11338 +                             "device %d, err = %d", bitmap_offset, i, -err);
11339 +
11340 +               n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
11341 +               if(n != sizeof(new_bitmap))
11342 +                       panic("Couldn't update bitmap  of ubd device %d, "
11343 +                             "err = %d", i, -n);
11344 +               
11345 +               /* Maybe we can map the COW page in, and maybe we can't.  If
11346 +                * it is a pre-V3 COW file, we can't, since the alignment will 
11347 +                * be wrong.  If it is a V3 or later COW file which has been 
11348 +                * moved to a system with a larger page size, then maybe we 
11349 +                * can't, depending on the exact location of the page.
11350 +                */
11351 +
11352 +               offset += dev->cow.data_offset;
11353 +
11354 +               /* Remove the remapping, putting the original anonymous page
11355 +                * back.  If the COW file can be mapped in, that is done.
11356 +                * Otherwise, the COW page is read in.
11357 +                */
11358 +
11359 +               if(!physmem_remove_mapping((void *) address))
11360 +                       panic("Address 0x%lx not remapped by ubd device %d", 
11361 +                             address, i);
11362 +               if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
11363 +                       physmem_subst_mapping((void *) address, dev->fd, 
11364 +                                             offset, 1);
11365 +               else {
11366 +                       err = os_seek_file(dev->fd, offset);
11367 +                       if(err < 0)
11368 +                               panic("Couldn't seek to %lld in COW file of "
11369 +                                     "ubd device %d, err = %d", offset, i, 
11370 +                                     -err);
11371 +
11372 +                       n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
11373 +                       if(n != PAGE_SIZE)
11374 +                               panic("Failed to read page from offset %llx of "
11375 +                                     "COW file of ubd device %d, err = %d",
11376 +                                     offset, i, -n);
11377 +               }
11378 +
11379 +               return(1);
11380 +       }
11381 +
11382 +       /* It's not a write on a ubd device */
11383 +       return(0);
11384 +}
11385 +
11386 +static struct remapper ubd_remapper = {
11387 +       .list   = LIST_HEAD_INIT(ubd_remapper.list),
11388 +       .proc   = ubd_check_remapped,
11389 +};
11390 +
11391 +static int ubd_remapper_setup(void)
11392 +{
11393 +       if(ubd_do_mmap)
11394 +               register_remapper(&ubd_remapper);
11395 +
11396 +       return(0);
11397 +}
11398 +
11399 +__initcall(ubd_remapper_setup);
11400 +
11401 +/*
11402 + * Overrides for Emacs so that we follow Linus's tabbing style.
11403 + * Emacs will notice this stuff at the end of the file and automatically
11404 + * adjust the settings for this buffer only.  This must remain at the end
11405 + * of the file.
11406 + * ---------------------------------------------------------------------------
11407 + * Local variables:
11408 + * c-file-style: "linux"
11409 + * End:
11410 + */
11411 Index: linux-2.4.29/arch/um/drivers/ubd_user.c
11412 ===================================================================
11413 --- linux-2.4.29.orig/arch/um/drivers/ubd_user.c        1970-01-01 03:00:00.000000000 +0300
11414 +++ linux-2.4.29/arch/um/drivers/ubd_user.c     2005-05-03 22:28:14.259442448 +0300
11415 @@ -0,0 +1,379 @@
11416 +/* 
11417 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
11418 + * Copyright (C) 2001 Ridgerun,Inc (glonnon@ridgerun.com)
11419 + * Licensed under the GPL
11420 + */
11421 +
11422 +#include <stddef.h>
11423 +#include <unistd.h>
11424 +#include <errno.h>
11425 +#include <sched.h>
11426 +#include <signal.h>
11427 +#include <string.h>
11428 +#include <netinet/in.h>
11429 +#include <sys/time.h>
11430 +#include <sys/socket.h>
11431 +#include <sys/mman.h>
11432 +#include <sys/param.h>
11433 +#include "asm/types.h"
11434 +#include "user_util.h"
11435 +#include "kern_util.h"
11436 +#include "user.h"
11437 +#include "ubd_user.h"
11438 +#include "os.h"
11439 +#include "cow.h"
11440 +
11441 +#include <endian.h>
11442 +#include <byteswap.h>
11443 +
11444 +static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
11445 +{
11446 +       struct uml_stat buf1, buf2;
11447 +       int err;
11448 +
11449 +       if(from_cmdline == NULL) return(1);
11450 +       if(!strcmp(from_cmdline, from_cow)) return(1);
11451 +
11452 +       err = os_stat_file(from_cmdline, &buf1);
11453 +       if(err < 0){
11454 +               printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
11455 +               return(1);
11456 +       }
11457 +       err = os_stat_file(from_cow, &buf2);
11458 +       if(err < 0){
11459 +               printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
11460 +               return(1);
11461 +       }
11462 +       if((buf1.ust_major == buf2.ust_major) && 
11463 +          (buf1.ust_minor == buf2.ust_minor) && 
11464 +          (buf1.ust_ino == buf2.ust_ino))
11465 +               return(1);
11466 +
11467 +       printk("Backing file mismatch - \"%s\" requested,\n"
11468 +              "\"%s\" specified in COW header of \"%s\"\n",
11469 +              from_cmdline, from_cow, cow);
11470 +       return(0);
11471 +}
11472 +
11473 +static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
11474 +{
11475 +       unsigned long modtime;
11476 +       long long actual;
11477 +       int err;
11478 +
11479 +       err = os_file_modtime(file, &modtime);
11480 +       if(err < 0){
11481 +               printk("Failed to get modification time of backing file "
11482 +                      "\"%s\", err = %d\n", file, -err);
11483 +               return(err);
11484 +       }
11485 +
11486 +       err = os_file_size(file, &actual);
11487 +       if(err < 0){
11488 +               printk("Failed to get size of backing file \"%s\", "
11489 +                      "err = %d\n", file, -err);
11490 +               return(err);
11491 +       }
11492 +
11493 +       if(actual != size){
11494 +               printk("Size mismatch (%ld vs %ld) of COW header vs backing "
11495 +                      "file\n", size, actual);
11496 +               return(-EINVAL);
11497 +       }
11498 +       if(modtime != mtime){
11499 +               printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
11500 +                      "file\n", mtime, modtime);
11501 +               return(-EINVAL);
11502 +       }
11503 +       return(0);
11504 +}
11505 +
11506 +int read_cow_bitmap(int fd, void *buf, int offset, int len)
11507 +{
11508 +       int err;
11509 +
11510 +       err = os_seek_file(fd, offset);
11511 +       if(err < 0) 
11512 +               return(err);
11513 +
11514 +       err = os_read_file(fd, buf, len);
11515 +       if(err < 0) 
11516 +               return(err);
11517 +
11518 +       return(0);
11519 +}
11520 +
11521 +int open_ubd_file(char *file, struct openflags *openflags, 
11522 +                 char **backing_file_out, int *bitmap_offset_out, 
11523 +                 unsigned long *bitmap_len_out, int *data_offset_out, 
11524 +                 int *create_cow_out)
11525 +{
11526 +       time_t mtime;
11527 +       __u64 size;
11528 +       __u32 version, align;
11529 +       char *backing_file;
11530 +       int fd, err, sectorsize, same, mode = 0644;
11531 +
11532 +       fd = os_open_file(file, *openflags, mode);
11533 +       if(fd < 0){
11534 +               if((fd == -ENOENT) && (create_cow_out != NULL))
11535 +                       *create_cow_out = 1;
11536 +                if(!openflags->w ||
11537 +                   ((errno != EROFS) && (errno != EACCES))) return(-errno);
11538 +               openflags->w = 0;
11539 +               fd = os_open_file(file, *openflags, mode); 
11540 +               if(fd < 0) 
11541 +                       return(fd);
11542 +        }
11543 +
11544 +       err = os_lock_file(fd, openflags->w);
11545 +       if(err < 0){
11546 +               printk("Failed to lock '%s', err = %d\n", file, -err);
11547 +               goto out_close;
11548 +       }
11549 +       
11550 +       if(backing_file_out == NULL) return(fd);
11551 +
11552 +       err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
11553 +                             &size, &sectorsize, &align, bitmap_offset_out);
11554 +       if(err && (*backing_file_out != NULL)){
11555 +               printk("Failed to read COW header from COW file \"%s\", "
11556 +                      "errno = %d\n", file, -err);
11557 +               goto out_close;
11558 +       }
11559 +       if(err) return(fd);
11560 +
11561 +       if(backing_file_out == NULL) return(fd);
11562 +       
11563 +       same = same_backing_files(*backing_file_out, backing_file, file);
11564 +
11565 +       if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
11566 +               printk("Switching backing file to '%s'\n", *backing_file_out);
11567 +               err = write_cow_header(file, fd, *backing_file_out,
11568 +                                      sectorsize, align, &size);
11569 +               if(err){
11570 +                       printk("Switch failed, errno = %d\n", -err);
11571 +                       return(err);
11572 +               }
11573 +       }
11574 +       else {
11575 +               *backing_file_out = backing_file;
11576 +               err = backing_file_mismatch(*backing_file_out, size, mtime);
11577 +               if(err) goto out_close;
11578 +       }
11579 +
11580 +       cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, 
11581 +                 bitmap_len_out, data_offset_out);
11582 +
11583 +        return(fd);
11584 + out_close:
11585 +       os_close_file(fd);
11586 +       return(err);
11587 +}
11588 +
11589 +int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
11590 +                   int sectorsize, int alignment, int *bitmap_offset_out, 
11591 +                   unsigned long *bitmap_len_out, int *data_offset_out)
11592 +{
11593 +       int err, fd;
11594 +
11595 +       flags.c = 1;
11596 +       fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
11597 +       if(fd < 0){
11598 +               err = fd;
11599 +               printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
11600 +                      -err);
11601 +               goto out;
11602 +       }
11603 +
11604 +       err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
11605 +                           bitmap_offset_out, bitmap_len_out, 
11606 +                           data_offset_out);
11607 +       if(!err)
11608 +               return(fd);
11609 +
11610 +       os_close_file(fd);
11611 + out:
11612 +       return(err);
11613 +}
11614 +
11615 +/* XXX Just trivial wrappers around os_read_file and os_write_file */
11616 +int read_ubd_fs(int fd, void *buffer, int len)
11617 +{
11618 +       return(os_read_file(fd, buffer, len));
11619 +}
11620 +
11621 +int write_ubd_fs(int fd, char *buffer, int len)
11622 +{
11623 +       return(os_write_file(fd, buffer, len));
11624 +}
11625 +
11626 +static int update_bitmap(struct io_thread_req *req)
11627 +{
11628 +       int n;
11629 +
11630 +       if(req->cow_offset == -1)
11631 +               return(0);
11632 +
11633 +       n = os_seek_file(req->fds[1], req->cow_offset);
11634 +       if(n < 0){
11635 +               printk("do_io - bitmap lseek failed : err = %d\n", -n);
11636 +               return(1);
11637 +       }
11638 +
11639 +       n = os_write_file(req->fds[1], &req->bitmap_words,
11640 +                         sizeof(req->bitmap_words));
11641 +       if(n != sizeof(req->bitmap_words)){
11642 +               printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
11643 +                      req->fds[1]);
11644 +               return(1);
11645 +       }
11646 +
11647 +       return(0);
11648 +}
11649 +
11650 +void do_io(struct io_thread_req *req)
11651 +{
11652 +       char *buf;
11653 +       unsigned long len;
11654 +       int n, nsectors, start, end, bit;
11655 +       int err;
11656 +       __u64 off;
11657 +
11658 +       if(req->op == UBD_MMAP){
11659 +               /* Touch the page to force the host to do any necessary IO to 
11660 +                * get it into memory 
11661 +                */
11662 +               n = *((volatile int *) req->buffer);
11663 +               req->error = update_bitmap(req);
11664 +               return;
11665 +       }
11666 +
11667 +       nsectors = req->length / req->sectorsize;
11668 +       start = 0;
11669 +       do {
11670 +               bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
11671 +               end = start;
11672 +               while((end < nsectors) && 
11673 +                     (ubd_test_bit(end, (unsigned char *) 
11674 +                                   &req->sector_mask) == bit))
11675 +                       end++;
11676 +
11677 +               off = req->offset + req->offsets[bit] + 
11678 +                       start * req->sectorsize;
11679 +               len = (end - start) * req->sectorsize;
11680 +               buf = &req->buffer[start * req->sectorsize];
11681 +
11682 +               err = os_seek_file(req->fds[bit], off);
11683 +               if(err < 0){
11684 +                       printk("do_io - lseek failed : err = %d\n", -err);
11685 +                       req->error = 1;
11686 +                       return;
11687 +               }
11688 +               if(req->op == UBD_READ){
11689 +                       n = 0;
11690 +                       do {
11691 +                               buf = &buf[n];
11692 +                               len -= n;
11693 +                               n = os_read_file(req->fds[bit], buf, len);
11694 +                               if (n < 0) {
11695 +                                       printk("do_io - read failed, err = %d "
11696 +                                              "fd = %d\n", -n, req->fds[bit]);
11697 +                                       req->error = 1;
11698 +                                       return;
11699 +                               }
11700 +                       } while((n < len) && (n != 0));
11701 +                       if (n < len) memset(&buf[n], 0, len - n);
11702 +               }
11703 +               else {
11704 +                       n = os_write_file(req->fds[bit], buf, len);
11705 +                       if(n != len){
11706 +                               printk("do_io - write failed err = %d "
11707 +                                      "fd = %d\n", -n, req->fds[bit]);
11708 +                               req->error = 1;
11709 +                               return;
11710 +                       }
11711 +               }
11712 +
11713 +               start = end;
11714 +       } while(start < nsectors);
11715 +
11716 +       req->error = update_bitmap(req);
11717 +}
11718 +
11719 +/* Changed in start_io_thread, which is serialized by being called only
11720 + * from ubd_init, which is an initcall.
11721 + */
11722 +int kernel_fd = -1;
11723 +
11724 +/* Only changed by the io thread */
11725 +int io_count = 0;
11726 +
11727 +int io_thread(void *arg)
11728 +{
11729 +       struct io_thread_req req;
11730 +       int n;
11731 +
11732 +       signal(SIGWINCH, SIG_IGN);
11733 +       while(1){
11734 +               n = os_read_file(kernel_fd, &req, sizeof(req));
11735 +               if(n != sizeof(req)){
11736 +                       if(n < 0)
11737 +                               printk("io_thread - read failed, fd = %d, "
11738 +                                      "err = %d\n", kernel_fd, -n);
11739 +                       else {
11740 +                               printk("io_thread - short read, fd = %d, "
11741 +                                      "length = %d\n", kernel_fd, n);
11742 +                       }
11743 +                       continue;
11744 +               }
11745 +               io_count++;
11746 +               do_io(&req);
11747 +               n = os_write_file(kernel_fd, &req, sizeof(req));
11748 +               if(n != sizeof(req))
11749 +                       printk("io_thread - write failed, fd = %d, err = %d\n",
11750 +                              kernel_fd, -n);
11751 +       }
11752 +}
11753 +
11754 +int start_io_thread(unsigned long sp, int *fd_out)
11755 +{
11756 +       int pid, fds[2], err;
11757 +
11758 +       err = os_pipe(fds, 1, 1);
11759 +       if(err < 0){
11760 +               printk("start_io_thread - os_pipe failed, err = %d\n", -err);
11761 +               goto out;
11762 +       }
11763 +
11764 +       kernel_fd = fds[0];
11765 +       *fd_out = fds[1];
11766 +
11767 +       pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
11768 +                   NULL);
11769 +       if(pid < 0){
11770 +               printk("start_io_thread - clone failed : errno = %d\n", errno);
11771 +               goto out_close;
11772 +       }
11773 +
11774 +       return(pid);
11775 +
11776 + out_close:
11777 +       os_close_file(fds[0]);
11778 +       os_close_file(fds[1]);
11779 +       kernel_fd = -1;
11780 +       *fd_out = -1;
11781 + out:
11782 +       return(err);
11783 +}
11784 +
11785 +/*
11786 + * Overrides for Emacs so that we follow Linus's tabbing style.
11787 + * Emacs will notice this stuff at the end of the file and automatically
11788 + * adjust the settings for this buffer only.  This must remain at the end
11789 + * of the file.
11790 + * ---------------------------------------------------------------------------
11791 + * Local variables:
11792 + * c-file-style: "linux"
11793 + * End:
11794 + */
11795 Index: linux-2.4.29/arch/um/drivers/xterm.c
11796 ===================================================================
11797 --- linux-2.4.29.orig/arch/um/drivers/xterm.c   1970-01-01 03:00:00.000000000 +0300
11798 +++ linux-2.4.29/arch/um/drivers/xterm.c        2005-05-03 22:28:14.260442296 +0300
11799 @@ -0,0 +1,213 @@
11800 +/* 
11801 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
11802 + * Licensed under the GPL
11803 + */
11804 +
11805 +#include <stdio.h>
11806 +#include <stdlib.h>
11807 +#include <unistd.h>
11808 +#include <string.h>
11809 +#include <errno.h>
11810 +#include <termios.h>
11811 +#include <signal.h>
11812 +#include <sched.h>
11813 +#include <sys/socket.h>
11814 +#include "kern_util.h"
11815 +#include "chan_user.h"
11816 +#include "helper.h"
11817 +#include "user_util.h"
11818 +#include "user.h"
11819 +#include "os.h"
11820 +#include "xterm.h"
11821 +
11822 +struct xterm_chan {
11823 +       int pid;
11824 +       int helper_pid;
11825 +       char *title;
11826 +       int device;
11827 +       int raw;
11828 +       struct termios tt;
11829 +       unsigned long stack;
11830 +       int direct_rcv;
11831 +};
11832 +
11833 +void *xterm_init(char *str, int device, struct chan_opts *opts)
11834 +{
11835 +       struct xterm_chan *data;
11836 +
11837 +       data = malloc(sizeof(*data));
11838 +       if(data == NULL) return(NULL);
11839 +       *data = ((struct xterm_chan) { .pid             = -1, 
11840 +                                      .helper_pid      = -1,
11841 +                                      .device          = device, 
11842 +                                      .title           = opts->xterm_title,
11843 +                                      .raw             = opts->raw,
11844 +                                      .stack           = opts->tramp_stack,
11845 +                                      .direct_rcv      = !opts->in_kernel } );
11846 +       return(data);
11847 +}
11848 +
11849 +/* Only changed by xterm_setup, which is a setup */
11850 +static char *terminal_emulator = "xterm";
11851 +static char *title_switch = "-T";
11852 +static char *exec_switch = "-e";
11853 +
11854 +static int __init xterm_setup(char *line, int *add)
11855 +{
11856 +       *add = 0;
11857 +       terminal_emulator = line;
11858 +
11859 +       line = strchr(line, ',');
11860 +       if(line == NULL) return(0);
11861 +       *line++ = '\0';
11862 +       if(*line) title_switch = line;
11863 +
11864 +       line = strchr(line, ',');
11865 +       if(line == NULL) return(0);
11866 +       *line++ = '\0';
11867 +       if(*line) exec_switch = line;
11868 +
11869 +       return(0);
11870 +}
11871 +
11872 +__uml_setup("xterm=", xterm_setup,
11873 +"xterm=<terminal emulator>,<title switch>,<exec switch>\n"
11874 +"    Specifies an alternate terminal emulator to use for the debugger,\n"
11875 +"    consoles, and serial lines when they are attached to the xterm channel.\n"
11876 +"    The values are the terminal emulator binary, the switch it uses to set\n"
11877 +"    its title, and the switch it uses to execute a subprocess,\n"
11878 +"    respectively.  The title switch must have the form '<switch> title',\n"
11879 +"    not '<switch>=title'.  Similarly, the exec switch must have the form\n"
11880 +"    '<switch> command arg1 arg2 ...'.\n"
11881 +"    The default values are 'xterm=xterm,-T,-e'.  Values for gnome-terminal\n"
11882 +"    are 'xterm=gnome-terminal,-t,-x'.\n\n"
11883 +);
11884 +
11885 +/* XXX This badly needs some cleaning up in the error paths */
11886 +int xterm_open(int input, int output, int primary, void *d, char **dev_out)
11887 +{
11888 +       struct xterm_chan *data = d;
11889 +       unsigned long stack;
11890 +       int pid, fd, new, err;
11891 +       char title[256], file[] = "/tmp/xterm-pipeXXXXXX";
11892 +       char *argv[] = { terminal_emulator, title_switch, title, exec_switch, 
11893 +                        "/usr/lib/uml/port-helper", "-uml-socket",
11894 +                        file, NULL };
11895 +
11896 +       if(os_access(argv[4], OS_ACC_X_OK) < 0)
11897 +               argv[4] = "port-helper";
11898 +
11899 +       fd = mkstemp(file);
11900 +       if(fd < 0){
11901 +               printk("xterm_open : mkstemp failed, errno = %d\n", errno);
11902 +               return(-errno);
11903 +       }
11904 +
11905 +       if(unlink(file)){
11906 +               printk("xterm_open : unlink failed, errno = %d\n", errno);
11907 +               return(-errno);
11908 +       }
11909 +       os_close_file(fd);
11910 +
11911 +       fd = os_create_unix_socket(file, sizeof(file), 1);
11912 +       if(fd < 0){
11913 +               printk("xterm_open : create_unix_socket failed, errno = %d\n", 
11914 +                      -fd);
11915 +               return(fd);
11916 +       }
11917 +
11918 +       sprintf(title, data->title, data->device);
11919 +       stack = data->stack;
11920 +       pid = run_helper(NULL, NULL, argv, &stack);
11921 +       if(pid < 0){
11922 +               printk("xterm_open : run_helper failed, errno = %d\n", -pid);
11923 +               return(pid);
11924 +       }
11925 +
11926 +       if(data->stack == 0) free_stack(stack, 0);
11927 +
11928 +       if(data->direct_rcv)
11929 +               new = os_rcv_fd(fd, &data->helper_pid);
11930 +       else {
11931 +               err = os_set_fd_block(fd, 0);
11932 +               if(err < 0){
11933 +                       printk("xterm_open : failed to set descriptor "
11934 +                              "non-blocking, err = %d\n", -err);
11935 +                       return(err);
11936 +               }
11937 +               new = xterm_fd(fd, &data->helper_pid);
11938 +       }
11939 +       if(new < 0){
11940 +               printk("xterm_open : os_rcv_fd failed, err = %d\n", -new);
11941 +               goto out;
11942 +       }
11943 +
11944 +       CATCH_EINTR(err = tcgetattr(new, &data->tt));
11945 +       if(err){
11946 +               new = err;
11947 +               goto out;
11948 +       }
11949 +
11950 +       if(data->raw){
11951 +               err = raw(new);
11952 +               if(err){
11953 +                       new = err;
11954 +                       goto out;
11955 +               }
11956 +       }
11957 +
11958 +       data->pid = pid;
11959 +       *dev_out = NULL;
11960 + out:
11961 +       unlink(file);
11962 +       return(new);
11963 +}
11964 +
11965 +void xterm_close(int fd, void *d)
11966 +{
11967 +       struct xterm_chan *data = d;
11968 +       
11969 +       if(data->pid != -1) 
11970 +               os_kill_process(data->pid, 1);
11971 +       data->pid = -1;
11972 +       if(data->helper_pid != -1) 
11973 +               os_kill_process(data->helper_pid, 0);
11974 +       data->helper_pid = -1;
11975 +       os_close_file(fd);
11976 +}
11977 +
11978 +void xterm_free(void *d)
11979 +{
11980 +       free(d);
11981 +}
11982 +
11983 +int xterm_console_write(int fd, const char *buf, int n, void *d)
11984 +{
11985 +       struct xterm_chan *data = d;
11986 +
11987 +       return(generic_console_write(fd, buf, n, &data->tt));
11988 +}
11989 +
11990 +struct chan_ops xterm_ops = {
11991 +       .type           = "xterm",
11992 +       .init           = xterm_init,
11993 +       .open           = xterm_open,
11994 +       .close          = xterm_close,
11995 +       .read           = generic_read,
11996 +       .write          = generic_write,
11997 +       .console_write  = xterm_console_write,
11998 +       .window_size    = generic_window_size,
11999 +       .free           = xterm_free,
12000 +       .winch          = 1,
12001 +};
12002 +
12003 +/*
12004 + * Overrides for Emacs so that we follow Linus's tabbing style.
12005 + * Emacs will notice this stuff at the end of the file and automatically
12006 + * adjust the settings for this buffer only.  This must remain at the end
12007 + * of the file.
12008 + * ---------------------------------------------------------------------------
12009 + * Local variables:
12010 + * c-file-style: "linux"
12011 + * End:
12012 + */
12013 Index: linux-2.4.29/arch/um/drivers/xterm.h
12014 ===================================================================
12015 --- linux-2.4.29.orig/arch/um/drivers/xterm.h   1970-01-01 03:00:00.000000000 +0300
12016 +++ linux-2.4.29/arch/um/drivers/xterm.h        2005-05-03 22:28:14.261442144 +0300
12017 @@ -0,0 +1,22 @@
12018 +/* 
12019 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
12020 + * Licensed under the GPL
12021 + */
12022 +
12023 +#ifndef __XTERM_H__
12024 +#define __XTERM_H__
12025 +
12026 +extern int xterm_fd(int socket, int *pid_out);
12027 +
12028 +#endif
12029 +
12030 +/*
12031 + * Overrides for Emacs so that we follow Linus's tabbing style.
12032 + * Emacs will notice this stuff at the end of the file and automatically
12033 + * adjust the settings for this buffer only.  This must remain at the end
12034 + * of the file.
12035 + * ---------------------------------------------------------------------------
12036 + * Local variables:
12037 + * c-file-style: "linux"
12038 + * End:
12039 + */
12040 Index: linux-2.4.29/arch/um/drivers/xterm_kern.c
12041 ===================================================================
12042 --- linux-2.4.29.orig/arch/um/drivers/xterm_kern.c      1970-01-01 03:00:00.000000000 +0300
12043 +++ linux-2.4.29/arch/um/drivers/xterm_kern.c   2005-05-03 22:28:14.262441992 +0300
12044 @@ -0,0 +1,82 @@
12045 +/* 
12046 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
12047 + * Licensed under the GPL
12048 + */
12049 +
12050 +#include "linux/errno.h"
12051 +#include "linux/slab.h"
12052 +#include "asm/semaphore.h"
12053 +#include "asm/irq.h"
12054 +#include "irq_user.h"
12055 +#include "irq_kern.h"
12056 +#include "kern_util.h"
12057 +#include "os.h"
12058 +#include "xterm.h"
12059 +
12060 +struct xterm_wait {
12061 +       struct semaphore sem;
12062 +       int fd;
12063 +       int pid;
12064 +       int new_fd;
12065 +};
12066 +
12067 +static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
12068 +{
12069 +       struct xterm_wait *xterm = data;
12070 +       int fd;
12071 +
12072 +       fd = os_rcv_fd(xterm->fd, &xterm->pid);
12073 +       if(fd == -EAGAIN)
12074 +               return;
12075 +
12076 +       xterm->new_fd = fd;
12077 +       up(&xterm->sem);
12078 +}
12079 +
12080 +int xterm_fd(int socket, int *pid_out)
12081 +{
12082 +       struct xterm_wait *data;
12083 +       int err, ret;
12084 +
12085 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
12086 +       if(data == NULL){
12087 +               printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
12088 +               return(-ENOMEM);
12089 +       }
12090 +       *data = ((struct xterm_wait) 
12091 +               { .sem          = __SEMAPHORE_INITIALIZER(data->sem, 0),
12092 +                 .fd           = socket,
12093 +                 .pid          = -1,
12094 +                 .new_fd       = -1 });
12095 +
12096 +       err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, 
12097 +                            SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
12098 +                            "xterm", data);
12099 +       if(err){
12100 +               printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
12101 +                      "err = %d\n",  err);
12102 +               ret = err;
12103 +               goto out;
12104 +       }
12105 +       down(&data->sem);
12106 +
12107 +       free_irq(XTERM_IRQ, data);
12108 +
12109 +       ret = data->new_fd;
12110 +       *pid_out = data->pid;
12111 + out:
12112 +       kfree(data);
12113 +
12114 +       return(ret);
12115 +}
12116 +
12117 +/*
12118 + * Overrides for Emacs so that we follow Linus's tabbing style.
12119 + * Emacs will notice this stuff at the end of the file and automatically
12120 + * adjust the settings for this buffer only.  This must remain at the end
12121 + * of the file.
12122 + * ---------------------------------------------------------------------------
12123 + * Local variables:
12124 + * c-file-style: "linux"
12125 + * End:
12126 + */
12127 Index: linux-2.4.29/arch/um/fs/hostfs/externfs.c
12128 ===================================================================
12129 --- linux-2.4.29.orig/arch/um/fs/hostfs/externfs.c      1970-01-01 03:00:00.000000000 +0300
12130 +++ linux-2.4.29/arch/um/fs/hostfs/externfs.c   2005-05-03 22:28:14.269440928 +0300
12131 @@ -0,0 +1,1283 @@
12132 +/* 
12133 + * Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com)
12134 + * Licensed under the GPL
12135 + */
12136 +
12137 +#include <linux/stddef.h>
12138 +#include <linux/fs.h>
12139 +#include <linux/version.h>
12140 +#include <linux/module.h>
12141 +#include <linux/init.h>
12142 +#include <linux/slab.h>
12143 +#include <linux/pagemap.h>
12144 +#include <linux/blkdev.h>
12145 +#include <asm/uaccess.h>
12146 +#include "hostfs.h"
12147 +#include "kern_util.h"
12148 +#include "kern.h"
12149 +#include "user_util.h"
12150 +#include "2_5compat.h"
12151 +#include "mem.h"
12152 +#include "filehandle.h"
12153 +
12154 +struct externfs {
12155 +       struct list_head list;
12156 +       struct externfs_mount_ops *mount_ops;
12157 +       struct file_system_type type;
12158 +};
12159 +
12160 +static inline struct externfs_inode *EXTERNFS_I(struct inode *inode)
12161 +{
12162 +       return(inode->u.generic_ip);
12163 +}
12164 +
12165 +#define file_externfs_i(file) EXTERNFS_I((file)->f_dentry->d_inode)
12166 +
12167 +int externfs_d_delete(struct dentry *dentry)
12168 +{
12169 +       return(1);
12170 +}
12171 +
12172 +struct dentry_operations externfs_dentry_ops = {
12173 +};
12174 +
12175 +#define EXTERNFS_SUPER_MAGIC 0x00c0ffee
12176 +
12177 +static struct inode_operations externfs_iops;
12178 +static struct inode_operations externfs_dir_iops;
12179 +static struct address_space_operations externfs_link_aops;
12180 +
12181 +static char *dentry_name(struct dentry *dentry, int extra)
12182 +{
12183 +       struct dentry *parent;
12184 +       char *name;
12185 +       int len;
12186 +
12187 +       len = 0;
12188 +       parent = dentry;
12189 +       while(parent->d_parent != parent){
12190 +               len += parent->d_name.len + 1;
12191 +               parent = parent->d_parent;
12192 +       }
12193 +       
12194 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
12195 +       if(name == NULL) return(NULL);
12196 +
12197 +       name[len] = '\0';
12198 +       parent = dentry;
12199 +       while(parent->d_parent != parent){
12200 +               len -= parent->d_name.len + 1;
12201 +               name[len] = '/';
12202 +               strncpy(&name[len + 1], parent->d_name.name, 
12203 +                       parent->d_name.len);
12204 +               parent = parent->d_parent;
12205 +       }
12206 +
12207 +       return(name);
12208 +}
12209 +
12210 +char *inode_name(struct inode *ino, int extra)
12211 +{
12212 +       struct dentry *dentry;
12213 +
12214 +       dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
12215 +       return(dentry_name(dentry, extra));
12216 +}
12217 +
12218 +char *inode_name_prefix(struct inode *inode, char *prefix)
12219 +{
12220 +       int len;
12221 +       char *name;
12222 +
12223 +       len = strlen(prefix);
12224 +       name = inode_name(inode, len);
12225 +       if(name == NULL)
12226 +               return(name);
12227 +
12228 +       memmove(&name[len], name, strlen(name) + 1);
12229 +       memcpy(name, prefix, strlen(prefix));
12230 +       return(name);
12231 +}
12232 +
12233 +static int read_name(struct inode *ino, char *name)
12234 +{
12235 +       struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
12236 +       /* The non-int inode fields are copied into ints by stat_file and
12237 +        * then copied into the inode because passing the actual pointers
12238 +        * in and having them treated as int * breaks on big-endian machines
12239 +        */
12240 +       int err;
12241 +       int i_dev, i_mode, i_nlink, i_blksize;
12242 +       unsigned long long i_size;
12243 +       unsigned long long i_ino;
12244 +       unsigned long long i_blocks;
12245 +
12246 +       err = (*ops->stat_file)(name, ino->i_sb->u.generic_sbp, 
12247 +                               (dev_t *) &i_dev, &i_ino, &i_mode, &i_nlink,
12248 +                               &ino->i_uid, &ino->i_gid, &i_size, 
12249 +                               &ino->i_atime, &ino->i_mtime, &ino->i_ctime, 
12250 +                               &i_blksize, &i_blocks);
12251 +       if(err) return(err);
12252 +       ino->i_ino = i_ino;
12253 +       ino->i_dev = i_dev;
12254 +       ino->i_mode = i_mode;
12255 +       ino->i_nlink = i_nlink;
12256 +       ino->i_size = i_size;
12257 +       ino->i_blksize = i_blksize;
12258 +       ino->i_blocks = i_blocks;
12259 +       return(0);
12260 +}
12261 +
12262 +static char *follow_link(char *link, 
12263 +                        int (*do_read_link)(char *path, int uid, int gid,
12264 +                                            char *buf, int size, 
12265 +                                            struct externfs_data *ed),
12266 +                        int uid, int gid, struct externfs_data *ed)
12267 +{
12268 +       int len, n;
12269 +       char *name, *resolved, *end;
12270 +
12271 +       len = 64;
12272 +       while(1){
12273 +               n = -ENOMEM;
12274 +               name = kmalloc(len, GFP_KERNEL);
12275 +               if(name == NULL)
12276 +                       goto out;
12277 +
12278 +               n = (*do_read_link)(link, uid, gid, name, len, ed);
12279 +               if(n < len)
12280 +                       break;
12281 +               len *= 2;
12282 +               kfree(name);
12283 +       }
12284 +       if(n < 0)
12285 +               goto out_free;
12286 +
12287 +       if(*name == '/')
12288 +               return(name);
12289 +
12290 +       end = strrchr(link, '/');
12291 +       if(end == NULL)
12292 +               return(name);
12293 +
12294 +       *(end + 1) = '\0';
12295 +       len = strlen(link) + strlen(name) + 1;
12296 +
12297 +       resolved = kmalloc(len, GFP_KERNEL);
12298 +       if(resolved == NULL){
12299 +               n = -ENOMEM;
12300 +               goto out_free;
12301 +       }
12302 +
12303 +       sprintf(resolved, "%s%s", link, name);
12304 +       kfree(name);
12305 +       return(resolved);
12306 +
12307 + out_free:
12308 +       kfree(name);
12309 + out:
12310 +       return(ERR_PTR(n));
12311 +}
12312 +
12313 +static int read_inode(struct inode *ino)
12314 +{
12315 +       struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
12316 +       struct externfs_data *ed = ino->i_sb->u.generic_sbp;
12317 +       char *name, *new;
12318 +       int err, type;
12319 +
12320 +       err = -ENOMEM;
12321 +       name = inode_name(ino, 0);
12322 +       if(name == NULL) 
12323 +               goto out;
12324 +
12325 +       type = (*ops->file_type)(name, NULL, ed);
12326 +       if(type < 0){
12327 +               err = type;
12328 +               goto out_free;
12329 +       }
12330 +
12331 +       if(type == OS_TYPE_SYMLINK){
12332 +               new = follow_link(name, ops->read_link, current->fsuid,
12333 +                                 current->fsgid, ed);
12334 +               if(IS_ERR(new)){
12335 +                       err = PTR_ERR(new);
12336 +                       goto out_free;
12337 +               }
12338 +               kfree(name);
12339 +               name = new;
12340 +       }
12341 +       
12342 +       err = read_name(ino, name);
12343 + out_free:
12344 +       kfree(name);
12345 + out:
12346 +       return(err);
12347 +}
12348 +
12349 +void externfs_delete_inode(struct inode *ino)
12350 +{
12351 +       struct externfs_inode *ext = EXTERNFS_I(ino);
12352 +       struct externfs_file_ops *ops = ext->ops;
12353 +
12354 +       (*ops->close_file)(ext, ino->i_size);
12355 +
12356 +       clear_inode(ino);
12357 +}
12358 +
12359 +int externfs_statfs(struct super_block *sb, struct statfs *sf)
12360 +{
12361 +       /* do_statfs uses struct statfs64 internally, but the linux kernel
12362 +        * struct statfs still has 32-bit versions for most of these fields,
12363 +        * so we convert them here
12364 +        */
12365 +       int err;
12366 +       long long f_blocks;
12367 +       long long f_bfree;
12368 +       long long f_bavail;
12369 +       long long f_files;
12370 +       long long f_ffree;
12371 +       struct externfs_data *ed = sb->u.generic_sbp;
12372 +       
12373 +       err = (*ed->file_ops->statfs)(&sf->f_bsize, &f_blocks, &f_bfree, 
12374 +                                     &f_bavail, &f_files, &f_ffree, 
12375 +                                     &sf->f_fsid, sizeof(sf->f_fsid), 
12376 +                                     &sf->f_namelen, sf->f_spare, ed);
12377 +       if(err)
12378 +               return(err);
12379 +
12380 +       sf->f_blocks = f_blocks;
12381 +       sf->f_bfree = f_bfree;
12382 +       sf->f_bavail = f_bavail;
12383 +       sf->f_files = f_files;
12384 +       sf->f_ffree = f_ffree;
12385 +       sf->f_type = EXTERNFS_SUPER_MAGIC;
12386 +       return(0);
12387 +}
12388 +
12389 +static struct super_operations externfs_sbops = { 
12390 +       .delete_inode   = externfs_delete_inode,
12391 +       .statfs         = externfs_statfs,
12392 +};
12393 +
12394 +int externfs_readdir(struct file *file, void *ent, filldir_t filldir)
12395 +{
12396 +       void *dir;
12397 +       char *name;
12398 +       unsigned long long next, ino;
12399 +       int error, len;
12400 +       struct externfs_file_ops *ops = file_externfs_i(file)->ops;
12401 +       struct externfs_data *ed = 
12402 +               file->f_dentry->d_inode->i_sb->u.generic_sbp;
12403 +
12404 +       name = dentry_name(file->f_dentry, 0);
12405 +       if(name == NULL) 
12406 +               return(-ENOMEM);
12407 +
12408 +       dir = (*ops->open_dir)(name, current->fsuid, current->fsgid, ed);
12409 +       kfree(name);
12410 +       if(IS_ERR(dir)) 
12411 +               return(PTR_ERR(dir));
12412 +
12413 +       next = file->f_pos;
12414 +       while((name = (*ops->read_dir)(dir, &next, &ino, &len, ed)) != NULL){
12415 +               error = (*filldir)(ent, name, len, file->f_pos, ino, 
12416 +                                  DT_UNKNOWN);
12417 +               if(error) 
12418 +                       break;
12419 +               file->f_pos = next;
12420 +       }
12421 +       (*ops->close_dir)(dir, ed);
12422 +       return(0);
12423 +}
12424 +
12425 +int externfs_file_open(struct inode *ino, struct file *file)
12426 +{
12427 +       ino->i_nlink++;
12428 +       return(0);
12429 +}
12430 +
12431 +int externfs_dir_open(struct inode *ino, struct file *file)
12432 +{
12433 +       return(0);      
12434 +}
12435 +
12436 +int externfs_dir_release(struct inode *ino, struct file *file)
12437 +{
12438 +       return(0);
12439 +}
12440 +
12441 +int externfs_fsync(struct file *file, struct dentry *dentry, int datasync)
12442 +{
12443 +       struct externfs_file_ops *ops = file_externfs_i(file)->ops;
12444 +       struct inode *inode = dentry->d_inode;
12445 +       struct externfs_data *ed = inode->i_sb->u.generic_sbp;
12446 +
12447 +       return((*ops->truncate_file)(EXTERNFS_I(inode), inode->i_size, ed));
12448 +}
12449 +
12450 +static struct file_operations externfs_file_fops = {
12451 +       .owner          = NULL,
12452 +       .read           = generic_file_read,
12453 +       .write          = generic_file_write,
12454 +       .mmap           = generic_file_mmap,
12455 +       .open           = externfs_file_open,
12456 +       .release        = NULL,
12457 +       .fsync          = externfs_fsync,
12458 +};
12459 +
12460 +static struct file_operations externfs_dir_fops = {
12461 +       .owner          = NULL,
12462 +       .readdir        = externfs_readdir,
12463 +       .open           = externfs_dir_open,
12464 +       .release        = externfs_dir_release,
12465 +       .fsync          = externfs_fsync,
12466 +};
12467 +
12468 +struct wp_info {
12469 +       struct page *page;
12470 +       int count;
12471 +       unsigned long long start;
12472 +       unsigned long long size;
12473 +       int (*truncate)(struct externfs_inode *ei, __u64 size, 
12474 +                       struct externfs_data *ed);
12475 +       struct externfs_inode *ei;
12476 +       struct externfs_data *ed;
12477 +};
12478 +
12479 +static void externfs_finish_writepage(char *buffer, int res, void *arg)
12480 +{
12481 +       struct wp_info *wp = arg;
12482 +
12483 +       if(res == wp->count){
12484 +               ClearPageError(wp->page);
12485 +               if(wp->start + res > wp->size)
12486 +                       (*wp->truncate)(wp->ei, wp->size, wp->ed);
12487 +       }
12488 +       else {
12489 +               SetPageError(wp->page);
12490 +               ClearPageUptodate(wp->page);
12491 +       }               
12492 +
12493 +       kunmap(wp->page);
12494 +       unlock_page(wp->page);
12495 +       kfree(wp);
12496 +}
12497 +
12498 +static int externfs_writepage(struct page *page)
12499 +{
12500 +       struct address_space *mapping = page->mapping;
12501 +       struct inode *inode = mapping->host;
12502 +       struct externfs_file_ops *ops = EXTERNFS_I(inode)->ops;
12503 +       struct wp_info *wp;
12504 +       struct externfs_data *ed = inode->i_sb->u.generic_sbp;
12505 +       char *buffer;
12506 +       unsigned long long base;
12507 +       int count = PAGE_CACHE_SIZE;
12508 +       int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
12509 +       int err, offset;
12510 +
12511 +       base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
12512 +
12513 +       /* If we are entirely outside the file, then return an error */
12514 +       err = -EIO;
12515 +       offset = inode->i_size & (PAGE_CACHE_SIZE-1);
12516 +       if (page->index > end_index || 
12517 +           ((page->index == end_index) && !offset))
12518 +               goto out_unlock;
12519 +
12520 +       err = -ENOMEM;
12521 +       wp = kmalloc(sizeof(*wp), GFP_KERNEL);
12522 +       if(wp == NULL)
12523 +               goto out_unlock;
12524 +
12525 +       *wp = ((struct wp_info) { .page         = page,
12526 +                                 .count        = count,
12527 +                                 .start        = base,
12528 +                                 .size         = inode->i_size,
12529 +                                 .truncate     = ops->truncate_file,
12530 +                                 .ei           = EXTERNFS_I(inode),
12531 +                                 .ed           = ed });
12532 +
12533 +       buffer = kmap(page);
12534 +       err = (*ops->write_file)(EXTERNFS_I(inode), base, buffer, 0, 
12535 +                                count, externfs_finish_writepage, wp, ed);
12536 +
12537 +       return err;
12538 +
12539 + out_unlock:
12540 +       unlock_page(page);
12541 +       return(err);
12542 +}
12543 +
12544 +static void externfs_finish_readpage(char *buffer, int res, void *arg)
12545 +{
12546 +       struct page *page = arg;
12547 +       struct inode *inode;
12548 +
12549 +       if(res < 0){
12550 +               SetPageError(page);
12551 +               goto out;
12552 +       }
12553 +
12554 +       inode = page->mapping->host;
12555 +       if(inode->i_size >> PAGE_CACHE_SHIFT == page->index)
12556 +               res = inode->i_size % PAGE_CACHE_SIZE;
12557 +
12558 +       memset(&buffer[res], 0, PAGE_CACHE_SIZE - res);
12559 +
12560 +       flush_dcache_page(page);
12561 +       SetPageUptodate(page);
12562 +       if (PageError(page)) 
12563 +               ClearPageError(page);
12564 + out:
12565 +       kunmap(page);
12566 +       unlock_page(page);
12567 +}
12568 +
12569 +static int externfs_readpage(struct file *file, struct page *page)
12570 +{
12571 +       struct inode *ino = page->mapping->host;
12572 +       struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
12573 +       struct externfs_data *ed = ino->i_sb->u.generic_sbp;
12574 +       char *buffer;
12575 +       long long start;
12576 +       int err = 0;
12577 +
12578 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
12579 +       buffer = kmap(page);
12580 +
12581 +       if(ops->map_file_page != NULL){
12582 +               /* XXX What happens when PAGE_SIZE != PAGE_CACHE_SIZE? */
12583 +               err = (*ops->map_file_page)(file_externfs_i(file), start, 
12584 +                                           buffer, file->f_mode & FMODE_WRITE,
12585 +                                           ed);
12586 +               if(!err)
12587 +                       err = PAGE_CACHE_SIZE;
12588 +       }
12589 +       else err = (*ops->read_file)(file_externfs_i(file), start, buffer,
12590 +                                    PAGE_CACHE_SIZE, 0, 0, 
12591 +                                    externfs_finish_readpage, page, ed);
12592 +
12593 +       if(err > 0)
12594 +               err = 0;
12595 +       return(err);
12596 +}
12597 +
12598 +struct writepage_info {
12599 +       struct semaphore sem;
12600 +       int res;
12601 +};
12602 +
12603 +static void externfs_finish_prepare(char *buffer, int res, void *arg)
12604 +{
12605 +       struct writepage_info *wp = arg;
12606 +
12607 +       wp->res = res;
12608 +       up(&wp->sem);
12609 +}
12610 +
12611 +int externfs_prepare_write(struct file *file, struct page *page, 
12612 +                        unsigned int from, unsigned int to)
12613 +{
12614 +       struct address_space *mapping = page->mapping;
12615 +       struct inode *inode = mapping->host;
12616 +       struct externfs_file_ops *ops = EXTERNFS_I(inode)->ops;
12617 +       struct externfs_data *ed = inode->i_sb->u.generic_sbp;
12618 +       char *buffer;
12619 +       long long start;
12620 +       int err;
12621 +       struct writepage_info wp;
12622 +
12623 +       if(Page_Uptodate(page))
12624 +               return(0);
12625 +
12626 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
12627 +       buffer = kmap(page);
12628 +
12629 +       if(ops->map_file_page != NULL){
12630 +               err = (*ops->map_file_page)(file_externfs_i(file), start, 
12631 +                                           buffer, file->f_mode & FMODE_WRITE,
12632 +                                           ed);
12633 +               goto out;
12634 +       }
12635 +
12636 +       init_MUTEX_LOCKED(&wp.sem);
12637 +       err = (*ops->read_file)(file_externfs_i(file), start, buffer,
12638 +                               PAGE_CACHE_SIZE, from, to, 
12639 +                               externfs_finish_prepare, &wp, ed);
12640 +       down(&wp.sem);
12641 +       if(err < 0) 
12642 +               goto out;
12643 +
12644 +       err = wp.res;
12645 +       if(err < 0)
12646 +               goto out;
12647 +
12648 +       if(from > 0)
12649 +               memset(buffer, 0, from);
12650 +       if(to < PAGE_CACHE_SIZE)
12651 +               memset(buffer + to, 0, PAGE_CACHE_SIZE - to);
12652 +
12653 +       SetPageUptodate(page);
12654 +       err = 0;
12655 + out:
12656 +       kunmap(page);
12657 +       return(err);
12658 +}
12659 +
12660 +static int externfs_commit_write(struct file *file, struct page *page, 
12661 +                              unsigned from, unsigned to)
12662 +{
12663 +       struct address_space *mapping = page->mapping;
12664 +       struct inode *inode = mapping->host;
12665 +       struct externfs_file_ops *ops = EXTERNFS_I(inode)->ops;
12666 +       unsigned long long size;
12667 +       long long start;
12668 +       int err;
12669 +
12670 +       start = (long long) (page->index << PAGE_CACHE_SHIFT);
12671 +
12672 +       if(ops->map_file_page != NULL)
12673 +               err = to - from;
12674 +       else {
12675 +               size = start + to;
12676 +               if(size > inode->i_size){
12677 +                       inode->i_size = size;
12678 +                       mark_inode_dirty(inode);
12679 +               }
12680 +       }
12681 +
12682 +       set_page_dirty(page);
12683 +       return(to - from);
12684 +}
12685 +
12686 +static void externfs_removepage(struct page *page)
12687 +{
12688 +       physmem_remove_mapping(page_address(page));
12689 +}
12690 +
12691 +static struct address_space_operations externfs_aops = {
12692 +       .writepage      = externfs_writepage,
12693 +       .readpage       = externfs_readpage,
12694 +       .removepage     = externfs_removepage,
12695 +/*     .set_page_dirty = __set_page_dirty_nobuffers, */
12696 +       .prepare_write  = externfs_prepare_write,
12697 +       .commit_write   = externfs_commit_write
12698 +};
12699 +
12700 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
12701 +                              int need_fh)
12702 +{
12703 +       struct inode *inode;
12704 +       struct externfs_data *ed = sb->u.generic_sbp;
12705 +       struct externfs_mount_ops *ops = ed->mount_ops;
12706 +       char *name = NULL;
12707 +       int type, err = -ENOMEM, rdev;
12708 +
12709 +       if(dentry){
12710 +               name = dentry_name(dentry, 0);
12711 +               if(name == NULL)
12712 +                       goto out;
12713 +               type = (*ed->file_ops->file_type)(name, &rdev, ed);
12714 +       }
12715 +       else type = OS_TYPE_DIR;
12716 +
12717 +       inode = new_inode(sb);
12718 +       if(inode == NULL)
12719 +               goto out_free;
12720 +
12721 +       insert_inode_hash(inode);
12722 +
12723 +       if(type == OS_TYPE_SYMLINK)
12724 +               inode->i_op = &page_symlink_inode_operations;
12725 +       else if(type == OS_TYPE_DIR)
12726 +               inode->i_op = &externfs_dir_iops;
12727 +       else inode->i_op = &externfs_iops;
12728 +
12729 +       if(type == OS_TYPE_DIR) inode->i_fop = &externfs_dir_fops;
12730 +       else inode->i_fop = &externfs_file_fops;
12731 +
12732 +       if(type == OS_TYPE_SYMLINK) 
12733 +               inode->i_mapping->a_ops = &externfs_link_aops;
12734 +       else inode->i_mapping->a_ops = &externfs_aops;
12735 +
12736 +       switch (type) {
12737 +       case OS_TYPE_CHARDEV:
12738 +               init_special_inode(inode, S_IFCHR, rdev);
12739 +               break;
12740 +       case OS_TYPE_BLOCKDEV:
12741 +               init_special_inode(inode, S_IFBLK, rdev);
12742 +               break;
12743 +       case OS_TYPE_FIFO:
12744 +               init_special_inode(inode, S_IFIFO, 0);
12745 +               break;
12746 +       case OS_TYPE_SOCK:
12747 +               init_special_inode(inode, S_IFSOCK, 0);
12748 +               break;
12749 +       case OS_TYPE_SYMLINK:
12750 +               inode->i_mode = S_IFLNK | S_IRWXUGO;
12751 +       }
12752 +       
12753 +       if(need_fh){
12754 +               struct externfs_inode *ei;
12755 +
12756 +               err = -ENOMEM;
12757 +               ei = (*ops->init_file)(ed);
12758 +               if(ei == NULL)
12759 +                       goto out_put;
12760 +
12761 +               *ei = ((struct externfs_inode) { .ops   = ed->file_ops });
12762 +               inode->u.generic_ip = ei;
12763 +
12764 +               err = (*ed->file_ops->open_file)(ei, name, current->fsuid, 
12765 +                                                current->fsgid, inode, ed);
12766 +               if(err && ((err != -ENOENT) && (err != -EISDIR)))
12767 +                       goto out_put;
12768 +       }
12769 +
12770 +       return(inode);
12771 +
12772 + out_put:
12773 +       iput(inode);
12774 + out_free:
12775 +       kfree(name);
12776 + out:
12777 +       return(ERR_PTR(err));
12778 +}
12779 +
12780 +int externfs_create(struct inode *dir, struct dentry *dentry, int mode)
12781 +{
12782 +       struct externfs_file_ops *ops = EXTERNFS_I(dir)->ops;
12783 +       struct inode *inode;
12784 +       struct externfs_data *ed = dir->i_sb->u.generic_sbp;
12785 +       struct externfs_inode *ei;
12786 +       char *name;
12787 +       int err = -ENOMEM;
12788 +
12789 +       name = dentry_name(dentry, 0);
12790 +       if(name == NULL)
12791 +               goto out;
12792 +
12793 +       inode = get_inode(dir->i_sb, dentry, 0);
12794 +       if(IS_ERR(inode)){
12795 +               err = PTR_ERR(inode);
12796 +               goto out_free;
12797 +       }
12798 +
12799 +       ei = (*ed->mount_ops->init_file)(ed);
12800 +       if(ei == NULL)
12801 +               /* XXX need a free_file() */
12802 +               goto out_put;
12803 +
12804 +       *ei = ((struct externfs_inode) { .ops   = ed->file_ops });
12805 +       inode->u.generic_ip = ei;
12806 +
12807 +       err = (*ops->create_file)(ei, name, mode, current->fsuid, 
12808 +                                 current->fsuid, inode, ed);
12809 +       if(err)
12810 +               goto out_put;
12811 +
12812 +       err = read_name(inode, name);
12813 +       if(err)
12814 +               goto out_rm;
12815 +
12816 +       inode->i_nlink++;
12817 +       d_instantiate(dentry, inode);
12818 + out_free:
12819 +       kfree(name);
12820 + out:
12821 +       return(err);
12822 +
12823 + out_rm:
12824 +       (*ops->unlink_file)(name, ed);
12825 + out_put:
12826 +       inode->i_nlink = 0;
12827 +       iput(inode);
12828 +       goto out_free;
12829 +}
12830
12831 +struct dentry *externfs_lookup(struct inode *ino, struct dentry *dentry)
12832 +{
12833 +       struct inode *inode;
12834 +       char *name;
12835 +       int err;
12836 +
12837 +       inode = get_inode(ino->i_sb, dentry, 1);
12838 +       if(IS_ERR(inode)){
12839 +               err = PTR_ERR(inode);
12840 +               goto out;
12841 +       }
12842 +
12843 +       err = -ENOMEM;
12844 +       name = dentry_name(dentry, 0);
12845 +       if(name == NULL)
12846 +               goto out_put;
12847 +
12848 +       err = read_name(inode, name);
12849 +       kfree(name);
12850 +       if(err){
12851 +               if(err != -ENOENT)
12852 +                       goto out_put;
12853 +
12854 +               inode->i_nlink = 0;
12855 +               iput(inode);
12856 +               inode = NULL;
12857 +       }
12858 +       d_add(dentry, inode);
12859 +       dentry->d_op = &externfs_dentry_ops;
12860 +       return(NULL);
12861 +
12862 + out_put:
12863 +       inode->i_nlink = 0;
12864 +       iput(inode);
12865 + out:
12866 +       return(ERR_PTR(err));
12867 +}
12868 +
12869 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
12870 +{
12871 +        char *file;
12872 +       int len;
12873 +
12874 +       file = inode_name(ino, dentry->d_name.len + 1);
12875 +       if(file == NULL) return(NULL);
12876 +        strcat(file, "/");
12877 +       len = strlen(file);
12878 +        strncat(file, dentry->d_name.name, dentry->d_name.len);
12879 +       file[len + dentry->d_name.len] = '\0';
12880 +        return(file);
12881 +}
12882 +
12883 +int externfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
12884 +{
12885 +       struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
12886 +       struct externfs_data *ed = ino->i_sb->u.generic_sbp;
12887 +        char *from_name, *to_name;
12888 +        int err = -ENOMEM;
12889 +
12890 +        from_name = inode_dentry_name(ino, from); 
12891 +        if(from_name == NULL) 
12892 +               goto out;
12893 +
12894 +        to_name = dentry_name(to, 0);
12895 +       if(to_name == NULL)
12896 +               goto out_free_from;
12897 +
12898 +        err = (*ops->link_file)(to_name, from_name, current->fsuid, 
12899 +                               current->fsgid, ed);
12900 +       if(err)
12901 +               goto out_free_to;
12902 +
12903 +       d_instantiate(from, to->d_inode);
12904 +       to->d_inode->i_nlink++;
12905 +       atomic_inc(&to->d_inode->i_count);
12906 +
12907 + out_free_to:
12908 +        kfree(to_name);
12909 + out_free_from:
12910 +        kfree(from_name);
12911 + out:
12912 +        return(err);
12913 +}
12914 +
12915 +int externfs_unlink(struct inode *ino, struct dentry *dentry)
12916 +{
12917 +       struct inode *inode;
12918 +       struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
12919 +       struct externfs_data *ed = ino->i_sb->u.generic_sbp;
12920 +       char *file;
12921 +       int err;
12922 +
12923 +       file = inode_dentry_name(ino, dentry);
12924 +       if(file == NULL) 
12925 +               return(-ENOMEM);
12926 +
12927 +       inode = dentry->d_inode;
12928 +       if((inode->i_nlink == 1) && (ops->invisible != NULL))
12929 +               (*ops->invisible)(EXTERNFS_I(inode));
12930 +
12931 +       err = (*ops->unlink_file)(file, ed);
12932 +       kfree(file);
12933 +
12934 +       inode->i_nlink--;
12935 +
12936 +       return(err);
12937 +}
12938 +
12939 +int externfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
12940 +{
12941 +       struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
12942 +       struct externfs_data *ed = ino->i_sb->u.generic_sbp;
12943 +       struct inode *inode;
12944 +       char *file;
12945 +       int err;
12946 +
12947 +       file = inode_dentry_name(ino, dentry);
12948 +       if(file == NULL) 
12949 +               return(-ENOMEM);
12950 +       err = (*ops->make_symlink)(file, to, current->fsuid, current->fsgid,
12951 +                                  ed);
12952 +       kfree(file);
12953 +
12954 +       inode = get_inode(ino->i_sb, dentry, 1);
12955 +       if(IS_ERR(inode)){
12956 +               err = PTR_ERR(inode);
12957 +               goto out;
12958 +       }
12959 +
12960 +       d_instantiate(dentry, inode);
12961 +       inode->i_nlink++;
12962 +       iput(inode);
12963 + out:
12964 +       return(err);
12965 +}
12966 +
12967 +int externfs_make_dir(struct inode *ino, struct dentry *dentry, int mode)
12968 +{
12969 +       struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
12970 +       struct externfs_data *ed = ino->i_sb->u.generic_sbp;
12971 +       struct inode *inode;
12972 +       char *file;
12973 +       int err;
12974 +
12975 +       file = inode_dentry_name(ino, dentry);
12976 +       if(file == NULL) 
12977 +               return(-ENOMEM);
12978 +       err = (*ops->make_dir)(file, mode, current->fsuid, current->fsgid, ed);
12979 +
12980 +       inode = get_inode(ino->i_sb, dentry, 1);
12981 +       if(IS_ERR(inode)){
12982 +               err = PTR_ERR(inode);
12983 +               goto out_free;
12984 +       }
12985 +
12986 +       err = read_name(inode, file);
12987 +       kfree(file);
12988 +       if(err)
12989 +               goto out_put;
12990 +
12991 +       d_instantiate(dentry, inode);
12992 +       inode->i_nlink = 2;
12993 +       inode->i_mode = S_IFDIR | mode;
12994 +       iput(inode);
12995 +
12996 +       ino->i_nlink++;
12997 + out:
12998 +       return(err);
12999 + out_free:
13000 +       kfree(file);
13001 + out_put:
13002 +       inode->i_nlink = 0;
13003 +       iput(inode);
13004 +       goto out;       
13005 +}
13006 +
13007 +int externfs_remove_dir(struct inode *ino, struct dentry *dentry)
13008 +{
13009 +       struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
13010 +       void *mount = ino->i_sb->u.generic_sbp;
13011 +       char *file;
13012 +       int err;
13013 +
13014 +       file = inode_dentry_name(ino, dentry);
13015 +       if(file == NULL) 
13016 +               return(-ENOMEM);
13017 +       err = (*ops->remove_dir)(file, current->fsuid, current->fsgid, mount);
13018 +       kfree(file);
13019 +
13020 +       dentry->d_inode->i_nlink = 0;
13021 +       ino->i_nlink--;
13022 +       return(err);
13023 +}
13024 +
13025 +int externfs_make_node(struct inode *dir, struct dentry *dentry, int mode, 
13026 +                    int dev)
13027 +{
13028 +       struct externfs_file_ops *ops = EXTERNFS_I(dir)->ops;
13029 +       struct externfs_data *ed = dir->i_sb->u.generic_sbp;
13030 +       struct inode *inode;
13031 +       char *name;
13032 +       int err = -ENOMEM;
13033
13034 +       name = dentry_name(dentry, 0);
13035 +       if(name == NULL)
13036 +               goto out;
13037 +
13038 +       inode = get_inode(dir->i_sb, dentry, 1);
13039 +       if(IS_ERR(inode)){
13040 +               err = PTR_ERR(inode);
13041 +               goto out_free;
13042 +       }
13043 +
13044 +       init_special_inode(inode, mode, dev);
13045 +       err = (*ops->make_node)(name, mode & S_IRWXUGO, current->fsuid, 
13046 +                               current->fsgid, mode & S_IFMT, major(dev), 
13047 +                               minor(dev), ed);
13048 +       if(err)
13049 +               goto out_put;
13050 +       
13051 +       err = read_name(inode, name);
13052 +       if(err)
13053 +               goto out_rm;
13054 +
13055 +       d_instantiate(dentry, inode);
13056 + out_free:
13057 +       kfree(name);
13058 + out:
13059 +       return(err);
13060 +
13061 + out_rm:
13062 +       (*ops->unlink_file)(name, ed);
13063 + out_put:
13064 +       inode->i_nlink = 0;
13065 +       iput(inode);
13066 +       goto out_free;
13067 +}
13068 +
13069 +int externfs_rename(struct inode *from_ino, struct dentry *from,
13070 +                 struct inode *to_ino, struct dentry *to)
13071 +{
13072 +       struct externfs_file_ops *ops = EXTERNFS_I(from_ino)->ops;
13073 +       struct externfs_data *ed = from_ino->i_sb->u.generic_sbp;
13074 +       char *from_name, *to_name;
13075 +       int err;
13076 +
13077 +       from_name = inode_dentry_name(from_ino, from);
13078 +       if(from_name == NULL)
13079 +               return(-ENOMEM);
13080 +       to_name = inode_dentry_name(to_ino, to);
13081 +       if(to_name == NULL){
13082 +               kfree(from_name);
13083 +               return(-ENOMEM);
13084 +       }
13085 +       err = (*ops->rename_file)(from_name, to_name, ed);
13086 +       kfree(from_name);
13087 +       kfree(to_name);
13088 +
13089 +       from_ino->i_nlink--;
13090 +       to_ino->i_nlink++;
13091 +       return(err);
13092 +}
13093 +
13094 +void externfs_truncate(struct inode *ino)
13095 +{
13096 +       struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
13097 +       struct externfs_data *ed = ino->i_sb->u.generic_sbp;
13098 +
13099 +       (*ops->truncate_file)(EXTERNFS_I(ino), ino->i_size, ed);
13100 +}
13101 +
13102 +int externfs_permission(struct inode *ino, int desired)
13103 +{
13104 +       struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
13105 +       struct externfs_data *ed = ino->i_sb->u.generic_sbp;
13106 +       char *name;
13107 +       int r = 0, w = 0, x = 0, err;
13108 +
13109 +       if(ops->access_file == NULL)
13110 +               return(vfs_permission(ino, desired));
13111 +
13112 +       if(desired & MAY_READ) r = 1;
13113 +       if(desired & MAY_WRITE) w = 1;
13114 +       if(desired & MAY_EXEC) x = 1;
13115 +       name = inode_name(ino, 0);
13116 +       if(name == NULL) 
13117 +               return(-ENOMEM);
13118 +
13119 +       err = (*ops->access_file)(name, r, w, x, current->fsuid, 
13120 +                                 current->fsgid, ed);
13121 +       kfree(name);
13122 +
13123 +       if(!err) 
13124 +               err = vfs_permission(ino, desired);
13125 +       return(err);
13126 +}
13127 +
13128 +int externfs_setattr(struct dentry *dentry, struct iattr *attr)
13129 +{
13130 +       struct externfs_file_ops *ops = EXTERNFS_I(dentry->d_inode)->ops;
13131 +       struct externfs_data *ed = dentry->d_inode->i_sb->u.generic_sbp;
13132 +       struct externfs_iattr attrs;
13133 +       char *name;
13134 +       int err;
13135 +       
13136 +       attrs.ia_valid = 0;
13137 +       if(attr->ia_valid & ATTR_MODE){
13138 +               attrs.ia_valid |= EXTERNFS_ATTR_MODE;
13139 +               attrs.ia_mode = attr->ia_mode;
13140 +       }
13141 +       if(attr->ia_valid & ATTR_UID){
13142 +               attrs.ia_valid |= EXTERNFS_ATTR_UID;
13143 +               attrs.ia_uid = attr->ia_uid;
13144 +       }
13145 +       if(attr->ia_valid & ATTR_GID){
13146 +               attrs.ia_valid |= EXTERNFS_ATTR_GID;
13147 +               attrs.ia_gid = attr->ia_gid;
13148 +       }
13149 +       if(attr->ia_valid & ATTR_SIZE){
13150 +               attrs.ia_valid |= EXTERNFS_ATTR_SIZE;
13151 +               attrs.ia_size = attr->ia_size;
13152 +       }
13153 +       if(attr->ia_valid & ATTR_ATIME){
13154 +               attrs.ia_valid |= EXTERNFS_ATTR_ATIME;
13155 +               attrs.ia_atime = attr->ia_atime;
13156 +       }
13157 +       if(attr->ia_valid & ATTR_MTIME){
13158 +               attrs.ia_valid |= EXTERNFS_ATTR_MTIME;
13159 +               attrs.ia_mtime = attr->ia_mtime;
13160 +       }
13161 +       if(attr->ia_valid & ATTR_CTIME){
13162 +               attrs.ia_valid |= EXTERNFS_ATTR_CTIME;
13163 +               attrs.ia_ctime = attr->ia_ctime;
13164 +       }
13165 +       if(attr->ia_valid & ATTR_ATIME_SET){
13166 +               attrs.ia_valid |= EXTERNFS_ATTR_ATIME_SET;
13167 +       }
13168 +       if(attr->ia_valid & ATTR_MTIME_SET){
13169 +               attrs.ia_valid |= EXTERNFS_ATTR_MTIME_SET;
13170 +       }
13171 +       name = dentry_name(dentry, 0);
13172 +       if(name == NULL) 
13173 +               return(-ENOMEM);
13174 +       err = (*ops->set_attr)(name, &attrs, ed);
13175 +       kfree(name);
13176 +       if(err)
13177 +               return(err);
13178 +
13179 +       return(inode_setattr(dentry->d_inode, attr));
13180 +}
13181 +
13182 +int externfs_getattr(struct dentry *dentry, struct iattr *attr)
13183 +{
13184 +       not_implemented();
13185 +       return(-EINVAL);
13186 +}
13187 +
13188 +static struct inode_operations externfs_iops = {
13189 +       .create         = externfs_create,
13190 +       .link           = externfs_link,
13191 +       .unlink         = externfs_unlink,
13192 +       .symlink        = externfs_symlink,
13193 +       .mkdir          = externfs_make_dir,
13194 +       .rmdir          = externfs_remove_dir,
13195 +       .mknod          = externfs_make_node,
13196 +       .rename         = externfs_rename,
13197 +       .truncate       = externfs_truncate,
13198 +       .permission     = externfs_permission,
13199 +       .setattr        = externfs_setattr,
13200 +       .getattr        = externfs_getattr,
13201 +};
13202 +
13203 +static struct inode_operations externfs_dir_iops = {
13204 +       .create         = externfs_create,
13205 +       .lookup         = externfs_lookup,
13206 +       .link           = externfs_link,
13207 +       .unlink         = externfs_unlink,
13208 +       .symlink        = externfs_symlink,
13209 +       .mkdir          = externfs_make_dir,
13210 +       .rmdir          = externfs_remove_dir,
13211 +       .mknod          = externfs_make_node,
13212 +       .rename         = externfs_rename,
13213 +       .truncate       = externfs_truncate,
13214 +       .permission     = externfs_permission,
13215 +       .setattr        = externfs_setattr,
13216 +       .getattr        = externfs_getattr,
13217 +};
13218 +
13219 +int externfs_link_readpage(struct file *file, struct page *page)
13220 +{
13221 +       struct inode *ino = page->mapping->host;
13222 +       struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
13223 +       struct externfs_data *ed = ino->i_sb->u.generic_sbp;
13224 +       char *buffer, *name;
13225 +       long long start;
13226 +       int err;
13227 +
13228 +       start = page->index << PAGE_CACHE_SHIFT;
13229 +       buffer = kmap(page);
13230 +       name = inode_name(ino, 0);
13231 +       if(name == NULL) 
13232 +               return(-ENOMEM);
13233 +
13234 +       err = (*ops->read_link)(name, current->fsuid, current->fsgid, buffer, 
13235 +                               PAGE_CACHE_SIZE, ed);
13236 +
13237 +       kfree(name);
13238 +       if(err == PAGE_CACHE_SIZE)
13239 +               err = -E2BIG;
13240 +       else if(err > 0){
13241 +               flush_dcache_page(page);
13242 +               SetPageUptodate(page);
13243 +               if (PageError(page)) ClearPageError(page);
13244 +               err = 0;
13245 +       }
13246 +       kunmap(page);
13247 +       UnlockPage(page);
13248 +       return(err);
13249 +}
13250 +
13251 +static int externfs_flushpage(struct page *page, unsigned long offset)
13252 +{
13253 +       return(externfs_writepage(page));
13254 +}
13255 +
13256 +struct externfs_data *inode_externfs_info(struct inode *inode)
13257 +{
13258 +       return(inode->i_sb->u.generic_sbp);
13259 +}
13260 +
13261 +static struct address_space_operations externfs_link_aops = {
13262 +       .readpage       = externfs_link_readpage,
13263 +       .removepage     = externfs_removepage,
13264 +       .flushpage      = externfs_flushpage,
13265 +};
13266 +
13267 +DECLARE_MUTEX(externfs_sem);
13268 +struct list_head externfses = LIST_HEAD_INIT(externfses);
13269 +
13270 +static struct externfs *find_externfs(struct file_system_type *type)
13271 +{
13272 +       struct list_head *ele;
13273 +       struct externfs *fs;
13274 +
13275 +       down(&externfs_sem);
13276 +       list_for_each(ele, &externfses){
13277 +               fs = list_entry(ele, struct externfs, list);
13278 +               if(&fs->type == type)
13279 +                       goto out;
13280 +       }
13281 +       fs = NULL;
13282 + out:
13283 +       up(&externfs_sem);
13284 +       return(fs);
13285 +}
13286 +
13287 +#define DEFAULT_ROOT "/"
13288 +
13289 +char *host_root_filename(char *mount_arg)
13290 +{
13291 +       char *root = DEFAULT_ROOT;
13292 +
13293 +       if((mount_arg != NULL) && (*mount_arg != '\0'))
13294 +               root = mount_arg;
13295 +
13296 +       return(uml_strdup(root));
13297 +}
13298 +
13299 +struct super_block *externfs_read_super(struct super_block *sb, void *data, 
13300 +                                       int silent)
13301 +{
13302 +       struct externfs *fs;
13303 +       struct inode *root_inode;
13304 +       struct externfs_data *sb_data;
13305 +       int err = -EINVAL;
13306 +
13307 +       sb->s_blocksize = 1024;
13308 +       sb->s_blocksize_bits = 10;
13309 +       sb->s_magic = EXTERNFS_SUPER_MAGIC;
13310 +       sb->s_op = &externfs_sbops;
13311 +
13312 +       fs = find_externfs(sb->s_type);
13313 +       if(fs == NULL){
13314 +               printk("Couldn't find externfs for filesystem '%s'\n",
13315 +                      sb->s_type->name);
13316 +               goto out;
13317 +       }
13318 +
13319 +       sb_data = (*fs->mount_ops->mount)(data);
13320 +       if(IS_ERR(sb_data)){
13321 +               err = PTR_ERR(sb_data);
13322 +               goto out;
13323 +       }
13324 +
13325 +       sb->u.generic_sbp = sb_data;
13326 +       sb_data->mount_ops = fs->mount_ops;
13327 +
13328 +       root_inode = get_inode(sb, NULL, 1);
13329 +       if(IS_ERR(root_inode))
13330 +               goto out;
13331 +
13332 +       sb->s_root = d_alloc_root(root_inode);
13333 +       if(sb->s_root == NULL)
13334 +               goto out_put;
13335 +
13336 +       if(read_inode(root_inode))
13337 +               goto out_dput;
13338 +       return(sb);
13339 +
13340 + out_dput:
13341 +       /* dput frees the inode */
13342 +       dput(sb->s_root);
13343 +       return(NULL);
13344 + out_put:
13345 +       root_inode->i_nlink = 0;
13346 +       make_bad_inode(root_inode);
13347 +       iput(root_inode);
13348 + out:
13349 +       return(NULL);
13350 +}
13351 +
13352 +void init_externfs(struct externfs_data *ed, struct externfs_file_ops *ops)
13353 +{
13354 +       ed->file_ops = ops;
13355 +}
13356 +
13357 +int register_externfs(char *name, struct externfs_mount_ops *mount_ops)
13358 +{
13359 +       struct externfs *new;
13360 +       int err = -ENOMEM;
13361 +
13362 +       new = kmalloc(sizeof(*new), GFP_KERNEL);
13363 +       if(new == NULL)
13364 +               goto out;
13365 +
13366 +       memset(new, 0, sizeof(*new));
13367 +       *new = ((struct externfs) { .list       = LIST_HEAD_INIT(new->list),
13368 +                                   .mount_ops  = mount_ops,
13369 +                                   .type = { .name     = name,
13370 +                                             .read_super = externfs_read_super,
13371 +                                             .fs_flags = 0,
13372 +                                             .owner    = THIS_MODULE } });
13373 +       list_add(&new->list, &externfses);
13374 +
13375 +       err = register_filesystem(&new->type);
13376 +       if(err)
13377 +               goto out_del;
13378 +       return(0);
13379 +
13380 + out_del:
13381 +       list_del(&new->list);
13382 +       kfree(new);
13383 + out:
13384 +       return(err);
13385 +}
13386 +
13387 +void unregister_externfs(char *name)
13388 +{
13389 +       struct list_head *ele;
13390 +       struct externfs *fs;
13391 +
13392 +       down(&externfs_sem);
13393 +       list_for_each(ele, &externfses){
13394 +               fs = list_entry(ele, struct externfs, list);
13395 +               if(!strcmp(fs->type.name, name)){
13396 +                       list_del(ele);
13397 +                       up(&externfs_sem);
13398 +                       return;
13399 +               }
13400 +       }
13401 +       up(&externfs_sem);
13402 +       printk("Unregister_externfs - filesystem '%s' not found\n", name);
13403 +}
13404 +
13405 +/*
13406 + * Overrides for Emacs so that we follow Linus's tabbing style.
13407 + * Emacs will notice this stuff at the end of the file and automatically
13408 + * adjust the settings for this buffer only.  This must remain at the end
13409 + * of the file.
13410 + * ---------------------------------------------------------------------------
13411 + * Local variables:
13412 + * c-file-style: "linux"
13413 + * End:
13414 + */
13415 Index: linux-2.4.29/arch/um/fs/hostfs/host_file.c
13416 ===================================================================
13417 --- linux-2.4.29.orig/arch/um/fs/hostfs/host_file.c     1970-01-01 03:00:00.000000000 +0300
13418 +++ linux-2.4.29/arch/um/fs/hostfs/host_file.c  2005-05-03 22:28:14.271440624 +0300
13419 @@ -0,0 +1,441 @@
13420 +/* 
13421 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
13422 + * Licensed under the GPL
13423 + */
13424 +
13425 +#include "linux/stddef.h"
13426 +#include "linux/string.h"
13427 +#include "linux/errno.h"
13428 +#include "linux/types.h"
13429 +#include "linux/slab.h"
13430 +#include "linux/blkdev.h"
13431 +#include "asm/fcntl.h"
13432 +#include "hostfs.h"
13433 +
13434 +extern int append;
13435 +
13436 +char *get_path(const char *path[], char *buf, int size)
13437 +{
13438 +       const char **s;
13439 +       char *p;
13440 +       int new = 1;
13441 +
13442 +       for(s = path; *s != NULL; s++){
13443 +               new += strlen(*s);
13444 +               if((*(s + 1) != NULL) && (strlen(*s) > 0) && 
13445 +                  ((*s)[strlen(*s) - 1] != '/'))
13446 +                       new++;
13447 +       }
13448 +
13449 +       if(new > size){
13450 +               buf = kmalloc(new, GFP_KERNEL);
13451 +               if(buf == NULL)
13452 +                       return(NULL);
13453 +       }
13454 +
13455 +       p = buf;
13456 +       for(s = path; *s != NULL; s++){
13457 +               strcpy(p, *s);
13458 +               p += strlen(*s);
13459 +               if((*(s + 1) != NULL) && (strlen(*s) > 0) && 
13460 +                  ((*s)[strlen(*s) - 1] != '/'))
13461 +                       strcpy(p++, "/");
13462 +       }
13463 +               
13464 +       return(buf);
13465 +}
13466 +
13467 +void free_path(const char *buf, char *tmp)
13468 +{
13469 +       if((buf != tmp) && (buf != NULL))
13470 +               kfree((char *) buf);
13471 +}
13472 +
13473 +int host_open_file(const char *path[], int r, int w, struct file_handle *fh)
13474 +{
13475 +       char tmp[HOSTFS_BUFSIZE], *file;
13476 +       int mode = 0, err;
13477 +       struct openflags flags = OPENFLAGS();
13478 +
13479 +       if (r)
13480 +               flags = of_read(flags);
13481 +       if (w)
13482 +               flags = of_write(flags);
13483 +       if(append)
13484 +               flags = of_append(flags);
13485 +
13486 +       err = -ENOMEM;
13487 +       file = get_path(path, tmp, sizeof(tmp));
13488 +       if(file == NULL)
13489 +               goto out;
13490 +       
13491 +       err = open_filehandle(file, flags, mode, fh);
13492 + out:
13493 +       free_path(file, tmp);
13494 +       return(err);
13495 +}
13496 +
13497 +void *host_open_dir(const char *path[])
13498 +{
13499 +       char tmp[HOSTFS_BUFSIZE], *file;
13500 +       void *dir = ERR_PTR(-ENOMEM);
13501 +
13502 +       file = get_path(path, tmp, sizeof(tmp));
13503 +       if(file == NULL)
13504 +               goto out;
13505 +       
13506 +       dir = open_dir(file);
13507 + out:
13508 +       free_path(file, tmp);
13509 +       return(dir);
13510 +}
13511 +
13512 +char *host_read_dir(void *stream, unsigned long long *pos, 
13513 +                   unsigned long long *ino_out, int *len_out)
13514 +{
13515 +       int err;
13516 +       char *name;
13517 +
13518 +       err = os_seek_dir(stream, *pos);
13519 +       if(err)
13520 +               return(ERR_PTR(err));
13521 +
13522 +       err = os_read_dir(stream, ino_out, &name);
13523 +       if(err)
13524 +               return(ERR_PTR(err));
13525 +
13526 +       if(name == NULL)
13527 +               return(NULL);
13528 +
13529 +       *len_out = strlen(name);
13530 +       *pos = os_tell_dir(stream);
13531 +       return(name);
13532 +}
13533 +
13534 +int host_file_type(const char *path[], int *rdev)
13535 +{
13536 +       char tmp[HOSTFS_BUFSIZE], *file;
13537 +       struct uml_stat buf;
13538 +       int ret;
13539 +
13540 +       ret = -ENOMEM;
13541 +       file = get_path(path, tmp, sizeof(tmp));
13542 +       if(file == NULL)
13543 +               goto out;
13544 +
13545 +       if(rdev != NULL){
13546 +               ret = os_lstat_file(file, &buf);
13547 +               if(ret)
13548 +                       goto out;
13549 +               *rdev = MKDEV(buf.ust_rmajor, buf.ust_rminor);
13550 +       }
13551 +
13552 +       ret = os_file_type(file);
13553 + out:
13554 +       free_path(file, tmp);
13555 +       return(ret);
13556 +}
13557 +
13558 +int host_create_file(const char *path[], int mode, struct file_handle *fh)
13559 +{
13560 +       char tmp[HOSTFS_BUFSIZE], *file;
13561 +       int err = -ENOMEM;
13562 +
13563 +       file = get_path(path, tmp, sizeof(tmp));
13564 +       if(file == NULL)
13565 +               goto out;
13566 +
13567 +       err = open_filehandle(file, of_create(of_rdwr(OPENFLAGS())), mode, fh);
13568 + out:
13569 +       free_path(file, tmp);
13570 +       return(err);
13571 +}
13572 +
13573 +static int do_stat_file(const char *path, dev_t *dev_out, 
13574 +                       unsigned long long *inode_out, int *mode_out, 
13575 +                       int *nlink_out, int *uid_out, int *gid_out, 
13576 +                       unsigned long long *size_out, unsigned long *atime_out,
13577 +                       unsigned long *mtime_out, unsigned long *ctime_out,
13578 +                       int *blksize_out, unsigned long long *blocks_out)
13579 +{
13580 +       struct uml_stat buf;
13581 +       int err;
13582 +
13583 +       err = os_lstat_file(path, &buf);
13584 +       if(err < 0)
13585 +               return(err);
13586 +
13587 +       if(dev_out != NULL) *dev_out = MKDEV(buf.ust_major, buf.ust_minor);
13588 +       if(inode_out != NULL) *inode_out = buf.ust_ino;
13589 +       if(mode_out != NULL) *mode_out = buf.ust_mode;
13590 +       if(nlink_out != NULL) *nlink_out = buf.ust_nlink;
13591 +       if(uid_out != NULL) *uid_out = buf.ust_uid;
13592 +       if(gid_out != NULL) *gid_out = buf.ust_gid;
13593 +       if(size_out != NULL) *size_out = buf.ust_size;
13594 +       if(atime_out != NULL) *atime_out = buf.ust_atime;
13595 +       if(mtime_out != NULL) *mtime_out = buf.ust_mtime;
13596 +       if(ctime_out != NULL) *ctime_out = buf.ust_ctime;
13597 +       if(blksize_out != NULL) *blksize_out = buf.ust_blksize;
13598 +       if(blocks_out != NULL) *blocks_out = buf.ust_blocks;
13599 +
13600 +       return(0);
13601 +}
13602 +
13603 +int host_stat_file(const char *path[], dev_t *dev_out, 
13604 +                  unsigned long long *inode_out, int *mode_out, 
13605 +                  int *nlink_out, int *uid_out, int *gid_out, 
13606 +                  unsigned long long *size_out, unsigned long *atime_out,
13607 +                  unsigned long *mtime_out, unsigned long *ctime_out,
13608 +                  int *blksize_out, unsigned long long *blocks_out)
13609 +{
13610 +       char tmp[HOSTFS_BUFSIZE], *file;
13611 +       int err;
13612 +
13613 +       err = -ENOMEM;
13614 +       file = get_path(path, tmp, sizeof(tmp));
13615 +       if(file == NULL)
13616 +               goto out;
13617 +
13618 +       err = do_stat_file(file, dev_out, inode_out, mode_out, nlink_out,
13619 +                          uid_out, gid_out, size_out, atime_out, mtime_out,
13620 +                          ctime_out, blksize_out, blocks_out);
13621 + out:
13622 +       free_path(file, tmp);
13623 +       return(err);
13624 +}
13625 +
13626 +int host_set_attr(const char *path[], struct externfs_iattr *attrs)
13627 +{
13628 +       char tmp[HOSTFS_BUFSIZE], *file;
13629 +       unsigned long time;
13630 +       int err = 0, ma;
13631 +
13632 +       if(append && (attrs->ia_valid & EXTERNFS_ATTR_SIZE))
13633 +               return(-EPERM);
13634 +
13635 +       err = -ENOMEM;
13636 +       file = get_path(path, tmp, sizeof(tmp));
13637 +       if(file == NULL)
13638 +               goto out;
13639 +
13640 +       if(attrs->ia_valid & EXTERNFS_ATTR_MODE){
13641 +               err = os_set_file_perms(file, attrs->ia_mode);
13642 +               if(err < 0)
13643 +                       goto out;
13644 +       }
13645 +       if(attrs->ia_valid & EXTERNFS_ATTR_UID){
13646 +               err = os_set_file_owner(file, attrs->ia_uid, -1);
13647 +               if(err < 0)
13648 +                       goto out;
13649 +       }
13650 +       if(attrs->ia_valid & EXTERNFS_ATTR_GID){
13651 +               err = os_set_file_owner(file, -1, attrs->ia_gid);
13652 +               if(err < 0)
13653 +                       goto out;
13654 +       }
13655 +       if(attrs->ia_valid & EXTERNFS_ATTR_SIZE){
13656 +               err = os_truncate_file(file, attrs->ia_size);
13657 +               if(err < 0)
13658 +                       goto out;
13659 +       }
13660 +       ma = EXTERNFS_ATTR_ATIME_SET | EXTERNFS_ATTR_MTIME_SET;
13661 +       if((attrs->ia_valid & ma) == ma){
13662 +               err = os_set_file_time(file, attrs->ia_atime, attrs->ia_mtime);
13663 +               if(err)
13664 +                       goto out;
13665 +       }
13666 +       else {
13667 +               if(attrs->ia_valid & EXTERNFS_ATTR_ATIME_SET){
13668 +                       err = do_stat_file(file, NULL, NULL, NULL, NULL, NULL, 
13669 +                                          NULL, NULL, NULL, &time, 
13670 +                                          NULL, NULL, NULL);
13671 +                       if(err != 0)
13672 +                               goto out;
13673 +
13674 +                       err = os_set_file_time(file, attrs->ia_atime, time);
13675 +                       if(err)
13676 +                               goto out;
13677 +               }
13678 +               if(attrs->ia_valid & EXTERNFS_ATTR_MTIME_SET){
13679 +                       err = do_stat_file(file, NULL, NULL, NULL, NULL, NULL, 
13680 +                                          NULL, NULL, &time, NULL, 
13681 +                                          NULL, NULL, NULL);
13682 +                       if(err != 0)
13683 +                               goto out;
13684 +
13685 +                       err = os_set_file_time(file, time, attrs->ia_mtime);
13686 +                       if(err)
13687 +                               goto out;
13688 +               }
13689 +       }
13690 +       if(attrs->ia_valid & EXTERNFS_ATTR_CTIME) ;
13691 +       if(attrs->ia_valid & (EXTERNFS_ATTR_ATIME | EXTERNFS_ATTR_MTIME)){
13692 +               err = do_stat_file(file, NULL, NULL, NULL, NULL, NULL, 
13693 +                                  NULL, NULL, &attrs->ia_atime, 
13694 +                                  &attrs->ia_mtime, NULL, NULL, NULL);
13695 +               if(err != 0)
13696 +                       goto out;
13697 +       }
13698 +
13699 +       err = 0;
13700 + out:
13701 +       free_path(file, tmp);
13702 +       return(err);
13703 +}
13704 +
13705 +int host_make_symlink(const char *from[], const char *to)
13706 +{
13707 +       char tmp[HOSTFS_BUFSIZE], *file;
13708 +       int err = -ENOMEM;
13709 +
13710 +       file = get_path(from, tmp, sizeof(tmp));
13711 +       if(file == NULL)
13712 +               goto out;
13713 +       
13714 +       err = os_make_symlink(to, file);
13715 + out:
13716 +       free_path(file, tmp);
13717 +       return(err);
13718 +}
13719 +
13720 +int host_unlink_file(const char *path[])
13721 +{
13722 +       char tmp[HOSTFS_BUFSIZE], *file;
13723 +       int err = -ENOMEM;
13724 +
13725 +       if(append)
13726 +               return(-EPERM);
13727 +
13728 +       file = get_path(path, tmp, sizeof(tmp));
13729 +       if(file == NULL)
13730 +               goto out;
13731 +
13732 +       err = os_remove_file(file);
13733 + out:
13734 +       free_path(file, tmp);
13735 +       return(err);
13736 +}
13737 +
13738 +int host_make_dir(const char *path[], int mode)
13739 +{
13740 +       char tmp[HOSTFS_BUFSIZE], *file;
13741 +       int err = -ENOMEM;
13742 +
13743 +       file = get_path(path, tmp, sizeof(tmp));
13744 +       if(file == NULL)
13745 +               goto out;
13746 +
13747 +       err = os_make_dir(file, mode);
13748 + out:
13749 +       free_path(file, tmp);
13750 +       return(err);
13751 +}
13752 +
13753 +int host_remove_dir(const char *path[])
13754 +{
13755 +       char tmp[HOSTFS_BUFSIZE], *file;
13756 +       int err = -ENOMEM;
13757 +
13758 +       file = get_path(path, tmp, sizeof(tmp));
13759 +       if(file == NULL)
13760 +               goto out;
13761 +
13762 +       err = os_remove_dir(file);
13763 + out:
13764 +       free_path(file, tmp);
13765 +       return(err);
13766 +}
13767 +
13768 +int host_link_file(const char *to[], const char *from[])
13769 +{
13770 +       char from_tmp[HOSTFS_BUFSIZE], *f, to_tmp[HOSTFS_BUFSIZE], *t;
13771 +       int err = -ENOMEM;
13772 +
13773 +       f = get_path(from, from_tmp, sizeof(from_tmp));
13774 +       t = get_path(to, to_tmp, sizeof(to_tmp));
13775 +       if((f == NULL) || (t == NULL))
13776 +               goto out;
13777 +
13778 +       err = os_link_file(t, f);
13779 + out:
13780 +       free_path(f, from_tmp);
13781 +       free_path(t, to_tmp);
13782 +       return(err);
13783 +}
13784 +
13785 +int host_read_link(const char *path[], char *buf, int size)
13786 +{
13787 +       char tmp[HOSTFS_BUFSIZE], *file;
13788 +       int n = -ENOMEM;
13789 +
13790 +       file = get_path(path, tmp, sizeof(tmp));
13791 +       if(file == NULL)
13792 +               goto out;
13793 +
13794 +       n = os_read_symlink(file, buf, size);
13795 +       if(n < size) 
13796 +               buf[n] = '\0';
13797 + out:
13798 +       free_path(file, tmp);
13799 +       return(n);
13800 +}
13801 +
13802 +int host_rename_file(const char *from[], const char *to[])
13803 +{
13804 +       char from_tmp[HOSTFS_BUFSIZE], *f, to_tmp[HOSTFS_BUFSIZE], *t;
13805 +       int err = -ENOMEM;
13806 +
13807 +       f = get_path(from, from_tmp, sizeof(from_tmp));
13808 +       t = get_path(to, to_tmp, sizeof(to_tmp));
13809 +       if((f == NULL) || (t == NULL))
13810 +               goto out;
13811 +
13812 +       err = os_move_file(f, t);
13813 + out:
13814 +       free_path(f, from_tmp);
13815 +       free_path(t, to_tmp);
13816 +       return(err);
13817 +}
13818 +
13819 +int host_stat_fs(const char *path[], long *bsize_out, long long *blocks_out, 
13820 +                long long *bfree_out, long long *bavail_out, 
13821 +                long long *files_out, long long *ffree_out, void *fsid_out, 
13822 +                int fsid_size, long *namelen_out, long *spare_out)
13823 +{
13824 +       char tmp[HOSTFS_BUFSIZE], *file;
13825 +       int err = -ENOMEM;
13826 +
13827 +       file = get_path(path, tmp, sizeof(tmp));
13828 +       if(file == NULL)
13829 +               goto out;
13830 +
13831 +       err = os_stat_filesystem(file, bsize_out, blocks_out, bfree_out, 
13832 +                                bavail_out, files_out, ffree_out, fsid_out, 
13833 +                                fsid_size, namelen_out, spare_out);
13834 + out:
13835 +       free_path(file, tmp);
13836 +       return(err);
13837 +}
13838 +
13839 +char *generic_host_read_dir(void *stream, unsigned long long *pos, 
13840 +                           unsigned long long *ino_out, int *len_out, 
13841 +                           void *mount)
13842 +{
13843 +       return(host_read_dir(stream, pos, ino_out, len_out));
13844 +}
13845 +
13846 +int generic_host_truncate_file(struct file_handle *fh, __u64 size, void *m)
13847 +{
13848 +       return(truncate_file(fh, size));
13849 +}
13850 +
13851 +/*
13852 + * Overrides for Emacs so that we follow Linus's tabbing style.
13853 + * Emacs will notice this stuff at the end of the file and automatically
13854 + * adjust the settings for this buffer only.  This must remain at the end
13855 + * of the file.
13856 + * ---------------------------------------------------------------------------
13857 + * Local variables:
13858 + * c-file-style: "linux"
13859 + * End:
13860 + */
13861 Index: linux-2.4.29/arch/um/fs/hostfs/host_fs.c
13862 ===================================================================
13863 --- linux-2.4.29.orig/arch/um/fs/hostfs/host_fs.c       1970-01-01 03:00:00.000000000 +0300
13864 +++ linux-2.4.29/arch/um/fs/hostfs/host_fs.c    2005-05-03 22:28:14.273440320 +0300
13865 @@ -0,0 +1,465 @@
13866 +/* 
13867 + * Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com)
13868 + * Licensed under the GPL
13869 + */
13870 +
13871 +#include "linux/stddef.h"
13872 +#include "linux/string.h"
13873 +#include "linux/types.h"
13874 +#include "linux/errno.h"
13875 +#include "linux/slab.h"
13876 +#include "linux/init.h"
13877 +#include "linux/fs.h"
13878 +#include "linux/stat.h"
13879 +#include "hostfs.h"
13880 +#include "kern.h"
13881 +#include "init.h"
13882 +#include "kern_util.h"
13883 +#include "filehandle.h"
13884 +#include "os.h"
13885 +
13886 +/* Changed in hostfs_args before the kernel starts running */
13887 +static char *jail_dir = "/";
13888 +int append = 0;
13889 +
13890 +static int __init hostfs_args(char *options, int *add)
13891 +{
13892 +       char *ptr;
13893 +
13894 +       ptr = strchr(options, ',');
13895 +       if(ptr != NULL)
13896 +               *ptr++ = '\0';
13897 +       if(*options != '\0')
13898 +               jail_dir = options;
13899 +
13900 +       options = ptr;
13901 +       while(options){
13902 +               ptr = strchr(options, ',');
13903 +               if(ptr != NULL)
13904 +                       *ptr++ = '\0';
13905 +               if(*options != '\0'){
13906 +                       if(!strcmp(options, "append"))
13907 +                               append = 1;
13908 +                       else printf("hostfs_args - unsupported option - %s\n",
13909 +                                   options);
13910 +               }
13911 +               options = ptr;
13912 +       }
13913 +       return(0);
13914 +}
13915 +
13916 +__uml_setup("hostfs=", hostfs_args,
13917 +"hostfs=<root dir>,<flags>,...\n"
13918 +"    This is used to set hostfs parameters.  The root directory argument\n"
13919 +"    is used to confine all hostfs mounts to within the specified directory\n"
13920 +"    tree on the host.  If this isn't specified, then a user inside UML can\n"
13921 +"    mount anything on the host that's accessible to the user that's running\n"
13922 +"    it.\n"
13923 +"    The only flag currently supported is 'append', which specifies that all\n"
13924 +"    files opened by hostfs will be opened in append mode.\n\n"
13925 +);
13926 +
13927 +struct hostfs_data {
13928 +       struct externfs_data ext;
13929 +       char *mount;
13930 +};
13931 +
13932 +struct hostfs_file {
13933 +       struct externfs_inode ext;
13934 +       struct file_handle fh;
13935 +};
13936 +
13937 +static int hostfs_access_file(char *file, int r, int w, int x, int uid, 
13938 +                             int gid, struct externfs_data *ed)
13939 +{
13940 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
13941 +       const char *path[] = { jail_dir, mount, file, NULL };
13942 +       char tmp[HOSTFS_BUFSIZE];
13943 +       int err, mode = 0;
13944 +
13945 +       if(r) mode = OS_ACC_R_OK;
13946 +       if(w) mode |= OS_ACC_W_OK;
13947 +       if(x) mode |= OS_ACC_X_OK;
13948 +       
13949 +       err = -ENOMEM;
13950 +       file = get_path(path, tmp, sizeof(tmp));
13951 +       if(file == NULL)
13952 +               goto out;
13953 +
13954 +       err = os_access(file, mode);
13955 +       free_path(file, tmp);
13956 + out:
13957 +       return(err);
13958 +}
13959 +
13960 +static int hostfs_make_node(const char *file, int mode, int uid, int gid, 
13961 +                           int type, int major, int minor, 
13962 +                           struct externfs_data *ed)
13963 +{
13964 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
13965 +       const char *path[] = { jail_dir, mount, file, NULL };
13966 +       char tmp[HOSTFS_BUFSIZE];
13967 +       int err = -ENOMEM;
13968 +
13969 +       file = get_path(path, tmp, sizeof(tmp));
13970 +       if(file == NULL)
13971 +               goto out;
13972 +
13973 +       /* XXX Pass type in an OS-independent way */
13974 +       mode |= type;
13975 +
13976 +       err = os_make_dev(file, mode, major, minor);
13977 +       free_path(file, tmp);
13978 + out:
13979 +       return(err);
13980 +}
13981 +
13982 +static int hostfs_stat_file(const char *file, struct externfs_data *ed, 
13983 +                           dev_t *dev_out, unsigned long long *inode_out, 
13984 +                           int *mode_out, int *nlink_out, int *uid_out, 
13985 +                           int *gid_out, unsigned long long *size_out, 
13986 +                           unsigned long *atime_out, unsigned long *mtime_out,
13987 +                           unsigned long *ctime_out, int *blksize_out, 
13988 +                           unsigned long long *blocks_out)
13989 +{
13990 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
13991 +       const char *path[] = { jail_dir, mount, file, NULL };
13992 +
13993 +       /* XXX Why pretend everything is owned by root? */
13994 +       *uid_out = 0;
13995 +       *gid_out = 0;
13996 +       return(host_stat_file(path, dev_out, inode_out, mode_out, nlink_out, 
13997 +                             NULL, NULL, size_out, atime_out, mtime_out, 
13998 +                             ctime_out, blksize_out, blocks_out));
13999 +}
14000 +
14001 +static int hostfs_file_type(const char *file, int *rdev, 
14002 +                            struct externfs_data *ed)
14003 +{
14004 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14005 +       const char *path[] = { jail_dir, mount, file, NULL };
14006 +
14007 +       return(host_file_type(path, rdev));
14008 +}
14009 +
14010 +static char *hostfs_name(struct inode *inode)
14011 +{
14012 +       struct externfs_data *ed = inode_externfs_info(inode);
14013 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14014 +
14015 +       return(inode_name_prefix(inode, mount));        
14016 +}
14017 +
14018 +static struct externfs_inode *hostfs_init_file(struct externfs_data *ed)
14019 +{
14020 +       struct hostfs_file *hf;
14021 +
14022 +       hf = kmalloc(sizeof(*hf), GFP_KERNEL);
14023 +       if(hf == NULL)
14024 +               return(NULL);
14025 +
14026 +       hf->fh.fd = -1;
14027 +       return(&hf->ext);
14028 +}
14029 +
14030 +static int hostfs_open_file(struct externfs_inode *ext, char *file, 
14031 +                           int uid, int gid, struct inode *inode, 
14032 +                           struct externfs_data *ed)
14033 +{
14034 +       struct hostfs_file *hf = container_of(ext, struct hostfs_file, ext);
14035 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14036 +       const char *path[] = { jail_dir, mount, file, NULL };
14037 +       int err;
14038 +
14039 +       err = host_open_file(path, 1, 1, &hf->fh);
14040 +       if(err == -EISDIR)
14041 +               goto out;
14042 +
14043 +       if(err == -EACCES)
14044 +               err = host_open_file(path, 1, 0, &hf->fh);
14045 +
14046 +       if(err)
14047 +               goto out;
14048 +
14049 +       is_reclaimable(&hf->fh, hostfs_name, inode);
14050 + out:
14051 +       return(err);
14052 +}
14053 +
14054 +static void *hostfs_open_dir(char *file, int uid, int gid, 
14055 +                            struct externfs_data *ed)
14056 +{
14057 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14058 +       const char *path[] = { jail_dir, mount, file, NULL };
14059 +
14060 +       return(host_open_dir(path));
14061 +}
14062 +
14063 +static void hostfs_close_dir(void *stream, struct externfs_data *ed)
14064 +{
14065 +       os_close_dir(stream);
14066 +}
14067 +
14068 +static char *hostfs_read_dir(void *stream, unsigned long long *pos, 
14069 +                            unsigned long long *ino_out, int *len_out, 
14070 +                            struct externfs_data *ed)
14071 +{
14072 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14073 +
14074 +       return(generic_host_read_dir(stream, pos, ino_out, len_out, mount));
14075 +}
14076 +
14077 +static int hostfs_read_file(struct externfs_inode *ext, 
14078 +                           unsigned long long offset, char *buf, int len, 
14079 +                           int ignore_start, int ignore_end,
14080 +                           void (*completion)(char *, int, void *), void *arg,
14081 +                           struct externfs_data *ed)
14082 +{
14083 +       struct hostfs_file *hf = container_of(ext, struct hostfs_file, ext);
14084 +       int err = 0;
14085 +
14086 +       if(ignore_start != 0){
14087 +               err = read_file(&hf->fh, offset, buf, ignore_start);
14088 +               if(err < 0)
14089 +                       goto out;
14090 +       }
14091 +
14092 +       if(ignore_end != len)
14093 +               err = read_file(&hf->fh, offset + ignore_end, buf + ignore_end,
14094 +                               len - ignore_end);
14095 +
14096 + out:
14097 +
14098 +       (*completion)(buf, err, arg);
14099 +       if (err > 0)
14100 +               err = 0;
14101 +       return(err);
14102 +}
14103 +
14104 +static int hostfs_write_file(struct externfs_inode *ext,
14105 +                            unsigned long long offset, const char *buf, 
14106 +                            int start, int len, 
14107 +                            void (*completion)(char *, int, void *), 
14108 +                            void *arg, struct externfs_data *ed)
14109 +{
14110 +       struct file_handle *fh;
14111 +       int err;
14112 +
14113 +       fh = &container_of(ext, struct hostfs_file, ext)->fh;
14114 +       err = write_file(fh, offset + start, buf + start, len);
14115 +
14116 +       (*completion)((char *) buf, err, arg);
14117 +       if (err > 0)
14118 +               err = 0;
14119 +
14120 +       return(err);
14121 +}
14122 +
14123 +static int hostfs_create_file(struct externfs_inode *ext, char *file, int mode,
14124 +                             int uid, int gid, struct inode *inode, 
14125 +                             struct externfs_data *ed)
14126 +{
14127 +       struct hostfs_file *hf = container_of(ext, struct hostfs_file, 
14128 +                                             ext);
14129 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14130 +       const char *path[] = { jail_dir, mount, file, NULL };
14131 +       int err = -ENOMEM;
14132 +
14133 +       err = host_create_file(path, mode, &hf->fh);
14134 +       if(err)
14135 +               goto out;
14136 +
14137 +       is_reclaimable(&hf->fh, hostfs_name, inode);
14138 + out:
14139 +       return(err);
14140 +}
14141 +
14142 +static int hostfs_set_attr(const char *file, struct externfs_iattr *attrs, 
14143 +                          struct externfs_data *ed)
14144 +{
14145 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14146 +       const char *path[] = { jail_dir, mount, file, NULL };
14147 +
14148 +       return(host_set_attr(path, attrs));
14149 +}
14150 +
14151 +static int hostfs_make_symlink(const char *from, const char *to, int uid, 
14152 +                              int gid, struct externfs_data *ed)
14153 +{
14154 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14155 +       const char *path[] = { jail_dir, mount, from, NULL };
14156 +
14157 +       return(host_make_symlink(path, to));
14158 +}
14159 +
14160 +static int hostfs_link_file(const char *to, const char *from, int uid, int gid,
14161 +                           struct externfs_data *ed)
14162 +{
14163 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14164 +       const char *to_path[] = { jail_dir, mount, to, NULL };
14165 +       const char *from_path[] = { jail_dir, mount, from, NULL };
14166 +
14167 +       return(host_link_file(to_path, from_path));
14168 +}
14169 +
14170 +static int hostfs_unlink_file(const char *file, struct externfs_data *ed)
14171 +{
14172 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14173 +       const char *path[] = { jail_dir, mount, file, NULL };
14174 +
14175 +       return(host_unlink_file(path));
14176 +}
14177 +
14178 +static int hostfs_make_dir(const char *file, int mode, int uid, int gid, 
14179 +                           struct externfs_data *ed)
14180 +{
14181 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14182 +       const char *path[] = { jail_dir, mount, file, NULL };
14183 +
14184 +       return(host_make_dir(path, mode));
14185 +}
14186 +
14187 +static int hostfs_remove_dir(const char *file, int uid, int gid, 
14188 +                            struct externfs_data *ed)
14189 +{
14190 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14191 +       const char *path[] = { jail_dir, mount, file, NULL };
14192 +
14193 +       return(host_remove_dir(path));
14194 +}
14195 +
14196 +static int hostfs_read_link(char *file, int uid, int gid, char *buf, int size, 
14197 +                           struct externfs_data *ed)
14198 +{
14199 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14200 +       const char *path[] = { jail_dir, mount, file, NULL };
14201 +
14202 +       return(host_read_link(path, buf, size));
14203 +}
14204 +
14205 +static int hostfs_rename_file(char *from, char *to, struct externfs_data *ed)
14206 +{
14207 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14208 +       const char *to_path[] = { jail_dir, mount, to, NULL };
14209 +       const char *from_path[] = { jail_dir, mount, from, NULL };
14210 +
14211 +       return(host_rename_file(from_path, to_path));
14212 +}
14213 +
14214 +static int hostfs_stat_fs(long *bsize_out, long long *blocks_out, 
14215 +                         long long *bfree_out, long long *bavail_out, 
14216 +                         long long *files_out, long long *ffree_out,
14217 +                         void *fsid_out, int fsid_size, long *namelen_out, 
14218 +                         long *spare_out, struct externfs_data *ed)
14219 +{
14220 +       char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14221 +       const char *path[] = { jail_dir, mount, NULL };
14222 +
14223 +       return(host_stat_fs(path, bsize_out, blocks_out, bfree_out, bavail_out,
14224 +                           files_out, ffree_out, fsid_out, fsid_size, 
14225 +                           namelen_out, spare_out));
14226 +}
14227 +
14228 +static void hostfs_close_file(struct externfs_inode *ext,
14229 +                             unsigned long long size)
14230 +{
14231 +       struct hostfs_file *hf = container_of(ext, struct hostfs_file, ext);
14232 +
14233 +       if(hf->fh.fd == -1)
14234 +               return;
14235 +
14236 +       truncate_file(&hf->fh, size);
14237 +       close_file(&hf->fh);
14238 +}
14239 +
14240 +static int hostfs_truncate_file(struct externfs_inode *ext, __u64 size, 
14241 +                               struct externfs_data *ed)
14242 +{
14243 +       struct hostfs_file *hf = container_of(ext, struct hostfs_file, ext);
14244 +
14245 +       return(truncate_file(&hf->fh, size));
14246 +}
14247 +
14248 +static struct externfs_file_ops hostfs_file_ops = {
14249 +       .stat_file              = hostfs_stat_file,
14250 +       .file_type              = hostfs_file_type,
14251 +       .access_file            = hostfs_access_file,
14252 +       .open_file              = hostfs_open_file,
14253 +       .open_dir               = hostfs_open_dir,
14254 +       .read_dir               = hostfs_read_dir,
14255 +       .read_file              = hostfs_read_file,
14256 +       .write_file             = hostfs_write_file,
14257 +       .map_file_page          = NULL,
14258 +       .close_file             = hostfs_close_file,
14259 +       .close_dir              = hostfs_close_dir,
14260 +       .invisible              = NULL,
14261 +       .create_file            = hostfs_create_file,
14262 +       .set_attr               = hostfs_set_attr,
14263 +       .make_symlink           = hostfs_make_symlink,
14264 +       .unlink_file            = hostfs_unlink_file,
14265 +       .make_dir               = hostfs_make_dir,
14266 +       .remove_dir             = hostfs_remove_dir,
14267 +       .make_node              = hostfs_make_node,
14268 +       .link_file              = hostfs_link_file,
14269 +       .read_link              = hostfs_read_link,
14270 +       .rename_file            = hostfs_rename_file,
14271 +       .statfs                 = hostfs_stat_fs,
14272 +       .truncate_file          = hostfs_truncate_file
14273 +};
14274 +
14275 +static struct externfs_data *mount_fs(char *mount_arg)
14276 +{
14277 +       struct hostfs_data *hd;
14278 +       int err = -ENOMEM;
14279 +
14280 +       hd = kmalloc(sizeof(*hd), GFP_KERNEL);
14281 +       if(hd == NULL)
14282 +               goto out;
14283 +
14284 +       hd->mount = host_root_filename(mount_arg);
14285 +       if(hd->mount == NULL)
14286 +               goto out_free;
14287 +
14288 +       init_externfs(&hd->ext, &hostfs_file_ops);
14289 +
14290 +       return(&hd->ext);
14291 + out_free:
14292 +       kfree(hd);
14293 + out:
14294 +       return(ERR_PTR(err));
14295 +}
14296 +
14297 +static struct externfs_mount_ops hostfs_mount_ops = {
14298 +       .init_file              = hostfs_init_file,
14299 +       .mount                  = mount_fs,
14300 +};
14301 +
14302 +static int __init init_hostfs(void)
14303 +{
14304 +       return(register_externfs("hostfs", &hostfs_mount_ops));
14305 +}
14306 +
14307 +static void __exit exit_hostfs(void)
14308 +{
14309 +       unregister_externfs("hostfs");
14310 +}
14311 +
14312 +__initcall(init_hostfs);
14313 +__exitcall(exit_hostfs);
14314 +
14315 +#if 0
14316 +module_init(init_hostfs)
14317 +module_exit(exit_hostfs)
14318 +MODULE_LICENSE("GPL");
14319 +#endif
14320 +
14321 +/*
14322 + * Overrides for Emacs so that we follow Linus's tabbing style.
14323 + * Emacs will notice this stuff at the end of the file and automatically
14324 + * adjust the settings for this buffer only.  This must remain at the end
14325 + * of the file.
14326 + * ---------------------------------------------------------------------------
14327 + * Local variables:
14328 + * c-file-style: "linux"
14329 + * End:
14330 + */
14331 Index: linux-2.4.29/arch/um/fs/hostfs/hostfs.h
14332 ===================================================================
14333 --- linux-2.4.29.orig/arch/um/fs/hostfs/hostfs.h        1970-01-01 03:00:00.000000000 +0300
14334 +++ linux-2.4.29/arch/um/fs/hostfs/hostfs.h     2005-05-03 23:46:13.801043992 +0300
14335 @@ -0,0 +1,200 @@
14336 +/* 
14337 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
14338 + * Licensed under the GPL
14339 + */
14340 +
14341 +#ifndef __UM_FS_HOSTFS
14342 +#define __UM_FS_HOSTFS
14343 +
14344 +#include "linux/fs.h"
14345 +#include "linux/blkdev.h"
14346 +#include "filehandle.h"
14347 +#include "os.h"
14348 +
14349 +/* These are exactly the same definitions as in fs.h, but the names are 
14350 + * changed so that this file can be included in both kernel and user files.
14351 + */
14352 +
14353 +#define EXTERNFS_ATTR_MODE     1
14354 +#define EXTERNFS_ATTR_UID      2
14355 +#define EXTERNFS_ATTR_GID      4
14356 +#define EXTERNFS_ATTR_SIZE     8
14357 +#define EXTERNFS_ATTR_ATIME    16
14358 +#define EXTERNFS_ATTR_MTIME    32
14359 +#define EXTERNFS_ATTR_CTIME    64
14360 +#define EXTERNFS_ATTR_ATIME_SET        128
14361 +#define EXTERNFS_ATTR_MTIME_SET        256
14362 +#define EXTERNFS_ATTR_FORCE    512     /* Not a change, but a change it */
14363 +#define EXTERNFS_ATTR_ATTR_FLAG        1024
14364 +
14365 +/**
14366 + * container_of - cast a member of a structure out to the containing structure
14367 + *
14368 + * @ptr:        the pointer to the member.
14369 + * @type:       the type of the container struct this is embedded in.
14370 + * @member:     the name of the member within the struct.
14371 + *
14372 + */
14373 +#define container_of(ptr, type, member) ({                      \
14374 +        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
14375 +        (type *)( (char *)__mptr - offsetof(type,member) );})
14376 +
14377 +struct externfs_iattr {
14378 +       unsigned int    ia_valid;
14379 +       mode_t          ia_mode;
14380 +       uid_t           ia_uid;
14381 +       gid_t           ia_gid;
14382 +       loff_t          ia_size;
14383 +       time_t          ia_atime;
14384 +       time_t          ia_mtime;
14385 +       time_t          ia_ctime;
14386 +       unsigned int    ia_attr_flags;
14387 +};
14388 +
14389 +struct externfs_data {
14390 +       struct externfs_file_ops *file_ops;
14391 +       struct externfs_mount_ops *mount_ops;
14392 +};
14393 +
14394 +struct externfs_inode {
14395 +       struct externfs_file_ops *ops;
14396 +};
14397 +
14398 +struct externfs_mount_ops {
14399 +       struct externfs_data *(*mount)(char *mount_arg);
14400 +       struct externfs_inode *(*init_file)(struct externfs_data *ed);
14401 +};
14402 +
14403 +struct externfs_file_ops {
14404 +       int (*stat_file)(const char *path, struct externfs_data *ed, 
14405 +                        dev_t *dev_out, unsigned long long *inode_out, 
14406 +                        int *mode_out, int *nlink_out, int *uid_out, 
14407 +                        int *gid_out, unsigned long long *size_out, 
14408 +                        unsigned long *atime_out, unsigned long *mtime_out,
14409 +                        unsigned long *ctime_out, int *blksize_out, 
14410 +                        unsigned long long *blocks_out);
14411 +       int (*file_type)(const char *path, int *rdev, 
14412 +                        struct externfs_data *ed);
14413 +       int (*access_file)(char *path, int r, int w, int x, int uid, int gid, 
14414 +                          struct externfs_data *ed);
14415 +       int (*open_file)(struct externfs_inode *ext, char *file, 
14416 +                        int uid, int gid, struct inode *inode, 
14417 +                        struct externfs_data *ed);
14418 +       void (*close_file)(struct externfs_inode *ext, 
14419 +                          unsigned long long size);
14420 +       void *(*open_dir)(char *path, int uid, int gid, 
14421 +                         struct externfs_data *ed);
14422 +       char *(*read_dir)(void *stream, unsigned long long *pos, 
14423 +                         unsigned long long *ino_out, int *len_out, 
14424 +                         struct externfs_data *ed);
14425 +       int (*read_file)(struct externfs_inode *ext, 
14426 +                        unsigned long long offset, char *buf, int len, 
14427 +                        int ignore_start, int ignore_end,
14428 +                        void (*completion)(char *, int, void *), void *arg, 
14429 +                        struct externfs_data *ed);
14430 +       int (*write_file)(struct externfs_inode *ext, 
14431 +                         unsigned long long offset, const char *buf, 
14432 +                         int start, int len, 
14433 +                         void (*completion)(char *, int, void *), void *arg, 
14434 +                         struct externfs_data *ed);
14435 +       int (*map_file_page)(struct externfs_inode *ext, 
14436 +                            unsigned long long offset, char *buf, int w, 
14437 +                            struct externfs_data *ed);
14438 +       void (*close_dir)(void *stream, struct externfs_data *ed);
14439 +       void (*invisible)(struct externfs_inode *ext);
14440 +       int (*create_file)(struct externfs_inode *ext, char *path, 
14441 +                          int mode, int uid, int gid, struct inode *inode, 
14442 +                          struct externfs_data *ed);
14443 +       int (*set_attr)(const char *path, struct externfs_iattr *attrs, 
14444 +                       struct externfs_data *ed);
14445 +       int (*make_symlink)(const char *from, const char *to, int uid, int gid,
14446 +                           struct externfs_data *ed);
14447 +       int (*unlink_file)(const char *path, struct externfs_data *ed);
14448 +       int (*make_dir)(const char *path, int mode, int uid, int gid, 
14449 +                       struct externfs_data *ed);
14450 +       int (*remove_dir)(const char *path, int uid, int gid, 
14451 +                         struct externfs_data *ed);
14452 +       int (*make_node)(const char *path, int mode, int uid, int gid, 
14453 +                        int type, int maj, int min, struct externfs_data *ed);
14454 +       int (*link_file)(const char *to, const char *from, int uid, int gid, 
14455 +                        struct externfs_data *ed);
14456 +       int (*read_link)(char *path, int uid, int gid, char *buf, int size, 
14457 +                        struct externfs_data *ed);
14458 +       int (*rename_file)(char *from, char *to, struct externfs_data *ed);
14459 +       int (*statfs)(long *bsize_out, long long *blocks_out, 
14460 +                     long long *bfree_out, long long *bavail_out, 
14461 +                     long long *files_out, long long *ffree_out,
14462 +                     void *fsid_out, int fsid_size, long *namelen_out, 
14463 +                     long *spare_out, struct externfs_data *ed);
14464 +       int (*truncate_file)(struct externfs_inode *ext, __u64 size, 
14465 +                            struct externfs_data *ed);
14466 +};
14467 +
14468 +#define HOSTFS_BUFSIZE 64
14469 +
14470 +extern int register_externfs(char *name, struct externfs_mount_ops *mount_ops);
14471 +extern void unregister_externfs(char *name);
14472 +extern void init_externfs(struct externfs_data *ed, 
14473 +                         struct externfs_file_ops *ops);
14474 +struct externfs_data *inode_externfs_info(struct inode *inode);
14475 +
14476 +extern char *generic_root_filename(char *mount_arg);
14477 +extern void host_close_file(void *stream);
14478 +extern int host_read_file(int fd, unsigned long long offset, char *buf, 
14479 +                         int len);
14480 +extern int host_open_file(const char *path[], int r, int w,
14481 +                         struct file_handle *fh);
14482 +extern void *host_open_dir(const char *path[]);
14483 +extern char *host_read_dir(void *stream, unsigned long long *pos, 
14484 +                          unsigned long long *ino_out, int *len_out);
14485 +extern int host_file_type(const char *path[], int *rdev);
14486 +extern char *host_root_filename(char *mount_arg);
14487 +extern char *get_path(const char *path[], char *buf, int size);
14488 +extern void free_path(const char *buf, char *tmp);
14489 +extern int host_create_file(const char *path[], int mode, 
14490 +                           struct file_handle *fh);
14491 +extern int host_set_attr(const char *path[], struct externfs_iattr *attrs);
14492 +extern int host_make_symlink(const char *from[], const char *to);
14493 +extern int host_unlink_file(const char *path[]);
14494 +extern int host_make_dir(const char *path[], int mode);
14495 +extern int host_remove_dir(const char *path[]);
14496 +extern int host_link_file(const char *to[], const char *from[]);
14497 +extern int host_read_link(const char *path[], char *buf, int size);
14498 +extern int host_rename_file(const char *from[], const char *to[]);
14499 +extern int host_stat_fs(const char *path[], long *bsize_out, 
14500 +                       long long *blocks_out, long long *bfree_out, 
14501 +                       long long *bavail_out, long long *files_out, 
14502 +                       long long *ffree_out, void *fsid_out, int fsid_size, 
14503 +                       long *namelen_out, long *spare_out);
14504 +extern int host_stat_file(const char *path[], dev_t *dev_out, 
14505 +                         unsigned long long *inode_out, int *mode_out, 
14506 +                         int *nlink_out, int *uid_out, int *gid_out, 
14507 +                         unsigned long long *size_out, 
14508 +                         unsigned long *atime_out, unsigned long *mtime_out,
14509 +                         unsigned long *ctime_out, int *blksize_out,
14510 +                         unsigned long long *blocks_out);
14511 +
14512 +extern char *generic_host_read_dir(void *stream, unsigned long long *pos, 
14513 +                             unsigned long long *ino_out, int *len_out, 
14514 +                             void *mount);
14515 +extern int generic_host_read_file(int fd, unsigned long long offset, char *buf,
14516 +                            int len, void *mount);
14517 +extern void generic_host_close_file(void *stream, unsigned long long size,
14518 +                                   void *mount);
14519 +extern int generic_host_truncate_file(struct file_handle *fh, __u64 size, 
14520 +                                     void *m);
14521 +
14522 +extern char *inode_name_prefix(struct inode *inode, char *prefix);
14523 +
14524 +#endif
14525 +
14526 +/*
14527 + * Overrides for Emacs so that we follow Linus's tabbing style.
14528 + * Emacs will notice this stuff at the end of the file and automatically
14529 + * adjust the settings for this buffer only.  This must remain at the end
14530 + * of the file.
14531 + * ---------------------------------------------------------------------------
14532 + * Local variables:
14533 + * c-file-style: "linux"
14534 + * End:
14535 + */
14536 Index: linux-2.4.29/arch/um/fs/hostfs/humfs.c
14537 ===================================================================
14538 --- linux-2.4.29.orig/arch/um/fs/hostfs/humfs.c 1970-01-01 03:00:00.000000000 +0300
14539 +++ linux-2.4.29/arch/um/fs/hostfs/humfs.c      2005-05-03 22:28:14.000000000 +0300
14540 @@ -0,0 +1,1024 @@
14541 +/* 
14542 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
14543 + * Licensed under the GPL
14544 + */
14545 +
14546 +#include <linux/kernel.h>
14547 +#include <linux/list.h>
14548 +#include <linux/sched.h>
14549 +#include <linux/slab.h>
14550 +#include <linux/stat.h>
14551 +#include <linux/tqueue.h>
14552 +#include <linux/types.h>
14553 +#include <linux/errno.h>
14554 +#include <linux/string.h>
14555 +#include <linux/kdev_t.h>
14556 +#include <asm/irq.h>
14557 +#include "hostfs.h"
14558 +#include "mem.h"
14559 +#include "os.h"
14560 +#include "mode.h"
14561 +#include "aio.h"
14562 +#include "irq_user.h"
14563 +#include "irq_kern.h"
14564 +#include "filehandle.h"
14565 +#include "metadata.h"
14566 +
14567 +#define HUMFS_VERSION 2
14568 +
14569 +static int humfs_stat_file(const char *path, struct externfs_data *ed, 
14570 +                          dev_t *dev_out, unsigned long long *inode_out, 
14571 +                          int *mode_out, int *nlink_out, int *uid_out, 
14572 +                          int *gid_out, unsigned long long *size_out, 
14573 +                          unsigned long *atime_out, unsigned long *mtime_out, 
14574 +                          unsigned long *ctime_out, int *blksize_out, 
14575 +                          unsigned long long *blocks_out)
14576 +{
14577 +       struct humfs *mount = container_of(ed, struct humfs, ext);
14578 +       const char *data_path[3] = { mount->data, path, NULL };
14579 +       int err, mode, perms, major, minor;
14580 +       char type;
14581 +
14582 +       err = host_stat_file(data_path, dev_out, inode_out, mode_out, 
14583 +                            nlink_out, NULL, NULL, size_out, atime_out, 
14584 +                            mtime_out, ctime_out, blksize_out, blocks_out);
14585 +       if(err)
14586 +               return(err);
14587 +
14588 +       err = (*mount->meta->ownerships)(path, &perms, uid_out, gid_out, 
14589 +                                        &type, &major, &minor, mount);
14590 +       if(err)
14591 +               return(err);
14592 +
14593 +       *mode_out = (*mode_out & ~S_IRWXUGO) | perms;
14594 +
14595 +       mode = 0;
14596 +       switch(type){
14597 +       case 'c':
14598 +               mode = S_IFCHR;
14599 +               break;
14600 +       case 'b':
14601 +               mode = S_IFBLK;
14602 +               break;
14603 +       case 's':
14604 +               mode = S_IFSOCK;
14605 +               break;
14606 +       default:
14607 +               break;
14608 +       }
14609 +
14610 +       if(mode != 0)
14611 +               *mode_out = (*mode_out & ~S_IFMT) | mode;
14612 +
14613 +       return(0);
14614 +}
14615 +
14616 +static int meta_type(const char *path, int *dev_out, void *m)
14617 +{
14618 +       struct humfs *mount = m;
14619 +       int err, type, maj, min;
14620 +       char c;
14621 +
14622 +       err = (*mount->meta->ownerships)(path, NULL, NULL, NULL, &c, &maj, 
14623 +                                        &min, mount);
14624 +       if(err)
14625 +               return(err);
14626 +
14627 +       if(c == 0)
14628 +               return(0);
14629 +
14630 +       if(dev_out)
14631 +               *dev_out = MKDEV(maj, min);
14632 +
14633 +       switch(c){
14634 +       case 'c':
14635 +               type = OS_TYPE_CHARDEV;
14636 +               break;
14637 +       case 'b':
14638 +               type = OS_TYPE_BLOCKDEV;
14639 +               break;
14640 +       case 'p':
14641 +               type = OS_TYPE_FIFO;
14642 +               break;
14643 +       case 's':
14644 +               type = OS_TYPE_SOCK;
14645 +               break;
14646 +       default:
14647 +               type = -EINVAL;
14648 +               break;
14649 +       }
14650 +
14651 +       return(type);
14652 +}
14653 +
14654 +static int humfs_file_type(const char *path, int *dev_out, 
14655 +                          struct externfs_data *ed)
14656 +{
14657 +       struct humfs *mount = container_of(ed, struct humfs, ext);
14658 +       const char *data_path[3] = { mount->data, path, NULL };
14659 +       int type;
14660 +
14661 +       type = meta_type(path, dev_out, mount);
14662 +       if(type != 0)
14663 +               return(type);
14664 +
14665 +       return(host_file_type(data_path, dev_out));
14666 +}
14667 +
14668 +static char *humfs_data_name(struct inode *inode)
14669 +{
14670 +       struct externfs_data *ed = inode_externfs_info(inode);
14671 +       struct humfs *mount = container_of(ed, struct humfs, ext);
14672 +
14673 +       return(inode_name_prefix(inode, mount->data));
14674 +}
14675 +
14676 +static struct externfs_inode *humfs_init_file(struct externfs_data *ed)
14677 +{
14678 +       struct humfs *mount = container_of(ed, struct humfs, ext);
14679 +       struct humfs_file *hf;
14680 +
14681 +       hf = (*mount->meta->init_file)();
14682 +       if(IS_ERR(hf))
14683 +               return((struct externfs_inode *) hf);
14684 +
14685 +       hf->data.fd = -1;
14686 +       return(&hf->ext);
14687 +}
14688 +
14689 +static int humfs_open_file(struct externfs_inode *ext, char *path, int uid, 
14690 +                          int gid, struct inode *inode, 
14691 +                          struct externfs_data *ed)
14692 +{
14693 +       struct humfs *mount = container_of(ed, struct humfs, ext);
14694 +       struct humfs_file *hf = container_of(ext, struct humfs_file, ext);
14695 +       const char *data_path[3] = { mount->data, path, NULL };
14696 +       struct openflags flags;
14697 +       char tmp[HOSTFS_BUFSIZE], *file;
14698 +       int err = -ENOMEM;
14699 +
14700 +       file = get_path(data_path, tmp, sizeof(tmp));
14701 +       if(file == NULL)
14702 +               goto out;
14703 +
14704 +       flags = of_rdwr(OPENFLAGS());
14705 +       if(mount->direct)
14706 +               flags = of_direct(flags);
14707 +
14708 +       if(path == NULL)
14709 +               path = "";
14710 +       err = (*mount->meta->open_file)(hf, path, inode, mount);
14711 +       if(err)
14712 +               goto out_free;
14713 +
14714 +       err = open_filehandle(file, flags, 0, &hf->data);
14715 +       if(err == -EISDIR)
14716 +               goto out;
14717 +       else if(err == -EPERM){
14718 +               flags = of_set_rw(flags, 1, 0);
14719 +               err = open_filehandle(file, flags, 0, &hf->data);
14720 +       }
14721 +       
14722 +       if(err)
14723 +               goto out_close;
14724 +
14725 +       hf->mount = mount;
14726 +       is_reclaimable(&hf->data, humfs_data_name, inode);
14727 +
14728 + out_free:
14729 +       free_path(file, tmp);
14730 + out:  
14731 +       return(err);
14732 +
14733 + out_close:
14734 +       (*mount->meta->close_file)(hf);
14735 +       goto out_free;
14736 +}
14737 +
14738 +static void *humfs_open_dir(char *path, int uid, int gid, 
14739 +                           struct externfs_data *ed)
14740 +{
14741 +       struct humfs *mount = container_of(ed, struct humfs, ext);
14742 +       const char *data_path[3] = { mount->data, path, NULL };
14743 +
14744 +       return(host_open_dir(data_path));
14745 +}
14746 +
14747 +static void humfs_close_dir(void *stream, struct externfs_data *ed)
14748 +{
14749 +       os_close_dir(stream);
14750 +}
14751 +
14752 +static char *humfs_read_dir(void *stream, unsigned long long *pos, 
14753 +                           unsigned long long *ino_out, int *len_out, 
14754 +                           struct externfs_data *ed)
14755 +{
14756 +       struct humfs *mount = container_of(ed, struct humfs, ext);
14757 +
14758 +       return(generic_host_read_dir(stream, pos, ino_out, len_out, mount));
14759 +}
14760 +
14761 +LIST_HEAD(humfs_replies);
14762 +
14763 +struct humfs_aio {
14764 +       struct aio_context aio;
14765 +       struct list_head list;
14766 +       void (*completion)(char *, int, void *);
14767 +       char *buf;
14768 +       int real_len;
14769 +       int err;
14770 +       void *data;
14771 +};
14772 +
14773 +static int humfs_reply_fd = -1;
14774 +
14775 +struct humfs_aio last_task_aio, last_intr_aio;
14776 +struct humfs_aio *last_task_aio_ptr, *last_intr_aio_ptr;
14777 +
14778 +void humfs_task_proc(void *unused)
14779 +{
14780 +       struct humfs_aio *aio;
14781 +       unsigned long flags;
14782 +
14783 +       while(!list_empty(&humfs_replies)){
14784 +               local_irq_save(flags);
14785 +               aio = list_entry(humfs_replies.next, struct humfs_aio, list);
14786 +
14787 +               last_task_aio = *aio;
14788 +               last_task_aio_ptr = aio;
14789 +
14790 +               list_del(&aio->list);
14791 +               local_irq_restore(flags);
14792 +
14793 +               if(aio->err >= 0)
14794 +                       aio->err = aio->real_len;
14795 +               (*aio->completion)(aio->buf, aio->err, aio->data);
14796 +               kfree(aio);
14797 +       }
14798 +}
14799 +
14800 +struct tq_struct humfs_task = {
14801 +       .routine        = humfs_task_proc,
14802 +       .data           = NULL
14803 +};
14804 +
14805 +static void humfs_interrupt(int irq, void *dev_id, struct pt_regs *unused)
14806 +{
14807 +       struct aio_thread_reply reply;
14808 +       struct humfs_aio *aio;
14809 +       int err, fd = (int) dev_id;
14810 +
14811 +       while(1){
14812 +               err = os_read_file(fd, &reply, sizeof(reply));
14813 +               if(err < 0){
14814 +                       if(err == -EAGAIN)
14815 +                               break;
14816 +                       printk("humfs_interrupt - read returned err %d\n", 
14817 +                              -err);
14818 +                       return;
14819 +               }
14820 +               aio = reply.data;
14821 +               aio->err = reply.err;
14822 +               list_add(&aio->list, &humfs_replies);
14823 +               last_intr_aio = *aio;
14824 +               last_intr_aio_ptr = aio;
14825 +       }
14826 +
14827 +       if(!list_empty(&humfs_replies))
14828 +               schedule_task(&humfs_task);
14829 +       reactivate_fd(fd, HUMFS_IRQ);
14830 +}
14831 +
14832 +static int init_humfs_aio(void)
14833 +{
14834 +       int fds[2], err;
14835 +
14836 +       err = os_pipe(fds, 1, 1);
14837 +       if(err){
14838 +               printk("init_humfs_aio - pipe failed, err = %d\n", -err);
14839 +               goto out;
14840 +       }
14841 +
14842 +       err = um_request_irq(HUMFS_IRQ, fds[0], IRQ_READ, humfs_interrupt,
14843 +                            SA_INTERRUPT | SA_SAMPLE_RANDOM, "humfs", 
14844 +                            (void *) fds[0]);
14845 +       if(err){
14846 +               printk("init_humfs_aio - : um_request_irq failed, err = %d\n",
14847 +                      err);
14848 +               goto out_close;
14849 +       }
14850 +
14851 +       humfs_reply_fd = fds[1];
14852 +       goto out;
14853 +       
14854 + out_close:
14855 +       os_close_file(fds[0]);
14856 +       os_close_file(fds[1]);
14857 + out:
14858 +       return(0);
14859 +}
14860 +
14861 +__initcall(init_humfs_aio);
14862 +
14863 +static int humfs_aio(enum aio_type type, int fd, unsigned long long offset,
14864 +                    char *buf, int len, int real_len,
14865 +                    void (*completion)(char *, int, void *), void *arg)
14866 +{
14867 +       struct humfs_aio *aio;
14868 +       int err = -ENOMEM;
14869 +
14870 +       aio = kmalloc(sizeof(*aio), GFP_KERNEL);
14871 +       if(aio == NULL)
14872 +               goto out;
14873 +       *aio = ((struct humfs_aio) { .aio       = INIT_AIO_CONTEXT,
14874 +                                    .list      = LIST_HEAD_INIT(aio->list),
14875 +                                    .completion= completion,
14876 +                                    .buf       = buf,
14877 +                                    .err       = 0,
14878 +                                    .real_len  = real_len,
14879 +                                    .data      = arg });
14880 +
14881 +       err = submit_aio(type, fd, buf, len, offset, humfs_reply_fd, aio);
14882 +       if(err)
14883 +               (*completion)(buf, err, arg);
14884 +
14885 + out:
14886 +       return(err);
14887 +}
14888 +
14889 +static int humfs_read_file(struct externfs_inode *ext,
14890 +                          unsigned long long offset, char *buf, int len, 
14891 +                          int ignore_start, int ignore_end,
14892 +                          void (*completion)(char *, int, void *), void *arg, 
14893 +                          struct externfs_data *ed)
14894 +{
14895 +       struct humfs_file *hf = container_of(ext, struct humfs_file, ext);
14896 +       int fd = filehandle_fd(&hf->data);
14897 +
14898 +       if(fd < 0){
14899 +               (*completion)(buf, fd, arg);
14900 +               return(fd);
14901 +       }
14902 +
14903 +       return(humfs_aio(AIO_READ, fd, offset, buf, len, len, completion, 
14904 +                        arg));
14905 +}
14906 +
14907 +static int humfs_write_file(struct externfs_inode *ext,
14908 +                           unsigned long long offset, const char *buf, 
14909 +                           int start, int len, 
14910 +                           void (*completion)(char *, int, void *), void *arg,
14911 +                           struct externfs_data *ed)
14912 +{
14913 +       struct humfs *mount = container_of(ed, struct humfs, ext);
14914 +       struct humfs_file *hf = container_of(ext, struct humfs_file, ext);
14915 +       int err, orig_len = len, fd = filehandle_fd(&hf->data);
14916 +
14917 +       if(fd < 0){
14918 +               (*completion)((char *) buf, fd, arg);
14919 +               return(fd);
14920 +       }
14921 +
14922 +       if(mount->direct)
14923 +               len = PAGE_SIZE;
14924 +       else {
14925 +               offset += start;
14926 +               buf += start;
14927 +       }
14928 +
14929 +       err = humfs_aio(AIO_WRITE, fd, offset, (char *) buf, len, orig_len, 
14930 +                       completion, arg);
14931 +
14932 +       if(err < 0)
14933 +               return(err);
14934 +
14935 +       if(mount->direct)
14936 +               err = orig_len;
14937 +
14938 +       return(err);
14939 +}
14940 +
14941 +static int humfs_map_file_page(struct externfs_inode *ext, 
14942 +                              unsigned long long offset, char *buf, int w, 
14943 +                              struct externfs_data *ed)
14944 +{
14945 +       struct humfs_file *hf = container_of(ext, struct humfs_file, ext);
14946 +       unsigned long long size, need;
14947 +       int err, fd = filehandle_fd(&hf->data);
14948 +
14949 +       if(fd < 0)
14950 +               return(fd);
14951 +
14952 +       err = os_fd_size(fd, &size);
14953 +       if(err)
14954 +               return(err);
14955 +
14956 +       need = offset + PAGE_SIZE;
14957 +       if(size < need){
14958 +               err = os_truncate_fd(fd, need);
14959 +               if(err)
14960 +                       return(err);
14961 +       }
14962 +       
14963 +       return(physmem_subst_mapping(buf, fd, offset, w));
14964 +}
14965 +
14966 +static void humfs_close_file(struct externfs_inode *ext,
14967 +                            unsigned long long size)
14968 +{
14969 +       struct humfs_file *hf = container_of(ext, struct humfs_file, ext);
14970 +       int fd;
14971 +
14972 +       if(hf->data.fd == -1)
14973 +               return;
14974 +
14975 +       fd = filehandle_fd(&hf->data);
14976 +       physmem_forget_descriptor(fd);
14977 +       truncate_file(&hf->data, size);
14978 +       close_file(&hf->data);
14979 +
14980 +       (*hf->mount->meta->close_file)(hf);
14981 +}
14982 +
14983 +/* XXX Assumes that you can't make a normal file */
14984 +
14985 +static int humfs_make_node(const char *path, int mode, int uid, int gid, 
14986 +                          int type, int major, int minor, 
14987 +                          struct externfs_data *ed)
14988 +{
14989 +       struct humfs *mount = container_of(ed, struct humfs, ext);
14990 +       struct file_handle fh;
14991 +       const char *data_path[3] = { mount->data, path, NULL };
14992 +       int err;
14993 +       char t;
14994 +
14995 +       err = host_create_file(data_path, S_IRWXUGO, &fh);
14996 +       if(err)
14997 +               goto out;
14998 +
14999 +       close_file(&fh);
15000 +
15001 +       switch(type){
15002 +       case S_IFCHR:
15003 +               t = 'c';
15004 +               break;
15005 +       case S_IFBLK:
15006 +               t = 'b';
15007 +               break;
15008 +       case S_IFIFO:
15009 +               t = 'p';
15010 +               break;
15011 +       case S_IFSOCK:
15012 +               t = 's';
15013 +               break;
15014 +       default:
15015 +               err = -EINVAL;
15016 +               printk("humfs_make_node - bad node type : %d\n", type);
15017 +               goto out_rm;
15018 +       }
15019 +
15020 +       err = (*mount->meta->make_node)(path, mode, uid, gid, t, major, minor, 
15021 +                                       mount);
15022 +       if(err)
15023 +               goto out_rm;
15024 +
15025 + out:
15026 +       return(err);
15027 +
15028 + out_rm:
15029 +       host_unlink_file(data_path);
15030 +       goto out;
15031 +}
15032 +               
15033 +static int humfs_create_file(struct externfs_inode *ext, char *path, int mode, 
15034 +                            int uid, int gid, struct inode *inode, 
15035 +                            struct externfs_data *ed)
15036 +{
15037 +       struct humfs *mount = container_of(ed, struct humfs, ext);
15038 +       struct humfs_file *hf = container_of(ext, struct humfs_file, ext);
15039 +       const char *data_path[3] = { mount->data, path, NULL };
15040 +       int err;
15041 +
15042 +       err = (*mount->meta->create_file)(hf, path, mode, uid, gid, inode, 
15043 +                                         mount);
15044 +       if(err)
15045 +               goto out;
15046 +
15047 +       err = host_create_file(data_path, S_IRWXUGO, &hf->data);
15048 +       if(err)
15049 +               goto out_rm;
15050 +
15051 +       
15052 +       is_reclaimable(&hf->data, humfs_data_name, inode);
15053 +
15054 +       return(0);
15055 +
15056 + out_rm:
15057 +       (*mount->meta->remove_file)(path, mount);
15058 +       (*mount->meta->close_file)(hf);
15059 + out:
15060 +       return(err);
15061 +}
15062 +
15063 +static int humfs_set_attr(const char *path, struct externfs_iattr *attrs, 
15064 +                         struct externfs_data *ed)
15065 +{
15066 +       struct humfs *mount = container_of(ed, struct humfs, ext);
15067 +       const char *data_path[3] = { mount->data, path, NULL };
15068 +       int (*chown)(const char *, int, int, int, struct humfs *);
15069 +       int err;
15070 +
15071 +       chown = mount->meta->change_ownerships;
15072 +       if(attrs->ia_valid & EXTERNFS_ATTR_MODE){
15073 +               err = (*chown)(path, attrs->ia_mode, -1, -1, mount);
15074 +               if(err)
15075 +                       return(err);
15076 +       }
15077 +       if(attrs->ia_valid & EXTERNFS_ATTR_UID){
15078 +               err = (*chown)(path, -1, attrs->ia_uid, -1, mount);
15079 +               if(err)
15080 +                       return(err);
15081 +       }
15082 +       if(attrs->ia_valid & EXTERNFS_ATTR_GID){
15083 +               err = (*chown)(path, -1, -1, attrs->ia_gid, mount);
15084 +               if(err)
15085 +                       return(err);
15086 +       }
15087 +
15088 +       attrs->ia_valid &= ~(EXTERNFS_ATTR_MODE | EXTERNFS_ATTR_UID | 
15089 +                            EXTERNFS_ATTR_GID);
15090 +
15091 +       return(host_set_attr(data_path, attrs));
15092 +}
15093 +
15094 +static int humfs_make_symlink(const char *from, const char *to, int uid, 
15095 +                             int gid, struct externfs_data *ed)
15096 +{
15097 +       struct humfs *mount = container_of(ed, struct humfs, ext);
15098 +       struct humfs_file *hf;
15099 +       const char *data_path[3] = { mount->data, from, NULL };
15100 +       int err = -ENOMEM;
15101 +
15102 +       hf = (*mount->meta->init_file)();
15103 +       if(hf == NULL)
15104 +               goto out;
15105 +
15106 +       err = (*mount->meta->create_file)(hf, from, S_IRWXUGO, uid, gid, NULL, 
15107 +                                         mount);
15108 +       if(err)
15109 +               goto out_close;
15110 +
15111 +       err = host_make_symlink(data_path, to);
15112 +       if(err)
15113 +               (*mount->meta->remove_file)(from, mount);
15114 +
15115 + out_close:
15116 +       (*mount->meta->close_file)(hf);
15117 + out:
15118 +       return(err);
15119 +}
15120 +
15121 +static int humfs_link_file(const char *to, const char *from, int uid, int gid, 
15122 +                          struct externfs_data *ed)
15123 +{
15124 +       struct humfs *mount = container_of(ed, struct humfs, ext);
15125 +       const char *data_path_from[3] = { mount->data, from, NULL };
15126 +       const char *data_path_to[3] = { mount->data, to, NULL };
15127 +       int err;
15128 +
15129 +       err = (*mount->meta->create_link)(to, from, mount);
15130 +       if(err)
15131 +               return(err);
15132 +
15133 +       err = host_link_file(data_path_to, data_path_from);
15134 +       if(err)
15135 +               (*mount->meta->remove_file)(from, mount);
15136 +       
15137 +       return(err);
15138 +}
15139 +
15140 +static int humfs_unlink_file(const char *path, struct externfs_data *ed)
15141 +{
15142 +       struct humfs *mount = container_of(ed, struct humfs, ext);
15143 +       const char *data_path[3] = { mount->data, path, NULL };
15144 +       int err;
15145 +
15146 +       err = (*mount->meta->remove_file)(path, mount);
15147 +       if (err)
15148 +               return err;
15149 +
15150 +       (*mount->meta->remove_file)(path, mount);
15151 +       return(host_unlink_file(data_path));
15152 +}
15153 +
15154 +static void humfs_invisible(struct externfs_inode *ext)
15155 +{
15156 +       struct humfs_file *hf = container_of(ext, struct humfs_file, ext);
15157 +       struct humfs *mount = hf->mount;
15158 +       
15159 +       (*mount->meta->invisible)(hf);
15160 +       not_reclaimable(&hf->data);
15161 +}
15162 +
15163 +static int humfs_make_dir(const char *path, int mode, int uid, int gid, 
15164 +                         struct externfs_data *ed)
15165 +{
15166 +       struct humfs *mount = container_of(ed, struct humfs, ext);
15167 +       const char *data_path[3] = { mount->data, path, NULL };
15168 +       int err;
15169 +
15170 +       err = (*mount->meta->create_dir)(path, mode, uid, gid, mount);
15171 +       if(err)
15172 +               return(err);
15173 +       
15174 +       err = host_make_dir(data_path, S_IRWXUGO);
15175 +       if(err)
15176 +               (*mount->meta->remove_dir)(path, mount);
15177 +
15178 +       return(err);
15179 +}
15180 +
15181 +static int humfs_remove_dir(const char *path, int uid, int gid, 
15182 +                           struct externfs_data *ed)
15183 +{
15184 +       struct humfs *mount = container_of(ed, struct humfs, ext);
15185 +       const char *data_path[3] = { mount->data, path, NULL };
15186 +       int err;
15187 +
15188 +       err = host_remove_dir(data_path);
15189 +       if (err)
15190 +               return err;
15191 +
15192 +       (*mount->meta->remove_dir)(path, mount);
15193 +
15194 +       return(err);
15195 +}
15196 +
15197 +static int humfs_read_link(char *file, int uid, int gid, char *buf, int size, 
15198 +                          struct externfs_data *ed)
15199 +{
15200 +       struct humfs *mount = container_of(ed, struct humfs, ext);
15201 +       const char *data_path[3] = { mount->data, file, NULL };
15202 +
15203 +       return(host_read_link(data_path, buf, size));
15204 +}
15205 +
15206 +struct humfs *inode_humfs_info(struct inode *inode)
15207 +{
15208 +       return(container_of(inode_externfs_info(inode), struct humfs, ext));
15209 +}
15210 +
15211 +static int humfs_rename_file(char *from, char *to, struct externfs_data *ed)
15212 +{
15213 +       struct humfs *mount = container_of(ed, struct humfs, ext);
15214 +       const char *data_path_from[3] = { mount->data, from, NULL };
15215 +       const char *data_path_to[3] = { mount->data, to, NULL };
15216 +       int err;
15217 +
15218 +       err = (*mount->meta->rename_file)(from, to, mount);
15219 +       if(err)
15220 +               return(err);
15221 +       
15222 +       err = host_rename_file(data_path_from, data_path_to);
15223 +       if(err)
15224 +               (*mount->meta->rename_file)(to, from, mount);
15225 +
15226 +       return(err);
15227 +}
15228 +
15229 +static int humfs_stat_fs(long *bsize_out, long long *blocks_out, 
15230 +                        long long *bfree_out, long long *bavail_out, 
15231 +                        long long *files_out, long long *ffree_out, 
15232 +                        void *fsid_out, int fsid_size, long *namelen_out, 
15233 +                        long *spare_out, struct externfs_data *ed)
15234 +{
15235 +       struct humfs *mount = container_of(ed, struct humfs, ext);
15236 +       const char *data_path[3] = { mount->data, NULL };
15237 +       int err;
15238 +
15239 +       /* XXX Needs to maintain this info as metadata */
15240 +       err = host_stat_fs(data_path, bsize_out, blocks_out, bfree_out, 
15241 +                          bavail_out, files_out, ffree_out, fsid_out, 
15242 +                          fsid_size, namelen_out, spare_out);
15243 +       if(err)
15244 +               return(err);
15245 +
15246 +       *blocks_out = mount->total / *bsize_out;
15247 +       *bfree_out = (mount->total - mount->used) / *bsize_out;
15248 +       *bavail_out = (mount->total - mount->used) / *bsize_out;
15249 +       return(0);
15250 +}
15251 +
15252 +int humfs_truncate_file(struct externfs_inode *ext, __u64 size, 
15253 +                       struct externfs_data *ed)
15254 +{
15255 +       struct humfs_file *hf = container_of(ext, struct humfs_file, ext);
15256 +
15257 +       return(truncate_file(&hf->data, size));
15258 +}
15259 +
15260 +char *humfs_path(char *dir, char *file)
15261 +{
15262 +       int need_slash, len = strlen(dir) + strlen(file);
15263 +       char *new;
15264 +
15265 +       need_slash = (dir[strlen(dir) - 1] != '/');
15266 +       if(need_slash)
15267 +               len++;
15268 +
15269 +       new = kmalloc(len + 1, GFP_KERNEL);
15270 +       if(new == NULL)
15271 +               return(NULL);
15272 +
15273 +       strcpy(new, dir);
15274 +       if(need_slash)
15275 +               strcat(new, "/");
15276 +       strcat(new, file);
15277 +
15278 +       return(new);
15279 +}
15280 +
15281 +DECLARE_MUTEX(meta_sem);
15282 +struct list_head metas = LIST_HEAD_INIT(metas);
15283 +
15284 +static struct humfs_meta_ops *find_meta(const char *name)
15285 +{
15286 +       struct list_head *ele;
15287 +       struct humfs_meta_ops *m;
15288
15289 +       down(&meta_sem);
15290 +       list_for_each(ele, &metas){
15291 +               m = list_entry(ele, struct humfs_meta_ops, list);
15292 +               if(!strcmp(m->name, name))
15293 +                       goto out;
15294 +       }
15295 +       m = NULL;
15296 + out:
15297 +       up(&meta_sem);
15298 +       return(m);
15299 +}
15300 +
15301 +void register_meta(struct humfs_meta_ops *ops)
15302 +{
15303 +       down(&meta_sem);
15304 +       list_add(&ops->list, &metas);
15305 +       up(&meta_sem);
15306 +}
15307
15308 +void unregister_meta(struct humfs_meta_ops *ops)
15309 +{
15310 +       down(&meta_sem);
15311 +       list_del(&ops->list);
15312 +       up(&meta_sem);
15313 +}
15314
15315 +static struct humfs *read_superblock(char *root)
15316 +{
15317 +       struct humfs *mount;
15318 +       struct humfs_meta_ops *meta = NULL;
15319 +       struct file_handle *fh;
15320 +       const char *path[] = { root, "superblock", NULL };
15321 +       u64 used, total;
15322 +       char meta_buf[33], line[HOSTFS_BUFSIZE], *newline;
15323 +       unsigned long long pos;
15324 +       int version, i, n, err;
15325 +
15326 +       fh = kmalloc(sizeof(*fh), GFP_KERNEL);
15327 +       if(fh == NULL)
15328 +               return(ERR_PTR(-ENOMEM));
15329 +
15330 +       err = host_open_file(path, 1, 0, fh);
15331 +       if(err){
15332 +               printk("Failed to open %s/%s, errno = %d\n", path[0],
15333 +                      path[1], err);
15334 +               return(ERR_PTR(err));
15335 +       }
15336 +
15337 +       used = 0;
15338 +       total = 0;
15339 +       pos = 0;
15340 +       i = 0;
15341 +       while(1){
15342 +               n = read_file(fh, pos, &line[i], sizeof(line) - i - 1);
15343 +               if((n == 0) && (i == 0))
15344 +                       break;
15345 +               if(n < 0)
15346 +                       return(ERR_PTR(n));
15347 +
15348 +               pos += n;
15349 +               if(n > 0)
15350 +                       line[n + i] = '\0';
15351 +
15352 +               newline = strchr(line, '\n');
15353 +               if(newline == NULL){
15354 +                       printk("read_superblock - line too long : '%s'\n", 
15355 +                              line);
15356 +                       return(ERR_PTR(-EINVAL));
15357 +               }
15358 +               newline++;
15359 +
15360 +               if(sscanf(line, "version %d\n", &version) == 1){
15361 +                       if(version != HUMFS_VERSION){
15362 +                               printk("humfs version mismatch - want version "
15363 +                                      "%d, got version %d.\n", HUMFS_VERSION,
15364 +                                      version);
15365 +                               return(ERR_PTR(-EINVAL));
15366 +                       }
15367 +               }
15368 +               else if(sscanf(line, "used %Lu\n", &used) == 1) ;
15369 +               else if(sscanf(line, "total %Lu\n", &total) == 1) ;
15370 +               else if(sscanf(line, "metadata %32s\n", meta_buf) == 1){
15371 +                       meta = find_meta(meta_buf);
15372 +                       if(meta == NULL){
15373 +                               printk("read_superblock - meta api \"%s\" not "
15374 +                                      "registered\n", meta_buf);
15375 +                               return(ERR_PTR(-EINVAL));
15376 +                       }
15377 +               }
15378 +               
15379 +               else {
15380 +                       printk("read_superblock - bogus line : '%s'\n", line);
15381 +                       return(ERR_PTR(-EINVAL));
15382 +               }
15383 +
15384 +               i = newline - line;
15385 +               memmove(line, newline, sizeof(line) - i);
15386 +               i = strlen(line);
15387 +       }
15388 +
15389 +       if(used == 0){
15390 +               printk("read_superblock - used not specified or set to "
15391 +                      "zero\n");
15392 +               return(ERR_PTR(-EINVAL));
15393 +       }
15394 +       if(total == 0){
15395 +               printk("read_superblock - total not specified or set to "
15396 +                      "zero\n");
15397 +               return(ERR_PTR(-EINVAL));
15398 +       }
15399 +       if(used > total){
15400 +               printk("read_superblock - used is greater than total\n");
15401 +               return(ERR_PTR(-EINVAL));
15402 +       }
15403 +
15404 +       if(meta == NULL){
15405 +               meta = find_meta("shadow_fs");
15406 +       }
15407 +
15408 +       if(meta == NULL){
15409 +               printk("read_superblock - valid meta api was not specified\n");
15410 +               return(ERR_PTR(-EINVAL));
15411 +       }
15412 +
15413 +       mount = (*meta->init_mount)(root);
15414 +       if(IS_ERR(mount))
15415 +               return(mount);
15416 +
15417 +       *mount = ((struct humfs) { .total       = total,
15418 +                                  .used        = used,
15419 +                                  .meta        = meta });
15420 +       return(mount);
15421 +}
15422 +
15423 +struct externfs_file_ops humfs_no_mmap_file_ops = {
15424 +       .stat_file              = humfs_stat_file,
15425 +       .file_type              = humfs_file_type,
15426 +       .access_file            = NULL,
15427 +       .open_file              = humfs_open_file,
15428 +       .open_dir               = humfs_open_dir,
15429 +       .read_dir               = humfs_read_dir,
15430 +       .read_file              = humfs_read_file,
15431 +       .write_file             = humfs_write_file,
15432 +       .map_file_page          = NULL,
15433 +       .close_file             = humfs_close_file,
15434 +       .close_dir              = humfs_close_dir,
15435 +       .invisible              = humfs_invisible,
15436 +       .create_file            = humfs_create_file,
15437 +       .set_attr               = humfs_set_attr,
15438 +       .make_symlink           = humfs_make_symlink,
15439 +       .unlink_file            = humfs_unlink_file,
15440 +       .make_dir               = humfs_make_dir,
15441 +       .remove_dir             = humfs_remove_dir,
15442 +       .make_node              = humfs_make_node,
15443 +       .link_file              = humfs_link_file,
15444 +       .read_link              = humfs_read_link,
15445 +       .rename_file            = humfs_rename_file,
15446 +       .statfs                 = humfs_stat_fs,
15447 +       .truncate_file          = humfs_truncate_file
15448 +};
15449 +
15450 +struct externfs_file_ops humfs_mmap_file_ops = {
15451 +       .stat_file              = humfs_stat_file,
15452 +       .file_type              = humfs_file_type,
15453 +       .access_file            = NULL,
15454 +       .open_file              = humfs_open_file,
15455 +       .open_dir               = humfs_open_dir,
15456 +       .read_dir               = humfs_read_dir,
15457 +       .read_file              = humfs_read_file,
15458 +       .write_file             = humfs_write_file,
15459 +       .map_file_page          = humfs_map_file_page,
15460 +       .close_file             = humfs_close_file,
15461 +       .close_dir              = humfs_close_dir,
15462 +       .invisible              = humfs_invisible,
15463 +       .create_file            = humfs_create_file,
15464 +       .set_attr               = humfs_set_attr,
15465 +       .make_symlink           = humfs_make_symlink,
15466 +       .unlink_file            = humfs_unlink_file,
15467 +       .make_dir               = humfs_make_dir,
15468 +       .remove_dir             = humfs_remove_dir,
15469 +       .make_node              = humfs_make_node,
15470 +       .link_file              = humfs_link_file,
15471 +       .read_link              = humfs_read_link,
15472 +       .rename_file            = humfs_rename_file,
15473 +       .statfs                 = humfs_stat_fs,
15474 +       .truncate_file          = humfs_truncate_file
15475 +};
15476 +
15477 +static struct externfs_data *mount_fs(char *mount_arg)
15478 +{
15479 +       char *root, *data, *flags;
15480 +       struct humfs *mount;
15481 +       struct externfs_file_ops *file_ops;
15482 +       int err, do_mmap = 0;
15483 +
15484 +       if(mount_arg == NULL){
15485 +               printk("humfs - no host directory specified\n");
15486 +               return(NULL);
15487 +       }
15488 +
15489 +       flags = strchr((char *) mount_arg, ',');
15490 +       if(flags != NULL){
15491 +               do {
15492 +                       *flags++ = '\0';
15493 +
15494 +                       if(!strcmp(flags, "mmap"))
15495 +                               do_mmap = 1;
15496 +
15497 +                       flags = strchr(flags, ',');
15498 +               } while(flags != NULL);
15499 +       }
15500 +
15501 +       err = -ENOMEM;
15502 +       root = host_root_filename(mount_arg);
15503 +       if(root == NULL)
15504 +               goto err;
15505 +
15506 +       mount = read_superblock(root);
15507 +       if(IS_ERR(mount)){
15508 +               err = PTR_ERR(mount);
15509 +               goto err_free_root;
15510 +       }
15511 +
15512 +       data = humfs_path(root, "data/");
15513 +       if(data == NULL)
15514 +               goto err_free_mount;
15515 +
15516 +       if(CHOOSE_MODE(do_mmap, 0)){
15517 +               printk("humfs doesn't support mmap in tt mode\n");
15518 +               do_mmap = 0;
15519 +       }
15520 +
15521 +       mount->data = data;
15522 +       mount->mmap = do_mmap;
15523 +
15524 +       file_ops = do_mmap ? &humfs_mmap_file_ops : &humfs_no_mmap_file_ops;
15525 +       init_externfs(&mount->ext, file_ops);
15526 +
15527 +       return(&mount->ext);
15528 +
15529 + err_free_mount:
15530 +       kfree(mount);
15531 + err_free_root:
15532 +       kfree(root);
15533 + err:
15534 +       return(NULL);
15535 +}
15536 +
15537 +struct externfs_mount_ops humfs_mount_ops = {
15538 +       .init_file              = humfs_init_file,
15539 +       .mount                  = mount_fs,
15540 +};
15541 +
15542 +static int __init init_humfs(void)
15543 +{
15544 +       return(register_externfs("humfs", &humfs_mount_ops));
15545 +}
15546 +
15547 +static void __exit exit_humfs(void)
15548 +{
15549 +       unregister_externfs("humfs");
15550 +}
15551 +
15552 +__initcall(init_humfs);
15553 +__exitcall(exit_humfs);
15554 +
15555 +/*
15556 + * Overrides for Emacs so that we follow Linus's tabbing style.
15557 + * Emacs will notice this stuff at the end of the file and automatically
15558 + * adjust the settings for this buffer only.  This must remain at the end
15559 + * of the file.
15560 + * ---------------------------------------------------------------------------
15561 + * Local variables:
15562 + * c-file-style: "linux"
15563 + * End:
15564 + */
15565 Index: linux-2.4.29/arch/um/fs/hostfs/Makefile
15566 ===================================================================
15567 --- linux-2.4.29.orig/arch/um/fs/hostfs/Makefile        1970-01-01 03:00:00.000000000 +0300
15568 +++ linux-2.4.29/arch/um/fs/hostfs/Makefile     2005-05-03 22:28:14.284438648 +0300
15569 @@ -0,0 +1,14 @@
15570 +# 
15571 +# Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com)
15572 +# Licensed under the GPL
15573 +#
15574 +
15575 +O_TARGET := hostfs.o
15576 +
15577 +obj-$(CONFIG_EXTERNFS) += externfs.o
15578 +obj-$(CONFIG_HOSTFS) += host_fs.o host_file.o
15579 +obj-$(CONFIG_HUMFS) += humfs.o host_file.o meta_fs.o
15580 +
15581 +obj-m = $(O_TARGET)
15582 +
15583 +include $(TOPDIR)/Rules.make
15584 Index: linux-2.4.29/arch/um/fs/hostfs/metadata.h
15585 ===================================================================
15586 --- linux-2.4.29.orig/arch/um/fs/hostfs/metadata.h      1970-01-01 03:00:00.000000000 +0300
15587 +++ linux-2.4.29/arch/um/fs/hostfs/metadata.h   2005-05-03 22:28:14.000000000 +0300
15588 @@ -0,0 +1,84 @@
15589 +/* 
15590 + * Copyright (C) 2004 Piotr Neuman (sikkh@wp.pl) and 
15591 + * Jeff Dike (jdike@addtoit.com)
15592 + * Licensed under the GPL
15593 + */
15594 +
15595 +#ifndef __UM_FS_METADATA
15596 +#define __UM_FS_METADATA
15597 +
15598 +#include "linux/fs.h"
15599 +#include "linux/list.h"
15600 +#include "os.h"
15601 +#include "hostfs.h"
15602 +#include "filehandle.h"
15603 +
15604 +#define container_of(ptr, type, member) ({                      \
15605 +        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
15606 +        (type *)( (char *)__mptr - offsetof(type,member) );})
15607 +
15608 +struct humfs {
15609 +       struct externfs_data ext;
15610 +       __u64 used;
15611 +       __u64 total;
15612 +       char *data;
15613 +       int mmap;
15614 +       int direct;
15615 +       struct humfs_meta_ops *meta;
15616 +};
15617 +
15618 +struct humfs_file {
15619 +       struct humfs *mount;
15620 +       struct file_handle data;
15621 +       struct externfs_inode ext;
15622 +};
15623 +
15624 +struct humfs_meta_ops {
15625 +       struct list_head list;
15626 +       char *name;
15627 +       struct humfs_file *(*init_file)(void);
15628 +       int (*open_file)(struct humfs_file *hf, const char *path, 
15629 +                        struct inode *inode, struct humfs *humfs);
15630 +       int (*create_file)(struct humfs_file *hf, const char *path, int mode, 
15631 +                          int uid, int gid, struct inode *inode, 
15632 +                          struct humfs *humfs);
15633 +       void (*close_file)(struct humfs_file *humfs);
15634 +       int (*ownerships)(const char *path, int *mode_out, int *uid_out, 
15635 +                         int *gid_out, char *type_out, int *maj_out, 
15636 +                         int *min_out, struct humfs *humfs);
15637 +       int (*make_node)(const char *path, int mode, int uid, int gid,
15638 +                        int type, int major, int minor, struct humfs *humfs);
15639 +       int (*create_link)(const char *to, const char *from, 
15640 +                          struct humfs *humfs);
15641 +       int (*remove_file)(const char *path, struct humfs *humfs);
15642 +       int (*create_dir)(const char *path, int mode, int uid, int gid, 
15643 +                         struct humfs *humfs);
15644 +       int (*remove_dir)(const char *path, struct humfs *humfs);
15645 +       int (*change_ownerships)(const char *path, int mode, int uid, int gid,
15646 +                                struct humfs *humfs);
15647 +       int (*rename_file)(const char *from, const char *to, 
15648 +                          struct humfs *humfs);
15649 +       void (*invisible)(struct humfs_file *hf);
15650 +       struct humfs *(*init_mount)(char *root);
15651 +       void (*free_mount)(struct humfs *humfs);
15652 +};
15653 +
15654 +void register_meta(struct humfs_meta_ops *ops);
15655 +void unregister_meta(struct humfs_meta_ops *ops);
15656 +
15657 +char *humfs_path(char *dir, char *file);
15658 +char *humfs_name(struct inode *inode, char *prefix);
15659 +extern struct humfs *inode_humfs_info(struct inode *inode);
15660 +
15661 +#endif
15662 +
15663 +/*
15664 + * Overrides for Emacs so that we follow Linus's tabbing style.
15665 + * Emacs will notice this stuff at the end of the file and automatically
15666 + * adjust the settings for this buffer only.  This must remain at the end
15667 + * of the file.
15668 + * ---------------------------------------------------------------------------
15669 + * Local variables:
15670 + * c-file-style: "linux"
15671 + * End:
15672 + */
15673 Index: linux-2.4.29/arch/um/fs/hostfs/meta_fs.c
15674 ===================================================================
15675 --- linux-2.4.29.orig/arch/um/fs/hostfs/meta_fs.c       1970-01-01 03:00:00.000000000 +0300
15676 +++ linux-2.4.29/arch/um/fs/hostfs/meta_fs.c    2005-05-03 22:28:14.000000000 +0300
15677 @@ -0,0 +1,519 @@
15678 +/* 
15679 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
15680 + * Licensed under the GPL
15681 + */
15682 +
15683 +#include <linux/slab.h>
15684 +#include "hostfs.h"
15685 +#include "metadata.h"
15686 +#include "kern_util.h"
15687 +
15688 +#define METADATA_FILE_PATH(meta) (meta)->root, "file_metadata"
15689 +#define METADATA_DIR_PATH(meta) (meta)->root, "dir_metadata"
15690 +
15691 +struct meta_fs {
15692 +       struct humfs humfs;
15693 +       char *root;
15694 +};
15695 +
15696 +struct meta_file {
15697 +       struct humfs_file humfs;
15698 +       struct file_handle fh;
15699 +};
15700 +
15701 +static int meta_file_path(const char *path, struct meta_fs *meta, 
15702 +                         const char *path_out[])
15703 +{
15704 +       const char *data_path[] = { meta->root, "data", path, NULL };
15705 +       char data_tmp[HOSTFS_BUFSIZE];
15706 +       char *data_file = get_path(data_path, data_tmp, sizeof(data_tmp));
15707 +
15708 +       if(data_file == NULL)
15709 +               return(-ENOMEM);
15710 +
15711 +       path_out[0] = meta->root;
15712 +       path_out[2] = path;
15713 +       if(os_file_type(data_file) == OS_TYPE_DIR){
15714 +               path_out[1] = "dir_metadata";
15715 +               path_out[3] = "metadata";
15716 +               path_out[4] = NULL;
15717 +       }
15718 +       else {
15719 +               path_out[1] = "file_metadata";
15720 +               path_out[3] = NULL;
15721 +       }
15722 +
15723 +       return(0);
15724 +}
15725 +
15726 +static int open_meta_file(const char *path, struct humfs *humfs,
15727 +                         struct file_handle *fh)
15728 +{
15729 +       struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
15730 +       const char *meta_path[5];
15731 +       char meta_tmp[HOSTFS_BUFSIZE];
15732 +       char *meta_file;
15733 +       int err;
15734 +
15735 +       err = meta_file_path(path, meta, meta_path);
15736 +       if(err)
15737 +               goto out;
15738 +
15739 +       meta_file = get_path(meta_path, meta_tmp, sizeof(meta_tmp));
15740 +       if(meta_file == NULL)
15741 +               goto out;
15742 +       
15743 +       err = open_filehandle(meta_file, of_rdwr(OPENFLAGS()), 0, fh);
15744 +
15745 + out:
15746 +       return(err);
15747 +}
15748 +
15749 +static char *meta_fs_name(struct inode *inode)
15750 +{
15751 +       struct humfs *mount = inode->i_sb->u.generic_sbp;
15752 +       struct meta_fs *meta = container_of(mount, struct meta_fs, humfs);
15753 +       const char *metadata_path[5];
15754 +       char tmp[HOSTFS_BUFSIZE], *name, *file;
15755 +
15756 +       if(meta_file_path("", meta, metadata_path))
15757 +               return(NULL);
15758 +
15759 +       file = get_path(metadata_path, tmp, sizeof(tmp));
15760 +       if(file == NULL)
15761 +               return(NULL);
15762 +
15763 +       name = inode_name_prefix(inode, file);
15764 +
15765 +       free_path(file, tmp);
15766 +       return(name);
15767 +}
15768 +
15769 +static void metafs_invisible(struct humfs_file *hf)
15770 +{
15771 +       struct meta_file *mf = container_of(hf, struct meta_file, humfs);
15772 +
15773 +       not_reclaimable(&mf->fh);
15774 +}
15775 +
15776 +static struct humfs_file *metafs_init_file(void)
15777 +{
15778 +       struct meta_file *mf;
15779 +       int err = -ENOMEM;
15780 +
15781 +       mf = kmalloc(sizeof(*mf), GFP_KERNEL);
15782 +       if(mf == NULL)
15783 +               return(ERR_PTR(err));
15784 +
15785 +       return(&mf->humfs);
15786 +}
15787 +
15788 +static int metafs_open_file(struct humfs_file *hf, const char *path, 
15789 +                           struct inode *inode, struct humfs *humfs)
15790 +{
15791 +       struct meta_file *mf = container_of(hf, struct meta_file, humfs);
15792 +       int err;
15793 +
15794 +       err = open_meta_file(path, humfs, &mf->fh);
15795 +       if(err)
15796 +               return(err);
15797 +
15798 +       is_reclaimable(&mf->fh, meta_fs_name, inode);
15799 +
15800 +       return(0);
15801 +}
15802 +
15803 +static void metafs_close_file(struct humfs_file *hf)
15804 +{
15805 +       struct meta_file *meta = container_of(hf, struct meta_file, humfs);
15806 +
15807 +       close_file(&meta->fh);
15808 +       kfree(meta);
15809 +}
15810 +
15811 +static int metafs_create_file(struct humfs_file *hf, const char *path, 
15812 +                             int mode, int uid, int gid, struct inode *inode, 
15813 +                             struct humfs *humfs)
15814 +{
15815 +       struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
15816 +       struct meta_file *mf = container_of(hf, struct meta_file, humfs);
15817 +       char tmp[HOSTFS_BUFSIZE];
15818 +       const char *metadata_path[] = { METADATA_FILE_PATH(meta), path, NULL };
15819 +       char *file = get_path(metadata_path, tmp, sizeof(tmp));
15820 +       char buf[sizeof("mmmm uuuuuuuuuu gggggggggg")];
15821 +       int err = -ENOMEM;
15822 +
15823 +       if(file == NULL)
15824 +               goto out;
15825 +
15826 +       err = open_filehandle(file, of_write(of_create(OPENFLAGS())), 0644, 
15827 +                             &mf->fh);
15828 +       if(err)
15829 +               goto out_free_path;
15830 +
15831 +       if(inode != NULL)
15832 +               is_reclaimable(&mf->fh, meta_fs_name, inode);
15833 +
15834 +       sprintf(buf, "%d %d %d\n", mode  & S_IRWXUGO, uid, gid);
15835 +       err = write_file(&mf->fh, 0, buf, strlen(buf));
15836 +       if(err < 0)
15837 +               goto out_rm;
15838 +
15839 +       free_path(file, tmp);
15840 +       return(0);
15841 +
15842 + out_rm:
15843 +       close_file(&mf->fh);
15844 +       os_remove_file(file);
15845 + out_free_path:
15846 +       free_path(file, tmp);
15847 + out:
15848 +       return(err);
15849 +}
15850 +
15851 +static int metafs_create_link(const char *to, const char *from, 
15852 +                             struct humfs *humfs)
15853 +{
15854 +       struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
15855 +       const char *path_to[] = { METADATA_FILE_PATH(meta), to,  NULL };
15856 +       const char *path_from[] = { METADATA_FILE_PATH(meta), from, NULL };
15857 +
15858 +       return(host_link_file(path_to, path_from));
15859 +}
15860 +
15861 +static int metafs_remove_file(const char *path, struct humfs *humfs)
15862 +{
15863 +       struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
15864 +       char tmp[HOSTFS_BUFSIZE];
15865 +       const char *metadata_path[] = { METADATA_FILE_PATH(meta), path, NULL };
15866 +       char *file = get_path(metadata_path, tmp, sizeof(tmp));
15867 +       int err = -ENOMEM;
15868 +
15869 +       if(file == NULL)
15870 +               goto out;
15871 +
15872 +       err = os_remove_file(file);
15873 +
15874 + out:
15875 +       free_path(file, tmp);
15876 +       return(err);
15877 +}
15878 +
15879 +static int metafs_create_directory(const char *path, int mode, int uid, 
15880 +                                  int gid, struct humfs *humfs)
15881 +{
15882 +       struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
15883 +       char tmp[HOSTFS_BUFSIZE];
15884 +       const char *dir_path[] = { METADATA_DIR_PATH(meta), path, NULL, NULL };
15885 +       const char *file_path[] = { METADATA_FILE_PATH(meta), path, NULL, 
15886 +                                   NULL };
15887 +       char *file, dir_meta[sizeof("mmmm uuuuuuuuuu gggggggggg\n")];
15888 +       int err, fd;
15889 +
15890 +       err = host_make_dir(dir_path, 0755);
15891 +       if(err)
15892 +               goto out;
15893 +
15894 +       err = host_make_dir(file_path, 0755);
15895 +       if(err)
15896 +               goto out_rm;
15897 +
15898 +       /* This to make the index independent of the number of elements in
15899 +        * METADATA_DIR_PATH().
15900 +        */
15901 +       dir_path[sizeof(dir_path) / sizeof(dir_path[0]) - 2] = "metadata";
15902 +
15903 +       err = -ENOMEM;
15904 +       file = get_path(dir_path, tmp, sizeof(tmp));
15905 +       if(file == NULL)
15906 +               goto out;
15907 +
15908 +       fd = os_open_file(file, of_create(of_rdwr(OPENFLAGS())), 0644);
15909 +       if(fd < 0){
15910 +               err = fd;
15911 +               goto out_free;
15912 +       }
15913 +
15914 +       sprintf(dir_meta, "%d %d %d\n", mode & S_IRWXUGO, uid, gid);
15915 +       err = os_write_file(fd, dir_meta, strlen(dir_meta));
15916 +       if(err > 0)
15917 +               err = 0;
15918 +
15919 +       os_close_file(fd);
15920 +
15921 + out_free:
15922 +       free_path(file, tmp);
15923 + out_rm:
15924 +       host_remove_dir(dir_path);
15925 + out:
15926 +       return(err);
15927 +}
15928 +
15929 +static int metafs_remove_directory(const char *path, struct humfs *humfs)
15930 +{
15931 +       struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
15932 +       char tmp[HOSTFS_BUFSIZE], *file;
15933 +       const char *dir_path[] = { METADATA_DIR_PATH(meta), path, "metadata", 
15934 +                                  NULL };
15935 +       const char *file_path[] = { METADATA_FILE_PATH(meta), path, NULL };
15936 +       char *slash;
15937 +       int err;
15938 +
15939 +       err = -ENOMEM;
15940 +       file = get_path(dir_path, tmp, sizeof(tmp));
15941 +       if(file == NULL)
15942 +               goto out;
15943 +
15944 +       err = os_remove_file(file);
15945 +       if(err)
15946 +               goto out_free;
15947 +
15948 +       slash = strrchr(file, '/');
15949 +       if(slash == NULL){
15950 +               printk("remove_shadow_directory failed to find last slash\n");
15951 +               goto out_free;
15952 +       }
15953 +       *slash = '\0';
15954 +       err = os_remove_dir(file);
15955 +       free_path(file, tmp);
15956 +
15957 +       file = get_path(file_path, tmp, sizeof(tmp));
15958 +       if(file == NULL)
15959 +               goto out;
15960 +
15961 +       err = os_remove_dir(file);
15962 +       if(err)
15963 +               goto out_free;
15964 +
15965 + out:
15966 +       return(err);
15967 + out_free:
15968 +       free_path(file, tmp);
15969 +       goto out;
15970 +}
15971 +
15972 +static int metafs_make_node(const char *path, int mode, int uid, int gid, 
15973 +                           int type, int maj, int min, struct humfs *humfs)
15974 +{
15975 +       struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
15976 +       struct file_handle fh;
15977 +       char tmp[HOSTFS_BUFSIZE];
15978 +       const char *metadata_path[] = { METADATA_FILE_PATH(meta), path, NULL };
15979 +       int err;
15980 +       char buf[sizeof("mmmm uuuuuuuuuu gggggggggg x nnn mmm\n")], *file;
15981 +
15982 +       sprintf(buf, "%d %d %d %c %d %d\n", mode & S_IRWXUGO, uid, gid, type, 
15983 +               maj, min);
15984 +
15985 +       err = -ENOMEM;
15986 +       file = get_path(metadata_path, tmp, sizeof(tmp));
15987 +       if(file == NULL)
15988 +               goto out;
15989 +
15990 +       err = open_filehandle(file, 
15991 +                             of_create(of_rdwr(OPENFLAGS())), 0644, &fh);
15992 +       if(err)
15993 +               goto out_free;
15994 +
15995 +       err = write_file(&fh, 0, buf, strlen(buf));
15996 +       if(err > 0)
15997 +               err = 0;
15998 +
15999 +       close_file(&fh);
16000 +
16001 + out_free:
16002 +       free_path(file, tmp);
16003 + out:
16004 +       return(err);
16005 +}
16006 +
16007 +static int metafs_ownerships(const char *path, int *mode_out, int *uid_out, 
16008 +                            int *gid_out, char *type_out, int *maj_out, 
16009 +                            int *min_out, struct humfs *humfs)
16010 +{
16011 +       struct file_handle fh;
16012 +       char buf[sizeof("mmmm uuuuuuuuuu gggggggggg x nnn mmm\n")];
16013 +       int err, n, mode, uid, gid, maj, min;
16014 +       char type;
16015 +
16016 +       err = open_meta_file(path, humfs, &fh);
16017 +       if(err)
16018 +               goto out;
16019 +
16020 +       err = os_read_file(fh.fd, buf, sizeof(buf) - 1);
16021 +       if(err < 0)
16022 +               goto out_close;
16023 +
16024 +       buf[err] = '\0';
16025 +       err = 0;
16026 +
16027 +       n = sscanf(buf, "%d %d %d %c %d %d", &mode, &uid, &gid, &type, &maj, 
16028 +                  &min);
16029 +       if(n == 3){
16030 +               maj = -1;
16031 +               min = -1;
16032 +               type = 0;
16033 +               err = 0;
16034 +       }
16035 +       else if(n != 6)
16036 +               err = -EINVAL;
16037 +
16038 +       if(mode_out != NULL)
16039 +               *mode_out = mode;
16040 +       if(uid_out != NULL)
16041 +               *uid_out = uid;
16042 +       if(gid_out != NULL)
16043 +               *gid_out = uid;
16044 +       if(type_out != NULL)
16045 +               *type_out = type;
16046 +       if(maj_out != NULL)
16047 +               *maj_out = maj;
16048 +       if(min_out != NULL)
16049 +               *min_out = min;
16050 +
16051 + out_close:
16052 +       close_file(&fh);
16053 + out:
16054 +       return(err);
16055 +}
16056 +
16057 +static int metafs_change_ownerships(const char *path, int mode, int uid, 
16058 +                                   int gid, struct humfs *humfs)
16059 +{
16060 +       struct file_handle fh;
16061 +       char type;
16062 +       char buf[sizeof("mmmm uuuuuuuuuu gggggggggg x nnn mmm\n")];
16063 +       int err = -ENOMEM, old_mode, old_uid, old_gid, n, maj, min;
16064 +
16065 +       err = open_meta_file(path, humfs, &fh);
16066 +       if(err)
16067 +               goto out;
16068 +
16069 +       err = read_file(&fh, 0, buf, sizeof(buf) - 1);
16070 +       if(err < 0)
16071 +               goto out_close;
16072 +
16073 +       buf[err] = '\0';
16074 +
16075 +       n = sscanf(buf, "%d %d %d %c %d %d\n", &old_mode, &old_uid, &old_gid,
16076 +                  &type, &maj, &min);
16077 +       if((n != 3) && (n != 6)){
16078 +               err = -EINVAL;
16079 +               goto out_close;
16080 +       }
16081 +
16082 +       if(mode == -1)
16083 +                mode = old_mode;
16084 +       if(uid == -1)
16085 +               uid = old_uid;
16086 +       if(gid == -1)
16087 +               gid = old_gid;
16088 +
16089 +       if(n == 3)
16090 +               sprintf(buf, "%d %d %d\n", mode & S_IRWXUGO, uid, gid);
16091 +       else
16092 +               sprintf(buf, "%d %d %d %c %d %d\n", mode & S_IRWXUGO, uid, gid,
16093 +                       type, maj, min);
16094 +
16095 +       err = write_file(&fh, 0, buf, strlen(buf));
16096 +       if(err > 0)
16097 +               err = 0;
16098 +
16099 +       err = truncate_file(&fh, strlen(buf));
16100 +
16101 + out_close:
16102 +       close_file(&fh);
16103 + out:
16104 +       return(err);
16105 +}
16106 +
16107 +static int metafs_rename_file(const char *from, const char *to, 
16108 +                             struct humfs *humfs)
16109 +{
16110 +       struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
16111 +       const char *metadata_path_from[5], *metadata_path_to[5];
16112 +       int err;
16113 +
16114 +       err = meta_file_path(from, meta, metadata_path_from);
16115 +       if(err)
16116 +               return(err);
16117 +
16118 +       err = meta_file_path(to, meta, metadata_path_to);
16119 +       if(err)
16120 +               return(err);
16121 +
16122 +       return(host_rename_file(metadata_path_from, metadata_path_to));
16123 +}
16124 +
16125 +static struct humfs *metafs_init_mount(char *root)
16126 +{
16127 +       struct meta_fs *meta;
16128 +       int err = -ENOMEM;
16129 +
16130 +       meta = kmalloc(sizeof(*meta), GFP_KERNEL);
16131 +       if(meta == NULL)
16132 +               goto out;
16133 +
16134 +       meta->root = uml_strdup(root);
16135 +       if(meta->root == NULL)
16136 +               goto out_free_meta;
16137 +
16138 +       return(&meta->humfs);
16139 +
16140 + out_free_meta:
16141 +       kfree(meta);
16142 + out:
16143 +       return(ERR_PTR(err));
16144 +}
16145 +
16146 +static void metafs_free_mount(struct humfs *humfs)
16147 +{
16148 +       struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
16149 +       
16150 +       kfree(meta);
16151 +}
16152 +
16153 +struct humfs_meta_ops hum_fs_meta_fs_ops = {
16154 +       .list                   = LIST_HEAD_INIT(hum_fs_meta_fs_ops.list),
16155 +       .name                   = "shadow_fs",
16156 +       .init_file              = metafs_init_file,
16157 +       .open_file              = metafs_open_file,
16158 +       .close_file             = metafs_close_file,
16159 +       .ownerships             = metafs_ownerships,
16160 +       .make_node              = metafs_make_node,
16161 +       .create_file            = metafs_create_file,
16162 +       .create_link            = metafs_create_link,
16163 +       .remove_file            = metafs_remove_file,
16164 +       .create_dir             = metafs_create_directory,
16165 +       .remove_dir             = metafs_remove_directory,
16166 +       .change_ownerships      = metafs_change_ownerships,
16167 +       .rename_file            = metafs_rename_file,
16168 +       .invisible              = metafs_invisible,
16169 +       .init_mount             = metafs_init_mount,
16170 +       .free_mount             = metafs_free_mount,
16171 +};
16172 +
16173 +static int __init init_meta_fs(void)
16174 +{
16175 +       register_meta(&hum_fs_meta_fs_ops);
16176 +       return(0);
16177 +}
16178 +
16179 +static void __exit exit_meta_fs(void)
16180 +{
16181 +       unregister_meta(&hum_fs_meta_fs_ops);
16182 +}
16183 +
16184 +__initcall(init_meta_fs);
16185 +__exitcall(exit_meta_fs);
16186 +
16187 +/*
16188 + * Overrides for Emacs so that we follow Linus's tabbing style.
16189 + * Emacs will notice this stuff at the end of the file and automatically
16190 + * adjust the settings for this buffer only.  This must remain at the end
16191 + * of the file.
16192 + * ---------------------------------------------------------------------------
16193 + * Local variables:
16194 + * c-file-style: "linux"
16195 + * End:
16196 + */
16197 Index: linux-2.4.29/arch/um/fs/hppfs/hppfs_kern.c
16198 ===================================================================
16199 --- linux-2.4.29.orig/arch/um/fs/hppfs/hppfs_kern.c     1970-01-01 03:00:00.000000000 +0300
16200 +++ linux-2.4.29/arch/um/fs/hppfs/hppfs_kern.c  2005-05-03 22:28:14.000000000 +0300
16201 @@ -0,0 +1,737 @@
16202 +/* 
16203 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16204 + * Licensed under the GPL
16205 + */
16206 +
16207 +#include <linux/fs.h>
16208 +#include <linux/module.h>
16209 +#include <linux/slab.h>
16210 +#include <linux/list.h>
16211 +#include <linux/kernel.h>
16212 +#include <linux/ctype.h>
16213 +#include <asm/uaccess.h>
16214 +#include "os.h"
16215 +
16216 +struct hppfs_data {
16217 +       struct list_head list;
16218 +       char contents[PAGE_SIZE - sizeof(struct list_head)];
16219 +};
16220 +
16221 +struct hppfs_private {
16222 +       struct file proc_file;
16223 +       int host_fd;
16224 +       loff_t len;
16225 +       struct hppfs_data *contents;
16226 +};
16227 +
16228 +#define HPPFS_SUPER_MAGIC 0xb00000ee
16229 +
16230 +static struct super_operations hppfs_sbops;
16231 +
16232 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
16233 +                              int *error);
16234 +
16235 +static int is_pid(struct dentry *dentry)
16236 +{
16237 +       struct super_block *sb;
16238 +       int i;
16239 +
16240 +       sb = dentry->d_sb;
16241 +       if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
16242 +               return(0);
16243 +
16244 +       for(i = 0; i < dentry->d_name.len; i++){
16245 +               if(!isdigit(dentry->d_name.name[i]))
16246 +                       return(0);
16247 +       }
16248 +       return(1);
16249 +}
16250 +
16251 +static char *dentry_name(struct dentry *dentry, int extra)
16252 +{
16253 +       struct dentry *parent;
16254 +       char *root, *name;
16255 +       const char *seg_name;
16256 +       int len, seg_len;
16257 +
16258 +       len = 0;
16259 +       parent = dentry;
16260 +       while(parent->d_parent != parent){
16261 +               if(is_pid(parent))
16262 +                       len += strlen("pid") + 1;
16263 +               else len += parent->d_name.len + 1;
16264 +               parent = parent->d_parent;
16265 +       }
16266 +       
16267 +       root = "proc";
16268 +       len += strlen(root);
16269 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
16270 +       if(name == NULL) return(NULL);
16271 +
16272 +       name[len] = '\0';
16273 +       parent = dentry;
16274 +       while(parent->d_parent != parent){
16275 +               if(is_pid(parent)){
16276 +                       seg_name = "pid";
16277 +                       seg_len = strlen("pid");
16278 +               }
16279 +               else {
16280 +                       seg_name = parent->d_name.name;
16281 +                       seg_len = parent->d_name.len;
16282 +               }
16283 +
16284 +               len -= seg_len + 1;
16285 +               name[len] = '/';
16286 +               strncpy(&name[len + 1], seg_name, seg_len);
16287 +               parent = parent->d_parent;
16288 +       }
16289 +       strncpy(name, root, strlen(root));
16290 +       return(name);
16291 +}
16292 +
16293 +struct dentry_operations hppfs_dentry_ops = {
16294 +};
16295 +
16296 +static int file_removed(struct dentry *dentry, const char *file)
16297 +{
16298 +       char *host_file;
16299 +       int extra, fd;
16300 +
16301 +       extra = 0;
16302 +       if(file != NULL) extra += strlen(file) + 1;
16303 +
16304 +       host_file = dentry_name(dentry, extra + strlen("/remove"));
16305 +       if(host_file == NULL){
16306 +               printk("file_removed : allocation failed\n");
16307 +               return(-ENOMEM);
16308 +       }
16309 +
16310 +       if(file != NULL){
16311 +               strcat(host_file, "/");
16312 +               strcat(host_file, file);
16313 +       }
16314 +       strcat(host_file, "/remove");
16315 +
16316 +       fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
16317 +       kfree(host_file);
16318 +       if(fd >= 0){
16319 +               os_close_file(fd);
16320 +               return(1);
16321 +       }
16322 +       return(0);
16323 +}
16324 +
16325 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry)
16326 +{
16327 +       struct dentry *proc_dentry;
16328 +       struct inode *inode;
16329 +       int err, deleted;
16330 +
16331 +       deleted = file_removed(dentry, NULL);
16332 +       if(deleted < 0)
16333 +               return(ERR_PTR(deleted));
16334 +       else if(deleted)
16335 +               return(ERR_PTR(-ENOENT));
16336 +
16337 +       proc_dentry = lookup_hash(&dentry->d_name, ino->u.hppfs_i.proc_dentry);
16338 +       if(IS_ERR(proc_dentry))
16339 +               return(proc_dentry);
16340 +
16341 +       inode = get_inode(ino->i_sb, proc_dentry, &err);
16342 +       if(err != 0) 
16343 +               return(ERR_PTR(err));
16344 +
16345 +       d_add(dentry, inode);
16346 +       dentry->d_op = &hppfs_dentry_ops;
16347 +       return(NULL);
16348 +}
16349 +
16350 +static struct inode_operations hppfs_file_iops = {
16351 +};
16352 +
16353 +static struct inode_operations hppfs_dir_iops = {
16354 +       .lookup         = hppfs_lookup,
16355 +};
16356 +
16357 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count, 
16358 +                        loff_t *ppos, int is_user)
16359 +{
16360 +       ssize_t (*read)(struct file *, char *, size_t, loff_t *);
16361 +       ssize_t n;
16362 +
16363 +       read = file->f_dentry->d_inode->i_fop->read;
16364 +       if(read == NULL)
16365 +               return(-EOPNOTSUPP);
16366 +
16367 +       if(!is_user)
16368 +               set_fs(KERNEL_DS);
16369 +               
16370 +       n = (*read)(file, buf, count, &file->f_pos);
16371 +
16372 +       if(!is_user)
16373 +               set_fs(USER_DS);
16374 +
16375 +       if(ppos) *ppos = file->f_pos;
16376 +       return(n);
16377 +}
16378 +
16379 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
16380 +{
16381 +       ssize_t n;
16382 +       int cur, err;
16383 +       char *new_buf;
16384 +
16385 +       n = -ENOMEM;
16386 +       new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
16387 +       if(new_buf == NULL){
16388 +               printk("hppfs_read_file : kmalloc failed\n");
16389 +               goto out;
16390 +       }
16391 +       n = 0;
16392 +       while(count > 0){
16393 +               cur = min_t(ssize_t, count, PAGE_SIZE);
16394 +               err = os_read_file(fd, new_buf, cur);
16395 +               if(err < 0){
16396 +                       printk("hppfs_read : read failed, err = %d\n", -err);
16397 +                       n = err;
16398 +                       goto out_free;
16399 +               }
16400 +               else if(err == 0)
16401 +                       break;
16402 +
16403 +               if(copy_to_user(buf, new_buf, err)){
16404 +                       n = -EFAULT;
16405 +                       goto out_free;
16406 +               }
16407 +               n += err;
16408 +               count -= err;
16409 +       }
16410 + out_free:
16411 +       kfree(new_buf);
16412 + out:
16413 +       return(n);
16414 +}
16415 +
16416 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count, 
16417 +                         loff_t *ppos)
16418 +{
16419 +       struct hppfs_private *hppfs = file->private_data;
16420 +       struct hppfs_data *data;
16421 +       loff_t off;
16422 +       int err;
16423 +
16424 +       if(hppfs->contents != NULL){
16425 +               if(*ppos >= hppfs->len) return(0);
16426 +
16427 +               data = hppfs->contents;
16428 +               off = *ppos;
16429 +               while(off >= sizeof(data->contents)){
16430 +                       data = list_entry(data->list.next, struct hppfs_data,
16431 +                                         list);
16432 +                       off -= sizeof(data->contents);
16433 +               }
16434 +
16435 +               if(off + count > hppfs->len)
16436 +                       count = hppfs->len - off;
16437 +               copy_to_user(buf, &data->contents[off], count);
16438 +               *ppos += count;
16439 +       }
16440 +       else if(hppfs->host_fd != -1){
16441 +               err = os_seek_file(hppfs->host_fd, *ppos);
16442 +               if(err < 0){
16443 +                       printk("hppfs_read : seek failed, err = %d\n", -err);
16444 +                       return(err);
16445 +               }
16446 +               count = hppfs_read_file(hppfs->host_fd, buf, count);
16447 +               if(count > 0)
16448 +                       *ppos += count;
16449 +       }
16450 +       else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
16451 +
16452 +       return(count);
16453 +}
16454 +
16455 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, 
16456 +                          loff_t *ppos)
16457 +{
16458 +       struct hppfs_private *data = file->private_data;
16459 +       struct file *proc_file = &data->proc_file;
16460 +       ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
16461 +       int err;
16462 +
16463 +       write = proc_file->f_dentry->d_inode->i_fop->write;
16464 +       if(write == NULL)
16465 +               return(-EOPNOTSUPP);
16466 +
16467 +       proc_file->f_pos = file->f_pos;
16468 +       err = (*write)(proc_file, buf, len, &proc_file->f_pos);
16469 +       file->f_pos = proc_file->f_pos;
16470 +
16471 +       return(err);
16472 +}
16473 +
16474 +static int open_host_sock(char *host_file, int *filter_out)
16475 +{
16476 +       char *end;
16477 +       int fd;
16478 +
16479 +       end = &host_file[strlen(host_file)];
16480 +       strcpy(end, "/rw");
16481 +       *filter_out = 1;
16482 +       fd = os_connect_socket(host_file);
16483 +       if(fd >= 0)
16484 +               return(fd);
16485 +
16486 +       strcpy(end, "/r");
16487 +       *filter_out = 0;
16488 +       fd = os_connect_socket(host_file);
16489 +       return(fd);
16490 +}
16491 +
16492 +static void free_contents(struct hppfs_data *head)
16493 +{
16494 +       struct hppfs_data *data;
16495 +       struct list_head *ele, *next;
16496 +
16497 +       if(head == NULL) return;
16498 +
16499 +       list_for_each_safe(ele, next, &head->list){
16500 +               data = list_entry(ele, struct hppfs_data, list);
16501 +               kfree(data);
16502 +       }
16503 +       kfree(head);
16504 +}
16505 +
16506 +static struct hppfs_data *hppfs_get_data(int fd, int filter, 
16507 +                                        struct file *proc_file, 
16508 +                                        struct file *hppfs_file, 
16509 +                                        loff_t *size_out)
16510 +{
16511 +       struct hppfs_data *data, *new, *head;
16512 +       int n, err;
16513 +
16514 +       err = -ENOMEM;
16515 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
16516 +       if(data == NULL){
16517 +               printk("hppfs_get_data : head allocation failed\n");
16518 +               goto failed;
16519 +       }
16520 +
16521 +       INIT_LIST_HEAD(&data->list);
16522 +
16523 +       head = data;
16524 +       *size_out = 0;
16525 +
16526 +       if(filter){
16527 +               while((n = read_proc(proc_file, data->contents,
16528 +                                    sizeof(data->contents), NULL, 0)) > 0) {
16529 +                       err = os_write_file(fd, data->contents, n);
16530 +                       if(err != n)
16531 +                               printk("hppfs_get_data : failed to write out "
16532 +                                      "%d bytes, err = %d\n", n, -err);
16533 +               }
16534 +               err = os_shutdown_socket(fd, 0, 1);
16535 +               if(err < 0){
16536 +                       printk("hppfs_get_data : failed to shut down "
16537 +                              "socket\n");
16538 +                       goto failed_free;
16539 +               }
16540 +       }
16541 +       while(1){
16542 +               n = os_read_file(fd, data->contents, sizeof(data->contents));
16543 +               if(n < 0){
16544 +                       err = n;
16545 +                       printk("hppfs_get_data : read failed, err = %d\n", -n);
16546 +                       goto failed_free;
16547 +               }
16548 +               else if(n == 0)
16549 +                       break;
16550 +
16551 +               *size_out += n;
16552 +
16553 +               if(n < sizeof(data->contents))
16554 +                       break;
16555 +
16556 +               new = kmalloc(sizeof(*data), GFP_KERNEL);
16557 +               if(new == 0){
16558 +                       printk("hppfs_get_data : data allocation failed\n");
16559 +                       err = -ENOMEM;
16560 +                       goto failed_free;
16561 +               }
16562 +       
16563 +               INIT_LIST_HEAD(&new->list);
16564 +               list_add(&new->list, &data->list);
16565 +               data = new;
16566 +       }
16567 +       return(head);
16568 +
16569 + failed_free:
16570 +       free_contents(head);
16571 + failed:               
16572 +       return(ERR_PTR(err));
16573 +}
16574 +
16575 +static struct hppfs_private *hppfs_data(void)
16576 +{
16577 +       struct hppfs_private *data;
16578 +
16579 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
16580 +       if(data == NULL)
16581 +               return(data);
16582 +
16583 +       *data = ((struct hppfs_private ) { .host_fd             = -1,
16584 +                                          .len                 = -1,
16585 +                                          .contents            = NULL } );
16586 +       return(data);
16587 +}
16588 +
16589 +static int hppfs_open(struct inode *inode, struct file *file)
16590 +{
16591 +       struct hppfs_private *data;
16592 +       struct dentry *proc_dentry;
16593 +       char *host_file;
16594 +       int err, fd, type, filter;
16595 +
16596 +       err = -ENOMEM;
16597 +       data = hppfs_data();
16598 +       if(data == NULL)
16599 +               goto out;
16600 +
16601 +       host_file = dentry_name(file->f_dentry, strlen("/rw"));
16602 +       if(host_file == NULL)
16603 +               goto out_free2;
16604 +
16605 +       proc_dentry = inode->u.hppfs_i.proc_dentry;
16606 +       err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
16607 +       if(err)
16608 +               goto out_free1;
16609 +
16610 +       type = os_file_type(host_file);
16611 +       if(type == OS_TYPE_FILE){
16612 +               fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
16613 +               if(fd >= 0) 
16614 +                       data->host_fd = fd;
16615 +               else printk("hppfs_open : failed to open '%s', err = %d\n",
16616 +                           host_file, -fd);
16617 +
16618 +               data->contents = NULL;
16619 +       }
16620 +       else if(type == OS_TYPE_DIR){
16621 +               fd = open_host_sock(host_file, &filter);
16622 +               if(fd >= 0){
16623 +                       data->contents = hppfs_get_data(fd, filter, 
16624 +                                                       &data->proc_file, 
16625 +                                                       file, &data->len);
16626 +                       if(!IS_ERR(data->contents))
16627 +                               data->host_fd = fd;
16628 +               }
16629 +               else printk("hppfs_open : failed to open a socket in "
16630 +                           "'%s', err = %d\n", host_file, -fd);
16631 +       }
16632 +       kfree(host_file);
16633 +
16634 +       file->private_data = data;
16635 +       return(0);
16636 +
16637 + out_free1:
16638 +       kfree(host_file);
16639 + out_free2:
16640 +       free_contents(data->contents);
16641 +       kfree(data);
16642 + out:
16643 +       return(err);
16644 +}
16645 +
16646 +static int hppfs_dir_open(struct inode *inode, struct file *file)
16647 +{
16648 +       struct hppfs_private *data;
16649 +       struct dentry *proc_dentry;
16650 +       int err;
16651 +
16652 +       err = -ENOMEM;
16653 +       data = hppfs_data();
16654 +       if(data == NULL)
16655 +               goto out;
16656 +
16657 +       proc_dentry = inode->u.hppfs_i.proc_dentry;
16658 +       err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
16659 +       if(err)
16660 +               goto out_free;
16661 +
16662 +       file->private_data = data;
16663 +       return(0);
16664 +
16665 + out_free:
16666 +       kfree(data);
16667 + out:
16668 +       return(err);
16669 +}
16670 +
16671 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
16672 +{
16673 +       struct hppfs_private *data = file->private_data;
16674 +       struct file *proc_file = &data->proc_file;
16675 +       loff_t (*llseek)(struct file *, loff_t, int);
16676 +       loff_t ret;
16677 +
16678 +       llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
16679 +       if(llseek != NULL){
16680 +               ret = (*llseek)(proc_file, off, where);
16681 +               if(ret < 0)
16682 +                       return(ret);
16683 +       }
16684 +
16685 +       return(default_llseek(file, off, where));
16686 +}
16687 +
16688 +struct hppfs_dirent {
16689 +       void *vfs_dirent;
16690 +       filldir_t filldir;
16691 +       struct dentry *dentry;
16692 +};
16693 +
16694 +static int hppfs_filldir(void *d, const char *name, int size, 
16695 +                        loff_t offset, ino_t inode, unsigned int type)
16696 +{
16697 +       struct hppfs_dirent *dirent = d;
16698 +
16699 +       if(file_removed(dirent->dentry, name))
16700 +               return(0);
16701 +
16702 +       return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset, 
16703 +                                 inode, type));
16704 +}
16705 +
16706 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
16707 +{
16708 +       struct hppfs_private *data = file->private_data;
16709 +       struct file *proc_file = &data->proc_file;
16710 +       int (*readdir)(struct file *, void *, filldir_t);
16711 +       struct hppfs_dirent dirent = ((struct hppfs_dirent)
16712 +                                     { .vfs_dirent     = ent,
16713 +                                       .filldir        = filldir,
16714 +                                       .dentry         = file->f_dentry } );
16715 +       int err;
16716 +
16717 +       readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
16718 +       if(readdir == NULL)
16719 +               return(-EOPNOTSUPP);
16720 +
16721 +       proc_file->f_pos = file->f_pos;
16722 +       err = (*readdir)(proc_file, &dirent, hppfs_filldir);
16723 +       file->f_pos = proc_file->f_pos;
16724 +
16725 +       return(err);
16726 +}
16727 +
16728 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
16729 +{
16730 +       return(0);
16731 +}
16732 +
16733 +static struct file_operations hppfs_file_fops = {
16734 +       .owner          = NULL,
16735 +       .llseek         = hppfs_llseek,
16736 +       .read           = hppfs_read,
16737 +       .write          = hppfs_write,
16738 +       .open           = hppfs_open,
16739 +};
16740 +
16741 +static struct file_operations hppfs_dir_fops = {
16742 +       .owner          = NULL,
16743 +       .readdir        = hppfs_readdir,
16744 +       .open           = hppfs_dir_open,
16745 +       .fsync          = hppfs_fsync,
16746 +};
16747 +
16748 +static int hppfs_statfs(struct super_block *sb, struct statfs *sf)
16749 +{
16750 +       sf->f_blocks = 0;
16751 +       sf->f_bfree = 0;
16752 +       sf->f_bavail = 0;
16753 +       sf->f_files = 0;
16754 +       sf->f_ffree = 0;
16755 +       sf->f_type = HPPFS_SUPER_MAGIC;
16756 +       return(0);
16757 +}
16758 +
16759 +static struct super_operations hppfs_sbops = { 
16760 +       .put_inode      = force_delete,
16761 +       .delete_inode   = NULL,
16762 +       .statfs         = hppfs_statfs,
16763 +};
16764 +
16765 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
16766 +{
16767 +       struct file proc_file;
16768 +       struct dentry *proc_dentry;
16769 +       int (*readlink)(struct dentry *, char *, int);
16770 +       int err, n;
16771 +
16772 +       proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
16773 +       err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
16774 +       if(err) 
16775 +               return(err);
16776 +
16777 +       readlink = proc_dentry->d_inode->i_op->readlink;
16778 +       if(readlink == NULL)
16779 +               return(-EOPNOTSUPP);
16780 +       n = (*readlink)(proc_dentry, buffer, buflen);
16781 +
16782 +       if(proc_file.f_op->release)
16783 +               (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
16784 +       
16785 +       return(n);
16786 +}
16787 +
16788 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
16789 +{
16790 +       struct file proc_file;
16791 +       struct dentry *proc_dentry;
16792 +       int (*follow_link)(struct dentry *, struct nameidata *);
16793 +       int err, n;
16794 +
16795 +       proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
16796 +       err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
16797 +       if(err) 
16798 +               return(err);
16799 +
16800 +       follow_link = proc_dentry->d_inode->i_op->follow_link;
16801 +       if(follow_link == NULL)
16802 +               return(-EOPNOTSUPP);
16803 +       n = (*follow_link)(proc_dentry, nd);
16804 +
16805 +       if(proc_file.f_op->release)
16806 +               (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
16807 +       
16808 +       return(n);
16809 +}
16810 +
16811 +static struct inode_operations hppfs_link_iops = {
16812 +       .readlink       = hppfs_readlink,
16813 +       .follow_link    = hppfs_follow_link,
16814 +};
16815 +
16816 +static void read_inode(struct inode *ino)
16817 +{
16818 +       struct inode *proc_ino;
16819 +
16820 +       proc_ino = ino->u.hppfs_i.proc_dentry->d_inode;
16821 +       ino->i_uid = proc_ino->i_uid;
16822 +       ino->i_gid = proc_ino->i_gid;
16823 +       ino->i_atime = proc_ino->i_atime;
16824 +       ino->i_mtime = proc_ino->i_mtime;
16825 +       ino->i_ctime = proc_ino->i_ctime;
16826 +       ino->i_ino = proc_ino->i_ino;
16827 +       ino->i_dev = proc_ino->i_dev;
16828 +       ino->i_mode = proc_ino->i_mode;
16829 +       ino->i_nlink = proc_ino->i_nlink;
16830 +       ino->i_size = proc_ino->i_size;
16831 +       ino->i_blksize = proc_ino->i_blksize;
16832 +       ino->i_blocks = proc_ino->i_blocks;
16833 +}
16834 +
16835 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
16836 +                              int *error)
16837 +{
16838 +       struct inode *inode;
16839 +       int err = -ENOMEM;
16840 +
16841 +       inode = new_inode(sb);
16842 +       if(inode == NULL) 
16843 +               goto out;
16844 +
16845 +       insert_inode_hash(inode);
16846 +       if(S_ISDIR(dentry->d_inode->i_mode)){
16847 +               inode->i_op = &hppfs_dir_iops;
16848 +               inode->i_fop = &hppfs_dir_fops;
16849 +       }
16850 +       else if(S_ISLNK(dentry->d_inode->i_mode)){
16851 +               inode->i_op = &hppfs_link_iops;
16852 +               inode->i_fop = &hppfs_file_fops;
16853 +       }
16854 +       else {
16855 +               inode->i_op = &hppfs_file_iops;
16856 +               inode->i_fop = &hppfs_file_fops;
16857 +       }
16858 +
16859 +       inode->i_sb = sb;
16860 +       inode->u.hppfs_i.proc_dentry = dentry;
16861 +
16862 +       read_inode(inode);
16863 +       err = 0;
16864 +
16865 +       if(error) *error = err;
16866 +       return(inode);
16867 + out:
16868 +       if(error) *error = err;
16869 +       return(NULL);
16870 +}
16871 +
16872 +static struct super_block *hppfs_read_super(struct super_block *sb, void *d, 
16873 +                                           int silent)
16874 +{
16875 +       struct inode *root_inode;
16876 +       struct file_system_type *procfs;
16877 +       struct super_block *proc_sb;
16878 +
16879 +       procfs = get_fs_type("proc");
16880 +       if(procfs == NULL) 
16881 +               goto out;
16882 +
16883 +       if(list_empty(&procfs->fs_supers))
16884 +               goto out;
16885 +
16886 +       proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
16887 +                            s_instances);
16888 +       
16889 +       sb->s_blocksize = 1024;
16890 +       sb->s_blocksize_bits = 10;
16891 +       sb->s_magic = HPPFS_SUPER_MAGIC;
16892 +       sb->s_op = &hppfs_sbops;
16893 +
16894 +       dget(proc_sb->s_root);
16895 +       root_inode = get_inode(sb, proc_sb->s_root, NULL);
16896 +       if(root_inode == NULL)
16897 +               goto out_dput;
16898 +
16899 +       sb->s_root = d_alloc_root(root_inode);
16900 +       if(sb->s_root == NULL)
16901 +               goto out_put;
16902 +
16903 +       return(sb);
16904 +
16905 + out_put:
16906 +       iput(root_inode);
16907 + out_dput:
16908 +       dput(proc_sb->s_root);
16909 + out:
16910 +       return(NULL);
16911 +}
16912 +
16913 +DECLARE_FSTYPE(hppfs_type, "hppfs", hppfs_read_super, 0);
16914 +
16915 +static int __init init_hppfs(void)
16916 +{
16917 +       return(register_filesystem(&hppfs_type));
16918 +}
16919 +
16920 +static void __exit exit_hppfs(void)
16921 +{
16922 +       unregister_filesystem(&hppfs_type);
16923 +}
16924 +
16925 +module_init(init_hppfs)
16926 +module_exit(exit_hppfs)
16927 +MODULE_LICENSE("GPL");
16928 +
16929 +/*
16930 + * Overrides for Emacs so that we follow Linus's tabbing style.
16931 + * Emacs will notice this stuff at the end of the file and automatically
16932 + * adjust the settings for this buffer only.  This must remain at the end
16933 + * of the file.
16934 + * ---------------------------------------------------------------------------
16935 + * Local variables:
16936 + * c-file-style: "linux"
16937 + * End:
16938 + */
16939 Index: linux-2.4.29/arch/um/fs/hppfs/Makefile
16940 ===================================================================
16941 --- linux-2.4.29.orig/arch/um/fs/hppfs/Makefile 1970-01-01 03:00:00.000000000 +0300
16942 +++ linux-2.4.29/arch/um/fs/hppfs/Makefile      2005-05-03 22:28:14.000000000 +0300
16943 @@ -0,0 +1,10 @@
16944 +O_TARGET := hppfs.o
16945 +obj-y = hppfs_kern.o #hppfs_user.o
16946 +obj-m = $(O_TARGET)
16947 +
16948 +CFLAGS_hppfs_kern.o := $(CFLAGS)
16949 +#CFLAGS_hppfs_user.o := $(USER_CFLAGS)
16950 +
16951 +override CFLAGS =  
16952 +
16953 +include $(TOPDIR)/Rules.make
16954 Index: linux-2.4.29/arch/um/fs/Makefile
16955 ===================================================================
16956 --- linux-2.4.29.orig/arch/um/fs/Makefile       1970-01-01 03:00:00.000000000 +0300
16957 +++ linux-2.4.29/arch/um/fs/Makefile    2005-05-03 22:28:14.291437584 +0300
16958 @@ -0,0 +1,23 @@
16959 +# 
16960 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16961 +# Licensed under the GPL
16962 +#
16963 +
16964 +O_TARGET := built-in.o
16965 +
16966 +subdir-y =
16967 +subdir-m =
16968 +
16969 +subdir-$(CONFIG_HOSTFS) += hostfs
16970 +subdir-$(CONFIG_HPPFS) += hppfs
16971 +
16972 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
16973 +obj-m += $(join $(subdir-m),$(subdir-m:%=/%.o))
16974 +
16975 +include $(TOPDIR)/Rules.make
16976 +
16977 +dep:
16978 +
16979 +clean:
16980 +
16981 +archmrproper:
16982 Index: linux-2.4.29/arch/um/include/2_5compat.h
16983 ===================================================================
16984 --- linux-2.4.29.orig/arch/um/include/2_5compat.h       1970-01-01 03:00:00.000000000 +0300
16985 +++ linux-2.4.29/arch/um/include/2_5compat.h    2005-05-03 22:28:14.292437432 +0300
16986 @@ -0,0 +1,33 @@
16987 +/* 
16988 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
16989 + * Licensed under the GPL
16990 + */
16991 +
16992 +#ifndef __2_5_COMPAT_H__
16993 +#define __2_5_COMPAT_H__
16994 +
16995 +#include "linux/version.h"
16996 +
16997 +#define INIT_ELV(queue, elv) elevator_init(elv, ELV_NOOP)
16998 +
16999 +#define ELV_NOOP ELEVATOR_NOOP
17000 +
17001 +#define INIT_HARDSECT(arr, maj, sizes) arr[maj] = sizes
17002 +
17003 +#define IS_WRITE(req) ((req)->cmd == WRITE)
17004 +
17005 +#define SET_PRI(task) \
17006 +       do { (task)->nice = 20; (task)->counter = -100; } while(0);
17007 +
17008 +#endif
17009 +
17010 +/*
17011 + * Overrides for Emacs so that we follow Linus's tabbing style.
17012 + * Emacs will notice this stuff at the end of the file and automatically
17013 + * adjust the settings for this buffer only.  This must remain at the end
17014 + * of the file.
17015 + * ---------------------------------------------------------------------------
17016 + * Local variables:
17017 + * c-file-style: "linux"
17018 + * End:
17019 + */
17020 Index: linux-2.4.29/arch/um/include/aio.h
17021 ===================================================================
17022 --- linux-2.4.29.orig/arch/um/include/aio.h     1970-01-01 03:00:00.000000000 +0300
17023 +++ linux-2.4.29/arch/um/include/aio.h  2005-05-03 22:28:14.293437280 +0300
17024 @@ -0,0 +1,36 @@
17025 +/* 
17026 + * Copyright (C) 2004 Jeff Dike (jdike@karaya.com)
17027 + * Licensed under the GPL
17028 + */
17029 +
17030 +#ifndef AIO_H__
17031 +#define AIO_H__
17032 +
17033 +enum aio_type { AIO_READ, AIO_WRITE, AIO_MMAP };
17034 +
17035 +struct aio_thread_reply {
17036 +       void *data;
17037 +       int err;
17038 +};
17039 +
17040 +struct aio_context {
17041 +       int reply_fd;
17042 +};
17043 +
17044 +#define INIT_AIO_CONTEXT { .reply_fd   = -1 }
17045 +
17046 +extern int submit_aio(enum aio_type type, int fd, char *buf, int len, 
17047 +                     unsigned long long offset, int reply_fd, void *data);
17048 +
17049 +#endif
17050 +
17051 +/*
17052 + * Overrides for Emacs so that we follow Linus's tabbing style.
17053 + * Emacs will notice this stuff at the end of the file and automatically
17054 + * adjust the settings for this buffer only.  This must remain at the end
17055 + * of the file.
17056 + * ---------------------------------------------------------------------------
17057 + * Local variables:
17058 + * c-file-style: "linux"
17059 + * End:
17060 + */
17061 Index: linux-2.4.29/arch/um/include/chan_kern.h
17062 ===================================================================
17063 --- linux-2.4.29.orig/arch/um/include/chan_kern.h       1970-01-01 03:00:00.000000000 +0300
17064 +++ linux-2.4.29/arch/um/include/chan_kern.h    2005-05-03 22:28:14.294437128 +0300
17065 @@ -0,0 +1,56 @@
17066 +/* 
17067 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
17068 + * Licensed under the GPL
17069 + */
17070 +
17071 +#ifndef __CHAN_KERN_H__
17072 +#define __CHAN_KERN_H__
17073 +
17074 +#include "linux/tty.h"
17075 +#include "linux/list.h"
17076 +#include "chan_user.h"
17077 +
17078 +struct chan {
17079 +       struct list_head list;
17080 +       char *dev;
17081 +       unsigned int primary:1;
17082 +       unsigned int input:1;
17083 +       unsigned int output:1;
17084 +       unsigned int opened:1;
17085 +       int fd;
17086 +       enum chan_init_pri pri;
17087 +       struct chan_ops *ops;
17088 +       void *data;
17089 +};
17090 +
17091 +extern void chan_interrupt(struct list_head *chans, struct tq_struct *task,
17092 +                          struct tty_struct *tty, int irq, void *dev);
17093 +extern int parse_chan_pair(char *str, struct list_head *chans, int pri, 
17094 +                          int device, struct chan_opts *opts);
17095 +extern int open_chan(struct list_head *chans);
17096 +extern int write_chan(struct list_head *chans, const char *buf, int len,
17097 +                            int write_irq);
17098 +extern int console_write_chan(struct list_head *chans, const char *buf, 
17099 +                             int len);
17100 +extern void close_chan(struct list_head *chans);
17101 +extern void chan_enable_winch(struct list_head *chans, void *line);
17102 +extern void enable_chan(struct list_head *chans, void *data);
17103 +extern int chan_window_size(struct list_head *chans, 
17104 +                            unsigned short *rows_out, 
17105 +                            unsigned short *cols_out);
17106 +extern int chan_out_fd(struct list_head *chans);
17107 +extern int chan_config_string(struct list_head *chans, char *str, int size,
17108 +                             char **error_out);
17109 +
17110 +#endif
17111 +
17112 +/*
17113 + * Overrides for Emacs so that we follow Linus's tabbing style.
17114 + * Emacs will notice this stuff at the end of the file and automatically
17115 + * adjust the settings for this buffer only.  This must remain at the end
17116 + * of the file.
17117 + * ---------------------------------------------------------------------------
17118 + * Local variables:
17119 + * c-file-style: "linux"
17120 + * End:
17121 + */
17122 Index: linux-2.4.29/arch/um/include/chan_user.h
17123 ===================================================================
17124 --- linux-2.4.29.orig/arch/um/include/chan_user.h       1970-01-01 03:00:00.000000000 +0300
17125 +++ linux-2.4.29/arch/um/include/chan_user.h    2005-05-03 22:28:14.295436976 +0300
17126 @@ -0,0 +1,66 @@
17127 +/* 
17128 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
17129 + * Licensed under the GPL
17130 + */
17131 +
17132 +#ifndef __CHAN_USER_H__
17133 +#define __CHAN_USER_H__
17134 +
17135 +#include "init.h"
17136 +
17137 +struct chan_opts {
17138 +       void (*announce)(char *dev_name, int dev);
17139 +       char *xterm_title;
17140 +       int raw;
17141 +       unsigned long tramp_stack;
17142 +       int in_kernel;
17143 +};
17144 +
17145 +enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE };
17146 +
17147 +struct chan_ops {
17148 +       char *type;
17149 +       void *(*init)(char *, int, struct chan_opts *);
17150 +       int (*open)(int, int, int, void *, char **);
17151 +       void (*close)(int, void *);
17152 +       int (*read)(int, char *, void *);
17153 +       int (*write)(int, const char *, int, void *);
17154 +       int (*console_write)(int, const char *, int, void *);
17155 +       int (*window_size)(int, void *, unsigned short *, unsigned short *);
17156 +       void (*free)(void *);
17157 +       int winch;
17158 +};
17159 +
17160 +extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops,
17161 +       xterm_ops;
17162 +
17163 +extern void generic_close(int fd, void *unused);
17164 +extern int generic_read(int fd, char *c_out, void *unused);
17165 +extern int generic_write(int fd, const char *buf, int n, void *unused);
17166 +extern int generic_console_write(int fd, const char *buf, int n, void *state);
17167 +extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
17168 +                              unsigned short *cols_out);
17169 +extern void generic_free(void *data);
17170 +
17171 +extern void register_winch(int fd, void *device_data);
17172 +extern void register_winch_irq(int fd, int tty_fd, int pid, void *line);
17173 +
17174 +#define __channel_help(fn, prefix) \
17175 +__uml_help(fn, prefix "[0-9]*=<channel description>\n" \
17176 +"    Attach a console or serial line to a host channel.  See\n" \
17177 +"    http://user-mode-linux.sourceforge.net/input.html for a complete\n" \
17178 +"    description of this switch.\n\n" \
17179 +);
17180 +
17181 +#endif
17182 +
17183 +/*
17184 + * Overrides for Emacs so that we follow Linus's tabbing style.
17185 + * Emacs will notice this stuff at the end of the file and automatically
17186 + * adjust the settings for this buffer only.  This must remain at the end
17187 + * of the file.
17188 + * ---------------------------------------------------------------------------
17189 + * Local variables:
17190 + * c-file-style: "linux"
17191 + * End:
17192 + */
17193 Index: linux-2.4.29/arch/um/include/choose-mode.h
17194 ===================================================================
17195 --- linux-2.4.29.orig/arch/um/include/choose-mode.h     1970-01-01 03:00:00.000000000 +0300
17196 +++ linux-2.4.29/arch/um/include/choose-mode.h  2005-05-03 22:28:14.295436976 +0300
17197 @@ -0,0 +1,35 @@
17198 +/* 
17199 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17200 + * Licensed under the GPL
17201 + */
17202 +
17203 +#ifndef __CHOOSE_MODE_H__
17204 +#define __CHOOSE_MODE_H__
17205 +
17206 +#include "uml-config.h"
17207 +
17208 +#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS)
17209 +#define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas))
17210 +
17211 +#elif defined(UML_CONFIG_MODE_SKAS)
17212 +#define CHOOSE_MODE(tt, skas) (skas)
17213 +
17214 +#elif defined(UML_CONFIG_MODE_TT)
17215 +#define CHOOSE_MODE(tt, skas) (tt)
17216 +#endif
17217 +
17218 +#define CHOOSE_MODE_PROC(tt, skas, args...) \
17219 +       CHOOSE_MODE(tt(args), skas(args))
17220 +
17221 +#endif
17222 +
17223 +/*
17224 + * Overrides for Emacs so that we follow Linus's tabbing style.
17225 + * Emacs will notice this stuff at the end of the file and automatically
17226 + * adjust the settings for this buffer only.  This must remain at the end
17227 + * of the file.
17228 + * ---------------------------------------------------------------------------
17229 + * Local variables:
17230 + * c-file-style: "linux"
17231 + * End:
17232 + */
17233 Index: linux-2.4.29/arch/um/include/filehandle.h
17234 ===================================================================
17235 --- linux-2.4.29.orig/arch/um/include/filehandle.h      1970-01-01 03:00:00.000000000 +0300
17236 +++ linux-2.4.29/arch/um/include/filehandle.h   2005-05-03 22:28:14.296436824 +0300
17237 @@ -0,0 +1,51 @@
17238 +/* 
17239 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
17240 + * Licensed under the GPL
17241 + */
17242 +
17243 +#ifndef __FILEHANDLE_H__
17244 +#define __FILEHANDLE_H__
17245 +
17246 +#include "linux/list.h"
17247 +#include "linux/fs.h"
17248 +#include "os.h"
17249 +
17250 +struct file_handle {
17251 +       struct list_head list;
17252 +       int fd;
17253 +       char *(*get_name)(struct inode *);
17254 +       struct inode *inode;
17255 +       struct openflags flags;
17256 +};
17257 +
17258 +extern struct file_handle bad_filehandle;
17259 +
17260 +extern int open_file(char *name, struct openflags flags, int mode);
17261 +extern void *open_dir(char *file);
17262 +extern int open_filehandle(char *name, struct openflags flags, int mode, 
17263 +                          struct file_handle *fh);
17264 +extern int read_file(struct file_handle *fh, unsigned long long offset, 
17265 +                    char *buf, int len);
17266 +extern int write_file(struct file_handle *fh, unsigned long long offset, 
17267 +                     const char *buf, int len);
17268 +extern int truncate_file(struct file_handle *fh, unsigned long long size);
17269 +extern int close_file(struct file_handle *fh);
17270 +extern void not_reclaimable(struct file_handle *fh);
17271 +extern void is_reclaimable(struct file_handle *fh, 
17272 +                          char *(name_proc)(struct inode *),
17273 +                          struct inode *inode);
17274 +extern int filehandle_fd(struct file_handle *fh);
17275 +extern int make_pipe(struct file_handle *fhs);
17276 +
17277 +#endif
17278 +
17279 +/*
17280 + * Overrides for Emacs so that we follow Linus's tabbing style.
17281 + * Emacs will notice this stuff at the end of the file and automatically
17282 + * adjust the settings for this buffer only.  This must remain at the end
17283 + * of the file.
17284 + * ---------------------------------------------------------------------------
17285 + * Local variables:
17286 + * c-file-style: "linux"
17287 + * End:
17288 + */
17289 Index: linux-2.4.29/arch/um/include/frame.h
17290 ===================================================================
17291 --- linux-2.4.29.orig/arch/um/include/frame.h   1970-01-01 03:00:00.000000000 +0300
17292 +++ linux-2.4.29/arch/um/include/frame.h        2005-05-03 22:28:14.297436672 +0300
17293 @@ -0,0 +1,53 @@
17294 +/* 
17295 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17296 + * Licensed under the GPL
17297 + */
17298 +
17299 +#ifndef __FRAME_H_
17300 +#define __FRAME_H_
17301 +
17302 +#include "sysdep/frame.h"
17303 +
17304 +struct frame_common {
17305 +       void *data;
17306 +       int len;
17307 +       int sig_index;
17308 +       int sr_index;
17309 +       int sr_relative;
17310 +       int sp_index;
17311 +       struct arch_frame_data arch;
17312 +};
17313 +
17314 +struct sc_frame {
17315 +       struct frame_common common;
17316 +       int sc_index;
17317 +};
17318 +
17319 +extern struct sc_frame signal_frame_sc;
17320 +
17321 +extern struct sc_frame signal_frame_sc_sr;
17322 +
17323 +struct si_frame {
17324 +       struct frame_common common;
17325 +       int sip_index;
17326 +       int si_index;
17327 +       int ucp_index;
17328 +       int uc_index;
17329 +};
17330 +
17331 +extern struct si_frame signal_frame_si;
17332 +
17333 +extern void capture_signal_stack(void);
17334 +
17335 +#endif
17336 +
17337 +/*
17338 + * Overrides for Emacs so that we follow Linus's tabbing style.
17339 + * Emacs will notice this stuff at the end of the file and automatically
17340 + * adjust the settings for this buffer only.  This must remain at the end
17341 + * of the file.
17342 + * ---------------------------------------------------------------------------
17343 + * Local variables:
17344 + * c-file-style: "linux"
17345 + * End:
17346 + */
17347 Index: linux-2.4.29/arch/um/include/frame_kern.h
17348 ===================================================================
17349 --- linux-2.4.29.orig/arch/um/include/frame_kern.h      1970-01-01 03:00:00.000000000 +0300
17350 +++ linux-2.4.29/arch/um/include/frame_kern.h   2005-05-03 22:28:14.298436520 +0300
17351 @@ -0,0 +1,34 @@
17352 +/* 
17353 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17354 + * Licensed under the GPL
17355 + */
17356 +
17357 +#ifndef __FRAME_KERN_H_
17358 +#define __FRAME_KERN_H_
17359 +
17360 +#include "frame.h"
17361 +#include "sysdep/frame_kern.h"
17362 +
17363 +extern int setup_signal_stack_sc(unsigned long stack_top, int sig, 
17364 +                                unsigned long handler,
17365 +                                void (*restorer)(void), 
17366 +                                struct pt_regs *regs, 
17367 +                                sigset_t *mask);
17368 +extern int setup_signal_stack_si(unsigned long stack_top, int sig, 
17369 +                                unsigned long handler, 
17370 +                                void (*restorer)(void), 
17371 +                                struct pt_regs *regs, siginfo_t *info, 
17372 +                                sigset_t *mask);
17373 +
17374 +#endif
17375 +
17376 +/*
17377 + * Overrides for Emacs so that we follow Linus's tabbing style.
17378 + * Emacs will notice this stuff at the end of the file and automatically
17379 + * adjust the settings for this buffer only.  This must remain at the end
17380 + * of the file.
17381 + * ---------------------------------------------------------------------------
17382 + * Local variables:
17383 + * c-file-style: "linux"
17384 + * End:
17385 + */
17386 Index: linux-2.4.29/arch/um/include/frame_user.h
17387 ===================================================================
17388 --- linux-2.4.29.orig/arch/um/include/frame_user.h      1970-01-01 03:00:00.000000000 +0300
17389 +++ linux-2.4.29/arch/um/include/frame_user.h   2005-05-03 22:28:14.299436368 +0300
17390 @@ -0,0 +1,23 @@
17391 +/* 
17392 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17393 + * Licensed under the GPL
17394 + */
17395 +
17396 +#ifndef __FRAME_USER_H_
17397 +#define __FRAME_USER_H_
17398 +
17399 +#include "sysdep/frame_user.h"
17400 +#include "frame.h"
17401 +
17402 +#endif
17403 +
17404 +/*
17405 + * Overrides for Emacs so that we follow Linus's tabbing style.
17406 + * Emacs will notice this stuff at the end of the file and automatically
17407 + * adjust the settings for this buffer only.  This must remain at the end
17408 + * of the file.
17409 + * ---------------------------------------------------------------------------
17410 + * Local variables:
17411 + * c-file-style: "linux"
17412 + * End:
17413 + */
17414 Index: linux-2.4.29/arch/um/include/helper.h
17415 ===================================================================
17416 --- linux-2.4.29.orig/arch/um/include/helper.h  1970-01-01 03:00:00.000000000 +0300
17417 +++ linux-2.4.29/arch/um/include/helper.h       2005-05-03 22:28:14.300436216 +0300
17418 @@ -0,0 +1,27 @@
17419 +/* 
17420 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17421 + * Licensed under the GPL
17422 + */
17423 +
17424 +#ifndef __HELPER_H__
17425 +#define __HELPER_H__
17426 +
17427 +extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
17428 +                     unsigned long *stack_out);
17429 +extern int run_helper_thread(int (*proc)(void *), void *arg, 
17430 +                            unsigned int flags, unsigned long *stack_out,
17431 +                            int stack_order);
17432 +extern int helper_wait(int pid);
17433 +
17434 +#endif
17435 +
17436 +/*
17437 + * Overrides for Emacs so that we follow Linus's tabbing style.
17438 + * Emacs will notice this stuff at the end of the file and automatically
17439 + * adjust the settings for this buffer only.  This must remain at the end
17440 + * of the file.
17441 + * ---------------------------------------------------------------------------
17442 + * Local variables:
17443 + * c-file-style: "linux"
17444 + * End:
17445 + */
17446 Index: linux-2.4.29/arch/um/include/init.h
17447 ===================================================================
17448 --- linux-2.4.29.orig/arch/um/include/init.h    1970-01-01 03:00:00.000000000 +0300
17449 +++ linux-2.4.29/arch/um/include/init.h 2005-05-03 22:28:14.301436064 +0300
17450 @@ -0,0 +1,124 @@
17451 +#ifndef _LINUX_UML_INIT_H
17452 +#define _LINUX_UML_INIT_H
17453 +
17454 +/* These macros are used to mark some functions or
17455 + * initialized data (doesn't apply to uninitialized data)
17456 + * as `initialization' functions. The kernel can take this
17457 + * as hint that the function is used only during the initialization
17458 + * phase and free up used memory resources after
17459 + *
17460 + * Usage:
17461 + * For functions:
17462 + *
17463 + * You should add __init immediately before the function name, like:
17464 + *
17465 + * static void __init initme(int x, int y)
17466 + * {
17467 + *    extern int z; z = x * y;
17468 + * }
17469 + *
17470 + * If the function has a prototype somewhere, you can also add
17471 + * __init between closing brace of the prototype and semicolon:
17472 + *
17473 + * extern int initialize_foobar_device(int, int, int) __init;
17474 + *
17475 + * For initialized data:
17476 + * You should insert __initdata between the variable name and equal
17477 + * sign followed by value, e.g.:
17478 + *
17479 + * static int init_variable __initdata = 0;
17480 + * static char linux_logo[] __initdata = { 0x32, 0x36, ... };
17481 + *
17482 + * Don't forget to initialize data not at file scope, i.e. within a function,
17483 + * as gcc otherwise puts the data into the bss section and not into the init
17484 + * section.
17485 + *
17486 + * Also note, that this data cannot be "const".
17487 + */
17488 +
17489 +#ifndef _LINUX_INIT_H
17490 +typedef int (*initcall_t)(void);
17491 +typedef void (*exitcall_t)(void);
17492 +
17493 +#define __init          __attribute__ ((__section__ (".text.init")))
17494 +#define __exit          __attribute__ ((unused, __section__(".text.exit")))
17495 +#define __initdata      __attribute__ ((__section__ (".data.init")))
17496 +
17497 +#endif
17498 +
17499 +#ifndef MODULE
17500 +struct uml_param {
17501 +        const char *str;
17502 +        int (*setup_func)(char *, int *);
17503 +};
17504 +
17505 +extern initcall_t __uml_initcall_start, __uml_initcall_end;
17506 +extern initcall_t __uml_postsetup_start, __uml_postsetup_end;
17507 +extern const char *__uml_help_start, *__uml_help_end;
17508 +#endif
17509 +
17510 +#define __uml_initcall(fn)                                             \
17511 +       static initcall_t __uml_initcall_##fn __uml_init_call = fn
17512 +
17513 +#define __uml_exitcall(fn)                                             \
17514 +       static exitcall_t __uml_exitcall_##fn __uml_exit_call = fn
17515 +
17516 +extern struct uml_param __uml_setup_start, __uml_setup_end;
17517 +
17518 +#define __uml_postsetup(fn)                                            \
17519 +       static initcall_t __uml_postsetup_##fn __uml_postsetup_call = fn
17520 +
17521 +#define __non_empty_string(dummyname,string)                           \
17522 +       struct __uml_non_empty_string_struct_##dummyname                \
17523 +       {                                                               \
17524 +               char _string[sizeof(string)-2];                         \
17525 +       }
17526 +
17527 +#ifndef MODULE
17528 +#define __uml_setup(str, fn, help...)                                  \
17529 +       __non_empty_string(fn ##_setup, str);                           \
17530 +       __uml_help(fn, help);                                           \
17531 +       static char __uml_setup_str_##fn[] __initdata = str;            \
17532 +       static struct uml_param __uml_setup_##fn __uml_init_setup = { __uml_setup_str_##fn, fn }
17533 +#else
17534 +#define __uml_setup(str, fn, help...)                                  \
17535 +
17536 +#endif
17537 +
17538 +#define __uml_help(fn, help...)                                                \
17539 +       __non_empty_string(fn ##__help, help);                          \
17540 +       static char __uml_help_str_##fn[] __initdata = help;            \
17541 +       static const char *__uml_help_##fn __uml_setup_help = __uml_help_str_##fn
17542 +
17543 +/*
17544 + * Mark functions and data as being only used at initialization
17545 + * or exit time.
17546 + */
17547 +#define __uml_init_setup       __attribute__ ((unused,__section__ (".uml.setup.init")))
17548 +#define __uml_setup_help       __attribute__ ((unused,__section__ (".uml.help.init")))
17549 +#define __uml_init_call                __attribute__ ((unused,__section__ (".uml.initcall.init")))
17550 +#define __uml_postsetup_call   __attribute__ ((unused,__section__ (".uml.postsetup.init")))
17551 +#define __uml_exit_call                __attribute__ ((unused,__section__ (".uml.exitcall.exit")))
17552 +
17553 +#ifndef __KERNEL__
17554 +
17555 +#define __initcall(fn) static initcall_t __initcall_##fn __init_call = fn
17556 +#define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn
17557 +
17558 +#define __init_call __attribute__ ((unused,__section__ (".initcall.init")))
17559 +#define __exit_call __attribute__ ((unused,__section__ (".exitcall.exit")))
17560 +
17561 +#endif
17562 +
17563 +#endif /* _LINUX_UML_INIT_H */
17564 +
17565 +/*
17566 + * Overrides for Emacs so that we follow Linus's tabbing style.
17567 + * Emacs will notice this stuff at the end of the file and automatically
17568 + * adjust the settings for this buffer only.  This must remain at the end
17569 + * of the file.
17570 + * ---------------------------------------------------------------------------
17571 + * Local variables:
17572 + * c-file-style: "linux"
17573 + * End:
17574 + */
17575 Index: linux-2.4.29/arch/um/include/initrd.h
17576 ===================================================================
17577 --- linux-2.4.29.orig/arch/um/include/initrd.h  1970-01-01 03:00:00.000000000 +0300
17578 +++ linux-2.4.29/arch/um/include/initrd.h       2005-05-03 22:28:14.301436064 +0300
17579 @@ -0,0 +1,22 @@
17580 +/*
17581 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17582 + * Licensed under the GPL
17583 + */
17584 +
17585 +#ifndef __INITRD_USER_H__
17586 +#define __INITRD_USER_H__
17587 +
17588 +extern int load_initrd(char *filename, void *buf, int size);
17589 +
17590 +#endif
17591 +
17592 +/*
17593 + * Overrides for Emacs so that we follow Linus's tabbing style.
17594 + * Emacs will notice this stuff at the end of the file and automatically
17595 + * adjust the settings for this buffer only.  This must remain at the end
17596 + * of the file.
17597 + * ---------------------------------------------------------------------------
17598 + * Local variables:
17599 + * c-file-style: "linux"
17600 + * End:
17601 + */
17602 Index: linux-2.4.29/arch/um/include/irq_kern.h
17603 ===================================================================
17604 --- linux-2.4.29.orig/arch/um/include/irq_kern.h        1970-01-01 03:00:00.000000000 +0300
17605 +++ linux-2.4.29/arch/um/include/irq_kern.h     2005-05-03 22:28:14.303435760 +0300
17606 @@ -0,0 +1,27 @@
17607 +/* 
17608 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17609 + * Licensed under the GPL
17610 + */
17611 +
17612 +#ifndef __IRQ_KERN_H__
17613 +#define __IRQ_KERN_H__
17614 +
17615 +#include "linux/interrupt.h"
17616 +
17617 +extern int um_request_irq(unsigned int irq, int fd, int type,
17618 +                         void (*handler)(int, void *, struct pt_regs *),
17619 +                         unsigned long irqflags,  const char * devname,
17620 +                         void *dev_id);
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 Index: linux-2.4.29/arch/um/include/irq_user.h
17635 ===================================================================
17636 --- linux-2.4.29.orig/arch/um/include/irq_user.h        1970-01-01 03:00:00.000000000 +0300
17637 +++ linux-2.4.29/arch/um/include/irq_user.h     2005-05-03 22:28:14.304435608 +0300
17638 @@ -0,0 +1,36 @@
17639 +/* 
17640 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17641 + * Licensed under the GPL
17642 + */
17643 +
17644 +#ifndef __IRQ_USER_H__
17645 +#define __IRQ_USER_H__
17646 +
17647 +enum { IRQ_READ, IRQ_WRITE };
17648 +
17649 +extern void sigio_handler(int sig, union uml_pt_regs *regs);
17650 +extern int activate_fd(int irq, int fd, int type, void *dev_id);
17651 +extern void free_irq_by_irq_and_dev(int irq, void *dev_id);
17652 +extern void free_irq_by_fd(int fd);
17653 +extern void reactivate_fd(int fd, int irqnum);
17654 +extern void deactivate_fd(int fd, int irqnum);
17655 +extern int deactivate_all_fds(void);
17656 +extern void forward_interrupts(int pid);
17657 +extern void init_irq_signals(int on_sigstack);
17658 +extern void forward_ipi(int fd, int pid);
17659 +extern void free_irq_later(int irq, void *dev_id);
17660 +extern int activate_ipi(int fd, int pid);
17661 +extern unsigned long irq_lock(void);
17662 +extern void irq_unlock(unsigned long flags);
17663 +#endif
17664 +
17665 +/*
17666 + * Overrides for Emacs so that we follow Linus's tabbing style.
17667 + * Emacs will notice this stuff at the end of the file and automatically
17668 + * adjust the settings for this buffer only.  This must remain at the end
17669 + * of the file.
17670 + * ---------------------------------------------------------------------------
17671 + * Local variables:
17672 + * c-file-style: "linux"
17673 + * End:
17674 + */
17675 Index: linux-2.4.29/arch/um/include/kern.h
17676 ===================================================================
17677 --- linux-2.4.29.orig/arch/um/include/kern.h    1970-01-01 03:00:00.000000000 +0300
17678 +++ linux-2.4.29/arch/um/include/kern.h 2005-05-03 22:28:14.304435608 +0300
17679 @@ -0,0 +1,48 @@
17680 +/* 
17681 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17682 + * Licensed under the GPL
17683 + */
17684 +
17685 +#ifndef __KERN_H__
17686 +#define __KERN_H__
17687 +
17688 +/* These are all user-mode things which are convenient to call directly
17689 + * from kernel code and for which writing a wrapper is too much of a pain.
17690 + * The regular include files can't be included because this file is included
17691 + * only into kernel code, and user-space includes conflict with kernel
17692 + * includes.
17693 + */
17694 +
17695 +extern int errno;
17696 +
17697 +extern int clone(int (*proc)(void *), void *sp, int flags, void *data);
17698 +extern int sleep(int);
17699 +extern int printf(char *fmt, ...);
17700 +extern char *strerror(int errnum);
17701 +extern char *ptsname(int __fd);
17702 +extern int munmap(void *, int);
17703 +extern void *sbrk(int increment);
17704 +extern void *malloc(int size);
17705 +extern void perror(char *err);
17706 +extern int kill(int pid, int sig);
17707 +extern int getuid(void);
17708 +extern int pause(void);
17709 +extern int write(int, const void *, int);
17710 +extern int exit(int);
17711 +extern int close(int);
17712 +extern int read(unsigned int, char *, int);
17713 +extern int pipe(int *);
17714 +extern int sched_yield(void);
17715 +extern int ptrace(int op, int pid, long addr, long data);
17716 +#endif
17717 +
17718 +/*
17719 + * Overrides for Emacs so that we follow Linus's tabbing style.
17720 + * Emacs will notice this stuff at the end of the file and automatically
17721 + * adjust the settings for this buffer only.  This must remain at the end
17722 + * of the file.
17723 + * ---------------------------------------------------------------------------
17724 + * Local variables:
17725 + * c-file-style: "linux"
17726 + * End:
17727 + */
17728 Index: linux-2.4.29/arch/um/include/kern_util.h
17729 ===================================================================
17730 --- linux-2.4.29.orig/arch/um/include/kern_util.h       1970-01-01 03:00:00.000000000 +0300
17731 +++ linux-2.4.29/arch/um/include/kern_util.h    2005-05-03 22:28:14.306435304 +0300
17732 @@ -0,0 +1,123 @@
17733 +/* 
17734 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
17735 + * Licensed under the GPL
17736 + */
17737 +
17738 +#ifndef __KERN_UTIL_H__
17739 +#define __KERN_UTIL_H__
17740 +
17741 +#include "sysdep/ptrace.h"
17742 +
17743 +extern int ncpus;
17744 +extern char *linux_prog;
17745 +extern char *gdb_init;
17746 +extern int kmalloc_ok;
17747 +extern int timer_irq_inited;
17748 +extern int jail;
17749 +extern int nsyscalls;
17750 +
17751 +#define UML_ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK))
17752 +#define UML_ROUND_UP(addr) \
17753 +       UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
17754 +
17755 +extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg);
17756 +extern unsigned long stack_sp(unsigned long page);
17757 +extern int kernel_thread_proc(void *data);
17758 +extern void syscall_segv(int sig);
17759 +extern int current_pid(void);
17760 +extern unsigned long alloc_stack(int order, int atomic);
17761 +extern int do_signal(int error);
17762 +extern int is_stack_fault(unsigned long sp);
17763 +extern unsigned long segv(unsigned long address, unsigned long ip, 
17764 +                         int is_write, int is_user, void *sc);
17765 +extern unsigned long handle_page_fault(unsigned long address, unsigned long ip,
17766 +                                      int is_write, int is_user, 
17767 +                                      int *code_out);
17768 +extern void syscall_ready(void);
17769 +extern int segv_syscall(void);
17770 +extern void kern_finish_exec(void *task, int new_pid, unsigned long stack);
17771 +extern int page_size(void);
17772 +extern int page_mask(void);
17773 +extern int need_finish_fork(void);
17774 +extern void free_stack(unsigned long stack, int order);
17775 +extern void add_input_request(int op, void (*proc)(int), void *arg);
17776 +extern int sys_execve(char *file, char **argv, char **env);
17777 +extern char *current_cmd(void);
17778 +extern void timer_handler(int sig, union uml_pt_regs *regs);
17779 +extern int set_signals(int enable);
17780 +extern void force_sigbus(void);
17781 +extern int pid_to_processor_id(int pid);
17782 +extern void block_signals(void);
17783 +extern void unblock_signals(void);
17784 +extern void deliver_signals(void *t);
17785 +extern int next_syscall_index(int max);
17786 +extern int next_trap_index(int max);
17787 +extern void cpu_idle(void);
17788 +extern void finish_fork(void);
17789 +extern void paging_init(void);
17790 +extern void init_flush_vm(void);
17791 +extern void *syscall_sp(void *t);
17792 +extern void syscall_trace(void);
17793 +extern int hz(void);
17794 +extern void idle_timer(void);
17795 +extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
17796 +extern int external_pid(void *t);
17797 +extern void boot_timer_handler(int sig);
17798 +extern void interrupt_end(void);
17799 +extern void initial_thread_cb(void (*proc)(void *), void *arg);
17800 +extern int debugger_signal(int status, int pid);
17801 +extern void debugger_parent_signal(int status, int pid);
17802 +extern void child_signal(int pid, int status);
17803 +extern int init_ptrace_proxy(int idle_pid, int startup, int stop);
17804 +extern int init_parent_proxy(int pid);
17805 +extern void check_stack_overflow(void *ptr);
17806 +extern void relay_signal(int sig, union uml_pt_regs *regs);
17807 +extern void not_implemented(void);
17808 +extern int user_context(unsigned long sp);
17809 +extern void timer_irq(union uml_pt_regs *regs);
17810 +extern void unprotect_stack(unsigned long stack);
17811 +extern void do_uml_exitcalls(void);
17812 +extern int attach_debugger(int idle_pid, int pid, int stop);
17813 +extern void bad_segv(unsigned long address, unsigned long ip, int is_write);
17814 +extern int config_gdb(char *str);
17815 +extern int remove_gdb(void);
17816 +extern char *uml_strdup(char *string);
17817 +extern void unprotect_kernel_mem(void);
17818 +extern void protect_kernel_mem(void);
17819 +extern void set_kmem_end(unsigned long);
17820 +extern void uml_cleanup(void);
17821 +extern void set_current(void *t);
17822 +extern void lock_signalled_task(void *t);
17823 +extern void IPI_handler(int cpu);
17824 +extern int jail_setup(char *line, int *add);
17825 +extern void *get_init_task(void);
17826 +extern int clear_user_proc(void *buf, int size);
17827 +extern int copy_to_user_proc(void *to, void *from, int size);
17828 +extern int copy_from_user_proc(void *to, void *from, int size);
17829 +extern int strlen_user_proc(char *str);
17830 +extern void bus_handler(int sig, union uml_pt_regs *regs);
17831 +extern void winch(int sig, union uml_pt_regs *regs);
17832 +extern long execute_syscall(void *r);
17833 +extern int smp_sigio_handler(void);
17834 +extern void *get_current(void);
17835 +extern struct task_struct *get_task(int pid, int require);
17836 +extern void machine_halt(void);
17837 +extern int is_syscall(unsigned long addr);
17838 +extern void arch_switch(void);
17839 +extern void free_irq(unsigned int, void *);
17840 +extern int um_in_interrupt(void);
17841 +extern int cpu(void);
17842 +extern unsigned long long time_stamp(void);
17843 +
17844 +#endif
17845 +
17846 +/*
17847 + * Overrides for Emacs so that we follow Linus's tabbing style.
17848 + * Emacs will notice this stuff at the end of the file and automatically
17849 + * adjust the settings for this buffer only.  This must remain at the end
17850 + * of the file.
17851 + * ---------------------------------------------------------------------------
17852 + * Local variables:
17853 + * c-file-style: "linux"
17854 + * End:
17855 + */
17856 Index: linux-2.4.29/arch/um/include/line.h
17857 ===================================================================
17858 --- linux-2.4.29.orig/arch/um/include/line.h    1970-01-01 03:00:00.000000000 +0300
17859 +++ linux-2.4.29/arch/um/include/line.h 2005-05-03 22:28:14.307435152 +0300
17860 @@ -0,0 +1,103 @@
17861 +/* 
17862 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17863 + * Licensed under the GPL
17864 + */
17865 +
17866 +#ifndef __LINE_H__
17867 +#define __LINE_H__
17868 +
17869 +#include "linux/list.h"
17870 +#include "linux/tqueue.h"
17871 +#include "linux/tty.h"
17872 +#include "asm/semaphore.h"
17873 +#include "chan_user.h"
17874 +#include "mconsole_kern.h"
17875 +
17876 +struct line_driver {
17877 +       char *name;
17878 +       char *devfs_name;
17879 +       short major;
17880 +       short minor_start;
17881 +       short type;
17882 +       short subtype;
17883 +       int read_irq;
17884 +       char *read_irq_name;
17885 +       int write_irq;
17886 +       char *write_irq_name;
17887 +       char *symlink_from;
17888 +       char *symlink_to;
17889 +       struct mc_device mc;
17890 +};
17891 +
17892 +struct line {
17893 +       char *init_str;
17894 +       int init_pri;
17895 +       struct list_head chan_list;
17896 +       int valid;
17897 +       int count;
17898 +       struct tty_struct *tty;
17899 +       struct semaphore sem;
17900 +       char *buffer;
17901 +       char *head;
17902 +       char *tail;
17903 +       int sigio;
17904 +       struct tq_struct task;
17905 +       struct line_driver *driver;
17906 +       int have_irq;
17907 +};
17908 +
17909 +#define LINE_INIT(str, d) \
17910 +       { init_str :    str, \
17911 +         init_pri :    INIT_STATIC, \
17912 +         chan_list :   { }, \
17913 +         valid :       1, \
17914 +         count :       0, \
17915 +         tty :         NULL, \
17916 +         sem :         { }, \
17917 +         buffer :      NULL, \
17918 +         head :        NULL, \
17919 +         tail :        NULL, \
17920 +         sigio :       0, \
17921 +         driver :      d, \
17922 +          have_irq :   0 }
17923 +
17924 +struct lines {
17925 +       int num;
17926 +};
17927 +
17928 +#define LINES_INIT(n) {  num :         n }
17929 +
17930 +extern void line_close(struct line *lines, struct tty_struct *tty);
17931 +extern int line_open(struct line *lines, struct tty_struct *tty, 
17932 +                    struct chan_opts *opts);
17933 +extern int line_setup(struct line *lines, int num, char *init, 
17934 +                     int all_allowed);
17935 +extern int line_write(struct line *line, struct tty_struct *tty, int from_user,
17936 +                     const char *buf, int len);
17937 +extern char *add_xterm_umid(char *base);
17938 +extern int line_setup_irq(int fd, int input, int output, void *data);
17939 +extern void line_close_chan(struct line *line);
17940 +extern void line_disable(struct line *line, int current_irq);
17941 +extern void line_register_devfs(struct lines *set, 
17942 +                               struct line_driver *line_driver, 
17943 +                               struct tty_driver *driver, struct line *lines,
17944 +                               int nlines);
17945 +extern void lines_init(struct line *lines, int nlines);
17946 +extern void close_lines(struct line *lines, int nlines);
17947 +extern int line_config(struct line *lines, int num, char *str);
17948 +extern int line_remove(struct line *lines, int num, char *str);
17949 +extern int line_get_config(char *dev, struct line *lines, int num, char *str, 
17950 +                          int size, char **error_out);
17951 +
17952 +#endif
17953 +
17954 +/*
17955 + * Overrides for Emacs so that we follow Linus's tabbing style.
17956 + * Emacs will notice this stuff at the end of the file and automatically
17957 + * adjust the settings for this buffer only.  This must remain at the end
17958 + * of the file.
17959 + * ---------------------------------------------------------------------------
17960 + * Local variables:
17961 + * c-file-style: "linux"
17962 + * End:
17963 + */
17964 Index: linux-2.4.29/arch/um/include/Makefile
17965 ===================================================================
17966 --- linux-2.4.29.orig/arch/um/include/Makefile  1970-01-01 03:00:00.000000000 +0300
17967 +++ linux-2.4.29/arch/um/include/Makefile       2005-05-03 22:28:14.000000000 +0300
17968 @@ -0,0 +1,7 @@
17969 +all : sc.h
17970 +
17971 +sc.h : ../util/mk_sc
17972 +       ../util/mk_sc > $@
17973 +
17974 +../util/mk_sc :
17975 +       $(MAKE) -C ../util mk_sc
17976 Index: linux-2.4.29/arch/um/include/mconsole.h
17977 ===================================================================
17978 --- linux-2.4.29.orig/arch/um/include/mconsole.h        1970-01-01 03:00:00.000000000 +0300
17979 +++ linux-2.4.29/arch/um/include/mconsole.h     2005-05-03 22:28:14.309434848 +0300
17980 @@ -0,0 +1,103 @@
17981 +/*
17982 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
17983 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17984 + * Licensed under the GPL
17985 + */
17986 +
17987 +#ifndef __MCONSOLE_H__
17988 +#define __MCONSOLE_H__
17989 +
17990 +#ifndef __KERNEL__
17991 +#include <stdint.h>
17992 +#define u32 uint32_t
17993 +#endif
17994 +
17995 +#define MCONSOLE_MAGIC (0xcafebabe)
17996 +#define MCONSOLE_MAX_DATA (512)
17997 +#define MCONSOLE_VERSION 2
17998 +
17999 +struct mconsole_request {
18000 +       u32 magic;
18001 +       u32 version;
18002 +       u32 len;
18003 +       char data[MCONSOLE_MAX_DATA];
18004 +};
18005 +
18006 +struct mconsole_reply {
18007 +       u32 err;
18008 +       u32 more;
18009 +       u32 len;
18010 +       char data[MCONSOLE_MAX_DATA];
18011 +};
18012 +
18013 +struct mconsole_notify {
18014 +       u32 magic;
18015 +       u32 version;    
18016 +       enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
18017 +              MCONSOLE_USER_NOTIFY } type;
18018 +       u32 len;
18019 +       char data[MCONSOLE_MAX_DATA];
18020 +};
18021 +
18022 +struct mc_request;
18023 +
18024 +enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
18025 +
18026 +struct mconsole_command
18027 +{
18028 +       char *command;
18029 +       void (*handler)(struct mc_request *req);
18030 +       enum mc_context context;
18031 +};
18032 +
18033 +struct mc_request
18034 +{
18035 +       int len;
18036 +       int as_interrupt;
18037 +
18038 +       int originating_fd;
18039 +       int originlen;
18040 +       unsigned char origin[128];                      /* sockaddr_un */
18041 +
18042 +       struct mconsole_request request;
18043 +       struct mconsole_command *cmd;
18044 +};
18045 +
18046 +extern char mconsole_socket_name[];
18047 +
18048 +extern int mconsole_unlink_socket(void);
18049 +extern int mconsole_reply(struct mc_request *req, char *reply, int err,
18050 +                         int more);
18051 +
18052 +extern void mconsole_version(struct mc_request *req);
18053 +extern void mconsole_help(struct mc_request *req);
18054 +extern void mconsole_halt(struct mc_request *req);
18055 +extern void mconsole_reboot(struct mc_request *req);
18056 +extern void mconsole_config(struct mc_request *req);
18057 +extern void mconsole_remove(struct mc_request *req);
18058 +extern void mconsole_sysrq(struct mc_request *req);
18059 +extern void mconsole_cad(struct mc_request *req);
18060 +extern void mconsole_stop(struct mc_request *req);
18061 +extern void mconsole_go(struct mc_request *req);
18062 +extern void mconsole_log(struct mc_request *req);
18063 +extern void mconsole_proc(struct mc_request *req);
18064 +
18065 +extern int mconsole_get_request(int fd, struct mc_request *req);
18066 +extern int mconsole_notify(char *sock_name, int type, const void *data, 
18067 +                          int len);
18068 +extern char *mconsole_notify_socket(void);
18069 +extern void lock_notify(void);
18070 +extern void unlock_notify(void);
18071 +
18072 +#endif
18073 +
18074 +/*
18075 + * Overrides for Emacs so that we follow Linus's tabbing style.
18076 + * Emacs will notice this stuff at the end of the file and automatically
18077 + * adjust the settings for this buffer only.  This must remain at the end
18078 + * of the file.
18079 + * ---------------------------------------------------------------------------
18080 + * Local variables:
18081 + * c-file-style: "linux"
18082 + * End:
18083 + */
18084 Index: linux-2.4.29/arch/um/include/mconsole_kern.h
18085 ===================================================================
18086 --- linux-2.4.29.orig/arch/um/include/mconsole_kern.h   1970-01-01 03:00:00.000000000 +0300
18087 +++ linux-2.4.29/arch/um/include/mconsole_kern.h        2005-05-03 22:28:14.310434696 +0300
18088 @@ -0,0 +1,62 @@
18089 +/*
18090 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
18091 + * Licensed under the GPL
18092 + */
18093 +
18094 +#ifndef __MCONSOLE_KERN_H__
18095 +#define __MCONSOLE_KERN_H__
18096 +
18097 +#include "linux/config.h"
18098 +#include "linux/list.h"
18099 +#include "mconsole.h"
18100 +
18101 +struct mconsole_entry {
18102 +       struct list_head list;
18103 +       struct mc_request request;
18104 +};
18105 +
18106 +struct mc_device {
18107 +       struct list_head list;
18108 +       char *name;
18109 +       int (*config)(char *);
18110 +       int (*get_config)(char *, char *, int, char **);
18111 +       int (*remove)(char *);
18112 +};
18113 +
18114 +#define CONFIG_CHUNK(str, size, current, chunk, end) \
18115 +do { \
18116 +       current += strlen(chunk); \
18117 +       if(current >= size) \
18118 +               str = NULL; \
18119 +       if(str != NULL){ \
18120 +               strcpy(str, chunk); \
18121 +               str += strlen(chunk); \
18122 +       } \
18123 +       if(end) \
18124 +               current++; \
18125 +} while(0)
18126 +
18127 +#ifdef CONFIG_MCONSOLE
18128 +
18129 +extern void mconsole_register_dev(struct mc_device *new);
18130 +
18131 +#else
18132 +
18133 +static inline void mconsole_register_dev(struct mc_device *new)
18134 +{
18135 +}
18136 +
18137 +#endif
18138 +
18139 +#endif
18140 +
18141 +/*
18142 + * Overrides for Emacs so that we follow Linus's tabbing style.
18143 + * Emacs will notice this stuff at the end of the file and automatically
18144 + * adjust the settings for this buffer only.  This must remain at the end
18145 + * of the file.
18146 + * ---------------------------------------------------------------------------
18147 + * Local variables:
18148 + * c-file-style: "linux"
18149 + * End:
18150 + */
18151 Index: linux-2.4.29/arch/um/include/mem.h
18152 ===================================================================
18153 --- linux-2.4.29.orig/arch/um/include/mem.h     1970-01-01 03:00:00.000000000 +0300
18154 +++ linux-2.4.29/arch/um/include/mem.h  2005-05-03 22:28:14.310434696 +0300
18155 @@ -0,0 +1,29 @@
18156 +/* 
18157 + * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com)
18158 + * Licensed under the GPL
18159 + */
18160 +
18161 +#ifndef __MEM_H__
18162 +#define __MEM_H__
18163 +
18164 +#include "linux/types.h"
18165 +
18166 +extern void set_kmem_end(unsigned long new);
18167 +extern int phys_mapping(unsigned long phys, __u64 *offset_out);
18168 +extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
18169 +extern int is_remapped(const void *virt, int fd, __u64 offset);
18170 +extern int physmem_remove_mapping(void *virt);
18171 +extern void physmem_forget_descriptor(int fd);
18172 +
18173 +#endif
18174 +
18175 +/*
18176 + * Overrides for Emacs so that we follow Linus's tabbing style.
18177 + * Emacs will notice this stuff at the end of the file and automatically
18178 + * adjust the settings for this buffer only.  This must remain at the end
18179 + * of the file.
18180 + * ---------------------------------------------------------------------------
18181 + * Local variables:
18182 + * c-file-style: "linux"
18183 + * End:
18184 + */
18185 Index: linux-2.4.29/arch/um/include/mem_kern.h
18186 ===================================================================
18187 --- linux-2.4.29.orig/arch/um/include/mem_kern.h        1970-01-01 03:00:00.000000000 +0300
18188 +++ linux-2.4.29/arch/um/include/mem_kern.h     2005-05-03 22:28:14.311434544 +0300
18189 @@ -0,0 +1,30 @@
18190 +/* 
18191 + * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com)
18192 + * Licensed under the GPL
18193 + */
18194 +
18195 +#ifndef __MEM_KERN_H__
18196 +#define __MEM_KERN_H__
18197 +
18198 +#include "linux/list.h"
18199 +#include "linux/types.h"
18200 +
18201 +struct remapper {
18202 +       struct list_head list;
18203 +       int (*proc)(int, unsigned long, int, __u64, int);
18204 +};
18205 +
18206 +extern void register_remapper(struct remapper *info);
18207 +
18208 +#endif
18209 +
18210 +/*
18211 + * Overrides for Emacs so that we follow Linus's tabbing style.
18212 + * Emacs will notice this stuff at the end of the file and automatically
18213 + * adjust the settings for this buffer only.  This must remain at the end
18214 + * of the file.
18215 + * ---------------------------------------------------------------------------
18216 + * Local variables:
18217 + * c-file-style: "linux"
18218 + * End:
18219 + */
18220 Index: linux-2.4.29/arch/um/include/mem_user.h
18221 ===================================================================
18222 --- linux-2.4.29.orig/arch/um/include/mem_user.h        1970-01-01 03:00:00.000000000 +0300
18223 +++ linux-2.4.29/arch/um/include/mem_user.h     2005-05-03 22:28:14.313434240 +0300
18224 @@ -0,0 +1,82 @@
18225 +/*
18226 + * arch/um/include/mem_user.h
18227 + *
18228 + * BRIEF MODULE DESCRIPTION
18229 + * user side memory interface for support IO memory inside user mode linux
18230 + *
18231 + * Copyright (C) 2001 RidgeRun, Inc.
18232 + * Author: RidgeRun, Inc.
18233 + *         Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
18234 + *
18235 + *  This program is free software; you can redistribute  it and/or modify it
18236 + *  under  the terms of  the GNU General  Public License as published by the
18237 + *  Free Software Foundation;  either version 2 of the  License, or (at your
18238 + *  option) any later version.
18239 + *
18240 + *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
18241 + *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
18242 + *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
18243 + *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
18244 + *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18245 + *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
18246 + *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
18247 + *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
18248 + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
18249 + *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18250 + *
18251 + *  You should have received a copy of the  GNU General Public License along
18252 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
18253 + *  675 Mass Ave, Cambridge, MA 02139, USA.
18254 + */
18255 +
18256 +#ifndef _MEM_USER_H
18257 +#define _MEM_USER_H
18258 +
18259 +struct iomem_region {
18260 +       struct iomem_region *next;
18261 +       char *driver;
18262 +       int fd;
18263 +       int size;
18264 +       unsigned long phys;
18265 +       unsigned long virt;
18266 +};
18267 +
18268 +extern struct iomem_region *iomem_regions;
18269 +extern int iomem_size;
18270 +
18271 +#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
18272 +
18273 +extern unsigned long host_task_size;
18274 +extern unsigned long task_size;
18275 +
18276 +extern int init_mem_user(void);
18277 +extern int create_mem_file(unsigned long len);
18278 +extern void setup_memory(void *entry);
18279 +extern unsigned long find_iomem(char *driver, unsigned long *len_out);
18280 +extern int init_maps(unsigned long physmem, unsigned long iomem, 
18281 +                    unsigned long highmem);
18282 +extern unsigned long get_vm(unsigned long len);
18283 +extern void setup_physmem(unsigned long start, unsigned long usable,
18284 +                         unsigned long len, unsigned long highmem);
18285 +extern void add_iomem(char *name, int fd, unsigned long size);
18286 +extern unsigned long phys_offset(unsigned long phys);
18287 +extern void unmap_physmem(void);
18288 +extern void map_memory(unsigned long virt, unsigned long phys, 
18289 +                      unsigned long len, int r, int w, int x);
18290 +extern int protect_memory(unsigned long addr, unsigned long len, 
18291 +                         int r, int w, int x, int must_succeed);
18292 +extern unsigned long get_kmem_end(void);
18293 +extern void check_tmpexec(void);
18294 +
18295 +#endif
18296 +
18297 +/*
18298 + * Overrides for Emacs so that we follow Linus's tabbing style.
18299 + * Emacs will notice this stuff at the end of the file and automatically
18300 + * adjust the settings for this buffer only.  This must remain at the end
18301 + * of the file.
18302 + * ---------------------------------------------------------------------------
18303 + * Local variables:
18304 + * c-file-style: "linux"
18305 + * End:
18306 + */
18307 Index: linux-2.4.29/arch/um/include/mode.h
18308 ===================================================================
18309 --- linux-2.4.29.orig/arch/um/include/mode.h    1970-01-01 03:00:00.000000000 +0300
18310 +++ linux-2.4.29/arch/um/include/mode.h 2005-05-03 22:28:14.313434240 +0300
18311 @@ -0,0 +1,30 @@
18312 +/* 
18313 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18314 + * Licensed under the GPL
18315 + */
18316 +
18317 +#ifndef __MODE_H__
18318 +#define __MODE_H__
18319 +
18320 +#include "uml-config.h"
18321 +
18322 +#ifdef UML_CONFIG_MODE_TT
18323 +#include "../kernel/tt/include/mode.h"
18324 +#endif
18325 +
18326 +#ifdef UML_CONFIG_MODE_SKAS
18327 +#include "../kernel/skas/include/mode.h"
18328 +#endif
18329 +
18330 +#endif
18331 +
18332 +/*
18333 + * Overrides for Emacs so that we follow Linus's tabbing style.
18334 + * Emacs will notice this stuff at the end of the file and automatically
18335 + * adjust the settings for this buffer only.  This must remain at the end
18336 + * of the file.
18337 + * ---------------------------------------------------------------------------
18338 + * Local variables:
18339 + * c-file-style: "linux"
18340 + * End:
18341 + */
18342 Index: linux-2.4.29/arch/um/include/mode_kern.h
18343 ===================================================================
18344 --- linux-2.4.29.orig/arch/um/include/mode_kern.h       1970-01-01 03:00:00.000000000 +0300
18345 +++ linux-2.4.29/arch/um/include/mode_kern.h    2005-05-03 22:28:14.314434088 +0300
18346 @@ -0,0 +1,30 @@
18347 +/* 
18348 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18349 + * Licensed under the GPL
18350 + */
18351 +
18352 +#ifndef __MODE_KERN_H__
18353 +#define __MODE_KERN_H__
18354 +
18355 +#include "linux/config.h"
18356 +
18357 +#ifdef CONFIG_MODE_TT
18358 +#include "../kernel/tt/include/mode_kern.h"
18359 +#endif
18360 +
18361 +#ifdef CONFIG_MODE_SKAS
18362 +#include "../kernel/skas/include/mode_kern.h"
18363 +#endif
18364 +
18365 +#endif
18366 +
18367 +/*
18368 + * Overrides for Emacs so that we follow Linus's tabbing style.
18369 + * Emacs will notice this stuff at the end of the file and automatically
18370 + * adjust the settings for this buffer only.  This must remain at the end
18371 + * of the file.
18372 + * ---------------------------------------------------------------------------
18373 + * Local variables:
18374 + * c-file-style: "linux"
18375 + * End:
18376 + */
18377 Index: linux-2.4.29/arch/um/include/net_kern.h
18378 ===================================================================
18379 --- linux-2.4.29.orig/arch/um/include/net_kern.h        1970-01-01 03:00:00.000000000 +0300
18380 +++ linux-2.4.29/arch/um/include/net_kern.h     2005-05-03 22:28:14.315433936 +0300
18381 @@ -0,0 +1,81 @@
18382 +/* 
18383 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18384 + * Licensed under the GPL
18385 + */
18386 +
18387 +#ifndef __UM_NET_KERN_H
18388 +#define __UM_NET_KERN_H
18389 +
18390 +#include "linux/netdevice.h"
18391 +#include "linux/skbuff.h"
18392 +#include "linux/socket.h"
18393 +#include "linux/list.h"
18394 +
18395 +struct uml_net {
18396 +       struct list_head list;
18397 +       struct net_device *dev;
18398 +       int index;
18399 +       unsigned char mac[ETH_ALEN];
18400 +       int have_mac;
18401 +};
18402 +
18403 +struct uml_net_private {
18404 +       struct list_head list;
18405 +       spinlock_t lock;
18406 +       struct net_device *dev;
18407 +       struct timer_list tl;
18408 +       struct net_device_stats stats;
18409 +       int fd;
18410 +       unsigned char mac[ETH_ALEN];
18411 +       int have_mac;
18412 +       unsigned short (*protocol)(struct sk_buff *);
18413 +       int (*open)(void *);
18414 +       void (*close)(int, void *);
18415 +       void (*remove)(void *);
18416 +       int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
18417 +       int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
18418 +       
18419 +       void (*add_address)(unsigned char *, unsigned char *, void *);
18420 +       void (*delete_address)(unsigned char *, unsigned char *, void *);
18421 +       int (*set_mtu)(int mtu, void *);
18422 +       int user[1];
18423 +};
18424 +
18425 +struct net_kern_info {
18426 +       void (*init)(struct net_device *, void *);
18427 +       unsigned short (*protocol)(struct sk_buff *);
18428 +       int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
18429 +       int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
18430 +};
18431 +
18432 +struct transport {
18433 +       struct list_head list;
18434 +       char *name;
18435 +       int (*setup)(char *, char **, void *);
18436 +       struct net_user_info *user;
18437 +       struct net_kern_info *kern;
18438 +       int private_size;
18439 +       int setup_size;
18440 +};
18441 +
18442 +extern struct net_device *ether_init(int);
18443 +extern unsigned short ether_protocol(struct sk_buff *);
18444 +extern int setup_etheraddr(char *str, unsigned char *addr);
18445 +extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
18446 +extern int tap_setup_common(char *str, char *type, char **dev_name, 
18447 +                           char **mac_out, char **gate_addr);
18448 +extern void register_transport(struct transport *new);
18449 +extern unsigned short eth_protocol(struct sk_buff *skb);
18450 +
18451 +#endif
18452 +
18453 +/*
18454 + * Overrides for Emacs so that we follow Linus's tabbing style.
18455 + * Emacs will notice this stuff at the end of the file and automatically
18456 + * adjust the settings for this buffer only.  This must remain at the end
18457 + * of the file.
18458 + * ---------------------------------------------------------------------------
18459 + * Local variables:
18460 + * c-file-style: "linux"
18461 + * End:
18462 + */
18463 Index: linux-2.4.29/arch/um/include/net_user.h
18464 ===================================================================
18465 --- linux-2.4.29.orig/arch/um/include/net_user.h        1970-01-01 03:00:00.000000000 +0300
18466 +++ linux-2.4.29/arch/um/include/net_user.h     2005-05-03 22:28:14.316433784 +0300
18467 @@ -0,0 +1,66 @@
18468 +/* 
18469 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18470 + * Licensed under the GPL
18471 + */
18472 +
18473 +#ifndef __UM_NET_USER_H__
18474 +#define __UM_NET_USER_H__
18475 +
18476 +#define ETH_ADDR_LEN (6)
18477 +#define ETH_HEADER_ETHERTAP (16)
18478 +#define ETH_HEADER_OTHER (14)
18479 +#define ETH_MAX_PACKET (1500)
18480 +
18481 +#define UML_NET_VERSION (4)
18482 +
18483 +struct net_user_info {
18484 +       void (*init)(void *, void *);
18485 +       int (*open)(void *);
18486 +       void (*close)(int, void *);
18487 +       void (*remove)(void *);
18488 +       int (*set_mtu)(int mtu, void *);
18489 +       void (*add_address)(unsigned char *, unsigned char *, void *);
18490 +       void (*delete_address)(unsigned char *, unsigned char *, void *);
18491 +       int max_packet;
18492 +};
18493 +
18494 +extern void ether_user_init(void *data, void *dev);
18495 +extern void dev_ip_addr(void *d, char *buf, char *bin_buf);
18496 +extern void set_ether_mac(void *d, unsigned char *addr);
18497 +extern void iter_addresses(void *d, void (*cb)(unsigned char *, 
18498 +                                              unsigned char *, void *), 
18499 +                          void *arg);
18500 +
18501 +extern void *get_output_buffer(int *len_out);
18502 +extern void free_output_buffer(void *buffer);
18503 +
18504 +extern int tap_open_common(void *dev, char *gate_addr);
18505 +extern void tap_check_ips(char *gate_addr, char *eth_addr);
18506 +
18507 +extern void read_output(int fd, char *output_out, int len);
18508 +
18509 +extern int net_read(int fd, void *buf, int len);
18510 +extern int net_recvfrom(int fd, void *buf, int len);
18511 +extern int net_write(int fd, void *buf, int len);
18512 +extern int net_send(int fd, void *buf, int len);
18513 +extern int net_sendto(int fd, void *buf, int len, void *to, int sock_len);
18514 +
18515 +extern void open_addr(unsigned char *addr, unsigned char *netmask, void *arg);
18516 +extern void close_addr(unsigned char *addr, unsigned char *netmask, void *arg);
18517 +
18518 +extern char *split_if_spec(char *str, ...);
18519 +
18520 +extern int dev_netmask(void *d, void *m);
18521 +
18522 +#endif
18523 +
18524 +/*
18525 + * Overrides for Emacs so that we follow Linus's tabbing style.
18526 + * Emacs will notice this stuff at the end of the file and automatically
18527 + * adjust the settings for this buffer only.  This must remain at the end
18528 + * of the file.
18529 + * ---------------------------------------------------------------------------
18530 + * Local variables:
18531 + * c-file-style: "linux"
18532 + * End:
18533 + */
18534 Index: linux-2.4.29/arch/um/include/os.h
18535 ===================================================================
18536 --- linux-2.4.29.orig/arch/um/include/os.h      1970-01-01 03:00:00.000000000 +0300
18537 +++ linux-2.4.29/arch/um/include/os.h   2005-05-03 22:28:14.318433480 +0300
18538 @@ -0,0 +1,221 @@
18539 +/* 
18540 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18541 + * Licensed under the GPL
18542 + */
18543 +
18544 +#ifndef __OS_H__
18545 +#define __OS_H__
18546 +
18547 +#include "asm/types.h"
18548 +#include "../os/include/file.h"
18549 +
18550 +#define OS_TYPE_FILE 1 
18551 +#define OS_TYPE_DIR 2 
18552 +#define OS_TYPE_SYMLINK 3 
18553 +#define OS_TYPE_CHARDEV 4
18554 +#define OS_TYPE_BLOCKDEV 5
18555 +#define OS_TYPE_FIFO 6
18556 +#define OS_TYPE_SOCK 7
18557 +
18558 +/* os_access() flags */
18559 +#define OS_ACC_F_OK    0       /* Test for existence.  */
18560 +#define OS_ACC_X_OK    1       /* Test for execute permission.  */
18561 +#define OS_ACC_W_OK    2       /* Test for write permission.  */
18562 +#define OS_ACC_R_OK    4       /* Test for read permission.  */
18563 +#define OS_ACC_RW_OK   (OS_ACC_W_OK | OS_ACC_R_OK) /* Test for RW permission */
18564 +
18565 +/*
18566 + * types taken from stat_file() in hostfs_user.c
18567 + * (if they are wrong here, they are wrong there...).
18568 + */
18569 +struct uml_stat {
18570 +       int                ust_major;      /* device */
18571 +       int                ust_minor;
18572 +       unsigned long long ust_ino;        /* inode */
18573 +       int                ust_mode;       /* protection */
18574 +       int                ust_nlink;      /* number of hard links */
18575 +       int                ust_uid;        /* user ID of owner */
18576 +       int                ust_gid;        /* group ID of owner */
18577 +       unsigned long long ust_size;       /* total size, in bytes */
18578 +       int                ust_blksize;    /* blocksize for filesystem I/O */
18579 +       unsigned long long ust_blocks;     /* number of blocks allocated */
18580 +       unsigned long      ust_atime;      /* time of last access */
18581 +       unsigned long      ust_mtime;      /* time of last modification */
18582 +       unsigned long      ust_ctime;      /* time of last change */
18583 +       int                ust_rmajor;
18584 +       int                ust_rminor;
18585 +};
18586 +
18587 +struct openflags {
18588 +       unsigned int r : 1;
18589 +       unsigned int w : 1;
18590 +       unsigned int s : 1;     /* O_SYNC */
18591 +       unsigned int c : 1;     /* O_CREAT */
18592 +       unsigned int t : 1;     /* O_TRUNC */
18593 +       unsigned int a : 1;     /* O_APPEND */
18594 +       unsigned int e : 1;     /* O_EXCL */
18595 +       unsigned int cl : 1;    /* FD_CLOEXEC */
18596 +       unsigned int d : 1;     /* O_DIRECT */
18597 +};
18598 +
18599 +#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
18600 +                                         .t = 0, .a = 0, .e = 0, .cl = 0, \
18601 +                                         .d = 0 })
18602 +
18603 +static inline struct openflags of_read(struct openflags flags)
18604 +{
18605 +       flags.r = 1; 
18606 +       return(flags);
18607 +}
18608 +
18609 +static inline struct openflags of_write(struct openflags flags)
18610 +{
18611 +       flags.w = 1; 
18612 +       return(flags); 
18613 +}
18614 +
18615 +static inline struct openflags of_rdwr(struct openflags flags)
18616 +{
18617 +       return(of_read(of_write(flags)));
18618 +}
18619 +
18620 +static inline struct openflags of_set_rw(struct openflags flags, int r, int w)
18621 +{
18622 +       flags.r = r;
18623 +       flags.w = w;
18624 +       return(flags);
18625 +}
18626 +
18627 +static inline struct openflags of_sync(struct openflags flags)
18628 +{ 
18629 +       flags.s = 1; 
18630 +       return(flags); 
18631 +}
18632 +
18633 +static inline struct openflags of_create(struct openflags flags)
18634 +{ 
18635 +       flags.c = 1; 
18636 +       return(flags); 
18637 +}
18638
18639 +static inline struct openflags of_trunc(struct openflags flags)
18640 +{ 
18641 +       flags.t = 1; 
18642 +       return(flags); 
18643 +}
18644
18645 +static inline struct openflags of_append(struct openflags flags)
18646 +{ 
18647 +       flags.a = 1; 
18648 +       return(flags); 
18649 +}
18650
18651 +static inline struct openflags of_excl(struct openflags flags)
18652 +{ 
18653 +       flags.e = 1; 
18654 +       return(flags); 
18655 +}
18656 +
18657 +static inline struct openflags of_cloexec(struct openflags flags)
18658 +{ 
18659 +       flags.cl = 1; 
18660 +       return(flags); 
18661 +}
18662
18663 +static inline struct openflags of_direct(struct openflags flags)
18664 +{ 
18665 +       flags.d = 1; 
18666 +       return(flags); 
18667 +}
18668
18669 +extern int os_stat_file(const char *file_name, struct uml_stat *buf);
18670 +extern int os_lstat_file(const char *file_name, struct uml_stat *ubuf);
18671 +extern int os_stat_fd(const int fd, struct uml_stat *buf);
18672 +extern int os_access(const char *file, int mode);
18673 +extern int os_set_file_time(const char *file, unsigned long access, 
18674 +                           unsigned long mod);
18675 +extern int os_set_file_perms(const char *file, int mode);
18676 +extern int os_set_file_owner(const char *file, int owner, int group);
18677 +extern void os_print_error(int error, const char* str);
18678 +extern int os_get_exec_close(int fd, int *close_on_exec);
18679 +extern int os_set_exec_close(int fd, int close_on_exec);
18680 +extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
18681 +extern int os_window_size(int fd, int *rows, int *cols);
18682 +extern int os_new_tty_pgrp(int fd, int pid);
18683 +extern int os_get_ifname(int fd, char *namebuf);
18684 +extern int os_set_slip(int fd);
18685 +extern int os_set_owner(int fd, int pid);
18686 +extern int os_sigio_async(int master, int slave);
18687 +extern int os_mode_fd(int fd, int mode);
18688 +
18689 +extern int os_seek_file(int fd, __u64 offset);
18690 +extern int os_open_file(char *file, struct openflags flags, int mode);
18691 +extern void *os_open_dir(char *dir, int *err_out);
18692 +extern int os_seek_dir(void *stream, unsigned long long pos);
18693 +extern int os_read_dir(void *stream, unsigned long long *ino_out, 
18694 +                      char **name_out);
18695 +extern int os_tell_dir(void *stream);
18696 +extern int os_close_dir(void *stream);
18697 +extern int os_remove_file(const char *file);
18698 +extern int os_move_file(const char *from, const char *to);
18699 +extern int os_truncate_file(const char *file, unsigned long long len);
18700 +extern int os_truncate_fd(int fd, unsigned long long len);
18701 +extern int os_read_file(int fd, void *buf, int len);
18702 +extern int os_write_file(int fd, const void *buf, int count);
18703 +extern int os_file_size(char *file, long long *size_out);
18704 +extern int os_fd_size(int fd, long long *size_out);
18705 +extern int os_file_modtime(char *file, unsigned long *modtime);
18706 +extern int os_pipe(int *fd, int stream, int close_on_exec);
18707 +extern int os_set_fd_async(int fd, int owner);
18708 +extern int os_clear_fd_async(int fd);
18709 +extern int os_set_fd_block(int fd, int blocking);
18710 +extern int os_accept_connection(int fd);
18711 +extern int os_create_unix_socket(char *file, int len, int close_on_exec);
18712 +extern int os_make_symlink(const char *to, const char *from);
18713 +extern int os_read_symlink(const char *file, char *buf, int size);
18714 +extern int os_link_file(const char *to, const char *from);
18715 +extern int os_make_dir(const char *dir, int mode);
18716 +extern int os_remove_dir(const char *dir);
18717 +extern int os_make_dev(const char *name, int mode, int major, int minor);
18718 +extern int os_shutdown_socket(int fd, int r, int w);
18719 +extern void os_close_file(int fd);
18720 +extern int os_rcv_fd(int fd, int *helper_pid_out);
18721 +extern int create_unix_socket(char *file, int len, int close_on_exec);
18722 +extern int os_connect_socket(char *name);
18723 +extern int os_file_type(char *file);
18724 +extern int os_file_mode(char *file, struct openflags *mode_out);
18725 +extern int os_lock_file(int fd, int excl);
18726 +
18727 +extern unsigned long os_process_pc(int pid);
18728 +extern int os_process_parent(int pid);
18729 +extern void os_stop_process(int pid);
18730 +extern void os_kill_process(int pid, int reap_child);
18731 +extern void os_usr1_process(int pid);
18732 +extern int os_getpid(void);
18733 +
18734 +extern int os_map_memory(void *virt, int fd, unsigned long long off, 
18735 +                        unsigned long len, int r, int w, int x);
18736 +extern int os_protect_memory(void *addr, unsigned long len, 
18737 +                            int r, int w, int x);
18738 +extern int os_unmap_memory(void *addr, int len);
18739 +extern void os_flush_stdout(void);
18740 +extern int os_stat_filesystem(char *path, long *bsize_out, 
18741 +                             long long *blocks_out, long long *bfree_out,
18742 +                             long long *bavail_out, long long *files_out,
18743 +                             long long *ffree_out, void *fsid_out, 
18744 +                             int fsid_size, long *namelen_out, 
18745 +                             long *spare_out);
18746 +extern unsigned long long os_usecs(void);
18747 +
18748 +#endif
18749 +
18750 +/*
18751 + * Overrides for Emacs so that we follow Linus's tabbing style.
18752 + * Emacs will notice this stuff at the end of the file and automatically
18753 + * adjust the settings for this buffer only.  This must remain at the end
18754 + * of the file.
18755 + * ---------------------------------------------------------------------------
18756 + * Local variables:
18757 + * c-file-style: "linux"
18758 + * End:
18759 + */
18760 Index: linux-2.4.29/arch/um/include/process.h
18761 ===================================================================
18762 --- linux-2.4.29.orig/arch/um/include/process.h 1970-01-01 03:00:00.000000000 +0300
18763 +++ linux-2.4.29/arch/um/include/process.h      2005-05-03 22:28:14.319433328 +0300
18764 @@ -0,0 +1,25 @@
18765 +/* 
18766 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
18767 + * Licensed under the GPL
18768 + */
18769 +
18770 +#ifndef __PROCESS_H__
18771 +#define __PROCESS_H__
18772 +
18773 +#include <asm/sigcontext.h>
18774 +
18775 +extern void sig_handler(int sig, struct sigcontext sc);
18776 +extern void alarm_handler(int sig, struct sigcontext sc);
18777 +
18778 +#endif
18779 +
18780 +/*
18781 + * Overrides for Emacs so that we follow Linus's tabbing style.
18782 + * Emacs will notice this stuff at the end of the file and automatically
18783 + * adjust the settings for this buffer only.  This must remain at the end
18784 + * of the file.
18785 + * ---------------------------------------------------------------------------
18786 + * Local variables:
18787 + * c-file-style: "linux"
18788 + * End:
18789 + */
18790 Index: linux-2.4.29/arch/um/include/ptrace_user.h
18791 ===================================================================
18792 --- linux-2.4.29.orig/arch/um/include/ptrace_user.h     1970-01-01 03:00:00.000000000 +0300
18793 +++ linux-2.4.29/arch/um/include/ptrace_user.h  2005-05-03 22:28:14.319433328 +0300
18794 @@ -0,0 +1,25 @@
18795 +/* 
18796 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
18797 + * Licensed under the GPL
18798 + */
18799 +
18800 +#ifndef __PTRACE_USER_H__
18801 +#define __PTRACE_USER_H__
18802 +
18803 +#include "sysdep/ptrace_user.h"
18804 +
18805 +/* syscall emulation path in ptrace */
18806 +#ifndef PTRACE_SYSEMU
18807 +#define PTRACE_SYSEMU 31
18808 +#endif
18809 +
18810 +extern int use_sysemu;
18811 +
18812 +extern int ptrace_getregs(long pid, unsigned long *regs_out);
18813 +extern int ptrace_setregs(long pid, unsigned long *regs_in);
18814 +extern int ptrace_getfpregs(long pid, unsigned long *regs_out);
18815 +extern void arch_enter_kernel(void *task, int pid);
18816 +extern void arch_leave_kernel(void *task, int pid);
18817 +extern void ptrace_pokeuser(unsigned long addr, unsigned long data);
18818 +
18819 +#endif
18820 Index: linux-2.4.29/arch/um/include/sigcontext.h
18821 ===================================================================
18822 --- linux-2.4.29.orig/arch/um/include/sigcontext.h      1970-01-01 03:00:00.000000000 +0300
18823 +++ linux-2.4.29/arch/um/include/sigcontext.h   2005-05-03 22:28:14.320433176 +0300
18824 @@ -0,0 +1,25 @@
18825 +/* 
18826 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
18827 + * Licensed under the GPL
18828 + */
18829 +
18830 +#ifndef __UML_SIGCONTEXT_H__
18831 +#define __UML_SIGCONTEXT_H__
18832 +
18833 +#include "sysdep/sigcontext.h"
18834 +
18835 +extern int sc_size(void *data);
18836 +extern void sc_to_sc(void *to_ptr, void *from_ptr);
18837 +
18838 +#endif
18839 +
18840 +/*
18841 + * Overrides for Emacs so that we follow Linus's tabbing style.
18842 + * Emacs will notice this stuff at the end of the file and automatically
18843 + * adjust the settings for this buffer only.  This must remain at the end
18844 + * of the file.
18845 + * ---------------------------------------------------------------------------
18846 + * Local variables:
18847 + * c-file-style: "linux"
18848 + * End:
18849 + */
18850 Index: linux-2.4.29/arch/um/include/sigio.h
18851 ===================================================================
18852 --- linux-2.4.29.orig/arch/um/include/sigio.h   1970-01-01 03:00:00.000000000 +0300
18853 +++ linux-2.4.29/arch/um/include/sigio.h        2005-05-03 22:28:14.321433024 +0300
18854 @@ -0,0 +1,28 @@
18855 +/* 
18856 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18857 + * Licensed under the GPL
18858 + */
18859 +
18860 +#ifndef __SIGIO_H__
18861 +#define __SIGIO_H__
18862 +
18863 +extern int write_sigio_irq(int fd);
18864 +extern int register_sigio_fd(int fd);
18865 +extern int read_sigio_fd(int fd);
18866 +extern int add_sigio_fd(int fd, int read);
18867 +extern int ignore_sigio_fd(int fd);
18868 +extern void sigio_lock(void);
18869 +extern void sigio_unlock(void);
18870 +
18871 +#endif
18872 +
18873 +/*
18874 + * Overrides for Emacs so that we follow Linus's tabbing style.
18875 + * Emacs will notice this stuff at the end of the file and automatically
18876 + * adjust the settings for this buffer only.  This must remain at the end
18877 + * of the file.
18878 + * ---------------------------------------------------------------------------
18879 + * Local variables:
18880 + * c-file-style: "linux"
18881 + * End:
18882 + */
18883 Index: linux-2.4.29/arch/um/include/signal_kern.h
18884 ===================================================================
18885 --- linux-2.4.29.orig/arch/um/include/signal_kern.h     1970-01-01 03:00:00.000000000 +0300
18886 +++ linux-2.4.29/arch/um/include/signal_kern.h  2005-05-03 22:28:14.322432872 +0300
18887 @@ -0,0 +1,22 @@
18888 +/* 
18889 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
18890 + * Licensed under the GPL
18891 + */
18892 +
18893 +#ifndef __SIGNAL_KERN_H__
18894 +#define __SIGNAL_KERN_H__
18895 +
18896 +extern int have_signals(void *t);
18897 +
18898 +#endif
18899 +
18900 +/*
18901 + * Overrides for Emacs so that we follow Linus's tabbing style.
18902 + * Emacs will notice this stuff at the end of the file and automatically
18903 + * adjust the settings for this buffer only.  This must remain at the end
18904 + * of the file.
18905 + * ---------------------------------------------------------------------------
18906 + * Local variables:
18907 + * c-file-style: "linux"
18908 + * End:
18909 + */
18910 Index: linux-2.4.29/arch/um/include/signal_user.h
18911 ===================================================================
18912 --- linux-2.4.29.orig/arch/um/include/signal_user.h     1970-01-01 03:00:00.000000000 +0300
18913 +++ linux-2.4.29/arch/um/include/signal_user.h  2005-05-03 22:28:14.323432720 +0300
18914 @@ -0,0 +1,26 @@
18915 +/* 
18916 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
18917 + * Licensed under the GPL
18918 + */
18919 +
18920 +#ifndef __SIGNAL_USER_H__
18921 +#define __SIGNAL_USER_H__
18922 +
18923 +extern int signal_stack_size;
18924 +
18925 +extern int change_sig(int signal, int on);
18926 +extern void set_sigstack(void *stack, int size);
18927 +extern void set_handler(int sig, void (*handler)(int), int flags, ...);
18928 +
18929 +#endif
18930 +
18931 +/*
18932 + * Overrides for Emacs so that we follow Linus's tabbing style.
18933 + * Emacs will notice this stuff at the end of the file and automatically
18934 + * adjust the settings for this buffer only.  This must remain at the end
18935 + * of the file.
18936 + * ---------------------------------------------------------------------------
18937 + * Local variables:
18938 + * c-file-style: "linux"
18939 + * End:
18940 + */
18941 Index: linux-2.4.29/arch/um/include/skas_ptrace.h
18942 ===================================================================
18943 --- linux-2.4.29.orig/arch/um/include/skas_ptrace.h     1970-01-01 03:00:00.000000000 +0300
18944 +++ linux-2.4.29/arch/um/include/skas_ptrace.h  2005-05-03 22:28:14.323432720 +0300
18945 @@ -0,0 +1,36 @@
18946 +/* 
18947 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
18948 + * Licensed under the GPL
18949 + */
18950 +
18951 +#ifndef __SKAS_PTRACE_H
18952 +#define __SKAS_PTRACE_H
18953 +
18954 +struct ptrace_faultinfo {
18955 +       int is_write;
18956 +       unsigned long addr;
18957 +};
18958 +
18959 +struct ptrace_ldt {
18960 +       int func;
18961 +       void *ptr;
18962 +       unsigned long bytecount;
18963 +};
18964 +
18965 +#define PTRACE_FAULTINFO 52
18966 +#define PTRACE_SIGPENDING 53
18967 +#define PTRACE_LDT 54
18968 +#define PTRACE_SWITCH_MM 55
18969 +
18970 +#endif
18971 +
18972 +/*
18973 + * Overrides for Emacs so that we follow Linus's tabbing style.
18974 + * Emacs will notice this stuff at the end of the file and automatically
18975 + * adjust the settings for this buffer only.  This must remain at the end
18976 + * of the file.
18977 + * ---------------------------------------------------------------------------
18978 + * Local variables:
18979 + * c-file-style: "linux"
18980 + * End:
18981 + */
18982 Index: linux-2.4.29/arch/um/include/syscall_user.h
18983 ===================================================================
18984 --- linux-2.4.29.orig/arch/um/include/syscall_user.h    1970-01-01 03:00:00.000000000 +0300
18985 +++ linux-2.4.29/arch/um/include/syscall_user.h 2005-05-03 22:28:14.324432568 +0300
18986 @@ -0,0 +1,23 @@
18987 +/* 
18988 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18989 + * Licensed under the GPL
18990 + */
18991 +
18992 +#ifndef __SYSCALL_USER_H
18993 +#define __SYSCALL_USER_H
18994 +
18995 +extern int record_syscall_start(int syscall);
18996 +extern void record_syscall_end(int index, int result);
18997 +
18998 +#endif
18999 +
19000 +/*
19001 + * Overrides for Emacs so that we follow Linus's tabbing style.
19002 + * Emacs will notice this stuff at the end of the file and automatically
19003 + * adjust the settings for this buffer only.  This must remain at the end
19004 + * of the file.
19005 + * ---------------------------------------------------------------------------
19006 + * Local variables:
19007 + * c-file-style: "linux"
19008 + * End:
19009 + */
19010 Index: linux-2.4.29/arch/um/include/sysdep-i386/checksum.h
19011 ===================================================================
19012 --- linux-2.4.29.orig/arch/um/include/sysdep-i386/checksum.h    1970-01-01 03:00:00.000000000 +0300
19013 +++ linux-2.4.29/arch/um/include/sysdep-i386/checksum.h 2005-05-03 22:28:14.326432264 +0300
19014 @@ -0,0 +1,218 @@
19015 +/* 
19016 + * Licensed under the GPL
19017 + */
19018 +
19019 +#ifndef __UM_SYSDEP_CHECKSUM_H
19020 +#define __UM_SYSDEP_CHECKSUM_H
19021 +
19022 +#include "linux/string.h"
19023 +#include "asm/uaccess.h"
19024 +
19025 +/*
19026 + * computes the checksum of a memory block at buff, length len,
19027 + * and adds in "sum" (32-bit)
19028 + *
19029 + * returns a 32-bit number suitable for feeding into itself
19030 + * or csum_tcpudp_magic
19031 + *
19032 + * this function must be called with even lengths, except
19033 + * for the last fragment, which may be odd
19034 + *
19035 + * it's best to have buff aligned on a 32-bit boundary
19036 + */
19037 +unsigned int csum_partial(const unsigned char * buff, int len, 
19038 +                         unsigned int sum);
19039 +
19040 +/*
19041 + * the same as csum_partial, but copies from src while it
19042 + * checksums, and handles user-space pointer exceptions correctly, when needed.
19043 + *
19044 + * here even more important to align src and dst on a 32-bit (or even
19045 + * better 64-bit) boundary
19046 + */
19047 +
19048 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len, 
19049 +                                 int sum, int *err_ptr);
19050 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len, 
19051 +                                   int sum, int *err_ptr);
19052 +
19053 +/*
19054 + *     Note: when you get a NULL pointer exception here this means someone
19055 + *     passed in an incorrect kernel address to one of these functions.
19056 + *
19057 + *     If you use these functions directly please don't forget the
19058 + *     verify_area().
19059 + */
19060 +
19061 +static __inline__
19062 +unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
19063 +                                      int len, int sum)
19064 +{
19065 +       memcpy(dst, src, len);
19066 +       return(csum_partial(dst, len, sum));
19067 +}
19068 +
19069 +static __inline__
19070 +unsigned int csum_partial_copy_from_user(const char *src, char *dst,
19071 +                                        int len, int sum, int *err_ptr)
19072 +{
19073 +       return csum_partial_copy_from(src, dst, len, sum, err_ptr);
19074 +}
19075 +
19076 +/*
19077 + * These are the old (and unsafe) way of doing checksums, a warning message 
19078 + * will be printed if they are used and an exception occurs.
19079 + *
19080 + * these functions should go away after some time.
19081 + */
19082 +
19083 +#define csum_partial_copy_fromuser csum_partial_copy_from_user
19084 +unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
19085 +
19086 +/*
19087 + *     This is a version of ip_compute_csum() optimized for IP headers,
19088 + *     which always checksum on 4 octet boundaries.
19089 + *
19090 + *     By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
19091 + *     Arnt Gulbrandsen.
19092 + */
19093 +static inline unsigned short ip_fast_csum(unsigned char * iph,
19094 +                                         unsigned int ihl)
19095 +{
19096 +       unsigned int sum;
19097 +
19098 +       __asm__ __volatile__(
19099 +           "movl (%1), %0      ;\n"
19100 +           "subl $4, %2        ;\n"
19101 +           "jbe 2f             ;\n"
19102 +           "addl 4(%1), %0     ;\n"
19103 +           "adcl 8(%1), %0     ;\n"
19104 +           "adcl 12(%1), %0    ;\n"
19105 +"1:        adcl 16(%1), %0     ;\n"
19106 +           "lea 4(%1), %1      ;\n"
19107 +           "decl %2            ;\n"
19108 +           "jne 1b             ;\n"
19109 +           "adcl $0, %0        ;\n"
19110 +           "movl %0, %2        ;\n"
19111 +           "shrl $16, %0       ;\n"
19112 +           "addw %w2, %w0      ;\n"
19113 +           "adcl $0, %0        ;\n"
19114 +           "notl %0            ;\n"
19115 +"2:                            ;\n"
19116 +       /* Since the input registers which are loaded with iph and ipl
19117 +          are modified, we must also specify them as outputs, or gcc
19118 +          will assume they contain their original values. */
19119 +       : "=r" (sum), "=r" (iph), "=r" (ihl)
19120 +       : "1" (iph), "2" (ihl));
19121 +       return(sum);
19122 +}
19123 +
19124 +/*
19125 + *     Fold a partial checksum
19126 + */
19127 +
19128 +static inline unsigned int csum_fold(unsigned int sum)
19129 +{
19130 +       __asm__(
19131 +               "addl %1, %0            ;\n"
19132 +               "adcl $0xffff, %0       ;\n"
19133 +               : "=r" (sum)
19134 +               : "r" (sum << 16), "0" (sum & 0xffff0000)
19135 +       );
19136 +       return (~sum) >> 16;
19137 +}
19138 +
19139 +static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
19140 +                                                  unsigned long daddr,
19141 +                                                  unsigned short len,
19142 +                                                  unsigned short proto,
19143 +                                                  unsigned int sum)
19144 +{
19145 +    __asm__(
19146 +       "addl %1, %0    ;\n"
19147 +       "adcl %2, %0    ;\n"
19148 +       "adcl %3, %0    ;\n"
19149 +       "adcl $0, %0    ;\n"
19150 +       : "=r" (sum)
19151 +       : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum));
19152 +    return sum;
19153 +}
19154 +
19155 +/*
19156 + * computes the checksum of the TCP/UDP pseudo-header
19157 + * returns a 16-bit checksum, already complemented
19158 + */
19159 +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
19160 +                                                  unsigned long daddr,
19161 +                                                  unsigned short len,
19162 +                                                  unsigned short proto,
19163 +                                                  unsigned int sum)
19164 +{
19165 +       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
19166 +}
19167 +
19168 +/*
19169 + * this routine is used for miscellaneous IP-like checksums, mainly
19170 + * in icmp.c
19171 + */
19172 +
19173 +static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
19174 +{
19175 +    return csum_fold (csum_partial(buff, len, 0));
19176 +}
19177 +
19178 +#define _HAVE_ARCH_IPV6_CSUM
19179 +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
19180 +                                                    struct in6_addr *daddr,
19181 +                                                    __u32 len,
19182 +                                                    unsigned short proto,
19183 +                                                    unsigned int sum)
19184 +{
19185 +       __asm__(
19186 +               "addl 0(%1), %0         ;\n"
19187 +               "adcl 4(%1), %0         ;\n"
19188 +               "adcl 8(%1), %0         ;\n"
19189 +               "adcl 12(%1), %0        ;\n"
19190 +               "adcl 0(%2), %0         ;\n"
19191 +               "adcl 4(%2), %0         ;\n"
19192 +               "adcl 8(%2), %0         ;\n"
19193 +               "adcl 12(%2), %0        ;\n"
19194 +               "adcl %3, %0            ;\n"
19195 +               "adcl %4, %0            ;\n"
19196 +               "adcl $0, %0            ;\n"
19197 +               : "=&r" (sum)
19198 +               : "r" (saddr), "r" (daddr),
19199 +                 "r"(htonl(len)), "r"(htonl(proto)), "0"(sum));
19200 +
19201 +       return csum_fold(sum);
19202 +}
19203 +
19204 +/*
19205 + *     Copy and checksum to user
19206 + */
19207 +#define HAVE_CSUM_COPY_USER
19208 +static __inline__ unsigned int csum_and_copy_to_user(const char *src, 
19209 +                                                    char *dst, int len,
19210 +                                                    int sum, int *err_ptr)
19211 +{
19212 +       if (access_ok(VERIFY_WRITE, dst, len))
19213 +               return(csum_partial_copy_to(src, dst, len, sum, err_ptr));
19214 +
19215 +       if (len)
19216 +               *err_ptr = -EFAULT;
19217 +
19218 +       return -1; /* invalid checksum */
19219 +}
19220 +
19221 +#endif
19222 +
19223 +/*
19224 + * Overrides for Emacs so that we follow Linus's tabbing style.
19225 + * Emacs will notice this stuff at the end of the file and automatically
19226 + * adjust the settings for this buffer only.  This must remain at the end
19227 + * of the file.
19228 + * ---------------------------------------------------------------------------
19229 + * Local variables:
19230 + * c-file-style: "linux"
19231 + * End:
19232 + */
19233 Index: linux-2.4.29/arch/um/include/sysdep-i386/frame.h
19234 ===================================================================
19235 --- linux-2.4.29.orig/arch/um/include/sysdep-i386/frame.h       1970-01-01 03:00:00.000000000 +0300
19236 +++ linux-2.4.29/arch/um/include/sysdep-i386/frame.h    2005-05-03 22:28:14.351428464 +0300
19237 @@ -0,0 +1,29 @@
19238 +/* 
19239 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
19240 + * Licensed under the GPL
19241 + */
19242 +
19243 +#ifndef __FRAME_I386_H
19244 +#define __FRAME_I386_H
19245 +
19246 +struct arch_frame_data_raw {
19247 +       unsigned long fp_start;
19248 +       unsigned long sr;
19249 +};
19250 +
19251 +struct arch_frame_data {
19252 +       int fpstate_size;
19253 +};
19254 +
19255 +#endif
19256 +
19257 +/*
19258 + * Overrides for Emacs so that we follow Linus's tabbing style.
19259 + * Emacs will notice this stuff at the end of the file and automatically
19260 + * adjust the settings for this buffer only.  This must remain at the end
19261 + * of the file.
19262 + * ---------------------------------------------------------------------------
19263 + * Local variables:
19264 + * c-file-style: "linux"
19265 + * End:
19266 + */
19267 Index: linux-2.4.29/arch/um/include/sysdep-i386/frame_kern.h
19268 ===================================================================
19269 --- linux-2.4.29.orig/arch/um/include/sysdep-i386/frame_kern.h  1970-01-01 03:00:00.000000000 +0300
19270 +++ linux-2.4.29/arch/um/include/sysdep-i386/frame_kern.h       2005-05-03 22:28:14.352428312 +0300
19271 @@ -0,0 +1,69 @@
19272 +/* 
19273 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
19274 + * Licensed under the GPL
19275 + */
19276 +
19277 +#ifndef __FRAME_KERN_I386_H
19278 +#define __FRAME_KERN_I386_H
19279 +
19280 +/* This is called from sys_sigreturn.  It takes the sp at the point of the
19281 + * sigreturn system call and returns the address of the sigcontext struct
19282 + * on the stack.
19283 + */
19284 +
19285 +static inline void *sp_to_sc(unsigned long sp)
19286 +{
19287 +       return((void *) sp);
19288 +}
19289 +
19290 +static inline void *sp_to_uc(unsigned long sp)
19291 +{
19292 +       unsigned long uc;
19293 +
19294 +       uc = sp + signal_frame_si.uc_index - 
19295 +               signal_frame_si.common.sp_index - 4;
19296 +       return((void *) uc);
19297 +}
19298 +
19299 +static inline void *sp_to_rt_sc(unsigned long sp)
19300 +{
19301 +       unsigned long sc;
19302 +
19303 +       sc = sp - signal_frame_si.common.sp_index + 
19304 +               signal_frame_si.common.len - 4;
19305 +       return((void *) sc);
19306 +}
19307 +
19308 +static inline void *sp_to_mask(unsigned long sp)
19309 +{
19310 +       unsigned long mask;
19311 +
19312 +       mask = sp - signal_frame_sc.common.sp_index + 
19313 +               signal_frame_sc.common.len - 8;
19314 +       return((void *) mask);
19315 +}
19316 +
19317 +extern int sc_size(void *data);
19318 +
19319 +static inline void *sp_to_rt_mask(unsigned long sp)
19320 +{
19321 +       unsigned long mask;
19322 +
19323 +       mask = sp - signal_frame_si.common.sp_index + 
19324 +               signal_frame_si.common.len + 
19325 +               sc_size(&signal_frame_si.common.arch) - 4;
19326 +       return((void *) mask);
19327 +}
19328 +
19329 +#endif
19330 +
19331 +/*
19332 + * Overrides for Emacs so that we follow Linus's tabbing style.
19333 + * Emacs will notice this stuff at the end of the file and automatically
19334 + * adjust the settings for this buffer only.  This must remain at the end
19335 + * of the file.
19336 + * ---------------------------------------------------------------------------
19337 + * Local variables:
19338 + * c-file-style: "linux"
19339 + * End:
19340 + */
19341 Index: linux-2.4.29/arch/um/include/sysdep-i386/frame_user.h
19342 ===================================================================
19343 --- linux-2.4.29.orig/arch/um/include/sysdep-i386/frame_user.h  1970-01-01 03:00:00.000000000 +0300
19344 +++ linux-2.4.29/arch/um/include/sysdep-i386/frame_user.h       2005-05-03 22:28:14.353428160 +0300
19345 @@ -0,0 +1,91 @@
19346 +/* 
19347 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
19348 + * Licensed under the GPL
19349 + */
19350 +
19351 +#ifndef __FRAME_USER_I386_H
19352 +#define __FRAME_USER_I386_H
19353 +
19354 +#include <asm/page.h>
19355 +#include "sysdep/frame.h"
19356 +
19357 +/* This stuff is to calculate the size of the fp state struct at runtime
19358 + * because it has changed between 2.2 and 2.4 and it would be good for a
19359 + * UML compiled on one to work on the other.
19360 + * So, setup_arch_frame_raw fills in the arch struct with the raw data, which
19361 + * just contains the address of the end of the sigcontext.  This is invoked
19362 + * from the signal handler.
19363 + * setup_arch_frame uses that data to figure out what 
19364 + * arch_frame_data.fpstate_size should be.  It really has no idea, since it's
19365 + * not allowed to do sizeof(struct fpstate) but it's safe to consider that it's
19366 + * everything from the end of the sigcontext up to the top of the stack.  So,
19367 + * it masks off the page number to get the offset within the page and subtracts
19368 + * that from the page size, and that's how big the fpstate struct will be
19369 + * considered to be.
19370 + */
19371 +
19372 +static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data,
19373 +                                       void *end, unsigned long srp)
19374 +{
19375 +       unsigned long sr = *((unsigned long *) srp);
19376 +
19377 +       data->fp_start = (unsigned long) end;
19378 +       if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK))
19379 +               data->sr = sr;
19380 +       else data->sr = 0;
19381 +}
19382 +
19383 +static inline void setup_arch_frame(struct arch_frame_data_raw *in, 
19384 +                                   struct arch_frame_data *out)
19385 +{
19386 +       unsigned long fpstate_start = in->fp_start;
19387 +
19388 +       if(in->sr == 0){
19389 +               fpstate_start &= ~PAGE_MASK;
19390 +               out->fpstate_size = PAGE_SIZE - fpstate_start;
19391 +       }
19392 +       else {
19393 +               out->fpstate_size = in->sr - fpstate_start;
19394 +       }
19395 +}
19396 +
19397 +/* This figures out where on the stack the SA_RESTORER function address
19398 + * is stored.  For i386, it's the signal handler return address, so it's
19399 + * located next to the frame pointer.
19400 + * This is inlined, so __builtin_frame_address(0) is correct.  Otherwise,
19401 + * it would have to be __builtin_frame_address(1).
19402 + */
19403 +
19404 +#define frame_restorer() \
19405 +({ \
19406 +       unsigned long *fp; \
19407 +\
19408 +       fp = __builtin_frame_address(0); \
19409 +       ((unsigned long) (fp + 1)); \
19410 +})
19411 +
19412 +/* Similarly, this returns the value of sp when the handler was first
19413 + * entered.  This is used to calculate the proper sp when delivering
19414 + * signals.
19415 + */
19416 +
19417 +#define frame_sp() \
19418 +({ \
19419 +       unsigned long *fp; \
19420 +\
19421 +       fp = __builtin_frame_address(0); \
19422 +       ((unsigned long) (fp + 1)); \
19423 +})
19424 +
19425 +#endif
19426 +
19427 +/*
19428 + * Overrides for Emacs so that we follow Linus's tabbing style.
19429 + * Emacs will notice this stuff at the end of the file and automatically
19430 + * adjust the settings for this buffer only.  This must remain at the end
19431 + * of the file.
19432 + * ---------------------------------------------------------------------------
19433 + * Local variables:
19434 + * c-file-style: "linux"
19435 + * End:
19436 + */
19437 Index: linux-2.4.29/arch/um/include/sysdep-i386/ptrace.h
19438 ===================================================================
19439 --- linux-2.4.29.orig/arch/um/include/sysdep-i386/ptrace.h      1970-01-01 03:00:00.000000000 +0300
19440 +++ linux-2.4.29/arch/um/include/sysdep-i386/ptrace.h   2005-05-03 22:28:14.355427856 +0300
19441 @@ -0,0 +1,193 @@
19442 +/* 
19443 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
19444 + * Licensed under the GPL
19445 + */
19446 +
19447 +#ifndef __SYSDEP_I386_PTRACE_H
19448 +#define __SYSDEP_I386_PTRACE_H
19449 +
19450 +#include "uml-config.h"
19451 +
19452 +#ifdef UML_CONFIG_MODE_TT
19453 +#include "ptrace-tt.h"
19454 +#endif
19455 +
19456 +#ifdef UML_CONFIG_MODE_SKAS
19457 +#include "ptrace-skas.h"
19458 +#endif
19459 +
19460 +#include "choose-mode.h"
19461 +
19462 +union uml_pt_regs {
19463 +#ifdef UML_CONFIG_MODE_TT
19464 +       struct tt_regs {
19465 +               long syscall;
19466 +               void *sc;
19467 +       } tt;
19468 +#endif
19469 +#ifdef UML_CONFIG_MODE_SKAS
19470 +       struct skas_regs {
19471 +               unsigned long regs[HOST_FRAME_SIZE];
19472 +               unsigned long fp[HOST_FP_SIZE];
19473 +               unsigned long xfp[HOST_XFP_SIZE];
19474 +               unsigned long fault_addr;
19475 +               unsigned long fault_type;
19476 +               unsigned long trap_type;
19477 +               long syscall;
19478 +               int is_user;
19479 +       } skas;
19480 +#endif
19481 +};
19482 +
19483 +#define EMPTY_UML_PT_REGS { }
19484 +
19485 +extern int mode_tt;
19486 +
19487 +#define UPT_SC(r) ((r)->tt.sc)
19488 +#define UPT_IP(r) \
19489 +       CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
19490 +#define UPT_SP(r) \
19491 +       CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
19492 +#define UPT_EFLAGS(r) \
19493 +       CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
19494 +#define UPT_EAX(r) \
19495 +       CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs))
19496 +#define UPT_EBX(r) \
19497 +       CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs))
19498 +#define UPT_ECX(r) \
19499 +       CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs))
19500 +#define UPT_EDX(r) \
19501 +       CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs))
19502 +#define UPT_ESI(r) \
19503 +       CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs))
19504 +#define UPT_EDI(r) \
19505 +       CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs))
19506 +#define UPT_EBP(r) \
19507 +       CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs))
19508 +#define UPT_ORIG_EAX(r) \
19509 +       CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
19510 +#define UPT_CS(r) \
19511 +       CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
19512 +#define UPT_SS(r) \
19513 +       CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs))
19514 +#define UPT_DS(r) \
19515 +       CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
19516 +#define UPT_ES(r) \
19517 +       CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
19518 +#define UPT_FS(r) \
19519 +       CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
19520 +#define UPT_GS(r) \
19521 +       CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
19522 +
19523 +#define UPT_SYSCALL_ARG1(r) UPT_EBX(r)
19524 +#define UPT_SYSCALL_ARG2(r) UPT_ECX(r)
19525 +#define UPT_SYSCALL_ARG3(r) UPT_EDX(r)
19526 +#define UPT_SYSCALL_ARG4(r) UPT_ESI(r)
19527 +#define UPT_SYSCALL_ARG5(r) UPT_EDI(r)
19528 +#define UPT_SYSCALL_ARG6(r) UPT_EBP(r)
19529 +
19530 +extern int user_context(unsigned long sp);
19531 +
19532 +#define UPT_IS_USER(r) \
19533 +       CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
19534 +
19535 +struct syscall_args {
19536 +       unsigned long args[6];
19537 +};
19538 +
19539 +#define SYSCALL_ARGS(r) ((struct syscall_args) \
19540 +                        { .args = { UPT_SYSCALL_ARG1(r), \
19541 +                                    UPT_SYSCALL_ARG2(r), \
19542 +                                   UPT_SYSCALL_ARG3(r), \
19543 +                                    UPT_SYSCALL_ARG4(r), \
19544 +                                   UPT_SYSCALL_ARG5(r), \
19545 +                                    UPT_SYSCALL_ARG6(r) } } )
19546 +
19547 +#define UPT_REG(regs, reg) \
19548 +       ({      unsigned long val; \
19549 +               switch(reg){ \
19550 +               case EIP: val = UPT_IP(regs); break; \
19551 +               case UESP: val = UPT_SP(regs); break; \
19552 +               case EAX: val = UPT_EAX(regs); break; \
19553 +               case EBX: val = UPT_EBX(regs); break; \
19554 +               case ECX: val = UPT_ECX(regs); break; \
19555 +               case EDX: val = UPT_EDX(regs); break; \
19556 +               case ESI: val = UPT_ESI(regs); break; \
19557 +               case EDI: val = UPT_EDI(regs); break; \
19558 +               case EBP: val = UPT_EBP(regs); break; \
19559 +               case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \
19560 +               case CS: val = UPT_CS(regs); break; \
19561 +               case SS: val = UPT_SS(regs); break; \
19562 +               case DS: val = UPT_DS(regs); break; \
19563 +               case ES: val = UPT_ES(regs); break; \
19564 +               case FS: val = UPT_FS(regs); break; \
19565 +               case GS: val = UPT_GS(regs); break; \
19566 +               case EFL: val = UPT_EFLAGS(regs); break; \
19567 +               default :  \
19568 +                       panic("Bad register in UPT_REG : %d\n", reg);  \
19569 +                       val = -1; \
19570 +               } \
19571 +               val; \
19572 +       })
19573 +       
19574 +
19575 +#define UPT_SET(regs, reg, val) \
19576 +       do { \
19577 +               switch(reg){ \
19578 +               case EIP: UPT_IP(regs) = val; break; \
19579 +               case UESP: UPT_SP(regs) = val; break; \
19580 +               case EAX: UPT_EAX(regs) = val; break; \
19581 +               case EBX: UPT_EBX(regs) = val; break; \
19582 +               case ECX: UPT_ECX(regs) = val; break; \
19583 +               case EDX: UPT_EDX(regs) = val; break; \
19584 +               case ESI: UPT_ESI(regs) = val; break; \
19585 +               case EDI: UPT_EDI(regs) = val; break; \
19586 +               case EBP: UPT_EBP(regs) = val; break; \
19587 +               case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \
19588 +               case CS: UPT_CS(regs) = val; break; \
19589 +               case SS: UPT_SS(regs) = val; break; \
19590 +               case DS: UPT_DS(regs) = val; break; \
19591 +               case ES: UPT_ES(regs) = val; break; \
19592 +               case FS: UPT_FS(regs) = val; break; \
19593 +               case GS: UPT_GS(regs) = val; break; \
19594 +               case EFL: UPT_EFLAGS(regs) = val; break; \
19595 +               default :  \
19596 +                       panic("Bad register in UPT_SET : %d\n", reg);  \
19597 +                       break; \
19598 +               } \
19599 +       } while (0)
19600 +
19601 +#define UPT_SET_SYSCALL_RETURN(r, res) \
19602 +       CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \
19603 +                    REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
19604 +
19605 +#define UPT_RESTART_SYSCALL(r) \
19606 +       CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
19607 +                   REGS_RESTART_SYSCALL((r)->skas.regs))
19608 +
19609 +#define UPT_ORIG_SYSCALL(r) UPT_EAX(r)
19610 +#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
19611 +#define UPT_SYSCALL_RET(r) UPT_EAX(r)
19612 +
19613 +#define UPT_SEGV_IS_FIXABLE(r) \
19614 +       CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
19615 +                    REGS_SEGV_IS_FIXABLE(&r->skas))
19616 +
19617 +#define UPT_FAULT_ADDR(r) \
19618 +       CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
19619 +
19620 +#define UPT_FAULT_WRITE(r) \
19621 +       CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
19622 +
19623 +#endif
19624 +
19625 +/*
19626 + * Overrides for Emacs so that we follow Linus's tabbing style.
19627 + * Emacs will notice this stuff at the end of the file and automatically
19628 + * adjust the settings for this buffer only.  This must remain at the end
19629 + * of the file.
19630 + * ---------------------------------------------------------------------------
19631 + * Local variables:
19632 + * c-file-style: "linux"
19633 + * End:
19634 + */
19635 Index: linux-2.4.29/arch/um/include/sysdep-i386/ptrace_user.h
19636 ===================================================================
19637 --- linux-2.4.29.orig/arch/um/include/sysdep-i386/ptrace_user.h 1970-01-01 03:00:00.000000000 +0300
19638 +++ linux-2.4.29/arch/um/include/sysdep-i386/ptrace_user.h      2005-05-03 22:28:14.356427704 +0300
19639 @@ -0,0 +1,62 @@
19640 +/* 
19641 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
19642 + * Licensed under the GPL
19643 + */
19644 +
19645 +#ifndef __SYSDEP_I386_PTRACE_USER_H__
19646 +#define __SYSDEP_I386_PTRACE_USER_H__
19647 +
19648 +#include <asm/ptrace.h>
19649 +
19650 +#define PT_OFFSET(r) ((r) * sizeof(long))
19651 +
19652 +#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX])
19653 +#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX)
19654 +
19655 +#define PT_SYSCALL_ARG1_OFFSET PT_OFFSET(EBX)
19656 +#define PT_SYSCALL_ARG2_OFFSET PT_OFFSET(ECX)
19657 +#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX)
19658 +#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI)
19659 +#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI)
19660 +
19661 +#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX)
19662 +
19663 +#define PT_IP_OFFSET PT_OFFSET(EIP)
19664 +#define PT_IP(regs) ((regs)[EIP])
19665 +#define PT_SP(regs) ((regs)[UESP])
19666 +
19667 +#ifndef FRAME_SIZE
19668 +#define FRAME_SIZE (17)
19669 +#endif
19670 +#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long))
19671 +
19672 +#define FP_FRAME_SIZE (27)
19673 +#define FPX_FRAME_SIZE (128)
19674 +
19675 +#ifdef PTRACE_GETREGS
19676 +#define UM_HAVE_GETREGS
19677 +#endif
19678 +
19679 +#ifdef PTRACE_SETREGS
19680 +#define UM_HAVE_SETREGS
19681 +#endif
19682 +
19683 +#ifdef PTRACE_GETFPREGS
19684 +#define UM_HAVE_GETFPREGS
19685 +#endif
19686 +
19687 +#ifdef PTRACE_SETFPREGS
19688 +#define UM_HAVE_SETFPREGS
19689 +#endif
19690 +
19691 +#ifdef PTRACE_GETFPXREGS
19692 +#define UM_HAVE_GETFPXREGS
19693 +#endif
19694 +
19695 +#ifdef PTRACE_SETFPXREGS
19696 +#define UM_HAVE_SETFPXREGS
19697 +#endif
19698 +
19699 +extern void update_debugregs(int seq);
19700 +
19701 +#endif
19702 Index: linux-2.4.29/arch/um/include/sysdep-i386/sigcontext.h
19703 ===================================================================
19704 --- linux-2.4.29.orig/arch/um/include/sysdep-i386/sigcontext.h  1970-01-01 03:00:00.000000000 +0300
19705 +++ linux-2.4.29/arch/um/include/sysdep-i386/sigcontext.h       2005-05-03 22:28:14.357427552 +0300
19706 @@ -0,0 +1,49 @@
19707 +/* 
19708 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
19709 + * Licensed under the GPL
19710 + */
19711 +
19712 +#ifndef __SYS_SIGCONTEXT_I386_H
19713 +#define __SYS_SIGCONTEXT_I386_H
19714 +
19715 +#include "sc.h"
19716 +
19717 +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
19718 +
19719 +#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
19720 +#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
19721 +
19722 +#define SC_FAULT_ADDR(sc) SC_CR2(sc)
19723 +#define SC_FAULT_TYPE(sc) SC_ERR(sc)
19724 +
19725 +#define FAULT_WRITE(err) (err & 2)
19726 +#define TO_SC_ERR(is_write) ((is_write) ? 2 : 0)
19727 +
19728 +#define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc)))
19729 +
19730 +#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
19731 +
19732 +/* ptrace expects that, at the start of a system call, %eax contains
19733 + * -ENOSYS, so this makes it so.
19734 + */
19735 +#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
19736 +
19737 +/* This is Page Fault */
19738 +#define SEGV_IS_FIXABLE(trap) (trap == 14)
19739 +
19740 +#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
19741 +
19742 +extern unsigned long *sc_sigmask(void *sc_ptr);
19743 +extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
19744 +
19745 +#endif
19746 +/*
19747 + * Overrides for Emacs so that we follow Linus's tabbing style.
19748 + * Emacs will notice this stuff at the end of the file and automatically
19749 + * adjust the settings for this buffer only.  This must remain at the end
19750 + * of the file.
19751 + * ---------------------------------------------------------------------------
19752 + * Local variables:
19753 + * c-file-style: "linux"
19754 + * End:
19755 + */
19756 Index: linux-2.4.29/arch/um/include/sysdep-i386/syscalls.h
19757 ===================================================================
19758 --- linux-2.4.29.orig/arch/um/include/sysdep-i386/syscalls.h    1970-01-01 03:00:00.000000000 +0300
19759 +++ linux-2.4.29/arch/um/include/sysdep-i386/syscalls.h 2005-05-03 22:28:14.358427400 +0300
19760 @@ -0,0 +1,61 @@
19761 +/* 
19762 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19763 + * Licensed under the GPL
19764 + */
19765 +
19766 +#include "asm/unistd.h"
19767 +#include "sysdep/ptrace.h"
19768 +
19769 +typedef long syscall_handler_t(struct pt_regs);
19770 +
19771 +#define EXECUTE_SYSCALL(syscall, regs) \
19772 +       ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
19773 +
19774 +extern syscall_handler_t sys_modify_ldt;
19775 +extern syscall_handler_t old_mmap_i386;
19776 +extern syscall_handler_t old_select;
19777 +extern syscall_handler_t sys_ni_syscall;
19778 +
19779 +#define ARCH_SYSCALLS \
19780 +       [ __NR_mmap ] = old_mmap_i386, \
19781 +       [ __NR_select ] = old_select, \
19782 +       [ __NR_vm86old ] = sys_ni_syscall, \
19783 +        [ __NR_modify_ldt ] = sys_modify_ldt, \
19784 +       [ __NR_lchown32 ] = sys_lchown, \
19785 +       [ __NR_getuid32 ] = sys_getuid, \
19786 +       [ __NR_getgid32 ] = sys_getgid, \
19787 +       [ __NR_geteuid32 ] = sys_geteuid, \
19788 +       [ __NR_getegid32 ] = sys_getegid, \
19789 +       [ __NR_setreuid32 ] = sys_setreuid, \
19790 +       [ __NR_setregid32 ] = sys_setregid, \
19791 +       [ __NR_getgroups32 ] = sys_getgroups, \
19792 +       [ __NR_setgroups32 ] = sys_setgroups, \
19793 +       [ __NR_fchown32 ] = sys_fchown, \
19794 +       [ __NR_setresuid32 ] = sys_setresuid, \
19795 +       [ __NR_getresuid32 ] = sys_getresuid, \
19796 +       [ __NR_setresgid32 ] = sys_setresgid, \
19797 +       [ __NR_getresgid32 ] = sys_getresgid, \
19798 +       [ __NR_chown32 ] = sys_chown, \
19799 +       [ __NR_setuid32 ] = sys_setuid, \
19800 +       [ __NR_setgid32 ] = sys_setgid, \
19801 +       [ __NR_setfsuid32 ] = sys_setfsuid, \
19802 +       [ __NR_setfsgid32 ] = sys_setfsgid, \
19803 +       [ __NR_pivot_root ] = sys_pivot_root, \
19804 +       [ __NR_mincore ] = sys_mincore, \
19805 +       [ __NR_madvise ] = sys_madvise, \
19806 +        [ 222 ] = sys_ni_syscall, 
19807 +        
19808 +/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
19809 +
19810 +#define LAST_ARCH_SYSCALL 222
19811 +
19812 +/*
19813 + * Overrides for Emacs so that we follow Linus's tabbing style.
19814 + * Emacs will notice this stuff at the end of the file and automatically
19815 + * adjust the settings for this buffer only.  This must remain at the end
19816 + * of the file.
19817 + * ---------------------------------------------------------------------------
19818 + * Local variables:
19819 + * c-file-style: "linux"
19820 + * End:
19821 + */
19822 Index: linux-2.4.29/arch/um/include/sysdep-ia64/ptrace.h
19823 ===================================================================
19824 --- linux-2.4.29.orig/arch/um/include/sysdep-ia64/ptrace.h      1970-01-01 03:00:00.000000000 +0300
19825 +++ linux-2.4.29/arch/um/include/sysdep-ia64/ptrace.h   2005-05-03 22:28:14.000000000 +0300
19826 @@ -0,0 +1,26 @@
19827 +/* 
19828 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19829 + * Licensed under the GPL
19830 + */
19831 +
19832 +#ifndef __SYSDEP_IA64_PTRACE_H
19833 +#define __SYSDEP_IA64_PTRACE_H
19834 +
19835 +struct sys_pt_regs {
19836 +  int foo;
19837 +};
19838 +
19839 +#define EMPTY_REGS { 0 }
19840 +
19841 +#endif
19842 +
19843 +/*
19844 + * Overrides for Emacs so that we follow Linus's tabbing style.
19845 + * Emacs will notice this stuff at the end of the file and automatically
19846 + * adjust the settings for this buffer only.  This must remain at the end
19847 + * of the file.
19848 + * ---------------------------------------------------------------------------
19849 + * Local variables:
19850 + * c-file-style: "linux"
19851 + * End:
19852 + */
19853 Index: linux-2.4.29/arch/um/include/sysdep-ia64/sigcontext.h
19854 ===================================================================
19855 --- linux-2.4.29.orig/arch/um/include/sysdep-ia64/sigcontext.h  1970-01-01 03:00:00.000000000 +0300
19856 +++ linux-2.4.29/arch/um/include/sysdep-ia64/sigcontext.h       2005-05-03 22:28:14.000000000 +0300
19857 @@ -0,0 +1,20 @@
19858 +/* 
19859 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19860 + * Licensed under the GPL
19861 + */
19862 +
19863 +#ifndef __SYSDEP_IA64_SIGCONTEXT_H
19864 +#define __SYSDEP_IA64_SIGCONTEXT_H
19865 +
19866 +#endif
19867 +
19868 +/*
19869 + * Overrides for Emacs so that we follow Linus's tabbing style.
19870 + * Emacs will notice this stuff at the end of the file and automatically
19871 + * adjust the settings for this buffer only.  This must remain at the end
19872 + * of the file.
19873 + * ---------------------------------------------------------------------------
19874 + * Local variables:
19875 + * c-file-style: "linux"
19876 + * End:
19877 + */
19878 Index: linux-2.4.29/arch/um/include/sysdep-ia64/syscalls.h
19879 ===================================================================
19880 --- linux-2.4.29.orig/arch/um/include/sysdep-ia64/syscalls.h    1970-01-01 03:00:00.000000000 +0300
19881 +++ linux-2.4.29/arch/um/include/sysdep-ia64/syscalls.h 2005-05-03 22:28:14.000000000 +0300
19882 @@ -0,0 +1,20 @@
19883 +/* 
19884 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19885 + * Licensed under the GPL
19886 + */
19887 +
19888 +#ifndef __SYSDEP_IA64_SYSCALLS_H
19889 +#define __SYSDEP_IA64_SYSCALLS_H
19890 +
19891 +#endif
19892 +
19893 +/*
19894 + * Overrides for Emacs so that we follow Linus's tabbing style.
19895 + * Emacs will notice this stuff at the end of the file and automatically
19896 + * adjust the settings for this buffer only.  This must remain at the end
19897 + * of the file.
19898 + * ---------------------------------------------------------------------------
19899 + * Local variables:
19900 + * c-file-style: "linux"
19901 + * End:
19902 + */
19903 Index: linux-2.4.29/arch/um/include/sysdep-ppc/ptrace.h
19904 ===================================================================
19905 --- linux-2.4.29.orig/arch/um/include/sysdep-ppc/ptrace.h       1970-01-01 03:00:00.000000000 +0300
19906 +++ linux-2.4.29/arch/um/include/sysdep-ppc/ptrace.h    2005-05-03 22:28:14.000000000 +0300
19907 @@ -0,0 +1,104 @@
19908 +/* 
19909 + * Licensed under the GPL
19910 + */
19911 +
19912 +#ifndef __SYS_PTRACE_PPC_H
19913 +#define __SYS_PTRACE_PPC_H
19914 +
19915 +#include "linux/config.h"
19916 +#include "linux/types.h"
19917 +
19918 +/* the following taken from <asm-ppc/ptrace.h> */
19919 +
19920 +#ifdef CONFIG_PPC64
19921 +#define PPC_REG unsigned long /*long*/
19922 +#else
19923 +#define PPC_REG unsigned long
19924 +#endif
19925 +struct sys_pt_regs_s {
19926 +       PPC_REG gpr[32];
19927 +       PPC_REG nip;
19928 +       PPC_REG msr;
19929 +       PPC_REG orig_gpr3;      /* Used for restarting system calls */
19930 +       PPC_REG ctr;
19931 +       PPC_REG link;
19932 +       PPC_REG xer;
19933 +       PPC_REG ccr;
19934 +       PPC_REG mq;             /* 601 only (not used at present) */
19935 +                               /* Used on APUS to hold IPL value. */
19936 +       PPC_REG trap;           /* Reason for being here */
19937 +       PPC_REG dar;            /* Fault registers */
19938 +       PPC_REG dsisr;
19939 +       PPC_REG result;         /* Result of a system call */
19940 +};
19941 +
19942 +#define NUM_REGS (sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG))
19943 +
19944 +struct sys_pt_regs {
19945 +    PPC_REG regs[sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG)];
19946 +};
19947 +
19948 +#define UM_MAX_REG (PT_FPR0)
19949 +#define UM_MAX_REG_OFFSET (UM_MAX_REG * sizeof(PPC_REG))
19950 +
19951 +#define EMPTY_REGS { { [ 0 ... NUM_REGS - 1] = 0 } }
19952 +
19953 +#define UM_REG(r, n) ((r)->regs[n])
19954 +
19955 +#define UM_SYSCALL_RET(r) UM_REG(r, PT_R3)
19956 +#define UM_SP(r) UM_REG(r, PT_R1)
19957 +#define UM_IP(r) UM_REG(r, PT_NIP)
19958 +#define UM_ELF_ZERO(r) UM_REG(r, PT_FPSCR)
19959 +#define UM_SYSCALL_NR(r) UM_REG(r, PT_R0)
19960 +#define UM_SYSCALL_ARG1(r) UM_REG(r, PT_ORIG_R3)
19961 +#define UM_SYSCALL_ARG2(r) UM_REG(r, PT_R4)
19962 +#define UM_SYSCALL_ARG3(r) UM_REG(r, PT_R5)
19963 +#define UM_SYSCALL_ARG4(r) UM_REG(r, PT_R6)
19964 +#define UM_SYSCALL_ARG5(r) UM_REG(r, PT_R7)
19965 +#define UM_SYSCALL_ARG6(r) UM_REG(r, PT_R8)
19966 +
19967 +#define UM_SYSCALL_NR_OFFSET (PT_R0 * sizeof(PPC_REG))
19968 +#define UM_SYSCALL_RET_OFFSET (PT_R3 * sizeof(PPC_REG))
19969 +#define UM_SYSCALL_ARG1_OFFSET (PT_R3 * sizeof(PPC_REG))
19970 +#define UM_SYSCALL_ARG2_OFFSET (PT_R4 * sizeof(PPC_REG))
19971 +#define UM_SYSCALL_ARG3_OFFSET (PT_R5 * sizeof(PPC_REG))
19972 +#define UM_SYSCALL_ARG4_OFFSET (PT_R6 * sizeof(PPC_REG))
19973 +#define UM_SYSCALL_ARG5_OFFSET (PT_R7 * sizeof(PPC_REG))
19974 +#define UM_SYSCALL_ARG6_OFFSET (PT_R8 * sizeof(PPC_REG))
19975 +#define UM_SP_OFFSET (PT_R1 * sizeof(PPC_REG))
19976 +#define UM_IP_OFFSET (PT_NIP * sizeof(PPC_REG))
19977 +#define UM_ELF_ZERO_OFFSET (PT_R3 * sizeof(PPC_REG))
19978 +
19979 +#define UM_SET_SYSCALL_RETURN(_regs, result)           \
19980 +do {                                                    \
19981 +        if (result < 0) {                              \
19982 +               (_regs)->regs[PT_CCR] |= 0x10000000;    \
19983 +               UM_SYSCALL_RET((_regs)) = -result;      \
19984 +        } else {                                       \
19985 +               UM_SYSCALL_RET((_regs)) = result;       \
19986 +        }                                               \
19987 +} while(0)
19988 +
19989 +extern void shove_aux_table(unsigned long sp);
19990 +#define UM_FIX_EXEC_STACK(sp) shove_aux_table(sp);
19991 +
19992 +/* These aren't actually defined.  The undefs are just to make sure
19993 + * everyone's clear on the concept.
19994 + */
19995 +#undef UML_HAVE_GETREGS
19996 +#undef UML_HAVE_GETFPREGS
19997 +#undef UML_HAVE_SETREGS
19998 +#undef UML_HAVE_SETFPREGS
19999 +
20000 +#endif
20001 +
20002 +/*
20003 + * Overrides for Emacs so that we follow Linus's tabbing style.
20004 + * Emacs will notice this stuff at the end of the file and automatically
20005 + * adjust the settings for this buffer only.  This must remain at the end
20006 + * of the file.
20007 + * ---------------------------------------------------------------------------
20008 + * Local variables:
20009 + * c-file-style: "linux"
20010 + * End:
20011 + */
20012 Index: linux-2.4.29/arch/um/include/sysdep-ppc/sigcontext.h
20013 ===================================================================
20014 --- linux-2.4.29.orig/arch/um/include/sysdep-ppc/sigcontext.h   1970-01-01 03:00:00.000000000 +0300
20015 +++ linux-2.4.29/arch/um/include/sysdep-ppc/sigcontext.h        2005-05-03 22:28:14.000000000 +0300
20016 @@ -0,0 +1,62 @@
20017 +/* 
20018 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
20019 + * Licensed under the GPL
20020 + */
20021 +
20022 +#ifndef __SYS_SIGCONTEXT_PPC_H
20023 +#define __SYS_SIGCONTEXT_PPC_H
20024 +
20025 +#define DSISR_WRITE 0x02000000
20026 +
20027 +#define SC_FAULT_ADDR(sc) ({ \
20028 +               struct sigcontext *_sc = (sc); \
20029 +               long retval = -1; \
20030 +               switch (_sc->regs->trap) { \
20031 +               case 0x300: \
20032 +                       /* data exception */ \
20033 +                       retval = _sc->regs->dar; \
20034 +                       break; \
20035 +               case 0x400: \
20036 +                       /* instruction exception */ \
20037 +                       retval = _sc->regs->nip; \
20038 +                       break; \
20039 +               default: \
20040 +                       panic("SC_FAULT_ADDR: unhandled trap type\n"); \
20041 +               } \
20042 +               retval; \
20043 +       })
20044 +
20045 +#define SC_FAULT_WRITE(sc) ({ \
20046 +               struct sigcontext *_sc = (sc); \
20047 +               long retval = -1; \
20048 +               switch (_sc->regs->trap) { \
20049 +               case 0x300: \
20050 +                       /* data exception */ \
20051 +                       retval = !!(_sc->regs->dsisr & DSISR_WRITE); \
20052 +                       break; \
20053 +               case 0x400: \
20054 +                       /* instruction exception: not a write */ \
20055 +                       retval = 0; \
20056 +                       break; \
20057 +               default: \
20058 +                       panic("SC_FAULT_ADDR: unhandled trap type\n"); \
20059 +               } \
20060 +               retval; \
20061 +       })
20062 +
20063 +#define SC_IP(sc) ((sc)->regs->nip)
20064 +#define SC_SP(sc) ((sc)->regs->gpr[1])
20065 +#define SEGV_IS_FIXABLE(sc) (1)
20066 +
20067 +#endif
20068 +
20069 +/*
20070 + * Overrides for Emacs so that we follow Linus's tabbing style.
20071 + * Emacs will notice this stuff at the end of the file and automatically
20072 + * adjust the settings for this buffer only.  This must remain at the end
20073 + * of the file.
20074 + * ---------------------------------------------------------------------------
20075 + * Local variables:
20076 + * c-file-style: "linux"
20077 + * End:
20078 + */
20079 Index: linux-2.4.29/arch/um/include/sysdep-ppc/syscalls.h
20080 ===================================================================
20081 --- linux-2.4.29.orig/arch/um/include/sysdep-ppc/syscalls.h     1970-01-01 03:00:00.000000000 +0300
20082 +++ linux-2.4.29/arch/um/include/sysdep-ppc/syscalls.h  2005-05-03 22:28:14.000000000 +0300
20083 @@ -0,0 +1,50 @@
20084 +/* 
20085 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
20086 + * Licensed under the GPL
20087 + */
20088 +
20089 +typedef long syscall_handler_t(unsigned long arg1, unsigned long arg2,
20090 +                              unsigned long arg3, unsigned long arg4,
20091 +                              unsigned long arg5, unsigned long arg6);
20092 +
20093 +#define EXECUTE_SYSCALL(syscall, regs) \
20094 +        (*sys_call_table[syscall])(UM_SYSCALL_ARG1(&regs), \
20095 +                                  UM_SYSCALL_ARG2(&regs), \
20096 +                                  UM_SYSCALL_ARG3(&regs), \
20097 +                                  UM_SYSCALL_ARG4(&regs), \
20098 +                                  UM_SYSCALL_ARG5(&regs), \
20099 +                                  UM_SYSCALL_ARG6(&regs))
20100 +
20101 +extern syscall_handler_t sys_mincore;
20102 +extern syscall_handler_t sys_madvise;
20103 +
20104 +/* old_mmap needs the correct prototype since syscall_kern.c includes
20105 + * this file.
20106 + */
20107 +int old_mmap(unsigned long addr, unsigned long len,
20108 +            unsigned long prot, unsigned long flags,
20109 +            unsigned long fd, unsigned long offset);
20110 +
20111 +#define ARCH_SYSCALLS \
20112 +       [ __NR_modify_ldt ] = sys_ni_syscall, \
20113 +       [ __NR_pciconfig_read ] = sys_ni_syscall, \
20114 +       [ __NR_pciconfig_write ] = sys_ni_syscall, \
20115 +       [ __NR_pciconfig_iobase ] = sys_ni_syscall, \
20116 +       [ __NR_pivot_root ] = sys_ni_syscall, \
20117 +       [ __NR_multiplexer ] = sys_ni_syscall, \
20118 +       [ __NR_mmap ] = old_mmap, \
20119 +       [ __NR_madvise ] = sys_madvise, \
20120 +       [ __NR_mincore ] = sys_mincore, 
20121 +
20122 +#define LAST_ARCH_SYSCALL __NR_mincore
20123 +
20124 +/*
20125 + * Overrides for Emacs so that we follow Linus's tabbing style.
20126 + * Emacs will notice this stuff at the end of the file and automatically
20127 + * adjust the settings for this buffer only.  This must remain at the end
20128 + * of the file.
20129 + * ---------------------------------------------------------------------------
20130 + * Local variables:
20131 + * c-file-style: "linux"
20132 + * End:
20133 + */
20134 Index: linux-2.4.29/arch/um/include/sysrq.h
20135 ===================================================================
20136 --- linux-2.4.29.orig/arch/um/include/sysrq.h   1970-01-01 03:00:00.000000000 +0300
20137 +++ linux-2.4.29/arch/um/include/sysrq.h        2005-05-03 22:28:14.364426488 +0300
20138 @@ -0,0 +1,6 @@
20139 +#ifndef __UM_SYSRQ_H
20140 +#define __UM_SYSRQ_H
20141 +
20142 +extern void show_trace(unsigned long *stack);
20143 +
20144 +#endif
20145 Index: linux-2.4.29/arch/um/include/tempfile.h
20146 ===================================================================
20147 --- linux-2.4.29.orig/arch/um/include/tempfile.h        1970-01-01 03:00:00.000000000 +0300
20148 +++ linux-2.4.29/arch/um/include/tempfile.h     2005-05-03 22:28:14.365426336 +0300
20149 @@ -0,0 +1,21 @@
20150 +/* 
20151 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
20152 + * Licensed under the GPL
20153 + */
20154 +
20155 +#ifndef __TEMPFILE_H__
20156 +#define __TEMPFILE_H__
20157 +
20158 +extern int make_tempfile(const char *template, char **tempname, int do_unlink);
20159 +
20160 +#endif
20161 +/*
20162 + * Overrides for Emacs so that we follow Linus's tabbing style.
20163 + * Emacs will notice this stuff at the end of the file and automatically
20164 + * adjust the settings for this buffer only.  This must remain at the end
20165 + * of the file.
20166 + * ---------------------------------------------------------------------------
20167 + * Local variables:
20168 + * c-file-style: "linux"
20169 + * End:
20170 + */
20171 Index: linux-2.4.29/arch/um/include/time_user.h
20172 ===================================================================
20173 --- linux-2.4.29.orig/arch/um/include/time_user.h       1970-01-01 03:00:00.000000000 +0300
20174 +++ linux-2.4.29/arch/um/include/time_user.h    2005-05-03 22:28:14.366426184 +0300
20175 @@ -0,0 +1,18 @@
20176 +/* 
20177 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
20178 + * Licensed under the GPL
20179 + */
20180 +
20181 +#ifndef __TIME_USER_H__
20182 +#define __TIME_USER_H__
20183 +
20184 +extern void timer(void);
20185 +extern void switch_timers(int to_real);
20186 +extern void set_interval(int timer_type);
20187 +extern void idle_sleep(int secs);
20188 +extern void enable_timer(void);
20189 +extern void disable_timer(void);
20190 +extern unsigned long time_lock(void);
20191 +extern void time_unlock(unsigned long);
20192 +
20193 +#endif
20194 Index: linux-2.4.29/arch/um/include/tlb.h
20195 ===================================================================
20196 --- linux-2.4.29.orig/arch/um/include/tlb.h     1970-01-01 03:00:00.000000000 +0300
20197 +++ linux-2.4.29/arch/um/include/tlb.h  2005-05-03 22:28:14.367426032 +0300
20198 @@ -0,0 +1,23 @@
20199 +/* 
20200 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
20201 + * Licensed under the GPL
20202 + */
20203 +
20204 +#ifndef __TLB_H__
20205 +#define __TLB_H__
20206 +
20207 +extern void mprotect_kernel_vm(int w);
20208 +extern void force_flush_all(void);
20209 +
20210 +#endif
20211 +
20212 +/*
20213 + * Overrides for Emacs so that we follow Linus's tabbing style.
20214 + * Emacs will notice this stuff at the end of the file and automatically
20215 + * adjust the settings for this buffer only.  This must remain at the end
20216 + * of the file.
20217 + * ---------------------------------------------------------------------------
20218 + * Local variables:
20219 + * c-file-style: "linux"
20220 + * End:
20221 + */
20222 Index: linux-2.4.29/arch/um/include/ubd_user.h
20223 ===================================================================
20224 --- linux-2.4.29.orig/arch/um/include/ubd_user.h        1970-01-01 03:00:00.000000000 +0300
20225 +++ linux-2.4.29/arch/um/include/ubd_user.h     2005-05-03 22:28:14.368425880 +0300
20226 @@ -0,0 +1,79 @@
20227 +/* 
20228 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
20229 + * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com)
20230 + * Licensed under the GPL
20231 + */
20232 +
20233 +#ifndef __UM_UBD_USER_H
20234 +#define __UM_UBD_USER_H
20235 +
20236 +#include "os.h"
20237 +
20238 +enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
20239 +
20240 +struct io_thread_req {
20241 +       enum ubd_req op;
20242 +       int fds[2];
20243 +       unsigned long offsets[2];
20244 +       unsigned long long offset;
20245 +       unsigned long length;
20246 +       char *buffer;
20247 +       int sectorsize;
20248 +       unsigned long sector_mask;
20249 +       unsigned long long cow_offset;
20250 +       unsigned long bitmap_words[2];
20251 +       int map_fd;
20252 +       unsigned long long map_offset;
20253 +       int error;
20254 +};
20255 +
20256 +extern int open_ubd_file(char *file, struct openflags *openflags, 
20257 +                        char **backing_file_out, int *bitmap_offset_out, 
20258 +                        unsigned long *bitmap_len_out, int *data_offset_out,
20259 +                        int *create_cow_out);
20260 +extern int create_cow_file(char *cow_file, char *backing_file, 
20261 +                          struct openflags flags, int sectorsize, 
20262 +                          int alignment, int *bitmap_offset_out, 
20263 +                          unsigned long *bitmap_len_out,
20264 +                          int *data_offset_out);
20265 +extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
20266 +extern int read_ubd_fs(int fd, void *buffer, int len);
20267 +extern int write_ubd_fs(int fd, char *buffer, int len);
20268 +extern int start_io_thread(unsigned long sp, int *fds_out);
20269 +extern void do_io(struct io_thread_req *req);
20270 +
20271 +static inline int ubd_test_bit(__u64 bit, unsigned char *data)
20272 +{
20273 +       __u64 n;
20274 +       int bits, off;
20275 +
20276 +       bits = sizeof(data[0]) * 8;
20277 +       n = bit / bits;
20278 +       off = bit % bits;
20279 +       return((data[n] & (1 << off)) != 0);
20280 +}
20281 +
20282 +static inline void ubd_set_bit(__u64 bit, unsigned char *data)
20283 +{
20284 +       __u64 n;
20285 +       int bits, off;
20286 +
20287 +       bits = sizeof(data[0]) * 8;
20288 +       n = bit / bits;
20289 +       off = bit % bits;
20290 +       data[n] |= (1 << off);
20291 +}
20292 +
20293 +
20294 +#endif
20295 +
20296 +/*
20297 + * Overrides for Emacs so that we follow Linus's tabbing style.
20298 + * Emacs will notice this stuff at the end of the file and automatically
20299 + * adjust the settings for this buffer only.  This must remain at the end
20300 + * of the file.
20301 + * ---------------------------------------------------------------------------
20302 + * Local variables:
20303 + * c-file-style: "linux"
20304 + * End:
20305 + */
20306 Index: linux-2.4.29/arch/um/include/umid.h
20307 ===================================================================
20308 --- linux-2.4.29.orig/arch/um/include/umid.h    1970-01-01 03:00:00.000000000 +0300
20309 +++ linux-2.4.29/arch/um/include/umid.h 2005-05-03 22:28:14.368425880 +0300
20310 @@ -0,0 +1,22 @@
20311 +/*
20312 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
20313 + * Licensed under the GPL
20314 + */
20315 +
20316 +#ifndef __UMID_H__
20317 +#define __UMID_H__
20318 +
20319 +extern int umid_file_name(char *name, char *buf, int len);
20320 +
20321 +#endif
20322 +
20323 +/*
20324 + * Overrides for Emacs so that we follow Linus's tabbing style.
20325 + * Emacs will notice this stuff at the end of the file and automatically
20326 + * adjust the settings for this buffer only.  This must remain at the end
20327 + * of the file.
20328 + * ---------------------------------------------------------------------------
20329 + * Local variables:
20330 + * c-file-style: "linux"
20331 + * End:
20332 + */
20333 Index: linux-2.4.29/arch/um/include/uml_uaccess.h
20334 ===================================================================
20335 --- linux-2.4.29.orig/arch/um/include/uml_uaccess.h     1970-01-01 03:00:00.000000000 +0300
20336 +++ linux-2.4.29/arch/um/include/uml_uaccess.h  2005-05-03 22:28:14.369425728 +0300
20337 @@ -0,0 +1,28 @@
20338 +/*
20339 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
20340 + * Licensed under the GPL
20341 + */
20342 +
20343 +#ifndef __UML_UACCESS_H__
20344 +#define __UML_UACCESS_H__
20345 +
20346 +extern int __do_copy_to_user(void *to, const void *from, int n,
20347 +                                 void **fault_addr, void **fault_catcher);
20348 +extern unsigned long __do_user_copy(void *to, const void *from, int n,
20349 +                                   void **fault_addr, void **fault_catcher,
20350 +                                   void (*op)(void *to, const void *from,
20351 +                                              int n), int *faulted_out);
20352 +void __do_copy(void *to, const void *from, int n);
20353 +
20354 +#endif
20355 +
20356 +/*
20357 + * Overrides for Emacs so that we follow Linus's tabbing style.
20358 + * Emacs will notice this stuff at the end of the file and automatically
20359 + * adjust the settings for this buffer only.  This must remain at the end
20360 + * of the file.
20361 + * ---------------------------------------------------------------------------
20362 + * Local variables:
20363 + * c-file-style: "linux"
20364 + * End:
20365 + */
20366 Index: linux-2.4.29/arch/um/include/um_mmu.h
20367 ===================================================================
20368 --- linux-2.4.29.orig/arch/um/include/um_mmu.h  1970-01-01 03:00:00.000000000 +0300
20369 +++ linux-2.4.29/arch/um/include/um_mmu.h       2005-05-03 22:28:14.370425576 +0300
20370 @@ -0,0 +1,40 @@
20371 +/* 
20372 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
20373 + * Licensed under the GPL
20374 + */
20375 +
20376 +#ifndef __ARCH_UM_MMU_H
20377 +#define __ARCH_UM_MMU_H
20378 +
20379 +#include "linux/config.h"
20380 +#include "choose-mode.h"
20381 +
20382 +#ifdef CONFIG_MODE_TT
20383 +#include "../kernel/tt/include/mmu.h"
20384 +#endif
20385 +
20386 +#ifdef CONFIG_MODE_SKAS
20387 +#include "../kernel/skas/include/mmu.h"
20388 +#endif
20389 +
20390 +typedef union {
20391 +#ifdef CONFIG_MODE_TT
20392 +       struct mmu_context_tt tt;
20393 +#endif
20394 +#ifdef CONFIG_MODE_SKAS
20395 +       struct mmu_context_skas skas;
20396 +#endif
20397 +} mm_context_t;
20398 +
20399 +#endif
20400 +
20401 +/*
20402 + * Overrides for Emacs so that we follow Linus's tabbing style.
20403 + * Emacs will notice this stuff at the end of the file and automatically
20404 + * adjust the settings for this buffer only.  This must remain at the end
20405 + * of the file.
20406 + * ---------------------------------------------------------------------------
20407 + * Local variables:
20408 + * c-file-style: "linux"
20409 + * End:
20410 + */
20411 Index: linux-2.4.29/arch/um/include/umn.h
20412 ===================================================================
20413 --- linux-2.4.29.orig/arch/um/include/umn.h     1970-01-01 03:00:00.000000000 +0300
20414 +++ linux-2.4.29/arch/um/include/umn.h  2005-05-03 22:28:14.000000000 +0300
20415 @@ -0,0 +1,27 @@
20416 +/* 
20417 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
20418 + * Licensed under the GPL
20419 + */
20420 +
20421 +#ifndef __UMN_H
20422 +#define __UMN_H
20423 +
20424 +extern int open_umn_tty(int *slave_out, int *slipno_out);
20425 +extern void close_umn_tty(int master, int slave);
20426 +extern int umn_send_packet(int fd, void *data, int len);
20427 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
20428 +extern void slip_unesc(unsigned char s);
20429 +extern void umn_read(int fd);
20430 +
20431 +#endif
20432 +
20433 +/*
20434 + * Overrides for Emacs so that we follow Linus's tabbing style.
20435 + * Emacs will notice this stuff at the end of the file and automatically
20436 + * adjust the settings for this buffer only.  This must remain at the end
20437 + * of the file.
20438 + * ---------------------------------------------------------------------------
20439 + * Local variables:
20440 + * c-file-style: "linux"
20441 + * End:
20442 + */
20443 Index: linux-2.4.29/arch/um/include/um_uaccess.h
20444 ===================================================================
20445 --- linux-2.4.29.orig/arch/um/include/um_uaccess.h      1970-01-01 03:00:00.000000000 +0300
20446 +++ linux-2.4.29/arch/um/include/um_uaccess.h   2005-05-03 22:28:14.372425272 +0300
20447 @@ -0,0 +1,124 @@
20448 +/* 
20449 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
20450 + * Licensed under the GPL
20451 + */
20452 +
20453 +#ifndef __ARCH_UM_UACCESS_H
20454 +#define __ARCH_UM_UACCESS_H
20455 +
20456 +#include "linux/config.h"
20457 +#include "choose-mode.h"
20458 +
20459 +#ifdef CONFIG_MODE_TT
20460 +#include "../kernel/tt/include/uaccess.h"
20461 +#endif
20462 +
20463 +#ifdef CONFIG_MODE_SKAS
20464 +#include "../kernel/skas/include/uaccess.h"
20465 +#endif
20466 +
20467 +#define access_ok(type, addr, size) \
20468 +       CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
20469 +
20470 +static inline int verify_area(int type, const void * addr, unsigned long size)
20471 +{
20472 +       return(CHOOSE_MODE_PROC(verify_area_tt, verify_area_skas, type, addr,
20473 +                               size));
20474 +}
20475 +
20476 +static inline int copy_from_user(void *to, const void *from, int n)
20477 +{
20478 +       return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to,
20479 +                               from, n));
20480 +}
20481 +
20482 +static inline int copy_to_user(void *to, const void *from, int n)
20483 +{
20484 +       return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to, 
20485 +                               from, n));
20486 +}
20487 +
20488 +/*
20489 + * strncpy_from_user: - Copy a NUL terminated string from userspace.
20490 + * @dst:   Destination address, in kernel space.  This buffer must be at
20491 + *         least @count bytes long.
20492 + * @src:   Source address, in user space.
20493 + * @count: Maximum number of bytes to copy, including the trailing NUL.
20494 + * 
20495 + * Copies a NUL-terminated string from userspace to kernel space.
20496 + *
20497 + * On success, returns the length of the string (not including the trailing
20498 + * NUL).
20499 + *
20500 + * If access to userspace fails, returns -EFAULT (some data may have been
20501 + * copied).
20502 + *
20503 + * If @count is smaller than the length of the string, copies @count bytes
20504 + * and returns @count.
20505 + */
20506 +
20507 +static inline int strncpy_from_user(char *dst, const char *src, int count)
20508 +{
20509 +       return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
20510 +                               dst, src, count));
20511 +}
20512 +
20513 +/*
20514 + * __clear_user: - Zero a block of memory in user space, with less checking.
20515 + * @to:   Destination address, in user space.
20516 + * @n:    Number of bytes to zero.
20517 + *
20518 + * Zero a block of memory in user space.  Caller must check
20519 + * the specified block with access_ok() before calling this function.
20520 + *
20521 + * Returns number of bytes that could not be cleared.
20522 + * On success, this will be zero.
20523 + */
20524 +static inline int __clear_user(void *mem, int len)
20525 +{
20526 +       return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
20527 +}
20528 +
20529 +/*
20530 + * clear_user: - Zero a block of memory in user space.
20531 + * @to:   Destination address, in user space.
20532 + * @n:    Number of bytes to zero.
20533 + *
20534 + * Zero a block of memory in user space.
20535 + *
20536 + * Returns number of bytes that could not be cleared.
20537 + * On success, this will be zero.
20538 + */
20539 +static inline int clear_user(void *mem, int len)
20540 +{
20541 +       return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
20542 +}
20543 +
20544 +/*
20545 + * strlen_user: - Get the size of a string in user space.
20546 + * @str: The string to measure.
20547 + * @n:   The maximum valid length
20548 + *
20549 + * Get the size of a NUL-terminated string in user space.
20550 + *
20551 + * Returns the size of the string INCLUDING the terminating NUL.
20552 + * On exception, returns 0.
20553 + * If the string is too long, returns a value greater than @n.
20554 + */
20555 +static inline int strnlen_user(const void *str, int len)
20556 +{
20557 +       return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
20558 +}
20559 +
20560 +#endif
20561 +
20562 +/*
20563 + * Overrides for Emacs so that we follow Linus's tabbing style.
20564 + * Emacs will notice this stuff at the end of the file and automatically
20565 + * adjust the settings for this buffer only.  This must remain at the end
20566 + * of the file.
20567 + * ---------------------------------------------------------------------------
20568 + * Local variables:
20569 + * c-file-style: "linux"
20570 + * End:
20571 + */
20572 Index: linux-2.4.29/arch/um/include/user.h
20573 ===================================================================
20574 --- linux-2.4.29.orig/arch/um/include/user.h    1970-01-01 03:00:00.000000000 +0300
20575 +++ linux-2.4.29/arch/um/include/user.h 2005-05-03 22:28:14.373425120 +0300
20576 @@ -0,0 +1,31 @@
20577 +/* 
20578 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
20579 + * Licensed under the GPL
20580 + */
20581 +
20582 +#ifndef __USER_H__
20583 +#define __USER_H__
20584 +
20585 +extern void panic(const char *fmt, ...);
20586 +extern int printk(const char *fmt, ...);
20587 +extern void schedule(void);
20588 +extern void *um_kmalloc(int size);
20589 +extern void *um_kmalloc_atomic(int size);
20590 +extern void kfree(void *ptr);
20591 +extern int in_aton(char *str);
20592 +extern int open_gdb_chan(void);
20593 +extern void *um_vmalloc(int size);
20594 +extern void vfree(void *ptr);
20595 +
20596 +#endif
20597 +
20598 +/*
20599 + * Overrides for Emacs so that we follow Linus's tabbing style.
20600 + * Emacs will notice this stuff at the end of the file and automatically
20601 + * adjust the settings for this buffer only.  This must remain at the end
20602 + * of the file.
20603 + * ---------------------------------------------------------------------------
20604 + * Local variables:
20605 + * c-file-style: "linux"
20606 + * End:
20607 + */
20608 Index: linux-2.4.29/arch/um/include/user_util.h
20609 ===================================================================
20610 --- linux-2.4.29.orig/arch/um/include/user_util.h       1970-01-01 03:00:00.000000000 +0300
20611 +++ linux-2.4.29/arch/um/include/user_util.h    2005-05-03 22:28:14.374424968 +0300
20612 @@ -0,0 +1,105 @@
20613 +/* 
20614 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
20615 + * Licensed under the GPL
20616 + */
20617 +
20618 +#ifndef __USER_UTIL_H__
20619 +#define __USER_UTIL_H__
20620 +
20621 +#include "sysdep/ptrace.h"
20622 +
20623 +#define CATCH_EINTR(expr) while (((expr) < 0) && (errno == EINTR))
20624 +
20625 +extern int mode_tt;
20626 +
20627 +extern int grantpt(int __fd);
20628 +extern int unlockpt(int __fd);
20629 +extern char *ptsname(int __fd);
20630 +
20631 +struct cpu_task {
20632 +       int pid;
20633 +       void *task;
20634 +};
20635 +
20636 +extern struct cpu_task cpu_tasks[];
20637 +
20638 +struct signal_info {
20639 +       void (*handler)(int, union uml_pt_regs *);
20640 +       int is_irq;
20641 +};
20642 +
20643 +extern struct signal_info sig_info[];
20644 +
20645 +extern unsigned long low_physmem;
20646 +extern unsigned long high_physmem;
20647 +extern unsigned long uml_physmem;
20648 +extern unsigned long uml_reserved;
20649 +extern unsigned long end_vm;
20650 +extern unsigned long start_vm;
20651 +extern unsigned long highmem;
20652 +
20653 +extern char host_info[];
20654 +
20655 +extern char saved_command_line[];
20656 +extern char command_line[];
20657 +
20658 +extern char *tempdir;
20659 +
20660 +extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
20661 +extern unsigned long _unprotected_end;
20662 +extern unsigned long brk_start;
20663 +
20664 +extern int pty_output_sigio;
20665 +extern int pty_close_sigio;
20666 +
20667 +extern void stop(void);
20668 +extern void stack_protections(unsigned long address);
20669 +extern void task_protections(unsigned long address);
20670 +extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
20671 +extern void *add_signal_handler(int sig, void (*handler)(int));
20672 +extern int start_fork_tramp(void *arg, unsigned long temp_stack, 
20673 +                           int clone_flags, int (*tramp)(void *));
20674 +extern int linux_main(int argc, char **argv);
20675 +extern void set_cmdline(char *cmd);
20676 +extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
20677 +extern int get_pty(void);
20678 +extern void *um_kmalloc(int size);
20679 +extern int switcheroo(int fd, int prot, void *from, void *to, int size);
20680 +extern void setup_machinename(char *machine_out);
20681 +extern void setup_hostinfo(void);
20682 +extern void add_arg(char *cmd_line, char *arg);
20683 +extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
20684 +extern void init_new_thread_signals(int altstack);
20685 +extern void do_exec(int old_pid, int new_pid);
20686 +extern void tracer_panic(char *msg, ...);
20687 +extern char *get_umid(int only_if_set);
20688 +extern void do_longjmp(void *p, int val);
20689 +extern int detach(int pid, int sig);
20690 +extern int attach(int pid);
20691 +extern void kill_child_dead(int pid);
20692 +extern int cont(int pid);
20693 +extern void check_ptrace(void);
20694 +extern void check_sigio(void);
20695 +extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
20696 +extern void write_sigio_workaround(void);
20697 +extern void arch_check_bugs(void);
20698 +extern int cpu_feature(char *what, char *buf, int len);
20699 +extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
20700 +extern int arch_fixup(unsigned long address, void *sc_ptr);
20701 +extern int can_do_skas(void);
20702 +extern void arch_init_thread(void);
20703 +extern int setjmp_wrapper(void (*proc)(void *, void *), ...);
20704 +extern int raw(int fd);
20705 +
20706 +#endif
20707 +
20708 +/*
20709 + * Overrides for Emacs so that we follow Linus's tabbing style.
20710 + * Emacs will notice this stuff at the end of the file and automatically
20711 + * adjust the settings for this buffer only.  This must remain at the end
20712 + * of the file.
20713 + * ---------------------------------------------------------------------------
20714 + * Local variables:
20715 + * c-file-style: "linux"
20716 + * End:
20717 + */
20718 Index: linux-2.4.29/arch/um/kernel/checksum.c
20719 ===================================================================
20720 --- linux-2.4.29.orig/arch/um/kernel/checksum.c 1970-01-01 03:00:00.000000000 +0300
20721 +++ linux-2.4.29/arch/um/kernel/checksum.c      2005-05-03 22:28:14.375424816 +0300
20722 @@ -0,0 +1,42 @@
20723 +#include "asm/uaccess.h"
20724 +#include "linux/errno.h"
20725 +
20726 +extern unsigned int arch_csum_partial(const char *buff, int len, int sum);
20727 +
20728 +extern unsigned int csum_partial(char *buff, int len, int sum)
20729 +{
20730 +       return(arch_csum_partial(buff, len, sum));
20731 +}
20732 +
20733 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len, 
20734 +                                 int sum, int *err_ptr)
20735 +{
20736 +       if(copy_to_user(dst, src, len)){
20737 +               *err_ptr = -EFAULT;
20738 +               return(-1);
20739 +       }
20740 +
20741 +       return(arch_csum_partial(src, len, sum));
20742 +}
20743 +
20744 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len, 
20745 +                                   int sum, int *err_ptr)
20746 +{
20747 +       if(copy_from_user(dst, src, len)){
20748 +               *err_ptr = -EFAULT;
20749 +               return(-1);
20750 +       }
20751 +
20752 +       return(arch_csum_partial(dst, len, sum));
20753 +}
20754 +
20755 +/*
20756 + * Overrides for Emacs so that we follow Linus's tabbing style.
20757 + * Emacs will notice this stuff at the end of the file and automatically
20758 + * adjust the settings for this buffer only.  This must remain at the end
20759 + * of the file.
20760 + * ---------------------------------------------------------------------------
20761 + * Local variables:
20762 + * c-file-style: "linux"
20763 + * End:
20764 + */
20765 Index: linux-2.4.29/arch/um/kernel/common.ld.in
20766 ===================================================================
20767 --- linux-2.4.29.orig/arch/um/kernel/common.ld.in       1970-01-01 03:00:00.000000000 +0300
20768 +++ linux-2.4.29/arch/um/kernel/common.ld.in    2005-05-03 22:28:14.000000000 +0300
20769 @@ -0,0 +1,53 @@
20770 +  .kstrtab : { *(.kstrtab) }
20771 +
20772 +  . = ALIGN(16);               /* Exception table */
20773 +  __start___ex_table = .;
20774 +  __ex_table : { *(__ex_table) }
20775 +  __stop___ex_table = .;
20776 +
20777 +  __start___ksymtab = .;       /* Kernel symbol table */
20778 +  __ksymtab : { *(__ksymtab) }
20779 +  __stop___ksymtab = .;
20780 +
20781 +  .unprotected : { *(.unprotected) }
20782 +  . = ALIGN(4096);
20783 +  PROVIDE (_unprotected_end = .);
20784 +
20785 +  . = ALIGN(4096);
20786 +  __uml_setup_start = .;
20787 +  .uml.setup.init : { *(.uml.setup.init) }
20788 +  __uml_setup_end = .;
20789 +  __uml_help_start = .;
20790 +  .uml.help.init : { *(.uml.help.init) }
20791 +  __uml_help_end = .;
20792 +  __uml_postsetup_start = .;
20793 +  .uml.postsetup.init : { *(.uml.postsetup.init) }
20794 +  __uml_postsetup_end = .;
20795 +  __setup_start = .;
20796 +  .setup.init : { *(.setup.init) }
20797 +  __setup_end = .;
20798 +  __initcall_start = .;
20799 +  .initcall.init : { *(.initcall.init) }
20800 +  __initcall_end = .;
20801 +  __uml_initcall_start = .;
20802 +  .uml.initcall.init : { *(.uml.initcall.init) }
20803 +  __uml_initcall_end = .;
20804 +  __init_end = .;
20805 +  __exitcall_begin = .;
20806 +  .exitcall : { *(.exitcall.exit) }
20807 +  __exitcall_end = .;
20808 +  __uml_exitcall_begin = .;
20809 +  .uml.exitcall : { *(.uml.exitcall.exit) }
20810 +  __uml_exitcall_end = .;
20811 +
20812 +  __preinit_array_start = .;
20813 +  .preinit_array : { *(.preinit_array) }
20814 +  __preinit_array_end = .;
20815 +  __init_array_start = .;
20816 +  .init_array : { *(.init_array) }
20817 +  __init_array_end = .;
20818 +  __fini_array_start = .;
20819 +  .fini_array : { *(.fini_array) }
20820 +  __fini_array_end = .;
20821 +
20822 +  .data.init : { *(.data.init) }
20823 Index: linux-2.4.29/arch/um/kernel/config.c.in
20824 ===================================================================
20825 --- linux-2.4.29.orig/arch/um/kernel/config.c.in        1970-01-01 03:00:00.000000000 +0300
20826 +++ linux-2.4.29/arch/um/kernel/config.c.in     2005-05-03 22:28:14.406420104 +0300
20827 @@ -0,0 +1,32 @@
20828 +/* 
20829 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
20830 + * Licensed under the GPL
20831 + */
20832 +
20833 +#include <stdio.h>
20834 +#include <stdlib.h>
20835 +#include "init.h"
20836 +
20837 +static __initdata char *config = "CONFIG";
20838 +
20839 +static int __init print_config(char *line, int *add)
20840 +{
20841 +       printf("%s", config);
20842 +       exit(0);
20843 +}
20844 +
20845 +__uml_setup("--showconfig", print_config,
20846 +"--showconfig\n"
20847 +"    Prints the config file that this UML binary was generated from.\n\n"
20848 +);
20849 +
20850 +/*
20851 + * Overrides for Emacs so that we follow Linus's tabbing style.
20852 + * Emacs will notice this stuff at the end of the file and automatically
20853 + * adjust the settings for this buffer only.  This must remain at the end
20854 + * of the file.
20855 + * ---------------------------------------------------------------------------
20856 + * Local variables:
20857 + * c-file-style: "linux"
20858 + * End:
20859 + */
20860 Index: linux-2.4.29/arch/um/kernel/dyn_link.ld.in
20861 ===================================================================
20862 --- linux-2.4.29.orig/arch/um/kernel/dyn_link.ld.in     1970-01-01 03:00:00.000000000 +0300
20863 +++ linux-2.4.29/arch/um/kernel/dyn_link.ld.in  2005-05-03 22:28:14.000000000 +0300
20864 @@ -0,0 +1,169 @@
20865 +OUTPUT_FORMAT("ELF_FORMAT")
20866 +OUTPUT_ARCH(ELF_ARCH)
20867 +ENTRY(_start)
20868 +
20869 +SECTIONS
20870 +{
20871 +  . = START() + SIZEOF_HEADERS;
20872 +  .interp         : { *(.interp) }
20873 +  __binary_start = .;
20874 +  . = ALIGN(4096);             /* Init code and data */
20875 +  _stext = .;
20876 +  __init_begin = .;
20877 +  .text.init : { *(.text.init) }
20878 +
20879 +  . = ALIGN(4096);
20880 +
20881 +  /* Read-only sections, merged into text segment: */
20882 +  .hash           : { *(.hash) }
20883 +  .dynsym         : { *(.dynsym) }
20884 +  .dynstr         : { *(.dynstr) }
20885 +  .gnu.version    : { *(.gnu.version) }
20886 +  .gnu.version_d  : { *(.gnu.version_d) }
20887 +  .gnu.version_r  : { *(.gnu.version_r) }
20888 +  .rel.init       : { *(.rel.init) }
20889 +  .rela.init      : { *(.rela.init) }
20890 +  .rel.text       : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
20891 +  .rela.text      : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
20892 +  .rel.fini       : { *(.rel.fini) }
20893 +  .rela.fini      : { *(.rela.fini) }
20894 +  .rel.rodata     : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
20895 +  .rela.rodata    : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
20896 +  .rel.data       : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
20897 +  .rela.data      : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
20898 +  .rel.tdata     : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
20899 +  .rela.tdata    : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
20900 +  .rel.tbss      : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
20901 +  .rela.tbss     : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
20902 +  .rel.ctors      : { *(.rel.ctors) }
20903 +  .rela.ctors     : { *(.rela.ctors) }
20904 +  .rel.dtors      : { *(.rel.dtors) }
20905 +  .rela.dtors     : { *(.rela.dtors) }
20906 +  .rel.got        : { *(.rel.got) }
20907 +  .rela.got       : { *(.rela.got) }
20908 +  .rel.bss        : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
20909 +  .rela.bss       : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
20910 +  .rel.plt        : { *(.rel.plt) }
20911 +  .rela.plt       : { *(.rela.plt) }
20912 +  .init           : {
20913 +    KEEP (*(.init))
20914 +  } =0x90909090
20915 +  .plt            : { *(.plt) }
20916 +  .text           : {
20917 +    *(.text .stub .text.* .gnu.linkonce.t.*)
20918 +    /* .gnu.warning sections are handled specially by elf32.em.  */
20919 +    *(.gnu.warning)
20920 +  } =0x90909090
20921 +  .fini           : {
20922 +    KEEP (*(.fini))
20923 +  } =0x90909090
20924 +
20925 +  PROVIDE (__etext = .);
20926 +  PROVIDE (_etext = .);
20927 +  PROVIDE (etext = .);
20928 +  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
20929 +  .rodata1        : { *(.rodata1) }
20930 +  .eh_frame_hdr : { *(.eh_frame_hdr) }
20931 +
20932 +
20933 +  . = ALIGN(4096);
20934 +  PROVIDE (_sdata = .);
20935 +
20936 +include(`arch/um/kernel/common.ld.in')
20937 +
20938 +  /* Ensure the __preinit_array_start label is properly aligned.  We
20939 +     could instead move the label definition inside the section, but
20940 +     the linker would then create the section even if it turns out to
20941 +     be empty, which isn't pretty.  */
20942 +  . = ALIGN(32 / 8);
20943 +  .preinit_array     : { *(.preinit_array) }
20944 +  .init_array     : { *(.init_array) }
20945 +  .fini_array     : { *(.fini_array) }
20946 +  .data           : {
20947 +    . = ALIGN(KERNEL_STACK_SIZE);              /* init_task */
20948 +    *(.data.init_task)
20949 +    *(.data .data.* .gnu.linkonce.d.*)
20950 +    SORT(CONSTRUCTORS)
20951 +  }
20952 +  .data1          : { *(.data1) }
20953 +  .tdata         : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
20954 +  .tbss                  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
20955 +  .eh_frame       : { KEEP (*(.eh_frame)) }
20956 +  .gcc_except_table   : { *(.gcc_except_table) }
20957 +  .dynamic        : { *(.dynamic) }
20958 +  .ctors          : {
20959 +    /* gcc uses crtbegin.o to find the start of
20960 +       the constructors, so we make sure it is
20961 +       first.  Because this is a wildcard, it
20962 +       doesn't matter if the user does not
20963 +       actually link against crtbegin.o; the
20964 +       linker won't look for a file to match a
20965 +       wildcard.  The wildcard also means that it
20966 +       doesn't matter which directory crtbegin.o
20967 +       is in.  */
20968 +    KEEP (*crtbegin.o(.ctors))
20969 +    /* We don't want to include the .ctor section from
20970 +       from the crtend.o file until after the sorted ctors.
20971 +       The .ctor section from the crtend file contains the
20972 +       end of ctors marker and it must be last */
20973 +    KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
20974 +    KEEP (*(SORT(.ctors.*)))
20975 +    KEEP (*(.ctors))
20976 +  }
20977 +  .dtors          : {
20978 +    KEEP (*crtbegin.o(.dtors))
20979 +    KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
20980 +    KEEP (*(SORT(.dtors.*)))
20981 +    KEEP (*(.dtors))
20982 +  }
20983 +  .jcr            : { KEEP (*(.jcr)) }
20984 +  .got            : { *(.got.plt) *(.got) }
20985 +  _edata = .;
20986 +  PROVIDE (edata = .);
20987 +  __bss_start = .;
20988 +  .bss            : {
20989 +   *(.dynbss)
20990 +   *(.bss .bss.* .gnu.linkonce.b.*)
20991 +   *(COMMON)
20992 +   /* Align here to ensure that the .bss section occupies space up to
20993 +      _end.  Align after .bss to ensure correct alignment even if the
20994 +      .bss section disappears because there are no input sections.  */
20995 +   . = ALIGN(32 / 8);
20996 +  . = ALIGN(32 / 8);
20997 +  }
20998 +  _end = .;
20999 +  PROVIDE (end = .);
21000 +   /* Stabs debugging sections.  */
21001 +  .stab          0 : { *(.stab) }
21002 +  .stabstr       0 : { *(.stabstr) }
21003 +  .stab.excl     0 : { *(.stab.excl) }
21004 +  .stab.exclstr  0 : { *(.stab.exclstr) }
21005 +  .stab.index    0 : { *(.stab.index) }
21006 +  .stab.indexstr 0 : { *(.stab.indexstr) }
21007 +  .comment       0 : { *(.comment) }
21008 +  /* DWARF debug sections.
21009 +     Symbols in the DWARF debugging sections are relative to the beginning
21010 +     of the section so we begin them at 0.  */
21011 +  /* DWARF 1 */
21012 +  .debug          0 : { *(.debug) }
21013 +  .line           0 : { *(.line) }
21014 +  /* GNU DWARF 1 extensions */
21015 +  .debug_srcinfo  0 : { *(.debug_srcinfo) }
21016 +  .debug_sfnames  0 : { *(.debug_sfnames) }
21017 +  /* DWARF 1.1 and DWARF 2 */
21018 +  .debug_aranges  0 : { *(.debug_aranges) }
21019 +  .debug_pubnames 0 : { *(.debug_pubnames) }
21020 +  /* DWARF 2 */
21021 +  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
21022 +  .debug_abbrev   0 : { *(.debug_abbrev) }
21023 +  .debug_line     0 : { *(.debug_line) }
21024 +  .debug_frame    0 : { *(.debug_frame) }
21025 +  .debug_str      0 : { *(.debug_str) }
21026 +  .debug_loc      0 : { *(.debug_loc) }
21027 +  .debug_macinfo  0 : { *(.debug_macinfo) }
21028 +  /* SGI/MIPS DWARF 2 extensions */
21029 +  .debug_weaknames 0 : { *(.debug_weaknames) }
21030 +  .debug_funcnames 0 : { *(.debug_funcnames) }
21031 +  .debug_typenames 0 : { *(.debug_typenames) }
21032 +  .debug_varnames  0 : { *(.debug_varnames) }
21033 +}
21034 Index: linux-2.4.29/arch/um/kernel/exec_kern.c
21035 ===================================================================
21036 --- linux-2.4.29.orig/arch/um/kernel/exec_kern.c        1970-01-01 03:00:00.000000000 +0300
21037 +++ linux-2.4.29/arch/um/kernel/exec_kern.c     2005-05-03 22:28:14.408419800 +0300
21038 @@ -0,0 +1,86 @@
21039 +/* 
21040 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
21041 + * Licensed under the GPL
21042 + */
21043 +
21044 +#include "linux/slab.h"
21045 +#include "linux/smp_lock.h"
21046 +#include "asm/ptrace.h"
21047 +#include "asm/pgtable.h"
21048 +#include "asm/pgalloc.h"
21049 +#include "asm/uaccess.h"
21050 +#include "user_util.h"
21051 +#include "kern_util.h"
21052 +#include "mem_user.h"
21053 +#include "kern.h"
21054 +#include "irq_user.h"
21055 +#include "tlb.h"
21056 +#include "2_5compat.h"
21057 +#include "os.h"
21058 +#include "time_user.h"
21059 +#include "choose-mode.h"
21060 +#include "mode_kern.h"
21061 +
21062 +void flush_thread(void)
21063 +{
21064 +       CHOOSE_MODE(flush_thread_tt(), flush_thread_skas());
21065 +}
21066 +
21067 +void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
21068 +{
21069 +       CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
21070 +}
21071 +
21072 +extern void log_exec(char **argv, void *tty);
21073 +
21074 +static int execve1(char *file, char **argv, char **env)
21075 +{
21076 +        int error;
21077 +
21078 +#ifdef CONFIG_TTY_LOG
21079 +       log_exec(argv, current->tty);
21080 +#endif
21081 +        error = do_execve(file, argv, env, &current->thread.regs);
21082 +        if (error == 0){
21083 +                current->ptrace &= ~PT_DTRACE;
21084 +                set_cmdline(current_cmd());
21085 +        }
21086 +        return(error);
21087 +}
21088 +
21089 +int um_execve(char *file, char **argv, char **env)
21090 +{
21091 +       int err;
21092 +
21093 +       err = execve1(file, argv, env);
21094 +       if(!err) 
21095 +               do_longjmp(current->thread.exec_buf, 1);
21096 +       return(err);
21097 +}
21098 +
21099 +int sys_execve(char *file, char **argv, char **env)
21100 +{
21101 +       int error;
21102 +       char *filename;
21103 +
21104 +       lock_kernel();
21105 +       filename = getname((char *) file);
21106 +       error = PTR_ERR(filename);
21107 +       if (IS_ERR(filename)) goto out;
21108 +       error = execve1(filename, argv, env);
21109 +       putname(filename);
21110 + out:
21111 +       unlock_kernel();
21112 +       return(error);
21113 +}
21114 +
21115 +/*
21116 + * Overrides for Emacs so that we follow Linus's tabbing style.
21117 + * Emacs will notice this stuff at the end of the file and automatically
21118 + * adjust the settings for this buffer only.  This must remain at the end
21119 + * of the file.
21120 + * ---------------------------------------------------------------------------
21121 + * Local variables:
21122 + * c-file-style: "linux"
21123 + * End:
21124 + */
21125 Index: linux-2.4.29/arch/um/kernel/exitcode.c
21126 ===================================================================
21127 --- linux-2.4.29.orig/arch/um/kernel/exitcode.c 1970-01-01 03:00:00.000000000 +0300
21128 +++ linux-2.4.29/arch/um/kernel/exitcode.c      2005-05-03 22:28:14.409419648 +0300
21129 @@ -0,0 +1,73 @@
21130 +/* 
21131 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
21132 + * Licensed under the GPL
21133 + */
21134 +
21135 +#include "linux/init.h"
21136 +#include "linux/ctype.h"
21137 +#include "linux/proc_fs.h"
21138 +#include "asm/uaccess.h"
21139 +
21140 +/* If read and write race, the read will still atomically read a valid
21141 + * value.
21142 + */
21143 +int uml_exitcode = 0;
21144 +
21145 +static int read_proc_exitcode(char *page, char **start, off_t off,
21146 +                             int count, int *eof, void *data)
21147 +{
21148 +       int len;
21149 +
21150 +       len = sprintf(page, "%d\n", uml_exitcode);
21151 +       len -= off;
21152 +       if(len <= off+count) *eof = 1;
21153 +       *start = page + off;
21154 +       if(len > count) len = count;
21155 +       if(len < 0) len = 0;
21156 +       return(len);
21157 +}
21158 +
21159 +static int write_proc_exitcode(struct file *file, const char *buffer,
21160 +                              unsigned long count, void *data)
21161 +{
21162 +       char *end, buf[sizeof("nnnnn\0")];
21163 +       int tmp;
21164 +
21165 +       if(copy_from_user(buf, buffer, count))
21166 +               return(-EFAULT);
21167 +       tmp = simple_strtol(buf, &end, 0);
21168 +       if((*end != '\0') && !isspace(*end))
21169 +               return(-EINVAL);
21170 +       uml_exitcode = tmp;
21171 +       return(count);
21172 +}
21173 +
21174 +static int make_proc_exitcode(void)
21175 +{
21176 +       struct proc_dir_entry *ent;
21177 +
21178 +       ent = create_proc_entry("exitcode", 0600, &proc_root);
21179 +       if(ent == NULL){
21180 +               printk("make_proc_exitcode : Failed to register "
21181 +                      "/proc/exitcode\n");
21182 +               return(0);
21183 +       }
21184 +
21185 +       ent->read_proc = read_proc_exitcode;
21186 +       ent->write_proc = write_proc_exitcode;
21187 +       
21188 +       return(0);
21189 +}
21190 +
21191 +__initcall(make_proc_exitcode);
21192 +
21193 +/*
21194 + * Overrides for Emacs so that we follow Linus's tabbing style.
21195 + * Emacs will notice this stuff at the end of the file and automatically
21196 + * adjust the settings for this buffer only.  This must remain at the end
21197 + * of the file.
21198 + * ---------------------------------------------------------------------------
21199 + * Local variables:
21200 + * c-file-style: "linux"
21201 + * End:
21202 + */
21203 Index: linux-2.4.29/arch/um/kernel/filehandle.c
21204 ===================================================================
21205 --- linux-2.4.29.orig/arch/um/kernel/filehandle.c       1970-01-01 03:00:00.000000000 +0300
21206 +++ linux-2.4.29/arch/um/kernel/filehandle.c    2005-05-03 22:28:14.410419496 +0300
21207 @@ -0,0 +1,250 @@
21208 +/* 
21209 + * Copyright (C) 2004 Jeff Dike (jdike@karaya.com)
21210 + * Licensed under the GPL
21211 + */
21212 +
21213 +#include "linux/slab.h"
21214 +#include "linux/list.h"
21215 +#include "linux/spinlock.h"
21216 +#include "linux/fs.h"
21217 +#include "linux/errno.h"
21218 +#include "filehandle.h"
21219 +#include "os.h"
21220 +#include "kern_util.h"
21221 +
21222 +static spinlock_t open_files_lock = SPIN_LOCK_UNLOCKED;
21223 +static struct list_head open_files = LIST_HEAD_INIT(open_files);
21224 +
21225 +#define NUM_RECLAIM 128
21226 +
21227 +static void reclaim_fds(void)
21228 +{
21229 +       struct file_handle *victim;
21230 +       int closed = NUM_RECLAIM;
21231 +
21232 +       spin_lock(&open_files_lock);
21233 +       while(!list_empty(&open_files) && closed--){
21234 +               victim = list_entry(open_files.prev, struct file_handle, list);
21235 +               os_close_file(victim->fd);
21236 +               victim->fd = -1;
21237 +               list_del_init(&victim->list);
21238 +       }
21239 +       spin_unlock(&open_files_lock);
21240 +}
21241 +
21242 +int open_file(char *name, struct openflags flags, int mode)
21243 +{
21244 +       int fd;
21245 +
21246 +       fd = os_open_file(name, flags, mode);
21247 +       if(fd != -EMFILE)
21248 +               return(fd);
21249 +
21250 +       reclaim_fds();
21251 +       fd = os_open_file(name, flags, mode);
21252 +
21253 +       return(fd);
21254 +}
21255 +
21256 +void *open_dir(char *file)
21257 +{
21258 +       void *dir;
21259 +       int err;
21260 +
21261 +       dir = os_open_dir(file, &err);
21262 +       if(dir != NULL)
21263 +               return(dir);
21264 +       if(err != -EMFILE)
21265 +               return(ERR_PTR(err));
21266 +
21267 +       reclaim_fds();
21268 +
21269 +       dir = os_open_dir(file, &err);
21270 +       if(dir == NULL)
21271 +               dir = ERR_PTR(err);
21272 +
21273 +       return(dir);
21274 +}
21275 +
21276 +void not_reclaimable(struct file_handle *fh)
21277 +{
21278 +       char *name;
21279 +
21280 +       if(fh->get_name == NULL)
21281 +               return;
21282 +
21283 +       if(list_empty(&fh->list)){
21284 +               name = (*fh->get_name)(fh->inode);
21285 +               if(name != NULL){
21286 +                       fh->fd = open_file(name, fh->flags, 0);
21287 +                       kfree(name);
21288 +               }
21289 +               else printk("File descriptor %d has no name\n", fh->fd);
21290 +       }
21291 +       else {
21292 +               spin_lock(&open_files_lock);
21293 +               list_del_init(&fh->list);
21294 +               spin_unlock(&open_files_lock);
21295 +       }
21296 +}
21297 +
21298 +void is_reclaimable(struct file_handle *fh, char *(name_proc)(struct inode *),
21299 +                   struct inode *inode)
21300 +{
21301 +       fh->get_name = name_proc;
21302 +       fh->inode = inode;
21303 +
21304 +       spin_lock(&open_files_lock);
21305 +       list_add(&fh->list, &open_files);
21306 +       spin_unlock(&open_files_lock);
21307 +}
21308 +
21309 +static int active_handle(struct file_handle *fh)
21310 +{
21311 +       int fd;
21312 +       char *name;
21313 +
21314 +       if(!list_empty(&fh->list))
21315 +               list_move(&fh->list, &open_files);
21316 +
21317 +       if(fh->fd != -1)
21318 +               return(0);
21319 +
21320 +       if(fh->inode == NULL)
21321 +               return(-ENOENT);
21322 +
21323 +       name = (*fh->get_name)(fh->inode);
21324 +       if(name == NULL)
21325 +               return(-ENOMEM);
21326 +
21327 +       fd = open_file(name, fh->flags, 0);
21328 +       kfree(name);
21329 +       if(fd < 0)
21330 +               return(fd);
21331 +
21332 +       fh->fd = fd;
21333 +       is_reclaimable(fh, fh->get_name, fh->inode);
21334 +
21335 +       return(0);
21336 +}
21337 +
21338 +int filehandle_fd(struct file_handle *fh)
21339 +{
21340 +       int err;
21341 +
21342 +       err = active_handle(fh);
21343 +       if(err)
21344 +               return(err);
21345 +
21346 +       return(fh->fd);
21347 +}
21348 +
21349 +static void init_fh(struct file_handle *fh, int fd, struct openflags flags)
21350 +{
21351 +       flags.c = 0;
21352 +       *fh = ((struct file_handle) { .list     = LIST_HEAD_INIT(fh->list),
21353 +                                     .fd       = fd,
21354 +                                     .get_name = NULL,
21355 +                                     .inode    = NULL,
21356 +                                     .flags    = flags });
21357 +}
21358 +
21359 +int open_filehandle(char *name, struct openflags flags, int mode, 
21360 +                   struct file_handle *fh)
21361 +{
21362 +       int fd;
21363 +
21364 +       fd = open_file(name, flags, mode);
21365 +       if(fd < 0)
21366 +               return(fd);
21367 +
21368 +       init_fh(fh, fd, flags);
21369 +       return(0);
21370 +}
21371 +
21372 +int close_file(struct file_handle *fh)
21373 +{
21374 +       spin_lock(&open_files_lock);
21375 +       list_del(&fh->list);
21376 +       spin_unlock(&open_files_lock);
21377 +
21378 +       os_close_file(fh->fd);
21379 +
21380 +       fh->fd = -1;
21381 +       return(0);
21382 +}
21383 +
21384 +int read_file(struct file_handle *fh, unsigned long long offset, char *buf,
21385 +             int len)
21386 +{
21387 +       int err;
21388 +
21389 +       err = active_handle(fh);
21390 +       if(err)
21391 +               return(err);
21392 +
21393 +       err = os_seek_file(fh->fd, offset);
21394 +       if(err)
21395 +               return(err);
21396 +
21397 +       return(os_read_file(fh->fd, buf, len));
21398 +}
21399 +
21400 +int write_file(struct file_handle *fh, unsigned long long offset, 
21401 +              const char *buf, int len)
21402 +{
21403 +       int err;
21404 +
21405 +       err = active_handle(fh);
21406 +       if(err)
21407 +               return(err);
21408 +
21409 +       if(offset != -1)
21410 +               err = os_seek_file(fh->fd, offset);
21411 +       if(err)
21412 +               return(err);
21413 +
21414 +       return(os_write_file(fh->fd, buf, len));
21415 +}
21416 +
21417 +int truncate_file(struct file_handle *fh, unsigned long long size)
21418 +{
21419 +       int err;
21420 +
21421 +       err = active_handle(fh);
21422 +       if(err)
21423 +               return(err);
21424 +
21425 +       return(os_truncate_fd(fh->fd, size));
21426 +}
21427 +
21428 +int make_pipe(struct file_handle *fhs)
21429 +{
21430 +       int fds[2], err;
21431 +
21432 +       err = os_pipe(fds, 1, 1);
21433 +       if(err && (err != -EMFILE))
21434 +               return(err);
21435 +
21436 +       if(err){
21437 +               reclaim_fds();
21438 +               err = os_pipe(fds, 1, 1);
21439 +       }
21440 +       if(err)
21441 +               return(err);
21442 +
21443 +       init_fh(&fhs[0], fds[0], OPENFLAGS());
21444 +       init_fh(&fhs[1], fds[1], OPENFLAGS());
21445 +       return(0);
21446 +}
21447 +
21448 +/*
21449 + * Overrides for Emacs so that we follow Linus's tabbing style.
21450 + * Emacs will notice this stuff at the end of the file and automatically
21451 + * adjust the settings for this buffer only.  This must remain at the end
21452 + * of the file.
21453 + * ---------------------------------------------------------------------------
21454 + * Local variables:
21455 + * c-file-style: "linux"
21456 + * End:
21457 + */
21458 Index: linux-2.4.29/arch/um/kernel/frame.c
21459 ===================================================================
21460 --- linux-2.4.29.orig/arch/um/kernel/frame.c    1970-01-01 03:00:00.000000000 +0300
21461 +++ linux-2.4.29/arch/um/kernel/frame.c 2005-05-03 22:28:14.412419192 +0300
21462 @@ -0,0 +1,343 @@
21463 +/* 
21464 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
21465 + * Licensed under the GPL
21466 + */
21467 +
21468 +#include <stdio.h>
21469 +#include <stdlib.h>
21470 +#include <unistd.h>
21471 +#include <string.h>
21472 +#include <signal.h>
21473 +#include <wait.h>
21474 +#include <sched.h>
21475 +#include <errno.h>
21476 +#include <sys/ptrace.h>
21477 +#include <sys/syscall.h>
21478 +#include <sys/mman.h>
21479 +#include <asm/page.h>
21480 +#include <asm/ptrace.h>
21481 +#include <asm/sigcontext.h>
21482 +#include "sysdep/ptrace.h"
21483 +#include "sysdep/sigcontext.h"
21484 +#include "frame_user.h"
21485 +#include "kern_util.h"
21486 +#include "user_util.h"
21487 +#include "ptrace_user.h"
21488 +#include "os.h"
21489 +
21490 +static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
21491 +                        unsigned long top, void **data_out)
21492 +{
21493 +       unsigned long regs[FRAME_SIZE];
21494 +       int pid, status, n, len;
21495 +
21496 +       /* Start the child as a thread */
21497 +       pid = clone(child, sp, CLONE_VM | SIGCHLD, arg);
21498 +       if(pid < 0){
21499 +               printf("capture_stack : clone failed - errno = %d\n", errno);
21500 +               exit(1);
21501 +       }
21502 +
21503 +       /* Wait for it to stop itself and continue it with a SIGUSR1 to force 
21504 +        * it into the signal handler.
21505 +        */
21506 +       CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
21507 +       if(n < 0){
21508 +               printf("capture_stack : waitpid failed - errno = %d\n", errno);
21509 +               exit(1);
21510 +       }
21511 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
21512 +               fprintf(stderr, "capture_stack : Expected SIGSTOP, "
21513 +                       "got status = 0x%x\n", status);
21514 +               exit(1);
21515 +       }
21516 +       if(ptrace(PTRACE_CONT, pid, 0, SIGUSR1) < 0){
21517 +               printf("capture_stack : PTRACE_CONT failed - errno = %d\n", 
21518 +                      errno);
21519 +               exit(1);
21520 +       }
21521 +
21522 +       /* Wait for it to stop itself again and grab its registers again.  
21523 +        * At this point, the handler has stuffed the addresses of
21524 +        * sig, sc, and SA_RESTORER in raw.
21525 +        */
21526 +       CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
21527 +       if(n < 0){
21528 +               printf("capture_stack : waitpid failed - errno = %d\n", errno);
21529 +               exit(1);
21530 +       }
21531 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
21532 +               fprintf(stderr, "capture_stack : Expected SIGSTOP, "
21533 +                       "got status = 0x%x\n", status);
21534 +               exit(1);
21535 +       }
21536 +       if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0){
21537 +               printf("capture_stack : PTRACE_GETREGS failed - errno = %d\n", 
21538 +                      errno);
21539 +               exit(1);
21540 +       }
21541 +
21542 +       /* It has outlived its usefulness, so continue it so it can exit */
21543 +       if(ptrace(PTRACE_CONT, pid, 0, 0) < 0){
21544 +               printf("capture_stack : PTRACE_CONT failed - errno = %d\n", 
21545 +                      errno);
21546 +               exit(1);
21547 +       }
21548 +       CATCH_EINTR(n = waitpid(pid, &status, 0));
21549 +       if(n < 0){
21550 +               printf("capture_stack : waitpid failed - errno = %d\n", errno);
21551 +               exit(1);
21552 +       }
21553 +       if(!WIFSIGNALED(status) || (WTERMSIG(status) != 9)){
21554 +               printf("capture_stack : Expected exit signal 9, "
21555 +                      "got status = 0x%x\n", status);
21556 +               exit(1);
21557 +       }
21558 +
21559 +       /* The frame that we want is the top of the signal stack */
21560 +
21561 +       len = top - PT_SP(regs);
21562 +       *data_out = malloc(len);
21563 +       if(*data_out == NULL){
21564 +               printf("capture_stack : malloc failed - errno = %d\n", errno);
21565 +               exit(1);
21566 +       }
21567 +       memcpy(*data_out, (void *) PT_SP(regs), len);
21568 +
21569 +       return(len);
21570 +}
21571 +
21572 +struct common_raw {
21573 +       void *stack;
21574 +       int size;
21575 +       unsigned long sig;
21576 +       unsigned long sr;
21577 +       unsigned long sp;       
21578 +       struct arch_frame_data_raw arch;
21579 +};
21580 +
21581 +#define SA_RESTORER (0x04000000)
21582 +
21583 +typedef unsigned long old_sigset_t;
21584 +
21585 +struct old_sigaction {
21586 +       __sighandler_t handler;
21587 +       old_sigset_t sa_mask;
21588 +       unsigned long sa_flags;
21589 +       void (*sa_restorer)(void);
21590 +};
21591 +
21592 +static void child_common(struct common_raw *common, sighandler_t handler,
21593 +                        int restorer, int flags)
21594 +{
21595 +       stack_t ss = ((stack_t) { .ss_sp        = common->stack,
21596 +                                 .ss_flags     = 0,
21597 +                                 .ss_size      = common->size });
21598 +       int err;
21599 +
21600 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
21601 +               printf("PTRACE_TRACEME failed, errno = %d\n", errno);
21602 +       }
21603 +       if(sigaltstack(&ss, NULL) < 0){
21604 +               printf("sigaltstack failed - errno = %d\n", errno);
21605 +               kill(getpid(), SIGKILL);
21606 +       }
21607 +
21608 +       if(restorer){
21609 +               struct sigaction sa;
21610 +
21611 +               sa.sa_handler = handler;
21612 +               sigemptyset(&sa.sa_mask);
21613 +               sa.sa_flags = SA_ONSTACK | flags;
21614 +               err = sigaction(SIGUSR1, &sa, NULL);
21615 +       }
21616 +       else {
21617 +               struct old_sigaction sa;
21618 +
21619 +               sa.handler = handler;
21620 +               sa.sa_mask = 0;
21621 +               sa.sa_flags = (SA_ONSTACK | flags) & ~SA_RESTORER;
21622 +               err = syscall(__NR_sigaction, SIGUSR1, &sa, NULL);
21623 +       }
21624 +       
21625 +       if(err < 0){
21626 +               printf("sigaction failed - errno = %d\n", errno);
21627 +               kill(getpid(), SIGKILL);
21628 +       }
21629 +
21630 +       os_stop_process(os_getpid());
21631 +}
21632 +
21633 +/* Changed only during early boot */
21634 +struct sc_frame signal_frame_sc;
21635 +
21636 +struct sc_frame signal_frame_sc_sr;
21637 +
21638 +struct sc_frame_raw {
21639 +       struct common_raw common;
21640 +       unsigned long sc;
21641 +       int restorer;
21642 +};
21643 +
21644 +/* Changed only during early boot */
21645 +static struct sc_frame_raw *raw_sc = NULL;
21646 +
21647 +static void sc_handler(int sig, struct sigcontext sc)
21648 +{
21649 +       raw_sc->common.sig = (unsigned long) &sig;
21650 +       raw_sc->common.sr = frame_restorer();
21651 +       raw_sc->common.sp = frame_sp();
21652 +       raw_sc->sc = (unsigned long) &sc;
21653 +       setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr);
21654 +
21655 +       os_stop_process(os_getpid());
21656 +       kill(getpid(), SIGKILL);
21657 +}
21658 +
21659 +static int sc_child(void *arg)
21660 +{
21661 +       raw_sc = arg;
21662 +       child_common(&raw_sc->common, (sighandler_t) sc_handler, 
21663 +                    raw_sc->restorer, 0);
21664 +       return(-1);
21665 +}
21666 +
21667 +/* Changed only during early boot */
21668 +struct si_frame signal_frame_si;
21669 +
21670 +struct si_frame_raw {
21671 +       struct common_raw common;
21672 +       unsigned long sip;
21673 +       unsigned long si;
21674 +       unsigned long ucp;
21675 +       unsigned long uc;
21676 +};
21677 +
21678 +/* Changed only during early boot */
21679 +static struct si_frame_raw *raw_si = NULL;
21680 +
21681 +static void si_handler(int sig, siginfo_t *si, struct ucontext *ucontext)
21682 +{
21683 +       raw_si->common.sig = (unsigned long) &sig;
21684 +       raw_si->common.sr = frame_restorer();
21685 +       raw_si->common.sp = frame_sp();
21686 +       raw_si->sip = (unsigned long) &si;
21687 +       raw_si->si = (unsigned long) si;
21688 +       raw_si->ucp = (unsigned long) &ucontext;
21689 +       raw_si->uc = (unsigned long) ucontext;
21690 +       setup_arch_frame_raw(&raw_si->common.arch, 
21691 +                            ucontext->uc_mcontext.fpregs, raw_si->common.sr);
21692 +       
21693 +       os_stop_process(os_getpid());
21694 +       kill(getpid(), SIGKILL);
21695 +}
21696 +
21697 +static int si_child(void *arg)
21698 +{
21699 +       raw_si = arg;
21700 +       child_common(&raw_si->common, (sighandler_t) si_handler, 1, 
21701 +                    SA_SIGINFO);
21702 +       return(-1);
21703 +}
21704 +
21705 +static int relative_sr(unsigned long sr, int sr_index, void *stack, 
21706 +                      void *framep)
21707 +{
21708 +       unsigned long *srp = (unsigned long *) sr;
21709 +       unsigned long frame = (unsigned long) framep;
21710 +
21711 +       if((*srp & PAGE_MASK) == (unsigned long) stack){
21712 +               *srp -= sr;
21713 +               *((unsigned long *) (frame + sr_index)) = *srp;
21714 +               return(1);
21715 +       }
21716 +       else return(0);
21717 +}
21718 +
21719 +static unsigned long capture_stack_common(int (*proc)(void *), void *arg, 
21720 +                                         struct common_raw *common_in, 
21721 +                                         void *top, void *sigstack, 
21722 +                                         int stack_len, 
21723 +                                         struct frame_common *common_out)
21724 +{
21725 +       unsigned long sig_top = (unsigned long) sigstack + stack_len, base;
21726 +
21727 +       common_in->stack = (void *) sigstack;
21728 +       common_in->size = stack_len;
21729 +       common_out->len = capture_stack(proc, arg, top, sig_top, 
21730 +                                       &common_out->data);
21731 +       base = sig_top - common_out->len;
21732 +       common_out->sig_index = common_in->sig - base;
21733 +       common_out->sp_index = common_in->sp - base;
21734 +       common_out->sr_index = common_in->sr - base;
21735 +       common_out->sr_relative = relative_sr(common_in->sr, 
21736 +                                             common_out->sr_index, sigstack, 
21737 +                                             common_out->data);
21738 +       return(base);
21739 +}
21740 +
21741 +void capture_signal_stack(void)
21742 +{
21743 +       struct sc_frame_raw raw_sc;
21744 +       struct si_frame_raw raw_si;
21745 +       void *stack, *sigstack;
21746 +       unsigned long top, base;
21747 +
21748 +       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
21749 +                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
21750 +       sigstack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
21751 +                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
21752 +       if((stack == MAP_FAILED) || (sigstack == MAP_FAILED)){
21753 +               printf("capture_signal_stack : mmap failed - errno = %d\n", 
21754 +                      errno);
21755 +               exit(1);
21756 +       }
21757 +
21758 +       top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
21759 +
21760 +       /* Get the sigcontext, no sigrestorer layout */
21761 +       raw_sc.restorer = 0;
21762 +       base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common, 
21763 +                                   (void *) top, sigstack, PAGE_SIZE, 
21764 +                                   &signal_frame_sc.common);
21765 +
21766 +       signal_frame_sc.sc_index = raw_sc.sc - base;
21767 +       setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc.common.arch);
21768 +
21769 +       /* Ditto for the sigcontext, sigrestorer layout */
21770 +       raw_sc.restorer = 1;
21771 +       base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common, 
21772 +                                   (void *) top, sigstack, PAGE_SIZE, 
21773 +                                   &signal_frame_sc_sr.common);
21774 +       signal_frame_sc_sr.sc_index = raw_sc.sc - base;
21775 +       setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc_sr.common.arch);
21776 +
21777 +       /* And the siginfo layout */
21778 +
21779 +       base = capture_stack_common(si_child, &raw_si, &raw_si.common, 
21780 +                                   (void *) top, sigstack, PAGE_SIZE, 
21781 +                                   &signal_frame_si.common);
21782 +       signal_frame_si.sip_index = raw_si.sip - base;
21783 +       signal_frame_si.si_index = raw_si.si - base;
21784 +       signal_frame_si.ucp_index = raw_si.ucp - base;
21785 +       signal_frame_si.uc_index = raw_si.uc - base;
21786 +       setup_arch_frame(&raw_si.common.arch, &signal_frame_si.common.arch);
21787 +
21788 +       if((munmap(stack, PAGE_SIZE) < 0) || 
21789 +          (munmap(sigstack, PAGE_SIZE) < 0)){
21790 +               printf("capture_signal_stack : munmap failed - errno = %d\n", 
21791 +                      errno);
21792 +               exit(1);
21793 +       }
21794 +}
21795 +
21796 +/*
21797 + * Overrides for Emacs so that we follow Linus's tabbing style.
21798 + * Emacs will notice this stuff at the end of the file and automatically
21799 + * adjust the settings for this buffer only.  This must remain at the end
21800 + * of the file.
21801 + * ---------------------------------------------------------------------------
21802 + * Local variables:
21803 + * c-file-style: "linux"
21804 + * End:
21805 + */
21806 Index: linux-2.4.29/arch/um/kernel/frame_kern.c
21807 ===================================================================
21808 --- linux-2.4.29.orig/arch/um/kernel/frame_kern.c       1970-01-01 03:00:00.000000000 +0300
21809 +++ linux-2.4.29/arch/um/kernel/frame_kern.c    2005-05-03 22:28:14.413419040 +0300
21810 @@ -0,0 +1,173 @@
21811 +/* 
21812 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
21813 + * Licensed under the GPL
21814 + */
21815 +
21816 +#include "asm/ptrace.h"
21817 +#include "asm/uaccess.h"
21818 +#include "asm/signal.h"
21819 +#include "asm/ucontext.h"
21820 +#include "frame_kern.h"
21821 +#include "sigcontext.h"
21822 +#include "sysdep/ptrace.h"
21823 +#include "choose-mode.h"
21824 +#include "mode.h"
21825 +
21826 +int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
21827 +{
21828 +       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
21829 +               return -EFAULT;
21830 +       if (from->si_code < 0)
21831 +               return __copy_to_user(to, from, sizeof(siginfo_t));
21832 +       else {
21833 +               int err;
21834 +
21835 +               /* If you change siginfo_t structure, please be sure
21836 +                  this code is fixed accordingly.
21837 +                  It should never copy any pad contained in the structure
21838 +                  to avoid security leaks, but must copy the generic
21839 +                  3 ints plus the relevant union member.  */
21840 +               err = __put_user(from->si_signo, &to->si_signo);
21841 +               err |= __put_user(from->si_errno, &to->si_errno);
21842 +               err |= __put_user((short)from->si_code, &to->si_code);
21843 +               /* First 32bits of unions are always present.  */
21844 +               err |= __put_user(from->si_pid, &to->si_pid);
21845 +               switch (from->si_code >> 16) {
21846 +               case __SI_FAULT >> 16:
21847 +                       break;
21848 +               case __SI_CHLD >> 16:
21849 +                       err |= __put_user(from->si_utime, &to->si_utime);
21850 +                       err |= __put_user(from->si_stime, &to->si_stime);
21851 +                       err |= __put_user(from->si_status, &to->si_status);
21852 +               default:
21853 +                       err |= __put_user(from->si_uid, &to->si_uid);
21854 +                       break;
21855 +               }
21856 +               return err;
21857 +       }
21858 +}
21859 +
21860 +static int copy_restorer(void (*restorer)(void), unsigned long start, 
21861 +                        unsigned long sr_index, int sr_relative)
21862 +{
21863 +       unsigned long sr;
21864 +
21865 +       if(sr_relative){
21866 +               sr = (unsigned long) restorer;
21867 +               sr += start + sr_index;
21868 +               restorer = (void (*)(void)) sr;
21869 +       }
21870 +
21871 +       return(copy_to_user((void *) (start + sr_index), &restorer, 
21872 +                           sizeof(restorer)));
21873 +}
21874 +
21875 +extern int userspace_pid[];
21876 +
21877 +static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from, 
21878 +                          struct arch_frame_data *arch)
21879 +{
21880 +       return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 
21881 +                                             arch),
21882 +                          copy_sc_to_user_skas(userspace_pid[0], to, fp, 
21883 +                                               &from->regs,
21884 +                                               current->thread.cr2,
21885 +                                               current->thread.err)));
21886 +}
21887 +
21888 +static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set,
21889 +                                unsigned long sp)
21890 +{
21891 +       int err = 0;
21892 +
21893 +       err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
21894 +       err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
21895 +       err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
21896 +       err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs,
21897 +                              &signal_frame_si.common.arch);
21898 +       err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
21899 +       return(err);
21900 +}
21901 +
21902 +int setup_signal_stack_si(unsigned long stack_top, int sig, 
21903 +                         unsigned long handler, void (*restorer)(void), 
21904 +                         struct pt_regs *regs, siginfo_t *info, 
21905 +                         sigset_t *mask)
21906 +{
21907 +       unsigned long start;
21908 +       void *sip, *ucp, *fp;
21909 +
21910 +       start = stack_top - signal_frame_si.common.len;
21911 +       sip = (void *) (start + signal_frame_si.si_index);
21912 +       ucp = (void *) (start + signal_frame_si.uc_index);
21913 +       fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext));
21914 +
21915 +       if(restorer == NULL)
21916 +               panic("setup_signal_stack_si - no restorer");
21917 +
21918 +       if(copy_to_user((void *) start, signal_frame_si.common.data,
21919 +                       signal_frame_si.common.len) ||
21920 +          copy_to_user((void *) (start + signal_frame_si.common.sig_index), 
21921 +                       &sig, sizeof(sig)) ||
21922 +          copy_siginfo_to_user(sip, info) ||
21923 +          copy_to_user((void *) (start + signal_frame_si.sip_index), &sip,
21924 +                       sizeof(sip)) ||
21925 +          copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) ||
21926 +          copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp,
21927 +                       sizeof(ucp)) ||
21928 +          copy_restorer(restorer, start, signal_frame_si.common.sr_index,
21929 +                        signal_frame_si.common.sr_relative))
21930 +               return(1);
21931 +       
21932 +       PT_REGS_IP(regs) = handler;
21933 +       PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
21934 +       return(0);
21935 +}
21936 +
21937 +int setup_signal_stack_sc(unsigned long stack_top, int sig, 
21938 +                         unsigned long handler, void (*restorer)(void), 
21939 +                         struct pt_regs *regs, sigset_t *mask)
21940 +{
21941 +       struct frame_common *frame = &signal_frame_sc_sr.common;
21942 +       void *user_sc;
21943 +       int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
21944 +       unsigned long sigs, sr;
21945 +       unsigned long start = stack_top - frame->len - sig_size;
21946 +
21947 +       user_sc = (void *) (start + signal_frame_sc_sr.sc_index);
21948 +       if(restorer == NULL){
21949 +               frame = &signal_frame_sc.common;
21950 +               user_sc = (void *) (start + signal_frame_sc.sc_index);
21951 +               sr = (unsigned long) frame->data;
21952 +               sr += frame->sr_index;
21953 +               sr = *((unsigned long *) sr);
21954 +               restorer = ((void (*)(void)) sr);
21955 +       }
21956 +
21957 +       sigs = start + frame->len;
21958 +       if(copy_to_user((void *) start, frame->data, frame->len) ||
21959 +          copy_to_user((void *) (start + frame->sig_index), &sig, 
21960 +                       sizeof(sig)) ||
21961 +          copy_sc_to_user(user_sc, NULL, regs, 
21962 +                          &signal_frame_sc.common.arch) ||
21963 +          copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) ||
21964 +          copy_to_user((void *) sigs, &mask->sig[1], sig_size) ||
21965 +          copy_restorer(restorer, start, frame->sr_index, frame->sr_relative))
21966 +               return(1);
21967 +
21968 +       PT_REGS_IP(regs) = handler;
21969 +       PT_REGS_SP(regs) = start + frame->sp_index;
21970 +
21971 +       return(0);
21972 +}
21973 +
21974 +/*
21975 + * Overrides for Emacs so that we follow Linus's tabbing style.
21976 + * Emacs will notice this stuff at the end of the file and automatically
21977 + * adjust the settings for this buffer only.  This must remain at the end
21978 + * of the file.
21979 + * ---------------------------------------------------------------------------
21980 + * Local variables:
21981 + * c-file-style: "linux"
21982 + * End:
21983 + */
21984 Index: linux-2.4.29/arch/um/kernel/gmon_syms.c
21985 ===================================================================
21986 --- linux-2.4.29.orig/arch/um/kernel/gmon_syms.c        1970-01-01 03:00:00.000000000 +0300
21987 +++ linux-2.4.29/arch/um/kernel/gmon_syms.c     2005-05-03 22:28:14.000000000 +0300
21988 @@ -0,0 +1,20 @@
21989 +/* 
21990 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
21991 + * Licensed under the GPL
21992 + */
21993 +
21994 +#include "linux/module.h"
21995 +
21996 +extern void __bb_init_func(void *);
21997 +EXPORT_SYMBOL(__bb_init_func);
21998 +
21999 +/*
22000 + * Overrides for Emacs so that we follow Linus's tabbing style.
22001 + * Emacs will notice this stuff at the end of the file and automatically
22002 + * adjust the settings for this buffer only.  This must remain at the end
22003 + * of the file.
22004 + * ---------------------------------------------------------------------------
22005 + * Local variables:
22006 + * c-file-style: "linux"
22007 + * End:
22008 + */
22009 Index: linux-2.4.29/arch/um/kernel/gprof_syms.c
22010 ===================================================================
22011 --- linux-2.4.29.orig/arch/um/kernel/gprof_syms.c       1970-01-01 03:00:00.000000000 +0300
22012 +++ linux-2.4.29/arch/um/kernel/gprof_syms.c    2005-05-03 22:28:14.000000000 +0300
22013 @@ -0,0 +1,20 @@
22014 +/* 
22015 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
22016 + * Licensed under the GPL
22017 + */
22018 +
22019 +#include "linux/module.h"
22020 +
22021 +extern void mcount(void);
22022 +EXPORT_SYMBOL(mcount);
22023 +
22024 +/*
22025 + * Overrides for Emacs so that we follow Linus's tabbing style.
22026 + * Emacs will notice this stuff at the end of the file and automatically
22027 + * adjust the settings for this buffer only.  This must remain at the end
22028 + * of the file.
22029 + * ---------------------------------------------------------------------------
22030 + * Local variables:
22031 + * c-file-style: "linux"
22032 + * End:
22033 + */
22034 Index: linux-2.4.29/arch/um/kernel/helper.c
22035 ===================================================================
22036 --- linux-2.4.29.orig/arch/um/kernel/helper.c   1970-01-01 03:00:00.000000000 +0300
22037 +++ linux-2.4.29/arch/um/kernel/helper.c        2005-05-03 22:28:14.416418584 +0300
22038 @@ -0,0 +1,167 @@
22039 +/* 
22040 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22041 + * Licensed under the GPL
22042 + */
22043 +
22044 +#include <stdio.h>
22045 +#include <stdlib.h>
22046 +#include <unistd.h>
22047 +#include <errno.h>
22048 +#include <sched.h>
22049 +#include <sys/signal.h>
22050 +#include <sys/wait.h>
22051 +#include "user.h"
22052 +#include "kern_util.h"
22053 +#include "user_util.h"
22054 +#include "os.h"
22055 +
22056 +struct helper_data {
22057 +       void (*pre_exec)(void*);
22058 +       void *pre_data;
22059 +       char **argv;
22060 +       int fd;
22061 +};
22062 +
22063 +/* Debugging aid, changed only from gdb */
22064 +int helper_pause = 0;
22065 +
22066 +static void helper_hup(int sig)
22067 +{
22068 +}
22069 +
22070 +static int helper_child(void *arg)
22071 +{
22072 +       struct helper_data *data = arg;
22073 +       char **argv = data->argv;
22074 +       int errval;
22075 +
22076 +       if(helper_pause){
22077 +               signal(SIGHUP, helper_hup);
22078 +               pause();
22079 +       }
22080 +       if(data->pre_exec != NULL)
22081 +               (*data->pre_exec)(data->pre_data);
22082 +       execvp(argv[0], argv);
22083 +       errval = errno;
22084 +       printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
22085 +       os_write_file(data->fd, &errval, sizeof(errval));
22086 +       os_kill_process(os_getpid(), 0);
22087 +       return(0);
22088 +}
22089 +
22090 +/* XXX The alloc_stack here breaks if this is called in the tracing thread */
22091 +
22092 +int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
22093 +              unsigned long *stack_out)
22094 +{
22095 +       struct helper_data data;
22096 +       unsigned long stack, sp;
22097 +       int pid, fds[2], err, n;
22098 +
22099 +       if((stack_out != NULL) && (*stack_out != 0))
22100 +               stack = *stack_out;
22101 +       else stack = alloc_stack(0, um_in_interrupt());
22102 +       if(stack == 0) 
22103 +               return(-ENOMEM);
22104 +
22105 +       err = os_pipe(fds, 1, 0);
22106 +       if(err < 0){
22107 +               printk("run_helper : pipe failed, err = %d\n", -err);
22108 +               goto out_free;
22109 +       }
22110 +
22111 +       err = os_set_exec_close(fds[1], 1);
22112 +       if(err < 0){
22113 +               printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
22114 +                      -err);
22115 +               goto out_close;
22116 +       }
22117 +
22118 +       sp = stack + page_size() - sizeof(void *);
22119 +       data.pre_exec = pre_exec;
22120 +       data.pre_data = pre_data;
22121 +       data.argv = argv;
22122 +       data.fd = fds[1];
22123 +       pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
22124 +       if(pid < 0){
22125 +               printk("run_helper : clone failed, errno = %d\n", errno);
22126 +               err = -errno;
22127 +               goto out_close;
22128 +       }
22129 +
22130 +       os_close_file(fds[1]);
22131 +       n = os_read_file(fds[0], &err, sizeof(err));
22132 +       if(n < 0){
22133 +               printk("run_helper : read on pipe failed, err = %d\n", -n);
22134 +               err = n;
22135 +               os_kill_process(pid, 1);
22136 +       }
22137 +       else if(n != 0){
22138 +               CATCH_EINTR(n = waitpid(pid, NULL, 0));
22139 +               pid = -errno;
22140 +       }
22141 +       err = pid;
22142 +
22143 + out_close:
22144 +       os_close_file(fds[0]);
22145 + out_free:
22146 +       if(stack_out == NULL) 
22147 +               free_stack(stack, 0);
22148 +        else *stack_out = stack;
22149 +       return(err);
22150 +}
22151 +
22152 +int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, 
22153 +                     unsigned long *stack_out, int stack_order)
22154 +{
22155 +       unsigned long stack, sp;
22156 +       int pid, status;
22157 +
22158 +       stack = alloc_stack(stack_order, um_in_interrupt());
22159 +       if(stack == 0) return(-ENOMEM);
22160 +
22161 +       sp = stack + (page_size() << stack_order) - sizeof(void *);
22162 +       pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
22163 +       if(pid < 0){
22164 +               printk("run_helper_thread : clone failed, errno = %d\n", 
22165 +                      errno);
22166 +               return(-errno);
22167 +       }
22168 +       if(stack_out == NULL){
22169 +               CATCH_EINTR(pid = waitpid(pid, &status, 0));
22170 +               if(pid < 0){
22171 +                       printk("run_helper_thread - wait failed, errno = %d\n",
22172 +                              errno);
22173 +                       pid = -errno;
22174 +               }
22175 +               if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
22176 +                       printk("run_helper_thread - thread returned status "
22177 +                              "0x%x\n", status);
22178 +               free_stack(stack, stack_order);
22179 +       }
22180 +        else *stack_out = stack;
22181 +       return(pid);
22182 +}
22183 +
22184 +int helper_wait(int pid, int block)
22185 +{
22186 +       int ret;
22187 +
22188 +       CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG));
22189 +       if(ret < 0){
22190 +               printk("helper_wait : waitpid failed, errno = %d\n", errno);
22191 +               return(-errno);
22192 +       }
22193 +       return(ret);
22194 +}
22195 +
22196 +/*
22197 + * Overrides for Emacs so that we follow Linus's tabbing style.
22198 + * Emacs will notice this stuff at the end of the file and automatically
22199 + * adjust the settings for this buffer only.  This must remain at the end
22200 + * of the file.
22201 + * ---------------------------------------------------------------------------
22202 + * Local variables:
22203 + * c-file-style: "linux"
22204 + * End:
22205 + */
22206 Index: linux-2.4.29/arch/um/kernel/initrd_kern.c
22207 ===================================================================
22208 --- linux-2.4.29.orig/arch/um/kernel/initrd_kern.c      1970-01-01 03:00:00.000000000 +0300
22209 +++ linux-2.4.29/arch/um/kernel/initrd_kern.c   2005-05-03 22:28:14.417418432 +0300
22210 @@ -0,0 +1,59 @@
22211 +/*
22212 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
22213 + * Licensed under the GPL
22214 + */
22215 +
22216 +#include "linux/init.h"
22217 +#include "linux/bootmem.h"
22218 +#include "linux/blk.h"
22219 +#include "asm/types.h"
22220 +#include "user_util.h"
22221 +#include "kern_util.h"
22222 +#include "initrd.h"
22223 +#include "init.h"
22224 +#include "os.h"
22225 +
22226 +/* Changed by uml_initrd_setup, which is a setup */
22227 +static char *initrd __initdata = NULL;
22228 +
22229 +static int __init read_initrd(void)
22230 +{
22231 +       void *area;
22232 +       long long size;
22233 +       int err;
22234 +
22235 +       if(initrd == NULL) return 0;
22236 +       err = os_file_size(initrd, &size);
22237 +       if(err) return 0;
22238 +       area = alloc_bootmem(size);
22239 +       if(area == NULL) return 0;
22240 +       if(load_initrd(initrd, area, size) == -1) return 0;
22241 +       initrd_start = (unsigned long) area;
22242 +       initrd_end = initrd_start + size;
22243 +       return 0;
22244 +}
22245 +
22246 +__uml_postsetup(read_initrd);
22247 +
22248 +static int __init uml_initrd_setup(char *line, int *add)
22249 +{
22250 +       initrd = line;
22251 +       return 0;
22252 +}
22253 +
22254 +__uml_setup("initrd=", uml_initrd_setup, 
22255 +"initrd=<initrd image>\n"
22256 +"    This is used to boot UML from an initrd image.  The argument is the\n"
22257 +"    name of the file containing the image.\n\n"
22258 +);
22259 +
22260 +/*
22261 + * Overrides for Emacs so that we follow Linus's tabbing style.
22262 + * Emacs will notice this stuff at the end of the file and automatically
22263 + * adjust the settings for this buffer only.  This must remain at the end
22264 + * of the file.
22265 + * ---------------------------------------------------------------------------
22266 + * Local variables:
22267 + * c-file-style: "linux"
22268 + * End:
22269 + */
22270 Index: linux-2.4.29/arch/um/kernel/initrd_user.c
22271 ===================================================================
22272 --- linux-2.4.29.orig/arch/um/kernel/initrd_user.c      1970-01-01 03:00:00.000000000 +0300
22273 +++ linux-2.4.29/arch/um/kernel/initrd_user.c   2005-05-03 22:28:14.418418280 +0300
22274 @@ -0,0 +1,44 @@
22275 +/*
22276 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
22277 + * Licensed under the GPL
22278 + */
22279 +
22280 +#include <unistd.h>
22281 +#include <sys/types.h>
22282 +#include <sys/stat.h>
22283 +#include <errno.h>
22284 +
22285 +#include "user_util.h"
22286 +#include "kern_util.h"
22287 +#include "user.h"
22288 +#include "initrd.h"
22289 +#include "os.h"
22290 +
22291 +int load_initrd(char *filename, void *buf, int size)
22292 +{
22293 +       int fd, n;
22294 +
22295 +       fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
22296 +       if(fd < 0){
22297 +               printk("Opening '%s' failed - err = %d\n", filename, -fd);
22298 +               return(-1);
22299 +       }
22300 +       n = os_read_file(fd, buf, size);
22301 +       if(n != size){
22302 +               printk("Read of %d bytes from '%s' failed, err = %d\n", size, 
22303 +                      filename, -n);
22304 +               return(-1);
22305 +       }
22306 +       return(0);
22307 +}
22308 +
22309 +/*
22310 + * Overrides for Emacs so that we follow Linus's tabbing style.
22311 + * Emacs will notice this stuff at the end of the file and automatically
22312 + * adjust the settings for this buffer only.  This must remain at the end
22313 + * of the file.
22314 + * ---------------------------------------------------------------------------
22315 + * Local variables:
22316 + * c-file-style: "linux"
22317 + * End:
22318 + */
22319 Index: linux-2.4.29/arch/um/kernel/init_task.c
22320 ===================================================================
22321 --- linux-2.4.29.orig/arch/um/kernel/init_task.c        1970-01-01 03:00:00.000000000 +0300
22322 +++ linux-2.4.29/arch/um/kernel/init_task.c     2005-05-03 22:28:14.419418128 +0300
22323 @@ -0,0 +1,61 @@
22324 +/* 
22325 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
22326 + * Licensed under the GPL
22327 + */
22328 +
22329 +#include "linux/config.h"
22330 +#include "linux/mm.h"
22331 +#include "linux/sched.h"
22332 +#include "linux/version.h"
22333 +#include "asm/uaccess.h"
22334 +#include "asm/pgtable.h"
22335 +#include "user_util.h"
22336 +#include "mem_user.h"
22337 +
22338 +static struct fs_struct init_fs = INIT_FS;
22339 +static struct files_struct init_files = INIT_FILES;
22340 +static struct signal_struct init_signals = INIT_SIGNALS;
22341 +struct mm_struct init_mm = INIT_MM(init_mm);
22342 +
22343 +/*
22344 + * Initial task structure.
22345 + *
22346 + * We need to make sure that this is 16384-byte aligned due to the
22347 + * way process stacks are handled. This is done by having a special
22348 + * "init_task" linker map entry..
22349 + */
22350 +
22351 +union task_union init_task_union 
22352 +__attribute__((__section__(".data.init_task"))) = 
22353 +{ INIT_TASK(init_task_union.task) };
22354 +
22355 +struct task_struct *alloc_task_struct(void)
22356 +{
22357 +       return((struct task_struct *) 
22358 +              __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
22359 +}
22360 +
22361 +void unprotect_stack(unsigned long stack)
22362 +{
22363 +       protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, 
22364 +                      1, 1, 0, 1);
22365 +}
22366 +
22367 +void free_task_struct(struct task_struct *task)
22368 +{
22369 +       /* free_pages decrements the page counter and only actually frees
22370 +        * the pages if they are now not accessed by anything.
22371 +        */
22372 +       free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
22373 +}
22374 +
22375 +/*
22376 + * Overrides for Emacs so that we follow Linus's tabbing style.
22377 + * Emacs will notice this stuff at the end of the file and automatically
22378 + * adjust the settings for this buffer only.  This must remain at the end
22379 + * of the file.
22380 + * ---------------------------------------------------------------------------
22381 + * Local variables:
22382 + * c-file-style: "linux"
22383 + * End:
22384 + */
22385 Index: linux-2.4.29/arch/um/kernel/irq.c
22386 ===================================================================
22387 --- linux-2.4.29.orig/arch/um/kernel/irq.c      1970-01-01 03:00:00.000000000 +0300
22388 +++ linux-2.4.29/arch/um/kernel/irq.c   2005-05-03 22:28:14.422417672 +0300
22389 @@ -0,0 +1,840 @@
22390 +/* 
22391 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
22392 + * Licensed under the GPL
22393 + * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
22394 + *     Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
22395 + */
22396 +
22397 +#include "linux/config.h"
22398 +#include "linux/kernel.h"
22399 +#include "linux/smp.h"
22400 +#include "linux/irq.h"
22401 +#include "linux/kernel_stat.h"
22402 +#include "linux/interrupt.h"
22403 +#include "linux/random.h"
22404 +#include "linux/slab.h"
22405 +#include "linux/file.h"
22406 +#include "linux/proc_fs.h"
22407 +#include "linux/init.h"
22408 +#include "linux/seq_file.h"
22409 +#include "asm/irq.h"
22410 +#include "asm/hw_irq.h"
22411 +#include "asm/hardirq.h"
22412 +#include "asm/atomic.h"
22413 +#include "asm/signal.h"
22414 +#include "asm/system.h"
22415 +#include "asm/errno.h"
22416 +#include "asm/uaccess.h"
22417 +#include "user_util.h"
22418 +#include "kern_util.h"
22419 +#include "irq_user.h"
22420 +#include "irq_kern.h"
22421 +
22422 +static void register_irq_proc (unsigned int irq);
22423 +
22424 +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
22425 +        { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
22426 +
22427 +/*
22428 + * Generic no controller code
22429 + */
22430 +
22431 +static void enable_none(unsigned int irq) { }
22432 +static unsigned int startup_none(unsigned int irq) { return 0; }
22433 +static void disable_none(unsigned int irq) { }
22434 +static void ack_none(unsigned int irq)
22435 +{
22436 +/*
22437 + * 'what should we do if we get a hw irq event on an illegal vector'.
22438 + * each architecture has to answer this themselves, it doesnt deserve
22439 + * a generic callback i think.
22440 + */
22441 +#if CONFIG_X86
22442 +       printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
22443 +#ifdef CONFIG_X86_LOCAL_APIC
22444 +       /*
22445 +        * Currently unexpected vectors happen only on SMP and APIC.
22446 +        * We _must_ ack these because every local APIC has only N
22447 +        * irq slots per priority level, and a 'hanging, unacked' IRQ
22448 +        * holds up an irq slot - in excessive cases (when multiple
22449 +        * unexpected vectors occur) that might lock up the APIC
22450 +        * completely.
22451 +        */
22452 +       ack_APIC_irq();
22453 +#endif
22454 +#endif
22455 +}
22456 +
22457 +/* startup is the same as "enable", shutdown is same as "disable" */
22458 +#define shutdown_none  disable_none
22459 +#define end_none       enable_none
22460 +
22461 +struct hw_interrupt_type no_irq_type = {
22462 +       "none",
22463 +       startup_none,
22464 +       shutdown_none,
22465 +       enable_none,
22466 +       disable_none,
22467 +       ack_none,
22468 +       end_none
22469 +};
22470 +
22471 +/*
22472 + * Generic, controller-independent functions:
22473 + */
22474 +
22475 +int get_irq_list(char *buf)
22476 +{
22477 +       int i, j;
22478 +       unsigned long flags;
22479 +       struct irqaction * action;
22480 +       char *p = buf;
22481 +
22482 +       p += sprintf(p, "           ");
22483 +       for (j=0; j<smp_num_cpus; j++)
22484 +               p += sprintf(p, "CPU%d       ",j);
22485 +       *p++ = '\n';
22486 +
22487 +       for (i = 0 ; i < NR_IRQS ; i++) {
22488 +               spin_lock_irqsave(&irq_desc[i].lock, flags);
22489 +               action = irq_desc[i].action;
22490 +               if (!action) 
22491 +                       goto end;
22492 +               p += sprintf(p, "%3d: ",i);
22493 +#ifndef CONFIG_SMP
22494 +               p += sprintf(p, "%10u ", kstat_irqs(i));
22495 +#else
22496 +               for (j = 0; j < smp_num_cpus; j++)
22497 +                       p += sprintf(p, "%10u ",
22498 +                               kstat.irqs[cpu_logical_map(j)][i]);
22499 +#endif
22500 +               p += sprintf(p, " %14s", irq_desc[i].handler->typename);
22501 +               p += sprintf(p, "  %s", action->name);
22502 +
22503 +               for (action=action->next; action; action = action->next)
22504 +                       p += sprintf(p, ", %s", action->name);
22505 +               *p++ = '\n';
22506 +       end:
22507 +               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
22508 +       }
22509 +       p += sprintf(p, "\n");
22510 +#ifdef notdef
22511 +#if CONFIG_SMP
22512 +       p += sprintf(p, "LOC: ");
22513 +       for (j = 0; j < smp_num_cpus; j++)
22514 +               p += sprintf(p, "%10u ",
22515 +                       apic_timer_irqs[cpu_logical_map(j)]);
22516 +       p += sprintf(p, "\n");
22517 +#endif
22518 +#endif
22519 +       p += sprintf(p, "ERR: %10lu\n", 0L);
22520 +       return p - buf;
22521 +}
22522 +
22523 +/*
22524 + * This should really return information about whether
22525 + * we should do bottom half handling etc. Right now we
22526 + * end up _always_ checking the bottom half, which is a
22527 + * waste of time and is not what some drivers would
22528 + * prefer.
22529 + */
22530 +int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, 
22531 +                    struct irqaction * action)
22532 +{
22533 +       int status;
22534 +       int cpu = smp_processor_id();
22535 +
22536 +       irq_enter(cpu, irq);
22537 +
22538 +       status = 1;     /* Force the "do bottom halves" bit */
22539 +
22540 +       if (!(action->flags & SA_INTERRUPT))
22541 +               __sti();
22542 +
22543 +       do {
22544 +               status |= action->flags;
22545 +               action->handler(irq, action->dev_id, regs);
22546 +               action = action->next;
22547 +       } while (action);
22548 +       if (status & SA_SAMPLE_RANDOM)
22549 +               add_interrupt_randomness(irq);
22550 +       __cli();
22551 +
22552 +       irq_exit(cpu, irq);
22553 +
22554 +       return status;
22555 +}
22556 +
22557 +/*
22558 + * Generic enable/disable code: this just calls
22559 + * down into the PIC-specific version for the actual
22560 + * hardware disable after having gotten the irq
22561 + * controller lock. 
22562 + */
22563
22564 +/**
22565 + *     disable_irq_nosync - disable an irq without waiting
22566 + *     @irq: Interrupt to disable
22567 + *
22568 + *     Disable the selected interrupt line. Disables of an interrupt
22569 + *     stack. Unlike disable_irq(), this function does not ensure existing
22570 + *     instances of the IRQ handler have completed before returning.
22571 + *
22572 + *     This function may be called from IRQ context.
22573 + */
22574
22575 +void inline disable_irq_nosync(unsigned int irq)
22576 +{
22577 +       irq_desc_t *desc = irq_desc + irq;
22578 +       unsigned long flags;
22579 +
22580 +       spin_lock_irqsave(&desc->lock, flags);
22581 +       if (!desc->depth++) {
22582 +               desc->status |= IRQ_DISABLED;
22583 +               desc->handler->disable(irq);
22584 +       }
22585 +       spin_unlock_irqrestore(&desc->lock, flags);
22586 +}
22587 +
22588 +/**
22589 + *     disable_irq - disable an irq and wait for completion
22590 + *     @irq: Interrupt to disable
22591 + *
22592 + *     Disable the selected interrupt line. Disables of an interrupt
22593 + *     stack. That is for two disables you need two enables. This
22594 + *     function waits for any pending IRQ handlers for this interrupt
22595 + *     to complete before returning. If you use this function while
22596 + *     holding a resource the IRQ handler may need you will deadlock.
22597 + *
22598 + *     This function may be called - with care - from IRQ context.
22599 + */
22600
22601 +void disable_irq(unsigned int irq)
22602 +{
22603 +       disable_irq_nosync(irq);
22604 +
22605 +       if (!local_irq_count(smp_processor_id())) {
22606 +               do {
22607 +                       barrier();
22608 +               } while (irq_desc[irq].status & IRQ_INPROGRESS);
22609 +       }
22610 +}
22611 +
22612 +/**
22613 + *     enable_irq - enable interrupt handling on an irq
22614 + *     @irq: Interrupt to enable
22615 + *
22616 + *     Re-enables the processing of interrupts on this IRQ line
22617 + *     providing no disable_irq calls are now in effect.
22618 + *
22619 + *     This function may be called from IRQ context.
22620 + */
22621
22622 +void enable_irq(unsigned int irq)
22623 +{
22624 +       irq_desc_t *desc = irq_desc + irq;
22625 +       unsigned long flags;
22626 +
22627 +       spin_lock_irqsave(&desc->lock, flags);
22628 +       switch (desc->depth) {
22629 +       case 1: {
22630 +               unsigned int status = desc->status & ~IRQ_DISABLED;
22631 +               desc->status = status;
22632 +               if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
22633 +                       desc->status = status | IRQ_REPLAY;
22634 +                       hw_resend_irq(desc->handler,irq);
22635 +               }
22636 +               desc->handler->enable(irq);
22637 +               /* fall-through */
22638 +       }
22639 +       default:
22640 +               desc->depth--;
22641 +               break;
22642 +       case 0:
22643 +               printk(KERN_ERR "enable_irq() unbalanced from %p\n",
22644 +                      __builtin_return_address(0));
22645 +       }
22646 +       spin_unlock_irqrestore(&desc->lock, flags);
22647 +}
22648 +
22649 +/*
22650 + * do_IRQ handles all normal device IRQ's (the special
22651 + * SMP cross-CPU interrupts have their own specific
22652 + * handlers).
22653 + */
22654 +unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
22655 +{      
22656 +       /* 
22657 +        * 0 return value means that this irq is already being
22658 +        * handled by some other CPU. (or is disabled)
22659 +        */
22660 +       int cpu = smp_processor_id();
22661 +       irq_desc_t *desc = irq_desc + irq;
22662 +       struct irqaction * action;
22663 +       unsigned int status;
22664 +
22665 +       kstat.irqs[cpu][irq]++;
22666 +       spin_lock(&desc->lock);
22667 +       desc->handler->ack(irq);
22668 +       /*
22669 +          REPLAY is when Linux resends an IRQ that was dropped earlier
22670 +          WAITING is used by probe to mark irqs that are being tested
22671 +          */
22672 +       status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
22673 +       status |= IRQ_PENDING; /* we _want_ to handle it */
22674 +
22675 +       /*
22676 +        * If the IRQ is disabled for whatever reason, we cannot
22677 +        * use the action we have.
22678 +        */
22679 +       action = NULL;
22680 +       if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
22681 +               action = desc->action;
22682 +               status &= ~IRQ_PENDING; /* we commit to handling */
22683 +               status |= IRQ_INPROGRESS; /* we are handling it */
22684 +       }
22685 +       desc->status = status;
22686 +
22687 +       /*
22688 +        * If there is no IRQ handler or it was disabled, exit early.
22689 +          Since we set PENDING, if another processor is handling
22690 +          a different instance of this same irq, the other processor
22691 +          will take care of it.
22692 +        */
22693 +       if (!action)
22694 +               goto out;
22695 +
22696 +       /*
22697 +        * Edge triggered interrupts need to remember
22698 +        * pending events.
22699 +        * This applies to any hw interrupts that allow a second
22700 +        * instance of the same irq to arrive while we are in do_IRQ
22701 +        * or in the handler. But the code here only handles the _second_
22702 +        * instance of the irq, not the third or fourth. So it is mostly
22703 +        * useful for irq hardware that does not mask cleanly in an
22704 +        * SMP environment.
22705 +        */
22706 +       for (;;) {
22707 +               spin_unlock(&desc->lock);
22708 +               handle_IRQ_event(irq, (struct pt_regs *) regs, action);
22709 +               spin_lock(&desc->lock);
22710 +               
22711 +               if (!(desc->status & IRQ_PENDING))
22712 +                       break;
22713 +               desc->status &= ~IRQ_PENDING;
22714 +       }
22715 +       desc->status &= ~IRQ_INPROGRESS;
22716 +out:
22717 +       /*
22718 +        * The ->end() handler has to deal with interrupts which got
22719 +        * disabled while the handler was running.
22720 +        */
22721 +       desc->handler->end(irq);
22722 +       spin_unlock(&desc->lock);
22723 +
22724 +       if (softirq_pending(cpu))
22725 +               do_softirq();
22726 +       return 1;
22727 +}
22728 +
22729 +/**
22730 + *     request_irq - allocate an interrupt line
22731 + *     @irq: Interrupt line to allocate
22732 + *     @handler: Function to be called when the IRQ occurs
22733 + *     @irqflags: Interrupt type flags
22734 + *     @devname: An ascii name for the claiming device
22735 + *     @dev_id: A cookie passed back to the handler function
22736 + *
22737 + *     This call allocates interrupt resources and enables the
22738 + *     interrupt line and IRQ handling. From the point this
22739 + *     call is made your handler function may be invoked. Since
22740 + *     your handler function must clear any interrupt the board 
22741 + *     raises, you must take care both to initialise your hardware
22742 + *     and to set up the interrupt handler in the right order.
22743 + *
22744 + *     Dev_id must be globally unique. Normally the address of the
22745 + *     device data structure is used as the cookie. Since the handler
22746 + *     receives this value it makes sense to use it.
22747 + *
22748 + *     If your interrupt is shared you must pass a non NULL dev_id
22749 + *     as this is required when freeing the interrupt.
22750 + *
22751 + *     Flags:
22752 + *
22753 + *     SA_SHIRQ                Interrupt is shared
22754 + *
22755 + *     SA_INTERRUPT            Disable local interrupts while processing
22756 + *
22757 + *     SA_SAMPLE_RANDOM        The interrupt can be used for entropy
22758 + *
22759 + */
22760
22761 +int request_irq(unsigned int irq,
22762 +               void (*handler)(int, void *, struct pt_regs *),
22763 +               unsigned long irqflags, 
22764 +               const char * devname,
22765 +               void *dev_id)
22766 +{
22767 +       int retval;
22768 +       struct irqaction * action;
22769 +
22770 +#if 1
22771 +       /*
22772 +        * Sanity-check: shared interrupts should REALLY pass in
22773 +        * a real dev-ID, otherwise we'll have trouble later trying
22774 +        * to figure out which interrupt is which (messes up the
22775 +        * interrupt freeing logic etc).
22776 +        */
22777 +       if (irqflags & SA_SHIRQ) {
22778 +               if (!dev_id)
22779 +                       printk(KERN_ERR "Bad boy: %s (at 0x%x) called us "
22780 +                              "without a dev_id!\n", devname, (&irq)[-1]);
22781 +       }
22782 +#endif
22783 +
22784 +       if (irq >= NR_IRQS)
22785 +               return -EINVAL;
22786 +       if (!handler)
22787 +               return -EINVAL;
22788 +
22789 +       action = (struct irqaction *)
22790 +                       kmalloc(sizeof(struct irqaction), GFP_KERNEL);
22791 +       if (!action)
22792 +               return -ENOMEM;
22793 +
22794 +       action->handler = handler;
22795 +       action->flags = irqflags;
22796 +       action->mask = 0;
22797 +       action->name = devname;
22798 +       action->next = NULL;
22799 +       action->dev_id = dev_id;
22800 +
22801 +       retval = setup_irq(irq, action);
22802 +       if (retval)
22803 +               kfree(action);
22804 +       return retval;
22805 +}
22806 +
22807 +int um_request_irq(unsigned int irq, int fd, int type,
22808 +                  void (*handler)(int, void *, struct pt_regs *),
22809 +                  unsigned long irqflags, const char * devname,
22810 +                  void *dev_id)
22811 +{
22812 +       int err;
22813 +
22814 +       err = request_irq(irq, handler, irqflags, devname, dev_id);
22815 +       if(err) 
22816 +               return(err);
22817 +
22818 +       if(fd != -1)
22819 +               err = activate_fd(irq, fd, type, dev_id);
22820 +       return(err);
22821 +}
22822 +
22823 +/* this was setup_x86_irq but it seems pretty generic */
22824 +int setup_irq(unsigned int irq, struct irqaction * new)
22825 +{
22826 +       int shared = 0;
22827 +       unsigned long flags;
22828 +       struct irqaction *old, **p;
22829 +       irq_desc_t *desc = irq_desc + irq;
22830 +
22831 +       /*
22832 +        * Some drivers like serial.c use request_irq() heavily,
22833 +        * so we have to be careful not to interfere with a
22834 +        * running system.
22835 +        */
22836 +       if (new->flags & SA_SAMPLE_RANDOM) {
22837 +               /*
22838 +                * This function might sleep, we want to call it first,
22839 +                * outside of the atomic block.
22840 +                * Yes, this might clear the entropy pool if the wrong
22841 +                * driver is attempted to be loaded, without actually
22842 +                * installing a new handler, but is this really a problem,
22843 +                * only the sysadmin is able to do this.
22844 +                */
22845 +               rand_initialize_irq(irq);
22846 +       }
22847 +
22848 +       /*
22849 +        * The following block of code has to be executed atomically
22850 +        */
22851 +       spin_lock_irqsave(&desc->lock,flags);
22852 +       p = &desc->action;
22853 +       old = *p;
22854 +       if (old != NULL) {
22855 +               /* Can't share interrupts unless both agree to */
22856 +               if (!(old->flags & new->flags & SA_SHIRQ)) {
22857 +                       spin_unlock_irqrestore(&desc->lock,flags);
22858 +                       return -EBUSY;
22859 +               }
22860 +
22861 +               /* add new interrupt at end of irq queue */
22862 +               do {
22863 +                       p = &old->next;
22864 +                       old = *p;
22865 +               } while (old);
22866 +               shared = 1;
22867 +       }
22868 +
22869 +       *p = new;
22870 +
22871 +       if (!shared) {
22872 +               desc->depth = 0;
22873 +               desc->status &= ~IRQ_DISABLED;
22874 +               desc->handler->startup(irq);
22875 +       }
22876 +       spin_unlock_irqrestore(&desc->lock,flags);
22877 +
22878 +       register_irq_proc(irq);
22879 +       return 0;
22880 +}
22881 +
22882 +/**
22883 + *     free_irq - free an interrupt
22884 + *     @irq: Interrupt line to free
22885 + *     @dev_id: Device identity to free
22886 + *
22887 + *     Remove an interrupt handler. The handler is removed and if the
22888 + *     interrupt line is no longer in use by any driver it is disabled.
22889 + *     On a shared IRQ the caller must ensure the interrupt is disabled
22890 + *     on the card it drives before calling this function. The function
22891 + *     does not return until any executing interrupts for this IRQ
22892 + *     have completed.
22893 + *
22894 + *     This function may be called from interrupt context. 
22895 + *
22896 + *     Bugs: Attempting to free an irq in a handler for the same irq hangs
22897 + *           the machine.
22898 + */
22899
22900 +void free_irq(unsigned int irq, void *dev_id)
22901 +{
22902 +       irq_desc_t *desc;
22903 +       struct irqaction **p;
22904 +       unsigned long flags;
22905 +
22906 +       if (irq >= NR_IRQS)
22907 +               return;
22908 +
22909 +       desc = irq_desc + irq;
22910 +       spin_lock_irqsave(&desc->lock,flags);
22911 +       p = &desc->action;
22912 +       for (;;) {
22913 +               struct irqaction * action = *p;
22914 +               if (action) {
22915 +                       struct irqaction **pp = p;
22916 +                       p = &action->next;
22917 +                       if (action->dev_id != dev_id)
22918 +                               continue;
22919 +
22920 +                       /* Found it - now remove it from the list of entries */
22921 +                       *pp = action->next;
22922 +                       if (!desc->action) {
22923 +                               desc->status |= IRQ_DISABLED;
22924 +                               desc->handler->shutdown(irq);
22925 +                       }
22926 +                       free_irq_by_irq_and_dev(irq, dev_id);
22927 +                       spin_unlock_irqrestore(&desc->lock,flags);
22928 +
22929 +#ifdef CONFIG_SMP
22930 +                       /* Wait to make sure it's not being used on another CPU */
22931 +                       while (desc->status & IRQ_INPROGRESS)
22932 +                               barrier();
22933 +#endif
22934 +                       kfree(action);
22935 +                       return;
22936 +               }
22937 +               printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
22938 +               spin_unlock_irqrestore(&desc->lock,flags);
22939 +               return;
22940 +       }
22941 +}
22942 +
22943 +/* These are initialized by sysctl_init, which is called from init/main.c */
22944 +static struct proc_dir_entry * root_irq_dir;
22945 +static struct proc_dir_entry * irq_dir [NR_IRQS];
22946 +static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
22947 +
22948 +/* These are read and written as longs, so a read won't see a partial write
22949 + * even during a race.
22950 + */
22951 +static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
22952 +
22953 +#define HEX_DIGITS 8
22954 +
22955 +static int irq_affinity_read_proc (char *page, char **start, off_t off,
22956 +                       int count, int *eof, void *data)
22957 +{
22958 +       if (count < HEX_DIGITS+1)
22959 +               return -EINVAL;
22960 +       return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
22961 +}
22962 +
22963 +static unsigned int parse_hex_value (const char *buffer,
22964 +               unsigned long count, unsigned long *ret)
22965 +{
22966 +       unsigned char hexnum [HEX_DIGITS];
22967 +       unsigned long value;
22968 +       int i;
22969 +
22970 +       if (!count)
22971 +               return -EINVAL;
22972 +       if (count > HEX_DIGITS)
22973 +               count = HEX_DIGITS;
22974 +       if (copy_from_user(hexnum, buffer, count))
22975 +               return -EFAULT;
22976 +
22977 +       /*
22978 +        * Parse the first HEX_DIGITS characters as a hex string, any non-hex
22979 +        * char is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
22980 +        */
22981 +       value = 0;
22982 +
22983 +       for (i = 0; i < count; i++) {
22984 +               unsigned int c = hexnum[i];
22985 +
22986 +               switch (c) {
22987 +                       case '0' ... '9': c -= '0'; break;
22988 +                       case 'a' ... 'f': c -= 'a'-10; break;
22989 +                       case 'A' ... 'F': c -= 'A'-10; break;
22990 +               default:
22991 +                       goto out;
22992 +               }
22993 +               value = (value << 4) | c;
22994 +       }
22995 +out:
22996 +       *ret = value;
22997 +       return 0;
22998 +}
22999 +
23000 +static int irq_affinity_write_proc (struct file *file, const char *buffer,
23001 +                                       unsigned long count, void *data)
23002 +{
23003 +       int irq = (long) data, full_count = count, err;
23004 +       unsigned long new_value;
23005 +
23006 +       if (!irq_desc[irq].handler->set_affinity)
23007 +               return -EIO;
23008 +
23009 +       err = parse_hex_value(buffer, count, &new_value);
23010 +
23011 +#if CONFIG_SMP
23012 +       /*
23013 +        * Do not allow disabling IRQs completely - it's a too easy
23014 +        * way to make the system unusable accidentally :-) At least
23015 +        * one online CPU still has to be targeted.
23016 +        */
23017 +       if (!(new_value & cpu_online_map))
23018 +               return -EINVAL;
23019 +#endif
23020 +
23021 +       irq_affinity[irq] = new_value;
23022 +       irq_desc[irq].handler->set_affinity(irq, new_value);
23023 +
23024 +       return full_count;
23025 +}
23026 +
23027 +static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
23028 +                       int count, int *eof, void *data)
23029 +{
23030 +       unsigned long *mask = (unsigned long *) data;
23031 +       if (count < HEX_DIGITS+1)
23032 +               return -EINVAL;
23033 +       return sprintf (page, "%08lx\n", *mask);
23034 +}
23035 +
23036 +static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
23037 +                                       unsigned long count, void *data)
23038 +{
23039 +       unsigned long *mask = (unsigned long *) data, full_count = count, err;
23040 +       unsigned long new_value;
23041 +
23042 +       err = parse_hex_value(buffer, count, &new_value);
23043 +       if (err)
23044 +               return err;
23045 +
23046 +       *mask = new_value;
23047 +       return full_count;
23048 +}
23049 +
23050 +#define MAX_NAMELEN 10
23051 +
23052 +static void register_irq_proc (unsigned int irq)
23053 +{
23054 +       struct proc_dir_entry *entry;
23055 +       char name [MAX_NAMELEN];
23056 +
23057 +       if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
23058 +           irq_dir[irq])
23059 +               return;
23060 +
23061 +       memset(name, 0, MAX_NAMELEN);
23062 +       sprintf(name, "%d", irq);
23063 +
23064 +       /* create /proc/irq/1234 */
23065 +       irq_dir[irq] = proc_mkdir(name, root_irq_dir);
23066 +
23067 +       /* create /proc/irq/1234/smp_affinity */
23068 +       entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
23069 +
23070 +       entry->nlink = 1;
23071 +       entry->data = (void *)(long)irq;
23072 +       entry->read_proc = irq_affinity_read_proc;
23073 +       entry->write_proc = irq_affinity_write_proc;
23074 +
23075 +       smp_affinity_entry[irq] = entry;
23076 +}
23077 +
23078 +/* Read and written as a long */
23079 +unsigned long prof_cpu_mask = -1;
23080 +
23081 +void __init init_irq_proc (void)
23082 +{
23083 +       struct proc_dir_entry *entry;
23084 +       int i;
23085 +
23086 +       /* create /proc/irq */
23087 +       root_irq_dir = proc_mkdir("irq", 0);
23088 +
23089 +       /* create /proc/irq/prof_cpu_mask */
23090 +       entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
23091 +
23092 +       entry->nlink = 1;
23093 +       entry->data = (void *)&prof_cpu_mask;
23094 +       entry->read_proc = prof_cpu_mask_read_proc;
23095 +       entry->write_proc = prof_cpu_mask_write_proc;
23096 +
23097 +       /*
23098 +        * Create entries for all existing IRQs.
23099 +        */
23100 +       for (i = 0; i < NR_IRQS; i++)
23101 +               register_irq_proc(i);
23102 +}
23103 +
23104 +static spinlock_t irq_spinlock = SPIN_LOCK_UNLOCKED;
23105 +
23106 +unsigned long irq_lock(void)
23107 +{
23108 +       unsigned long flags;
23109 +
23110 +       spin_lock_irqsave(&irq_spinlock, flags);
23111 +       return(flags);
23112 +}
23113 +
23114 +void irq_unlock(unsigned long flags)
23115 +{
23116 +       spin_unlock_irqrestore(&irq_spinlock, flags);
23117 +}
23118 +
23119 +unsigned long probe_irq_on(void)
23120 +{
23121 +       return(0);
23122 +}
23123 +
23124 +int probe_irq_off(unsigned long val)
23125 +{
23126 +       return(0);
23127 +}
23128 +
23129 +static unsigned int startup_SIGIO_irq(unsigned int irq)
23130 +{
23131 +       return(0);
23132 +}
23133 +
23134 +static void shutdown_SIGIO_irq(unsigned int irq)
23135 +{
23136 +}
23137 +
23138 +static void enable_SIGIO_irq(unsigned int irq)
23139 +{
23140 +}
23141 +
23142 +static void disable_SIGIO_irq(unsigned int irq)
23143 +{
23144 +}
23145 +
23146 +static void mask_and_ack_SIGIO(unsigned int irq)
23147 +{
23148 +}
23149 +
23150 +static void end_SIGIO_irq(unsigned int irq)
23151 +{
23152 +}
23153 +
23154 +static unsigned int startup_SIGVTALRM_irq(unsigned int irq)
23155 +{
23156 +       return(0);
23157 +}
23158 +
23159 +static void shutdown_SIGVTALRM_irq(unsigned int irq)
23160 +{
23161 +}
23162 +
23163 +static void enable_SIGVTALRM_irq(unsigned int irq)
23164 +{
23165 +}
23166 +
23167 +static void disable_SIGVTALRM_irq(unsigned int irq)
23168 +{
23169 +}
23170 +
23171 +static void mask_and_ack_SIGVTALRM(unsigned int irq)
23172 +{
23173 +}
23174 +
23175 +static void end_SIGVTALRM_irq(unsigned int irq)
23176 +{
23177 +}
23178 +
23179 +static struct hw_interrupt_type SIGIO_irq_type = {
23180 +       "SIGIO",
23181 +       startup_SIGIO_irq,
23182 +       shutdown_SIGIO_irq,
23183 +       enable_SIGIO_irq,
23184 +       disable_SIGIO_irq,
23185 +       mask_and_ack_SIGIO,
23186 +       end_SIGIO_irq,
23187 +       NULL
23188 +};
23189 +
23190 +static struct hw_interrupt_type SIGVTALRM_irq_type = {
23191 +       "SIGVTALRM",
23192 +       startup_SIGVTALRM_irq,
23193 +       shutdown_SIGVTALRM_irq,
23194 +       enable_SIGVTALRM_irq,
23195 +       disable_SIGVTALRM_irq,
23196 +       mask_and_ack_SIGVTALRM,
23197 +       end_SIGVTALRM_irq,
23198 +       NULL
23199 +};
23200 +
23201 +void __init init_IRQ(void)
23202 +{
23203 +       int i;
23204 +
23205 +       irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
23206 +       irq_desc[TIMER_IRQ].action = 0;
23207 +       irq_desc[TIMER_IRQ].depth = 1;
23208 +       irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type;
23209 +       enable_irq(TIMER_IRQ);
23210 +       for(i=1;i<NR_IRQS;i++){
23211 +               irq_desc[i].status = IRQ_DISABLED;
23212 +               irq_desc[i].action = 0;
23213 +               irq_desc[i].depth = 1;
23214 +               irq_desc[i].handler = &SIGIO_irq_type;
23215 +               enable_irq(i);
23216 +       }
23217 +       init_irq_signals(0);
23218 +}
23219 +
23220 +/*
23221 + * Overrides for Emacs so that we follow Linus's tabbing style.
23222 + * Emacs will notice this stuff at the end of the file and automatically
23223 + * adjust the settings for this buffer only.  This must remain at the end
23224 + * of the file.
23225 + * ---------------------------------------------------------------------------
23226 + * Local variables:
23227 + * c-file-style: "linux"
23228 + * End:
23229 + */
23230 Index: linux-2.4.29/arch/um/kernel/irq_user.c
23231 ===================================================================
23232 --- linux-2.4.29.orig/arch/um/kernel/irq_user.c 1970-01-01 03:00:00.000000000 +0300
23233 +++ linux-2.4.29/arch/um/kernel/irq_user.c      2005-05-03 22:28:14.424417368 +0300
23234 @@ -0,0 +1,438 @@
23235 +/* 
23236 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
23237 + * Licensed under the GPL
23238 + */
23239 +
23240 +#include <stdlib.h>
23241 +#include <unistd.h>
23242 +#include <errno.h>
23243 +#include <signal.h>
23244 +#include <string.h>
23245 +#include <sys/poll.h>
23246 +#include <sys/types.h>
23247 +#include <sys/time.h>
23248 +#include "user_util.h"
23249 +#include "kern_util.h"
23250 +#include "user.h"
23251 +#include "process.h"
23252 +#include "signal_user.h"
23253 +#include "sigio.h"
23254 +#include "irq_user.h"
23255 +#include "os.h"
23256 +
23257 +struct irq_fd {
23258 +       struct irq_fd *next;
23259 +       void *id;
23260 +       int fd;
23261 +       int type;
23262 +       int irq;
23263 +       int pid;
23264 +       int events;
23265 +       int current_events;
23266 +       int freed;
23267 +};
23268 +
23269 +static struct irq_fd *active_fds = NULL;
23270 +static struct irq_fd **last_irq_ptr = &active_fds;
23271 +
23272 +static struct pollfd *pollfds = NULL;
23273 +static int pollfds_num = 0;
23274 +static int pollfds_size = 0;
23275 +
23276 +extern int io_count, intr_count;
23277 +
23278 +void sigio_handler(int sig, union uml_pt_regs *regs)
23279 +{
23280 +       struct irq_fd *irq_fd, *next;
23281 +       int i, n;
23282 +
23283 +       if(smp_sigio_handler()) return;
23284 +       while(1){
23285 +               n = poll(pollfds, pollfds_num, 0);
23286 +               if(n < 0){
23287 +                       if(errno == EINTR) continue;
23288 +                       printk("sigio_handler : poll returned %d, "
23289 +                              "errno = %d\n", n, errno);
23290 +                       break;
23291 +               }
23292 +               if(n == 0) break;
23293 +
23294 +               irq_fd = active_fds;
23295 +               for(i = 0; i < pollfds_num; i++){
23296 +                       if(pollfds[i].revents != 0){
23297 +                               irq_fd->current_events = pollfds[i].revents;
23298 +                               pollfds[i].fd = -1;
23299 +                       }
23300 +                       irq_fd = irq_fd->next;
23301 +               }
23302 +
23303 +               for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){
23304 +                       next = irq_fd->next;
23305 +                       if(irq_fd->current_events != 0){
23306 +                               irq_fd->current_events = 0;
23307 +                               do_IRQ(irq_fd->irq, regs);
23308 +
23309 +                               /* This is here because the next irq may be
23310 +                                * freed in the handler.  If a console goes
23311 +                                * away, both the read and write irqs will be
23312 +                                * freed.  After do_IRQ, ->next will point to
23313 +                                * a good IRQ.
23314 +                                * Irqs can't be freed inside their handlers,
23315 +                                * so the next best thing is to have them
23316 +                                * marked as needing freeing, so that they
23317 +                                * can be freed here.
23318 +                                */
23319 +                               next = irq_fd->next;
23320 +                               if(irq_fd->freed)
23321 +                                       free_irq(irq_fd->irq, irq_fd->id);
23322 +                       }
23323 +               }
23324 +       }
23325 +}
23326 +
23327 +int activate_ipi(int fd, int pid)
23328 +{
23329 +       return(os_set_fd_async(fd, pid));
23330 +}
23331 +
23332 +static void maybe_sigio_broken(int fd, int type)
23333 +{
23334 +       if(isatty(fd)){
23335 +               if((type == IRQ_WRITE) && !pty_output_sigio){
23336 +                       write_sigio_workaround();
23337 +                       add_sigio_fd(fd, 0);
23338 +               }
23339 +               else if((type == IRQ_READ) && !pty_close_sigio){
23340 +                       write_sigio_workaround();
23341 +                       add_sigio_fd(fd, 1);                    
23342 +               }
23343 +       }
23344 +}
23345 +
23346 +int activate_fd(int irq, int fd, int type, void *dev_id)
23347 +{
23348 +       struct pollfd *tmp_pfd;
23349 +       struct irq_fd *new_fd, *irq_fd;
23350 +       unsigned long flags;
23351 +       int pid, events, err, n, size;
23352 +
23353 +       pid = os_getpid();
23354 +       err = os_set_fd_async(fd, pid);
23355 +       if(err < 0)
23356 +               goto out;
23357 +
23358 +       new_fd = um_kmalloc(sizeof(*new_fd));
23359 +       err = -ENOMEM;
23360 +       if(new_fd == NULL)
23361 +               goto out;
23362 +
23363 +       if(type == IRQ_READ) events = POLLIN | POLLPRI;
23364 +       else events = POLLOUT;
23365 +       *new_fd = ((struct irq_fd) { .next              = NULL,
23366 +                                    .id                = dev_id,
23367 +                                    .fd                = fd,
23368 +                                    .type              = type,
23369 +                                    .irq               = irq,
23370 +                                    .pid               = pid,
23371 +                                    .events            = events,
23372 +                                    .current_events    = 0,
23373 +                                    .freed             = 0  } );
23374 +
23375 +       /* Critical section - locked by a spinlock because this stuff can
23376 +        * be changed from interrupt handlers.  The stuff above is done 
23377 +        * outside the lock because it allocates memory.
23378 +        */
23379 +
23380 +       /* Actually, it only looks like it can be called from interrupt
23381 +        * context.  The culprit is reactivate_fd, which calls 
23382 +        * maybe_sigio_broken, which calls write_sigio_workaround,
23383 +        * which calls activate_fd.  However, write_sigio_workaround should
23384 +        * only be called once, at boot time.  That would make it clear that
23385 +        * this is called only from process context, and can be locked with
23386 +        * a semaphore.
23387 +        */
23388 +       flags = irq_lock();
23389 +       for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
23390 +               if((irq_fd->fd == fd) && (irq_fd->type == type)){
23391 +                       printk("Registering fd %d twice\n", fd);
23392 +                       printk("Irqs : %d, %d\n", irq_fd->irq, irq);
23393 +                       printk("Ids : 0x%x, 0x%x\n", irq_fd->id, dev_id);
23394 +                       goto out_unlock;
23395 +               }
23396 +       }
23397 +
23398 +       n = pollfds_num;
23399 +       if(n == pollfds_size){
23400 +               while(1){
23401 +                       /* Here we have to drop the lock in order to call 
23402 +                        * kmalloc, which might sleep.  If something else
23403 +                        * came in and changed the pollfds array, we free
23404 +                        * the buffer and try again.
23405 +                        */
23406 +                       irq_unlock(flags);
23407 +                       size = (pollfds_num + 1) * sizeof(pollfds[0]);
23408 +                       tmp_pfd = um_kmalloc(size);
23409 +                       flags = irq_lock();
23410 +                       if(tmp_pfd == NULL)
23411 +                               goto out_unlock;
23412 +                       if(n == pollfds_size)
23413 +                               break;
23414 +                       kfree(tmp_pfd);
23415 +               }
23416 +               if(pollfds != NULL){
23417 +                       memcpy(tmp_pfd, pollfds,
23418 +                              sizeof(pollfds[0]) * pollfds_size);
23419 +                       kfree(pollfds);
23420 +               }
23421 +               pollfds = tmp_pfd;
23422 +               pollfds_size++;
23423 +       }
23424 +
23425 +       if(type == IRQ_WRITE) 
23426 +               fd = -1;
23427 +
23428 +       pollfds[pollfds_num] = ((struct pollfd) { .fd   = fd,
23429 +                                                 .events       = events,
23430 +                                                 .revents      = 0 });
23431 +       pollfds_num++;
23432 +
23433 +       *last_irq_ptr = new_fd;
23434 +       last_irq_ptr = &new_fd->next;
23435 +
23436 +       irq_unlock(flags);
23437 +
23438 +       /* This calls activate_fd, so it has to be outside the critical
23439 +        * section.
23440 +        */
23441 +       maybe_sigio_broken(fd, type);
23442 +
23443 +       return(0);
23444 +
23445 + out_unlock:
23446 +       irq_unlock(flags);
23447 +       kfree(new_fd);
23448 + out:
23449 +       return(err);
23450 +}
23451 +
23452 +static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
23453 +{
23454 +       struct irq_fd **prev;
23455 +       unsigned long flags;
23456 +       int i = 0;
23457 +
23458 +       flags = irq_lock();
23459 +       prev = &active_fds;
23460 +       while(*prev != NULL){
23461 +               if((*test)(*prev, arg)){
23462 +                       struct irq_fd *old_fd = *prev;
23463 +                       if((pollfds[i].fd != -1) && 
23464 +                          (pollfds[i].fd != (*prev)->fd)){
23465 +                               printk("free_irq_by_cb - mismatch between "
23466 +                                      "active_fds and pollfds, fd %d vs %d\n",
23467 +                                      (*prev)->fd, pollfds[i].fd);
23468 +                               goto out;
23469 +                       }
23470 +                       memcpy(&pollfds[i], &pollfds[i + 1],
23471 +                              (pollfds_num - i - 1) * sizeof(pollfds[0]));
23472 +                       pollfds_num--;
23473 +                       if(last_irq_ptr == &old_fd->next) 
23474 +                               last_irq_ptr = prev;
23475 +                       *prev = (*prev)->next;
23476 +                       if(old_fd->type == IRQ_WRITE) 
23477 +                               ignore_sigio_fd(old_fd->fd);
23478 +                       kfree(old_fd);
23479 +                       continue;
23480 +               }
23481 +               prev = &(*prev)->next;
23482 +               i++;
23483 +       }
23484 + out:
23485 +       irq_unlock(flags);
23486 +}
23487 +
23488 +struct irq_and_dev {
23489 +       int irq;
23490 +       void *dev;
23491 +};
23492 +
23493 +static int same_irq_and_dev(struct irq_fd *irq, void *d)
23494 +{
23495 +       struct irq_and_dev *data = d;
23496 +
23497 +       return((irq->irq == data->irq) && (irq->id == data->dev));
23498 +}
23499 +
23500 +void free_irq_by_irq_and_dev(int irq, void *dev)
23501 +{
23502 +       struct irq_and_dev data = ((struct irq_and_dev) { .irq  = irq,
23503 +                                                         .dev  = dev });
23504 +
23505 +       free_irq_by_cb(same_irq_and_dev, &data);
23506 +}
23507 +
23508 +static int same_fd(struct irq_fd *irq, void *fd)
23509 +{
23510 +       return(irq->fd == *((int *) fd));
23511 +}
23512 +
23513 +void free_irq_by_fd(int fd)
23514 +{
23515 +       free_irq_by_cb(same_fd, &fd);
23516 +}
23517 +
23518 +static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
23519 +{
23520 +       struct irq_fd *irq;
23521 +       int i = 0;
23522 +
23523 +       for(irq=active_fds; irq != NULL; irq = irq->next){
23524 +               if((irq->fd == fd) && (irq->irq == irqnum)) break;
23525 +               i++;
23526 +       }
23527 +       if(irq == NULL){
23528 +               printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
23529 +               goto out;
23530 +       }
23531 +       if((pollfds[i].fd != -1) && (pollfds[i].fd != fd)){
23532 +               printk("find_irq_by_fd - mismatch between active_fds and "
23533 +                      "pollfds, fd %d vs %d, need %d\n", irq->fd, 
23534 +                      pollfds[i].fd, fd);
23535 +               irq = NULL;
23536 +               goto out;
23537 +       }
23538 +       *index_out = i;
23539 + out:
23540 +       return(irq);
23541 +}
23542 +
23543 +void free_irq_later(int irq, void *dev_id)
23544 +{
23545 +       struct irq_fd *irq_fd;
23546 +       unsigned long flags;
23547 +
23548 +       flags = irq_lock();
23549 +       for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
23550 +               if((irq_fd->irq == irq) && (irq_fd->id == dev_id))
23551 +                       break;
23552 +       }
23553 +       if(irq_fd == NULL){
23554 +               printk("free_irq_later found no irq, irq = %d, "
23555 +                      "dev_id = 0x%p\n", irq, dev_id);
23556 +               goto out;
23557 +       }
23558 +       irq_fd->freed = 1;
23559 + out:
23560 +       irq_unlock(flags);
23561 +}
23562 +
23563 +void reactivate_fd(int fd, int irqnum)
23564 +{
23565 +       struct irq_fd *irq;
23566 +       unsigned long flags;
23567 +       int i;
23568 +
23569 +       flags = irq_lock();
23570 +       irq = find_irq_by_fd(fd, irqnum, &i);
23571 +       if(irq == NULL){
23572 +               irq_unlock(flags);
23573 +               return;
23574 +       }
23575 +
23576 +       pollfds[i].fd = irq->fd;
23577 +
23578 +       irq_unlock(flags);
23579 +
23580 +       /* This calls activate_fd, so it has to be outside the critical
23581 +        * section.
23582 +        */
23583 +       maybe_sigio_broken(fd, irq->type);
23584 +}
23585 +
23586 +void deactivate_fd(int fd, int irqnum)
23587 +{
23588 +       struct irq_fd *irq;
23589 +       unsigned long flags;
23590 +       int i;
23591 +
23592 +       flags = irq_lock();
23593 +       irq = find_irq_by_fd(fd, irqnum, &i);
23594 +       if(irq == NULL)
23595 +               goto out;
23596 +       pollfds[i].fd = -1;
23597 + out:
23598 +       irq_unlock(flags);
23599 +}
23600 +
23601 +int deactivate_all_fds(void)
23602 +{
23603 +       struct irq_fd *irq;
23604 +       int err;
23605 +
23606 +       for(irq=active_fds;irq != NULL;irq = irq->next){
23607 +               err = os_clear_fd_async(irq->fd);
23608 +               if(err)
23609 +                       return(err);
23610 +       }
23611 +
23612 +       return(0);
23613 +}
23614 +
23615 +void forward_ipi(int fd, int pid)
23616 +{
23617 +       int err;
23618 +
23619 +       err = os_set_owner(fd, pid);
23620 +       if(err < 0)
23621 +               printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
23622 +                      "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
23623 +}
23624 +
23625 +void forward_interrupts(int pid)
23626 +{
23627 +       struct irq_fd *irq;
23628 +       unsigned long flags;
23629 +       int err;
23630 +
23631 +       flags = irq_lock();
23632 +       for(irq=active_fds;irq != NULL;irq = irq->next){
23633 +               err = os_set_owner(irq->fd, pid);
23634 +               if(err < 0){
23635 +                       /* XXX Just remove the irq rather than
23636 +                        * print out an infinite stream of these
23637 +                        */
23638 +                       printk("Failed to forward %d to pid %d, err = %d\n",
23639 +                              irq->fd, pid, -err);
23640 +               }
23641 +
23642 +               irq->pid = pid;
23643 +       }
23644 +       irq_unlock(flags);
23645 +}
23646 +
23647 +void init_irq_signals(int on_sigstack)
23648 +{
23649 +       __sighandler_t h;
23650 +       int flags;
23651 +
23652 +       flags = on_sigstack ? SA_ONSTACK : 0;
23653 +       if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
23654 +       else h = boot_timer_handler;
23655 +
23656 +       set_handler(SIGVTALRM, h, flags | SA_RESTART, 
23657 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
23658 +       set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
23659 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
23660 +       signal(SIGWINCH, SIG_IGN);
23661 +}
23662 +
23663 +/*
23664 + * Overrides for Emacs so that we follow Linus's tabbing style.
23665 + * Emacs will notice this stuff at the end of the file and automatically
23666 + * adjust the settings for this buffer only.  This must remain at the end
23667 + * of the file.
23668 + * ---------------------------------------------------------------------------
23669 + * Local variables:
23670 + * c-file-style: "linux"
23671 + * End:
23672 + */
23673 Index: linux-2.4.29/arch/um/kernel/ksyms.c
23674 ===================================================================
23675 --- linux-2.4.29.orig/arch/um/kernel/ksyms.c    1970-01-01 03:00:00.000000000 +0300
23676 +++ linux-2.4.29/arch/um/kernel/ksyms.c 2005-05-03 23:56:02.752509760 +0300
23677 @@ -0,0 +1,124 @@
23678 +/* 
23679 + * Copyright (C) 2001 - 2004 Jeff Dike (jdike@addtoit.com)
23680 + * Licensed under the GPL
23681 + */
23682 +
23683 +#include "linux/config.h"
23684 +#include "linux/module.h"
23685 +#include "linux/string.h"
23686 +#include "linux/smp_lock.h"
23687 +#include "linux/spinlock.h"
23688 +#include "asm/current.h"
23689 +#include "asm/delay.h"
23690 +#include "asm/processor.h"
23691 +#include "asm/unistd.h"
23692 +#include "asm/pgalloc.h"
23693 +#include "asm/pgtable.h"
23694 +#include "asm/page.h"
23695 +#include "kern_util.h"
23696 +#include "user_util.h"
23697 +#include "mem_user.h"
23698 +#include "os.h"
23699 +#include "helper.h"
23700 +
23701 +EXPORT_SYMBOL(stop);
23702 +EXPORT_SYMBOL(strtok);
23703 +EXPORT_SYMBOL(uml_physmem);
23704 +EXPORT_SYMBOL(set_signals);
23705 +EXPORT_SYMBOL(get_signals);
23706 +EXPORT_SYMBOL(kernel_thread);
23707 +EXPORT_SYMBOL(__const_udelay);
23708 +EXPORT_SYMBOL(__udelay);
23709 +EXPORT_SYMBOL(sys_waitpid);
23710 +EXPORT_SYMBOL(task_size);
23711 +EXPORT_SYMBOL(flush_tlb_range);
23712 +EXPORT_SYMBOL(host_task_size);
23713 +EXPORT_SYMBOL(arch_validate);
23714 +EXPORT_SYMBOL(get_kmem_end);
23715 +
23716 +EXPORT_SYMBOL(high_physmem);
23717 +EXPORT_SYMBOL(empty_zero_page);
23718 +EXPORT_SYMBOL(um_virt_to_phys);
23719 +EXPORT_SYMBOL(__virt_to_page);
23720 +EXPORT_SYMBOL(to_phys);
23721 +EXPORT_SYMBOL(to_virt);
23722 +EXPORT_SYMBOL(mode_tt);
23723 +EXPORT_SYMBOL(handle_page_fault);
23724 +EXPORT_SYMBOL(find_iomem);
23725 +
23726 +#ifdef CONFIG_MODE_TT
23727 +EXPORT_SYMBOL(strncpy_from_user_tt);
23728 +EXPORT_SYMBOL(copy_from_user_tt);
23729 +EXPORT_SYMBOL(copy_to_user_tt);
23730 +#endif
23731 +
23732 +#ifdef CONFIG_MODE_SKAS
23733 +EXPORT_SYMBOL(strncpy_from_user_skas);
23734 +EXPORT_SYMBOL(copy_to_user_skas);
23735 +EXPORT_SYMBOL(copy_from_user_skas);
23736 +#endif
23737 +
23738 +EXPORT_SYMBOL(os_stat_fd);
23739 +EXPORT_SYMBOL(os_stat_file);
23740 +EXPORT_SYMBOL(os_access);
23741 +EXPORT_SYMBOL(os_print_error);
23742 +EXPORT_SYMBOL(os_get_exec_close);
23743 +EXPORT_SYMBOL(os_set_exec_close);
23744 +EXPORT_SYMBOL(os_getpid);
23745 +EXPORT_SYMBOL(os_open_file);
23746 +EXPORT_SYMBOL(os_read_file);
23747 +EXPORT_SYMBOL(os_write_file);
23748 +EXPORT_SYMBOL(os_seek_file);
23749 +EXPORT_SYMBOL(os_lock_file);
23750 +EXPORT_SYMBOL(os_pipe);
23751 +EXPORT_SYMBOL(os_file_type);
23752 +EXPORT_SYMBOL(os_file_mode);
23753 +EXPORT_SYMBOL(os_file_size);
23754 +EXPORT_SYMBOL(os_flush_stdout);
23755 +EXPORT_SYMBOL(os_close_file);
23756 +EXPORT_SYMBOL(os_set_fd_async);
23757 +EXPORT_SYMBOL(os_set_fd_block);
23758 +EXPORT_SYMBOL(helper_wait);
23759 +EXPORT_SYMBOL(os_shutdown_socket);
23760 +EXPORT_SYMBOL(os_create_unix_socket);
23761 +EXPORT_SYMBOL(os_connect_socket);
23762 +EXPORT_SYMBOL(os_accept_connection);
23763 +EXPORT_SYMBOL(os_ioctl_generic);
23764 +EXPORT_SYMBOL(os_rcv_fd);
23765 +EXPORT_SYMBOL(run_helper);
23766 +EXPORT_SYMBOL(start_thread);
23767 +EXPORT_SYMBOL(dump_thread);
23768 +
23769 +/* This is here because UML expands open to sys_open, not to a system
23770 + * call instruction.
23771 + */
23772 +EXPORT_SYMBOL(sys_open);
23773 +EXPORT_SYMBOL(sys_lseek);
23774 +EXPORT_SYMBOL(sys_read);
23775 +EXPORT_SYMBOL(sys_wait4);
23776 +
23777 +#ifdef CONFIG_SMP
23778 +
23779 +/* required for SMP */
23780 +
23781 +extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
23782 +EXPORT_SYMBOL_NOVERS(__write_lock_failed);
23783 +
23784 +extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
23785 +EXPORT_SYMBOL_NOVERS(__read_lock_failed);
23786 +
23787 +EXPORT_SYMBOL(kernel_flag_cacheline);
23788 +EXPORT_SYMBOL(smp_num_cpus);
23789 +
23790 +#endif
23791 +
23792 +/*
23793 + * Overrides for Emacs so that we follow Linus's tabbing style.
23794 + * Emacs will notice this stuff at the end of the file and automatically
23795 + * adjust the settings for this buffer only.  This must remain at the end
23796 + * of the file.
23797 + * ---------------------------------------------------------------------------
23798 + * Local variables:
23799 + * c-file-style: "linux"
23800 + * End:
23801 + */
23802 Index: linux-2.4.29/arch/um/kernel/link.ld
23803 ===================================================================
23804 --- linux-2.4.29.orig/arch/um/kernel/link.ld    1970-01-01 03:00:00.000000000 +0300
23805 +++ linux-2.4.29/arch/um/kernel/link.ld 2005-05-03 22:43:46.000000000 +0300
23806 @@ -0,0 +1,147 @@
23807 +OUTPUT_FORMAT("elf32-i386")
23808 +OUTPUT_ARCH(i386)
23809 +ENTRY(_start)
23810 +
23811 +SECTIONS
23812 +{
23813 +  . = 2684354560 + SIZEOF_HEADERS;
23814 +
23815 +  __binary_start = .;
23816 +
23817 +  .thread_private : {
23818 +    __start_thread_private = .;
23819 +    errno = .;
23820 +    . += 4;
23821 +    arch/um/kernel/tt/unmap_fin.o (.data)
23822 +    __end_thread_private = .;
23823 +  }
23824 +  . = ALIGN(4096);
23825 +  .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
23826 +
23827 +  . = ALIGN(4096);             /* Init code and data */
23828 +  _stext = .;
23829 +  __init_begin = .;
23830 +  .text.init : { *(.text.init) }
23831 +  . = ALIGN(4096);
23832 +  .text      :
23833 +  {
23834 +    *(.text)
23835 +    /* .gnu.warning sections are handled specially by elf32.em.  */
23836 +    *(.gnu.warning)
23837 +    *(.gnu.linkonce.t*)
23838 +  }
23839 +  .fini      : { *(.fini)    } =0x9090
23840 +  .rodata    : { *(.rodata) *(.gnu.linkonce.r*) }
23841 +  .rodata1   : { *(.rodata1) }
23842 +  _etext = .;
23843 +  PROVIDE (etext = .);
23844 +
23845 +  . = ALIGN(4096);
23846 +  PROVIDE (_sdata = .);
23847 +
23848 +  .kstrtab : { *(.kstrtab) }
23849 +
23850 +  . = ALIGN(16);               /* Exception table */
23851 +  __start___ex_table = .;
23852 +  __ex_table : { *(__ex_table) }
23853 +  __stop___ex_table = .;
23854 +
23855 +  __start___ksymtab = .;       /* Kernel symbol table */
23856 +  __ksymtab : { *(__ksymtab) }
23857 +  __stop___ksymtab = .;
23858 +
23859 +  .unprotected : { *(.unprotected) }
23860 +  . = ALIGN(4096);
23861 +  PROVIDE (_unprotected_end = .);
23862 +
23863 +  . = ALIGN(4096);
23864 +  __uml_setup_start = .;
23865 +  .uml.setup.init : { *(.uml.setup.init) }
23866 +  __uml_setup_end = .;
23867 +  __uml_help_start = .;
23868 +  .uml.help.init : { *(.uml.help.init) }
23869 +  __uml_help_end = .;
23870 +  __uml_postsetup_start = .;
23871 +  .uml.postsetup.init : { *(.uml.postsetup.init) }
23872 +  __uml_postsetup_end = .;
23873 +  __setup_start = .;
23874 +  .setup.init : { *(.setup.init) }
23875 +  __setup_end = .;
23876 +  __initcall_start = .;
23877 +  .initcall.init : { *(.initcall.init) }
23878 +  __initcall_end = .;
23879 +  __uml_initcall_start = .;
23880 +  .uml.initcall.init : { *(.uml.initcall.init) }
23881 +  __uml_initcall_end = .;
23882 +  __init_end = .;
23883 +  __exitcall_begin = .;
23884 +  .exitcall : { *(.exitcall.exit) }
23885 +  __exitcall_end = .;
23886 +  __uml_exitcall_begin = .;
23887 +  .uml.exitcall : { *(.uml.exitcall.exit) }
23888 +  __uml_exitcall_end = .;
23889 +
23890 +  __preinit_array_start = .;
23891 +  .preinit_array : { *(.preinit_array) }
23892 +  __preinit_array_end = .;
23893 +  __init_array_start = .;
23894 +  .init_array : { *(.init_array) }
23895 +  __init_array_end = .;
23896 +  __fini_array_start = .;
23897 +  .fini_array : { *(.fini_array) }
23898 +  __fini_array_end = .;
23899 +
23900 +  .data.init : { *(.data.init) }
23901 +
23902 +
23903 +  .data    :
23904 +  {
23905 +    . = ALIGN(32768);          /* init_task */
23906 +    *(.data.init_task)
23907 +    *(.data)
23908 +    *(.gnu.linkonce.d*)
23909 +    CONSTRUCTORS
23910 +  }
23911 +  .data1   : { *(.data1) }
23912 +  .ctors         :
23913 +  {
23914 +    *(.ctors)
23915 +  }
23916 +  .dtors         :
23917 +  {
23918 +    *(.dtors)
23919 +  }
23920 +
23921 +  .got           : { *(.got.plt) *(.got) }
23922 +  .dynamic       : { *(.dynamic) }
23923 +  /* We want the small data sections together, so single-instruction offsets
23924 +     can access them all, and initialized data all before uninitialized, so
23925 +     we can shorten the on-disk segment size.  */
23926 +  .sdata     : { *(.sdata) }
23927 +  _edata  =  .;
23928 +  PROVIDE (edata = .);
23929 +  . = ALIGN(0x1000);
23930 +  .sbss      : 
23931 +  {
23932 +   __bss_start = .;
23933 +   PROVIDE(_bss_start = .);
23934 +   *(.sbss) 
23935 +   *(.scommon) 
23936 +  }
23937 +  .bss       :
23938 +  {
23939 +   *(.dynbss)
23940 +   *(.bss)
23941 +   *(COMMON)
23942 +  }
23943 +  _end = . ;
23944 +  PROVIDE (end = .);
23945 +  /* Stabs debugging sections.  */
23946 +  .stab 0 : { *(.stab) }
23947 +  .stabstr 0 : { *(.stabstr) }
23948 +  .stab.excl 0 : { *(.stab.excl) }
23949 +  .stab.exclstr 0 : { *(.stab.exclstr) }
23950 +  .stab.index 0 : { *(.stab.index) }
23951 +  .stab.indexstr 0 : { *(.stab.indexstr) }
23952 +  .comment 0 : { *(.comment) }
23953 +}
23954 Index: linux-2.4.29/arch/um/kernel/link.ld.in
23955 ===================================================================
23956 --- linux-2.4.29.orig/arch/um/kernel/link.ld.in 1970-01-01 03:00:00.000000000 +0300
23957 +++ linux-2.4.29/arch/um/kernel/link.ld.in      2005-05-03 22:28:14.000000000 +0300
23958 @@ -0,0 +1,94 @@
23959 +OUTPUT_FORMAT("ELF_FORMAT")
23960 +OUTPUT_ARCH(ELF_ARCH)
23961 +ENTRY(_start)
23962 +
23963 +SECTIONS
23964 +{
23965 +  . = START() + SIZEOF_HEADERS;
23966 +
23967 +  __binary_start = .;
23968 +ifdef(`MODE_TT', `
23969 +  .thread_private : {
23970 +    __start_thread_private = .;
23971 +    errno = .;
23972 +    . += 4;
23973 +    arch/um/kernel/tt/unmap_fin.o (.data)
23974 +    __end_thread_private = .;
23975 +  }
23976 +  . = ALIGN(4096);
23977 +  .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
23978 +')
23979 +  . = ALIGN(4096);             /* Init code and data */
23980 +  _stext = .;
23981 +  __init_begin = .;
23982 +  .text.init : { *(.text.init) }
23983 +  . = ALIGN(4096);
23984 +  .text      :
23985 +  {
23986 +    *(.text)
23987 +    /* .gnu.warning sections are handled specially by elf32.em.  */
23988 +    *(.gnu.warning)
23989 +    *(.gnu.linkonce.t*)
23990 +  }
23991 +  .fini      : { *(.fini)    } =0x9090
23992 +  .rodata    : { *(.rodata) *(.gnu.linkonce.r*) }
23993 +  .rodata1   : { *(.rodata1) }
23994 +  _etext = .;
23995 +  PROVIDE (etext = .);
23996 +
23997 +  . = ALIGN(4096);
23998 +  PROVIDE (_sdata = .);
23999 +
24000 +include(`arch/um/kernel/common.ld.in')
24001 +
24002 +  .data    :
24003 +  {
24004 +    . = ALIGN(KERNEL_STACK_SIZE);              /* init_task */
24005 +    *(.data.init_task)
24006 +    *(.data)
24007 +    *(.gnu.linkonce.d*)
24008 +    CONSTRUCTORS
24009 +  }
24010 +  .data1   : { *(.data1) }
24011 +  .ctors         :
24012 +  {
24013 +    *(.ctors)
24014 +  }
24015 +  .dtors         :
24016 +  {
24017 +    *(.dtors)
24018 +  }
24019 +
24020 +  .got           : { *(.got.plt) *(.got) }
24021 +  .dynamic       : { *(.dynamic) }
24022 +  /* We want the small data sections together, so single-instruction offsets
24023 +     can access them all, and initialized data all before uninitialized, so
24024 +     we can shorten the on-disk segment size.  */
24025 +  .sdata     : { *(.sdata) }
24026 +  _edata  =  .;
24027 +  PROVIDE (edata = .);
24028 +  . = ALIGN(0x1000);
24029 +  .sbss      : 
24030 +  {
24031 +   __bss_start = .;
24032 +   PROVIDE(_bss_start = .);
24033 +   *(.sbss) 
24034 +   *(.scommon) 
24035 +  }
24036 +  .bss       :
24037 +  {
24038 +   *(.dynbss)
24039 +   *(.bss)
24040 +   *(COMMON)
24041 +  }
24042 +  _end = . ;
24043 +  PROVIDE (end = .);
24044 +  /* Stabs debugging sections.  */
24045 +  .stab 0 : { *(.stab) }
24046 +  .stabstr 0 : { *(.stabstr) }
24047 +  .stab.excl 0 : { *(.stab.excl) }
24048 +  .stab.exclstr 0 : { *(.stab.exclstr) }
24049 +  .stab.index 0 : { *(.stab.index) }
24050 +  .stab.indexstr 0 : { *(.stab.indexstr) }
24051 +  .comment 0 : { *(.comment) }
24052 +}
24053 Index: linux-2.4.29/arch/um/kernel/main.c
24054 ===================================================================
24055 --- linux-2.4.29.orig/arch/um/kernel/main.c     1970-01-01 03:00:00.000000000 +0300
24056 +++ linux-2.4.29/arch/um/kernel/main.c  2005-05-03 22:28:14.429416608 +0300
24057 @@ -0,0 +1,250 @@
24058 +/* 
24059 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
24060 + * Licensed under the GPL
24061 + */
24062 +
24063 +#include <unistd.h>
24064 +#include <stdio.h> 
24065 +#include <stdlib.h>
24066 +#include <string.h>
24067 +#include <signal.h>
24068 +#include <errno.h>
24069 +#include <sys/resource.h>
24070 +#include <sys/mman.h>
24071 +#include <sys/user.h>
24072 +#include <asm/page.h>
24073 +#include "user_util.h"
24074 +#include "kern_util.h"
24075 +#include "mem_user.h"
24076 +#include "signal_user.h"
24077 +#include "time_user.h"
24078 +#include "irq_user.h"
24079 +#include "user.h"
24080 +#include "init.h"
24081 +#include "mode.h"
24082 +#include "choose-mode.h"
24083 +#include "uml-config.h"
24084 +
24085 +/* Set in set_stklim, which is called from main and __wrap_malloc.  
24086 + * __wrap_malloc only calls it if main hasn't started.
24087 + */
24088 +unsigned long stacksizelim;
24089 +
24090 +/* Set in main */
24091 +char *linux_prog;
24092 +
24093 +#define PGD_BOUND (4 * 1024 * 1024)
24094 +#define STACKSIZE (8 * 1024 * 1024)
24095 +#define THREAD_NAME_LEN (256)
24096 +
24097 +static void set_stklim(void)
24098 +{
24099 +       struct rlimit lim;
24100 +
24101 +       if(getrlimit(RLIMIT_STACK, &lim) < 0){
24102 +               perror("getrlimit");
24103 +               exit(1);
24104 +       }
24105 +       if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){
24106 +               lim.rlim_cur = STACKSIZE;
24107 +               if(setrlimit(RLIMIT_STACK, &lim) < 0){
24108 +                       perror("setrlimit");
24109 +                       exit(1);
24110 +               }
24111 +       }
24112 +       stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1);
24113 +}
24114 +
24115 +static __init void do_uml_initcalls(void)
24116 +{
24117 +       initcall_t *call;
24118 +
24119 +       call = &__uml_initcall_start;
24120 +       while (call < &__uml_initcall_end){;
24121 +               (*call)();
24122 +               call++;
24123 +       }
24124 +}
24125 +
24126 +static void last_ditch_exit(int sig)
24127 +{
24128 +       CHOOSE_MODE(kmalloc_ok = 0, (void) 0);
24129 +       signal(SIGINT, SIG_DFL);
24130 +       signal(SIGTERM, SIG_DFL);
24131 +       signal(SIGHUP, SIG_DFL);
24132 +       uml_cleanup();
24133 +       exit(1);
24134 +}
24135 +
24136 +extern int uml_exitcode;
24137 +
24138 +int main(int argc, char **argv, char **envp)
24139 +{
24140 +       char **new_argv;
24141 +       sigset_t mask;
24142 +       int ret, i;
24143 +
24144 +       /* Enable all signals except SIGIO - in some environments, we can 
24145 +        * enter with some signals blocked
24146 +        */
24147 +
24148 +       sigemptyset(&mask);
24149 +       sigaddset(&mask, SIGIO);
24150 +       if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){
24151 +               perror("sigprocmask");
24152 +               exit(1);
24153 +       }
24154 +
24155 +#ifdef UML_CONFIG_MODE_TT
24156 +       /* Allocate memory for thread command lines */
24157 +       if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
24158 +
24159 +               char padding[THREAD_NAME_LEN] = { 
24160 +                       [ 0 ...  THREAD_NAME_LEN - 2] = ' ', '\0' 
24161 +               };
24162 +
24163 +               new_argv = malloc((argc + 2) * sizeof(char*));
24164 +               if(!new_argv) {
24165 +                       perror("Allocating extended argv");
24166 +                       exit(1);
24167 +               }       
24168 +               
24169 +               new_argv[0] = argv[0];
24170 +               new_argv[1] = padding;
24171 +               
24172 +               for(i = 2; i <= argc; i++)
24173 +                       new_argv[i] = argv[i - 1];
24174 +               new_argv[argc + 1] = NULL;
24175 +               
24176 +               execvp(new_argv[0], new_argv);
24177 +               perror("execing with extended args");
24178 +               exit(1);
24179 +       }       
24180 +#endif
24181 +
24182 +       linux_prog = argv[0];
24183 +
24184 +       set_stklim();
24185 +
24186 +       new_argv = malloc((argc + 1) * sizeof(char *));
24187 +       if(new_argv == NULL){
24188 +               perror("Mallocing argv");
24189 +               exit(1);
24190 +       }
24191 +       for(i=0;i<argc;i++){
24192 +               new_argv[i] = strdup(argv[i]);
24193 +               if(new_argv[i] == NULL){
24194 +                       perror("Mallocing an arg");
24195 +                       exit(1);
24196 +               }
24197 +       }
24198 +       new_argv[argc] = NULL;
24199 +
24200 +       set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
24201 +       set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
24202 +       set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
24203 +
24204 +       do_uml_initcalls();
24205 +       ret = linux_main(argc, argv);
24206 +       
24207 +       /* Reboot */
24208 +       if(ret){
24209 +               int err;
24210 +
24211 +               printf("\n");
24212 +
24213 +               /* Let any pending signals fire, then disable them.  This 
24214 +                * ensures that they won't be delivered after the exec, when 
24215 +                * they are definitely not expected.
24216 +                */
24217 +               unblock_signals();
24218 +               disable_timer();
24219 +               err = deactivate_all_fds();
24220 +               if(err)
24221 +                       printf("deactivate_all_fds failed, errno = %d\n", -err);
24222 +
24223 +               execvp(new_argv[0], new_argv);
24224 +               perror("Failed to exec kernel");
24225 +               ret = 1;
24226 +       }
24227 +       printf("\n");
24228 +       return(uml_exitcode);
24229 +}
24230 +
24231 +#define CAN_KMALLOC() \
24232 +       (kmalloc_ok && CHOOSE_MODE((getpid() != tracing_pid), 1))
24233 +
24234 +extern void *__real_malloc(int);
24235 +
24236 +void *__wrap_malloc(int size)
24237 +{
24238 +       void *ret;
24239 +
24240 +       if(!CAN_KMALLOC())
24241 +               return(__real_malloc(size));
24242 +       else if(size <= PAGE_SIZE) /* finding contiguos pages is hard */
24243 +               ret = um_kmalloc(size);
24244 +       else ret = um_vmalloc(size);
24245 +
24246 +       /* glibc people insist that if malloc fails, errno should be
24247 +        * set by malloc as well. So we do.
24248 +        */
24249 +       if(ret == NULL)
24250 +               errno = ENOMEM;
24251 +
24252 +       return(ret);
24253 +}
24254 +
24255 +void *__wrap_calloc(int n, int size)
24256 +{
24257 +       void *ptr = __wrap_malloc(n * size);
24258 +
24259 +       if(ptr == NULL) return(NULL);
24260 +       memset(ptr, 0, n * size);
24261 +       return(ptr);
24262 +}
24263 +
24264 +extern void __real_free(void *);
24265 +
24266 +extern unsigned long high_physmem;
24267 +
24268 +void __wrap_free(void *ptr)
24269 +{
24270 +       unsigned long addr = (unsigned long) ptr;
24271 +
24272 +       /* We need to know how the allocation happened, so it can be correctly
24273 +        * freed.  This is done by seeing what region of memory the pointer is
24274 +        * in -
24275 +        *      physical memory - kmalloc/kfree
24276 +        *      kernel virtual memory - vmalloc/vfree
24277 +        *      anywhere else - malloc/free
24278 +        * If kmalloc is not yet possible, then the kernel memory regions
24279 +        * may not be set up yet, and the variables not set up.  So,
24280 +        * free is called.
24281 +        *
24282 +        * CAN_KMALLOC is checked because it would be bad to free a buffer
24283 +        * with kmalloc/vmalloc after they have been turned off during 
24284 +        * shutdown.
24285 +        */
24286 +
24287 +       if((addr >= uml_physmem) && (addr < high_physmem)){
24288 +               if(CAN_KMALLOC())
24289 +                       kfree(ptr);
24290 +       }
24291 +       else if((addr >= start_vm) && (addr < end_vm)){
24292 +               if(CAN_KMALLOC())
24293 +                       vfree(ptr);
24294 +       }
24295 +       else __real_free(ptr);
24296 +}
24297 +
24298 +/*
24299 + * Overrides for Emacs so that we follow Linus's tabbing style.
24300 + * Emacs will notice this stuff at the end of the file and automatically
24301 + * adjust the settings for this buffer only.  This must remain at the end
24302 + * of the file.
24303 + * ---------------------------------------------------------------------------
24304 + * Local variables:
24305 + * c-file-style: "linux"
24306 + * End:
24307 + */
24308 Index: linux-2.4.29/arch/um/kernel/Makefile
24309 ===================================================================
24310 --- linux-2.4.29.orig/arch/um/kernel/Makefile   1970-01-01 03:00:00.000000000 +0300
24311 +++ linux-2.4.29/arch/um/kernel/Makefile        2005-05-03 22:28:14.430416456 +0300
24312 @@ -0,0 +1,73 @@
24313 +# 
24314 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24315 +# Licensed under the GPL
24316 +#
24317 +
24318 +O_TARGET = built-in.o
24319 +
24320 +obj-y = config.o checksum.o exec_kern.o exitcode.o filehandle.o frame_kern.o \
24321 +       frame.o helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o \
24322 +       mem_user.o physmem.o process.o process_kern.o ptrace.o reboot.o \
24323 +       resource.o sigio_user.o sigio_kern.o signal_kern.o signal_user.o \
24324 +       smp.o syscall_kern.o syscall_user.o sysrq.o sys_call_table.o \
24325 +       tempfile.o time.o time_kern.o tlb.o trap_kern.o trap_user.o \
24326 +       uaccess_user.o um_arch.o umid.o user_syms.o user_util.o
24327 +
24328 +obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
24329 +obj-$(CONFIG_GPROF) += gprof_syms.o
24330 +obj-$(CONFIG_GCOV) += gmon_syms.o
24331 +obj-$(CONFIG_TTY_LOG) += tty_log.o
24332 +
24333 +subdir-$(CONFIG_MODE_TT) += tt
24334 +subdir-$(CONFIG_MODE_SKAS) += skas
24335 +
24336 +user-objs-$(CONFIG_TTY_LOG) += tty_log.o
24337 +
24338 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
24339 +
24340 +# user_syms.o not included here because Rules.make has its own ideas about
24341 +# building anything in export-objs
24342 +
24343 +USER_OBJS = $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
24344 +       main.o process.o tempfile.o time.o umid.o user_util.o 
24345 +
24346 +DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__
24347 +DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__
24348 +
24349 +export-objs-$(CONFIG_GPROF) += gprof_syms.o
24350 +export-objs-$(CONFIG_GCOV) += gmon_syms.o
24351 +
24352 +export-objs = ksyms.o process_kern.o signal_kern.o user_syms.o $(export-objs-y)
24353 +
24354 +CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \
24355 +       -I/usr/include -I../include
24356 +
24357 +CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
24358 +
24359 +include $(TOPDIR)/Rules.make
24360 +
24361 +$(USER_OBJS) : %.o: %.c
24362 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
24363 +
24364 +# This has to be separate because it needs be compiled with frame pointers
24365 +# regardless of how the rest of the kernel is built.
24366 +
24367 +frame.o: frame.c
24368 +       $(CC) $(CFLAGS_$@) -c -o $@ $<
24369 +
24370 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
24371 +
24372 +config.c : config.c.in $(TOPDIR)/.config
24373 +       $(PERL) -e $(QUOTE) < config.c.in > $@
24374 +
24375 +clean:
24376 +       $(RM) config.c
24377 +       for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
24378 +
24379 +modules:
24380 +
24381 +fastdep:
24382 +
24383 +dep:
24384 +
24385 +archmrproper: clean
24386 Index: linux-2.4.29/arch/um/kernel/mem.c
24387 ===================================================================
24388 --- linux-2.4.29.orig/arch/um/kernel/mem.c      1970-01-01 03:00:00.000000000 +0300
24389 +++ linux-2.4.29/arch/um/kernel/mem.c   2005-05-03 22:28:14.431416304 +0300
24390 @@ -0,0 +1,336 @@
24391 +/* 
24392 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
24393 + * Licensed under the GPL
24394 + */
24395 +
24396 +#include "linux/stddef.h"
24397 +#include "linux/kernel.h"
24398 +#include "linux/mm.h"
24399 +#include "linux/bootmem.h"
24400 +#include "linux/highmem.h"
24401 +#include "asm/page.h"
24402 +#include "asm/fixmap.h"
24403 +#include "asm/pgalloc.h"
24404 +#include "user_util.h"
24405 +#include "kern_util.h"
24406 +#include "kern.h"
24407 +#include "mem_user.h"
24408 +#include "uml_uaccess.h"
24409 +#include "os.h"
24410 +
24411 +extern char __binary_start;
24412 +
24413 +/* Changed during early boot */
24414 +unsigned long *empty_zero_page = NULL;
24415 +unsigned long *empty_bad_page = NULL;
24416 +pgd_t swapper_pg_dir[1024];
24417 +unsigned long highmem;
24418 +int kmalloc_ok = 0;
24419 +
24420 +static unsigned long brk_end;
24421 +static unsigned long totalram_pages = 0;
24422 +
24423 +void unmap_physmem(void)
24424 +{
24425 +       os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
24426 +}
24427 +
24428 +static void map_cb(void *unused)
24429 +{
24430 +       map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
24431 +}
24432 +
24433 +#ifdef CONFIG_HIGHMEM
24434 +static void setup_highmem(unsigned long highmem_start, 
24435 +                         unsigned long highmem_len)
24436 +{
24437 +       struct page *page;
24438 +       unsigned long highmem_pfn;
24439 +       int i;
24440 +
24441 +       highmem_start_page = virt_to_page(highmem_start);
24442 +
24443 +       highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT;
24444 +       for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
24445 +               page = &mem_map[highmem_pfn + i];
24446 +               ClearPageReserved(page);
24447 +               set_bit(PG_highmem, &page->flags);
24448 +               atomic_set(&page->count, 1);
24449 +               __free_page(page);
24450 +       }
24451 +}
24452 +#endif
24453 +
24454 +void mem_init(void)
24455 +{
24456 +       unsigned long start;
24457 +
24458 +        /* clear the zero-page */
24459 +        memset((void *) empty_zero_page, 0, PAGE_SIZE);
24460 +
24461 +       /* Map in the area just after the brk now that kmalloc is about
24462 +        * to be turned on.
24463 +        */
24464 +       brk_end = (unsigned long) UML_ROUND_UP(sbrk(0));
24465 +       map_cb(NULL);
24466 +       initial_thread_cb(map_cb, NULL);
24467 +       free_bootmem(__pa(brk_end), uml_reserved - brk_end);
24468 +       uml_reserved = brk_end;
24469 +
24470 +       /* Fill in any hole at the start of the binary */
24471 +       start = (unsigned long) &__binary_start;
24472 +       if(uml_physmem != start){
24473 +               map_memory(uml_physmem, __pa(uml_physmem), start - uml_physmem,
24474 +                          1, 1, 0);
24475 +       }
24476 +
24477 +       /* this will put all low memory onto the freelists */
24478 +       totalram_pages = free_all_bootmem();
24479 +       totalram_pages += highmem >> PAGE_SHIFT;
24480 +       num_physpages = totalram_pages;
24481 +       printk(KERN_INFO "Memory: %luk available\n", 
24482 +              (unsigned long) nr_free_pages() << (PAGE_SHIFT-10));
24483 +       kmalloc_ok = 1;
24484 +
24485 +#ifdef CONFIG_HIGHMEM
24486 +       setup_highmem(end_iomem, highmem);
24487 +#endif
24488 +}
24489 +
24490 +static void __init fixrange_init(unsigned long start, unsigned long end, 
24491 +                                pgd_t *pgd_base)
24492 +{
24493 +       pgd_t *pgd;
24494 +       pmd_t *pmd;
24495 +       pte_t *pte;
24496 +       int i, j;
24497 +       unsigned long vaddr;
24498 +
24499 +       vaddr = start;
24500 +       i = __pgd_offset(vaddr);
24501 +       j = __pmd_offset(vaddr);
24502 +       pgd = pgd_base + i;
24503 +
24504 +       for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
24505 +               pmd = (pmd_t *)pgd;
24506 +               for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
24507 +                       if (pmd_none(*pmd)) {
24508 +                               pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
24509 +                               set_pmd(pmd, __pmd(_KERNPG_TABLE + 
24510 +                                                  (unsigned long) __pa(pte)));
24511 +                               if (pte != pte_offset(pmd, 0))
24512 +                                       BUG();
24513 +                       }
24514 +                       vaddr += PMD_SIZE;
24515 +               }
24516 +               j = 0;
24517 +       }
24518 +}
24519 +
24520 +#ifdef CONFIG_HIGHMEM
24521 +pte_t *kmap_pte;
24522 +pgprot_t kmap_prot;
24523 +
24524 +#define kmap_get_fixmap_pte(vaddr)                                     \
24525 +       pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
24526 +
24527 +void __init kmap_init(void)
24528 +{
24529 +       unsigned long kmap_vstart;
24530 +
24531 +       /* cache the first kmap pte */
24532 +       kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
24533 +       kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
24534 +
24535 +       kmap_prot = PAGE_KERNEL;
24536 +}
24537 +
24538 +static void init_highmem(void)
24539 +{
24540 +       pgd_t *pgd;
24541 +       pmd_t *pmd;
24542 +       pte_t *pte;
24543 +       unsigned long vaddr;
24544 +
24545 +       /*
24546 +        * Permanent kmaps:
24547 +        */
24548 +       vaddr = PKMAP_BASE;
24549 +       fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, swapper_pg_dir);
24550 +
24551 +       pgd = swapper_pg_dir + __pgd_offset(vaddr);
24552 +       pmd = pmd_offset(pgd, vaddr);
24553 +       pte = pte_offset(pmd, vaddr);
24554 +       pkmap_page_table = pte;
24555 +
24556 +       kmap_init();
24557 +}
24558 +
24559 +#endif /* CONFIG_HIGHMEM */
24560 +
24561 +void paging_init(void)
24562 +{
24563 +       unsigned long zones_size[MAX_NR_ZONES], vaddr;
24564 +       int i;
24565 +
24566 +       empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
24567 +       empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
24568 +       for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++) 
24569 +               zones_size[i] = 0;
24570 +       zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
24571 +       zones_size[2] = highmem >> PAGE_SHIFT;
24572 +       free_area_init(zones_size);
24573 +
24574 +       /*
24575 +        * Fixed mappings, only the page table structure has to be
24576 +        * created - mappings will be set by set_fixmap():
24577 +        */
24578 +       vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
24579 +       fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir);
24580 +
24581 +#if CONFIG_HIGHMEM
24582 +       init_highmem();
24583 +#endif
24584 +}
24585 +
24586 +struct page *arch_validate(struct page *page, int mask, int order)
24587 +{
24588 +       unsigned long addr, zero = 0;
24589 +       int i;
24590 +
24591 + again:
24592 +       if(page == NULL) return(page);
24593 +       if(PageHighMem(page)) return(page);
24594 +
24595 +       addr = (unsigned long) page_address(page);
24596 +       for(i = 0; i < (1 << order); i++){
24597 +               current->thread.fault_addr = (void *) addr;
24598 +               if(__do_copy_to_user((void *) addr, &zero, 
24599 +                                    sizeof(zero),
24600 +                                    &current->thread.fault_addr,
24601 +                                    &current->thread.fault_catcher)){
24602 +                       if(!(mask & __GFP_WAIT)) return(NULL);
24603 +                       else break;
24604 +               }
24605 +               addr += PAGE_SIZE;
24606 +       }
24607 +       if(i == (1 << order)) return(page);
24608 +       page = _alloc_pages(mask, order);
24609 +       goto again;
24610 +}
24611 +
24612 +/* This can't do anything because nothing in the kernel image can be freed
24613 + * since it's not in kernel physical memory.
24614 + */
24615 +
24616 +void free_initmem(void)
24617 +{
24618 +}
24619 +
24620 +#ifdef CONFIG_BLK_DEV_INITRD
24621 +
24622 +void free_initrd_mem(unsigned long start, unsigned long end)
24623 +{
24624 +       if (start < end)
24625 +               printk ("Freeing initrd memory: %ldk freed\n", 
24626 +                       (end - start) >> 10);
24627 +       for (; start < end; start += PAGE_SIZE) {
24628 +               ClearPageReserved(virt_to_page(start));
24629 +               set_page_count(virt_to_page(start), 1);
24630 +               free_page(start);
24631 +               totalram_pages++;
24632 +       }
24633 +}
24634 +       
24635 +#endif
24636 +
24637 +int do_check_pgt_cache(int low, int high)
24638 +{
24639 +        int freed = 0;
24640 +        if(pgtable_cache_size > high) {
24641 +                do {
24642 +                        if (pgd_quicklist) {
24643 +                                free_pgd_slow(get_pgd_fast());
24644 +                                freed++;
24645 +                        }
24646 +                        if (pmd_quicklist) {
24647 +                                pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
24648 +                                freed++;
24649 +                        }
24650 +                        if (pte_quicklist) {
24651 +                                pte_free_slow(pte_alloc_one_fast(NULL, 0));
24652 +                                freed++;
24653 +                        }
24654 +                } while(pgtable_cache_size > low);
24655 +        }
24656 +        return freed;
24657 +}
24658 +
24659 +void show_mem(void)
24660 +{
24661 +        int i, total = 0, reserved = 0;
24662 +        int shared = 0, cached = 0;
24663 +        int highmem = 0;
24664 +
24665 +        printk("Mem-info:\n");
24666 +        show_free_areas();
24667 +        printk("Free swap:       %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
24668 +        i = max_mapnr;
24669 +        while(i-- > 0) {
24670 +                total++;
24671 +                if(PageHighMem(mem_map + i))
24672 +                        highmem++;
24673 +                if(PageReserved(mem_map + i))
24674 +                        reserved++;
24675 +                else if(PageSwapCache(mem_map + i))
24676 +                        cached++;
24677 +                else if(page_count(mem_map + i))
24678 +                        shared += page_count(mem_map + i) - 1;
24679 +        }
24680 +        printk("%d pages of RAM\n", total);
24681 +        printk("%d pages of HIGHMEM\n", highmem);
24682 +        printk("%d reserved pages\n", reserved);
24683 +        printk("%d pages shared\n", shared);
24684 +        printk("%d pages swap cached\n", cached);
24685 +        printk("%ld pages in page table cache\n", pgtable_cache_size);
24686 +        show_buffers();
24687 +}
24688 +
24689 +/* Changed by meminfo_compat, which is a setup */
24690 +static int meminfo_22 = 0;
24691 +
24692 +static int meminfo_compat(char *str)
24693 +{
24694 +       meminfo_22 = 1;
24695 +       return(1);
24696 +}
24697 +
24698 +__setup("22_meminfo", meminfo_compat);
24699 +
24700 +void si_meminfo(struct sysinfo *val)
24701 +{
24702 +       val->totalram = totalram_pages;
24703 +       val->sharedram = 0;
24704 +       val->freeram = nr_free_pages();
24705 +       val->bufferram = atomic_read(&buffermem_pages);
24706 +       val->totalhigh = highmem >> PAGE_SHIFT;
24707 +       val->freehigh = nr_free_highpages();
24708 +       val->mem_unit = PAGE_SIZE;
24709 +       if(meminfo_22){
24710 +               val->freeram <<= PAGE_SHIFT;
24711 +               val->bufferram <<= PAGE_SHIFT;
24712 +               val->totalram <<= PAGE_SHIFT;
24713 +               val->sharedram <<= PAGE_SHIFT;
24714 +       }
24715 +}
24716 +
24717 +/*
24718 + * Overrides for Emacs so that we follow Linus's tabbing style.
24719 + * Emacs will notice this stuff at the end of the file and automatically
24720 + * adjust the settings for this buffer only.  This must remain at the end
24721 + * of the file.
24722 + * ---------------------------------------------------------------------------
24723 + * Local variables:
24724 + * c-file-style: "linux"
24725 + * End:
24726 + */
24727 Index: linux-2.4.29/arch/um/kernel/mem_user.c
24728 ===================================================================
24729 --- linux-2.4.29.orig/arch/um/kernel/mem_user.c 1970-01-01 03:00:00.000000000 +0300
24730 +++ linux-2.4.29/arch/um/kernel/mem_user.c      2005-05-03 22:28:14.433416000 +0300
24731 @@ -0,0 +1,271 @@
24732 +/*
24733 + * arch/um/kernel/mem_user.c
24734 + *
24735 + * BRIEF MODULE DESCRIPTION
24736 + * user side memory routines for supporting IO memory inside user mode linux
24737 + *
24738 + * Copyright (C) 2001 RidgeRun, Inc.
24739 + * Author: RidgeRun, Inc.
24740 + *         Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
24741 + *
24742 + *  This program is free software; you can redistribute  it and/or modify it
24743 + *  under  the terms of  the GNU General  Public License as published by the
24744 + *  Free Software Foundation;  either version 2 of the  License, or (at your
24745 + *  option) any later version.
24746 + *
24747 + *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
24748 + *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
24749 + *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
24750 + *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
24751 + *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24752 + *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
24753 + *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24754 + *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
24755 + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24756 + *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24757 + *
24758 + *  You should have received a copy of the  GNU General Public License along
24759 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
24760 + *  675 Mass Ave, Cambridge, MA 02139, USA.
24761 + */
24762 +
24763 +#include <stdio.h>
24764 +#include <stdlib.h>
24765 +#include <stddef.h>
24766 +#include <stdarg.h>
24767 +#include <unistd.h>
24768 +#include <errno.h>
24769 +#include <string.h>
24770 +#include <fcntl.h>
24771 +#include <sys/types.h>
24772 +#include <sys/mman.h>
24773 +#include "kern_util.h"
24774 +#include "user.h"
24775 +#include "user_util.h"
24776 +#include "mem_user.h"
24777 +#include "init.h"
24778 +#include "os.h"
24779 +#include "tempfile.h"
24780 +#include "kern_constants.h"
24781 +
24782 +extern struct mem_region physmem_region;
24783 +
24784 +#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
24785 +
24786 +static int create_tmp_file(unsigned long len)
24787 +{
24788 +       int fd, err;
24789 +       char zero;
24790 +
24791 +       fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
24792 +       if(fd < 0) {
24793 +               os_print_error(fd, "make_tempfile");
24794 +               exit(1);
24795 +       }
24796 +
24797 +       err = os_mode_fd(fd, 0777);
24798 +       if(err < 0){
24799 +               os_print_error(err, "os_mode_fd");
24800 +               exit(1);
24801 +       }
24802 +       err = os_seek_file(fd, len);
24803 +       if(err < 0){
24804 +               os_print_error(err, "os_seek_file");
24805 +               exit(1);
24806 +       }
24807 +       zero = 0;
24808 +       err = os_write_file(fd, &zero, 1);
24809 +       if(err != 1){
24810 +               os_print_error(err, "os_write_file");
24811 +               exit(1);
24812 +       }
24813 +
24814 +       return(fd);
24815 +}
24816 +
24817 +void check_tmpexec(void)
24818 +{
24819 +       void *addr;
24820 +       int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
24821 +
24822 +       addr = mmap(NULL, UM_KERN_PAGE_SIZE, 
24823 +                   PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
24824 +       printf("Checking PROT_EXEC mmap in /tmp...");
24825 +       fflush(stdout);
24826 +       if(addr == MAP_FAILED){
24827 +               err = errno;
24828 +               perror("failed");
24829 +               if(err == EPERM)
24830 +                       printf("/tmp must be not mounted noexec\n");
24831 +               exit(1);
24832 +       }
24833 +       printf("OK\n");
24834 +       munmap(addr, UM_KERN_PAGE_SIZE);
24835 +}
24836 +
24837 +static int have_devanon(void)
24838 +{
24839 +       int fd;
24840 +
24841 +       printk("Checking for /dev/anon on the host...");
24842 +       fd = open("/dev/anon", O_RDWR);
24843 +       if(fd < 0){
24844 +               printk("Not available (open failed with errno %d)\n", errno);
24845 +               return(0);
24846 +       }
24847 +
24848 +       printk("OK\n");
24849 +       return(1);
24850 +}
24851 +
24852 +static int create_anon_file(unsigned long len)
24853 +{
24854 +       void *addr;
24855 +       int fd;
24856 +
24857 +       fd = open("/dev/anon", O_RDWR);
24858 +       if(fd < 0) {
24859 +               os_print_error(fd, "opening /dev/anon");
24860 +               exit(1);
24861 +       }
24862 +
24863 +       addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
24864 +       if(addr == MAP_FAILED){
24865 +               os_print_error((int) addr, "mapping physmem file");
24866 +               exit(1);
24867 +       }
24868 +       munmap(addr, len);
24869 +
24870 +       return(fd);
24871 +}
24872 +
24873 +int create_mem_file(unsigned long len)
24874 +{
24875 +       int err, fd;
24876 +
24877 +       if(have_devanon())
24878 +               fd = create_anon_file(len);
24879 +       else fd = create_tmp_file(len);
24880 +
24881 +       err = os_set_exec_close(fd, 1);
24882 +       if(err < 0)
24883 +               os_print_error(err, "exec_close");
24884 +       return(fd);
24885 +}
24886 +
24887 +struct iomem_region *iomem_regions = NULL;
24888 +int iomem_size = 0;
24889 +
24890 +static int __init parse_iomem(char *str, int *add)
24891 +{
24892 +       struct iomem_region *new;
24893 +       struct uml_stat buf;
24894 +       char *file, *driver;
24895 +       int fd, err, size;
24896 +
24897 +       driver = str;
24898 +       file = strchr(str,',');
24899 +       if(file == NULL){
24900 +               printf("parse_iomem : failed to parse iomem\n");
24901 +               goto out;
24902 +       }
24903 +       *file = '\0';
24904 +       file++;
24905 +       fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
24906 +       if(fd < 0){
24907 +               os_print_error(fd, "parse_iomem - Couldn't open io file");
24908 +               goto out;
24909 +       }
24910 +
24911 +       err = os_stat_fd(fd, &buf);
24912 +       if(err < 0){
24913 +               os_print_error(err, "parse_iomem - cannot stat_fd file");
24914 +               goto out_close;
24915 +       }
24916 +
24917 +       new = malloc(sizeof(*new));
24918 +       if(new == NULL){
24919 +               perror("Couldn't allocate iomem_region struct");
24920 +               goto out_close;
24921 +       }
24922 +
24923 +       size = (buf.ust_size + UM_KERN_PAGE_SIZE) & ~(UM_KERN_PAGE_SIZE - 1);
24924 +
24925 +       *new = ((struct iomem_region) { .next           = iomem_regions,
24926 +                                       .driver         = driver,
24927 +                                       .fd             = fd,
24928 +                                       .size           = size,
24929 +                                       .phys           = 0,
24930 +                                       .virt           = 0 });
24931 +       iomem_regions = new;
24932 +       iomem_size += new->size + UM_KERN_PAGE_SIZE;
24933 +
24934 +       return(0);
24935 + out_close:
24936 +       os_close_file(fd);
24937 + out:
24938 +       return(1);
24939 +}
24940 +
24941 +__uml_setup("iomem=", parse_iomem,
24942 +"iomem=<name>,<file>\n"
24943 +"    Configure <file> as an IO memory region named <name>.\n\n"
24944 +);
24945 +
24946 +int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
24947 +                  int must_succeed)
24948 +{
24949 +       int err;
24950 +
24951 +       err = os_protect_memory((void *) addr, len, r, w, x);
24952 +       if(err < 0){
24953 +                if(must_succeed)
24954 +                        panic("protect failed, err = %d", -err);
24955 +                else return(err);
24956 +       }
24957 +       return(0);
24958 +}
24959 +
24960 +#if 0
24961 +/* Debugging facility for dumping stuff out to the host, avoiding the timing
24962 + * problems that come with printf and breakpoints.
24963 + * Enable in case of emergency.
24964 + */
24965 +
24966 +int logging = 1;
24967 +int logging_fd = -1;
24968 +
24969 +int logging_line = 0;
24970 +char logging_buf[512];
24971 +
24972 +void log(char *fmt, ...)
24973 +{
24974 +        va_list ap;
24975 +        struct timeval tv;
24976 +        struct openflags flags;
24977 +
24978 +        if(logging == 0) return;
24979 +        if(logging_fd < 0){
24980 +                flags = of_create(of_trunc(of_rdwr(OPENFLAGS())));
24981 +                logging_fd = os_open_file("log", flags, 0644);
24982 +        }
24983 +        gettimeofday(&tv, NULL);
24984 +        sprintf(logging_buf, "%d\t %u.%u  ", logging_line++, tv.tv_sec, 
24985 +                tv.tv_usec);
24986 +        va_start(ap, fmt);
24987 +        vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
24988 +        va_end(ap);
24989 +        write(logging_fd, logging_buf, strlen(logging_buf));
24990 +}
24991 +#endif
24992 +
24993 +/*
24994 + * Overrides for Emacs so that we follow Linus's tabbing style.
24995 + * Emacs will notice this stuff at the end of the file and automatically
24996 + * adjust the settings for this buffer only.  This must remain at the end
24997 + * of the file.
24998 + * ---------------------------------------------------------------------------
24999 + * Local variables:
25000 + * c-file-style: "linux"
25001 + * End:
25002 + */
25003 Index: linux-2.4.29/arch/um/kernel/physmem.c
25004 ===================================================================
25005 --- linux-2.4.29.orig/arch/um/kernel/physmem.c  1970-01-01 03:00:00.000000000 +0300
25006 +++ linux-2.4.29/arch/um/kernel/physmem.c       2005-05-03 22:28:14.436415544 +0300
25007 @@ -0,0 +1,480 @@
25008 +/* 
25009 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
25010 + * Licensed under the GPL
25011 + */
25012 +
25013 +#include "linux/mm.h"
25014 +#include "linux/rbtree.h"
25015 +#include "linux/slab.h"
25016 +#include "linux/vmalloc.h"
25017 +#include "linux/bootmem.h"
25018 +#include "asm/types.h"
25019 +#include "asm/pgtable.h"
25020 +#include "kern_util.h"
25021 +#include "user_util.h"
25022 +#include "mode_kern.h"
25023 +#include "mem.h"
25024 +#include "mem_user.h"
25025 +#include "os.h"
25026 +#include "kern.h"
25027 +#include "init.h"
25028 +
25029 +struct phys_desc {
25030 +       struct rb_node_s rb;
25031 +       int fd;
25032 +       __u64 offset;
25033 +       void *virt;
25034 +       unsigned long phys;
25035 +       struct list_head list;
25036 +};
25037 +
25038 +static struct rb_root_s phys_mappings = RB_ROOT;
25039 +
25040 +static struct rb_node_s **find_rb(void *virt)
25041 +{
25042 +       struct rb_node_s **n = &phys_mappings.rb_node;
25043 +       struct phys_desc *d;
25044 +
25045 +       while(*n != NULL){
25046 +               d = rb_entry(n, struct phys_desc, rb);
25047 +               if(d->virt == virt)
25048 +                       return(n);
25049 +
25050 +               if(d->virt > virt)
25051 +                       n = &(*n)->rb_left;
25052 +               else
25053 +                       n = &(*n)->rb_right;
25054 +       }
25055 +
25056 +       return(n);
25057 +}
25058 +
25059 +static struct phys_desc *find_phys_mapping(void *virt)
25060 +{
25061 +       struct rb_node_s **n = find_rb(virt);
25062 +
25063 +       if(*n == NULL)
25064 +               return(NULL);
25065 +
25066 +       return(rb_entry(n, struct phys_desc, rb));
25067 +}
25068 +
25069 +static void insert_phys_mapping(struct phys_desc *desc)
25070 +{
25071 +       struct rb_node_s **n = find_rb(desc->virt);
25072 +
25073 +       if(*n != NULL)
25074 +               panic("Physical remapping for %p already present", 
25075 +                     desc->virt);
25076 +
25077 +       rb_link_node(&desc->rb, (*n)->rb_parent, n);
25078 +       rb_insert_color(&desc->rb, &phys_mappings);
25079 +}
25080 +
25081 +LIST_HEAD(descriptor_mappings);
25082 +
25083 +struct desc_mapping {
25084 +       int fd;
25085 +       struct list_head list;
25086 +       struct list_head pages;
25087 +};
25088 +
25089 +static struct desc_mapping *find_mapping(int fd)
25090 +{
25091 +       struct desc_mapping *desc;
25092 +       struct list_head *ele;
25093 +
25094 +       list_for_each(ele, &descriptor_mappings){
25095 +               desc = list_entry(ele, struct desc_mapping, list);
25096 +               if(desc->fd == fd)
25097 +                       return(desc);
25098 +       }
25099 +
25100 +       return(NULL);
25101 +}
25102 +
25103 +static struct desc_mapping *descriptor_mapping(int fd)
25104 +{
25105 +       struct desc_mapping *desc;
25106 +
25107 +       desc = find_mapping(fd);
25108 +       if(desc != NULL)
25109 +               return(desc);
25110 +
25111 +       desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
25112 +       if(desc == NULL)
25113 +               return(NULL);
25114 +
25115 +       *desc = ((struct desc_mapping) 
25116 +               { .fd =         fd,
25117 +                 .list =       LIST_HEAD_INIT(desc->list),
25118 +                 .pages =      LIST_HEAD_INIT(desc->pages) });
25119 +       list_add(&desc->list, &descriptor_mappings);
25120 +
25121 +       return(desc);
25122 +}
25123 +
25124 +int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
25125 +{
25126 +       struct desc_mapping *fd_maps;
25127 +       struct phys_desc *desc;
25128 +       unsigned long phys;
25129 +       int err;
25130 +
25131 +       phys = __pa(virt);
25132 +       desc = find_phys_mapping(virt);
25133 +       if(desc != NULL){
25134 +               if((virt != desc->virt) || (fd != desc->fd) || 
25135 +                  (offset != desc->offset))
25136 +                       panic("Address 0x%p is already substituted\n", virt);
25137 +               return(0);
25138 +       }
25139 +
25140 +       fd_maps = descriptor_mapping(fd);
25141 +       if(fd_maps == NULL)
25142 +               return(-ENOMEM);
25143 +
25144 +       err = -ENOMEM;
25145 +       desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
25146 +       if(desc == NULL)
25147 +               goto out;
25148 +
25149 +       *desc = ((struct phys_desc) 
25150 +               { .fd =                 fd,
25151 +                 .offset =             offset,
25152 +                 .virt =               virt,
25153 +                 .phys =               __pa(virt),
25154 +                 .list =               LIST_HEAD_INIT(desc->list) });
25155 +       insert_phys_mapping(desc);
25156 +
25157 +       list_add(&desc->list, &fd_maps->pages);
25158 +
25159 +       virt = (void *) ((unsigned long) virt & PAGE_MASK);
25160 +       err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
25161 +       if(!err)
25162 +               goto out;
25163 +
25164 +       rb_erase(&desc->rb, &phys_mappings);
25165 +       kfree(desc);
25166 + out:
25167 +       return(err);
25168 +}
25169 +
25170 +static int physmem_fd = -1;
25171 +
25172 +static void remove_mapping(struct phys_desc *desc)
25173 +{
25174 +       void *virt = desc->virt;
25175 +       int err;
25176 +
25177 +       rb_erase(&desc->rb, &phys_mappings);
25178 +       list_del(&desc->list);
25179 +       kfree(desc);
25180 +
25181 +       err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
25182 +       if(err)
25183 +               panic("Failed to unmap block device page from physical memory, "
25184 +                     "errno = %d", -err);
25185 +}
25186 +
25187 +int physmem_remove_mapping(void *virt)
25188 +{
25189 +       struct phys_desc *desc;
25190 +
25191 +       virt = (void *) ((unsigned long) virt & PAGE_MASK);
25192 +       desc = find_phys_mapping(virt);
25193 +       if(desc == NULL)
25194 +               return(0);
25195 +
25196 +       remove_mapping(desc);
25197 +       return(1);
25198 +}
25199 +
25200 +void physmem_forget_descriptor(int fd)
25201 +{
25202 +       struct desc_mapping *desc;
25203 +       struct phys_desc *page;
25204 +       struct list_head *ele, *next;
25205 +       __u64 offset;
25206 +       void *addr;
25207 +       int err;
25208 +
25209 +       desc = find_mapping(fd);
25210 +       if(desc == NULL)
25211 +               return;
25212 +
25213 +       if(!list_empty(&desc->pages))
25214 +               printk("Still have mapped pages on fd %d\n", fd);
25215 +
25216 +       list_for_each_safe(ele, next, &desc->pages){
25217 +               page = list_entry(ele, struct phys_desc, list);
25218 +               offset = page->offset;
25219 +               addr = page->virt;
25220 +               remove_mapping(page);
25221 +               err = os_seek_file(fd, offset);
25222 +               if(err)
25223 +                       panic("physmem_forget_descriptor - failed to seek "
25224 +                             "to %lld in fd %d, error = %d\n",
25225 +                             offset, fd, -err);
25226 +               err = os_read_file(fd, addr, PAGE_SIZE);
25227 +               if(err < 0)
25228 +                       panic("physmem_forget_descriptor - failed to read "
25229 +                             "from fd %d to 0x%p, error = %d\n",
25230 +                             fd, addr, -err);
25231 +       }
25232 +
25233 +       list_del(&desc->list);
25234 +       kfree(desc);
25235 +}
25236 +
25237 +void arch_free_page(struct page *page, int order)
25238 +{
25239 +       void *virt;
25240 +       int i;
25241 +
25242 +       for(i = 0; i < (1 << order); i++){
25243 +               virt = __va(page_to_phys(page + i));
25244 +               physmem_remove_mapping(virt);
25245 +       }
25246 +}
25247 +
25248 +int is_remapped(const void *virt, int fd, __u64 offset)
25249 +{
25250 +       struct phys_desc *desc;
25251 +
25252 +       desc = find_phys_mapping((void *) virt);
25253 +       if(desc == NULL)
25254 +               return(0);
25255 +       if(offset != desc->offset)
25256 +               printk("offset mismatch\n");
25257 +       return(find_phys_mapping((void *) virt) != NULL);
25258 +}
25259 +
25260 +/* Changed during early boot */
25261 +unsigned long high_physmem;
25262 +
25263 +extern unsigned long physmem_size;
25264 +
25265 +void *to_virt(unsigned long phys)
25266 +{
25267 +       return((void *) uml_physmem + phys);
25268 +}
25269 +
25270 +unsigned long to_phys(void *virt)
25271 +{
25272 +       return(((unsigned long) virt) - uml_physmem);
25273 +}
25274 +
25275 +int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
25276 +{
25277 +       struct page *p, *map;
25278 +       unsigned long phys_len, phys_pages, highmem_len, highmem_pages;
25279 +       unsigned long iomem_len, iomem_pages, total_len, total_pages;
25280 +       int i;
25281 +
25282 +       phys_pages = physmem >> PAGE_SHIFT;
25283 +       phys_len = phys_pages * sizeof(struct page);
25284 +
25285 +       iomem_pages = iomem >> PAGE_SHIFT;
25286 +       iomem_len = iomem_pages * sizeof(struct page);
25287 +
25288 +       highmem_pages = highmem >> PAGE_SHIFT;
25289 +       highmem_len = highmem_pages * sizeof(struct page);
25290 +
25291 +       total_pages = phys_pages + iomem_pages + highmem_pages;
25292 +       total_len = phys_len + iomem_pages + highmem_len;
25293 +
25294 +       if(kmalloc_ok){
25295 +               map = kmalloc(total_len, GFP_KERNEL);
25296 +               if(map == NULL) 
25297 +                       map = vmalloc(total_len);
25298 +       }
25299 +       else map = alloc_bootmem_low_pages(total_len);
25300 +
25301 +       if(map == NULL)
25302 +               return(-ENOMEM);
25303 +
25304 +       for(i = 0; i < total_pages; i++){
25305 +               p = &map[i];
25306 +               set_page_count(p, 0);
25307 +               SetPageReserved(p);
25308 +               INIT_LIST_HEAD(&p->list);
25309 +       }
25310 +
25311 +       mem_map = map;
25312 +       max_mapnr = total_pages;
25313 +       return(0);
25314 +}
25315 +
25316 +struct page *phys_to_page(const unsigned long phys)
25317 +{
25318 +       return(&mem_map[phys >> PAGE_SHIFT]);
25319 +}
25320 +
25321 +struct page *__virt_to_page(const unsigned long virt)
25322 +{
25323 +       return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
25324 +}
25325 +
25326 +unsigned long page_to_phys(struct page *page)
25327 +{
25328 +       return((page - mem_map) << PAGE_SHIFT);
25329 +}
25330 +
25331 +pte_t mk_pte(struct page *page, pgprot_t pgprot)
25332 +{
25333 +       pte_t pte;
25334 +
25335 +       pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot);
25336 +       if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte));
25337 +       return(pte);
25338 +}
25339 +
25340 +/* Changed during early boot */
25341 +static unsigned long kmem_top = 0;
25342 +
25343 +unsigned long get_kmem_end(void)
25344 +{
25345 +       if(kmem_top == 0) 
25346 +               kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
25347 +       return(kmem_top);
25348 +}
25349 +
25350 +void map_memory(unsigned long virt, unsigned long phys, unsigned long len, 
25351 +               int r, int w, int x)
25352 +{
25353 +       __u64 offset;
25354 +       int fd, err;
25355 +
25356 +       fd = phys_mapping(phys, &offset);
25357 +       err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
25358 +       if(err)
25359 +               panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, "
25360 +                     "err = %d\n", virt, fd, offset, len, r, w, x, err);
25361 +}
25362 +
25363 +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
25364 +
25365 +void setup_physmem(unsigned long start, unsigned long reserve_end,
25366 +                  unsigned long len, unsigned long highmem)
25367 +{
25368 +       unsigned long reserve = reserve_end - start;
25369 +       int pfn = PFN_UP(__pa(reserve_end));
25370 +       int delta = (len - reserve) >> PAGE_SHIFT;
25371 +       int err, offset, bootmap_size;
25372 +
25373 +       physmem_fd = create_mem_file(len + highmem);
25374 +
25375 +       offset = uml_reserved - uml_physmem;
25376 +       err = os_map_memory((void *) uml_reserved, physmem_fd, offset, 
25377 +                           len - offset, 1, 1, 0);
25378 +       if(err < 0){
25379 +               os_print_error(err, "Mapping memory");
25380 +               exit(1);
25381 +       }
25382 +
25383 +       bootmap_size = init_bootmem(pfn, pfn + delta);
25384 +       free_bootmem(__pa(reserve_end) + bootmap_size,
25385 +                    len - bootmap_size - reserve);
25386 +}
25387 +
25388 +int phys_mapping(unsigned long phys, __u64 *offset_out)
25389 +{
25390 +       struct phys_desc *desc = find_phys_mapping(__va(phys & PAGE_MASK));
25391 +       int fd = -1;
25392 +
25393 +       if(desc != NULL){
25394 +               fd = desc->fd;
25395 +               *offset_out = desc->offset;
25396 +       }
25397 +       else if(phys < physmem_size){
25398 +               fd = physmem_fd;
25399 +               *offset_out = phys;
25400 +       }
25401 +       else if(phys < __pa(end_iomem)){
25402 +               struct iomem_region *region = iomem_regions;
25403 +       
25404 +               while(region != NULL){
25405 +                       if((phys >= region->phys) && 
25406 +                          (phys < region->phys + region->size)){
25407 +                               fd = region->fd;
25408 +                               *offset_out = phys - region->phys;
25409 +                               break;
25410 +                       }
25411 +                       region = region->next;
25412 +               }
25413 +       }
25414 +       else if(phys < __pa(end_iomem) + highmem){
25415 +               fd = physmem_fd;
25416 +               *offset_out = phys - iomem_size;
25417 +       }
25418 +
25419 +       return(fd);
25420 +}
25421 +
25422 +static int __init uml_mem_setup(char *line, int *add)
25423 +{
25424 +       char *retptr;
25425 +       physmem_size = memparse(line,&retptr);
25426 +       return 0;
25427 +}
25428 +__uml_setup("mem=", uml_mem_setup,
25429 +"mem=<Amount of desired ram>\n"
25430 +"    This controls how much \"physical\" memory the kernel allocates\n"
25431 +"    for the system. The size is specified as a number followed by\n"
25432 +"    one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
25433 +"    This is not related to the amount of memory in the host.  It can\n"
25434 +"    be more, and the excess, if it's ever used, will just be swapped out.\n"
25435 +"      Example: mem=64M\n\n"
25436 +);
25437 +
25438 +unsigned long find_iomem(char *driver, unsigned long *len_out)
25439 +{
25440 +       struct iomem_region *region = iomem_regions;
25441 +       
25442 +       while(region != NULL){
25443 +               if(!strcmp(region->driver, driver)){
25444 +                       *len_out = region->size;
25445 +                       return(region->virt);
25446 +               }
25447 +       }
25448 +
25449 +       return(0);
25450 +}
25451 +
25452 +int setup_iomem(void)
25453 +{
25454 +       struct iomem_region *region = iomem_regions;
25455 +       unsigned long iomem_start = high_physmem + PAGE_SIZE;
25456 +       int err;
25457 +
25458 +       while(region != NULL){
25459 +               err = os_map_memory((void *) iomem_start, region->fd, 0, 
25460 +                                   region->size, 1, 1, 0);
25461 +               if(err)
25462 +                       printk("Mapping iomem region for driver '%s' failed, "
25463 +                              "errno = %d\n", region->driver, -err);
25464 +               else {
25465 +                       region->virt = iomem_start;
25466 +                       region->phys = __pa(region->virt);
25467 +               }
25468 +
25469 +               iomem_start += region->size + PAGE_SIZE;
25470 +               region = region->next;
25471 +       }
25472 +
25473 +       return(0);
25474 +}
25475 +
25476 +__initcall(setup_iomem);
25477 +
25478 +/*
25479 + * Overrides for Emacs so that we follow Linus's tabbing style.
25480 + * Emacs will notice this stuff at the end of the file and automatically
25481 + * adjust the settings for this buffer only.  This must remain at the end
25482 + * of the file.
25483 + * ---------------------------------------------------------------------------
25484 + * Local variables:
25485 + * c-file-style: "linux"
25486 + * End:
25487 + */
25488 Index: linux-2.4.29/arch/um/kernel/process.c
25489 ===================================================================
25490 --- linux-2.4.29.orig/arch/um/kernel/process.c  1970-01-01 03:00:00.000000000 +0300
25491 +++ linux-2.4.29/arch/um/kernel/process.c       2005-05-03 22:28:14.437415392 +0300
25492 @@ -0,0 +1,310 @@
25493 +/* 
25494 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
25495 + * Licensed under the GPL
25496 + */
25497 +
25498 +#include <stdio.h>
25499 +#include <unistd.h>
25500 +#include <signal.h>
25501 +#include <sched.h>
25502 +#include <errno.h>
25503 +#include <stdarg.h>
25504 +#include <stdlib.h>
25505 +#include <setjmp.h>
25506 +#include <sys/time.h>
25507 +#include <sys/ptrace.h>
25508 +#include <sys/wait.h>
25509 +#include <sys/mman.h>
25510 +#include <asm/ptrace.h>
25511 +#include <asm/sigcontext.h>
25512 +#include <asm/unistd.h>
25513 +#include <asm/page.h>
25514 +#include <asm/user.h>
25515 +#include "user_util.h"
25516 +#include "kern_util.h"
25517 +#include "user.h"
25518 +#include "process.h"
25519 +#include "signal_kern.h"
25520 +#include "signal_user.h"
25521 +#include "sysdep/ptrace.h"
25522 +#include "sysdep/sigcontext.h"
25523 +#include "irq_user.h"
25524 +#include "ptrace_user.h"
25525 +#include "time_user.h"
25526 +#include "init.h"
25527 +#include "os.h"
25528 +#include "uml-config.h"
25529 +#include "choose-mode.h"
25530 +#include "mode.h"
25531 +#ifdef UML_CONFIG_MODE_SKAS
25532 +#include "skas.h"
25533 +#include "skas_ptrace.h"
25534 +#endif
25535 +
25536 +void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
25537 +{
25538 +       int flags = 0, pages;
25539 +
25540 +       if(sig_stack != NULL){
25541 +               pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER);
25542 +               set_sigstack(sig_stack, pages * page_size());
25543 +               flags = SA_ONSTACK;
25544 +       }
25545 +       if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
25546 +}
25547 +
25548 +void init_new_thread_signals(int altstack)
25549 +{
25550 +       int flags = altstack ? SA_ONSTACK : 0;
25551 +
25552 +       set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags, 
25553 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
25554 +       set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags, 
25555 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
25556 +       set_handler(SIGFPE, (__sighandler_t) sig_handler, flags, 
25557 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
25558 +       set_handler(SIGILL, (__sighandler_t) sig_handler, flags, 
25559 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
25560 +       set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, 
25561 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
25562 +       set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags, 
25563 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
25564 +       set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
25565 +                   flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
25566 +       signal(SIGHUP, SIG_IGN);
25567 +
25568 +       init_irq_signals(altstack);
25569 +}
25570 +
25571 +struct tramp {
25572 +       int (*tramp)(void *);
25573 +       void *tramp_data;
25574 +       unsigned long temp_stack;
25575 +       int flags;
25576 +       int pid;
25577 +};
25578 +
25579 +/* See above for why sigkill is here */
25580 +
25581 +int sigkill = SIGKILL;
25582 +
25583 +int outer_tramp(void *arg)
25584 +{
25585 +       struct tramp *t;
25586 +       int sig = sigkill;
25587 +
25588 +       t = arg;
25589 +       t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2,
25590 +                      t->flags, t->tramp_data);
25591 +       if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
25592 +       kill(os_getpid(), sig);
25593 +       _exit(0);
25594 +}
25595 +
25596 +int start_fork_tramp(void *thread_arg, unsigned long temp_stack, 
25597 +                    int clone_flags, int (*tramp)(void *))
25598 +{
25599 +       struct tramp arg;
25600 +       unsigned long sp;
25601 +       int new_pid, status, err;
25602 +
25603 +       /* The trampoline will run on the temporary stack */
25604 +       sp = stack_sp(temp_stack);
25605 +
25606 +       clone_flags |= CLONE_FILES | SIGCHLD;
25607 +
25608 +       arg.tramp = tramp;
25609 +       arg.tramp_data = thread_arg;
25610 +       arg.temp_stack = temp_stack;
25611 +       arg.flags = clone_flags;
25612 +
25613 +       /* Start the process and wait for it to kill itself */
25614 +       new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
25615 +       if(new_pid < 0) 
25616 +               return(new_pid);
25617 +
25618 +       CATCH_EINTR(err = waitpid(new_pid, &status, 0));
25619 +       if(err < 0) 
25620 +               panic("Waiting for outer trampoline failed - errno = %d", 
25621 +                     errno);
25622 +
25623 +       if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
25624 +               panic("outer trampoline didn't exit with SIGKILL, "
25625 +                     "status = %d", status);
25626 +
25627 +       return(arg.pid);
25628 +}
25629 +
25630 +static int ptrace_child(void *arg)
25631 +{
25632 +       int pid = os_getpid();
25633 +
25634 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
25635 +               perror("ptrace");
25636 +               os_kill_process(pid, 0);
25637 +       }
25638 +       os_stop_process(pid);
25639 +       _exit(os_getpid() == pid);
25640 +}
25641 +
25642 +static int start_ptraced_child(void **stack_out)
25643 +{
25644 +       void *stack;
25645 +       unsigned long sp;
25646 +       int pid, n, status;
25647 +       
25648 +       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
25649 +                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
25650 +       if(stack == MAP_FAILED)
25651 +               panic("check_ptrace : mmap failed, errno = %d", errno);
25652 +       sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
25653 +       pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
25654 +       if(pid < 0)
25655 +               panic("check_ptrace : clone failed, errno = %d", errno);
25656 +       CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
25657 +       if(n < 0)
25658 +               panic("check_ptrace : wait failed, errno = %d", errno);
25659 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
25660 +               panic("check_ptrace : expected SIGSTOP, got status = %d",
25661 +                     status);
25662 +
25663 +       *stack_out = stack;
25664 +       return(pid);
25665 +}
25666 +
25667 +static void stop_ptraced_child(int pid, void *stack, int exitcode)
25668 +{
25669 +       int status, n;
25670 +
25671 +       if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
25672 +               panic("check_ptrace : ptrace failed, errno = %d", errno);
25673 +       CATCH_EINTR(n = waitpid(pid, &status, 0));
25674 +       if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode))
25675 +               panic("check_ptrace : child exited with status 0x%x", status);
25676 +
25677 +       if(munmap(stack, PAGE_SIZE) < 0)
25678 +               panic("check_ptrace : munmap failed, errno = %d", errno);
25679 +}
25680 +
25681 +int use_sysemu = 0;
25682 +
25683 +void __init check_ptrace(void)
25684 +{
25685 +       void *stack;
25686 +       int pid, syscall, n, status;
25687 +
25688 +       printk("Checking that ptrace can change system call numbers...");
25689 +       pid = start_ptraced_child(&stack);
25690 +
25691 +       while(1){
25692 +               if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
25693 +                       panic("check_ptrace : ptrace failed, errno = %d", 
25694 +                             errno);
25695 +               CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
25696 +               if(n < 0)
25697 +                       panic("check_ptrace : wait failed, errno = %d", errno);
25698 +               if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
25699 +                       panic("check_ptrace : expected SIGTRAP, "
25700 +                             "got status = %d", status);
25701 +               
25702 +               syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET,
25703 +                                0);
25704 +               if(syscall == __NR_getpid){
25705 +                       n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
25706 +                                  __NR_getppid);
25707 +                       if(n < 0)
25708 +                               panic("check_ptrace : failed to modify system "
25709 +                                     "call, errno = %d", errno);
25710 +                       break;
25711 +               }
25712 +       }
25713 +       stop_ptraced_child(pid, stack, 0);
25714 +       printk("OK\n");
25715 +
25716 +       printk("Checking syscall emulation patch for ptrace...");
25717 +       pid = start_ptraced_child(&stack);
25718 +       if(ptrace(PTRACE_SYSEMU, pid, 0, 0) >= 0) {
25719 +               CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
25720 +               if(n < 0)
25721 +                       panic("check_ptrace : wait failed, errno = %d", errno);
25722 +
25723 +               if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
25724 +                       panic("check_ptrace : expected SIGTRAP, "
25725 +                             "got status = %d", status);
25726 +
25727 +               
25728 +               n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET,
25729 +                          os_getpid());
25730 +               if(n < 0)
25731 +                       panic("check_ptrace : failed to modify system "
25732 +                             "call return, errno = %d", errno);
25733 +
25734 +               stop_ptraced_child(pid, stack, 0);
25735 +
25736 +               printk("OK\n");
25737 +               use_sysemu = 1;
25738 +       }
25739 +       else {
25740 +               printk("missing\n");
25741 +               stop_ptraced_child(pid, stack, 1);
25742 +       }
25743 +}
25744 +
25745 +int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
25746 +{
25747 +       sigjmp_buf buf;
25748 +       int n;
25749 +
25750 +       *jmp_ptr = &buf;
25751 +       n = sigsetjmp(buf, 1);
25752 +       if(n != 0)
25753 +               return(n);
25754 +       (*fn)(arg);
25755 +       return(0);
25756 +}
25757 +
25758 +int can_do_skas(void)
25759 +{
25760 +#ifdef UML_CONFIG_MODE_SKAS
25761 +       struct ptrace_faultinfo fi;
25762 +       void *stack;
25763 +       int pid, n, ret = 1;
25764 +
25765 +       printf("Checking for the skas3 patch in the host...");
25766 +       pid = start_ptraced_child(&stack);
25767 +
25768 +       n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
25769 +       if(n < 0){
25770 +               if(errno == EIO)
25771 +                       printf("not found\n");
25772 +               else printf("No (unexpected errno - %d)\n", errno);
25773 +               ret = 0;
25774 +       }
25775 +       else printf("found\n");
25776 +
25777 +       init_registers(pid);
25778 +       stop_ptraced_child(pid, stack, 1);
25779 +
25780 +       printf("Checking for /proc/mm...");
25781 +       if(os_access("/proc/mm", OS_ACC_W_OK) < 0){
25782 +               printf("not found\n");
25783 +               ret = 0;
25784 +       }
25785 +       else printf("found\n");
25786 +
25787 +       return(ret);
25788 +#else
25789 +       return(0);
25790 +#endif
25791 +}
25792 +
25793 +/*
25794 + * Overrides for Emacs so that we follow Linus's tabbing style.
25795 + * Emacs will notice this stuff at the end of the file and automatically
25796 + * adjust the settings for this buffer only.  This must remain at the end
25797 + * of the file.
25798 + * ---------------------------------------------------------------------------
25799 + * Local variables:
25800 + * c-file-style: "linux"
25801 + * End:
25802 + */
25803 Index: linux-2.4.29/arch/um/kernel/process_kern.c
25804 ===================================================================
25805 --- linux-2.4.29.orig/arch/um/kernel/process_kern.c     1970-01-01 03:00:00.000000000 +0300
25806 +++ linux-2.4.29/arch/um/kernel/process_kern.c  2005-05-03 22:28:14.439415088 +0300
25807 @@ -0,0 +1,413 @@
25808 +/* 
25809 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
25810 + * Licensed under the GPL
25811 + */
25812 +
25813 +#include "linux/config.h"
25814 +#include "linux/kernel.h"
25815 +#include "linux/sched.h"
25816 +#include "linux/interrupt.h"
25817 +#include "linux/mm.h"
25818 +#include "linux/slab.h"
25819 +#include "linux/utsname.h"
25820 +#include "linux/fs.h"
25821 +#include "linux/utime.h"
25822 +#include "linux/smp_lock.h"
25823 +#include "linux/module.h"
25824 +#include "linux/init.h"
25825 +#include "linux/capability.h"
25826 +#include "linux/vmalloc.h"
25827 +#include "linux/ptrace.h"
25828 +#include "asm/unistd.h"
25829 +#include "asm/mman.h"
25830 +#include "asm/segment.h"
25831 +#include "asm/stat.h"
25832 +#include "asm/pgtable.h"
25833 +#include "asm/processor.h"
25834 +#include "asm/pgalloc.h"
25835 +#include "asm/spinlock.h"
25836 +#include "asm/uaccess.h"
25837 +#include "asm/user.h"
25838 +#include "user_util.h"
25839 +#include "kern_util.h"
25840 +#include "kern.h"
25841 +#include "signal_kern.h"
25842 +#include "signal_user.h"
25843 +#include "init.h"
25844 +#include "irq_user.h"
25845 +#include "mem_user.h"
25846 +#include "time_user.h"
25847 +#include "tlb.h"
25848 +#include "frame_kern.h"
25849 +#include "sigcontext.h"
25850 +#include "2_5compat.h"
25851 +#include "os.h"
25852 +#include "mode.h"
25853 +#include "mode_kern.h"
25854 +#include "choose-mode.h"
25855 +
25856 +/* This is a per-cpu array.  A processor only modifies its entry and it only
25857 + * cares about its entry, so it's OK if another processor is modifying its
25858 + * entry.
25859 + */
25860 +struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
25861 +
25862 +struct task_struct *get_task(int pid, int require)
25863 +{
25864 +        struct task_struct *ret;
25865 +
25866 +        read_lock(&tasklist_lock);
25867 +       ret = find_task_by_pid(pid);
25868 +        read_unlock(&tasklist_lock);
25869 +
25870 +        if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
25871 +        return(ret);
25872 +}
25873 +
25874 +int external_pid(void *t)
25875 +{
25876 +       struct task_struct *task = t ? t : current;
25877 +
25878 +       return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
25879 +}
25880 +
25881 +int pid_to_processor_id(int pid)
25882 +{
25883 +       int i;
25884 +
25885 +       for(i = 0; i < smp_num_cpus; i++){
25886 +               if(cpu_tasks[i].pid == pid) return(i);
25887 +       }
25888 +       return(-1);
25889 +}
25890 +
25891 +void free_stack(unsigned long stack, int order)
25892 +{
25893 +       free_pages(stack, order);
25894 +}
25895 +
25896 +unsigned long alloc_stack(int order, int atomic)
25897 +{
25898 +       unsigned long page;
25899 +       int flags = GFP_KERNEL;
25900 +
25901 +       if(atomic) flags |= GFP_ATOMIC;
25902 +       page = __get_free_pages(flags, order);
25903 +       if(page == 0)
25904 +               return(0);
25905 +       stack_protections(page);
25906 +       return(page);
25907 +}
25908 +
25909 +int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
25910 +{
25911 +       int pid;
25912 +
25913 +       current->thread.request.u.thread.proc = fn;
25914 +       current->thread.request.u.thread.arg = arg;
25915 +       pid = do_fork(CLONE_VM | flags, 0, NULL, 0);
25916 +#if 0 /* CLONE_UNTRACED for 2.6 */
25917 +       pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0);
25918 +#endif
25919 +       if(pid < 0) 
25920 +               panic("do_fork failed in kernel_thread, errno = %d", pid);
25921 +       return(pid);
25922 +}
25923 +
25924 +void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
25925 +              struct task_struct *tsk, unsigned cpu)
25926 +{
25927 +       if (prev != next) 
25928 +               clear_bit(cpu, &prev->cpu_vm_mask);
25929 +       set_bit(cpu, &next->cpu_vm_mask);
25930 +}
25931 +
25932 +void set_current(void *t)
25933 +{
25934 +       struct task_struct *task = t;
25935 +
25936 +       cpu_tasks[task->processor] = ((struct cpu_task) 
25937 +               { external_pid(task), task });
25938 +}
25939 +
25940 +void *_switch_to(void *prev, void *next)
25941 +{
25942 +       return(CHOOSE_MODE(_switch_to_tt(prev, next), 
25943 +                          _switch_to_skas(prev, next)));
25944 +}
25945 +
25946 +void interrupt_end(void)
25947 +{
25948 +       if(current->need_resched) schedule();
25949 +       if(current->sigpending != 0) do_signal(0);
25950 +}
25951 +
25952 +void release_thread(struct task_struct *task)
25953 +{
25954 +       CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
25955 +}
25956 +
25957 +void exit_thread(void)
25958 +{
25959 +       CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
25960 +       unprotect_stack((unsigned long) current);
25961 +}
25962 +
25963 +void *get_current(void)
25964 +{
25965 +       return(current);
25966 +}
25967 +
25968 +int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
25969 +               unsigned long stack_top, struct task_struct * p, 
25970 +               struct pt_regs *regs)
25971 +{
25972 +       p->thread = (struct thread_struct) INIT_THREAD;
25973 +       return(CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr, 
25974 +                               clone_flags, sp, stack_top, p, regs));
25975 +}
25976 +
25977 +void initial_thread_cb(void (*proc)(void *), void *arg)
25978 +{
25979 +       int save_kmalloc_ok = kmalloc_ok;
25980 +
25981 +       kmalloc_ok = 0;
25982 +       CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc, 
25983 +                        arg);
25984 +       kmalloc_ok = save_kmalloc_ok;
25985 +}
25986 +
25987 +unsigned long stack_sp(unsigned long page)
25988 +{
25989 +       return(page + PAGE_SIZE - sizeof(void *));
25990 +}
25991 +
25992 +int current_pid(void)
25993 +{
25994 +       return(current->pid);
25995 +}
25996 +
25997 +void cpu_idle(void)
25998 +{
25999 +       CHOOSE_MODE(init_idle_tt(), init_idle_skas());
26000 +
26001 +       atomic_inc(&init_mm.mm_count);
26002 +       current->mm = &init_mm;
26003 +       current->active_mm = &init_mm;
26004 +
26005 +       while(1){
26006 +               /* endless idle loop with no priority at all */
26007 +               SET_PRI(current);
26008 +
26009 +               /*
26010 +                * although we are an idle CPU, we do not want to
26011 +                * get into the scheduler unnecessarily.
26012 +                */
26013 +               if (current->need_resched) {
26014 +                       schedule();
26015 +                       check_pgt_cache();
26016 +               }
26017 +               idle_sleep(10);
26018 +       }
26019 +}
26020 +
26021 +int page_size(void)
26022 +{
26023 +       return(PAGE_SIZE);
26024 +}
26025 +
26026 +int page_mask(void)
26027 +{
26028 +       return(PAGE_MASK);
26029 +}
26030 +
26031 +void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 
26032 +                     pte_t *pte_out)
26033 +{
26034 +       pgd_t *pgd;
26035 +       pmd_t *pmd;
26036 +       pte_t *pte;
26037 +
26038 +       if(task->mm == NULL) 
26039 +               return(ERR_PTR(-EINVAL));
26040 +       pgd = pgd_offset(task->mm, addr);
26041 +       pmd = pmd_offset(pgd, addr);
26042 +       if(!pmd_present(*pmd)) 
26043 +               return(ERR_PTR(-EINVAL));
26044 +       pte = pte_offset(pmd, addr);
26045 +       if(!pte_present(*pte)) 
26046 +               return(ERR_PTR(-EINVAL));
26047 +       if(pte_out != NULL)
26048 +               *pte_out = *pte;
26049 +       return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK));
26050 +}
26051 +
26052 +char *current_cmd(void)
26053 +{
26054 +#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
26055 +       return("(Unknown)");
26056 +#else
26057 +       void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
26058 +       return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
26059 +#endif
26060 +}
26061 +
26062 +void force_sigbus(void)
26063 +{
26064 +       printk(KERN_ERR "Killing pid %d because of a lack of memory\n", 
26065 +              current->pid);
26066 +       lock_kernel();
26067 +       sigaddset(&current->pending.signal, SIGBUS);
26068 +       recalc_sigpending(current);
26069 +       current->flags |= PF_SIGNALED;
26070 +       do_exit(SIGBUS | 0x80);
26071 +}
26072 +
26073 +void dump_thread(struct pt_regs *regs, struct user *u)
26074 +{
26075 +}
26076 +
26077 +void enable_hlt(void)
26078 +{
26079 +       panic("enable_hlt");
26080 +}
26081 +
26082 +void disable_hlt(void)
26083 +{
26084 +       panic("disable_hlt");
26085 +}
26086 +
26087 +extern int signal_frame_size;
26088 +
26089 +void *um_kmalloc(int size)
26090 +{
26091 +       return(kmalloc(size, GFP_KERNEL));
26092 +}
26093 +
26094 +void *um_kmalloc_atomic(int size)
26095 +{
26096 +       return(kmalloc(size, GFP_ATOMIC));
26097 +}
26098 +
26099 +void *um_vmalloc(int size)
26100 +{
26101 +       return(vmalloc(size));
26102 +}
26103 +
26104 +unsigned long get_fault_addr(void)
26105 +{
26106 +       return((unsigned long) current->thread.fault_addr);
26107 +}
26108 +
26109 +EXPORT_SYMBOL(get_fault_addr);
26110 +
26111 +void not_implemented(void)
26112 +{
26113 +       printk(KERN_DEBUG "Something isn't implemented in here\n");
26114 +}
26115 +
26116 +EXPORT_SYMBOL(not_implemented);
26117 +
26118 +int user_context(unsigned long sp)
26119 +{
26120 +       unsigned long stack;
26121 +
26122 +       stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
26123 +       return(stack != current);
26124 +}
26125 +
26126 +extern void remove_umid_dir(void);
26127 +
26128 +__uml_exitcall(remove_umid_dir);
26129 +
26130 +extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
26131 +
26132 +void do_uml_exitcalls(void)
26133 +{
26134 +       exitcall_t *call;
26135 +
26136 +       call = &__uml_exitcall_end;
26137 +       while (--call >= &__uml_exitcall_begin)
26138 +               (*call)();
26139 +}
26140 +
26141 +char *uml_strdup(char *string)
26142 +{
26143 +       char *new;
26144 +
26145 +       new = kmalloc(strlen(string) + 1, GFP_KERNEL);
26146 +       if(new == NULL) return(NULL);
26147 +       strcpy(new, string);
26148 +       return(new);
26149 +}
26150 +
26151 +void *get_init_task(void)
26152 +{
26153 +       return(&init_task_union.task);
26154 +}
26155 +
26156 +int copy_to_user_proc(void *to, void *from, int size)
26157 +{
26158 +       return(copy_to_user(to, from, size));
26159 +}
26160 +
26161 +int copy_from_user_proc(void *to, void *from, int size)
26162 +{
26163 +       return(copy_from_user(to, from, size));
26164 +}
26165 +
26166 +int clear_user_proc(void *buf, int size)
26167 +{
26168 +       return(clear_user(buf, size));
26169 +}
26170 +
26171 +int strlen_user_proc(char *str)
26172 +{
26173 +       return(strlen_user(str));
26174 +}
26175 +
26176 +int smp_sigio_handler(void)
26177 +{
26178 +#ifdef CONFIG_SMP
26179 +       int cpu = current->processor;
26180 +
26181 +       IPI_handler(cpu);
26182 +       if(cpu != 0)
26183 +               return(1);
26184 +#endif
26185 +       return(0);
26186 +}
26187 +
26188 +int um_in_interrupt(void)
26189 +{
26190 +       return(in_interrupt());
26191 +}
26192 +
26193 +int cpu(void)
26194 +{
26195 +        return(current->processor);
26196 +}
26197 +
26198 +int singlestepping(void * t)
26199 +{
26200 +       struct task_struct *task = t ? t : current;
26201 +
26202 +       if ( ! (task->ptrace & PT_DTRACE) )
26203 +               return(0);
26204 +
26205 +       if (task->thread.singlestep_syscall)
26206 +               return(0);
26207 +
26208 +       return 1;
26209 +}
26210 +
26211 +/*
26212 + * Overrides for Emacs so that we follow Linus's tabbing style.
26213 + * Emacs will notice this stuff at the end of the file and automatically
26214 + * adjust the settings for this buffer only.  This must remain at the end
26215 + * of the file.
26216 + * ---------------------------------------------------------------------------
26217 + * Local variables:
26218 + * c-file-style: "linux"
26219 + * End:
26220 + */
26221 Index: linux-2.4.29/arch/um/kernel/ptrace.c
26222 ===================================================================
26223 --- linux-2.4.29.orig/arch/um/kernel/ptrace.c   1970-01-01 03:00:00.000000000 +0300
26224 +++ linux-2.4.29/arch/um/kernel/ptrace.c        2005-05-03 22:28:14.441414784 +0300
26225 @@ -0,0 +1,341 @@
26226 +/* 
26227 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
26228 + * Licensed under the GPL
26229 + */
26230 +
26231 +#include "linux/sched.h"
26232 +#include "linux/mm.h"
26233 +#include "linux/errno.h"
26234 +#include "linux/smp_lock.h"
26235 +#ifdef CONFIG_PROC_MM
26236 +#include "linux/proc_mm.h"
26237 +#endif
26238 +#include "asm/ptrace.h"
26239 +#include "asm/uaccess.h"
26240 +#include "kern_util.h"
26241 +#include "ptrace_user.h"
26242 +
26243 +/*
26244 + * Called by kernel/ptrace.c when detaching..
26245 + */
26246 +void ptrace_disable(struct task_struct *child)
26247 +{ 
26248 +       child->ptrace &= ~PT_DTRACE;
26249 +       child->thread.singlestep_syscall = 0;
26250 +}
26251 +
26252 +extern long do_mmap2(struct task_struct *task, unsigned long addr, 
26253 +                    unsigned long len, unsigned long prot, 
26254 +                    unsigned long flags, unsigned long fd,
26255 +                    unsigned long pgoff);
26256 +
26257 +int sys_ptrace(long request, long pid, long addr, long data)
26258 +{
26259 +       struct task_struct *child;
26260 +       int i, ret;
26261 +
26262 +       lock_kernel();
26263 +       ret = -EPERM;
26264 +       if (request == PTRACE_TRACEME) {
26265 +               /* are we already being traced? */
26266 +               if (current->ptrace & PT_PTRACED)
26267 +                       goto out;
26268 +               /* set the ptrace bit in the process flags. */
26269 +               current->ptrace |= PT_PTRACED;
26270 +               ret = 0;
26271 +               goto out;
26272 +       }
26273 +       ret = -ESRCH;
26274 +       read_lock(&tasklist_lock);
26275 +       child = find_task_by_pid(pid);
26276 +       if (child)
26277 +               get_task_struct(child);
26278 +       read_unlock(&tasklist_lock);
26279 +       if (!child)
26280 +               goto out;
26281 +
26282 +       ret = -EPERM;
26283 +       if (pid == 1)           /* you may not mess with init */
26284 +               goto out_tsk;
26285 +
26286 +       if (request == PTRACE_ATTACH) {
26287 +               ret = ptrace_attach(child);
26288 +               goto out_tsk;
26289 +       }
26290 +
26291 +       ret = ptrace_check_attach(child, request == PTRACE_KILL);
26292 +       if (ret < 0)
26293 +               goto out_tsk;
26294 +
26295 +       switch (request) {
26296 +               /* when I and D space are separate, these will need to be fixed. */
26297 +       case PTRACE_PEEKTEXT: /* read word at location addr. */ 
26298 +       case PTRACE_PEEKDATA: {
26299 +               unsigned long tmp;
26300 +               int copied;
26301 +
26302 +               ret = -EIO;
26303 +               copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
26304 +               if (copied != sizeof(tmp))
26305 +                       break;
26306 +               ret = put_user(tmp,(unsigned long *) data);
26307 +               break;
26308 +       }
26309 +
26310 +       /* read the word at location addr in the USER area. */
26311 +       case PTRACE_PEEKUSR: {
26312 +               unsigned long tmp;
26313 +
26314 +               ret = -EIO;
26315 +               if ((addr & 3) || addr < 0) 
26316 +                       break;
26317 +
26318 +               tmp = 0;  /* Default return condition */
26319 +               if(addr < FRAME_SIZE_OFFSET){
26320 +                       tmp = getreg(child, addr);
26321 +               }
26322 +               else if((addr >= offsetof(struct user, u_debugreg[0])) &&
26323 +                       (addr <= offsetof(struct user, u_debugreg[7]))){
26324 +                       addr -= offsetof(struct user, u_debugreg[0]);
26325 +                       addr = addr >> 2;
26326 +                       tmp = child->thread.arch.debugregs[addr];
26327 +               }
26328 +               ret = put_user(tmp, (unsigned long *) data);
26329 +               break;
26330 +       }
26331 +
26332 +       /* when I and D space are separate, this will have to be fixed. */
26333 +       case PTRACE_POKETEXT: /* write the word at location addr. */
26334 +       case PTRACE_POKEDATA:
26335 +               ret = -EIO;
26336 +               if (access_process_vm(child, addr, &data, sizeof(data), 
26337 +                                     1) != sizeof(data))
26338 +                       break;
26339 +               ret = 0;
26340 +               break;
26341 +
26342 +       case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
26343 +               ret = -EIO;
26344 +               if ((addr & 3) || addr < 0)
26345 +                       break;
26346 +
26347 +               if (addr < FRAME_SIZE_OFFSET) {
26348 +                       ret = putreg(child, addr, data);
26349 +                       break;
26350 +               }
26351 +               else if((addr >= offsetof(struct user, u_debugreg[0])) &&
26352 +                       (addr <= offsetof(struct user, u_debugreg[7]))){
26353 +                         addr -= offsetof(struct user, u_debugreg[0]);
26354 +                         addr = addr >> 2;
26355 +                         if((addr == 4) || (addr == 5)) break;
26356 +                         child->thread.arch.debugregs[addr] = data;
26357 +                         ret = 0;
26358 +               }
26359 +
26360 +               break;
26361 +
26362 +       case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
26363 +       case PTRACE_CONT: { /* restart after signal. */
26364 +               ret = -EIO;
26365 +               if ((unsigned long) data > _NSIG)
26366 +                       break;
26367 +
26368 +               child->ptrace &= ~PT_DTRACE;
26369 +               child->thread.singlestep_syscall = 0;
26370 +
26371 +               if (request == PTRACE_SYSCALL)
26372 +                       child->ptrace |= PT_TRACESYS;
26373 +               else
26374 +                       child->ptrace &= ~PT_TRACESYS;
26375 +               child->exit_code = data;
26376 +               wake_up_process(child);
26377 +               ret = 0;
26378 +               break;
26379 +       }
26380 +
26381 +/*
26382 + * make the child exit.  Best I can do is send it a sigkill. 
26383 + * perhaps it should be put in the status that it wants to 
26384 + * exit.
26385 + */
26386 +       case PTRACE_KILL: {
26387 +               ret = 0;
26388 +               if (child->state == TASK_ZOMBIE)        /* already dead */
26389 +                       break;
26390 +
26391 +               child->ptrace &= ~PT_DTRACE;
26392 +               child->thread.singlestep_syscall = 0;
26393 +               child->exit_code = SIGKILL;
26394 +               wake_up_process(child);
26395 +               break;
26396 +       }
26397 +
26398 +       case PTRACE_SINGLESTEP: {  /* set the trap flag. */
26399 +               ret = -EIO;
26400 +               if ((unsigned long) data > _NSIG)
26401 +                       break;
26402 +               child->ptrace &= ~PT_TRACESYS;
26403 +               child->ptrace |= PT_DTRACE;
26404 +               child->thread.singlestep_syscall = 0;
26405 +               child->exit_code = data;
26406 +               /* give it a chance to run. */
26407 +               wake_up_process(child);
26408 +               ret = 0;
26409 +               break;
26410 +       }
26411 +
26412 +       case PTRACE_DETACH:
26413 +               /* detach a process that was attached. */
26414 +               ret = ptrace_detach(child, data);
26415 +               break;
26416 +
26417 +#ifdef PTRACE_GETREGS
26418 +       case PTRACE_GETREGS: { /* Get all gp regs from the child. */
26419 +               if (!access_ok(VERIFY_WRITE, (unsigned long *)data, 
26420 +                              FRAME_SIZE_OFFSET)) {
26421 +                       ret = -EIO;
26422 +                       break;
26423 +               }
26424 +               for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
26425 +                       __put_user(getreg(child, i), (unsigned long *) data);
26426 +                       data += sizeof(long);
26427 +               }
26428 +               ret = 0;
26429 +               break;
26430 +       }
26431 +#endif
26432 +#ifdef PTRACE_SETREGS
26433 +       case PTRACE_SETREGS: { /* Set all gp regs in the child. */
26434 +               unsigned long tmp = 0;
26435 +               if (!access_ok(VERIFY_READ, (unsigned *)data, 
26436 +                              FRAME_SIZE_OFFSET)) {
26437 +                       ret = -EIO;
26438 +                       break;
26439 +               }
26440 +               for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
26441 +                       __get_user(tmp, (unsigned long *) data);
26442 +                       putreg(child, i, tmp);
26443 +                       data += sizeof(long);
26444 +               }
26445 +               ret = 0;
26446 +               break;
26447 +       }
26448 +#endif
26449 +#ifdef PTRACE_GETFPREGS
26450 +       case PTRACE_GETFPREGS: /* Get the child FPU state. */
26451 +               ret = get_fpregs(data, child);
26452 +               break;
26453 +#endif
26454 +#ifdef PTRACE_SETFPREGS
26455 +       case PTRACE_SETFPREGS: /* Set the child FPU state. */
26456 +               ret = set_fpregs(data, child);
26457 +               break;
26458 +#endif
26459 +#ifdef PTRACE_GETFPXREGS
26460 +       case PTRACE_GETFPXREGS: /* Get the child FPU state. */
26461 +               ret = get_fpxregs(data, child);
26462 +               break;
26463 +#endif
26464 +#ifdef PTRACE_SETFPXREGS
26465 +       case PTRACE_SETFPXREGS: /* Set the child FPU state. */
26466 +               ret = set_fpxregs(data, child);
26467 +               break;
26468 +#endif
26469 +       case PTRACE_FAULTINFO: {
26470 +               struct ptrace_faultinfo fault;
26471 +
26472 +               fault = ((struct ptrace_faultinfo) 
26473 +                       { .is_write     = child->thread.err,
26474 +                         .addr         = child->thread.cr2 });
26475 +               ret = copy_to_user((unsigned long *) data, &fault, 
26476 +                                  sizeof(fault));
26477 +               if(ret)
26478 +                       break;
26479 +               break;
26480 +       }
26481 +       case PTRACE_SIGPENDING:
26482 +               ret = copy_to_user((unsigned long *) data, 
26483 +                                  &child->pending.signal,
26484 +                                  sizeof(child->pending.signal));
26485 +               break;
26486 +
26487 +       case PTRACE_LDT: {
26488 +               struct ptrace_ldt ldt;
26489 +
26490 +               if(copy_from_user(&ldt, (unsigned long *) data, 
26491 +                                 sizeof(ldt))){
26492 +                       ret = -EIO;
26493 +                       break;
26494 +               }
26495 +
26496 +               /* This one is confusing, so just punt and return -EIO for 
26497 +                * now
26498 +                */
26499 +               ret = -EIO;
26500 +               break;
26501 +       }
26502 +#ifdef CONFIG_PROC_MM
26503 +       case PTRACE_SWITCH_MM: {
26504 +               struct mm_struct *old = child->mm;
26505 +               struct mm_struct *new = proc_mm_get_mm(data);
26506 +
26507 +               if(IS_ERR(new)){
26508 +                       ret = PTR_ERR(new);
26509 +                       break;
26510 +               }
26511 +
26512 +               atomic_inc(&new->mm_users);
26513 +               child->mm = new;
26514 +               child->active_mm = new;
26515 +               mmput(old);
26516 +               ret = 0;
26517 +               break;
26518 +       }
26519 +#endif
26520 +       default:
26521 +               ret = -EIO;
26522 +               break;
26523 +       }
26524 + out_tsk:
26525 +       free_task_struct(child);
26526 + out:
26527 +       unlock_kernel();
26528 +       return ret;
26529 +}
26530 +
26531 +void syscall_trace(void)
26532 +{
26533 +       int is_singlestep = (current->ptrace & PT_DTRACE);
26534 +
26535 +       if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
26536 +           != (PT_PTRACED|PT_TRACESYS) && !is_singlestep)
26537 +               return;
26538 +       current->exit_code = SIGTRAP;
26539 +       current->state = TASK_STOPPED;
26540 +       notify_parent(current, SIGCHLD);
26541 +
26542 +       schedule();
26543 +       /*
26544 +        * this isn't the same as continuing with a signal, but it will do
26545 +        * for normal use.  strace only continues with a signal if the
26546 +        * stopping signal is not SIGTRAP.  -brl
26547 +        */
26548 +       if (current->exit_code) {
26549 +               send_sig(current->exit_code, current, 1);
26550 +               current->exit_code = 0;
26551 +       }
26552 +
26553 +       if(is_syscall(PT_REGS_IP(&current->thread.regs)))
26554 +               current->thread.singlestep_syscall = 1;
26555 +}
26556 +
26557 +/*
26558 + * Overrides for Emacs so that we follow Linus's tabbing style.
26559 + * Emacs will notice this stuff at the end of the file and automatically
26560 + * adjust the settings for this buffer only.  This must remain at the end
26561 + * of the file.
26562 + * ---------------------------------------------------------------------------
26563 + * Local variables:
26564 + * c-file-style: "linux"
26565 + * End:
26566 + */
26567 Index: linux-2.4.29/arch/um/kernel/reboot.c
26568 ===================================================================
26569 --- linux-2.4.29.orig/arch/um/kernel/reboot.c   1970-01-01 03:00:00.000000000 +0300
26570 +++ linux-2.4.29/arch/um/kernel/reboot.c        2005-05-03 22:28:14.441414784 +0300
26571 @@ -0,0 +1,73 @@
26572 +/* 
26573 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
26574 + * Licensed under the GPL
26575 + */
26576 +
26577 +#include "linux/sched.h"
26578 +#include "user_util.h"
26579 +#include "kern_util.h"
26580 +#include "kern.h"
26581 +#include "os.h"
26582 +#include "mode.h"
26583 +#include "choose-mode.h"
26584 +
26585 +#ifdef CONFIG_SMP
26586 +static void kill_idlers(int me)
26587 +{
26588 +#ifdef CONFIG_MODE_TT
26589 +       struct task_struct *p;
26590 +       int i;
26591 +
26592 +       for(i = 0; i < sizeof(init_tasks)/sizeof(init_tasks[0]); i++){
26593 +               p = init_tasks[i];
26594 +               if((p != NULL) && (p->thread.mode.tt.extern_pid != me) &&
26595 +                  (p->thread.mode.tt.extern_pid != -1))
26596 +                       os_kill_process(p->thread.mode.tt.extern_pid, 0);
26597 +       }
26598 +#endif
26599 +}
26600 +#endif
26601 +
26602 +static void kill_off_processes(void)
26603 +{
26604 +       CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas());
26605 +#ifdef CONFIG_SMP
26606 +       kill_idlers(os_getpid());
26607 +#endif
26608 +}
26609 +
26610 +void uml_cleanup(void)
26611 +{
26612 +       kill_off_processes();
26613 +       do_uml_exitcalls();
26614 +}
26615 +
26616 +void machine_restart(char * __unused)
26617 +{
26618 +       do_uml_exitcalls();
26619 +       kill_off_processes();
26620 +       CHOOSE_MODE(reboot_tt(), reboot_skas());
26621 +}
26622 +
26623 +void machine_power_off(void)
26624 +{
26625 +       do_uml_exitcalls();
26626 +       kill_off_processes();
26627 +       CHOOSE_MODE(halt_tt(), halt_skas());
26628 +}
26629 +
26630 +void machine_halt(void)
26631 +{
26632 +       machine_power_off();
26633 +}
26634 +
26635 +/*
26636 + * Overrides for Emacs so that we follow Linus's tabbing style.
26637 + * Emacs will notice this stuff at the end of the file and automatically
26638 + * adjust the settings for this buffer only.  This must remain at the end
26639 + * of the file.
26640 + * ---------------------------------------------------------------------------
26641 + * Local variables:
26642 + * c-file-style: "linux"
26643 + * End:
26644 + */
26645 Index: linux-2.4.29/arch/um/kernel/resource.c
26646 ===================================================================
26647 --- linux-2.4.29.orig/arch/um/kernel/resource.c 1970-01-01 03:00:00.000000000 +0300
26648 +++ linux-2.4.29/arch/um/kernel/resource.c      2005-05-03 22:28:14.442414632 +0300
26649 @@ -0,0 +1,23 @@
26650 +/* 
26651 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
26652 + * Licensed under the GPL
26653 + */
26654 +
26655 +#include "linux/pci.h"
26656 +
26657 +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
26658 +                            unsigned long start, unsigned long size)
26659 +{
26660 +       return start;
26661 +}
26662 +
26663 +/*
26664 + * Overrides for Emacs so that we follow Linus's tabbing style.
26665 + * Emacs will notice this stuff at the end of the file and automatically
26666 + * adjust the settings for this buffer only.  This must remain at the end
26667 + * of the file.
26668 + * ---------------------------------------------------------------------------
26669 + * Local variables:
26670 + * c-file-style: "linux"
26671 + * End:
26672 + */
26673 Index: linux-2.4.29/arch/um/kernel/sigio_kern.c
26674 ===================================================================
26675 --- linux-2.4.29.orig/arch/um/kernel/sigio_kern.c       1970-01-01 03:00:00.000000000 +0300
26676 +++ linux-2.4.29/arch/um/kernel/sigio_kern.c    2005-05-03 22:28:14.443414480 +0300
26677 @@ -0,0 +1,61 @@
26678 +/* 
26679 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
26680 + * Licensed under the GPL
26681 + */
26682 +
26683 +#include "linux/kernel.h"
26684 +#include "linux/list.h"
26685 +#include "linux/slab.h"
26686 +#include "asm/irq.h"
26687 +#include "init.h"
26688 +#include "sigio.h"
26689 +#include "irq_user.h"
26690 +#include "irq_kern.h"
26691 +
26692 +/* Protected by sigio_lock() called from write_sigio_workaround */
26693 +static int sigio_irq_fd = -1;
26694 +
26695 +static void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
26696 +{
26697 +       read_sigio_fd(sigio_irq_fd);
26698 +       reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
26699 +}
26700 +
26701 +int write_sigio_irq(int fd)
26702 +{
26703 +       int err;
26704 +
26705 +       err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
26706 +                            SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio", 
26707 +                            NULL);
26708 +       if(err){
26709 +               printk("write_sigio_irq : um_request_irq failed, err = %d\n",
26710 +                      err);
26711 +               return(-1);
26712 +       }
26713 +       sigio_irq_fd = fd;
26714 +       return(0);
26715 +}
26716 +
26717 +static spinlock_t sigio_spinlock = SPIN_LOCK_UNLOCKED;
26718 +
26719 +void sigio_lock(void)
26720 +{
26721 +       spin_lock(&sigio_spinlock);
26722 +}
26723 +
26724 +void sigio_unlock(void)
26725 +{
26726 +       spin_unlock(&sigio_spinlock);
26727 +}
26728 +
26729 +/*
26730 + * Overrides for Emacs so that we follow Linus's tabbing style.
26731 + * Emacs will notice this stuff at the end of the file and automatically
26732 + * adjust the settings for this buffer only.  This must remain at the end
26733 + * of the file.
26734 + * ---------------------------------------------------------------------------
26735 + * Local variables:
26736 + * c-file-style: "linux"
26737 + * End:
26738 + */
26739 Index: linux-2.4.29/arch/um/kernel/sigio_user.c
26740 ===================================================================
26741 --- linux-2.4.29.orig/arch/um/kernel/sigio_user.c       1970-01-01 03:00:00.000000000 +0300
26742 +++ linux-2.4.29/arch/um/kernel/sigio_user.c    2005-05-03 22:28:14.445414176 +0300
26743 @@ -0,0 +1,436 @@
26744 +/* 
26745 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
26746 + * Licensed under the GPL
26747 + */
26748 +
26749 +#include <unistd.h>
26750 +#include <stdlib.h>
26751 +#include <termios.h>
26752 +#include <pty.h>
26753 +#include <signal.h>
26754 +#include <errno.h>
26755 +#include <string.h>
26756 +#include <sched.h>
26757 +#include <sys/socket.h>
26758 +#include <sys/poll.h>
26759 +#include "init.h"
26760 +#include "user.h"
26761 +#include "kern_util.h"
26762 +#include "user_util.h"
26763 +#include "sigio.h"
26764 +#include "helper.h"
26765 +#include "os.h"
26766 +
26767 +/* Changed during early boot */
26768 +int pty_output_sigio = 0;
26769 +int pty_close_sigio = 0;
26770 +
26771 +/* Used as a flag during SIGIO testing early in boot */
26772 +static volatile int got_sigio = 0;
26773 +
26774 +void __init handler(int sig)
26775 +{
26776 +       got_sigio = 1;
26777 +}
26778 +
26779 +struct openpty_arg {
26780 +       int master;
26781 +       int slave;
26782 +       int err;
26783 +};
26784 +
26785 +static void openpty_cb(void *arg)
26786 +{
26787 +       struct openpty_arg *info = arg;
26788 +
26789 +       info->err = 0;
26790 +       if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
26791 +               info->err = -errno;
26792 +}
26793 +
26794 +void __init check_one_sigio(void (*proc)(int, int))
26795 +{
26796 +       struct sigaction old, new;
26797 +       struct openpty_arg pty = { .master = -1, .slave = -1 };
26798 +       int master, slave, err;
26799 +
26800 +       initial_thread_cb(openpty_cb, &pty);
26801 +       if(pty.err){
26802 +               printk("openpty failed, errno = %d\n", -pty.err);
26803 +               return;
26804 +       }
26805 +
26806 +       master = pty.master;
26807 +       slave = pty.slave;
26808 +
26809 +       if((master == -1) || (slave == -1)){
26810 +               printk("openpty failed to allocate a pty\n");
26811 +               return;
26812 +       }
26813 +
26814 +       /* Not now, but complain so we now where we failed. */
26815 +       err = raw(master);
26816 +       if (err < 0)
26817 +               panic("check_sigio : __raw failed, errno = %d\n", -err);
26818 +
26819 +       err = os_sigio_async(master, slave);
26820 +       if(err < 0)
26821 +               panic("tty_fds : sigio_async failed, err = %d\n", -err);
26822 +
26823 +       if(sigaction(SIGIO, NULL, &old) < 0)
26824 +               panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
26825 +       new = old;
26826 +       new.sa_handler = handler;
26827 +       if(sigaction(SIGIO, &new, NULL) < 0)
26828 +               panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
26829 +
26830 +       got_sigio = 0;
26831 +       (*proc)(master, slave);
26832 +               
26833 +       os_close_file(master);
26834 +       os_close_file(slave);
26835 +
26836 +       if(sigaction(SIGIO, &old, NULL) < 0)
26837 +               panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
26838 +}
26839 +
26840 +static void tty_output(int master, int slave)
26841 +{
26842 +       int n;
26843 +       char buf[512];
26844 +
26845 +       printk("Checking that host ptys support output SIGIO...");
26846 +
26847 +       memset(buf, 0, sizeof(buf));
26848 +
26849 +       while(os_write_file(master, buf, sizeof(buf)) > 0) ;
26850 +       if(errno != EAGAIN)
26851 +               panic("check_sigio : write failed, errno = %d\n", errno);
26852 +       while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
26853 +
26854 +       if(got_sigio){
26855 +               printk("Yes\n");
26856 +               pty_output_sigio = 1;
26857 +       }
26858 +       else if(n == -EAGAIN) printk("No, enabling workaround\n");
26859 +       else panic("check_sigio : read failed, err = %d\n", n);
26860 +}
26861 +
26862 +static void tty_close(int master, int slave)
26863 +{
26864 +       printk("Checking that host ptys support SIGIO on close...");
26865 +
26866 +       os_close_file(slave);
26867 +       if(got_sigio){
26868 +               printk("Yes\n");
26869 +               pty_close_sigio = 1;
26870 +       }
26871 +       else printk("No, enabling workaround\n");
26872 +}
26873 +
26874 +void __init check_sigio(void)
26875 +{
26876 +       if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
26877 +          (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
26878 +               printk("No pseudo-terminals available - skipping pty SIGIO "
26879 +                      "check\n");
26880 +               return;
26881 +       }
26882 +       check_one_sigio(tty_output);
26883 +       check_one_sigio(tty_close);
26884 +}
26885 +
26886 +/* Protected by sigio_lock(), also used by sigio_cleanup, which is an 
26887 + * exitcall.
26888 + */
26889 +static int write_sigio_pid = -1;
26890 +
26891 +/* These arrays are initialized before the sigio thread is started, and
26892 + * the descriptors closed after it is killed.  So, it can't see them change.
26893 + * On the UML side, they are changed under the sigio_lock.
26894 + */
26895 +static int write_sigio_fds[2] = { -1, -1 };
26896 +static int sigio_private[2] = { -1, -1 };
26897 +
26898 +struct pollfds {
26899 +       struct pollfd *poll;
26900 +       int size;
26901 +       int used;
26902 +};
26903 +
26904 +/* Protected by sigio_lock().  Used by the sigio thread, but the UML thread
26905 + * synchronizes with it.
26906 + */
26907 +struct pollfds current_poll = {
26908 +       .poll           = NULL,
26909 +       .size           = 0,
26910 +       .used           = 0
26911 +};
26912 +
26913 +struct pollfds next_poll = {
26914 +       .poll           = NULL,
26915 +       .size           = 0,
26916 +       .used           = 0
26917 +};
26918 +
26919 +static int write_sigio_thread(void *unused)
26920 +{
26921 +       struct pollfds *fds, tmp;
26922 +       struct pollfd *p;
26923 +       int i, n, respond_fd;
26924 +       char c;
26925 +
26926 +       fds = &current_poll;
26927 +       while(1){
26928 +               n = poll(fds->poll, fds->used, -1);
26929 +               if(n < 0){
26930 +                       if(errno == EINTR) continue;
26931 +                       printk("write_sigio_thread : poll returned %d, "
26932 +                              "errno = %d\n", n, errno);
26933 +               }
26934 +               for(i = 0; i < fds->used; i++){
26935 +                       p = &fds->poll[i];
26936 +                       if(p->revents == 0) continue;
26937 +                       if(p->fd == sigio_private[1]){
26938 +                               n = os_read_file(sigio_private[1], &c, sizeof(c));
26939 +                               if(n != sizeof(c))
26940 +                                       printk("write_sigio_thread : "
26941 +                                              "read failed, err = %d\n", -n);
26942 +                               tmp = current_poll;
26943 +                               current_poll = next_poll;
26944 +                               next_poll = tmp;
26945 +                               respond_fd = sigio_private[1];
26946 +                       }
26947 +                       else {
26948 +                               respond_fd = write_sigio_fds[1];
26949 +                               fds->used--;
26950 +                               memmove(&fds->poll[i], &fds->poll[i + 1],
26951 +                                       (fds->used - i) * sizeof(*fds->poll));
26952 +                       }
26953 +
26954 +                       n = os_write_file(respond_fd, &c, sizeof(c));
26955 +                       if(n != sizeof(c))
26956 +                               printk("write_sigio_thread : write failed, "
26957 +                                      "err = %d\n", -n);
26958 +               }
26959 +       }
26960 +}
26961 +
26962 +static int need_poll(int n)
26963 +{
26964 +       if(n <= next_poll.size){
26965 +               next_poll.used = n;
26966 +               return(0);
26967 +       }
26968 +       if(next_poll.poll != NULL) kfree(next_poll.poll);
26969 +       next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
26970 +       if(next_poll.poll == NULL){
26971 +               printk("need_poll : failed to allocate new pollfds\n");
26972 +               next_poll.size = 0;
26973 +               next_poll.used = 0;
26974 +               return(-1);
26975 +       }
26976 +       next_poll.size = n;
26977 +       next_poll.used = n;
26978 +       return(0);
26979 +}
26980 +
26981 +static void update_thread(void)
26982 +{
26983 +       unsigned long flags;
26984 +       int n;
26985 +       char c;
26986 +
26987 +       flags = set_signals(0);
26988 +       n = os_write_file(sigio_private[0], &c, sizeof(c));
26989 +       if(n != sizeof(c)){
26990 +               printk("update_thread : write failed, err = %d\n", -n);
26991 +               goto fail;
26992 +       }
26993 +
26994 +       n = os_read_file(sigio_private[0], &c, sizeof(c));
26995 +       if(n != sizeof(c)){
26996 +               printk("update_thread : read failed, err = %d\n", -n);
26997 +               goto fail;
26998 +       }
26999 +
27000 +       set_signals(flags);
27001 +       return;
27002 + fail:
27003 +       sigio_lock();
27004 +       if(write_sigio_pid != -1) 
27005 +               os_kill_process(write_sigio_pid, 1);
27006 +       write_sigio_pid = -1;
27007 +       os_close_file(sigio_private[0]);
27008 +       os_close_file(sigio_private[1]);        
27009 +       os_close_file(write_sigio_fds[0]);
27010 +       os_close_file(write_sigio_fds[1]);
27011 +       sigio_unlock();
27012 +       set_signals(flags);
27013 +}
27014 +
27015 +int add_sigio_fd(int fd, int read)
27016 +{
27017 +       int err = 0, i, n, events;
27018 +
27019 +       sigio_lock();
27020 +       for(i = 0; i < current_poll.used; i++){
27021 +               if(current_poll.poll[i].fd == fd) 
27022 +                       goto out;
27023 +       }
27024 +
27025 +       n = current_poll.used + 1;
27026 +       err = need_poll(n);
27027 +       if(err) 
27028 +               goto out;
27029 +
27030 +       for(i = 0; i < current_poll.used; i++)
27031 +               next_poll.poll[i] = current_poll.poll[i];
27032 +
27033 +       if(read) events = POLLIN;
27034 +       else events = POLLOUT;
27035 +
27036 +       next_poll.poll[n - 1] = ((struct pollfd) { .fd          = fd,
27037 +                                                  .events      = events,
27038 +                                                  .revents     = 0 });
27039 +       update_thread();
27040 + out:
27041 +       sigio_unlock();
27042 +       return(err);
27043 +}
27044 +
27045 +int ignore_sigio_fd(int fd)
27046 +{
27047 +       struct pollfd *p;
27048 +       int err = 0, i, n = 0;
27049 +
27050 +       sigio_lock();
27051 +       for(i = 0; i < current_poll.used; i++){
27052 +               if(current_poll.poll[i].fd == fd) break;
27053 +       }
27054 +       if(i == current_poll.used)
27055 +               goto out;
27056 +       
27057 +       err = need_poll(current_poll.used - 1);
27058 +       if(err)
27059 +               goto out;
27060 +
27061 +       for(i = 0; i < current_poll.used; i++){
27062 +               p = &current_poll.poll[i];
27063 +               if(p->fd != fd) next_poll.poll[n++] = current_poll.poll[i];
27064 +       }
27065 +       if(n == i){
27066 +               printk("ignore_sigio_fd : fd %d not found\n", fd);
27067 +               err = -1;
27068 +               goto out;
27069 +       }
27070 +
27071 +       update_thread();
27072 + out:
27073 +       sigio_unlock();
27074 +       return(err);
27075 +}
27076 +
27077 +static int setup_initial_poll(int fd)
27078 +{
27079 +       struct pollfd *p;
27080 +
27081 +       p = um_kmalloc(sizeof(struct pollfd));
27082 +       if(p == NULL){
27083 +               printk("setup_initial_poll : failed to allocate poll\n");
27084 +               return(-1);
27085 +       }
27086 +       *p = ((struct pollfd) { .fd     = fd,
27087 +                               .events         = POLLIN,
27088 +                               .revents        = 0 });
27089 +       current_poll = ((struct pollfds) { .poll        = p,
27090 +                                          .used        = 1,
27091 +                                          .size        = 1 });
27092 +       return(0);
27093 +}
27094 +
27095 +void write_sigio_workaround(void)
27096 +{
27097 +       unsigned long stack;
27098 +       int err;
27099 +
27100 +       sigio_lock();
27101 +       if(write_sigio_pid != -1)
27102 +               goto out;
27103 +
27104 +       err = os_pipe(write_sigio_fds, 1, 1);
27105 +       if(err < 0){
27106 +               printk("write_sigio_workaround - os_pipe 1 failed, "
27107 +                      "err = %d\n", -err);
27108 +               goto out;
27109 +       }
27110 +       err = os_pipe(sigio_private, 1, 1);
27111 +       if(err < 0){
27112 +               printk("write_sigio_workaround - os_pipe 2 failed, "
27113 +                      "err = %d\n", -err);
27114 +               goto out_close1;
27115 +       }
27116 +       if(setup_initial_poll(sigio_private[1]))
27117 +               goto out_close2;
27118 +
27119 +       write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, 
27120 +                                           CLONE_FILES | CLONE_VM, &stack, 0);
27121 +
27122 +       if(write_sigio_pid < 0) goto out_close2;
27123 +
27124 +       if(write_sigio_irq(write_sigio_fds[0])) 
27125 +               goto out_kill;
27126 +
27127 + out:
27128 +       sigio_unlock();
27129 +       return;
27130 +
27131 + out_kill:
27132 +       os_kill_process(write_sigio_pid, 1);
27133 +       write_sigio_pid = -1;
27134 + out_close2:
27135 +       os_close_file(sigio_private[0]);
27136 +       os_close_file(sigio_private[1]);        
27137 + out_close1:
27138 +       os_close_file(write_sigio_fds[0]);
27139 +       os_close_file(write_sigio_fds[1]);
27140 +       sigio_unlock();
27141 +}
27142 +
27143 +int read_sigio_fd(int fd)
27144 +{
27145 +       int n;
27146 +       char c;
27147 +
27148 +       n = os_read_file(fd, &c, sizeof(c));
27149 +       if(n != sizeof(c)){
27150 +               if(n < 0) {
27151 +                       printk("read_sigio_fd - read failed, err = %d\n", -n);
27152 +                       return(n);
27153 +               } 
27154 +               else { 
27155 +                       printk("read_sigio_fd - short read, bytes = %d\n", n);
27156 +                       return(-EIO);
27157 +               }
27158 +       }
27159 +       return(n);
27160 +}
27161 +
27162 +static void sigio_cleanup(void)
27163 +{
27164 +       if(write_sigio_pid != -1)
27165 +               os_kill_process(write_sigio_pid, 1);
27166 +}
27167 +
27168 +__uml_exitcall(sigio_cleanup);
27169 +
27170 +/*
27171 + * Overrides for Emacs so that we follow Linus's tabbing style.
27172 + * Emacs will notice this stuff at the end of the file and automatically
27173 + * adjust the settings for this buffer only.  This must remain at the end
27174 + * of the file.
27175 + * ---------------------------------------------------------------------------
27176 + * Local variables:
27177 + * c-file-style: "linux"
27178 + * End:
27179 + */
27180 Index: linux-2.4.29/arch/um/kernel/signal_kern.c
27181 ===================================================================
27182 --- linux-2.4.29.orig/arch/um/kernel/signal_kern.c      1970-01-01 03:00:00.000000000 +0300
27183 +++ linux-2.4.29/arch/um/kernel/signal_kern.c   2005-05-03 22:28:14.447413872 +0300
27184 @@ -0,0 +1,368 @@
27185 +/* 
27186 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
27187 + * Licensed under the GPL
27188 + */
27189 +
27190 +#include "linux/config.h"
27191 +#include "linux/stddef.h"
27192 +#include "linux/sys.h"
27193 +#include "linux/sched.h"
27194 +#include "linux/wait.h"
27195 +#include "linux/kernel.h"
27196 +#include "linux/smp_lock.h"
27197 +#include "linux/module.h"
27198 +#include "linux/slab.h"
27199 +#include "asm/signal.h"
27200 +#include "asm/uaccess.h"
27201 +#include "asm/ucontext.h"
27202 +#include "user_util.h"
27203 +#include "kern_util.h"
27204 +#include "signal_kern.h"
27205 +#include "signal_user.h"
27206 +#include "kern.h"
27207 +#include "frame_kern.h"
27208 +#include "sigcontext.h"
27209 +#include "mode.h"
27210 +
27211 +EXPORT_SYMBOL(block_signals);
27212 +EXPORT_SYMBOL(unblock_signals);
27213 +
27214 +static void force_segv(int sig)
27215 +{
27216 +       if(sig == SIGSEGV){
27217 +               struct k_sigaction *ka;
27218 +
27219 +               ka = &current->sig->action[SIGSEGV - 1];
27220 +               ka->sa.sa_handler = SIG_DFL;
27221 +       }
27222 +       force_sig(SIGSEGV, current);
27223 +}
27224 +
27225 +#define _S(nr) (1<<((nr)-1))
27226 +
27227 +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
27228 +
27229 +/*
27230 + * OK, we're invoking a handler
27231 + */    
27232 +static void handle_signal(struct pt_regs *regs, unsigned long signr, 
27233 +                         struct k_sigaction *ka, siginfo_t *info, 
27234 +                         sigset_t *oldset, int error)
27235 +{
27236 +        __sighandler_t handler;
27237 +       void (*restorer)(void);
27238 +       unsigned long sp;
27239 +       sigset_t save;
27240 +       int err, ret;
27241 +
27242 +       err = PT_REGS_SYSCALL_RET(&current->thread.regs);
27243 +       ret = 0;
27244 +       switch(err){
27245 +       case -ERESTARTNOHAND:
27246 +               ret = -EINTR;
27247 +               break;
27248 +
27249 +       case -ERESTARTSYS:
27250 +               if (!(ka->sa.sa_flags & SA_RESTART)) {
27251 +                       ret = -EINTR;
27252 +                       break;
27253 +               }
27254 +               /* fallthrough */
27255 +       case -ERESTARTNOINTR:
27256 +               PT_REGS_RESTART_SYSCALL(regs);
27257 +               PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
27258 +
27259 +               /* This is because of the UM_SET_SYSCALL_RETURN and the fact
27260 +                * that on i386 the system call number and return value are
27261 +                * in the same register.  When the system call restarts, %eax
27262 +                * had better have the system call number in it.  Since the
27263 +                * return value doesn't matter (except that it shouldn't be
27264 +                * -ERESTART*), we'll stick the system call number there.
27265 +                */
27266 +               ret = PT_REGS_SYSCALL_NR(regs);
27267 +               break;
27268 +       }
27269 +
27270 +       handler = ka->sa.sa_handler;
27271 +       save = *oldset;
27272 +
27273 +       if (ka->sa.sa_flags & SA_ONESHOT)
27274 +               ka->sa.sa_handler = SIG_DFL;
27275 +
27276 +       if (!(ka->sa.sa_flags & SA_NODEFER)) {
27277 +               spin_lock_irq(&current->sigmask_lock);
27278 +               sigorsets(&current->blocked, &current->blocked, 
27279 +                         &ka->sa.sa_mask);
27280 +               sigaddset(&current->blocked, signr);
27281 +               recalc_sigpending(current);
27282 +               spin_unlock_irq(&current->sigmask_lock);
27283 +       }
27284 +
27285 +       sp = PT_REGS_SP(regs);
27286 +
27287 +       if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
27288 +               sp = current->sas_ss_sp + current->sas_ss_size;
27289 +       
27290 +       if(error != 0) 
27291 +               PT_REGS_SET_SYSCALL_RETURN(regs, ret);
27292 +
27293 +       if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer;
27294 +       else restorer = NULL;
27295 +
27296 +       if(ka->sa.sa_flags & SA_SIGINFO)
27297 +               err = setup_signal_stack_si(sp, signr, (unsigned long) handler,
27298 +                                           restorer, regs, info, &save);
27299 +       else
27300 +               err = setup_signal_stack_sc(sp, signr, (unsigned long) handler,
27301 +                                           restorer, regs, &save);
27302 +       if(err)
27303 +               force_segv(signr);
27304 +}
27305 +
27306 +/*
27307 + * Note that 'init' is a special process: it doesn't get signals it doesn't
27308 + * want to handle. Thus you cannot kill init even with a SIGKILL even by
27309 + * mistake.
27310 + */
27311 +
27312 +static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error)
27313 +{
27314 +       siginfo_t info;
27315 +       struct k_sigaction *ka;
27316 +
27317 +       if (!oldset)
27318 +               oldset = &current->blocked;
27319 +
27320 +       for (;;) {
27321 +               unsigned long signr;
27322 +
27323 +               spin_lock_irq(&current->sigmask_lock);
27324 +               signr = dequeue_signal(&current->blocked, &info);
27325 +               spin_unlock_irq(&current->sigmask_lock);
27326 +
27327 +               if (!signr)
27328 +                       break;
27329 +
27330 +               if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
27331 +                       /* Let the debugger run.  */
27332 +                       current->exit_code = signr;
27333 +                       current->state = TASK_STOPPED;
27334 +                       notify_parent(current, SIGCHLD);
27335 +                       schedule();
27336 +
27337 +                       /* We're back.  Did the debugger cancel the sig?  */
27338 +                       signr = current->exit_code;
27339 +                       if (!signr)
27340 +                               continue;
27341 +                       current->exit_code = 0;
27342 +
27343 +                       /* The debugger continued.  Ignore SIGSTOP.  */
27344 +                       if (signr == SIGSTOP)
27345 +                               continue;
27346 +
27347 +                       /* Update the siginfo structure.  Is this good?  */
27348 +                       if (signr != info.si_signo) {
27349 +                               info.si_signo = signr;
27350 +                               info.si_errno = 0;
27351 +                               info.si_code = SI_USER;
27352 +                               info.si_pid = current->p_pptr->pid;
27353 +                               info.si_uid = current->p_pptr->uid;
27354 +                       }
27355 +
27356 +                       /* If the (new) signal is now blocked, requeue it.  */
27357 +                       if (sigismember(&current->blocked, signr)) {
27358 +                               send_sig_info(signr, &info, current);
27359 +                               continue;
27360 +                       }
27361 +               }
27362 +
27363 +               ka = &current->sig->action[signr-1];
27364 +               if (ka->sa.sa_handler == SIG_IGN) {
27365 +                       if (signr != SIGCHLD)
27366 +                               continue;
27367 +                       /* Check for SIGCHLD: it's special.  */
27368 +                       while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
27369 +                               /* nothing */;
27370 +                       continue;
27371 +               }
27372 +
27373 +               if (ka->sa.sa_handler == SIG_DFL) {
27374 +                       int exit_code = signr;
27375 +
27376 +                       /* Init gets no signals it doesn't want.  */
27377 +                       if (current->pid == 1)
27378 +                               continue;
27379 +
27380 +                       switch (signr) {
27381 +                       case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
27382 +                               continue;
27383 +
27384 +                       case SIGTSTP: case SIGTTIN: case SIGTTOU:
27385 +                               if (is_orphaned_pgrp(current->pgrp))
27386 +                                       continue;
27387 +                               /* FALLTHRU */
27388 +
27389 +                        case SIGSTOP: {
27390 +                                struct signal_struct *sig;
27391 +                               current->state = TASK_STOPPED;
27392 +                               current->exit_code = signr;
27393 +                                sig = current->p_pptr->sig;
27394 +                                if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
27395 +                                       notify_parent(current, SIGCHLD);
27396 +                               schedule();
27397 +                               continue;
27398 +                       }
27399 +                       case SIGQUIT: case SIGILL: case SIGTRAP:
27400 +                       case SIGABRT: case SIGFPE: case SIGSEGV:
27401 +                       case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
27402 +                               if (do_coredump(signr, &current->thread.regs))
27403 +                                       exit_code |= 0x80;
27404 +                               /* FALLTHRU */
27405 +
27406 +                       default:
27407 +                               sig_exit(signr, exit_code, &info);
27408 +                               /* NOTREACHED */
27409 +                       }
27410 +               }
27411 +
27412 +               /* Whee!  Actually deliver the signal.  */
27413 +               handle_signal(regs, signr, ka, &info, oldset, error);
27414 +               return(1);
27415 +       }
27416 +
27417 +       /* Did we come from a system call? */
27418 +       if(PT_REGS_SYSCALL_NR(regs) >= 0){
27419 +               /* Restart the system call - no handlers present */
27420 +               if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND ||
27421 +                  PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS ||
27422 +                  PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOINTR){
27423 +                       PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
27424 +                       PT_REGS_RESTART_SYSCALL(regs);
27425 +               }
27426 +       }
27427 +
27428 +       /* This closes a way to execute a system call on the host.  If
27429 +        * you set a breakpoint on a system call instruction and singlestep
27430 +        * from it, the tracing thread used to PTRACE_SINGLESTEP the process
27431 +        * rather than PTRACE_SYSCALL it, allowing the system call to execute
27432 +        * on the host.  The tracing thread will check this flag and 
27433 +        * PTRACE_SYSCALL if necessary.
27434 +        */
27435 +       if((current->ptrace & PT_DTRACE) && 
27436 +          is_syscall(PT_REGS_IP(&current->thread.regs)))
27437 +               current->thread.singlestep_syscall = 1;
27438 +
27439 +       return(0);
27440 +}
27441 +
27442 +int do_signal(int error)
27443 +{
27444 +       return(kern_do_signal(&current->thread.regs, NULL, error));
27445 +}
27446 +
27447 +/*
27448 + * Atomically swap in the new signal mask, and wait for a signal.
27449 + */
27450 +int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
27451 +{
27452 +       sigset_t saveset;
27453 +
27454 +       mask &= _BLOCKABLE;
27455 +       spin_lock_irq(&current->sigmask_lock);
27456 +       saveset = current->blocked;
27457 +       siginitset(&current->blocked, mask);
27458 +       recalc_sigpending(current);
27459 +       spin_unlock_irq(&current->sigmask_lock);
27460 +
27461 +       PT_REGS_SYSCALL_RET(&current->thread.regs) = -EINTR;
27462 +       while (1) {
27463 +               current->state = TASK_INTERRUPTIBLE;
27464 +               schedule();
27465 +               if(kern_do_signal(&current->thread.regs, &saveset, -EINTR))
27466 +                       return(-EINTR);
27467 +       }
27468 +}
27469 +
27470 +int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
27471 +{
27472 +       sigset_t saveset, newset;
27473 +
27474 +       /* XXX: Don't preclude handling different sized sigset_t's.  */
27475 +       if (sigsetsize != sizeof(sigset_t))
27476 +               return -EINVAL;
27477 +
27478 +       if (copy_from_user(&newset, unewset, sizeof(newset)))
27479 +               return -EFAULT;
27480 +       sigdelsetmask(&newset, ~_BLOCKABLE);
27481 +
27482 +       spin_lock_irq(&current->sigmask_lock);
27483 +       saveset = current->blocked;
27484 +       current->blocked = newset;
27485 +       recalc_sigpending(current);
27486 +       spin_unlock_irq(&current->sigmask_lock);
27487 +
27488 +       PT_REGS_SYSCALL_RET(&current->thread.regs) = -EINTR;
27489 +       while (1) {
27490 +               current->state = TASK_INTERRUPTIBLE;
27491 +               schedule();
27492 +               if (kern_do_signal(&current->thread.regs, &saveset, -EINTR))
27493 +                       return(-EINTR);
27494 +       }
27495 +}
27496 +
27497 +extern int userspace_pid[];
27498 +
27499 +static int copy_sc_from_user(struct pt_regs *to, void *from, 
27500 +                            struct arch_frame_data *arch)
27501 +{
27502 +       int ret;
27503 +
27504 +       ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
27505 +                         copy_sc_from_user_skas(userspace_pid[0], 
27506 +                                                &to->regs, from));
27507 +       return(ret);
27508 +}
27509 +
27510 +int sys_sigreturn(struct pt_regs regs)
27511 +{
27512 +       void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
27513 +       void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
27514 +       int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
27515 +
27516 +       spin_lock_irq(&current->sigmask_lock);
27517 +       copy_from_user(&current->blocked.sig[0], sc_sigmask(sc), 
27518 +                      sizeof(current->blocked.sig[0]));
27519 +       copy_from_user(&current->blocked.sig[1], mask, sig_size);
27520 +       sigdelsetmask(&current->blocked, ~_BLOCKABLE);
27521 +       recalc_sigpending(current);
27522 +       spin_unlock_irq(&current->sigmask_lock);
27523 +       copy_sc_from_user(&current->thread.regs, sc, 
27524 +                         &signal_frame_sc.common.arch);
27525 +       return(PT_REGS_SYSCALL_RET(&current->thread.regs));
27526 +}
27527 +
27528 +int sys_rt_sigreturn(struct pt_regs regs)
27529 +{
27530 +       struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
27531 +       int sig_size = _NSIG_WORDS * sizeof(unsigned long);
27532 +
27533 +       spin_lock_irq(&current->sigmask_lock);
27534 +       copy_from_user(&current->blocked, &uc->uc_sigmask, sig_size);
27535 +       sigdelsetmask(&current->blocked, ~_BLOCKABLE);
27536 +       recalc_sigpending(current);
27537 +       spin_unlock_irq(&current->sigmask_lock);
27538 +       copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext,
27539 +                         &signal_frame_si.common.arch);
27540 +       return(PT_REGS_SYSCALL_RET(&current->thread.regs));
27541 +}
27542 +
27543 +/*
27544 + * Overrides for Emacs so that we follow Linus's tabbing style.
27545 + * Emacs will notice this stuff at the end of the file and automatically
27546 + * adjust the settings for this buffer only.  This must remain at the end
27547 + * of the file.
27548 + * ---------------------------------------------------------------------------
27549 + * Local variables:
27550 + * c-file-style: "linux"
27551 + * End:
27552 + */
27553 Index: linux-2.4.29/arch/um/kernel/signal_user.c
27554 ===================================================================
27555 --- linux-2.4.29.orig/arch/um/kernel/signal_user.c      1970-01-01 03:00:00.000000000 +0300
27556 +++ linux-2.4.29/arch/um/kernel/signal_user.c   2005-05-03 22:28:14.448413720 +0300
27557 @@ -0,0 +1,142 @@
27558 +/* 
27559 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
27560 + * Licensed under the GPL
27561 + */
27562 +
27563 +#include <stdio.h>
27564 +#include <unistd.h>
27565 +#include <stdlib.h>
27566 +#include <signal.h>
27567 +#include <errno.h>
27568 +#include <stdarg.h>
27569 +#include <string.h>
27570 +#include <sys/mman.h>
27571 +#include "user_util.h"
27572 +#include "kern_util.h"
27573 +#include "user.h"
27574 +#include "signal_user.h"
27575 +#include "signal_kern.h"
27576 +#include "sysdep/sigcontext.h"
27577 +#include "sigcontext.h"
27578 +
27579 +void set_sigstack(void *sig_stack, int size)
27580 +{
27581 +       stack_t stack = ((stack_t) { .ss_flags  = 0,
27582 +                                    .ss_sp     = (__ptr_t) sig_stack,
27583 +                                    .ss_size   = size - sizeof(void *) });
27584 +
27585 +       if(sigaltstack(&stack, NULL) != 0)
27586 +               panic("enabling signal stack failed, errno = %d\n", errno);
27587 +}
27588 +
27589 +void set_handler(int sig, void (*handler)(int), int flags, ...)
27590 +{
27591 +       struct sigaction action;
27592 +       va_list ap;
27593 +       int mask;
27594 +
27595 +       va_start(ap, flags);
27596 +       action.sa_handler = handler;
27597 +       sigemptyset(&action.sa_mask);
27598 +       while((mask = va_arg(ap, int)) != -1){
27599 +               sigaddset(&action.sa_mask, mask);
27600 +       }
27601 +       action.sa_flags = flags;
27602 +       action.sa_restorer = NULL;
27603 +       if(sigaction(sig, &action, NULL) < 0)
27604 +               panic("sigaction failed");
27605 +}
27606 +
27607 +int change_sig(int signal, int on)
27608 +{
27609 +       sigset_t sigset, old;
27610 +
27611 +       sigemptyset(&sigset);
27612 +       sigaddset(&sigset, signal);
27613 +       sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
27614 +       return(!sigismember(&old, signal));
27615 +}
27616 +
27617 +static void change_signals(int type)
27618 +{
27619 +       sigset_t mask;
27620 +
27621 +       sigemptyset(&mask);
27622 +       sigaddset(&mask, SIGVTALRM);
27623 +       sigaddset(&mask, SIGALRM);
27624 +       sigaddset(&mask, SIGIO);
27625 +       sigaddset(&mask, SIGPROF);
27626 +       if(sigprocmask(type, &mask, NULL) < 0)
27627 +               panic("Failed to change signal mask - errno = %d", errno);
27628 +}
27629 +
27630 +void block_signals(void)
27631 +{
27632 +       change_signals(SIG_BLOCK);
27633 +}
27634 +
27635 +void unblock_signals(void)
27636 +{
27637 +       change_signals(SIG_UNBLOCK);
27638 +}
27639 +
27640 +#define SIGIO_BIT 0
27641 +#define SIGVTALRM_BIT 1
27642 +
27643 +static int enable_mask(sigset_t *mask)
27644 +{
27645 +       int sigs;
27646 +
27647 +       sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
27648 +       sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
27649 +       sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
27650 +       return(sigs);
27651 +}
27652 +
27653 +int get_signals(void)
27654 +{
27655 +       sigset_t mask;
27656 +       
27657 +       if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
27658 +               panic("Failed to get signal mask");
27659 +       return(enable_mask(&mask));
27660 +}
27661 +
27662 +int set_signals(int enable)
27663 +{
27664 +       sigset_t mask;
27665 +       int ret;
27666 +
27667 +       sigemptyset(&mask);
27668 +       if(enable & (1 << SIGIO_BIT)) 
27669 +               sigaddset(&mask, SIGIO);
27670 +       if(enable & (1 << SIGVTALRM_BIT)){
27671 +               sigaddset(&mask, SIGVTALRM);
27672 +               sigaddset(&mask, SIGALRM);
27673 +       }
27674 +       if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
27675 +               panic("Failed to enable signals");
27676 +       ret = enable_mask(&mask);
27677 +       sigemptyset(&mask);
27678 +       if((enable & (1 << SIGIO_BIT)) == 0) 
27679 +               sigaddset(&mask, SIGIO);
27680 +       if((enable & (1 << SIGVTALRM_BIT)) == 0){
27681 +               sigaddset(&mask, SIGVTALRM);
27682 +               sigaddset(&mask, SIGALRM);
27683 +       }
27684 +       if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
27685 +               panic("Failed to block signals");
27686 +
27687 +       return(ret);
27688 +}
27689 +
27690 +/*
27691 + * Overrides for Emacs so that we follow Linus's tabbing style.
27692 + * Emacs will notice this stuff at the end of the file and automatically
27693 + * adjust the settings for this buffer only.  This must remain at the end
27694 + * of the file.
27695 + * ---------------------------------------------------------------------------
27696 + * Local variables:
27697 + * c-file-style: "linux"
27698 + * End:
27699 + */
27700 Index: linux-2.4.29/arch/um/kernel/skas/exec_kern.c
27701 ===================================================================
27702 --- linux-2.4.29.orig/arch/um/kernel/skas/exec_kern.c   1970-01-01 03:00:00.000000000 +0300
27703 +++ linux-2.4.29/arch/um/kernel/skas/exec_kern.c        2005-05-03 22:28:14.000000000 +0300
27704 @@ -0,0 +1,41 @@
27705 +/* 
27706 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27707 + * Licensed under the GPL
27708 + */
27709 +
27710 +#include "linux/kernel.h"
27711 +#include "asm/current.h"
27712 +#include "asm/page.h"
27713 +#include "asm/signal.h"
27714 +#include "asm/ptrace.h"
27715 +#include "asm/uaccess.h"
27716 +#include "asm/mmu_context.h"
27717 +#include "tlb.h"
27718 +#include "skas.h"
27719 +#include "mmu.h"
27720 +#include "os.h"
27721 +
27722 +void flush_thread_skas(void)
27723 +{
27724 +       force_flush_all();
27725 +       switch_mm_skas(current->mm->context.skas.mm_fd);
27726 +}
27727 +
27728 +void start_thread_skas(struct pt_regs *regs, unsigned long eip, 
27729 +                      unsigned long esp)
27730 +{
27731 +       set_fs(USER_DS);
27732 +        PT_REGS_IP(regs) = eip;
27733 +       PT_REGS_SP(regs) = esp;
27734 +}
27735 +
27736 +/*
27737 + * Overrides for Emacs so that we follow Linus's tabbing style.
27738 + * Emacs will notice this stuff at the end of the file and automatically
27739 + * adjust the settings for this buffer only.  This must remain at the end
27740 + * of the file.
27741 + * ---------------------------------------------------------------------------
27742 + * Local variables:
27743 + * c-file-style: "linux"
27744 + * End:
27745 + */
27746 Index: linux-2.4.29/arch/um/kernel/skas/exec_user.c
27747 ===================================================================
27748 --- linux-2.4.29.orig/arch/um/kernel/skas/exec_user.c   1970-01-01 03:00:00.000000000 +0300
27749 +++ linux-2.4.29/arch/um/kernel/skas/exec_user.c        2005-05-03 22:28:14.000000000 +0300
27750 @@ -0,0 +1,63 @@
27751 +/* 
27752 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27753 + * Licensed under the GPL
27754 + */
27755 +
27756 +#include <stdlib.h>
27757 +#include <errno.h>
27758 +#include <signal.h>
27759 +#include <sched.h>
27760 +#include <sys/wait.h>
27761 +#include <sys/ptrace.h>
27762 +#include "user.h"
27763 +#include "kern_util.h"
27764 +#include "user_util.h"
27765 +#include "os.h"
27766 +#include "time_user.h"
27767 +
27768 +static int user_thread_tramp(void *arg)
27769 +{
27770 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
27771 +               panic("user_thread_tramp - PTRACE_TRACEME failed, "
27772 +                     "errno = %d\n", errno);
27773 +       enable_timer();
27774 +       os_stop_process(os_getpid());
27775 +       return(0);
27776 +}
27777 +
27778 +int user_thread(unsigned long stack, int flags)
27779 +{
27780 +       int pid, status, err;
27781 +
27782 +       pid = clone(user_thread_tramp, (void *) stack_sp(stack), 
27783 +                   flags | CLONE_FILES | SIGCHLD, NULL);
27784 +       if(pid < 0){
27785 +               printk("user_thread - clone failed, errno = %d\n", errno);
27786 +               return(pid);
27787 +       }
27788 +
27789 +       CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
27790 +       if(err < 0){
27791 +               printk("user_thread - waitpid failed, errno = %d\n", errno);
27792 +               return(-errno);
27793 +       }
27794 +
27795 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
27796 +               printk("user_thread - trampoline didn't stop, status = %d\n", 
27797 +                      status);
27798 +               return(-EINVAL);
27799 +       }
27800 +
27801 +       return(pid);
27802 +}
27803 +
27804 +/*
27805 + * Overrides for Emacs so that we follow Linus's tabbing style.
27806 + * Emacs will notice this stuff at the end of the file and automatically
27807 + * adjust the settings for this buffer only.  This must remain at the end
27808 + * of the file.
27809 + * ---------------------------------------------------------------------------
27810 + * Local variables:
27811 + * c-file-style: "linux"
27812 + * End:
27813 + */
27814 Index: linux-2.4.29/arch/um/kernel/skas/include/mmu.h
27815 ===================================================================
27816 --- linux-2.4.29.orig/arch/um/kernel/skas/include/mmu.h 1970-01-01 03:00:00.000000000 +0300
27817 +++ linux-2.4.29/arch/um/kernel/skas/include/mmu.h      2005-05-03 22:28:14.000000000 +0300
27818 @@ -0,0 +1,27 @@
27819 +/* 
27820 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27821 + * Licensed under the GPL
27822 + */
27823 +
27824 +#ifndef __SKAS_MMU_H
27825 +#define __SKAS_MMU_H
27826 +
27827 +#include "linux/list.h"
27828 +#include "linux/spinlock.h"
27829 +
27830 +struct mmu_context_skas {
27831 +       int mm_fd;
27832 +};
27833 +
27834 +#endif
27835 +
27836 +/*
27837 + * Overrides for Emacs so that we follow Linus's tabbing style.
27838 + * Emacs will notice this stuff at the end of the file and automatically
27839 + * adjust the settings for this buffer only.  This must remain at the end
27840 + * of the file.
27841 + * ---------------------------------------------------------------------------
27842 + * Local variables:
27843 + * c-file-style: "linux"
27844 + * End:
27845 + */
27846 Index: linux-2.4.29/arch/um/kernel/skas/include/mode.h
27847 ===================================================================
27848 --- linux-2.4.29.orig/arch/um/kernel/skas/include/mode.h        1970-01-01 03:00:00.000000000 +0300
27849 +++ linux-2.4.29/arch/um/kernel/skas/include/mode.h     2005-05-03 22:28:14.000000000 +0300
27850 @@ -0,0 +1,39 @@
27851 +/* 
27852 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27853 + * Licensed under the GPL
27854 + */
27855 +
27856 +#ifndef __MODE_SKAS_H__
27857 +#define __MODE_SKAS_H__
27858 +
27859 +#include <sysdep/ptrace.h>
27860 +
27861 +extern unsigned long exec_regs[];
27862 +extern unsigned long exec_fp_regs[];
27863 +extern unsigned long exec_fpx_regs[];
27864 +extern int have_fpx_regs;
27865 +
27866 +extern void user_time_init_skas(void);
27867 +extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, 
27868 +                                 void *from_ptr);
27869 +extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, 
27870 +                               union uml_pt_regs *regs, 
27871 +                               unsigned long fault_addr, int fault_type);
27872 +extern void sig_handler_common_skas(int sig, void *sc_ptr);
27873 +extern void halt_skas(void);
27874 +extern void reboot_skas(void);
27875 +extern void kill_off_processes_skas(void);
27876 +extern int is_skas_winch(int pid, int fd, void *data);
27877 +
27878 +#endif
27879 +
27880 +/*
27881 + * Overrides for Emacs so that we follow Linus's tabbing style.
27882 + * Emacs will notice this stuff at the end of the file and automatically
27883 + * adjust the settings for this buffer only.  This must remain at the end
27884 + * of the file.
27885 + * ---------------------------------------------------------------------------
27886 + * Local variables:
27887 + * c-file-style: "linux"
27888 + * End:
27889 + */
27890 Index: linux-2.4.29/arch/um/kernel/skas/include/mode_kern.h
27891 ===================================================================
27892 --- linux-2.4.29.orig/arch/um/kernel/skas/include/mode_kern.h   1970-01-01 03:00:00.000000000 +0300
27893 +++ linux-2.4.29/arch/um/kernel/skas/include/mode_kern.h        2005-05-03 22:28:14.000000000 +0300
27894 @@ -0,0 +1,51 @@
27895 +/* 
27896 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27897 + * Licensed under the GPL
27898 + */
27899 +
27900 +#ifndef __SKAS_MODE_KERN_H__
27901 +#define __SKAS_MODE_KERN_H__
27902 +
27903 +#include "linux/sched.h"
27904 +#include "asm/page.h"
27905 +#include "asm/ptrace.h"
27906 +
27907 +extern void flush_thread_skas(void);
27908 +extern void *_switch_to_skas(void *prev, void *next);
27909 +extern void start_thread_skas(struct pt_regs *regs, unsigned long eip, 
27910 +                             unsigned long esp);
27911 +extern int copy_thread_skas(int nr, unsigned long clone_flags, 
27912 +                           unsigned long sp, unsigned long stack_top, 
27913 +                           struct task_struct *p, struct pt_regs *regs);
27914 +extern void release_thread_skas(struct task_struct *task);
27915 +extern void exit_thread_skas(void);
27916 +extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
27917 +extern void init_idle_skas(void);
27918 +extern void flush_tlb_kernel_vm_skas(void);
27919 +extern void __flush_tlb_one_skas(unsigned long addr);
27920 +extern void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start, 
27921 +                                unsigned long end);
27922 +extern void flush_tlb_mm_skas(struct mm_struct *mm);
27923 +extern void force_flush_all_skas(void);
27924 +extern long execute_syscall_skas(void *r);
27925 +extern void before_mem_skas(unsigned long unused);
27926 +extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
27927 +                                        unsigned long *task_size_out);
27928 +extern int start_uml_skas(void);
27929 +extern int external_pid_skas(struct task_struct *task);
27930 +extern int thread_pid_skas(struct thread_struct *thread);
27931 +
27932 +#define kmem_end_skas (host_task_size - 1024 * 1024)
27933 +
27934 +#endif
27935 +
27936 +/*
27937 + * Overrides for Emacs so that we follow Linus's tabbing style.
27938 + * Emacs will notice this stuff at the end of the file and automatically
27939 + * adjust the settings for this buffer only.  This must remain at the end
27940 + * of the file.
27941 + * ---------------------------------------------------------------------------
27942 + * Local variables:
27943 + * c-file-style: "linux"
27944 + * End:
27945 + */
27946 Index: linux-2.4.29/arch/um/kernel/skas/include/proc_mm.h
27947 ===================================================================
27948 --- linux-2.4.29.orig/arch/um/kernel/skas/include/proc_mm.h     1970-01-01 03:00:00.000000000 +0300
27949 +++ linux-2.4.29/arch/um/kernel/skas/include/proc_mm.h  2005-05-03 22:28:14.000000000 +0300
27950 @@ -0,0 +1,55 @@
27951 +/* 
27952 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27953 + * Licensed under the GPL
27954 + */
27955 +
27956 +#ifndef __SKAS_PROC_MM_H
27957 +#define __SKAS_PROC_MM_H
27958 +
27959 +#define MM_MMAP 54
27960 +#define MM_MUNMAP 55
27961 +#define MM_MPROTECT 56
27962 +#define MM_COPY_SEGMENTS 57
27963 +
27964 +struct mm_mmap {
27965 +       unsigned long addr;
27966 +       unsigned long len;
27967 +       unsigned long prot;
27968 +       unsigned long flags;
27969 +       unsigned long fd;
27970 +       unsigned long offset;
27971 +};
27972 +
27973 +struct mm_munmap {
27974 +       unsigned long addr;
27975 +       unsigned long len;      
27976 +};
27977 +
27978 +struct mm_mprotect {
27979 +       unsigned long addr;
27980 +       unsigned long len;
27981 +        unsigned int prot;
27982 +};
27983 +
27984 +struct proc_mm_op {
27985 +       int op;
27986 +       union {
27987 +               struct mm_mmap mmap;
27988 +               struct mm_munmap munmap;
27989 +               struct mm_mprotect mprotect;
27990 +               int copy_segments;
27991 +       } u;
27992 +};
27993 +
27994 +#endif
27995 +
27996 +/*
27997 + * Overrides for Emacs so that we follow Linus's tabbing style.
27998 + * Emacs will notice this stuff at the end of the file and automatically
27999 + * adjust the settings for this buffer only.  This must remain at the end
28000 + * of the file.
28001 + * ---------------------------------------------------------------------------
28002 + * Local variables:
28003 + * c-file-style: "linux"
28004 + * End:
28005 + */
28006 Index: linux-2.4.29/arch/um/kernel/skas/include/ptrace-skas.h
28007 ===================================================================
28008 --- linux-2.4.29.orig/arch/um/kernel/skas/include/ptrace-skas.h 1970-01-01 03:00:00.000000000 +0300
28009 +++ linux-2.4.29/arch/um/kernel/skas/include/ptrace-skas.h      2005-05-03 22:28:14.000000000 +0300
28010 @@ -0,0 +1,57 @@
28011 +/* 
28012 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28013 + * Licensed under the GPL
28014 + */
28015 +
28016 +#ifndef __PTRACE_SKAS_H
28017 +#define __PTRACE_SKAS_H
28018 +
28019 +#include "uml-config.h"
28020 +
28021 +#ifdef UML_CONFIG_MODE_SKAS
28022 +
28023 +#include "skas_ptregs.h"
28024 +
28025 +#define HOST_FRAME_SIZE 17
28026 +
28027 +#define REGS_IP(r) ((r)[HOST_IP])
28028 +#define REGS_SP(r) ((r)[HOST_SP])
28029 +#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
28030 +#define REGS_EAX(r) ((r)[HOST_EAX])
28031 +#define REGS_EBX(r) ((r)[HOST_EBX])
28032 +#define REGS_ECX(r) ((r)[HOST_ECX])
28033 +#define REGS_EDX(r) ((r)[HOST_EDX])
28034 +#define REGS_ESI(r) ((r)[HOST_ESI])
28035 +#define REGS_EDI(r) ((r)[HOST_EDI])
28036 +#define REGS_EBP(r) ((r)[HOST_EBP])
28037 +#define REGS_CS(r) ((r)[HOST_CS])
28038 +#define REGS_SS(r) ((r)[HOST_SS])
28039 +#define REGS_DS(r) ((r)[HOST_DS])
28040 +#define REGS_ES(r) ((r)[HOST_ES])
28041 +#define REGS_FS(r) ((r)[HOST_FS])
28042 +#define REGS_GS(r) ((r)[HOST_GS])
28043 +
28044 +#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res)
28045 +
28046 +#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
28047 +
28048 +#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
28049 +
28050 +#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
28051 +
28052 +#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
28053 +
28054 +#endif
28055 +
28056 +#endif
28057 +
28058 +/*
28059 + * Overrides for Emacs so that we follow Linus's tabbing style.
28060 + * Emacs will notice this stuff at the end of the file and automatically
28061 + * adjust the settings for this buffer only.  This must remain at the end
28062 + * of the file.
28063 + * ---------------------------------------------------------------------------
28064 + * Local variables:
28065 + * c-file-style: "linux"
28066 + * End:
28067 + */
28068 Index: linux-2.4.29/arch/um/kernel/skas/include/skas.h
28069 ===================================================================
28070 --- linux-2.4.29.orig/arch/um/kernel/skas/include/skas.h        1970-01-01 03:00:00.000000000 +0300
28071 +++ linux-2.4.29/arch/um/kernel/skas/include/skas.h     2005-05-03 22:28:14.000000000 +0300
28072 @@ -0,0 +1,48 @@
28073 +/* 
28074 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28075 + * Licensed under the GPL
28076 + */
28077 +
28078 +#ifndef __SKAS_H
28079 +#define __SKAS_H
28080 +
28081 +#include "sysdep/ptrace.h"
28082 +
28083 +extern int userspace_pid[];
28084 +
28085 +extern void switch_threads(void *me, void *next);
28086 +extern void thread_wait(void *sw, void *fb);
28087 +extern void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
28088 +                       void (*handler)(int));
28089 +extern int start_idle_thread(void *stack, void *switch_buf_ptr, 
28090 +                            void **fork_buf_ptr);
28091 +extern int user_thread(unsigned long stack, int flags);
28092 +extern void userspace(union uml_pt_regs *regs);
28093 +extern void new_thread_proc(void *stack, void (*handler)(int sig));
28094 +extern void remove_sigstack(void);
28095 +extern void new_thread_handler(int sig);
28096 +extern void handle_syscall(union uml_pt_regs *regs);
28097 +extern void map(int fd, unsigned long virt, unsigned long phys, 
28098 +               unsigned long len, int r, int w, int x);
28099 +extern int unmap(int fd, void *addr, int len);
28100 +extern int protect(int fd, unsigned long addr, unsigned long len, 
28101 +                  int r, int w, int x, int must_succeed);
28102 +extern void user_signal(int sig, union uml_pt_regs *regs);
28103 +extern int new_mm(int from);
28104 +extern void save_registers(union uml_pt_regs *regs);
28105 +extern void restore_registers(union uml_pt_regs *regs);
28106 +extern void start_userspace(int cpu);
28107 +extern void init_registers(int pid);
28108 +
28109 +#endif
28110 +
28111 +/*
28112 + * Overrides for Emacs so that we follow Linus's tabbing style.
28113 + * Emacs will notice this stuff at the end of the file and automatically
28114 + * adjust the settings for this buffer only.  This must remain at the end
28115 + * of the file.
28116 + * ---------------------------------------------------------------------------
28117 + * Local variables:
28118 + * c-file-style: "linux"
28119 + * End:
28120 + */
28121 Index: linux-2.4.29/arch/um/kernel/skas/include/uaccess.h
28122 ===================================================================
28123 --- linux-2.4.29.orig/arch/um/kernel/skas/include/uaccess.h     1970-01-01 03:00:00.000000000 +0300
28124 +++ linux-2.4.29/arch/um/kernel/skas/include/uaccess.h  2005-05-03 22:28:14.000000000 +0300
28125 @@ -0,0 +1,40 @@
28126 +/* 
28127 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28128 + * Licensed under the GPL
28129 + */
28130 +
28131 +#ifndef __SKAS_UACCESS_H
28132 +#define __SKAS_UACCESS_H
28133 +
28134 +#include "asm/errno.h"
28135 +
28136 +#define access_ok_skas(type, addr, size) \
28137 +       ((segment_eq(get_fs(), KERNEL_DS)) || \
28138 +        (((unsigned long) (addr) < TASK_SIZE) && \
28139 +         ((unsigned long) (addr) + (size) <= TASK_SIZE)))
28140 +
28141 +static inline int verify_area_skas(int type, const void * addr, 
28142 +                                  unsigned long size)
28143 +{
28144 +       return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
28145 +}
28146 +
28147 +extern int copy_from_user_skas(void *to, const void *from, int n);
28148 +extern int copy_to_user_skas(void *to, const void *from, int n);
28149 +extern int strncpy_from_user_skas(char *dst, const char *src, int count);
28150 +extern int __clear_user_skas(void *mem, int len);
28151 +extern int clear_user_skas(void *mem, int len);
28152 +extern int strnlen_user_skas(const void *str, int len);
28153 +
28154 +#endif
28155 +
28156 +/*
28157 + * Overrides for Emacs so that we follow Linus's tabbing style.
28158 + * Emacs will notice this stuff at the end of the file and automatically
28159 + * adjust the settings for this buffer only.  This must remain at the end
28160 + * of the file.
28161 + * ---------------------------------------------------------------------------
28162 + * Local variables:
28163 + * c-file-style: "linux"
28164 + * End:
28165 + */
28166 Index: linux-2.4.29/arch/um/kernel/skas/Makefile
28167 ===================================================================
28168 --- linux-2.4.29.orig/arch/um/kernel/skas/Makefile      1970-01-01 03:00:00.000000000 +0300
28169 +++ linux-2.4.29/arch/um/kernel/skas/Makefile   2005-05-03 22:28:14.000000000 +0300
28170 @@ -0,0 +1,31 @@
28171 +# 
28172 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28173 +# Licensed under the GPL
28174 +#
28175 +
28176 +O_TARGET = skas.o
28177 +
28178 +obj-y = exec_kern.o exec_user.o mem.o mem_user.o mmu.o process.o \
28179 +       process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
28180 +       uaccess.o
28181 +
28182 +subdir-y = sys-$(SUBARCH)
28183 +
28184 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
28185 +
28186 +USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
28187 +
28188 +include $(TOPDIR)/Rules.make
28189 +
28190 +include/skas_ptregs.h : util/mk_ptregs
28191 +       util/mk_ptregs > $@
28192 +
28193 +util/mk_ptregs :
28194 +       $(MAKE) -C util
28195 +
28196 +$(USER_OBJS) : %.o: %.c
28197 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
28198 +
28199 +clean :
28200 +       $(MAKE) -C util clean
28201 +       $(RM) -f include/skas_ptregs.h
28202 Index: linux-2.4.29/arch/um/kernel/skas/mem.c
28203 ===================================================================
28204 --- linux-2.4.29.orig/arch/um/kernel/skas/mem.c 1970-01-01 03:00:00.000000000 +0300
28205 +++ linux-2.4.29/arch/um/kernel/skas/mem.c      2005-05-03 22:28:14.000000000 +0300
28206 @@ -0,0 +1,30 @@
28207 +/* 
28208 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28209 + * Licensed under the GPL
28210 + */
28211 +
28212 +#include "linux/config.h"
28213 +#include "linux/mm.h"
28214 +#include "mem_user.h"
28215 +
28216 +unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, 
28217 +                                 unsigned long *task_size_out)
28218 +{
28219 +       /* Round up to the nearest 4M */
28220 +       unsigned long top = ROUND_4M((unsigned long) &arg);
28221 +
28222 +       *host_size_out = top;
28223 +       *task_size_out = top;
28224 +       return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
28225 +}
28226 +
28227 +/*
28228 + * Overrides for Emacs so that we follow Linus's tabbing style.
28229 + * Emacs will notice this stuff at the end of the file and automatically
28230 + * adjust the settings for this buffer only.  This must remain at the end
28231 + * of the file.
28232 + * ---------------------------------------------------------------------------
28233 + * Local variables:
28234 + * c-file-style: "linux"
28235 + * End:
28236 + */
28237 Index: linux-2.4.29/arch/um/kernel/skas/mem_user.c
28238 ===================================================================
28239 --- linux-2.4.29.orig/arch/um/kernel/skas/mem_user.c    1970-01-01 03:00:00.000000000 +0300
28240 +++ linux-2.4.29/arch/um/kernel/skas/mem_user.c 2005-05-03 22:28:14.000000000 +0300
28241 @@ -0,0 +1,105 @@
28242 +/* 
28243 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28244 + * Licensed under the GPL
28245 + */
28246 +
28247 +#include <errno.h>
28248 +#include <sys/mman.h>
28249 +#include <sys/ptrace.h>
28250 +#include "mem_user.h"
28251 +#include "mem.h"
28252 +#include "user.h"
28253 +#include "os.h"
28254 +#include "proc_mm.h"
28255 +
28256 +void map(int fd, unsigned long virt, unsigned long phys, unsigned long len, 
28257 +        int r, int w, int x)
28258 +{
28259 +       struct proc_mm_op map;
28260 +       __u64 offset;
28261 +       int prot, n, phys_fd;
28262 +
28263 +       prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
28264 +               (x ? PROT_EXEC : 0);
28265 +       phys_fd = phys_mapping(phys, &offset);
28266 +
28267 +       map = ((struct proc_mm_op) { .op        = MM_MMAP,
28268 +                                    .u         = 
28269 +                                    { .mmap    = 
28270 +                                      { .addr          = virt,
28271 +                                        .len           = len,
28272 +                                        .prot          = prot,
28273 +                                        .flags         = MAP_SHARED | 
28274 +                                                         MAP_FIXED,
28275 +                                        .fd            = phys_fd,
28276 +                                        .offset        = offset
28277 +                                      } } } );
28278 +       n = os_write_file(fd, &map, sizeof(map));
28279 +       if(n != sizeof(map)) 
28280 +               printk("map : /proc/mm map failed, err = %d\n", -n);
28281 +}
28282 +
28283 +int unmap(int fd, void *addr, int len)
28284 +{
28285 +       struct proc_mm_op unmap;
28286 +       int n;
28287 +
28288 +       unmap = ((struct proc_mm_op) { .op      = MM_MUNMAP,
28289 +                                      .u       = 
28290 +                                      { .munmap        = 
28291 +                                        { .addr        = (unsigned long) addr,
28292 +                                          .len         = len } } } );
28293 +       n = os_write_file(fd, &unmap, sizeof(unmap));
28294 +       if(n != sizeof(unmap)) {
28295 +               if(n < 0) 
28296 +                       return(n);
28297 +               else if(n > 0) 
28298 +                       return(-EIO);
28299 +       }
28300 +
28301 +       return(0);
28302 +}
28303 +
28304 +int protect(int fd, unsigned long addr, unsigned long len, int r, int w, 
28305 +           int x, int must_succeed)
28306 +{
28307 +       struct proc_mm_op protect;
28308 +       int prot, n;
28309 +
28310 +       prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
28311 +               (x ? PROT_EXEC : 0);
28312 +
28313 +       protect = ((struct proc_mm_op) { .op    = MM_MPROTECT,
28314 +                                      .u       = 
28315 +                                      { .mprotect      = 
28316 +                                        { .addr        = (unsigned long) addr,
28317 +                                          .len         = len,
28318 +                                          .prot        = prot } } } );
28319 +
28320 +       n = os_write_file(fd, &protect, sizeof(protect));
28321 +       if(n != sizeof(protect)) {
28322 +               if(n == 0) return(0);
28323 +
28324 +               if(must_succeed)
28325 +                       panic("protect failed, err = %d", -n);
28326 +
28327 +               return(-EIO);
28328 +       }
28329 +
28330 +       return(0);
28331 +}
28332 +
28333 +void before_mem_skas(unsigned long unused)
28334 +{
28335 +}
28336 +
28337 +/*
28338 + * Overrides for Emacs so that we follow Linus's tabbing style.
28339 + * Emacs will notice this stuff at the end of the file and automatically
28340 + * adjust the settings for this buffer only.  This must remain at the end
28341 + * of the file.
28342 + * ---------------------------------------------------------------------------
28343 + * Local variables:
28344 + * c-file-style: "linux"
28345 + * End:
28346 + */
28347 Index: linux-2.4.29/arch/um/kernel/skas/mmu.c
28348 ===================================================================
28349 --- linux-2.4.29.orig/arch/um/kernel/skas/mmu.c 1970-01-01 03:00:00.000000000 +0300
28350 +++ linux-2.4.29/arch/um/kernel/skas/mmu.c      2005-05-03 22:28:14.000000000 +0300
28351 @@ -0,0 +1,46 @@
28352 +/* 
28353 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28354 + * Licensed under the GPL
28355 + */
28356 +
28357 +#include "linux/list.h"
28358 +#include "linux/spinlock.h"
28359 +#include "linux/slab.h"
28360 +#include "asm/segment.h"
28361 +#include "asm/mmu.h"
28362 +#include "os.h"
28363 +#include "skas.h"
28364 +
28365 +int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
28366 +{
28367 +       int from;
28368 +
28369 +       if((current->mm != NULL) && (current->mm != &init_mm))
28370 +               from = current->mm->context.skas.mm_fd;
28371 +       else from = -1;
28372 +
28373 +       mm->context.skas.mm_fd = new_mm(from);
28374 +       if(mm->context.skas.mm_fd < 0){
28375 +               printk("init_new_context_skas - new_mm failed, errno = %d\n",
28376 +                      mm->context.skas.mm_fd);
28377 +               return(mm->context.skas.mm_fd);
28378 +       }
28379 +
28380 +       return(0);
28381 +}
28382 +
28383 +void destroy_context_skas(struct mm_struct *mm)
28384 +{
28385 +       os_close_file(mm->context.skas.mm_fd);
28386 +}
28387 +
28388 +/*
28389 + * Overrides for Emacs so that we follow Linus's tabbing style.
28390 + * Emacs will notice this stuff at the end of the file and automatically
28391 + * adjust the settings for this buffer only.  This must remain at the end
28392 + * of the file.
28393 + * ---------------------------------------------------------------------------
28394 + * Local variables:
28395 + * c-file-style: "linux"
28396 + * End:
28397 + */
28398 Index: linux-2.4.29/arch/um/kernel/skas/process.c
28399 ===================================================================
28400 --- linux-2.4.29.orig/arch/um/kernel/skas/process.c     1970-01-01 03:00:00.000000000 +0300
28401 +++ linux-2.4.29/arch/um/kernel/skas/process.c  2005-05-03 22:28:14.000000000 +0300
28402 @@ -0,0 +1,400 @@
28403 +/* 
28404 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28405 + * Licensed under the GPL
28406 + */
28407 +
28408 +#include <stdlib.h>
28409 +#include <unistd.h>
28410 +#include <errno.h>
28411 +#include <signal.h>
28412 +#include <setjmp.h>
28413 +#include <sched.h>
28414 +#include <sys/wait.h>
28415 +#include <sys/ptrace.h>
28416 +#include <sys/mman.h>
28417 +#include <sys/user.h>
28418 +#include <asm/unistd.h>
28419 +#include "user.h"
28420 +#include "ptrace_user.h"
28421 +#include "time_user.h"
28422 +#include "sysdep/ptrace.h"
28423 +#include "user_util.h"
28424 +#include "kern_util.h"
28425 +#include "skas.h"
28426 +#include "sysdep/sigcontext.h"
28427 +#include "os.h"
28428 +#include "proc_mm.h"
28429 +#include "skas_ptrace.h"
28430 +#include "chan_user.h"
28431 +
28432 +int is_skas_winch(int pid, int fd, void *data)
28433 +{
28434 +       if(pid != getpid())
28435 +               return(0);
28436 +
28437 +       register_winch_irq(-1, fd, -1, data);
28438 +       return(1);
28439 +}
28440 +
28441 +/* These are set once at boot time and not changed thereafter */
28442 +
28443 +unsigned long exec_regs[FRAME_SIZE];
28444 +unsigned long exec_fp_regs[HOST_FP_SIZE];
28445 +unsigned long exec_fpx_regs[HOST_XFP_SIZE];
28446 +int have_fpx_regs = 1;
28447 +
28448 +static void handle_segv(int pid)
28449 +{
28450 +       struct ptrace_faultinfo fault;
28451 +       int err;
28452 +
28453 +       err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault);
28454 +       if(err)
28455 +               panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n",
28456 +                     errno);
28457 +
28458 +       segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
28459 +}
28460 +
28461 +static void handle_trap(int pid, union uml_pt_regs *regs)
28462 +{
28463 +       int err, syscall_nr, status;
28464 +
28465 +       syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
28466 +       UPT_SYSCALL_NR(regs) = syscall_nr;
28467 +       if(syscall_nr < 1){
28468 +               relay_signal(SIGTRAP, regs);
28469 +               return;
28470 +       }
28471 +
28472 +       if(!use_sysemu){
28473 +               err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
28474 +                            __NR_getpid);
28475 +               if(err < 0)
28476 +                       panic("handle_trap - nullifying syscall failed, "
28477 +                             "errno = %d\n", errno);
28478 +
28479 +               err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
28480 +               if(err < 0)
28481 +                       panic("handle_trap - continuing to end of syscall "
28482 +                             "failed, errno = %d\n", errno);
28483 +
28484 +               CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
28485 +               if((err < 0) || !WIFSTOPPED(status) || 
28486 +                  (WSTOPSIG(status) != SIGTRAP))
28487 +                       panic("handle_trap - failed to wait at end of "
28488 +                             "syscall, errno = %d, status = %d\n", errno, 
28489 +                             status);
28490 +       }
28491 +
28492 +       handle_syscall(regs);
28493 +}
28494 +
28495 +static int userspace_tramp(void *arg)
28496 +{
28497 +       init_new_thread_signals(0);
28498 +       enable_timer();
28499 +       ptrace(PTRACE_TRACEME, 0, 0, 0);
28500 +       os_stop_process(os_getpid());
28501 +       return(0);
28502 +}
28503 +
28504 +/* Each element set once, and only accessed by a single processor anyway */
28505 +#define NR_CPUS 1
28506 +int userspace_pid[NR_CPUS];
28507 +
28508 +void start_userspace(int cpu)
28509 +{
28510 +       void *stack;
28511 +       unsigned long sp;
28512 +       int pid, status, n;
28513 +
28514 +       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
28515 +                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
28516 +       if(stack == MAP_FAILED)
28517 +               panic("start_userspace : mmap failed, errno = %d", errno);
28518 +       sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
28519 +
28520 +       pid = clone(userspace_tramp, (void *) sp, 
28521 +                   CLONE_FILES | CLONE_VM | SIGCHLD, NULL);
28522 +       if(pid < 0)
28523 +               panic("start_userspace : clone failed, errno = %d", errno);
28524 +
28525 +       do {
28526 +               CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
28527 +               if(n < 0)
28528 +                       panic("start_userspace : wait failed, errno = %d", 
28529 +                             errno);
28530 +       } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
28531 +
28532 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
28533 +               panic("start_userspace : expected SIGSTOP, got status = %d",
28534 +                     status);
28535 +
28536 +       if(munmap(stack, PAGE_SIZE) < 0)
28537 +               panic("start_userspace : munmap failed, errno = %d\n", errno);
28538 +
28539 +       userspace_pid[cpu] = pid;
28540 +}
28541 +
28542 +void userspace(union uml_pt_regs *regs)
28543 +{
28544 +       int err, status, op, do_syscall, pid = userspace_pid[0];
28545 +
28546 +       do_syscall = use_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;
28547 +       restore_registers(regs);
28548 +               
28549 +       err = ptrace(do_syscall, pid, 0, 0);
28550 +       if(err)
28551 +               panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", 
28552 +                      errno);
28553 +       while(1){
28554 +               CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
28555 +               if(err < 0)
28556 +                       panic("userspace - waitpid failed, errno = %d\n", 
28557 +                             errno);
28558 +
28559 +               regs->skas.is_user = 1;
28560 +               save_registers(regs);
28561 +
28562 +               if(WIFSTOPPED(status)){
28563 +                       switch(WSTOPSIG(status)){
28564 +                       case SIGSEGV:
28565 +                               handle_segv(pid);
28566 +                               break;
28567 +                       case SIGTRAP:
28568 +                               handle_trap(pid, regs);
28569 +                               break;
28570 +                       case SIGIO:
28571 +                       case SIGVTALRM:
28572 +                       case SIGILL:
28573 +                       case SIGBUS:
28574 +                       case SIGFPE:
28575 +                       case SIGWINCH:
28576 +                               user_signal(WSTOPSIG(status), regs);
28577 +                               break;
28578 +                       default:
28579 +                               printk("userspace - child stopped with signal "
28580 +                                      "%d\n", WSTOPSIG(status));
28581 +                       }
28582 +                       interrupt_end();
28583 +               }
28584 +
28585 +               restore_registers(regs);
28586 +
28587 +               op = singlestepping(NULL) ? PTRACE_SINGLESTEP : do_syscall;
28588 +               err = ptrace(op, pid, 0, 0);
28589 +               if(err)
28590 +                       panic("userspace - PTRACE_SYSCALL failed, "
28591 +                             "errno = %d\n", errno);
28592 +       }
28593 +}
28594 +
28595 +void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
28596 +               void (*handler)(int))
28597 +{
28598 +       sigjmp_buf switch_buf, fork_buf;
28599 +
28600 +       *switch_buf_ptr = &switch_buf;
28601 +       *fork_buf_ptr = &fork_buf;
28602 +
28603 +       if(sigsetjmp(fork_buf, 1) == 0)
28604 +               new_thread_proc(stack, handler);
28605 +
28606 +       remove_sigstack();
28607 +}
28608 +
28609 +void thread_wait(void *sw, void *fb)
28610 +{
28611 +       sigjmp_buf buf, **switch_buf = sw, *fork_buf;
28612 +
28613 +       *switch_buf = &buf;
28614 +       fork_buf = fb;
28615 +       if(sigsetjmp(buf, 1) == 0)
28616 +               siglongjmp(*fork_buf, 1);
28617 +}
28618 +
28619 +static int move_registers(int pid, int int_op, int fp_op, 
28620 +                         union uml_pt_regs *regs, unsigned long *fp_regs)
28621 +{
28622 +       if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
28623 +               return(-errno);
28624 +       if(ptrace(fp_op, pid, 0, fp_regs) < 0)
28625 +               return(-errno);
28626 +       return(0);
28627 +}
28628 +
28629 +void save_registers(union uml_pt_regs *regs)
28630 +{
28631 +       unsigned long *fp_regs;
28632 +       int err, fp_op;
28633 +
28634 +       if(have_fpx_regs){
28635 +               fp_op = PTRACE_GETFPXREGS;
28636 +               fp_regs = regs->skas.xfp;
28637 +       }
28638 +       else {
28639 +               fp_op = PTRACE_GETFPREGS;
28640 +               fp_regs = regs->skas.fp;
28641 +       }
28642 +
28643 +       err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs, 
28644 +                            fp_regs);
28645 +       if(err)
28646 +               panic("save_registers - saving registers failed, errno = %d\n",
28647 +                     -err);
28648 +}
28649 +
28650 +void restore_registers(union uml_pt_regs *regs)
28651 +{
28652 +       unsigned long *fp_regs;
28653 +       int err, fp_op;
28654 +
28655 +       if(have_fpx_regs){
28656 +               fp_op = PTRACE_SETFPXREGS;
28657 +               fp_regs = regs->skas.xfp;
28658 +       }
28659 +       else {
28660 +               fp_op = PTRACE_SETFPREGS;
28661 +               fp_regs = regs->skas.fp;
28662 +       }
28663 +
28664 +       err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs, 
28665 +                            fp_regs);
28666 +       if(err)
28667 +               panic("restore_registers - saving registers failed, "
28668 +                     "errno = %d\n", -err);
28669 +}
28670 +
28671 +void switch_threads(void *me, void *next)
28672 +{
28673 +       sigjmp_buf my_buf, **me_ptr = me, *next_buf = next;
28674 +       
28675 +       *me_ptr = &my_buf;
28676 +       if(sigsetjmp(my_buf, 1) == 0)
28677 +               siglongjmp(*next_buf, 1);
28678 +}
28679 +
28680 +static sigjmp_buf initial_jmpbuf;
28681 +
28682 +/* XXX Make these percpu */
28683 +static void (*cb_proc)(void *arg);
28684 +static void *cb_arg;
28685 +static sigjmp_buf *cb_back;
28686 +
28687 +int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
28688 +{
28689 +       sigjmp_buf **switch_buf = switch_buf_ptr;
28690 +       int n;
28691 +
28692 +       *fork_buf_ptr = &initial_jmpbuf;
28693 +       n = sigsetjmp(initial_jmpbuf, 1);
28694 +       if(n == 0)
28695 +               new_thread_proc((void *) stack, new_thread_handler);
28696 +       else if(n == 1)
28697 +               remove_sigstack();
28698 +       else if(n == 2){
28699 +               (*cb_proc)(cb_arg);
28700 +               siglongjmp(*cb_back, 1);
28701 +       }
28702 +       else if(n == 3){
28703 +               kmalloc_ok = 0;
28704 +               return(0);
28705 +       }
28706 +       else if(n == 4){
28707 +               kmalloc_ok = 0;
28708 +               return(1);
28709 +       }
28710 +       siglongjmp(**switch_buf, 1);
28711 +}
28712 +
28713 +void remove_sigstack(void)
28714 +{
28715 +       stack_t stack = ((stack_t) { .ss_flags  = SS_DISABLE,
28716 +                                    .ss_sp     = NULL,
28717 +                                    .ss_size   = 0 });
28718 +
28719 +       if(sigaltstack(&stack, NULL) != 0)
28720 +               panic("disabling signal stack failed, errno = %d\n", errno);
28721 +}
28722 +
28723 +void initial_thread_cb_skas(void (*proc)(void *), void *arg)
28724 +{
28725 +       sigjmp_buf here;
28726 +
28727 +       cb_proc = proc;
28728 +       cb_arg = arg;
28729 +       cb_back = &here;
28730 +
28731 +       block_signals();
28732 +       if(sigsetjmp(here, 1) == 0)
28733 +               siglongjmp(initial_jmpbuf, 2);
28734 +       unblock_signals();
28735 +
28736 +       cb_proc = NULL;
28737 +       cb_arg = NULL;
28738 +       cb_back = NULL;
28739 +}
28740 +
28741 +void halt_skas(void)
28742 +{
28743 +       block_signals();
28744 +       siglongjmp(initial_jmpbuf, 3);
28745 +}
28746 +
28747 +void reboot_skas(void)
28748 +{
28749 +       block_signals();
28750 +       siglongjmp(initial_jmpbuf, 4);
28751 +}
28752 +
28753 +void switch_mm_skas(int mm_fd)
28754 +{
28755 +       int err;
28756 +
28757 +#warning need cpu pid in switch_mm_skas
28758 +       err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd);
28759 +       if(err)
28760 +               panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
28761 +                     errno);
28762 +}
28763 +
28764 +void kill_off_processes_skas(void)
28765 +{
28766 +#warning need to loop over userspace_pids in kill_off_processes_skas
28767 +       os_kill_process(userspace_pid[0], 1);
28768 +}
28769 +
28770 +void init_registers(int pid)
28771 +{
28772 +       int err;
28773 +
28774 +       if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0)
28775 +               panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", 
28776 +                     errno);
28777 +
28778 +       err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
28779 +       if(!err)
28780 +               return;
28781 +
28782 +       have_fpx_regs = 0;
28783 +       if(errno != EIO)
28784 +               panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", 
28785 +                     errno);
28786 +
28787 +       err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
28788 +       if(err)
28789 +               panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", 
28790 +                     errno);
28791 +}
28792 +
28793 +/*
28794 + * Overrides for Emacs so that we follow Linus's tabbing style.
28795 + * Emacs will notice this stuff at the end of the file and automatically
28796 + * adjust the settings for this buffer only.  This must remain at the end
28797 + * of the file.
28798 + * ---------------------------------------------------------------------------
28799 + * Local variables:
28800 + * c-file-style: "linux"
28801 + * End:
28802 + */
28803 Index: linux-2.4.29/arch/um/kernel/skas/process_kern.c
28804 ===================================================================
28805 --- linux-2.4.29.orig/arch/um/kernel/skas/process_kern.c        1970-01-01 03:00:00.000000000 +0300
28806 +++ linux-2.4.29/arch/um/kernel/skas/process_kern.c     2005-05-03 22:28:14.000000000 +0300
28807 @@ -0,0 +1,211 @@
28808 +/* 
28809 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28810 + * Licensed under the GPL
28811 + */
28812 +
28813 +#include "linux/sched.h"
28814 +#include "linux/slab.h"
28815 +#include "kern_util.h"
28816 +#include "time_user.h"
28817 +#include "signal_user.h"
28818 +#include "skas.h"
28819 +#include "os.h"
28820 +#include "user_util.h"
28821 +#include "tlb.h"
28822 +#include "frame.h"
28823 +#include "kern.h"
28824 +#include "mode.h"
28825 +#include "filehandle.h"
28826 +#include "proc_mm.h"
28827 +
28828 +void *_switch_to_skas(void *prev, void *next)
28829 +{
28830 +       struct task_struct *from, *to;
28831 +
28832 +       from = prev;
28833 +       to = next;
28834 +
28835 +       /* XXX need to check runqueues[cpu].idle */
28836 +       if(current->pid == 0)
28837 +               switch_timers(0);
28838 +
28839 +       to->thread.prev_sched = from;
28840 +       set_current(to);
28841 +
28842 +       switch_threads(&from->thread.mode.skas.switch_buf, 
28843 +                      to->thread.mode.skas.switch_buf);
28844 +
28845 +       if(current->pid == 0)
28846 +               switch_timers(1);
28847 +
28848 +       return(current->thread.prev_sched);
28849 +}
28850 +
28851 +extern void schedule_tail(struct task_struct *prev);
28852 +
28853 +void new_thread_handler(int sig)
28854 +{
28855 +       int (*fn)(void *), n;
28856 +       void *arg;
28857 +
28858 +       fn = current->thread.request.u.thread.proc;
28859 +       arg = current->thread.request.u.thread.arg;
28860 +       change_sig(SIGUSR1, 1);
28861 +       thread_wait(&current->thread.mode.skas.switch_buf, 
28862 +                   current->thread.mode.skas.fork_buf);
28863 +
28864 +       if(current->thread.prev_sched != NULL)
28865 +               schedule_tail(current->thread.prev_sched);
28866 +       current->thread.prev_sched = NULL;
28867 +
28868 +       /* The return value is 1 if the kernel thread execs a process,
28869 +        * 0 if it just exits
28870 +        */
28871 +       n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
28872 +       if(n == 1)
28873 +               userspace(&current->thread.regs.regs);
28874 +       else do_exit(0);
28875 +}
28876 +
28877 +void new_thread_proc(void *stack, void (*handler)(int sig))
28878 +{
28879 +       init_new_thread_stack(stack, handler);
28880 +       os_usr1_process(os_getpid());
28881 +}
28882 +
28883 +void release_thread_skas(struct task_struct *task)
28884 +{
28885 +}
28886 +
28887 +void exit_thread_skas(void)
28888 +{
28889 +}
28890 +
28891 +void fork_handler(int sig)
28892 +{
28893 +        change_sig(SIGUSR1, 1);
28894 +       thread_wait(&current->thread.mode.skas.switch_buf, 
28895 +                   current->thread.mode.skas.fork_buf);
28896 +       
28897 +       force_flush_all();
28898 +       if(current->thread.prev_sched != NULL)
28899 +               schedule_tail(current->thread.prev_sched);
28900 +       current->thread.prev_sched = NULL;
28901 +       unblock_signals();
28902 +
28903 +       userspace(&current->thread.regs.regs);
28904 +}
28905 +
28906 +int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
28907 +                    unsigned long stack_top, struct task_struct * p, 
28908 +                    struct pt_regs *regs)
28909 +{
28910 +       void (*handler)(int);
28911 +
28912 +       if(current->thread.forking){
28913 +               memcpy(&p->thread.regs.regs.skas, 
28914 +                      &current->thread.regs.regs.skas, 
28915 +                      sizeof(p->thread.regs.regs.skas));
28916 +               REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
28917 +               if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
28918 +
28919 +               handler = fork_handler;
28920 +       }
28921 +       else {
28922 +               memcpy(p->thread.regs.regs.skas.regs, exec_regs, 
28923 +                      sizeof(p->thread.regs.regs.skas.regs));
28924 +               memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs, 
28925 +                      sizeof(p->thread.regs.regs.skas.fp));
28926 +               memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs, 
28927 +                      sizeof(p->thread.regs.regs.skas.xfp));
28928 +                p->thread.request.u.thread = current->thread.request.u.thread;
28929 +               handler = new_thread_handler;
28930 +       }
28931 +
28932 +       new_thread(p, &p->thread.mode.skas.switch_buf, 
28933 +                  &p->thread.mode.skas.fork_buf, handler);
28934 +       return(0);
28935 +}
28936 +
28937 +int new_mm(int from)
28938 +{
28939 +       struct proc_mm_op copy;
28940 +       int n;
28941 +       int fd = open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
28942 +
28943 +       if(fd < 0)
28944 +               return(fd);
28945 +
28946 +       if(from != -1){
28947 +               copy = ((struct proc_mm_op) { .op       = MM_COPY_SEGMENTS,
28948 +                                             .u        = 
28949 +                                             { .copy_segments  = from } } );
28950 +               n = os_write_file(fd, &copy, sizeof(copy));
28951 +               if(n != sizeof(copy)) 
28952 +                       printk("new_mm : /proc/mm copy_segments failed, "
28953 +                              "err = %d\n", -n);
28954 +       }
28955 +
28956 +       return(fd);
28957 +}
28958 +
28959 +void init_idle_skas(void)
28960 +{
28961 +       cpu_tasks[current->processor].pid = os_getpid();
28962 +}
28963 +
28964 +extern void start_kernel(void);
28965 +
28966 +static int start_kernel_proc(void *unused)
28967 +{
28968 +       int pid;
28969 +
28970 +       block_signals();
28971 +       pid = os_getpid();
28972 +
28973 +       cpu_tasks[0].pid = pid;
28974 +       cpu_tasks[0].task = current;
28975 +#ifdef CONFIG_SMP
28976 +       cpu_online_map = 1;
28977 +#endif
28978 +       start_kernel();
28979 +       return(0);
28980 +}
28981 +
28982 +int start_uml_skas(void)
28983 +{
28984 +       start_userspace(0);
28985 +       capture_signal_stack();
28986 +
28987 +       init_new_thread_signals(1);
28988 +       idle_timer();
28989 +
28990 +       init_task.thread.request.u.thread.proc = start_kernel_proc;
28991 +       init_task.thread.request.u.thread.arg = NULL;
28992 +       return(start_idle_thread(&init_task,
28993 +                                &init_task.thread.mode.skas.switch_buf,
28994 +                                &init_task.thread.mode.skas.fork_buf));
28995 +}
28996 +
28997 +int external_pid_skas(struct task_struct *task)
28998 +{
28999 +#warning Need to look up userspace_pid by cpu  
29000 +       return(userspace_pid[0]);
29001 +}
29002 +
29003 +int thread_pid_skas(struct thread_struct *thread)
29004 +{
29005 +#warning Need to look up userspace_pid by cpu  
29006 +       return(userspace_pid[0]);
29007 +}
29008 +
29009 +/*
29010 + * Overrides for Emacs so that we follow Linus's tabbing style.
29011 + * Emacs will notice this stuff at the end of the file and automatically
29012 + * adjust the settings for this buffer only.  This must remain at the end
29013 + * of the file.
29014 + * ---------------------------------------------------------------------------
29015 + * Local variables:
29016 + * c-file-style: "linux"
29017 + * End:
29018 + */
29019 Index: linux-2.4.29/arch/um/kernel/skas/syscall_kern.c
29020 ===================================================================
29021 --- linux-2.4.29.orig/arch/um/kernel/skas/syscall_kern.c        1970-01-01 03:00:00.000000000 +0300
29022 +++ linux-2.4.29/arch/um/kernel/skas/syscall_kern.c     2005-05-03 22:28:14.000000000 +0300
29023 @@ -0,0 +1,43 @@
29024 +/* 
29025 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
29026 + * Licensed under the GPL
29027 + */
29028 +
29029 +#include "linux/sys.h"
29030 +#include "linux/ptrace.h"
29031 +#include "asm/errno.h"
29032 +#include "asm/unistd.h"
29033 +#include "asm/ptrace.h"
29034 +#include "asm/current.h"
29035 +#include "sysdep/syscalls.h"
29036 +#include "kern_util.h"
29037 +
29038 +extern syscall_handler_t *sys_call_table[];
29039 +
29040 +long execute_syscall_skas(void *r)
29041 +{
29042 +       struct pt_regs *regs = r;
29043 +       long res;
29044 +       int syscall;
29045 +
29046 +       current->thread.nsyscalls++;
29047 +       nsyscalls++;
29048 +       syscall = UPT_SYSCALL_NR(&regs->regs);
29049 +
29050 +       if((syscall >= NR_syscalls) || (syscall < 1))
29051 +               res = -ENOSYS;
29052 +       else res = EXECUTE_SYSCALL(syscall, regs);
29053 +
29054 +       return(res);
29055 +}
29056 +
29057 +/*
29058 + * Overrides for Emacs so that we follow Linus's tabbing style.
29059 + * Emacs will notice this stuff at the end of the file and automatically
29060 + * adjust the settings for this buffer only.  This must remain at the end
29061 + * of the file.
29062 + * ---------------------------------------------------------------------------
29063 + * Local variables:
29064 + * c-file-style: "linux"
29065 + * End:
29066 + */
29067 Index: linux-2.4.29/arch/um/kernel/skas/syscall_user.c
29068 ===================================================================
29069 --- linux-2.4.29.orig/arch/um/kernel/skas/syscall_user.c        1970-01-01 03:00:00.000000000 +0300
29070 +++ linux-2.4.29/arch/um/kernel/skas/syscall_user.c     2005-05-03 22:28:14.000000000 +0300
29071 @@ -0,0 +1,46 @@
29072 +/* 
29073 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29074 + * Licensed under the GPL
29075 + */
29076 +
29077 +#include <stdlib.h>
29078 +#include <signal.h>
29079 +#include "kern_util.h"
29080 +#include "syscall_user.h"
29081 +#include "sysdep/ptrace.h"
29082 +#include "sysdep/sigcontext.h"
29083 +
29084 +/* XXX Bogus */
29085 +#define ERESTARTSYS    512
29086 +#define ERESTARTNOINTR 513
29087 +#define ERESTARTNOHAND 514
29088 +
29089 +void handle_syscall(union uml_pt_regs *regs)
29090 +{
29091 +       long result;
29092 +       int index;
29093 +
29094 +       index = record_syscall_start(UPT_SYSCALL_NR(regs));
29095 +
29096 +       syscall_trace();
29097 +       result = execute_syscall(regs);
29098 +
29099 +       REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
29100 +       if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || 
29101 +          (result == -ERESTARTNOINTR))
29102 +               do_signal(result);
29103 +
29104 +       syscall_trace();
29105 +       record_syscall_end(index, result);
29106 +}
29107 +
29108 +/*
29109 + * Overrides for Emacs so that we follow Linus's tabbing style.
29110 + * Emacs will notice this stuff at the end of the file and automatically
29111 + * adjust the settings for this buffer only.  This must remain at the end
29112 + * of the file.
29113 + * ---------------------------------------------------------------------------
29114 + * Local variables:
29115 + * c-file-style: "linux"
29116 + * End:
29117 + */
29118 Index: linux-2.4.29/arch/um/kernel/skas/sys-i386/Makefile
29119 ===================================================================
29120 --- linux-2.4.29.orig/arch/um/kernel/skas/sys-i386/Makefile     1970-01-01 03:00:00.000000000 +0300
29121 +++ linux-2.4.29/arch/um/kernel/skas/sys-i386/Makefile  2005-05-03 22:28:14.000000000 +0300
29122 @@ -0,0 +1,17 @@
29123 +# 
29124 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29125 +# Licensed under the GPL
29126 +#
29127 +
29128 +O_TARGET = sys-i386.o
29129 +
29130 +obj-y = sigcontext.o
29131 +
29132 +USER_OBJS = sigcontext.o
29133 +
29134 +include $(TOPDIR)/Rules.make
29135 +
29136 +$(USER_OBJS) : %.o: %.c
29137 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
29138 +
29139 +clean :
29140 Index: linux-2.4.29/arch/um/kernel/skas/sys-i386/sigcontext.c
29141 ===================================================================
29142 --- linux-2.4.29.orig/arch/um/kernel/skas/sys-i386/sigcontext.c 1970-01-01 03:00:00.000000000 +0300
29143 +++ linux-2.4.29/arch/um/kernel/skas/sys-i386/sigcontext.c      2005-05-03 22:28:14.000000000 +0300
29144 @@ -0,0 +1,114 @@
29145 +/* 
29146 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29147 + * Licensed under the GPL
29148 + */
29149 +
29150 +#include <errno.h>
29151 +#include <asm/sigcontext.h>
29152 +#include <sys/ptrace.h>
29153 +#include <linux/ptrace.h>
29154 +#include "sysdep/ptrace.h"
29155 +#include "sysdep/ptrace_user.h"
29156 +#include "kern_util.h"
29157 +#include "user.h"
29158 +#include "sigcontext.h"
29159 +#include "mode.h"
29160 +
29161 +int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr)
29162 +{
29163 +       struct sigcontext sc, *from = from_ptr;
29164 +       unsigned long fpregs[FP_FRAME_SIZE];
29165 +       int err;
29166 +
29167 +       err = copy_from_user_proc(&sc, from, sizeof(sc));
29168 +       err |= copy_from_user_proc(fpregs, sc.fpstate, sizeof(fpregs));
29169 +       if(err)
29170 +               return(err);
29171 +
29172 +       regs->skas.regs[GS] = sc.gs;
29173 +       regs->skas.regs[FS] = sc.fs;
29174 +       regs->skas.regs[ES] = sc.es;
29175 +       regs->skas.regs[DS] = sc.ds;
29176 +       regs->skas.regs[EDI] = sc.edi;
29177 +       regs->skas.regs[ESI] = sc.esi;
29178 +       regs->skas.regs[EBP] = sc.ebp;
29179 +       regs->skas.regs[UESP] = sc.esp;
29180 +       regs->skas.regs[EBX] = sc.ebx;
29181 +       regs->skas.regs[EDX] = sc.edx;
29182 +       regs->skas.regs[ECX] = sc.ecx;
29183 +       regs->skas.regs[EAX] = sc.eax;
29184 +       regs->skas.regs[EIP] = sc.eip;
29185 +       regs->skas.regs[CS] = sc.cs;
29186 +       regs->skas.regs[EFL] = sc.eflags;
29187 +       regs->skas.regs[SS] = sc.ss;
29188 +       regs->skas.fault_addr = sc.cr2;
29189 +       regs->skas.fault_type = FAULT_WRITE(sc.err);
29190 +       regs->skas.trap_type = sc.trapno;
29191 +
29192 +       err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
29193 +       if(err < 0){
29194 +               printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
29195 +                      "errno = %d\n", errno);
29196 +               return(1);
29197 +       }
29198 +
29199 +       return(0);
29200 +}
29201 +
29202 +int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, 
29203 +                        union uml_pt_regs *regs, unsigned long fault_addr, 
29204 +                        int fault_type)
29205 +{
29206 +       struct sigcontext sc, *to = to_ptr;
29207 +       struct _fpstate *to_fp;
29208 +       unsigned long fpregs[FP_FRAME_SIZE];
29209 +       int err;
29210 +
29211 +       sc.gs = regs->skas.regs[GS];
29212 +       sc.fs = regs->skas.regs[FS];
29213 +       sc.es = regs->skas.regs[ES];
29214 +       sc.ds = regs->skas.regs[DS];
29215 +       sc.edi = regs->skas.regs[EDI];
29216 +       sc.esi = regs->skas.regs[ESI];
29217 +       sc.ebp = regs->skas.regs[EBP];
29218 +       sc.esp = regs->skas.regs[UESP];
29219 +       sc.ebx = regs->skas.regs[EBX];
29220 +       sc.edx = regs->skas.regs[EDX];
29221 +       sc.ecx = regs->skas.regs[ECX];
29222 +       sc.eax = regs->skas.regs[EAX];
29223 +       sc.eip = regs->skas.regs[EIP];
29224 +       sc.cs = regs->skas.regs[CS];
29225 +       sc.eflags = regs->skas.regs[EFL];
29226 +       sc.esp_at_signal = regs->skas.regs[UESP];
29227 +       sc.ss = regs->skas.regs[SS];
29228 +       sc.cr2 = fault_addr;
29229 +       sc.err = TO_SC_ERR(fault_type);
29230 +       sc.trapno = regs->skas.trap_type;
29231 +
29232 +       err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
29233 +       if(err < 0){
29234 +               printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
29235 +                      "errno = %d\n", errno);
29236 +               return(1);
29237 +       }
29238 +       to_fp = (struct _fpstate *) 
29239 +               (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
29240 +       sc.fpstate = to_fp;
29241 +
29242 +       if(err)
29243 +               return(err);
29244 +
29245 +       return(copy_to_user_proc(to, &sc, sizeof(sc)) ||
29246 +              copy_to_user_proc(to_fp, fpregs, sizeof(fpregs)));
29247 +}
29248 +
29249 +/*
29250 + * Overrides for Emacs so that we follow Linus's tabbing style.
29251 + * Emacs will notice this stuff at the end of the file and automatically
29252 + * adjust the settings for this buffer only.  This must remain at the end
29253 + * of the file.
29254 + * ---------------------------------------------------------------------------
29255 + * Local variables:
29256 + * c-file-style: "linux"
29257 + * End:
29258 + */
29259 Index: linux-2.4.29/arch/um/kernel/skas/time.c
29260 ===================================================================
29261 --- linux-2.4.29.orig/arch/um/kernel/skas/time.c        1970-01-01 03:00:00.000000000 +0300
29262 +++ linux-2.4.29/arch/um/kernel/skas/time.c     2005-05-03 22:28:14.000000000 +0300
29263 @@ -0,0 +1,30 @@
29264 +/* 
29265 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29266 + * Licensed under the GPL
29267 + */
29268 +
29269 +#include <sys/signal.h>
29270 +#include <sys/time.h>
29271 +#include "time_user.h"
29272 +#include "process.h"
29273 +#include "user.h"
29274 +
29275 +void user_time_init_skas(void)
29276 +{
29277 +        if(signal(SIGALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
29278 +                panic("Couldn't set SIGALRM handler");
29279 +       if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
29280 +               panic("Couldn't set SIGVTALRM handler");
29281 +       set_interval(ITIMER_VIRTUAL);
29282 +}
29283 +
29284 +/*
29285 + * Overrides for Emacs so that we follow Linus's tabbing style.
29286 + * Emacs will notice this stuff at the end of the file and automatically
29287 + * adjust the settings for this buffer only.  This must remain at the end
29288 + * of the file.
29289 + * ---------------------------------------------------------------------------
29290 + * Local variables:
29291 + * c-file-style: "linux"
29292 + * End:
29293 + */
29294 Index: linux-2.4.29/arch/um/kernel/skas/tlb.c
29295 ===================================================================
29296 --- linux-2.4.29.orig/arch/um/kernel/skas/tlb.c 1970-01-01 03:00:00.000000000 +0300
29297 +++ linux-2.4.29/arch/um/kernel/skas/tlb.c      2005-05-03 22:28:14.000000000 +0300
29298 @@ -0,0 +1,153 @@
29299 +/* 
29300 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29301 + * Licensed under the GPL
29302 + */
29303 +
29304 +#include "linux/stddef.h"
29305 +#include "linux/sched.h"
29306 +#include "asm/page.h"
29307 +#include "asm/pgtable.h"
29308 +#include "asm/mmu.h"
29309 +#include "user_util.h"
29310 +#include "mem_user.h"
29311 +#include "skas.h"
29312 +#include "os.h"
29313 +
29314 +static void fix_range(struct mm_struct *mm, unsigned long start_addr,
29315 +                     unsigned long end_addr, int force)
29316 +{
29317 +       pgd_t *npgd;
29318 +       pmd_t *npmd;
29319 +       pte_t *npte;
29320 +       unsigned long addr;
29321 +       int r, w, x, err, fd;
29322 +
29323 +       if(mm == NULL) return;
29324 +       fd = mm->context.skas.mm_fd;
29325 +       for(addr = start_addr; addr < end_addr;){
29326 +               npgd = pgd_offset(mm, addr);
29327 +               npmd = pmd_offset(npgd, addr);
29328 +               if(pmd_present(*npmd)){
29329 +                       npte = pte_offset(npmd, addr);
29330 +                       r = pte_read(*npte);
29331 +                       w = pte_write(*npte);
29332 +                       x = pte_exec(*npte);
29333 +                       if(!pte_dirty(*npte)) w = 0;
29334 +                       if(!pte_young(*npte)){
29335 +                               r = 0;
29336 +                               w = 0;
29337 +                       }
29338 +                       if(force || pte_newpage(*npte)){
29339 +                               err = unmap(fd, (void *) addr, PAGE_SIZE);
29340 +                               if(err < 0)
29341 +                                       panic("munmap failed, errno = %d\n",
29342 +                                             -err);
29343 +                               if(pte_present(*npte))
29344 +                                       map(fd, addr, 
29345 +                                           pte_val(*npte) & PAGE_MASK,
29346 +                                           PAGE_SIZE, r, w, x);
29347 +                       }
29348 +                       else if(pte_newprot(*npte)){
29349 +                               protect(fd, addr, PAGE_SIZE, r, w, x, 1);
29350 +                       }
29351 +                       *npte = pte_mkuptodate(*npte);
29352 +                       addr += PAGE_SIZE;
29353 +               }
29354 +               else {
29355 +                       if(force || pmd_newpage(*npmd)){
29356 +                               err = unmap(fd, (void *) addr, PMD_SIZE);
29357 +                               if(err < 0)
29358 +                                       panic("munmap failed, errno = %d\n",
29359 +                                             -err);
29360 +                               pmd_mkuptodate(*npmd);
29361 +                       }
29362 +                       addr += PMD_SIZE;
29363 +               }
29364 +       }
29365 +}
29366 +
29367 +static void flush_kernel_vm_range(unsigned long start, unsigned long end)
29368 +{
29369 +       struct mm_struct *mm;
29370 +       pgd_t *pgd;
29371 +       pmd_t *pmd;
29372 +       pte_t *pte;
29373 +       unsigned long addr;
29374 +       int updated = 0, err;
29375 +
29376 +       mm = &init_mm;
29377 +       for(addr = start; addr < end;){
29378 +               pgd = pgd_offset(mm, addr);
29379 +               pmd = pmd_offset(pgd, addr);
29380 +               if(pmd_present(*pmd)){
29381 +                       pte = pte_offset(pmd, addr);
29382 +                       if(!pte_present(*pte) || pte_newpage(*pte)){
29383 +                               updated = 1;
29384 +                               err = os_unmap_memory((void *) addr, 
29385 +                                                     PAGE_SIZE);
29386 +                               if(err < 0)
29387 +                                       panic("munmap failed, errno = %d\n",
29388 +                                             -err);
29389 +                               if(pte_present(*pte))
29390 +                                       map_memory(addr, 
29391 +                                                  pte_val(*pte) & PAGE_MASK,
29392 +                                                  PAGE_SIZE, 1, 1, 1);
29393 +                       }
29394 +                       else if(pte_newprot(*pte)){
29395 +                               updated = 1;
29396 +                               protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
29397 +                       }
29398 +                       addr += PAGE_SIZE;
29399 +               }
29400 +               else {
29401 +                       if(pmd_newpage(*pmd)){
29402 +                               updated = 1;
29403 +                               err = os_unmap_memory((void *) addr, PMD_SIZE);
29404 +                               if(err < 0)
29405 +                                       panic("munmap failed, errno = %d\n",
29406 +                                             -err);
29407 +                       }
29408 +                       addr += PMD_SIZE;
29409 +               }
29410 +       }
29411 +}
29412 +
29413 +void flush_tlb_kernel_vm_skas(void)
29414 +{
29415 +       flush_kernel_vm_range(start_vm, end_vm);
29416 +}
29417 +
29418 +void __flush_tlb_one_skas(unsigned long addr)
29419 +{
29420 +       flush_kernel_vm_range(addr, addr + PAGE_SIZE);
29421 +}
29422 +
29423 +void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start, 
29424 +                    unsigned long end)
29425 +{
29426 +       if(mm == NULL)
29427 +               flush_kernel_vm_range(start, end);
29428 +       else fix_range(mm, start, end, 0);
29429 +}
29430 +
29431 +void flush_tlb_mm_skas(struct mm_struct *mm)
29432 +{
29433 +       flush_tlb_kernel_vm_skas();
29434 +       fix_range(mm, 0, host_task_size, 0);
29435 +}
29436 +
29437 +void force_flush_all_skas(void)
29438 +{
29439 +       fix_range(current->mm, 0, host_task_size, 1);
29440 +}
29441 +
29442 +/*
29443 + * Overrides for Emacs so that we follow Linus's tabbing style.
29444 + * Emacs will notice this stuff at the end of the file and automatically
29445 + * adjust the settings for this buffer only.  This must remain at the end
29446 + * of the file.
29447 + * ---------------------------------------------------------------------------
29448 + * Local variables:
29449 + * c-file-style: "linux"
29450 + * End:
29451 + */
29452 Index: linux-2.4.29/arch/um/kernel/skas/trap_user.c
29453 ===================================================================
29454 --- linux-2.4.29.orig/arch/um/kernel/skas/trap_user.c   1970-01-01 03:00:00.000000000 +0300
29455 +++ linux-2.4.29/arch/um/kernel/skas/trap_user.c        2005-05-03 22:28:14.000000000 +0300
29456 @@ -0,0 +1,66 @@
29457 +/* 
29458 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
29459 + * Licensed under the GPL
29460 + */
29461 +
29462 +#include <signal.h>
29463 +#include <errno.h>
29464 +#include <asm/sigcontext.h>
29465 +#include "sysdep/ptrace.h"
29466 +#include "signal_user.h"
29467 +#include "user_util.h"
29468 +#include "kern_util.h"
29469 +#include "task.h"
29470 +#include "sigcontext.h"
29471 +
29472 +void sig_handler_common_skas(int sig, void *sc_ptr)
29473 +{
29474 +       struct sigcontext *sc = sc_ptr;
29475 +       struct skas_regs *r;
29476 +       struct signal_info *info;
29477 +       int save_errno = errno;
29478 +       int save_user;
29479 +
29480 +       r = &TASK_REGS(get_current())->skas;
29481 +       save_user = r->is_user;
29482 +       r->is_user = 0;
29483 +       r->fault_addr = SC_FAULT_ADDR(sc);
29484 +       r->fault_type = SC_FAULT_TYPE(sc);
29485 +       r->trap_type = SC_TRAP_TYPE(sc);
29486 +
29487 +       change_sig(SIGUSR1, 1);
29488 +       info = &sig_info[sig];
29489 +       if(!info->is_irq) unblock_signals();
29490 +
29491 +       (*info->handler)(sig, (union uml_pt_regs *) r);
29492 +
29493 +       errno = save_errno;
29494 +       r->is_user = save_user;
29495 +}
29496 +
29497 +extern int missed_ticks[];
29498 +
29499 +void user_signal(int sig, union uml_pt_regs *regs)
29500 +{
29501 +       struct signal_info *info;
29502 +
29503 +       regs->skas.is_user = 1;
29504 +       regs->skas.fault_addr = 0;
29505 +       regs->skas.fault_type = 0;
29506 +       regs->skas.trap_type = 0;
29507 +       info = &sig_info[sig];
29508 +       (*info->handler)(sig, regs);
29509 +
29510 +       unblock_signals();
29511 +}
29512 +
29513 +/*
29514 + * Overrides for Emacs so that we follow Linus's tabbing style.
29515 + * Emacs will notice this stuff at the end of the file and automatically
29516 + * adjust the settings for this buffer only.  This must remain at the end
29517 + * of the file.
29518 + * ---------------------------------------------------------------------------
29519 + * Local variables:
29520 + * c-file-style: "linux"
29521 + * End:
29522 + */
29523 Index: linux-2.4.29/arch/um/kernel/skas/uaccess.c
29524 ===================================================================
29525 --- linux-2.4.29.orig/arch/um/kernel/skas/uaccess.c     1970-01-01 03:00:00.000000000 +0300
29526 +++ linux-2.4.29/arch/um/kernel/skas/uaccess.c  2005-05-03 22:28:14.000000000 +0300
29527 @@ -0,0 +1,248 @@
29528 +/* 
29529 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
29530 + * Licensed under the GPL
29531 + */
29532 +
29533 +#include "linux/stddef.h"
29534 +#include "linux/kernel.h"
29535 +#include "linux/string.h"
29536 +#include "linux/fs.h"
29537 +#include "linux/highmem.h"
29538 +#include "asm/page.h"
29539 +#include "asm/pgtable.h"
29540 +#include "asm/uaccess.h"
29541 +#include "kern_util.h"
29542 +#include "user_util.h"
29543 +
29544 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 
29545 +                            pte_t *pte_out);
29546 +
29547 +static unsigned long maybe_map(unsigned long virt, int is_write)
29548 +{
29549 +       pte_t pte;
29550 +
29551 +       void *phys = um_virt_to_phys(current, virt, &pte);
29552 +       int dummy_code;
29553 +
29554 +       if(IS_ERR(phys) || (is_write && !pte_write(pte))){
29555 +               if(!handle_page_fault(virt, 0, is_write, 1, &dummy_code))
29556 +                       return(0);
29557 +               phys = um_virt_to_phys(current, virt, NULL);
29558 +       }
29559 +       return((unsigned long) phys);
29560 +}
29561 +
29562 +static int do_op(unsigned long addr, int len, int is_write, 
29563 +                int (*op)(unsigned long addr, int len, void *arg), void *arg)
29564 +{
29565 +       struct page *page;
29566 +       int n;
29567 +
29568 +       addr = maybe_map(addr, is_write);
29569 +       if(addr == -1)
29570 +               return(-1);
29571 +
29572 +       page = phys_to_page(addr);
29573 +       addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
29574 +       n = (*op)(addr, len, arg);
29575 +       kunmap(page);
29576 +
29577 +       return(n);
29578 +}
29579 +
29580 +static void do_buffer_op(void *jmpbuf, void *arg_ptr)
29581 +{
29582 +       va_list args = *((va_list *) arg_ptr);
29583 +       unsigned long addr = va_arg(args, unsigned long);
29584 +       int len = va_arg(args, int);
29585 +       int is_write = va_arg(args, int);
29586 +       int (*op)(unsigned long, int, void *) = va_arg(args, void *);
29587 +       void *arg = va_arg(args, void *);
29588 +       int *res = va_arg(args, int *);
29589 +       int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
29590 +       int remain = len, n;
29591 +
29592 +       current->thread.fault_catcher = jmpbuf;
29593 +       n = do_op(addr, size, is_write, op, arg);
29594 +       if(n != 0){
29595 +               *res = (n < 0 ? remain : 0);
29596 +               goto out;
29597 +       }
29598 +
29599 +       addr += size;
29600 +       remain -= size;
29601 +       if(remain == 0){
29602 +               *res = 0;
29603 +               goto out;
29604 +       }
29605 +
29606 +       while(addr < ((addr + remain) & PAGE_MASK)){
29607 +               n = do_op(addr, PAGE_SIZE, is_write, op, arg);
29608 +               if(n != 0){
29609 +                       *res = (n < 0 ? remain : 0);
29610 +                       goto out;
29611 +               }
29612 +
29613 +               addr += PAGE_SIZE;
29614 +               remain -= PAGE_SIZE;
29615 +       }
29616 +       if(remain == 0){
29617 +               *res = 0;
29618 +               goto out;
29619 +       }
29620 +
29621 +       n = do_op(addr, remain, is_write, op, arg);
29622 +       if(n != 0)
29623 +               *res = (n < 0 ? remain : 0);
29624 +       else *res = 0;
29625 + out:
29626 +       current->thread.fault_catcher = NULL;
29627 +}
29628 +
29629 +static int buffer_op(unsigned long addr, int len, int is_write,
29630 +                    int (*op)(unsigned long addr, int len, void *arg),
29631 +                    void *arg)
29632 +{
29633 +       int faulted, res;
29634 +       
29635 +       faulted = setjmp_wrapper(do_buffer_op, addr, len, is_write, op, arg, 
29636 +                                &res);
29637 +       if(!faulted)
29638 +               return(res);
29639 +
29640 +       return(addr + len - (unsigned long) current->thread.fault_addr);
29641 +}
29642 +
29643 +static int copy_chunk_from_user(unsigned long from, int len, void *arg)
29644 +{
29645 +       unsigned long *to_ptr = arg, to = *to_ptr;
29646 +
29647 +       memcpy((void *) to, (void *) from, len);
29648 +       *to_ptr += len;
29649 +       return(0);
29650 +}
29651 +
29652 +int copy_from_user_skas(void *to, const void *from, int n)
29653 +{
29654 +       if(segment_eq(get_fs(), KERNEL_DS)){
29655 +               memcpy(to, from, n);
29656 +               return(0);
29657 +       }
29658 +
29659 +       return(access_ok_skas(VERIFY_READ, from, n) ?
29660 +              buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
29661 +              n);
29662 +}
29663 +
29664 +static int copy_chunk_to_user(unsigned long to, int len, void *arg)
29665 +{
29666 +       unsigned long *from_ptr = arg, from = *from_ptr;
29667 +
29668 +       memcpy((void *) to, (void *) from, len);
29669 +       *from_ptr += len;
29670 +       return(0);
29671 +}
29672 +
29673 +int copy_to_user_skas(void *to, const void *from, int n)
29674 +{
29675 +       if(segment_eq(get_fs(), KERNEL_DS)){
29676 +               memcpy(to, from, n);
29677 +               return(0);
29678 +       }
29679 +
29680 +       return(access_ok_skas(VERIFY_WRITE, to, n) ?
29681 +              buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
29682 +              n);
29683 +}
29684 +
29685 +static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
29686 +{
29687 +       char **to_ptr = arg, *to = *to_ptr;
29688 +       int n;
29689 +
29690 +       strncpy(to, (void *) from, len);
29691 +       n = strnlen(to, len);
29692 +       *to_ptr += n;
29693 +
29694 +       if(n < len) 
29695 +               return(1);
29696 +       return(0);
29697 +}
29698 +
29699 +int strncpy_from_user_skas(char *dst, const char *src, int count)
29700 +{
29701 +       int n;
29702 +       char *ptr = dst;
29703 +
29704 +       if(segment_eq(get_fs(), KERNEL_DS)){
29705 +               strncpy(dst, src, count);
29706 +               return(strnlen(dst, count));
29707 +       }
29708 +
29709 +       if(!access_ok_skas(VERIFY_READ, src, 1))
29710 +               return(-EFAULT);
29711 +
29712 +       n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user, 
29713 +                     &ptr);
29714 +       if(n != 0)
29715 +               return(-EFAULT);
29716 +       return(strnlen(dst, count));
29717 +}
29718 +
29719 +static int clear_chunk(unsigned long addr, int len, void *unused)
29720 +{
29721 +       memset((void *) addr, 0, len);
29722 +       return(0);
29723 +}
29724 +
29725 +int __clear_user_skas(void *mem, int len)
29726 +{
29727 +       return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
29728 +}
29729 +
29730 +int clear_user_skas(void *mem, int len)
29731 +{
29732 +       if(segment_eq(get_fs(), KERNEL_DS)){
29733 +               memset(mem, 0, len);
29734 +               return(0);
29735 +       }
29736 +
29737 +       return(access_ok_skas(VERIFY_WRITE, mem, len) ? 
29738 +              buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
29739 +}
29740 +
29741 +static int strnlen_chunk(unsigned long str, int len, void *arg)
29742 +{
29743 +       int *len_ptr = arg, n;
29744 +
29745 +       n = strnlen((void *) str, len);
29746 +       *len_ptr += n;
29747 +
29748 +       if(n < len)
29749 +               return(1);
29750 +       return(0);
29751 +}
29752 +
29753 +int strnlen_user_skas(const void *str, int len)
29754 +{
29755 +       int count = 0, n;
29756 +
29757 +       if(segment_eq(get_fs(), KERNEL_DS))
29758 +               return(strnlen(str, len) + 1);
29759 +
29760 +       n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
29761 +       if(n == 0)
29762 +               return(count + 1);
29763 +       return(-EFAULT);
29764 +}
29765 +
29766 +/*
29767 + * Overrides for Emacs so that we follow Linus's tabbing style.
29768 + * Emacs will notice this stuff at the end of the file and automatically
29769 + * adjust the settings for this buffer only.  This must remain at the end
29770 + * of the file.
29771 + * ---------------------------------------------------------------------------
29772 + * Local variables:
29773 + * c-file-style: "linux"
29774 + * End:
29775 + */
29776 Index: linux-2.4.29/arch/um/kernel/skas/util/Makefile
29777 ===================================================================
29778 --- linux-2.4.29.orig/arch/um/kernel/skas/util/Makefile 1970-01-01 03:00:00.000000000 +0300
29779 +++ linux-2.4.29/arch/um/kernel/skas/util/Makefile      2005-05-03 22:28:14.000000000 +0300
29780 @@ -0,0 +1,10 @@
29781 +all: mk_ptregs
29782 +
29783 +mk_ptregs : mk_ptregs.o
29784 +       $(HOSTCC) -o mk_ptregs mk_ptregs.o
29785 +
29786 +mk_ptregs.o : mk_ptregs.c
29787 +       $(HOSTCC) -c $< 
29788 +
29789 +clean : 
29790 +       $(RM) -f mk_ptregs *.o *~
29791 Index: linux-2.4.29/arch/um/kernel/skas/util/mk_ptregs.c
29792 ===================================================================
29793 --- linux-2.4.29.orig/arch/um/kernel/skas/util/mk_ptregs.c      1970-01-01 03:00:00.000000000 +0300
29794 +++ linux-2.4.29/arch/um/kernel/skas/util/mk_ptregs.c   2005-05-03 22:28:14.000000000 +0300
29795 @@ -0,0 +1,51 @@
29796 +#include <stdio.h>
29797 +#include <asm/ptrace.h>
29798 +#include <asm/user.h>
29799 +
29800 +#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val))
29801 +
29802 +int main(int argc, char **argv)
29803 +{
29804 +       printf("/* Automatically generated by "
29805 +              "arch/um/kernel/skas/util/mk_ptregs */\n");
29806 +       printf("\n");
29807 +       printf("#ifndef __SKAS_PT_REGS_\n");
29808 +       printf("#define __SKAS_PT_REGS_\n");
29809 +       printf("\n");
29810 +       printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE);
29811 +       printf("#define HOST_FP_SIZE %d\n", 
29812 +              sizeof(struct user_i387_struct) / sizeof(unsigned long));
29813 +       printf("#define HOST_XFP_SIZE %d\n", 
29814 +              sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
29815 +
29816 +       PRINT_REG("IP", EIP);
29817 +       PRINT_REG("SP", UESP);
29818 +       PRINT_REG("EFLAGS", EFL);
29819 +       PRINT_REG("EAX", EAX);
29820 +       PRINT_REG("EBX", EBX);
29821 +       PRINT_REG("ECX", ECX);
29822 +       PRINT_REG("EDX", EDX);
29823 +       PRINT_REG("ESI", ESI);
29824 +       PRINT_REG("EDI", EDI);
29825 +       PRINT_REG("EBP", EBP);
29826 +       PRINT_REG("CS", CS);
29827 +       PRINT_REG("SS", SS);
29828 +       PRINT_REG("DS", DS);
29829 +       PRINT_REG("FS", FS);
29830 +       PRINT_REG("ES", ES);
29831 +       PRINT_REG("GS", GS);
29832 +       printf("\n");
29833 +       printf("#endif\n");
29834 +       return(0);
29835 +}
29836 +
29837 +/*
29838 + * Overrides for Emacs so that we follow Linus's tabbing style.
29839 + * Emacs will notice this stuff at the end of the file and automatically
29840 + * adjust the settings for this buffer only.  This must remain at the end
29841 + * of the file.
29842 + * ---------------------------------------------------------------------------
29843 + * Local variables:
29844 + * c-file-style: "linux"
29845 + * End:
29846 + */
29847 Index: linux-2.4.29/arch/um/kernel/smp.c
29848 ===================================================================
29849 --- linux-2.4.29.orig/arch/um/kernel/smp.c      1970-01-01 03:00:00.000000000 +0300
29850 +++ linux-2.4.29/arch/um/kernel/smp.c   2005-05-03 22:28:14.476409464 +0300
29851 @@ -0,0 +1,329 @@
29852 +/* 
29853 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
29854 + * Licensed under the GPL
29855 + */
29856 +
29857 +#include "linux/config.h"
29858 +
29859 +#ifdef CONFIG_SMP
29860 +
29861 +#include "linux/sched.h"
29862 +#include "linux/threads.h"
29863 +#include "linux/interrupt.h"
29864 +#include "asm/smp.h"
29865 +#include "asm/processor.h"
29866 +#include "asm/spinlock.h"
29867 +#include "asm/softirq.h"
29868 +#include "asm/hardirq.h"
29869 +#include "asm/tlb.h"
29870 +#include "user_util.h"
29871 +#include "kern_util.h"
29872 +#include "irq_user.h"
29873 +#include "kern.h"
29874 +#include "os.h"
29875 +
29876 +/* Total count of live CPUs, set by smp_boot_cpus */
29877 +int smp_num_cpus = 1;
29878 +
29879 +/* The 'big kernel lock' */
29880 +spinlock_cacheline_t kernel_flag_cacheline = {SPIN_LOCK_UNLOCKED};
29881 +
29882 +/* Per CPU bogomips and other parameters */
29883 +
29884 +/* The only piece used here is the ipi pipe, which is set before SMP is
29885 + * started and never changed.
29886 + */
29887 +struct cpuinfo_um cpu_data[NR_CPUS];
29888 +
29889 +/* CPU online map, set by smp_boot_cpus */
29890 +unsigned long cpu_online_map;
29891 +
29892 +atomic_t global_bh_count;
29893 +
29894 +/* Set when the idlers are all forked */
29895 +int smp_threads_ready = 0;
29896 +
29897 +/* Not used by UML */
29898 +unsigned char global_irq_holder = 0;
29899 +unsigned volatile long global_irq_lock;
29900 +
29901 +/* A statistic, can be a little off */
29902 +static int num_reschedules_sent = 0;
29903 +
29904 +mmu_gather_t mmu_gathers[NR_CPUS];
29905 +
29906 +void smp_send_reschedule(int cpu)
29907 +{
29908 +       os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1);
29909 +       num_reschedules_sent++;
29910 +}
29911 +
29912 +static void show(char * str)
29913 +{
29914 +       int cpu = smp_processor_id();
29915 +
29916 +       printk(KERN_INFO "\n%s, CPU %d:\n", str, cpu);
29917 +}
29918 +       
29919 +#define MAXCOUNT 100000000
29920 +
29921 +static inline void wait_on_bh(void)
29922 +{
29923 +       int count = MAXCOUNT;
29924 +       do {
29925 +               if (!--count) {
29926 +                       show("wait_on_bh");
29927 +                       count = ~0;
29928 +               }
29929 +               /* nothing .. wait for the other bh's to go away */
29930 +       } while (atomic_read(&global_bh_count) != 0);
29931 +}
29932 +
29933 +/*
29934 + * This is called when we want to synchronize with
29935 + * bottom half handlers. We need to wait until
29936 + * no other CPU is executing any bottom half handler.
29937 + *
29938 + * Don't wait if we're already running in an interrupt
29939 + * context or are inside a bh handler. 
29940 + */
29941 +void synchronize_bh(void)
29942 +{
29943 +       if (atomic_read(&global_bh_count) && !in_interrupt())
29944 +               wait_on_bh();
29945 +}
29946 +
29947 +void smp_send_stop(void)
29948 +{
29949 +       int i;
29950
29951 +       printk(KERN_INFO "Stopping all CPUs...");
29952 +       for(i = 0; i < ncpus; i++){
29953 +               if(i == current->processor)
29954 +                       continue;
29955 +               os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
29956 +       }
29957 +       printk("done\n");
29958 +}
29959 +
29960 +
29961 +static atomic_t smp_commenced = ATOMIC_INIT(0);
29962 +static volatile unsigned long smp_callin_map = 0;
29963 +
29964 +void smp_commence(void)
29965 +{
29966 +       printk("All CPUs are go!\n");
29967 +
29968 +       wmb();
29969 +       atomic_set(&smp_commenced, 1);
29970 +}
29971 +
29972 +static int idle_proc(void *unused)
29973 +{
29974 +       int cpu, err;
29975 +
29976 +       set_current(current);
29977 +       del_from_runqueue(current);
29978 +       unhash_process(current);
29979 +
29980 +       cpu = current->processor;
29981 +       err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
29982 +       if(err < 0)
29983 +               panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
29984 +
29985 +       activate_ipi(cpu_data[cpu].ipi_pipe[0], 
29986 +                    current->thread.mode.tt.extern_pid);
29987
29988 +       wmb();
29989 +       if (test_and_set_bit(current->processor, &smp_callin_map)) {
29990 +               printk("huh, CPU#%d already present??\n", current->processor);
29991 +               BUG();
29992 +       }
29993 +
29994 +       while (!atomic_read(&smp_commenced))
29995 +               cpu_relax();
29996 +
29997 +       init_idle();
29998 +       cpu_idle();
29999 +       return(0);
30000 +}
30001 +
30002 +static int idle_thread(int (*fn)(void *), int cpu)
30003 +{
30004 +       struct task_struct *new_task;
30005 +       int pid;
30006 +       unsigned char c;
30007 +
30008 +        current->thread.request.u.thread.proc = fn;
30009 +        current->thread.request.u.thread.arg = NULL;
30010 +       pid = do_fork(CLONE_VM | CLONE_PID, 0, NULL, 0);
30011 +       if(pid < 0) 
30012 +               panic("do_fork failed in idle_thread");
30013 +       new_task = get_task(pid, 1);
30014 +
30015 +       cpu_tasks[cpu] = ((struct cpu_task) 
30016 +                         { .pid =      new_task->thread.mode.tt.extern_pid,
30017 +                           .task =     new_task } );
30018 +       init_tasks[cpu] = new_task;
30019 +       new_task->processor = cpu;
30020 +       new_task->cpus_allowed = 1 << cpu;
30021 +       new_task->cpus_runnable = new_task->cpus_allowed;
30022 +       CHOOSE_MODE(({ struct file_handle *pipe;
30023 +                      pipe = new_task->thread.mode.tt.switch_pipe;
30024 +                      write_file(&pipe[1], -1, &c, sizeof(c)); }),
30025 +                   ({ panic("skas mode doesn't support SMP"); }));
30026 +       return(new_task->thread.mode.tt.extern_pid);
30027 +}
30028 +
30029 +void smp_boot_cpus(void)
30030 +{
30031 +       int err;
30032 +
30033 +       set_bit(0, &cpu_online_map);
30034 +       set_bit(0, &smp_callin_map);
30035 +
30036 +       err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
30037 +       if(err < 0) 
30038 +               panic("CPU#0 failed to create IPI pipe, err = %d", -err);
30039 +
30040 +       activate_ipi(cpu_data[0].ipi_pipe[0], 
30041 +                    current->thread.mode.tt.extern_pid);
30042 +
30043 +       if(ncpus < 1){
30044 +               printk(KERN_INFO "ncpus set to 1\n");
30045 +               ncpus = 1;
30046 +       }
30047 +       else if(ncpus > NR_CPUS){
30048 +               printk(KERN_INFO 
30049 +                      "ncpus can't be greater than NR_CPUS, set to %d\n",
30050 +                      NR_CPUS);
30051 +               ncpus = NR_CPUS;
30052 +       }
30053 +
30054 +       if(ncpus > 1){
30055 +               int i, pid;
30056 +
30057 +               printk(KERN_INFO "Starting up other processors:\n");
30058 +               for(i=1;i<ncpus;i++){
30059 +                       int waittime;
30060 +
30061 +                       /* Do this early, for hard_smp_processor_id()  */
30062 +                       cpu_tasks[i].pid = -1;
30063 +                       set_bit(i, &cpu_online_map);
30064 +                       smp_num_cpus++;
30065 +
30066 +                       pid = idle_thread(idle_proc, i);
30067 +                       printk(KERN_INFO "\t#%d - idle thread pid = %d.. ",
30068 +                              i, pid);
30069 +
30070 +                       waittime = 200000000;
30071 +                       while (waittime-- && !test_bit(i, &smp_callin_map))
30072 +                               cpu_relax();
30073 +
30074 +                       if (test_bit(i, &smp_callin_map))
30075 +                               printk("online\n");
30076 +                       else {
30077 +                               printk("failed\n");
30078 +                               clear_bit(i, &cpu_online_map);
30079 +                       }
30080 +               }
30081 +       }
30082 +}
30083 +
30084 +int setup_profiling_timer(unsigned int multiplier)
30085 +{
30086 +       printk(KERN_INFO "setup_profiling_timer\n");
30087 +       return(0);
30088 +}
30089 +
30090 +void smp_call_function_slave(int cpu);
30091 +
30092 +void IPI_handler(int cpu)
30093 +{
30094 +       unsigned char c;
30095 +       int fd;
30096 +
30097 +       fd = cpu_data[cpu].ipi_pipe[0];
30098 +       while (os_read_file(fd, &c, 1) == 1) {
30099 +               switch (c) {
30100 +               case 'C':
30101 +                       smp_call_function_slave(cpu);
30102 +                       break;
30103 +
30104 +               case 'R':
30105 +                       current->need_resched = 1;
30106 +                       break;
30107 +
30108 +               case 'S':
30109 +                       printk("CPU#%d stopping\n", cpu);
30110 +                       while(1)
30111 +                               pause();
30112 +                       break;
30113 +
30114 +               default:
30115 +                       printk("CPU#%d received unknown IPI [%c]!\n", cpu, c);
30116 +                       break;
30117 +               }
30118 +       }
30119 +}
30120 +
30121 +int hard_smp_processor_id(void)
30122 +{
30123 +       return(pid_to_processor_id(os_getpid()));
30124 +}
30125 +
30126 +static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
30127 +static atomic_t scf_started;
30128 +static atomic_t scf_finished;
30129 +static void (*func)(void *info);
30130 +static void *info;
30131 +
30132 +void smp_call_function_slave(int cpu)
30133 +{
30134 +       atomic_inc(&scf_started);
30135 +       (*func)(info);
30136 +       atomic_inc(&scf_finished);
30137 +}
30138 +
30139 +int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, 
30140 +                     int wait)
30141 +{
30142 +       int cpus = smp_num_cpus - 1;
30143 +       int i;
30144 +
30145 +       if (!cpus)
30146 +               return 0;
30147 +
30148 +       spin_lock_bh(&call_lock);
30149 +       atomic_set(&scf_started, 0);
30150 +       atomic_set(&scf_finished, 0);
30151 +       func = _func;
30152 +       info = _info;
30153 +
30154 +       for (i=0;i<NR_CPUS;i++)
30155 +               if (i != current->processor && test_bit(i, &cpu_online_map))
30156 +                       os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
30157 +
30158 +       while (atomic_read(&scf_started) != cpus)
30159 +               barrier();
30160 +
30161 +       if (wait)
30162 +               while (atomic_read(&scf_finished) != cpus)
30163 +                       barrier();
30164 +
30165 +       spin_unlock_bh(&call_lock);
30166 +       return 0;
30167 +}
30168 +
30169 +#endif
30170 +
30171 +/*
30172 + * Overrides for Emacs so that we follow Linus's tabbing style.
30173 + * Emacs will notice this stuff at the end of the file and automatically
30174 + * adjust the settings for this buffer only.  This must remain at the end
30175 + * of the file.
30176 + * ---------------------------------------------------------------------------
30177 + * Local variables:
30178 + * c-file-style: "linux"
30179 + * End:
30180 + */
30181 Index: linux-2.4.29/arch/um/kernel/syscall_kern.c
30182 ===================================================================
30183 --- linux-2.4.29.orig/arch/um/kernel/syscall_kern.c     1970-01-01 03:00:00.000000000 +0300
30184 +++ linux-2.4.29/arch/um/kernel/syscall_kern.c  2005-05-03 22:28:14.477409312 +0300
30185 @@ -0,0 +1,343 @@
30186 +/* 
30187 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
30188 + * Licensed under the GPL
30189 + */
30190 +
30191 +#include "linux/sched.h"
30192 +#include "linux/file.h"
30193 +#include "linux/smp_lock.h"
30194 +#include "linux/mm.h"
30195 +#include "linux/utsname.h"
30196 +#include "linux/msg.h"
30197 +#include "linux/shm.h"
30198 +#include "linux/sys.h"
30199 +#include "linux/unistd.h"
30200 +#include "linux/slab.h"
30201 +#include "linux/utime.h"
30202 +#include "asm/mman.h"
30203 +#include "asm/uaccess.h"
30204 +#include "asm/ipc.h"
30205 +#include "kern_util.h"
30206 +#include "user_util.h"
30207 +#include "sysdep/syscalls.h"
30208 +#include "mode_kern.h"
30209 +#include "choose-mode.h"
30210 +
30211 +/*  Unlocked, I don't care if this is a bit off */
30212 +int nsyscalls = 0;
30213 +
30214 +long um_mount(char * dev_name, char * dir_name, char * type,
30215 +             unsigned long new_flags, void * data)
30216 +{
30217 +       if(type == NULL) type = "";
30218 +       return(sys_mount(dev_name, dir_name, type, new_flags, data));
30219 +}
30220 +
30221 +long sys_fork(void)
30222 +{
30223 +       long ret;
30224 +
30225 +       current->thread.forking = 1;
30226 +        ret = do_fork(SIGCHLD, 0, NULL, 0);
30227 +       current->thread.forking = 0;
30228 +       return(ret);
30229 +}
30230 +
30231 +long sys_clone(unsigned long clone_flags, unsigned long newsp)
30232 +{
30233 +       long ret;
30234 +
30235 +       current->thread.forking = 1;
30236 +       ret = do_fork(clone_flags, newsp, NULL, 0);
30237 +       current->thread.forking = 0;
30238 +       return(ret);
30239 +}
30240 +
30241 +long sys_vfork(void)
30242 +{
30243 +       long ret;
30244 +
30245 +       current->thread.forking = 1;
30246 +       ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0);
30247 +       current->thread.forking = 0;
30248 +       return(ret);
30249 +}
30250 +
30251 +/* common code for old and new mmaps */
30252 +long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
30253 +             unsigned long prot, unsigned long flags, unsigned long fd,
30254 +             unsigned long pgoff)
30255 +{
30256 +       int error = -EBADF;
30257 +       struct file * file = NULL;
30258 +
30259 +       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
30260 +       if (!(flags & MAP_ANONYMOUS)) {
30261 +               file = fget(fd);
30262 +               if (!file)
30263 +                       goto out;
30264 +       }
30265 +
30266 +       down_write(&mm->mmap_sem);
30267 +       error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
30268 +       up_write(&mm->mmap_sem);
30269 +
30270 +       if (file)
30271 +               fput(file);
30272 + out:
30273 +       return error;
30274 +}
30275 +
30276 +long sys_mmap2(unsigned long addr, unsigned long len,
30277 +              unsigned long prot, unsigned long flags,
30278 +              unsigned long fd, unsigned long pgoff)
30279 +{
30280 +       return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
30281 +}
30282 +
30283 +/*
30284 + * Perform the select(nd, in, out, ex, tv) and mmap() system
30285 + * calls. Linux/i386 didn't use to be able to handle more than
30286 + * 4 system call parameters, so these system calls used a memory
30287 + * block for parameter passing..
30288 + */
30289 +
30290 +struct mmap_arg_struct {
30291 +       unsigned long addr;
30292 +       unsigned long len;
30293 +       unsigned long prot;
30294 +       unsigned long flags;
30295 +       unsigned long fd;
30296 +       unsigned long offset;
30297 +};
30298 +
30299 +int old_mmap(unsigned long addr, unsigned long len,
30300 +            unsigned long prot, unsigned long flags,
30301 +            unsigned long fd, unsigned long offset)
30302 +{
30303 +       int err = -EINVAL;
30304 +       if (offset & ~PAGE_MASK)
30305 +               goto out;
30306 +
30307 +       err = do_mmap2(current->mm, addr, len, prot, flags, fd, 
30308 +                      offset >> PAGE_SHIFT);
30309 + out:
30310 +       return err;
30311 +}
30312 +/*
30313 + * sys_pipe() is the normal C calling standard for creating
30314 + * a pipe. It's not the way unix traditionally does this, though.
30315 + */
30316 +int sys_pipe(unsigned long * fildes)
30317 +{
30318 +        int fd[2];
30319 +        int error;
30320 +
30321 +        error = do_pipe(fd);
30322 +        if (!error) {
30323 +               if (copy_to_user(fildes, fd, sizeof(fd)))
30324 +                        error = -EFAULT;
30325 +        }
30326 +        return error;
30327 +}
30328 +
30329 +int sys_pause(void)
30330 +{
30331 +       current->state = TASK_INTERRUPTIBLE;
30332 +       schedule();
30333 +       return -ERESTARTNOHAND;
30334 +}
30335 +
30336 +int sys_sigaction(int sig, const struct old_sigaction *act,
30337 +                        struct old_sigaction *oact)
30338 +{
30339 +       struct k_sigaction new_ka, old_ka;
30340 +       int ret;
30341 +
30342 +       if (act) {
30343 +               old_sigset_t mask;
30344 +               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
30345 +                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
30346 +                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
30347 +                       return -EFAULT;
30348 +               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
30349 +               __get_user(mask, &act->sa_mask);
30350 +               siginitset(&new_ka.sa.sa_mask, mask);
30351 +       }
30352 +
30353 +       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
30354 +
30355 +       if (!ret && oact) {
30356 +               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
30357 +                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
30358 +                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
30359 +                       return -EFAULT;
30360 +               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
30361 +               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
30362 +       }
30363 +
30364 +       return ret;
30365 +}
30366 +
30367 +/*
30368 + * sys_ipc() is the de-multiplexer for the SysV IPC calls..
30369 + *
30370 + * This is really horribly ugly.
30371 + */
30372 +int sys_ipc (uint call, int first, int second,
30373 +            int third, void *ptr, long fifth)
30374 +{
30375 +       int version, ret;
30376 +
30377 +       version = call >> 16; /* hack for backward compatibility */
30378 +       call &= 0xffff;
30379 +
30380 +       switch (call) {
30381 +       case SEMOP:
30382 +               return sys_semop (first, (struct sembuf *)ptr, second);
30383 +       case SEMGET:
30384 +               return sys_semget (first, second, third);
30385 +       case SEMCTL: {
30386 +               union semun fourth;
30387 +               if (!ptr)
30388 +                       return -EINVAL;
30389 +               if (get_user(fourth.__pad, (void **) ptr))
30390 +                       return -EFAULT;
30391 +               return sys_semctl (first, second, third, fourth);
30392 +       }
30393 +
30394 +       case MSGSND:
30395 +               return sys_msgsnd (first, (struct msgbuf *) ptr, 
30396 +                                  second, third);
30397 +       case MSGRCV:
30398 +               switch (version) {
30399 +               case 0: {
30400 +                       struct ipc_kludge tmp;
30401 +                       if (!ptr)
30402 +                               return -EINVAL;
30403 +                       
30404 +                       if (copy_from_user(&tmp,
30405 +                                          (struct ipc_kludge *) ptr, 
30406 +                                          sizeof (tmp)))
30407 +                               return -EFAULT;
30408 +                       return sys_msgrcv (first, tmp.msgp, second,
30409 +                                          tmp.msgtyp, third);
30410 +               }
30411 +               default:
30412 +                       panic("msgrcv with version != 0");
30413 +                       return sys_msgrcv (first,
30414 +                                          (struct msgbuf *) ptr,
30415 +                                          second, fifth, third);
30416 +               }
30417 +       case MSGGET:
30418 +               return sys_msgget ((key_t) first, second);
30419 +       case MSGCTL:
30420 +               return sys_msgctl (first, second, (struct msqid_ds *) ptr);
30421 +
30422 +       case SHMAT:
30423 +               switch (version) {
30424 +               default: {
30425 +                       ulong raddr;
30426 +                       ret = sys_shmat (first, (char *) ptr, second, &raddr);
30427 +                       if (ret)
30428 +                               return ret;
30429 +                       return put_user (raddr, (ulong *) third);
30430 +               }
30431 +               case 1: /* iBCS2 emulator entry point */
30432 +                       if (!segment_eq(get_fs(), get_ds()))
30433 +                               return -EINVAL;
30434 +                       return sys_shmat (first, (char *) ptr, second, (ulong *) third);
30435 +               }
30436 +       case SHMDT: 
30437 +               return sys_shmdt ((char *)ptr);
30438 +       case SHMGET:
30439 +               return sys_shmget (first, second, third);
30440 +       case SHMCTL:
30441 +               return sys_shmctl (first, second,
30442 +                                  (struct shmid_ds *) ptr);
30443 +       default:
30444 +               return -EINVAL;
30445 +       }
30446 +}
30447 +
30448 +int sys_uname(struct old_utsname * name)
30449 +{
30450 +       int err;
30451 +       if (!name)
30452 +               return -EFAULT;
30453 +       down_read(&uts_sem);
30454 +       err=copy_to_user(name, &system_utsname, sizeof (*name));
30455 +       up_read(&uts_sem);
30456 +       return err?-EFAULT:0;
30457 +}
30458 +
30459 +int sys_olduname(struct oldold_utsname * name)
30460 +{
30461 +       int error;
30462 +
30463 +       if (!name)
30464 +               return -EFAULT;
30465 +       if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
30466 +               return -EFAULT;
30467 +  
30468 +       down_read(&uts_sem);
30469 +       
30470 +       error = __copy_to_user(&name->sysname,&system_utsname.sysname,
30471 +                              __OLD_UTS_LEN);
30472 +       error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
30473 +       error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
30474 +                               __OLD_UTS_LEN);
30475 +       error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
30476 +       error |= __copy_to_user(&name->release,&system_utsname.release,
30477 +                               __OLD_UTS_LEN);
30478 +       error |= __put_user(0,name->release+__OLD_UTS_LEN);
30479 +       error |= __copy_to_user(&name->version,&system_utsname.version,
30480 +                               __OLD_UTS_LEN);
30481 +       error |= __put_user(0,name->version+__OLD_UTS_LEN);
30482 +       error |= __copy_to_user(&name->machine,&system_utsname.machine,
30483 +                               __OLD_UTS_LEN);
30484 +       error |= __put_user(0,name->machine+__OLD_UTS_LEN);
30485 +       
30486 +       up_read(&uts_sem);
30487 +       
30488 +       error = error ? -EFAULT : 0;
30489 +
30490 +       return error;
30491 +}
30492 +
30493 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
30494 +{
30495 +       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
30496 +}
30497 +
30498 +long execute_syscall(void *r)
30499 +{
30500 +       return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
30501 +}
30502 +
30503 +spinlock_t syscall_lock = SPIN_LOCK_UNLOCKED;
30504 +
30505 +static int syscall_index = 0;
30506 +
30507 +int next_syscall_index(int limit)
30508 +{
30509 +       int ret;
30510 +
30511 +       spin_lock(&syscall_lock);
30512 +       ret = syscall_index;
30513 +       if(++syscall_index == limit)
30514 +               syscall_index = 0;
30515 +       spin_unlock(&syscall_lock);
30516 +       return(ret);
30517 +}
30518 +
30519 +/*
30520 + * Overrides for Emacs so that we follow Linus's tabbing style.
30521 + * Emacs will notice this stuff at the end of the file and automatically
30522 + * adjust the settings for this buffer only.  This must remain at the end
30523 + * of the file.
30524 + * ---------------------------------------------------------------------------
30525 + * Local variables:
30526 + * c-file-style: "linux"
30527 + * End:
30528 + */
30529 Index: linux-2.4.29/arch/um/kernel/sys_call_table.c
30530 ===================================================================
30531 --- linux-2.4.29.orig/arch/um/kernel/sys_call_table.c   1970-01-01 03:00:00.000000000 +0300
30532 +++ linux-2.4.29/arch/um/kernel/sys_call_table.c        2005-05-03 22:28:14.480408856 +0300
30533 @@ -0,0 +1,496 @@
30534 +/* 
30535 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
30536 + * Licensed under the GPL
30537 + */
30538 +
30539 +#include "linux/unistd.h"
30540 +#include "linux/version.h"
30541 +#include "linux/sys.h"
30542 +#include "asm/signal.h"
30543 +#include "sysdep/syscalls.h"
30544 +#include "kern_util.h"
30545 +
30546 +extern syscall_handler_t sys_ni_syscall;
30547 +extern syscall_handler_t sys_exit;
30548 +extern syscall_handler_t sys_fork;
30549 +extern syscall_handler_t sys_creat;
30550 +extern syscall_handler_t sys_link;
30551 +extern syscall_handler_t sys_unlink;
30552 +extern syscall_handler_t sys_chdir;
30553 +extern syscall_handler_t sys_mknod;
30554 +extern syscall_handler_t sys_chmod;
30555 +extern syscall_handler_t sys_lchown16;
30556 +extern syscall_handler_t sys_ni_syscall;
30557 +extern syscall_handler_t sys_stat;
30558 +extern syscall_handler_t sys_getpid;
30559 +extern syscall_handler_t sys_oldumount;
30560 +extern syscall_handler_t sys_setuid16;
30561 +extern syscall_handler_t sys_getuid16;
30562 +extern syscall_handler_t sys_ptrace;
30563 +extern syscall_handler_t sys_alarm;
30564 +extern syscall_handler_t sys_fstat;
30565 +extern syscall_handler_t sys_pause;
30566 +extern syscall_handler_t sys_utime;
30567 +extern syscall_handler_t sys_ni_syscall;
30568 +extern syscall_handler_t sys_ni_syscall;
30569 +extern syscall_handler_t sys_access;
30570 +extern syscall_handler_t sys_nice;
30571 +extern syscall_handler_t sys_ni_syscall;
30572 +extern syscall_handler_t sys_sync;
30573 +extern syscall_handler_t sys_kill;
30574 +extern syscall_handler_t sys_rename;
30575 +extern syscall_handler_t sys_mkdir;
30576 +extern syscall_handler_t sys_rmdir;
30577 +extern syscall_handler_t sys_pipe;
30578 +extern syscall_handler_t sys_times;
30579 +extern syscall_handler_t sys_ni_syscall;
30580 +extern syscall_handler_t sys_brk;
30581 +extern syscall_handler_t sys_setgid16;
30582 +extern syscall_handler_t sys_getgid16;
30583 +extern syscall_handler_t sys_signal;
30584 +extern syscall_handler_t sys_geteuid16;
30585 +extern syscall_handler_t sys_getegid16;
30586 +extern syscall_handler_t sys_acct;
30587 +extern syscall_handler_t sys_umount;
30588 +extern syscall_handler_t sys_ni_syscall;
30589 +extern syscall_handler_t sys_ioctl;
30590 +extern syscall_handler_t sys_fcntl;
30591 +extern syscall_handler_t sys_ni_syscall;
30592 +extern syscall_handler_t sys_setpgid;
30593 +extern syscall_handler_t sys_ni_syscall;
30594 +extern syscall_handler_t sys_olduname;
30595 +extern syscall_handler_t sys_umask;
30596 +extern syscall_handler_t sys_chroot;
30597 +extern syscall_handler_t sys_ustat;
30598 +extern syscall_handler_t sys_dup2;
30599 +extern syscall_handler_t sys_getppid;
30600 +extern syscall_handler_t sys_getpgrp;
30601 +extern syscall_handler_t sys_sigaction;
30602 +extern syscall_handler_t sys_sgetmask;
30603 +extern syscall_handler_t sys_ssetmask;
30604 +extern syscall_handler_t sys_setreuid16;
30605 +extern syscall_handler_t sys_setregid16;
30606 +extern syscall_handler_t sys_sigsuspend;
30607 +extern syscall_handler_t sys_sigpending;
30608 +extern syscall_handler_t sys_sethostname;
30609 +extern syscall_handler_t sys_setrlimit;
30610 +extern syscall_handler_t sys_old_getrlimit;
30611 +extern syscall_handler_t sys_getrusage;
30612 +extern syscall_handler_t sys_gettimeofday;
30613 +extern syscall_handler_t sys_settimeofday;
30614 +extern syscall_handler_t sys_getgroups16;
30615 +extern syscall_handler_t sys_setgroups16;
30616 +extern syscall_handler_t sys_symlink;
30617 +extern syscall_handler_t sys_lstat;
30618 +extern syscall_handler_t sys_readlink;
30619 +extern syscall_handler_t sys_uselib;
30620 +extern syscall_handler_t sys_swapon;
30621 +extern syscall_handler_t sys_reboot;
30622 +extern syscall_handler_t old_readdir;
30623 +extern syscall_handler_t sys_munmap;
30624 +extern syscall_handler_t sys_truncate;
30625 +extern syscall_handler_t sys_ftruncate;
30626 +extern syscall_handler_t sys_fchmod;
30627 +extern syscall_handler_t sys_fchown16;
30628 +extern syscall_handler_t sys_getpriority;
30629 +extern syscall_handler_t sys_setpriority;
30630 +extern syscall_handler_t sys_ni_syscall;
30631 +extern syscall_handler_t sys_statfs;
30632 +extern syscall_handler_t sys_fstatfs;
30633 +extern syscall_handler_t sys_ni_syscall;
30634 +extern syscall_handler_t sys_socketcall;
30635 +extern syscall_handler_t sys_syslog;
30636 +extern syscall_handler_t sys_setitimer;
30637 +extern syscall_handler_t sys_getitimer;
30638 +extern syscall_handler_t sys_newstat;
30639 +extern syscall_handler_t sys_newlstat;
30640 +extern syscall_handler_t sys_newfstat;
30641 +extern syscall_handler_t sys_uname;
30642 +extern syscall_handler_t sys_ni_syscall;
30643 +extern syscall_handler_t sys_vhangup;
30644 +extern syscall_handler_t sys_ni_syscall;
30645 +extern syscall_handler_t sys_ni_syscall;
30646 +extern syscall_handler_t sys_swapoff;
30647 +extern syscall_handler_t sys_sysinfo;
30648 +extern syscall_handler_t sys_ipc;
30649 +extern syscall_handler_t sys_fsync;
30650 +extern syscall_handler_t sys_sigreturn;
30651 +extern syscall_handler_t sys_rt_sigreturn;
30652 +extern syscall_handler_t sys_clone;
30653 +extern syscall_handler_t sys_setdomainname;
30654 +extern syscall_handler_t sys_newuname;
30655 +extern syscall_handler_t sys_ni_syscall;
30656 +extern syscall_handler_t sys_adjtimex;
30657 +extern syscall_handler_t sys_mprotect;
30658 +extern syscall_handler_t sys_sigprocmask;
30659 +extern syscall_handler_t sys_create_module;
30660 +extern syscall_handler_t sys_init_module;
30661 +extern syscall_handler_t sys_delete_module;
30662 +extern syscall_handler_t sys_get_kernel_syms;
30663 +extern syscall_handler_t sys_quotactl;
30664 +extern syscall_handler_t sys_getpgid;
30665 +extern syscall_handler_t sys_fchdir;
30666 +extern syscall_handler_t sys_bdflush;
30667 +extern syscall_handler_t sys_sysfs;
30668 +extern syscall_handler_t sys_personality;
30669 +extern syscall_handler_t sys_ni_syscall;
30670 +extern syscall_handler_t sys_setfsuid16;
30671 +extern syscall_handler_t sys_setfsgid16;
30672 +extern syscall_handler_t sys_llseek;
30673 +extern syscall_handler_t sys_getdents;
30674 +extern syscall_handler_t sys_flock;
30675 +extern syscall_handler_t sys_msync;
30676 +extern syscall_handler_t sys_readv;
30677 +extern syscall_handler_t sys_writev;
30678 +extern syscall_handler_t sys_getsid;
30679 +extern syscall_handler_t sys_fdatasync;
30680 +extern syscall_handler_t sys_sysctl;
30681 +extern syscall_handler_t sys_mlock;
30682 +extern syscall_handler_t sys_munlock;
30683 +extern syscall_handler_t sys_mlockall;
30684 +extern syscall_handler_t sys_munlockall;
30685 +extern syscall_handler_t sys_sched_setparam;
30686 +extern syscall_handler_t sys_sched_getparam;
30687 +extern syscall_handler_t sys_sched_setscheduler;
30688 +extern syscall_handler_t sys_sched_getscheduler;
30689 +extern syscall_handler_t sys_sched_get_priority_max;
30690 +extern syscall_handler_t sys_sched_get_priority_min;
30691 +extern syscall_handler_t sys_sched_rr_get_interval;
30692 +extern syscall_handler_t sys_nanosleep;
30693 +extern syscall_handler_t sys_mremap;
30694 +extern syscall_handler_t sys_setresuid16;
30695 +extern syscall_handler_t sys_getresuid16;
30696 +extern syscall_handler_t sys_ni_syscall;
30697 +extern syscall_handler_t sys_query_module;
30698 +extern syscall_handler_t sys_poll;
30699 +extern syscall_handler_t sys_nfsservctl;
30700 +extern syscall_handler_t sys_setresgid16;
30701 +extern syscall_handler_t sys_getresgid16;
30702 +extern syscall_handler_t sys_prctl;
30703 +extern syscall_handler_t sys_ni_syscall;
30704 +extern syscall_handler_t sys_rt_sigaction;
30705 +extern syscall_handler_t sys_rt_sigprocmask;
30706 +extern syscall_handler_t sys_rt_sigpending;
30707 +extern syscall_handler_t sys_rt_sigtimedwait;
30708 +extern syscall_handler_t sys_rt_sigqueueinfo;
30709 +extern syscall_handler_t sys_rt_sigsuspend;
30710 +extern syscall_handler_t sys_pread;
30711 +extern syscall_handler_t sys_pwrite;
30712 +extern syscall_handler_t sys_chown16;
30713 +extern syscall_handler_t sys_getcwd;
30714 +extern syscall_handler_t sys_capget;
30715 +extern syscall_handler_t sys_capset;
30716 +extern syscall_handler_t sys_sigaltstack;
30717 +extern syscall_handler_t sys_sendfile;
30718 +extern syscall_handler_t sys_ni_syscall;
30719 +extern syscall_handler_t sys_ni_syscall;
30720 +extern syscall_handler_t sys_vfork;
30721 +extern syscall_handler_t sys_getrlimit;
30722 +extern syscall_handler_t sys_mmap2;
30723 +extern syscall_handler_t sys_truncate64;
30724 +extern syscall_handler_t sys_ftruncate64;
30725 +extern syscall_handler_t sys_stat64;
30726 +extern syscall_handler_t sys_lstat64;
30727 +extern syscall_handler_t sys_fstat64;
30728 +extern syscall_handler_t sys_lchown;
30729 +extern syscall_handler_t sys_getuid;
30730 +extern syscall_handler_t sys_getgid;
30731 +extern syscall_handler_t sys_geteuid;
30732 +extern syscall_handler_t sys_getegid;
30733 +extern syscall_handler_t sys_setreuid;
30734 +extern syscall_handler_t sys_setregid;
30735 +extern syscall_handler_t sys_getgroups;
30736 +extern syscall_handler_t sys_setgroups;
30737 +extern syscall_handler_t sys_fchown;
30738 +extern syscall_handler_t sys_setresuid;
30739 +extern syscall_handler_t sys_getresuid;
30740 +extern syscall_handler_t sys_setresgid;
30741 +extern syscall_handler_t sys_getresgid;
30742 +extern syscall_handler_t sys_chown;
30743 +extern syscall_handler_t sys_setuid;
30744 +extern syscall_handler_t sys_setgid;
30745 +extern syscall_handler_t sys_setfsuid;
30746 +extern syscall_handler_t sys_setfsgid;
30747 +extern syscall_handler_t sys_pivot_root;
30748 +extern syscall_handler_t sys_mincore;
30749 +extern syscall_handler_t sys_madvise;
30750 +extern syscall_handler_t sys_fcntl64;
30751 +extern syscall_handler_t sys_getdents64;
30752 +extern syscall_handler_t sys_gettid;
30753 +extern syscall_handler_t sys_readahead;
30754 +extern syscall_handler_t sys_tkill;
30755 +extern syscall_handler_t sys_setxattr;
30756 +extern syscall_handler_t sys_lsetxattr;
30757 +extern syscall_handler_t sys_fsetxattr;
30758 +extern syscall_handler_t sys_getxattr;
30759 +extern syscall_handler_t sys_lgetxattr;
30760 +extern syscall_handler_t sys_fgetxattr;
30761 +extern syscall_handler_t sys_listxattr;
30762 +extern syscall_handler_t sys_llistxattr;
30763 +extern syscall_handler_t sys_flistxattr;
30764 +extern syscall_handler_t sys_removexattr;
30765 +extern syscall_handler_t sys_lremovexattr;
30766 +extern syscall_handler_t sys_fremovexattr;
30767 +extern syscall_handler_t sys_sendfile64;
30768 +
30769 +extern syscall_handler_t um_mount;
30770 +extern syscall_handler_t um_time;
30771 +extern syscall_handler_t um_stime;
30772 +
30773 +#define LAST_GENERIC_SYSCALL __NR_exit_group
30774 +
30775 +#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
30776 +#define LAST_SYSCALL LAST_GENERIC_SYSCALL
30777 +#else
30778 +#define LAST_SYSCALL LAST_ARCH_SYSCALL
30779 +#endif
30780 +
30781 +syscall_handler_t *sys_call_table[] = {
30782 +       [ 0 ] = sys_ni_syscall,
30783 +       [ __NR_exit ] = sys_exit,
30784 +       [ __NR_fork ] = sys_fork,
30785 +       [ __NR_read ] = (syscall_handler_t *) sys_read,
30786 +       [ __NR_write ] = (syscall_handler_t *) sys_write,
30787 +
30788 +       /* These three are declared differently in asm/unistd.h */
30789 +       [ __NR_open ] = (syscall_handler_t *) sys_open,
30790 +       [ __NR_close ] = (syscall_handler_t *) sys_close,
30791 +       [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid,
30792 +       [ __NR_creat ] = sys_creat,
30793 +       [ __NR_link ] = sys_link,
30794 +       [ __NR_unlink ] = sys_unlink,
30795 +
30796 +       /* declared differently in kern_util.h */
30797 +       [ __NR_execve ] = (syscall_handler_t *) sys_execve,
30798 +       [ __NR_chdir ] = sys_chdir,
30799 +       [ __NR_time ] = um_time,
30800 +       [ __NR_mknod ] = sys_mknod,
30801 +       [ __NR_chmod ] = sys_chmod,
30802 +       [ __NR_lchown ] = sys_lchown16,
30803 +       [ __NR_break ] = sys_ni_syscall,
30804 +       [ __NR_oldstat ] = sys_stat,
30805 +       [ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
30806 +       [ __NR_getpid ] = sys_getpid,
30807 +       [ __NR_mount ] = um_mount,
30808 +       [ __NR_umount ] = sys_oldumount,
30809 +       [ __NR_setuid ] = sys_setuid16,
30810 +       [ __NR_getuid ] = sys_getuid16,
30811 +       [ __NR_stime ] = um_stime,
30812 +       [ __NR_ptrace ] = sys_ptrace,
30813 +       [ __NR_alarm ] = sys_alarm,
30814 +       [ __NR_oldfstat ] = sys_fstat,
30815 +       [ __NR_pause ] = sys_pause,
30816 +       [ __NR_utime ] = sys_utime,
30817 +       [ __NR_stty ] = sys_ni_syscall,
30818 +       [ __NR_gtty ] = sys_ni_syscall,
30819 +       [ __NR_access ] = sys_access,
30820 +       [ __NR_nice ] = sys_nice,
30821 +       [ __NR_ftime ] = sys_ni_syscall,
30822 +       [ __NR_sync ] = sys_sync,
30823 +       [ __NR_kill ] = sys_kill,
30824 +       [ __NR_rename ] = sys_rename,
30825 +       [ __NR_mkdir ] = sys_mkdir,
30826 +       [ __NR_rmdir ] = sys_rmdir,
30827 +
30828 +       /* Declared differently in asm/unistd.h */
30829 +       [ __NR_dup ] = (syscall_handler_t *) sys_dup,
30830 +       [ __NR_pipe ] = sys_pipe,
30831 +       [ __NR_times ] = sys_times,
30832 +       [ __NR_prof ] = sys_ni_syscall,
30833 +       [ __NR_brk ] = sys_brk,
30834 +       [ __NR_setgid ] = sys_setgid16,
30835 +       [ __NR_getgid ] = sys_getgid16,
30836 +       [ __NR_signal ] = sys_signal,
30837 +       [ __NR_geteuid ] = sys_geteuid16,
30838 +       [ __NR_getegid ] = sys_getegid16,
30839 +       [ __NR_acct ] = sys_acct,
30840 +       [ __NR_umount2 ] = sys_umount,
30841 +       [ __NR_lock ] = sys_ni_syscall,
30842 +       [ __NR_ioctl ] = sys_ioctl,
30843 +       [ __NR_fcntl ] = sys_fcntl,
30844 +       [ __NR_mpx ] = sys_ni_syscall,
30845 +       [ __NR_setpgid ] = sys_setpgid,
30846 +       [ __NR_ulimit ] = sys_ni_syscall,
30847 +       [ __NR_oldolduname ] = sys_olduname,
30848 +       [ __NR_umask ] = sys_umask,
30849 +       [ __NR_chroot ] = sys_chroot,
30850 +       [ __NR_ustat ] = sys_ustat,
30851 +       [ __NR_dup2 ] = sys_dup2,
30852 +       [ __NR_getppid ] = sys_getppid,
30853 +       [ __NR_getpgrp ] = sys_getpgrp,
30854 +       [ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
30855 +       [ __NR_sigaction ] = sys_sigaction,
30856 +       [ __NR_sgetmask ] = sys_sgetmask,
30857 +       [ __NR_ssetmask ] = sys_ssetmask,
30858 +       [ __NR_setreuid ] = sys_setreuid16,
30859 +       [ __NR_setregid ] = sys_setregid16,
30860 +       [ __NR_sigsuspend ] = sys_sigsuspend,
30861 +       [ __NR_sigpending ] = sys_sigpending,
30862 +       [ __NR_sethostname ] = sys_sethostname,
30863 +       [ __NR_setrlimit ] = sys_setrlimit,
30864 +       [ __NR_getrlimit ] = sys_old_getrlimit,
30865 +       [ __NR_getrusage ] = sys_getrusage,
30866 +       [ __NR_gettimeofday ] = sys_gettimeofday,
30867 +       [ __NR_settimeofday ] = sys_settimeofday,
30868 +       [ __NR_getgroups ] = sys_getgroups16,
30869 +       [ __NR_setgroups ] = sys_setgroups16,
30870 +       [ __NR_symlink ] = sys_symlink,
30871 +       [ __NR_oldlstat ] = sys_lstat,
30872 +       [ __NR_readlink ] = sys_readlink,
30873 +       [ __NR_uselib ] = sys_uselib,
30874 +       [ __NR_swapon ] = sys_swapon,
30875 +       [ __NR_reboot ] = sys_reboot,
30876 +       [ __NR_readdir ] = old_readdir,
30877 +       [ __NR_munmap ] = sys_munmap,
30878 +       [ __NR_truncate ] = sys_truncate,
30879 +       [ __NR_ftruncate ] = sys_ftruncate,
30880 +       [ __NR_fchmod ] = sys_fchmod,
30881 +       [ __NR_fchown ] = sys_fchown16,
30882 +       [ __NR_getpriority ] = sys_getpriority,
30883 +       [ __NR_setpriority ] = sys_setpriority,
30884 +       [ __NR_profil ] = sys_ni_syscall,
30885 +       [ __NR_statfs ] = sys_statfs,
30886 +       [ __NR_fstatfs ] = sys_fstatfs,
30887 +       [ __NR_ioperm ] = sys_ni_syscall,
30888 +       [ __NR_socketcall ] = sys_socketcall,
30889 +       [ __NR_syslog ] = sys_syslog,
30890 +       [ __NR_setitimer ] = sys_setitimer,
30891 +       [ __NR_getitimer ] = sys_getitimer,
30892 +       [ __NR_stat ] = sys_newstat,
30893 +       [ __NR_lstat ] = sys_newlstat,
30894 +       [ __NR_fstat ] = sys_newfstat,
30895 +       [ __NR_olduname ] = sys_uname,
30896 +       [ __NR_iopl ] = sys_ni_syscall,
30897 +       [ __NR_vhangup ] = sys_vhangup,
30898 +       [ __NR_idle ] = sys_ni_syscall,
30899 +       [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
30900 +       [ __NR_swapoff ] = sys_swapoff,
30901 +       [ __NR_sysinfo ] = sys_sysinfo,
30902 +       [ __NR_ipc ] = sys_ipc,
30903 +       [ __NR_fsync ] = sys_fsync,
30904 +       [ __NR_sigreturn ] = sys_sigreturn,
30905 +       [ __NR_clone ] = sys_clone,
30906 +       [ __NR_setdomainname ] = sys_setdomainname,
30907 +       [ __NR_uname ] = sys_newuname,
30908 +       [ __NR_adjtimex ] = sys_adjtimex,
30909 +       [ __NR_mprotect ] = sys_mprotect,
30910 +       [ __NR_sigprocmask ] = sys_sigprocmask,
30911 +       [ __NR_create_module ] = sys_create_module,
30912 +       [ __NR_init_module ] = sys_init_module,
30913 +       [ __NR_delete_module ] = sys_delete_module,
30914 +       [ __NR_get_kernel_syms ] = sys_get_kernel_syms,
30915 +       [ __NR_quotactl ] = sys_quotactl,
30916 +       [ __NR_getpgid ] = sys_getpgid,
30917 +       [ __NR_fchdir ] = sys_fchdir,
30918 +       [ __NR_bdflush ] = sys_bdflush,
30919 +       [ __NR_sysfs ] = sys_sysfs,
30920 +       [ __NR_personality ] = sys_personality,
30921 +       [ __NR_afs_syscall ] = sys_ni_syscall,
30922 +       [ __NR_setfsuid ] = sys_setfsuid16,
30923 +       [ __NR_setfsgid ] = sys_setfsgid16,
30924 +       [ __NR__llseek ] = sys_llseek,
30925 +       [ __NR_getdents ] = sys_getdents,
30926 +       [ __NR__newselect ] = (syscall_handler_t *) sys_select,
30927 +       [ __NR_flock ] = sys_flock,
30928 +       [ __NR_msync ] = sys_msync,
30929 +       [ __NR_readv ] = sys_readv,
30930 +       [ __NR_writev ] = sys_writev,
30931 +       [ __NR_getsid ] = sys_getsid,
30932 +       [ __NR_fdatasync ] = sys_fdatasync,
30933 +       [ __NR__sysctl ] = sys_sysctl,
30934 +       [ __NR_mlock ] = sys_mlock,
30935 +       [ __NR_munlock ] = sys_munlock,
30936 +       [ __NR_mlockall ] = sys_mlockall,
30937 +       [ __NR_munlockall ] = sys_munlockall,
30938 +       [ __NR_sched_setparam ] = sys_sched_setparam,
30939 +       [ __NR_sched_getparam ] = sys_sched_getparam,
30940 +       [ __NR_sched_setscheduler ] = sys_sched_setscheduler,
30941 +       [ __NR_sched_getscheduler ] = sys_sched_getscheduler,
30942 +       [ __NR_sched_yield ] = (syscall_handler_t *) yield,
30943 +       [ __NR_sched_get_priority_max ] = sys_sched_get_priority_max,
30944 +       [ __NR_sched_get_priority_min ] = sys_sched_get_priority_min,
30945 +       [ __NR_sched_rr_get_interval ] = sys_sched_rr_get_interval,
30946 +       [ __NR_nanosleep ] = sys_nanosleep,
30947 +       [ __NR_mremap ] = sys_mremap,
30948 +       [ __NR_setresuid ] = sys_setresuid16,
30949 +       [ __NR_getresuid ] = sys_getresuid16,
30950 +       [ __NR_vm86 ] = sys_ni_syscall,
30951 +       [ __NR_query_module ] = sys_query_module,
30952 +       [ __NR_poll ] = sys_poll,
30953 +       [ __NR_nfsservctl ] = sys_nfsservctl,
30954 +       [ __NR_setresgid ] = sys_setresgid16,
30955 +       [ __NR_getresgid ] = sys_getresgid16,
30956 +       [ __NR_prctl ] = sys_prctl,
30957 +       [ __NR_rt_sigreturn ] = sys_rt_sigreturn,
30958 +       [ __NR_rt_sigaction ] = sys_rt_sigaction,
30959 +       [ __NR_rt_sigprocmask ] = sys_rt_sigprocmask,
30960 +       [ __NR_rt_sigpending ] = sys_rt_sigpending,
30961 +       [ __NR_rt_sigtimedwait ] = sys_rt_sigtimedwait,
30962 +       [ __NR_rt_sigqueueinfo ] = sys_rt_sigqueueinfo,
30963 +       [ __NR_rt_sigsuspend ] = sys_rt_sigsuspend,
30964 +       [ __NR_pread ] = sys_pread,
30965 +       [ __NR_pwrite ] = sys_pwrite,
30966 +       [ __NR_chown ] = sys_chown16,
30967 +       [ __NR_getcwd ] = sys_getcwd,
30968 +       [ __NR_capget ] = sys_capget,
30969 +       [ __NR_capset ] = sys_capset,
30970 +       [ __NR_sigaltstack ] = sys_sigaltstack,
30971 +       [ __NR_sendfile ] = sys_sendfile,
30972 +       [ __NR_getpmsg ] = sys_ni_syscall,
30973 +       [ __NR_putpmsg ] = sys_ni_syscall,
30974 +       [ __NR_vfork ] = sys_vfork,
30975 +       [ __NR_ugetrlimit ] = sys_getrlimit,
30976 +       [ __NR_mmap2 ] = sys_mmap2,
30977 +       [ __NR_truncate64 ] = sys_truncate64,
30978 +       [ __NR_ftruncate64 ] = sys_ftruncate64,
30979 +       [ __NR_stat64 ] = sys_stat64,
30980 +       [ __NR_lstat64 ] = sys_lstat64,
30981 +       [ __NR_fstat64 ] = sys_fstat64,
30982 +       [ __NR_fcntl64 ] = sys_fcntl64,
30983 +       [ __NR_getdents64 ] = sys_getdents64,
30984 +        [ __NR_security ] = sys_ni_syscall,
30985 +       [ __NR_gettid ] = sys_gettid,
30986 +       [ __NR_readahead ] = sys_readahead,
30987 +       [ __NR_setxattr ] = sys_setxattr,
30988 +       [ __NR_lsetxattr ] = sys_lsetxattr,
30989 +       [ __NR_fsetxattr ] = sys_fsetxattr,
30990 +       [ __NR_getxattr ] = sys_getxattr,
30991 +       [ __NR_lgetxattr ] = sys_lgetxattr,
30992 +       [ __NR_fgetxattr ] = sys_fgetxattr,
30993 +       [ __NR_listxattr ] = sys_listxattr,
30994 +       [ __NR_llistxattr ] = sys_llistxattr,
30995 +       [ __NR_flistxattr ] = sys_flistxattr,
30996 +       [ __NR_removexattr ] = sys_removexattr,
30997 +       [ __NR_lremovexattr ] = sys_lremovexattr,
30998 +       [ __NR_fremovexattr ] = sys_fremovexattr,
30999 +       [ __NR_tkill ] = sys_tkill,
31000 +       [ __NR_sendfile64 ] = sys_sendfile64,
31001 +       [ __NR_futex ] = sys_ni_syscall,
31002 +       [ __NR_sched_setaffinity ] = sys_ni_syscall,
31003 +       [ __NR_sched_getaffinity ] = sys_ni_syscall,
31004 +       [ __NR_set_thread_area ] = sys_ni_syscall,
31005 +       [ __NR_get_thread_area ] = sys_ni_syscall,
31006 +       [ __NR_io_setup ] = sys_ni_syscall,
31007 +       [ __NR_io_destroy ] = sys_ni_syscall,
31008 +       [ __NR_io_getevents ] = sys_ni_syscall,
31009 +       [ __NR_io_submit ] = sys_ni_syscall,
31010 +       [ __NR_io_cancel ] = sys_ni_syscall,
31011 +       [ __NR_alloc_hugepages ] = sys_ni_syscall,
31012 +       [ __NR_free_hugepages ] = sys_ni_syscall,
31013 +       [ __NR_exit_group ] = sys_ni_syscall,
31014 +
31015 +       ARCH_SYSCALLS
31016 +       [ LAST_SYSCALL + 1 ... NR_syscalls ] = 
31017 +               (syscall_handler_t *) sys_ni_syscall
31018 +};
31019 +
31020 +/*
31021 + * Overrides for Emacs so that we follow Linus's tabbing style.
31022 + * Emacs will notice this stuff at the end of the file and automatically
31023 + * adjust the settings for this buffer only.  This must remain at the end
31024 + * of the file.
31025 + * ---------------------------------------------------------------------------
31026 + * Local variables:
31027 + * c-file-style: "linux"
31028 + * End:
31029 + */
31030 Index: linux-2.4.29/arch/um/kernel/syscall_user.c
31031 ===================================================================
31032 --- linux-2.4.29.orig/arch/um/kernel/syscall_user.c     1970-01-01 03:00:00.000000000 +0300
31033 +++ linux-2.4.29/arch/um/kernel/syscall_user.c  2005-05-03 22:28:14.481408704 +0300
31034 @@ -0,0 +1,48 @@
31035 +/* 
31036 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
31037 + * Licensed under the GPL
31038 + */
31039 +
31040 +#include <stdlib.h>
31041 +#include <sys/time.h>
31042 +#include "kern_util.h"
31043 +#include "syscall_user.h"
31044 +
31045 +struct {
31046 +       int syscall;
31047 +       int pid;
31048 +       int result;
31049 +       struct timeval start;
31050 +       struct timeval end;
31051 +} syscall_record[1024];
31052 +
31053 +int record_syscall_start(int syscall)
31054 +{
31055 +       int max, index;
31056 +
31057 +       max = sizeof(syscall_record)/sizeof(syscall_record[0]);
31058 +       index = next_syscall_index(max);
31059 +
31060 +       syscall_record[index].syscall = syscall;
31061 +       syscall_record[index].pid = current_pid();
31062 +       syscall_record[index].result = 0xdeadbeef;
31063 +       gettimeofday(&syscall_record[index].start, NULL);
31064 +       return(index);
31065 +}
31066 +
31067 +void record_syscall_end(int index, int result)
31068 +{
31069 +       syscall_record[index].result = result;
31070 +       gettimeofday(&syscall_record[index].end, NULL);
31071 +}
31072 +
31073 +/*
31074 + * Overrides for Emacs so that we follow Linus's tabbing style.
31075 + * Emacs will notice this stuff at the end of the file and automatically
31076 + * adjust the settings for this buffer only.  This must remain at the end
31077 + * of the file.
31078 + * ---------------------------------------------------------------------------
31079 + * Local variables:
31080 + * c-file-style: "linux"
31081 + * End:
31082 + */
31083 Index: linux-2.4.29/arch/um/kernel/sysrq.c
31084 ===================================================================
31085 --- linux-2.4.29.orig/arch/um/kernel/sysrq.c    1970-01-01 03:00:00.000000000 +0300
31086 +++ linux-2.4.29/arch/um/kernel/sysrq.c 2005-05-03 22:28:14.482408552 +0300
31087 @@ -0,0 +1,98 @@
31088 +/* 
31089 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
31090 + * Licensed under the GPL
31091 + */
31092 +
31093 +#include "linux/sched.h"
31094 +#include "linux/kernel.h"
31095 +#include "linux/module.h"
31096 +#include "asm/page.h"
31097 +#include "asm/processor.h"
31098 +#include "sysrq.h"
31099 +#include "user_util.h"
31100 +
31101 + /*
31102 +  * If the address is either in the .text section of the
31103 +  * kernel, or in the vmalloc'ed module regions, it *may* 
31104 +  * be the address of a calling routine
31105 +  */
31106
31107 +#ifdef CONFIG_MODULES
31108 +
31109 +extern struct module *module_list;
31110 +extern struct module kernel_module;
31111 +
31112 +static inline int kernel_text_address(unsigned long addr)
31113 +{
31114 +       int retval = 0;
31115 +       struct module *mod;
31116 +
31117 +       if (addr >= (unsigned long) &_stext &&
31118 +           addr <= (unsigned long) &_etext)
31119 +               return 1;
31120 +
31121 +       for (mod = module_list; mod != &kernel_module; mod = mod->next) {
31122 +               /* mod_bound tests for addr being inside the vmalloc'ed
31123 +                * module area. Of course it'd be better to test only
31124 +                * for the .text subset... */
31125 +               if (mod_bound(addr, 0, mod)) {
31126 +                       retval = 1;
31127 +                       break;
31128 +               }
31129 +       }
31130 +
31131 +       return retval;
31132 +}
31133 +
31134 +#else
31135 +
31136 +static inline int kernel_text_address(unsigned long addr)
31137 +{
31138 +       return (addr >= (unsigned long) &_stext &&
31139 +               addr <= (unsigned long) &_etext);
31140 +}
31141 +
31142 +#endif
31143 +
31144 +void show_trace(unsigned long * stack)
31145 +{
31146 +        int i;
31147 +        unsigned long addr;
31148 +
31149 +        if (!stack)
31150 +                stack = (unsigned long*) &stack;
31151 +
31152 +        printk("Call Trace: ");
31153 +        i = 1;
31154 +        while (((long) stack & (THREAD_SIZE-1)) != 0) {
31155 +                addr = *stack++;
31156 +               if (kernel_text_address(addr)) {
31157 +                       if (i && ((i % 6) == 0))
31158 +                               printk("\n   ");
31159 +                       printk("[<%08lx>] ", addr);
31160 +                       i++;
31161 +                }
31162 +        }
31163 +        printk("\n");
31164 +}
31165 +
31166 +void show_trace_task(struct task_struct *tsk)
31167 +{
31168 +       unsigned long esp = PT_REGS_SP(&tsk->thread.regs);
31169 +
31170 +       /* User space on another CPU? */
31171 +       if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
31172 +               return;
31173 +       show_trace((unsigned long *)esp);
31174 +}
31175 +
31176 +/*
31177 + * Overrides for Emacs so that we follow Linus's tabbing style.
31178 + * Emacs will notice this stuff at the end of the file and automatically
31179 + * adjust the settings for this buffer only.  This must remain at the end
31180 + * of the file.
31181 + * ---------------------------------------------------------------------------
31182 + * Local variables:
31183 + * c-file-style: "linux"
31184 + * End:
31185 + */
31186 Index: linux-2.4.29/arch/um/kernel/tempfile.c
31187 ===================================================================
31188 --- linux-2.4.29.orig/arch/um/kernel/tempfile.c 1970-01-01 03:00:00.000000000 +0300
31189 +++ linux-2.4.29/arch/um/kernel/tempfile.c      2005-05-03 22:28:14.483408400 +0300
31190 @@ -0,0 +1,82 @@
31191 +/*
31192 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
31193 + * Licensed under the GPL
31194 + */
31195 +
31196 +#include <stdio.h>
31197 +#include <stdlib.h>
31198 +#include <unistd.h>
31199 +#include <string.h>
31200 +#include <errno.h>
31201 +#include <sys/param.h>
31202 +#include "init.h"
31203 +
31204 +/* Modified from create_mem_file and start_debugger */
31205 +static char *tempdir = NULL;
31206 +
31207 +static void __init find_tempdir(void)
31208 +{
31209 +       char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
31210 +       int i;
31211 +       char *dir = NULL;
31212 +
31213 +       if(tempdir != NULL) return;     /* We've already been called */
31214 +       for(i = 0; dirs[i]; i++){
31215 +               dir = getenv(dirs[i]);
31216 +               if((dir != NULL) && (*dir != '\0'))
31217 +                       break;
31218 +       }
31219 +       if((dir == NULL) || (*dir == '\0')) 
31220 +               dir = "/tmp";
31221 +
31222 +       tempdir = malloc(strlen(dir) + 2);
31223 +       if(tempdir == NULL){
31224 +               fprintf(stderr, "Failed to malloc tempdir, "
31225 +                       "errno = %d\n", errno);
31226 +               return;
31227 +       }
31228 +       strcpy(tempdir, dir);
31229 +       strcat(tempdir, "/");
31230 +}
31231 +
31232 +int make_tempfile(const char *template, char **out_tempname, int do_unlink)
31233 +{
31234 +       char tempname[MAXPATHLEN];
31235 +       int fd;
31236 +
31237 +       find_tempdir();
31238 +       if (*template != '/')
31239 +               strcpy(tempname, tempdir);
31240 +       else
31241 +               *tempname = 0;
31242 +       strcat(tempname, template);
31243 +       fd = mkstemp(tempname);
31244 +       if(fd < 0){
31245 +               fprintf(stderr, "open - cannot create %s: %s\n", tempname, 
31246 +                       strerror(errno));
31247 +               return -1;
31248 +       }
31249 +       if(do_unlink && (unlink(tempname) < 0)){
31250 +               perror("unlink");
31251 +               return -1;
31252 +       }
31253 +       if(out_tempname){
31254 +               *out_tempname = strdup(tempname);
31255 +               if(*out_tempname == NULL){
31256 +                       perror("strdup");
31257 +                       return -1;
31258 +               }
31259 +       }
31260 +       return(fd);
31261 +}
31262 +
31263 +/*
31264 + * Overrides for Emacs so that we follow Linus's tabbing style.
31265 + * Emacs will notice this stuff at the end of the file and automatically
31266 + * adjust the settings for this buffer only.  This must remain at the end
31267 + * of the file.
31268 + * ---------------------------------------------------------------------------
31269 + * Local variables:
31270 + * c-file-style: "linux"
31271 + * End:
31272 + */
31273 Index: linux-2.4.29/arch/um/kernel/time.c
31274 ===================================================================
31275 --- linux-2.4.29.orig/arch/um/kernel/time.c     1970-01-01 03:00:00.000000000 +0300
31276 +++ linux-2.4.29/arch/um/kernel/time.c  2005-05-03 22:28:14.484408248 +0300
31277 @@ -0,0 +1,144 @@
31278 +/* 
31279 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
31280 + * Licensed under the GPL
31281 + */
31282 +
31283 +#include <stdio.h>
31284 +#include <stdlib.h>
31285 +#include <unistd.h>
31286 +#include <time.h>
31287 +#include <sys/time.h>
31288 +#include <signal.h>
31289 +#include <errno.h>
31290 +#include "user_util.h"
31291 +#include "kern_util.h"
31292 +#include "user.h"
31293 +#include "process.h"
31294 +#include "signal_user.h"
31295 +#include "time_user.h"
31296 +
31297 +extern struct timeval xtime;
31298 +
31299 +struct timeval local_offset = { 0, 0 };
31300 +
31301 +void timer(void)
31302 +{
31303 +       gettimeofday(&xtime, NULL);
31304 +       timeradd(&xtime, &local_offset, &xtime);
31305 +}
31306 +
31307 +void set_interval(int timer_type)
31308 +{
31309 +       int usec = 1000000/hz();
31310 +       struct itimerval interval = ((struct itimerval) { { 0, usec },
31311 +                                                         { 0, usec } });
31312 +
31313 +       if(setitimer(timer_type, &interval, NULL) == -1)
31314 +               panic("setitimer failed - errno = %d\n", errno);
31315 +}
31316 +
31317 +void enable_timer(void)
31318 +{
31319 +       int usec = 1000000/hz();
31320 +       struct itimerval enable = ((struct itimerval) { { 0, usec },
31321 +                                                       { 0, usec }});
31322 +       if(setitimer(ITIMER_VIRTUAL, &enable, NULL))
31323 +               printk("enable_timer - setitimer failed, errno = %d\n",
31324 +                      errno);
31325 +}
31326 +
31327 +void disable_timer(void)
31328 +{
31329 +       struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
31330 +       if((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) ||
31331 +          (setitimer(ITIMER_REAL, &disable, NULL) < 0))
31332 +               printk("disnable_timer - setitimer failed, errno = %d\n",
31333 +                      errno);
31334 +}
31335 +
31336 +void switch_timers(int to_real)
31337 +{
31338 +       struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
31339 +       struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
31340 +                                                       { 0, 1000000/hz() }});
31341 +       int old, new;
31342 +
31343 +       if(to_real){
31344 +               old = ITIMER_VIRTUAL;
31345 +               new = ITIMER_REAL;
31346 +       }
31347 +       else {
31348 +               old = ITIMER_REAL;
31349 +               new = ITIMER_VIRTUAL;
31350 +       }
31351 +
31352 +       if((setitimer(old, &disable, NULL) < 0) ||
31353 +          (setitimer(new, &enable, NULL)))
31354 +               printk("switch_timers - setitimer failed, errno = %d\n",
31355 +                      errno);
31356 +}
31357 +
31358 +void idle_timer(void)
31359 +{
31360 +       if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
31361 +               panic("Couldn't unset SIGVTALRM handler");
31362 +       
31363 +       set_handler(SIGALRM, (__sighandler_t) alarm_handler, 
31364 +                   SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
31365 +       set_interval(ITIMER_REAL);
31366 +}
31367 +
31368 +void time_init(void)
31369 +{
31370 +       /* XXX This is to fill xtime with something real - otherwise by the
31371 +        * time /proc is mounted, no timers have fired, and xtime is still 0,
31372 +        * meaning it shows times of Jan 1 1970.  The real fix is to figure
31373 +        * out why no timers have happened by then.
31374 +        */
31375 +       timer();
31376 +
31377 +       if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
31378 +               panic("Couldn't set SIGVTALRM handler");
31379 +       set_interval(ITIMER_VIRTUAL);
31380 +}
31381 +
31382 +void do_gettimeofday(struct timeval *tv)
31383 +{
31384 +       unsigned long flags;
31385 +
31386 +       flags = time_lock();
31387 +       gettimeofday(tv, NULL);
31388 +       timeradd(tv, &local_offset, tv);
31389 +       time_unlock(flags);
31390 +}
31391 +
31392 +void do_settimeofday(struct timeval *tv)
31393 +{
31394 +       struct timeval now;
31395 +       unsigned long flags;
31396 +
31397 +       flags = time_lock();
31398 +       gettimeofday(&now, NULL);
31399 +       timersub(tv, &now, &local_offset);
31400 +       time_unlock(flags);
31401 +}
31402 +
31403 +void idle_sleep(int secs)
31404 +{
31405 +       struct timespec ts;
31406 +
31407 +       ts.tv_sec = secs;
31408 +       ts.tv_nsec = 0;
31409 +       nanosleep(&ts, NULL);
31410 +}
31411 +
31412 +/*
31413 + * Overrides for Emacs so that we follow Linus's tabbing style.
31414 + * Emacs will notice this stuff at the end of the file and automatically
31415 + * adjust the settings for this buffer only.  This must remain at the end
31416 + * of the file.
31417 + * ---------------------------------------------------------------------------
31418 + * Local variables:
31419 + * c-file-style: "linux"
31420 + * End:
31421 + */
31422 Index: linux-2.4.29/arch/um/kernel/time_kern.c
31423 ===================================================================
31424 --- linux-2.4.29.orig/arch/um/kernel/time_kern.c        1970-01-01 03:00:00.000000000 +0300
31425 +++ linux-2.4.29/arch/um/kernel/time_kern.c     2005-05-03 22:28:14.485408096 +0300
31426 @@ -0,0 +1,209 @@
31427 +/* 
31428 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
31429 + * Licensed under the GPL
31430 + */
31431 +
31432 +#include "linux/kernel.h"
31433 +#include "linux/unistd.h"
31434 +#include "linux/stddef.h"
31435 +#include "linux/spinlock.h"
31436 +#include "linux/sched.h"
31437 +#include "linux/interrupt.h"
31438 +#include "linux/init.h"
31439 +#include "linux/delay.h"
31440 +#include "asm/irq.h"
31441 +#include "asm/param.h"
31442 +#include "asm/current.h"
31443 +#include "kern_util.h"
31444 +#include "user_util.h"
31445 +#include "time_user.h"
31446 +#include "mode.h"
31447 +#include "os.h"
31448 +
31449 +extern rwlock_t xtime_lock;
31450 +
31451 +int hz(void)
31452 +{
31453 +       return(HZ);
31454 +}
31455 +
31456 +/* Changed at early boot */
31457 +int timer_irq_inited = 0;
31458 +
31459 +/* missed_ticks will be modified after kernel memory has been 
31460 + * write-protected, so this puts it in a section which will be left 
31461 + * write-enabled.
31462 + */
31463 +int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
31464 +
31465 +static int first_tick;
31466 +static unsigned long long prev_usecs;
31467 +static long long delta;                /* Deviation per interval */
31468 +
31469 +#define MILLION 1000000
31470 +
31471 +void timer_irq(union uml_pt_regs *regs)
31472 +{
31473 +       unsigned long long ticks = 0;
31474 +
31475 +       if(!timer_irq_inited){
31476 +               /* This is to ensure that ticks don't pile up when
31477 +                * the timer handler is suspended */
31478 +               first_tick = 0;
31479 +               return;
31480 +       }
31481 +
31482 +       if(first_tick){
31483 +#if defined(CONFIG_UML_REAL_TIME_CLOCK)
31484 +               /* We've had 1 tick */
31485 +               unsigned long long usecs = os_usecs();
31486 +
31487 +               delta += usecs - prev_usecs;
31488 +               prev_usecs = usecs;
31489 +
31490 +               /* Protect against the host clock being set backwards */
31491 +               if(delta < 0)
31492 +                       delta = 0;
31493 +
31494 +               ticks += (delta * HZ) / MILLION;
31495 +               delta -= (ticks * MILLION) / HZ;
31496 +#else
31497 +               ticks = 1;
31498 +#endif
31499 +       }
31500 +       else {
31501 +               prev_usecs = os_usecs();
31502 +               first_tick = 1;
31503 +       }
31504 +
31505 +       while(ticks > 0){
31506 +               do_IRQ(TIMER_IRQ, regs);
31507 +               ticks--;
31508 +       }
31509 +}
31510 +
31511 +void boot_timer_handler(int sig)
31512 +{
31513 +       struct pt_regs regs;
31514 +
31515 +       CHOOSE_MODE((void) 
31516 +                   (UPT_SC(&regs.regs) = (struct sigcontext *) (&sig + 1)),
31517 +                   (void) (regs.regs.skas.is_user = 0));
31518 +       do_timer(&regs);
31519 +}
31520 +
31521 +void um_timer(int irq, void *dev, struct pt_regs *regs)
31522 +{
31523 +       do_timer(regs);
31524 +       write_lock(&xtime_lock);
31525 +       vxtime_lock();
31526 +       timer();
31527 +       vxtime_unlock();
31528 +       write_unlock(&xtime_lock);
31529 +}
31530 +
31531 +long um_time(int * tloc)
31532 +{
31533 +       struct timeval now;
31534 +
31535 +       do_gettimeofday(&now);
31536 +       if (tloc) {
31537 +               if (put_user(now.tv_sec,tloc))
31538 +                       now.tv_sec = -EFAULT;
31539 +       }
31540 +       return now.tv_sec;
31541 +}
31542 +
31543 +long um_stime(int * tptr)
31544 +{
31545 +       int value;
31546 +       struct timeval new;
31547 +
31548 +       if (get_user(value, tptr))
31549 +                return -EFAULT;
31550 +       new.tv_sec = value;
31551 +       new.tv_usec = 0;
31552 +       do_settimeofday(&new);
31553 +       return 0;
31554 +}
31555 +
31556 +/* XXX Needs to be moved under sys-i386 */
31557 +void __delay(um_udelay_t time)
31558 +{
31559 +       /* Stolen from the i386 __loop_delay */
31560 +       int d0;
31561 +       __asm__ __volatile__(
31562 +               "\tjmp 1f\n"
31563 +               ".align 16\n"
31564 +               "1:\tjmp 2f\n"
31565 +               ".align 16\n"
31566 +               "2:\tdecl %0\n\tjns 2b"
31567 +               :"=&a" (d0)
31568 +               :"0" (time));
31569 +}
31570 +
31571 +void __udelay(um_udelay_t usecs)
31572 +{
31573 +       int i, n;
31574 +
31575 +       n = (loops_per_jiffy * HZ * usecs) / MILLION;
31576 +       for(i=0;i<n;i++) ;
31577 +}
31578 +
31579 +void __const_udelay(um_udelay_t usecs)
31580 +{
31581 +       int i, n;
31582 +
31583 +       n = (loops_per_jiffy * HZ * usecs) / MILLION;
31584 +       for(i=0;i<n;i++) ;
31585 +}
31586 +
31587 +void timer_handler(int sig, union uml_pt_regs *regs)
31588 +{
31589 +#ifdef CONFIG_SMP
31590 +       update_process_times(user_context(UPT_SP(regs)));
31591 +#endif
31592 +       if(current->processor == 0)
31593 +               timer_irq(regs);
31594 +}
31595 +
31596 +static spinlock_t timer_spinlock = SPIN_LOCK_UNLOCKED;
31597 +
31598 +unsigned long time_lock(void)
31599 +{
31600 +       unsigned long flags;
31601 +
31602 +       spin_lock_irqsave(&timer_spinlock, flags);
31603 +       return(flags);
31604 +}
31605 +
31606 +void time_unlock(unsigned long flags)
31607 +{
31608 +       spin_unlock_irqrestore(&timer_spinlock, flags);
31609 +}
31610 +
31611 +int __init timer_init(void)
31612 +{
31613 +       int err;
31614 +
31615 +       CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
31616 +       err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
31617 +       if(err != 0)
31618 +               printk(KERN_ERR "timer_init : request_irq failed - "
31619 +                      "errno = %d\n", -err);
31620 +       timer_irq_inited = 1;
31621 +       return(0);
31622 +}
31623 +
31624 +__initcall(timer_init);
31625 +
31626 +/*
31627 + * Overrides for Emacs so that we follow Linus's tabbing style.
31628 + * Emacs will notice this stuff at the end of the file and automatically
31629 + * adjust the settings for this buffer only.  This must remain at the end
31630 + * of the file.
31631 + * ---------------------------------------------------------------------------
31632 + * Local variables:
31633 + * c-file-style: "linux"
31634 + * End:
31635 + */
31636 Index: linux-2.4.29/arch/um/kernel/tlb.c
31637 ===================================================================
31638 --- linux-2.4.29.orig/arch/um/kernel/tlb.c      1970-01-01 03:00:00.000000000 +0300
31639 +++ linux-2.4.29/arch/um/kernel/tlb.c   2005-05-03 22:28:14.486407944 +0300
31640 @@ -0,0 +1,80 @@
31641 +/* 
31642 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
31643 + * Licensed under the GPL
31644 + */
31645 +
31646 +#include "linux/mm.h"
31647 +#include "asm/page.h"
31648 +#include "asm/pgalloc.h"
31649 +#include "choose-mode.h"
31650 +#include "mode_kern.h"
31651 +
31652 +void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
31653 +{
31654 +       address &= PAGE_MASK;
31655 +       flush_tlb_range(vma->vm_mm, address, address + PAGE_SIZE);
31656 +}
31657 +
31658 +void flush_tlb_all(void)
31659 +{
31660 +       flush_tlb_mm(current->mm);
31661 +}
31662 +
31663 +void flush_tlb_kernel_vm(void)
31664 +{
31665 +       CHOOSE_MODE(flush_tlb_kernel_vm_tt(), flush_tlb_kernel_vm_skas());
31666 +}
31667 +
31668 +void __flush_tlb_one(unsigned long addr)
31669 +{
31670 +       CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
31671 +}
31672 +
31673 +void flush_tlb_range(struct mm_struct *mm, unsigned long start, 
31674 +                    unsigned long end)
31675 +{
31676 +       CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, mm, start, 
31677 +                        end);
31678 +}
31679 +
31680 +void flush_tlb_mm(struct mm_struct *mm)
31681 +{
31682 +       CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
31683 +}
31684 +
31685 +void force_flush_all(void)
31686 +{
31687 +       CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
31688 +}
31689 +
31690 +
31691 +pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
31692 +{
31693 +       return(pgd_offset(mm, address));
31694 +}
31695 +
31696 +pmd_t *pmd_offset_proc(pgd_t *pgd, unsigned long address)
31697 +{
31698 +       return(pmd_offset(pgd, address));
31699 +}
31700 +
31701 +pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
31702 +{
31703 +       return(pte_offset(pmd, address));
31704 +}
31705 +
31706 +pte_t *addr_pte(struct task_struct *task, unsigned long addr)
31707 +{
31708 +       return(pte_offset(pmd_offset(pgd_offset(task->mm, addr), addr), addr));
31709 +}
31710 +
31711 +/*
31712 + * Overrides for Emacs so that we follow Linus's tabbing style.
31713 + * Emacs will notice this stuff at the end of the file and automatically
31714 + * adjust the settings for this buffer only.  This must remain at the end
31715 + * of the file.
31716 + * ---------------------------------------------------------------------------
31717 + * Local variables:
31718 + * c-file-style: "linux"
31719 + * End:
31720 + */
31721 Index: linux-2.4.29/arch/um/kernel/trap_kern.c
31722 ===================================================================
31723 --- linux-2.4.29.orig/arch/um/kernel/trap_kern.c        1970-01-01 03:00:00.000000000 +0300
31724 +++ linux-2.4.29/arch/um/kernel/trap_kern.c     2005-05-03 22:28:14.487407792 +0300
31725 @@ -0,0 +1,220 @@
31726 +/* 
31727 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
31728 + * Licensed under the GPL
31729 + */
31730 +
31731 +#include "linux/kernel.h"
31732 +#include "linux/sched.h"
31733 +#include "linux/mm.h"
31734 +#include "linux/spinlock.h"
31735 +#include "linux/config.h"
31736 +#include "linux/init.h"
31737 +#include "asm/semaphore.h"
31738 +#include "asm/pgtable.h"
31739 +#include "asm/pgalloc.h"
31740 +#include "asm/a.out.h"
31741 +#include "asm/current.h"
31742 +#include "asm/irq.h"
31743 +#include "user_util.h"
31744 +#include "kern_util.h"
31745 +#include "kern.h"
31746 +#include "chan_kern.h"
31747 +#include "mconsole_kern.h"
31748 +#include "2_5compat.h"
31749 +#include "mem.h"
31750 +#include "mem_kern.h"
31751 +
31752 +unsigned long handle_page_fault(unsigned long address, unsigned long ip, 
31753 +                               int is_write, int is_user, int *code_out)
31754 +{
31755 +       struct mm_struct *mm = current->mm;
31756 +       struct vm_area_struct *vma;
31757 +       pgd_t *pgd;
31758 +       pmd_t *pmd;
31759 +       pte_t *pte;
31760 +       unsigned long page;
31761 +       int handled = 0;
31762 +
31763 +       *code_out = SEGV_MAPERR;
31764 +       down_read(&mm->mmap_sem);
31765 +       vma = find_vma(mm, address);
31766 +       if(!vma) 
31767 +               goto out;
31768 +       else if(vma->vm_start <= address) 
31769 +               goto good_area;
31770 +       else if(!(vma->vm_flags & VM_GROWSDOWN)) 
31771 +               goto out;
31772 +       else if(expand_stack(vma, address)) 
31773 +               goto out;
31774 +
31775 + good_area:
31776 +       *code_out = SEGV_ACCERR;
31777 +       if(is_write && !(vma->vm_flags & VM_WRITE)) 
31778 +               goto out;
31779 +       page = address & PAGE_MASK;
31780 +       if(page == (unsigned long) current + PAGE_SIZE)
31781 +               panic("Kernel stack overflow");
31782 +       pgd = pgd_offset(mm, page);
31783 +       pmd = pmd_offset(pgd, page);
31784 +       do {
31785 + survive:
31786 +               switch (handle_mm_fault(mm, vma, address, is_write)) {
31787 +               case 1:
31788 +                       current->min_flt++;
31789 +                       break;
31790 +               case 2:
31791 +                       current->maj_flt++;
31792 +                       break;
31793 +               default:
31794 +                       if (current->pid == 1) {
31795 +                               up_read(&mm->mmap_sem);
31796 +                               yield();
31797 +                               down_read(&mm->mmap_sem);
31798 +                               goto survive;
31799 +                       }
31800 +                       /* Fall through to bad area case */
31801 +               case 0:
31802 +                       goto out;
31803 +               }
31804 +               pte = pte_offset(pmd, page);
31805 +       } while(!pte_present(*pte));
31806 +       handled = 1;
31807 +       *pte = pte_mkyoung(*pte);
31808 +       if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
31809 +       flush_tlb_page(vma, page);
31810 + out:
31811 +       up_read(&mm->mmap_sem);
31812 +       return(handled);
31813 +}
31814 +
31815 +LIST_HEAD(physmem_remappers);
31816 +
31817 +void register_remapper(struct remapper *info)
31818 +{
31819 +       list_add(&info->list, &physmem_remappers);
31820 +}
31821 +
31822 +static int check_remapped_addr(unsigned long address, int is_write, int is_user)
31823 +{
31824 +       struct remapper *remapper;
31825 +       struct list_head *ele;
31826 +       __u64 offset;
31827 +       int fd;
31828 +
31829 +       fd = phys_mapping(__pa(address), &offset);
31830 +       if(fd == -1)
31831 +               return(0);
31832 +
31833 +       list_for_each(ele, &physmem_remappers){
31834 +               remapper = list_entry(ele, struct remapper, list);
31835 +               if((*remapper->proc)(fd, address, is_write, offset, is_user))
31836 +                       return(1);
31837 +       }
31838 +
31839 +       return(0);
31840 +}
31841 +
31842 +unsigned long segv(unsigned long address, unsigned long ip, int is_write, 
31843 +                  int is_user, void *sc)
31844 +{
31845 +       struct siginfo si;
31846 +       void *catcher;
31847 +       int handled;
31848 +
31849 +        if(!is_user && (address >= start_vm) && (address < end_vm)){
31850 +                flush_tlb_kernel_vm();
31851 +                return(0);
31852 +        }
31853 +       else if(check_remapped_addr(address & PAGE_MASK, is_write, is_user))
31854 +               return(0);
31855 +       else if(current->mm == NULL)
31856 +               panic("Segfault with no mm");
31857 +
31858 +       handled = handle_page_fault(address, ip, is_write, is_user, 
31859 +                                   &si.si_code);
31860 +
31861 +       catcher = current->thread.fault_catcher;
31862 +       if(handled)
31863 +               return(0);
31864 +       else if(catcher != NULL){
31865 +               current->thread.fault_addr = (void *) address;
31866 +               do_longjmp(catcher, 1);
31867 +       } 
31868 +       else if(current->thread.fault_addr != NULL)
31869 +               panic("fault_addr set but no fault catcher");
31870 +       else if(arch_fixup(ip, sc))
31871 +               return(0);
31872 +
31873 +       if(!is_user) 
31874 +               panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", 
31875 +                     address, ip);
31876 +       si.si_signo = SIGSEGV;
31877 +       si.si_addr = (void *) address;
31878 +       current->thread.cr2 = address;
31879 +       current->thread.err = is_write;
31880 +       force_sig_info(SIGSEGV, &si, current);
31881 +       return(0);
31882 +}
31883 +
31884 +void bad_segv(unsigned long address, unsigned long ip, int is_write)
31885 +{
31886 +       struct siginfo si;
31887 +
31888 +       si.si_signo = SIGSEGV;
31889 +       si.si_code = SEGV_ACCERR;
31890 +       si.si_addr = (void *) address;
31891 +       current->thread.cr2 = address;
31892 +       current->thread.err = is_write;
31893 +       force_sig_info(SIGSEGV, &si, current);
31894 +}
31895 +
31896 +void relay_signal(int sig, union uml_pt_regs *regs)
31897 +{
31898 +       if(arch_handle_signal(sig, regs)) return;
31899 +       if(!UPT_IS_USER(regs))
31900 +               panic("Kernel mode signal %d", sig);
31901 +       force_sig(sig, current);
31902 +}
31903 +
31904 +void bus_handler(int sig, union uml_pt_regs *regs)
31905 +{
31906 +       if(current->thread.fault_catcher != NULL)
31907 +               do_longjmp(current->thread.fault_catcher, 1);
31908 +       else relay_signal(sig, regs);
31909 +}
31910 +
31911 +void winch(int sig, union uml_pt_regs *regs)
31912 +{
31913 +       do_IRQ(WINCH_IRQ, regs);
31914 +}
31915 +
31916 +void trap_init(void)
31917 +{
31918 +}
31919 +
31920 +spinlock_t trap_lock = SPIN_LOCK_UNLOCKED;
31921 +
31922 +static int trap_index = 0;
31923 +
31924 +int next_trap_index(int limit)
31925 +{
31926 +       int ret;
31927 +
31928 +       spin_lock(&trap_lock);
31929 +       ret = trap_index;
31930 +       if(++trap_index == limit)
31931 +               trap_index = 0;
31932 +       spin_unlock(&trap_lock);
31933 +       return(ret);
31934 +}
31935 +
31936 +/*
31937 + * Overrides for Emacs so that we follow Linus's tabbing style.
31938 + * Emacs will notice this stuff at the end of the file and automatically
31939 + * adjust the settings for this buffer only.  This must remain at the end
31940 + * of the file.
31941 + * ---------------------------------------------------------------------------
31942 + * Local variables:
31943 + * c-file-style: "linux"
31944 + * End:
31945 + */
31946 Index: linux-2.4.29/arch/um/kernel/trap_user.c
31947 ===================================================================
31948 --- linux-2.4.29.orig/arch/um/kernel/trap_user.c        1970-01-01 03:00:00.000000000 +0300
31949 +++ linux-2.4.29/arch/um/kernel/trap_user.c     2005-05-03 22:28:14.489407488 +0300
31950 @@ -0,0 +1,145 @@
31951 +/* 
31952 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
31953 + * Licensed under the GPL
31954 + */
31955 +
31956 +#include <stdlib.h>
31957 +#include <errno.h>
31958 +#include <setjmp.h>
31959 +#include <signal.h>
31960 +#include <sys/time.h>
31961 +#include <sys/ptrace.h>
31962 +#include <sys/wait.h>
31963 +#include <asm/page.h>
31964 +#include <asm/unistd.h>
31965 +#include <asm/ptrace.h>
31966 +#include "init.h"
31967 +#include "sysdep/ptrace.h"
31968 +#include "sigcontext.h"
31969 +#include "sysdep/sigcontext.h"
31970 +#include "irq_user.h"
31971 +#include "frame_user.h"
31972 +#include "signal_user.h"
31973 +#include "time_user.h"
31974 +#include "task.h"
31975 +#include "mode.h"
31976 +#include "choose-mode.h"
31977 +#include "kern_util.h"
31978 +#include "user_util.h"
31979 +#include "os.h"
31980 +
31981 +void kill_child_dead(int pid)
31982 +{
31983 +       kill(pid, SIGKILL);
31984 +       kill(pid, SIGCONT);
31985 +       do {
31986 +               int n;
31987 +               CATCH_EINTR(n = waitpid(pid, NULL, 0));
31988 +               if (n > 0)
31989 +                       kill(pid, SIGCONT);
31990 +               else
31991 +                       break;
31992 +       } while(1);
31993 +}
31994 +
31995 +/* Unlocked - don't care if this is a bit off */
31996 +int nsegfaults = 0;
31997 +
31998 +struct {
31999 +       unsigned long address;
32000 +       int is_write;
32001 +       int pid;
32002 +       unsigned long sp;
32003 +       int is_user;
32004 +} segfault_record[1024];
32005 +
32006 +void segv_handler(int sig, union uml_pt_regs *regs)
32007 +{
32008 +       int index, max;
32009 +
32010 +       if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){
32011 +               bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), 
32012 +                        UPT_FAULT_WRITE(regs));
32013 +               return;
32014 +       }
32015 +       max = sizeof(segfault_record)/sizeof(segfault_record[0]);
32016 +       index = next_trap_index(max);
32017 +
32018 +       nsegfaults++;
32019 +       segfault_record[index].address = UPT_FAULT_ADDR(regs);
32020 +       segfault_record[index].pid = os_getpid();
32021 +       segfault_record[index].is_write = UPT_FAULT_WRITE(regs);
32022 +       segfault_record[index].sp = UPT_SP(regs);
32023 +       segfault_record[index].is_user = UPT_IS_USER(regs);
32024 +       segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs),
32025 +            UPT_IS_USER(regs), regs);
32026 +}
32027 +
32028 +void usr2_handler(int sig, union uml_pt_regs *regs)
32029 +{
32030 +       CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
32031 +}
32032 +
32033 +struct signal_info sig_info[] = {
32034 +       [ SIGTRAP ] { .handler          = relay_signal,
32035 +                     .is_irq           = 0 },
32036 +       [ SIGFPE ] { .handler           = relay_signal,
32037 +                    .is_irq            = 0 },
32038 +       [ SIGILL ] { .handler           = relay_signal,
32039 +                    .is_irq            = 0 },
32040 +       [ SIGWINCH ] { .handler         = winch,
32041 +                      .is_irq          = 1 },
32042 +       [ SIGBUS ] { .handler           = bus_handler,
32043 +                    .is_irq            = 0 },
32044 +       [ SIGSEGV] { .handler           = segv_handler,
32045 +                    .is_irq            = 0 },
32046 +       [ SIGIO ] { .handler            = sigio_handler,
32047 +                   .is_irq             = 1 },
32048 +       [ SIGVTALRM ] { .handler        = timer_handler,
32049 +                       .is_irq         = 1 },
32050 +        [ SIGALRM ] { .handler          = timer_handler,
32051 +                      .is_irq           = 1 },
32052 +       [ SIGUSR2 ] { .handler          = usr2_handler,
32053 +                     .is_irq           = 0 },
32054 +};
32055 +
32056 +void sig_handler(int sig, struct sigcontext sc)
32057 +{
32058 +       CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
32059 +                        sig, &sc);
32060 +}
32061 +
32062 +extern int timer_irq_inited, missed_ticks[];
32063 +
32064 +void alarm_handler(int sig, struct sigcontext sc)
32065 +{
32066 +       if(!timer_irq_inited) return;
32067 +       missed_ticks[cpu()]++;
32068 +
32069 +       if(sig == SIGALRM)
32070 +               switch_timers(0);
32071 +
32072 +       CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
32073 +                        sig, &sc);
32074 +
32075 +       if(sig == SIGALRM)
32076 +               switch_timers(1);
32077 +}
32078 +
32079 +void do_longjmp(void *b, int val)
32080 +{
32081 +       sigjmp_buf *buf = b;
32082 +
32083 +       siglongjmp(*buf, val);
32084 +}
32085 +
32086 +/*
32087 + * Overrides for Emacs so that we follow Linus's tabbing style.
32088 + * Emacs will notice this stuff at the end of the file and automatically
32089 + * adjust the settings for this buffer only.  This must remain at the end
32090 + * of the file.
32091 + * ---------------------------------------------------------------------------
32092 + * Local variables:
32093 + * c-file-style: "linux"
32094 + * End:
32095 + */
32096 Index: linux-2.4.29/arch/um/kernel/tt/exec_kern.c
32097 ===================================================================
32098 --- linux-2.4.29.orig/arch/um/kernel/tt/exec_kern.c     1970-01-01 03:00:00.000000000 +0300
32099 +++ linux-2.4.29/arch/um/kernel/tt/exec_kern.c  2005-05-03 22:28:14.490407336 +0300
32100 @@ -0,0 +1,86 @@
32101 +/* 
32102 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32103 + * Licensed under the GPL
32104 + */
32105 +
32106 +#include "linux/kernel.h"
32107 +#include "linux/mm.h"
32108 +#include "asm/signal.h"
32109 +#include "asm/ptrace.h"
32110 +#include "asm/uaccess.h"
32111 +#include "asm/pgalloc.h"
32112 +#include "user_util.h"
32113 +#include "kern_util.h"
32114 +#include "irq_user.h"
32115 +#include "time_user.h"
32116 +#include "mem_user.h"
32117 +#include "signal_user.h"
32118 +#include "os.h"
32119 +#include "tlb.h"
32120 +#include "mode.h"
32121 +
32122 +static int exec_tramp(void *sig_stack)
32123 +{
32124 +       init_new_thread_stack(sig_stack, NULL);
32125 +       init_new_thread_signals(1);
32126 +       os_stop_process(os_getpid());
32127 +       return(0);
32128 +}
32129 +
32130 +void flush_thread_tt(void)
32131 +{
32132 +       unsigned long stack;
32133 +       int new_pid;
32134 +
32135 +       stack = alloc_stack(0, 0);
32136 +       if(stack == 0){
32137 +               printk(KERN_ERR 
32138 +                      "flush_thread : failed to allocate temporary stack\n");
32139 +               do_exit(SIGKILL);
32140 +       }
32141 +               
32142 +       new_pid = start_fork_tramp(current, stack, 0, exec_tramp);
32143 +       if(new_pid < 0){
32144 +               printk(KERN_ERR 
32145 +                      "flush_thread : new thread failed, errno = %d\n",
32146 +                      -new_pid);
32147 +               do_exit(SIGKILL);
32148 +       }
32149 +
32150 +       if(current->processor == 0)
32151 +               forward_interrupts(new_pid);
32152 +       current->thread.request.op = OP_EXEC;
32153 +       current->thread.request.u.exec.pid = new_pid;
32154 +       unprotect_stack((unsigned long) current);
32155 +       os_usr1_process(os_getpid());
32156 +       change_sig(SIGUSR1, 1);
32157 +
32158 +       change_sig(SIGUSR1, 0);
32159 +       enable_timer();
32160 +       free_page(stack);
32161 +       protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
32162 +       task_protections((unsigned long) current);
32163 +       force_flush_all();
32164 +       unblock_signals();
32165 +}
32166 +
32167 +void start_thread_tt(struct pt_regs *regs, unsigned long eip, 
32168 +                    unsigned long esp)
32169 +{
32170 +       set_fs(USER_DS);
32171 +       flush_tlb_mm(current->mm);
32172 +       PT_REGS_IP(regs) = eip;
32173 +       PT_REGS_SP(regs) = esp;
32174 +       PT_FIX_EXEC_STACK(esp);
32175 +}
32176 +
32177 +/*
32178 + * Overrides for Emacs so that we follow Linus's tabbing style.
32179 + * Emacs will notice this stuff at the end of the file and automatically
32180 + * adjust the settings for this buffer only.  This must remain at the end
32181 + * of the file.
32182 + * ---------------------------------------------------------------------------
32183 + * Local variables:
32184 + * c-file-style: "linux"
32185 + * End:
32186 + */
32187 Index: linux-2.4.29/arch/um/kernel/tt/exec_user.c
32188 ===================================================================
32189 --- linux-2.4.29.orig/arch/um/kernel/tt/exec_user.c     1970-01-01 03:00:00.000000000 +0300
32190 +++ linux-2.4.29/arch/um/kernel/tt/exec_user.c  2005-05-03 22:28:14.491407184 +0300
32191 @@ -0,0 +1,54 @@
32192 +/* 
32193 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
32194 + * Licensed under the GPL
32195 + */
32196 +
32197 +#include <stdio.h>
32198 +#include <unistd.h>
32199 +#include <stdlib.h>
32200 +#include <sched.h>
32201 +#include <errno.h>
32202 +#include <sys/wait.h>
32203 +#include <sys/ptrace.h>
32204 +#include <signal.h>
32205 +#include "user_util.h"
32206 +#include "kern_util.h"
32207 +#include "user.h"
32208 +#include "ptrace_user.h"
32209 +
32210 +void do_exec(int old_pid, int new_pid)
32211 +{
32212 +       unsigned long regs[FRAME_SIZE];
32213 +       int err;
32214 +
32215 +       if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) ||
32216 +          (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0))
32217 +               tracer_panic("do_exec failed to attach proc - errno = %d",
32218 +                            errno);
32219 +
32220 +       CATCH_EINTR(err = waitpid(new_pid, 0, WUNTRACED));
32221 +       if (err < 0)
32222 +               tracer_panic("do_exec failed to attach proc in waitpid - errno = %d",
32223 +                            errno);
32224 +
32225 +       if(ptrace_getregs(old_pid, regs) < 0)
32226 +               tracer_panic("do_exec failed to get registers - errno = %d",
32227 +                            errno);
32228 +
32229 +       kill(old_pid, SIGKILL);
32230 +
32231 +       if(ptrace_setregs(new_pid, regs) < 0)
32232 +               tracer_panic("do_exec failed to start new proc - errno = %d",
32233 +                            errno);
32234 +}
32235 +
32236 +/*
32237 + * Overrides for Emacs so that we follow Linus's tabbing style.
32238 + * Emacs will notice this stuff at the end of the file and automatically
32239 + * adjust the settings for this buffer only.  This must remain at the end
32240 + * of the file.
32241 + * ---------------------------------------------------------------------------
32242 + * Local variables:
32243 + * c-file-style: "linux"
32244 + * End:
32245 + */
32246 Index: linux-2.4.29/arch/um/kernel/tt/gdb.c
32247 ===================================================================
32248 --- linux-2.4.29.orig/arch/um/kernel/tt/gdb.c   1970-01-01 03:00:00.000000000 +0300
32249 +++ linux-2.4.29/arch/um/kernel/tt/gdb.c        2005-05-03 22:28:14.492407032 +0300
32250 @@ -0,0 +1,278 @@
32251 +/* 
32252 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32253 + * Licensed under the GPL
32254 + */
32255 +
32256 +#include <stdio.h>
32257 +#include <stdlib.h>
32258 +#include <errno.h>
32259 +#include <string.h>
32260 +#include <signal.h>
32261 +#include <sys/ptrace.h>
32262 +#include <sys/types.h>
32263 +#include "uml-config.h"
32264 +#include "kern_constants.h"
32265 +#include "chan_user.h"
32266 +#include "init.h"
32267 +#include "user.h"
32268 +#include "debug.h"
32269 +#include "kern_util.h"
32270 +#include "user_util.h"
32271 +#include "tt.h"
32272 +#include "sysdep/thread.h"
32273 +
32274 +extern int debugger_pid;
32275 +extern int debugger_fd;
32276 +extern int debugger_parent;
32277 +
32278 +int detach(int pid, int sig)
32279 +{
32280 +       return(ptrace(PTRACE_DETACH, pid, 0, sig));
32281 +}
32282 +
32283 +int attach(int pid)
32284 +{
32285 +       int err;
32286 +
32287 +       err = ptrace(PTRACE_ATTACH, pid, 0, 0);
32288 +       if(err < 0) return(-errno);
32289 +       else return(err);
32290 +}
32291 +
32292 +int cont(int pid)
32293 +{
32294 +       return(ptrace(PTRACE_CONT, pid, 0, 0));
32295 +}
32296 +
32297 +#ifdef UML_CONFIG_PT_PROXY
32298 +
32299 +int debugger_signal(int status, pid_t pid)
32300 +{
32301 +       return(debugger_proxy(status, pid));
32302 +}
32303 +
32304 +void child_signal(pid_t pid, int status)
32305 +{
32306 +       child_proxy(pid, status);
32307 +}
32308 +
32309 +static void gdb_announce(char *dev_name, int dev)
32310 +{
32311 +       printf("gdb assigned device '%s'\n", dev_name);
32312 +}
32313 +
32314 +static struct chan_opts opts = {
32315 +       .announce       = gdb_announce,
32316 +       .xterm_title    = "UML kernel debugger",
32317 +       .raw            = 0,
32318 +       .tramp_stack    = 0,
32319 +       .in_kernel      = 0,
32320 +};
32321 +
32322 +/* Accessed by the tracing thread, which automatically serializes access */
32323 +static void *xterm_data;
32324 +static int xterm_fd;
32325 +
32326 +extern void *xterm_init(char *, int, struct chan_opts *);
32327 +extern int xterm_open(int, int, int, void *, char **);
32328 +extern void xterm_close(int, void *);
32329 +
32330 +int open_gdb_chan(void)
32331 +{
32332 +       char stack[UM_KERN_PAGE_SIZE], *dummy;
32333 +
32334 +       opts.tramp_stack = (unsigned long) stack;
32335 +       xterm_data = xterm_init("", 0, &opts);
32336 +       xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy);
32337 +       return(xterm_fd);
32338 +}
32339 +
32340 +static void exit_debugger_cb(void *unused)
32341 +{
32342 +       if(debugger_pid != -1){
32343 +               if(gdb_pid != -1){
32344 +                       fake_child_exit();
32345 +                       gdb_pid = -1;
32346 +               }
32347 +               else kill_child_dead(debugger_pid);
32348 +               debugger_pid = -1;
32349 +               if(debugger_parent != -1)
32350 +                       detach(debugger_parent, SIGINT);
32351 +       }
32352 +       if(xterm_data != NULL) xterm_close(xterm_fd, xterm_data);
32353 +}
32354 +
32355 +static void exit_debugger(void)
32356 +{
32357 +       initial_thread_cb(exit_debugger_cb, NULL);
32358 +}
32359 +
32360 +__uml_exitcall(exit_debugger);
32361 +
32362 +struct gdb_data {
32363 +       char *str;
32364 +       int err;
32365 +};
32366 +
32367 +static void config_gdb_cb(void *arg)
32368 +{
32369 +       struct gdb_data *data = arg;
32370 +       void *task;
32371 +       int pid;
32372 +
32373 +       data->err = -1;
32374 +       if(debugger_pid != -1) exit_debugger_cb(NULL);
32375 +       if(!strncmp(data->str, "pid,", strlen("pid,"))){
32376 +               data->str += strlen("pid,");
32377 +               pid = strtoul(data->str, NULL, 0);
32378 +               task = cpu_tasks[0].task;
32379 +               debugger_pid = attach_debugger(TASK_EXTERN_PID(task), pid, 0);
32380 +               if(debugger_pid != -1){
32381 +                       data->err = 0;
32382 +                       gdb_pid = pid;
32383 +               }
32384 +               return;
32385 +       }
32386 +       data->err = 0;
32387 +       debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
32388 +       init_proxy(debugger_pid, 0, 0);
32389 +}
32390 +
32391 +int gdb_config(char *str)
32392 +{
32393 +       struct gdb_data data;
32394 +
32395 +       if(*str++ != '=') return(-1);
32396 +       data.str = str;
32397 +       initial_thread_cb(config_gdb_cb, &data);
32398 +       return(data.err);
32399 +}
32400 +
32401 +void remove_gdb_cb(void *unused)
32402 +{
32403 +       exit_debugger_cb(NULL);
32404 +}
32405 +
32406 +int gdb_remove(char *unused)
32407 +{
32408 +       initial_thread_cb(remove_gdb_cb, NULL);
32409 +       return(0);
32410 +}
32411 +
32412 +void signal_usr1(int sig)
32413 +{
32414 +       if(debugger_pid != -1){
32415 +               printk(UM_KERN_ERR "The debugger is already running\n");
32416 +               return;
32417 +       }
32418 +       debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
32419 +       init_proxy(debugger_pid, 0, 0);
32420 +}
32421 +
32422 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
32423 +{
32424 +       int pid, status;
32425 +
32426 +       pid = start_debugger(linux_prog, startup, stop, &debugger_fd);
32427 +       status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
32428 +       if(pid < 0){
32429 +               cont(idle_pid);
32430 +               return(-1);
32431 +       }
32432 +       init_proxy(pid, 1, status);
32433 +       return(pid);
32434 +}
32435 +
32436 +int attach_debugger(int idle_pid, int pid, int stop)
32437 +{
32438 +       int status = 0, err;
32439 +
32440 +       err = attach(pid);
32441 +       if(err < 0){
32442 +               printf("Failed to attach pid %d, errno = %d\n", pid, -err);
32443 +               return(-1);
32444 +       }
32445 +       if(stop) status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
32446 +       init_proxy(pid, 1, status);
32447 +       return(pid);
32448 +}
32449 +
32450 +#ifdef notdef /* Put this back in when it does something useful */
32451 +static int __init uml_gdb_init_setup(char *line, int *add)
32452 +{
32453 +       gdb_init = uml_strdup(line);
32454 +       return 0;
32455 +}
32456 +
32457 +__uml_setup("gdb=", uml_gdb_init_setup, 
32458 +"gdb=<channel description>\n\n"
32459 +);
32460 +#endif
32461 +
32462 +static int __init uml_gdb_pid_setup(char *line, int *add)
32463 +{
32464 +       gdb_pid = strtoul(line, NULL, 0);
32465 +       *add = 0;
32466 +       return 0;
32467 +}
32468 +
32469 +__uml_setup("gdb-pid=", uml_gdb_pid_setup, 
32470 +"gdb-pid=<pid>\n"
32471 +"    gdb-pid is used to attach an external debugger to UML.  This may be\n"
32472 +"    an already-running gdb or a debugger-like process like strace.\n\n"
32473 +);
32474 +
32475 +#else
32476 +
32477 +int debugger_signal(int status, pid_t pid){ return(0); }
32478 +void child_signal(pid_t pid, int status){ }
32479 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
32480 +{
32481 +       printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
32482 +       kill_child_dead(idle_pid);
32483 +       exit(1);
32484 +}
32485 +
32486 +void signal_usr1(int sig)
32487 +{
32488 +       printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
32489 +}
32490 +
32491 +int attach_debugger(int idle_pid, int pid, int stop)
32492 +{
32493 +       printk(UM_KERN_ERR "attach_debugger called when CONFIG_PT_PROXY "
32494 +              "is off\n");
32495 +       return(-1);
32496 +}
32497 +
32498 +int config_gdb(char *str)
32499 +{
32500 +       return(-1);
32501 +}
32502 +
32503 +int remove_gdb(void)
32504 +{
32505 +       return(-1);
32506 +}
32507 +
32508 +int init_parent_proxy(int pid)
32509 +{
32510 +       return(-1);
32511 +}
32512 +
32513 +void debugger_parent_signal(int status, int pid)
32514 +{
32515 +}
32516 +
32517 +#endif
32518 +
32519 +/*
32520 + * Overrides for Emacs so that we follow Linus's tabbing style.
32521 + * Emacs will notice this stuff at the end of the file and automatically
32522 + * adjust the settings for this buffer only.  This must remain at the end
32523 + * of the file.
32524 + * ---------------------------------------------------------------------------
32525 + * Local variables:
32526 + * c-file-style: "linux"
32527 + * End:
32528 + */
32529 Index: linux-2.4.29/arch/um/kernel/tt/gdb_kern.c
32530 ===================================================================
32531 --- linux-2.4.29.orig/arch/um/kernel/tt/gdb_kern.c      1970-01-01 03:00:00.000000000 +0300
32532 +++ linux-2.4.29/arch/um/kernel/tt/gdb_kern.c   2005-05-03 22:28:14.493406880 +0300
32533 @@ -0,0 +1,40 @@
32534 +/* 
32535 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32536 + * Licensed under the GPL
32537 + */
32538 +
32539 +#include "linux/init.h"
32540 +#include "linux/config.h"
32541 +#include "mconsole_kern.h"
32542 +
32543 +#ifdef CONFIG_MCONSOLE
32544 +
32545 +extern int gdb_config(char *str);
32546 +extern int gdb_remove(char *unused);
32547 +
32548 +static struct mc_device gdb_mc = {
32549 +       .name           = "gdb",
32550 +       .config         = gdb_config,
32551 +       .remove         = gdb_remove,
32552 +};
32553 +
32554 +int gdb_mc_init(void)
32555 +{
32556 +       mconsole_register_dev(&gdb_mc);
32557 +       return(0);
32558 +}
32559 +
32560 +__initcall(gdb_mc_init);
32561 +
32562 +#endif
32563 +
32564 +/*
32565 + * Overrides for Emacs so that we follow Linus's tabbing style.
32566 + * Emacs will notice this stuff at the end of the file and automatically
32567 + * adjust the settings for this buffer only.  This must remain at the end
32568 + * of the file.
32569 + * ---------------------------------------------------------------------------
32570 + * Local variables:
32571 + * c-file-style: "linux"
32572 + * End:
32573 + */
32574 Index: linux-2.4.29/arch/um/kernel/tt/include/debug.h
32575 ===================================================================
32576 --- linux-2.4.29.orig/arch/um/kernel/tt/include/debug.h 1970-01-01 03:00:00.000000000 +0300
32577 +++ linux-2.4.29/arch/um/kernel/tt/include/debug.h      2005-05-03 22:28:14.494406728 +0300
32578 @@ -0,0 +1,29 @@
32579 +/* 
32580 + * Copyright (C) 2000, 2001, 2002  Jeff Dike (jdike@karaya.com) and
32581 + * Lars Brinkhoff.
32582 + * Licensed under the GPL
32583 + */
32584 +
32585 +#ifndef __DEBUG_H
32586 +#define __DEBUG_H
32587 +
32588 +extern int debugger_proxy(int status, pid_t pid);
32589 +extern void child_proxy(pid_t pid, int status);
32590 +extern void init_proxy (pid_t pid, int waiting, int status);
32591 +extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
32592 +extern void fake_child_exit(void);
32593 +extern int gdb_config(char *str);
32594 +extern int gdb_remove(char *unused);
32595 +
32596 +#endif
32597 +
32598 +/*
32599 + * Overrides for Emacs so that we follow Linus's tabbing style.
32600 + * Emacs will notice this stuff at the end of the file and automatically
32601 + * adjust the settings for this buffer only.  This must remain at the end
32602 + * of the file.
32603 + * ---------------------------------------------------------------------------
32604 + * Local variables:
32605 + * c-file-style: "linux"
32606 + * End:
32607 + */
32608 Index: linux-2.4.29/arch/um/kernel/tt/include/mmu.h
32609 ===================================================================
32610 --- linux-2.4.29.orig/arch/um/kernel/tt/include/mmu.h   1970-01-01 03:00:00.000000000 +0300
32611 +++ linux-2.4.29/arch/um/kernel/tt/include/mmu.h        2005-05-03 22:28:14.495406576 +0300
32612 @@ -0,0 +1,23 @@
32613 +/* 
32614 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32615 + * Licensed under the GPL
32616 + */
32617 +
32618 +#ifndef __TT_MMU_H
32619 +#define __TT_MMU_H
32620 +
32621 +struct mmu_context_tt {
32622 +};
32623 +
32624 +#endif
32625 +
32626 +/*
32627 + * Overrides for Emacs so that we follow Linus's tabbing style.
32628 + * Emacs will notice this stuff at the end of the file and automatically
32629 + * adjust the settings for this buffer only.  This must remain at the end
32630 + * of the file.
32631 + * ---------------------------------------------------------------------------
32632 + * Local variables:
32633 + * c-file-style: "linux"
32634 + * End:
32635 + */
32636 Index: linux-2.4.29/arch/um/kernel/tt/include/mode.h
32637 ===================================================================
32638 --- linux-2.4.29.orig/arch/um/kernel/tt/include/mode.h  1970-01-01 03:00:00.000000000 +0300
32639 +++ linux-2.4.29/arch/um/kernel/tt/include/mode.h       2005-05-03 22:28:14.496406424 +0300
32640 @@ -0,0 +1,38 @@
32641 +/* 
32642 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32643 + * Licensed under the GPL
32644 + */
32645 +
32646 +#ifndef __MODE_TT_H__
32647 +#define __MODE_TT_H__
32648 +
32649 +#include "sysdep/ptrace.h"
32650 +
32651 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
32652 +
32653 +extern int tracing_pid;
32654 +
32655 +extern int tracer(int (*init_proc)(void *), void *sp);
32656 +extern void user_time_init_tt(void);
32657 +extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data);
32658 +extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, 
32659 +                             void *data);
32660 +extern void sig_handler_common_tt(int sig, void *sc);
32661 +extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
32662 +extern void reboot_tt(void);
32663 +extern void halt_tt(void);
32664 +extern int is_tracer_winch(int pid, int fd, void *data);
32665 +extern void kill_off_processes_tt(void);
32666 +
32667 +#endif
32668 +
32669 +/*
32670 + * Overrides for Emacs so that we follow Linus's tabbing style.
32671 + * Emacs will notice this stuff at the end of the file and automatically
32672 + * adjust the settings for this buffer only.  This must remain at the end
32673 + * of the file.
32674 + * ---------------------------------------------------------------------------
32675 + * Local variables:
32676 + * c-file-style: "linux"
32677 + * End:
32678 + */
32679 Index: linux-2.4.29/arch/um/kernel/tt/include/mode_kern.h
32680 ===================================================================
32681 --- linux-2.4.29.orig/arch/um/kernel/tt/include/mode_kern.h     1970-01-01 03:00:00.000000000 +0300
32682 +++ linux-2.4.29/arch/um/kernel/tt/include/mode_kern.h  2005-05-03 22:28:14.496406424 +0300
32683 @@ -0,0 +1,52 @@
32684 +/* 
32685 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32686 + * Licensed under the GPL
32687 + */
32688 +
32689 +#ifndef __TT_MODE_KERN_H__
32690 +#define __TT_MODE_KERN_H__
32691 +
32692 +#include "linux/sched.h"
32693 +#include "asm/page.h"
32694 +#include "asm/ptrace.h"
32695 +#include "asm/uaccess.h"
32696 +
32697 +extern void *_switch_to_tt(void *prev, void *next);
32698 +extern void flush_thread_tt(void);
32699 +extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, 
32700 +                          unsigned long esp);
32701 +extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
32702 +                         unsigned long stack_top, struct task_struct *p, 
32703 +                         struct pt_regs *regs);
32704 +extern void release_thread_tt(struct task_struct *task);
32705 +extern void exit_thread_tt(void);
32706 +extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
32707 +extern void init_idle_tt(void);
32708 +extern void flush_tlb_kernel_vm_tt(void);
32709 +extern void __flush_tlb_one_tt(unsigned long addr);
32710 +extern void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start, 
32711 +                              unsigned long end);
32712 +extern void flush_tlb_mm_tt(struct mm_struct *mm);
32713 +extern void force_flush_all_tt(void);
32714 +extern long execute_syscall_tt(void *r);
32715 +extern void before_mem_tt(unsigned long brk_start);
32716 +extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, 
32717 +                                      unsigned long *task_size_out);
32718 +extern int start_uml_tt(void);
32719 +extern int external_pid_tt(struct task_struct *task);
32720 +extern int thread_pid_tt(struct thread_struct *thread);
32721 +
32722 +#define kmem_end_tt (host_task_size - ABOVE_KMEM)
32723 +
32724 +#endif
32725 +
32726 +/*
32727 + * Overrides for Emacs so that we follow Linus's tabbing style.
32728 + * Emacs will notice this stuff at the end of the file and automatically
32729 + * adjust the settings for this buffer only.  This must remain at the end
32730 + * of the file.
32731 + * ---------------------------------------------------------------------------
32732 + * Local variables:
32733 + * c-file-style: "linux"
32734 + * End:
32735 + */
32736 Index: linux-2.4.29/arch/um/kernel/tt/include/ptrace-tt.h
32737 ===================================================================
32738 --- linux-2.4.29.orig/arch/um/kernel/tt/include/ptrace-tt.h     1970-01-01 03:00:00.000000000 +0300
32739 +++ linux-2.4.29/arch/um/kernel/tt/include/ptrace-tt.h  2005-05-03 22:28:14.497406272 +0300
32740 @@ -0,0 +1,26 @@
32741 +/* 
32742 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
32743 + * Licensed under the GPL
32744 + */
32745 +
32746 +#ifndef __PTRACE_TT_H
32747 +#define __PTRACE_TT_H
32748 +
32749 +#include "uml-config.h"
32750 +
32751 +#ifdef UML_CONFIG_MODE_TT
32752 +#include "sysdep/sc.h"
32753 +#endif
32754 +
32755 +#endif
32756 +
32757 +/*
32758 + * Overrides for Emacs so that we follow Linus's tabbing style.
32759 + * Emacs will notice this stuff at the end of the file and automatically
32760 + * adjust the settings for this buffer only.  This must remain at the end
32761 + * of the file.
32762 + * ---------------------------------------------------------------------------
32763 + * Local variables:
32764 + * c-file-style: "linux"
32765 + * End:
32766 + */
32767 Index: linux-2.4.29/arch/um/kernel/tt/include/tt.h
32768 ===================================================================
32769 --- linux-2.4.29.orig/arch/um/kernel/tt/include/tt.h    1970-01-01 03:00:00.000000000 +0300
32770 +++ linux-2.4.29/arch/um/kernel/tt/include/tt.h 2005-05-03 22:28:14.498406120 +0300
32771 @@ -0,0 +1,44 @@
32772 +/* 
32773 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32774 + * Licensed under the GPL
32775 + */
32776 +
32777 +#ifndef __TT_H__
32778 +#define __TT_H__
32779 +
32780 +#include "sysdep/ptrace.h"
32781 +
32782 +extern int gdb_pid;
32783 +extern int debug;
32784 +extern int debug_stop;
32785 +extern int debug_trace;
32786 +
32787 +extern int honeypot;
32788 +
32789 +extern int fork_tramp(void *sig_stack);
32790 +extern int do_proc_op(void *t, int proc_id);
32791 +extern int tracer(int (*init_proc)(void *), void *sp);
32792 +extern void attach_process(int pid);
32793 +extern void tracer_panic(char *format, ...);
32794 +extern void set_init_pid(int pid);
32795 +extern int set_user_mode(void *task);
32796 +extern void set_tracing(void *t, int tracing);
32797 +extern int is_tracing(void *task);
32798 +extern void syscall_handler(int sig, union uml_pt_regs *regs);
32799 +extern void exit_kernel(int pid, void *task);
32800 +extern int do_syscall(void *task, int pid);
32801 +extern int is_valid_pid(int pid);
32802 +extern void remap_data(void *segment_start, void *segment_end, int w);
32803 +
32804 +#endif
32805 +
32806 +/*
32807 + * Overrides for Emacs so that we follow Linus's tabbing style.
32808 + * Emacs will notice this stuff at the end of the file and automatically
32809 + * adjust the settings for this buffer only.  This must remain at the end
32810 + * of the file.
32811 + * ---------------------------------------------------------------------------
32812 + * Local variables:
32813 + * c-file-style: "linux"
32814 + * End:
32815 + */
32816 Index: linux-2.4.29/arch/um/kernel/tt/include/uaccess.h
32817 ===================================================================
32818 --- linux-2.4.29.orig/arch/um/kernel/tt/include/uaccess.h       1970-01-01 03:00:00.000000000 +0300
32819 +++ linux-2.4.29/arch/um/kernel/tt/include/uaccess.h    2005-05-03 22:28:14.499405968 +0300
32820 @@ -0,0 +1,71 @@
32821 +/* 
32822 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
32823 + * Licensed under the GPL
32824 + */
32825 +
32826 +#ifndef __TT_UACCESS_H
32827 +#define __TT_UACCESS_H
32828 +
32829 +#include "linux/string.h"
32830 +#include "linux/sched.h"
32831 +#include "asm/processor.h"
32832 +#include "asm/errno.h"
32833 +#include "asm/current.h"
32834 +#include "asm/a.out.h"
32835 +#include "uml_uaccess.h"
32836 +
32837 +#define ABOVE_KMEM (16 * 1024 * 1024)
32838 +
32839 +extern unsigned long end_vm;
32840 +extern unsigned long uml_physmem;
32841 +
32842 +#define under_task_size(addr, size) \
32843 +       (((unsigned long) (addr) < TASK_SIZE) && \
32844 +         (((unsigned long) (addr) + (size)) < TASK_SIZE))
32845 +
32846 +#define is_stack(addr, size) \
32847 +       (((unsigned long) (addr) < STACK_TOP) && \
32848 +        ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
32849 +        (((unsigned long) (addr) + (size)) <= STACK_TOP))
32850 +
32851 +#define access_ok_tt(type, addr, size) \
32852 +       ((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \
32853 +         (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
32854 +          (under_task_size(addr, size) || is_stack(addr, size))))
32855 +
32856 +static inline int verify_area_tt(int type, const void * addr, 
32857 +                                unsigned long size)
32858 +{
32859 +       return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
32860 +}
32861 +
32862 +extern unsigned long get_fault_addr(void);
32863 +
32864 +extern int __do_copy_from_user(void *to, const void *from, int n,
32865 +                              void **fault_addr, void **fault_catcher);
32866 +extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
32867 +                                 void **fault_addr, void **fault_catcher);
32868 +extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
32869 +                          void **fault_catcher);
32870 +extern int __do_strnlen_user(const char *str, unsigned long n,
32871 +                            void **fault_addr, void **fault_catcher);
32872 +
32873 +extern int copy_from_user_tt(void *to, const void *from, int n);
32874 +extern int copy_to_user_tt(void *to, const void *from, int n);
32875 +extern int strncpy_from_user_tt(char *dst, const char *src, int count);
32876 +extern int __clear_user_tt(void *mem, int len);
32877 +extern int clear_user_tt(void *mem, int len);
32878 +extern int strnlen_user_tt(const void *str, int len);
32879 +
32880 +#endif
32881 +
32882 +/*
32883 + * Overrides for Emacs so that we follow Linus's tabbing style.
32884 + * Emacs will notice this stuff at the end of the file and automatically
32885 + * adjust the settings for this buffer only.  This must remain at the end
32886 + * of the file.
32887 + * ---------------------------------------------------------------------------
32888 + * Local variables:
32889 + * c-file-style: "linux"
32890 + * End:
32891 + */
32892 Index: linux-2.4.29/arch/um/kernel/tt/ksyms.c
32893 ===================================================================
32894 --- linux-2.4.29.orig/arch/um/kernel/tt/ksyms.c 1970-01-01 03:00:00.000000000 +0300
32895 +++ linux-2.4.29/arch/um/kernel/tt/ksyms.c      2005-05-03 22:28:14.500405816 +0300
32896 @@ -0,0 +1,28 @@
32897 +/* 
32898 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32899 + * Licensed under the GPL
32900 + */
32901 +
32902 +#include "linux/module.h"
32903 +#include "asm/uaccess.h"
32904 +#include "mode.h"
32905 +
32906 +EXPORT_SYMBOL(__do_copy_from_user);
32907 +EXPORT_SYMBOL(__do_copy_to_user);
32908 +EXPORT_SYMBOL(__do_strncpy_from_user);
32909 +EXPORT_SYMBOL(__do_strnlen_user); 
32910 +EXPORT_SYMBOL(__do_clear_user);
32911 +
32912 +EXPORT_SYMBOL(tracing_pid);
32913 +EXPORT_SYMBOL(honeypot);
32914 +
32915 +/*
32916 + * Overrides for Emacs so that we follow Linus's tabbing style.
32917 + * Emacs will notice this stuff at the end of the file and automatically
32918 + * adjust the settings for this buffer only.  This must remain at the end
32919 + * of the file.
32920 + * ---------------------------------------------------------------------------
32921 + * Local variables:
32922 + * c-file-style: "linux"
32923 + * End:
32924 + */
32925 Index: linux-2.4.29/arch/um/kernel/tt/Makefile
32926 ===================================================================
32927 --- linux-2.4.29.orig/arch/um/kernel/tt/Makefile        1970-01-01 03:00:00.000000000 +0300
32928 +++ linux-2.4.29/arch/um/kernel/tt/Makefile     2005-05-03 22:28:14.501405664 +0300
32929 @@ -0,0 +1,39 @@
32930 +# 
32931 +# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
32932 +# Licensed under the GPL
32933 +#
32934 +
32935 +O_TARGET = tt.o
32936 +
32937 +obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
32938 +       syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
32939 +       uaccess.o uaccess_user.o
32940 +
32941 +obj-$(CONFIG_PT_PROXY) += gdb_kern.o 
32942 +
32943 +subdir-y = sys-$(SUBARCH)
32944 +subdir-$(CONFIG_PT_PROXY) += ptproxy
32945 +
32946 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
32947 +
32948 +export-objs = ksyms.o
32949 +
32950 +USER_OBJS = $(filter %_user.o,$(obj-y)) gdb.o time.o tracer.o
32951 +
32952 +UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS))
32953 +UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS))
32954 +
32955 +include $(TOPDIR)/Rules.make
32956 +
32957 +$(USER_OBJS) : %.o: %.c
32958 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
32959 +
32960 +$(O_TARGET) : unmap_fin.o
32961 +
32962 +unmap.o: unmap.c
32963 +       $(CC) $(UNMAP_CFLAGS) -c -o $@ $<
32964 +
32965 +unmap_fin.o : unmap.o
32966 +       ld -r -o $@ $< -lc -L/usr/lib
32967 +
32968 +clean :
32969 Index: linux-2.4.29/arch/um/kernel/tt/mem.c
32970 ===================================================================
32971 --- linux-2.4.29.orig/arch/um/kernel/tt/mem.c   1970-01-01 03:00:00.000000000 +0300
32972 +++ linux-2.4.29/arch/um/kernel/tt/mem.c        2005-05-03 22:28:14.502405512 +0300
32973 @@ -0,0 +1,51 @@
32974 +/* 
32975 + * Copyright (C) 2002 - 2004 Jeff Dike (jdike@karaya.com)
32976 + * Licensed under the GPL
32977 + */
32978 +
32979 +#include "linux/stddef.h"
32980 +#include "linux/config.h"
32981 +#include "linux/mm.h"
32982 +#include "asm/uaccess.h"
32983 +#include "mem_user.h"
32984 +#include "kern_util.h"
32985 +#include "user_util.h"
32986 +#include "kern.h"
32987 +#include "tt.h"
32988 +
32989 +void before_mem_tt(unsigned long brk_start)
32990 +{
32991 +       if(!jail || debug)
32992 +               remap_data(UML_ROUND_DOWN(&_stext), UML_ROUND_UP(&_etext), 1);
32993 +       remap_data(UML_ROUND_DOWN(&_sdata), UML_ROUND_UP(&_edata), 1);
32994 +       remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1);
32995 +}
32996 +
32997 +#ifdef CONFIG_HOST_2G_2G
32998 +#define TOP 0x80000000
32999 +#else
33000 +#define TOP 0xc0000000
33001 +#endif
33002 +
33003 +#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
33004 +#define START (TOP - SIZE)
33005 +
33006 +unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, 
33007 +                               unsigned long *task_size_out)
33008 +{
33009 +       /* Round up to the nearest 4M */
33010 +       *host_size_out = ROUND_4M((unsigned long) &arg);
33011 +       *task_size_out = START;
33012 +       return(START);
33013 +}
33014 +
33015 +/*
33016 + * Overrides for Emacs so that we follow Linus's tabbing style.
33017 + * Emacs will notice this stuff at the end of the file and automatically
33018 + * adjust the settings for this buffer only.  This must remain at the end
33019 + * of the file.
33020 + * ---------------------------------------------------------------------------
33021 + * Local variables:
33022 + * c-file-style: "linux"
33023 + * End:
33024 + */
33025 Index: linux-2.4.29/arch/um/kernel/tt/mem_user.c
33026 ===================================================================
33027 --- linux-2.4.29.orig/arch/um/kernel/tt/mem_user.c      1970-01-01 03:00:00.000000000 +0300
33028 +++ linux-2.4.29/arch/um/kernel/tt/mem_user.c   2005-05-03 22:28:14.502405512 +0300
33029 @@ -0,0 +1,49 @@
33030 +/* 
33031 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33032 + * Licensed under the GPL
33033 + */
33034 +
33035 +#include <stdlib.h>
33036 +#include <stdio.h>
33037 +#include <unistd.h>
33038 +#include <string.h>
33039 +#include <errno.h>
33040 +#include <sys/mman.h>
33041 +#include "tt.h"
33042 +#include "mem_user.h"
33043 +#include "user_util.h"
33044 +
33045 +void remap_data(void *segment_start, void *segment_end, int w)
33046 +{
33047 +       void *addr;
33048 +       unsigned long size;
33049 +       int data, prot;
33050 +
33051 +       if(w) prot = PROT_WRITE;
33052 +       else prot = 0;
33053 +       prot |= PROT_READ | PROT_EXEC;
33054 +       size = (unsigned long) segment_end - 
33055 +               (unsigned long) segment_start;
33056 +       data = create_mem_file(size);
33057 +       addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0);
33058 +       if(addr == MAP_FAILED){
33059 +               perror("mapping new data segment");
33060 +               exit(1);
33061 +       }
33062 +       memcpy(addr, segment_start, size);
33063 +       if(switcheroo(data, prot, addr, segment_start, size) < 0){
33064 +               printf("switcheroo failed\n");
33065 +               exit(1);
33066 +       }
33067 +}
33068 +
33069 +/*
33070 + * Overrides for Emacs so that we follow Linus's tabbing style.
33071 + * Emacs will notice this stuff at the end of the file and automatically
33072 + * adjust the settings for this buffer only.  This must remain at the end
33073 + * of the file.
33074 + * ---------------------------------------------------------------------------
33075 + * Local variables:
33076 + * c-file-style: "linux"
33077 + * End:
33078 + */
33079 Index: linux-2.4.29/arch/um/kernel/tt/process_kern.c
33080 ===================================================================
33081 --- linux-2.4.29.orig/arch/um/kernel/tt/process_kern.c  1970-01-01 03:00:00.000000000 +0300
33082 +++ linux-2.4.29/arch/um/kernel/tt/process_kern.c       2005-05-03 22:28:14.526401864 +0300
33083 @@ -0,0 +1,615 @@
33084 +/* 
33085 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33086 + * Licensed under the GPL
33087 + */
33088 +
33089 +#include "linux/sched.h"
33090 +#include "linux/signal.h"
33091 +#include "linux/kernel.h"
33092 +#include "linux/slab.h"
33093 +#include "asm/system.h"
33094 +#include "asm/pgalloc.h"
33095 +#include "asm/ptrace.h"
33096 +#include "irq_user.h"
33097 +#include "signal_user.h"
33098 +#include "kern_util.h"
33099 +#include "user_util.h"
33100 +#include "os.h"
33101 +#include "kern.h"
33102 +#include "sigcontext.h"
33103 +#include "time_user.h"
33104 +#include "mem_user.h"
33105 +#include "tlb.h"
33106 +#include "mode.h"
33107 +#include "init.h"
33108 +#include "tt.h"
33109 +#include "filehandle.h"
33110 +
33111 +void *_switch_to_tt(void *prev, void *next)
33112 +{
33113 +       struct task_struct *from, *to, *prev_sched;
33114 +       struct file_handle *pipe;
33115 +       unsigned long flags;
33116 +       int err, vtalrm, alrm, prof, cpu;
33117 +       char c;
33118 +       /* jailing and SMP are incompatible, so this doesn't need to be 
33119 +        * made per-cpu 
33120 +        */
33121 +       static int reading;
33122 +
33123 +       from = prev;
33124 +       to = next;
33125 +
33126 +       to->thread.prev_sched = from;
33127 +
33128 +       cpu = from->processor;
33129 +       if(cpu == 0)
33130 +               forward_interrupts(to->thread.mode.tt.extern_pid);
33131 +#ifdef CONFIG_SMP
33132 +       forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid);
33133 +#endif
33134 +       local_irq_save(flags);
33135 +
33136 +       vtalrm = change_sig(SIGVTALRM, 0);
33137 +       alrm = change_sig(SIGALRM, 0);
33138 +       prof = change_sig(SIGPROF, 0);
33139 +
33140 +       c = 0;
33141 +       set_current(to);
33142 +
33143 +       reading = 0;
33144 +       pipe = to->thread.mode.tt.switch_pipe;
33145 +       err = write_file(&pipe[1], -1, &c, sizeof(c));
33146 +       if(err != sizeof(c))
33147 +               panic("write of switch_pipe failed, err = %d", -err);
33148 +
33149 +       reading = 1;
33150 +       if(from->state == TASK_ZOMBIE)
33151 +               os_kill_process(os_getpid(), 0);
33152 +
33153 +       pipe = from->thread.mode.tt.switch_pipe;
33154 +       err = read_file(&pipe[0], -1, &c, sizeof(c));
33155 +       if(err != sizeof(c))
33156 +               panic("read of switch_pipe failed, errno = %d", -err);
33157 +
33158 +       /* If the process that we have just scheduled away from has exited,
33159 +        * then it needs to be killed here.  The reason is that, even though
33160 +        * it will kill itself when it next runs, that may be too late.  Its
33161 +        * stack will be freed, possibly before then, and if that happens,
33162 +        * we have a use-after-free situation.  So, it gets killed here
33163 +        * in case it has not already killed itself.
33164 +        */
33165 +       prev_sched = current->thread.prev_sched;
33166 +       if(prev_sched->state == TASK_ZOMBIE)
33167 +               os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1);
33168 +
33169 +       /* This works around a nasty race with 'jail'.  If we are switching
33170 +        * between two threads of a threaded app and the incoming process 
33171 +        * runs before the outgoing process reaches the read, and it makes
33172 +        * it all the way out to userspace, then it will have write-protected 
33173 +        * the outgoing process stack.  Then, when the outgoing process 
33174 +        * returns from the write, it will segfault because it can no longer
33175 +        * write its own stack.  So, in order to avoid that, the incoming 
33176 +        * thread sits in a loop yielding until 'reading' is set.  This 
33177 +        * isn't entirely safe, since there may be a reschedule from a timer
33178 +        * happening between setting 'reading' and sleeping in read.  But,
33179 +        * it should get a whole quantum in which to reach the read and sleep,
33180 +        * which should be enough.
33181 +        */
33182 +
33183 +       if(jail){
33184 +               while(!reading) sched_yield();
33185 +       }
33186 +
33187 +       change_sig(SIGVTALRM, vtalrm);
33188 +       change_sig(SIGALRM, alrm);
33189 +       change_sig(SIGPROF, prof);
33190 +
33191 +       arch_switch();
33192 +
33193 +       flush_tlb_all();
33194 +       local_irq_restore(flags);
33195 +
33196 +       return(current->thread.prev_sched);
33197 +}
33198 +
33199 +void release_thread_tt(struct task_struct *task)
33200 +{
33201 +       os_kill_process(task->thread.mode.tt.extern_pid, 0);
33202 +}
33203 +
33204 +void exit_thread_tt(void)
33205 +{
33206 +       struct file_handle *pipe = current->thread.mode.tt.switch_pipe;
33207 +
33208 +       close_file(&pipe[0]);
33209 +       close_file(&pipe[1]);
33210 +       kfree(pipe);
33211 +}
33212 +
33213 +static void suspend_new_thread(struct file_handle *fh)
33214 +{
33215 +       char c;
33216 +
33217 +       os_stop_process(os_getpid());
33218 +
33219 +       if(read_file(fh, -1, &c, sizeof(c)) != sizeof(c))
33220 +               panic("read failed in suspend_new_thread");
33221 +}
33222 +
33223 +extern void schedule_tail(struct task_struct *prev);
33224 +
33225 +static void new_thread_handler(int sig)
33226 +{
33227 +       struct file_handle *pipe;
33228 +       unsigned long disable;
33229 +       int (*fn)(void *);
33230 +       void *arg;
33231 +
33232 +       fn = current->thread.request.u.thread.proc;
33233 +       arg = current->thread.request.u.thread.arg;
33234 +
33235 +       UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
33236 +       disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
33237 +               (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
33238 +       SC_SIGMASK(UPT_SC(&current->thread.regs.regs)) &= ~disable;
33239 +
33240 +       pipe = current->thread.mode.tt.switch_pipe;
33241 +       suspend_new_thread(&pipe[0]);
33242 +
33243 +       init_new_thread_signals(1);
33244 +       enable_timer();
33245 +       free_page(current->thread.temp_stack);
33246 +       set_cmdline("(kernel thread)");
33247 +       force_flush_all();
33248 +
33249 +       if(current->thread.prev_sched != NULL)
33250 +               schedule_tail(current->thread.prev_sched);
33251 +       current->thread.prev_sched = NULL;
33252 +
33253 +       change_sig(SIGUSR1, 1);
33254 +       change_sig(SIGVTALRM, 1);
33255 +       change_sig(SIGPROF, 1);
33256 +       sti();
33257 +       if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
33258 +               do_exit(0);
33259 +       
33260 +       /* XXX No set_user_mode here because a newly execed process will
33261 +        * immediately segfault on its non-existent IP, coming straight back
33262 +        * to the signal handler, which will call set_user_mode on its way
33263 +        * out.  This should probably change since it's confusing.
33264 +        */
33265 +}
33266 +
33267 +static int new_thread_proc(void *stack)
33268 +{
33269 +       /* cli is needed to block out signals until this thread is properly
33270 +        * scheduled.  Otherwise, the tracing thread will get mighty upset 
33271 +        * about any signals that arrive before that.  
33272 +        * This has the complication that it sets the saved signal mask in
33273 +        * the sigcontext to block signals.  This gets restored when this
33274 +        * thread (or a descendant, since they get a copy of this sigcontext)
33275 +        * returns to userspace.
33276 +        * So, this is compensated for elsewhere.
33277 +        * XXX There is still a small window until cli() actually finishes
33278 +        * where signals are possible - shouldn't be a problem in practice 
33279 +        * since SIGIO hasn't been forwarded here yet, and the cli should 
33280 +        * finish before a SIGVTALRM has time to be delivered.
33281 +        */
33282 +       cli();
33283 +       init_new_thread_stack(stack, new_thread_handler);
33284 +       os_usr1_process(os_getpid());
33285 +       change_sig(SIGUSR1, 1);
33286 +       return(0);
33287 +}
33288 +
33289 +/* Signal masking - signals are blocked at the start of fork_tramp.  They
33290 + * are re-enabled when finish_fork_handler is entered by fork_tramp hitting
33291 + * itself with a SIGUSR1.  set_user_mode has to be run with SIGUSR1 off,
33292 + * so it is blocked before it's called.  They are re-enabled on sigreturn
33293 + * despite the fact that they were blocked when the SIGUSR1 was issued because
33294 + * copy_thread copies the parent's sigcontext, including the signal mask
33295 + * onto the signal frame.
33296 + */
33297 +
33298 +static void finish_fork_handler(int sig)
33299 +{
33300 +       struct file_handle *pipe = current->thread.mode.tt.switch_pipe;
33301 +
33302 +       UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
33303 +       suspend_new_thread(&pipe[0]);
33304 +       
33305 +       init_new_thread_signals(1);
33306 +       enable_timer();
33307 +       sti();
33308 +       force_flush_all();
33309 +       if(current->mm != current->p_pptr->mm)
33310 +               protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
33311 +                              1, 0, 1);
33312 +       task_protections((unsigned long) current);
33313 +
33314 +       if(current->thread.prev_sched != NULL)
33315 +               schedule_tail(current->thread.prev_sched);
33316 +       current->thread.prev_sched = NULL;
33317 +
33318 +       free_page(current->thread.temp_stack);
33319 +       cli();
33320 +       change_sig(SIGUSR1, 0);
33321 +       set_user_mode(current);
33322 +}
33323 +
33324 +int fork_tramp(void *stack)
33325 +{
33326 +       cli();
33327 +       arch_init_thread();
33328 +       init_new_thread_stack(stack, finish_fork_handler);
33329 +       os_usr1_process(os_getpid());
33330 +       change_sig(SIGUSR1, 1);
33331 +       return(0);
33332 +}
33333 +
33334 +struct file_handle *make_switch_pipe(void)
33335 +{
33336 +       struct file_handle *pipe;
33337 +       int err;
33338 +
33339 +       pipe = kmalloc(sizeof(struct file_handle [2]), GFP_KERNEL);
33340 +       if(pipe == NULL){
33341 +               pipe = ERR_PTR(-ENOMEM);
33342 +               goto out;
33343 +       }
33344 +
33345 +       err = make_pipe(pipe);
33346 +       if(err)
33347 +               goto out_free;
33348 +
33349 + out:
33350 +       return(pipe);
33351 +
33352 + out_free:
33353 +       kfree(pipe);
33354 +       pipe = ERR_PTR(err);
33355 +       goto out;
33356 +}
33357 +
33358 +int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
33359 +                  unsigned long stack_top, struct task_struct * p, 
33360 +                  struct pt_regs *regs)
33361 +{
33362 +       int (*tramp)(void *);
33363 +       int new_pid, err;
33364 +       unsigned long stack;
33365 +       
33366 +       if(current->thread.forking)
33367 +               tramp = fork_tramp;
33368 +       else {
33369 +               tramp = new_thread_proc;
33370 +               p->thread.request.u.thread = current->thread.request.u.thread;
33371 +       }
33372 +
33373 +       p->thread.mode.tt.switch_pipe = make_switch_pipe();
33374 +       if(IS_ERR(p->thread.mode.tt.switch_pipe)){
33375 +               err = PTR_ERR(p->thread.mode.tt.switch_pipe);
33376 +               goto out;
33377 +       }
33378 +
33379 +       stack = alloc_stack(0, 0);
33380 +       if(stack == 0){
33381 +               printk(KERN_ERR "copy_thread : failed to allocate "
33382 +                      "temporary stack\n");
33383 +               err = -ENOMEM;
33384 +               goto out_close;
33385 +       }
33386 +
33387 +       clone_flags &= CLONE_VM;
33388 +       p->thread.temp_stack = stack;
33389 +       new_pid = start_fork_tramp(p, stack, clone_flags, tramp);
33390 +       if(new_pid < 0){
33391 +               printk(KERN_ERR "copy_thread : clone failed - errno = %d\n", 
33392 +                      -new_pid);
33393 +               err = new_pid;
33394 +               goto out_stack;
33395 +       }
33396 +
33397 +       if(current->thread.forking){
33398 +               sc_to_sc(UPT_SC(&p->thread.regs.regs), 
33399 +                        UPT_SC(&current->thread.regs.regs));
33400 +               SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
33401 +               if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
33402 +       }
33403 +       p->thread.mode.tt.extern_pid = new_pid;
33404 +
33405 +       current->thread.request.op = OP_FORK;
33406 +       current->thread.request.u.fork.pid = new_pid;
33407 +       os_usr1_process(os_getpid());
33408 +
33409 +       /* Enable the signal and then disable it to ensure that it is handled
33410 +        * here, and nowhere else.
33411 +        */
33412 +       change_sig(SIGUSR1, 1);
33413 +
33414 +       change_sig(SIGUSR1, 0);
33415 +       err = 0;
33416 +
33417 + out:
33418 +       return(err);
33419 +
33420 + out_stack:
33421 +       free_stack(stack, 0);
33422 + out_close:
33423 +       close_file(&((struct file_handle *) p->thread.mode.tt.switch_pipe)[0]);
33424 +       close_file(&((struct file_handle *) p->thread.mode.tt.switch_pipe)[1]);
33425 +       kfree(p->thread.mode.tt.switch_pipe);
33426 +       goto out;
33427 +}
33428 +
33429 +void reboot_tt(void)
33430 +{
33431 +       current->thread.request.op = OP_REBOOT;
33432 +       os_usr1_process(os_getpid());
33433 +       change_sig(SIGUSR1, 1);
33434 +}
33435 +
33436 +void halt_tt(void)
33437 +{
33438 +       current->thread.request.op = OP_HALT;
33439 +       os_usr1_process(os_getpid());
33440 +       change_sig(SIGUSR1, 1);
33441 +}
33442 +
33443 +void kill_off_processes_tt(void)
33444 +{
33445 +       struct task_struct *p;
33446 +       int me;
33447 +
33448 +       me = os_getpid();
33449 +       for_each_task(p){
33450 +               int pid = p->thread.mode.tt.extern_pid;
33451 +               if((pid != me) && (pid != -1))
33452 +                       os_kill_process(p->thread.mode.tt.extern_pid, 0);
33453 +       }
33454 +       if((init_task.thread.mode.tt.extern_pid != me) &&
33455 +          (init_task.thread.mode.tt.extern_pid != -1))
33456 +               os_kill_process(init_task.thread.mode.tt.extern_pid, 0);
33457 +}
33458 +
33459 +void initial_thread_cb_tt(void (*proc)(void *), void *arg)
33460 +{
33461 +       if(os_getpid() == tracing_pid){
33462 +               (*proc)(arg);
33463 +       }
33464 +       else {
33465 +               current->thread.request.op = OP_CB;
33466 +               current->thread.request.u.cb.proc = proc;
33467 +               current->thread.request.u.cb.arg = arg;
33468 +               os_usr1_process(os_getpid());
33469 +               change_sig(SIGUSR1, 1);
33470 +
33471 +               change_sig(SIGUSR1, 0);
33472 +       }
33473 +}
33474 +
33475 +int do_proc_op(void *t, int proc_id)
33476 +{
33477 +       struct task_struct *task;
33478 +       struct thread_struct *thread;
33479 +       int op, pid;
33480 +
33481 +       task = t;
33482 +       thread = &task->thread;
33483 +       op = thread->request.op;
33484 +       switch(op){
33485 +       case OP_NONE:
33486 +       case OP_TRACE_ON:
33487 +               break;
33488 +       case OP_EXEC:
33489 +               pid = thread->request.u.exec.pid;
33490 +               do_exec(thread->mode.tt.extern_pid, pid);
33491 +               thread->mode.tt.extern_pid = pid;
33492 +               cpu_tasks[task->processor].pid = pid;
33493 +               break;
33494 +       case OP_FORK:
33495 +               attach_process(thread->request.u.fork.pid);
33496 +               break;
33497 +       case OP_CB:
33498 +               (*thread->request.u.cb.proc)(thread->request.u.cb.arg);
33499 +               break;
33500 +       case OP_REBOOT:
33501 +       case OP_HALT:
33502 +               break;
33503 +       default:
33504 +               tracer_panic("Bad op in do_proc_op");
33505 +               break;
33506 +       }
33507 +       thread->request.op = OP_NONE;
33508 +       return(op);
33509 +}
33510 +
33511 +void init_idle_tt(void)
33512 +{
33513 +       idle_timer();
33514 +}
33515 +
33516 +/* Changed by jail_setup, which is a setup */
33517 +int jail = 0;
33518 +
33519 +int __init jail_setup(char *line, int *add)
33520 +{
33521 +       int ok = 1;
33522 +
33523 +       if(jail) return(0);
33524 +#ifdef CONFIG_SMP
33525 +       printf("'jail' may not used used in a kernel with CONFIG_SMP "
33526 +              "enabled\n");
33527 +       ok = 0;
33528 +#endif
33529 +#ifdef CONFIG_HOSTFS
33530 +       printf("'jail' may not used used in a kernel with CONFIG_HOSTFS "
33531 +              "enabled\n");
33532 +       ok = 0;
33533 +#endif
33534 +#ifdef CONFIG_MODULES
33535 +       printf("'jail' may not used used in a kernel with CONFIG_MODULES "
33536 +              "enabled\n");
33537 +       ok = 0;
33538 +#endif 
33539 +       if(!ok) exit(1);
33540 +
33541 +       /* CAP_SYS_RAWIO controls the ability to open /dev/mem and /dev/kmem.
33542 +        * Removing it from the bounding set eliminates the ability of anything
33543 +        * to acquire it, and thus read or write kernel memory.
33544 +        */
33545 +       cap_lower(cap_bset, CAP_SYS_RAWIO);
33546 +       jail = 1;
33547 +       return(0);
33548 +}
33549 +
33550 +__uml_setup("jail", jail_setup,
33551 +"jail\n"
33552 +"    Enables the protection of kernel memory from processes.\n\n"
33553 +);
33554 +
33555 +static void mprotect_kernel_mem(int w)
33556 +{
33557 +       unsigned long start, end;
33558 +       int pages;
33559 +
33560 +       if(!jail || (current == &init_task)) return;
33561 +
33562 +       pages = (1 << CONFIG_KERNEL_STACK_ORDER);
33563 +
33564 +       start = (unsigned long) current + PAGE_SIZE;
33565 +       end = (unsigned long) current + PAGE_SIZE * pages;
33566 +       protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
33567 +       protect_memory(end, high_physmem - end, 1, w, 1, 1);
33568 +
33569 +       start = (unsigned long) UML_ROUND_DOWN(&_stext);
33570 +       end = (unsigned long) UML_ROUND_UP(&_etext);
33571 +       protect_memory(start, end - start, 1, w, 1, 1);
33572 +
33573 +       start = (unsigned long) UML_ROUND_DOWN(&_unprotected_end);
33574 +       end = (unsigned long) UML_ROUND_UP(&_edata);
33575 +       protect_memory(start, end - start, 1, w, 1, 1);
33576 +
33577 +       start = (unsigned long) UML_ROUND_DOWN(&__bss_start);
33578 +       end = (unsigned long) UML_ROUND_UP(&_end);
33579 +       protect_memory(start, end - start, 1, w, 1, 1);
33580 +
33581 +       mprotect_kernel_vm(w);
33582 +}
33583 +
33584 +void unprotect_kernel_mem(void)
33585 +{
33586 +       mprotect_kernel_mem(1);
33587 +}
33588 +
33589 +void protect_kernel_mem(void)
33590 +{
33591 +       mprotect_kernel_mem(0);
33592 +}
33593 +
33594 +extern void start_kernel(void);
33595 +
33596 +static int start_kernel_proc(void *unused)
33597 +{
33598 +       int pid;
33599 +
33600 +       block_signals();
33601 +       pid = os_getpid();
33602 +
33603 +       cpu_tasks[0].pid = pid;
33604 +       cpu_tasks[0].task = current;
33605 +#ifdef CONFIG_SMP
33606 +       cpu_online_map = 1;
33607 +#endif
33608 +       if(debug) os_stop_process(pid);
33609 +       start_kernel();
33610 +       return(0);
33611 +}
33612 +
33613 +void set_tracing(void *task, int tracing)
33614 +{
33615 +       ((struct task_struct *) task)->thread.mode.tt.tracing = tracing;
33616 +}
33617 +
33618 +int is_tracing(void *t)
33619 +{
33620 +       return (((struct task_struct *) t)->thread.mode.tt.tracing);
33621 +}
33622 +
33623 +int set_user_mode(void *t)
33624 +{
33625 +       struct task_struct *task;
33626 +
33627 +       task = t ? t : current;
33628 +       if(task->thread.mode.tt.tracing) 
33629 +               return(1);
33630 +       task->thread.request.op = OP_TRACE_ON;
33631 +       os_usr1_process(os_getpid());
33632 +       return(0);
33633 +}
33634 +
33635 +/* This is static rather than kmalloced because this happens before kmalloc
33636 + * is initialized.  Also, it is always needed, so might as well be static on
33637 + * this ground.
33638 + */
33639 +static struct file_handle init_switch_pipe[2];
33640 +
33641 +void set_init_pid(int pid)
33642 +{
33643 +       int err;
33644 +
33645 +       init_task.thread.mode.tt.extern_pid = pid;
33646 +
33647 +       err = make_pipe(init_switch_pipe);
33648 +       if(err)
33649 +               panic("set_init_pid - make_pipe failed, errno = %d", err);
33650 +       init_task.thread.mode.tt.switch_pipe = init_switch_pipe;
33651 +}
33652 +
33653 +int start_uml_tt(void)
33654 +{
33655 +       void *sp;
33656 +       int pages;
33657 +
33658 +       pages = (1 << CONFIG_KERNEL_STACK_ORDER);
33659 +       sp = (void *) ((unsigned long) &init_task) + pages * PAGE_SIZE - 
33660 +               sizeof(unsigned long);
33661 +       return(tracer(start_kernel_proc, sp));
33662 +}
33663 +
33664 +int external_pid_tt(struct task_struct *task)
33665 +{
33666 +       return(task->thread.mode.tt.extern_pid);
33667 +}
33668 +
33669 +int thread_pid_tt(struct thread_struct *thread)
33670 +{
33671 +       return(thread->mode.tt.extern_pid);
33672 +}
33673 +
33674 +int is_valid_pid(int pid)
33675 +{
33676 +       struct task_struct *task;
33677 +
33678 +        read_lock(&tasklist_lock);
33679 +        for_each_task(task){
33680 +                if(task->thread.mode.tt.extern_pid == pid){
33681 +                       read_unlock(&tasklist_lock);
33682 +                       return(1);
33683 +                }
33684 +        }
33685 +       read_unlock(&tasklist_lock);
33686 +       return(0);
33687 +}
33688 +
33689 +/*
33690 + * Overrides for Emacs so that we follow Linus's tabbing style.
33691 + * Emacs will notice this stuff at the end of the file and automatically
33692 + * adjust the settings for this buffer only.  This must remain at the end
33693 + * of the file.
33694 + * ---------------------------------------------------------------------------
33695 + * Local variables:
33696 + * c-file-style: "linux"
33697 + * End:
33698 + */
33699 Index: linux-2.4.29/arch/um/kernel/tt/ptproxy/Makefile
33700 ===================================================================
33701 --- linux-2.4.29.orig/arch/um/kernel/tt/ptproxy/Makefile        1970-01-01 03:00:00.000000000 +0300
33702 +++ linux-2.4.29/arch/um/kernel/tt/ptproxy/Makefile     2005-05-03 22:28:14.526401864 +0300
33703 @@ -0,0 +1,12 @@
33704 +O_TARGET = ptproxy.o
33705 +
33706 +obj-y = proxy.o ptrace.o sysdep.o wait.o
33707 +
33708 +USER_OBJS = $(obj-y)
33709 +
33710 +include $(TOPDIR)/Rules.make
33711 +
33712 +$(USER_OBJS) : %.o: %.c
33713 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
33714 +
33715 +clean:
33716 Index: linux-2.4.29/arch/um/kernel/tt/ptproxy/proxy.c
33717 ===================================================================
33718 --- linux-2.4.29.orig/arch/um/kernel/tt/ptproxy/proxy.c 1970-01-01 03:00:00.000000000 +0300
33719 +++ linux-2.4.29/arch/um/kernel/tt/ptproxy/proxy.c      2005-05-03 22:28:14.529401408 +0300
33720 @@ -0,0 +1,371 @@
33721 +/**********************************************************************
33722 +proxy.c
33723 +
33724 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
33725 +terms and conditions.
33726 +
33727 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
33728 +**********************************************************************/
33729 +
33730 +/* XXX This file shouldn't refer to CONFIG_* */
33731 +
33732 +#include <errno.h>
33733 +#include <stdio.h>
33734 +#include <stdlib.h>
33735 +#include <unistd.h>
33736 +#include <signal.h>
33737 +#include <string.h>
33738 +#include <termios.h>
33739 +#include <sys/wait.h>
33740 +#include <sys/types.h>
33741 +#include <sys/ptrace.h>
33742 +#include <sys/ioctl.h>
33743 +#include <asm/unistd.h>
33744 +
33745 +#include "ptproxy.h"
33746 +#include "sysdep.h"
33747 +#include "wait.h"
33748 +
33749 +#include "user_util.h"
33750 +#include "user.h"
33751 +#include "os.h"
33752 +#include "tempfile.h"
33753 +
33754 +static int debugger_wait(debugger_state *debugger, int *status, int options,
33755 +                        int (*syscall)(debugger_state *debugger, pid_t child),
33756 +                        int (*normal_return)(debugger_state *debugger, 
33757 +                                             pid_t unused),
33758 +                        int (*wait_return)(debugger_state *debugger, 
33759 +                                           pid_t unused))
33760 +{
33761 +       if(debugger->real_wait){
33762 +               debugger->handle_trace = normal_return;
33763 +               syscall_continue(debugger->pid);
33764 +               debugger->real_wait = 0;
33765 +               return(1);
33766 +       }
33767 +       debugger->wait_status_ptr = status;
33768 +       debugger->wait_options = options;
33769 +       if((debugger->debugee != NULL) && debugger->debugee->event){
33770 +               syscall_continue(debugger->pid);
33771 +               wait_for_stop(debugger->pid, SIGTRAP, PTRACE_SYSCALL,
33772 +                             NULL);
33773 +               (*wait_return)(debugger, -1);
33774 +               return(0);
33775 +       }
33776 +       else if(debugger->wait_options & WNOHANG){
33777 +               syscall_cancel(debugger->pid, 0);
33778 +               debugger->handle_trace = syscall;
33779 +               return(0);
33780 +       }
33781 +       else {
33782 +               syscall_pause(debugger->pid);
33783 +               debugger->handle_trace = wait_return;
33784 +               debugger->waiting = 1;
33785 +       }
33786 +       return(1);
33787 +}
33788 +
33789 +/*
33790 + * Handle debugger trap, i.e. syscall.
33791 + */
33792 +
33793 +int debugger_syscall(debugger_state *debugger, pid_t child)
33794 +{
33795 +       long arg1, arg2, arg3, arg4, arg5, result;
33796 +       int syscall, ret = 0;
33797 +
33798 +       syscall = get_syscall(debugger->pid, &arg1, &arg2, &arg3, &arg4, 
33799 +                             &arg5);
33800 +
33801 +       switch(syscall){
33802 +       case __NR_execve:
33803 +               /* execve never returns */
33804 +               debugger->handle_trace = debugger_syscall; 
33805 +               break;
33806 +
33807 +       case __NR_ptrace:
33808 +               if(debugger->debugee->pid != 0) arg2 = debugger->debugee->pid;
33809 +               if(!debugger->debugee->in_context) 
33810 +                       child = debugger->debugee->pid;
33811 +               result = proxy_ptrace(debugger, arg1, arg2, arg3, arg4, child,
33812 +                                     &ret);
33813 +               syscall_cancel(debugger->pid, result);
33814 +               debugger->handle_trace = debugger_syscall;
33815 +               return(ret);
33816 +
33817 +       case __NR_waitpid:
33818 +       case __NR_wait4:
33819 +               if(!debugger_wait(debugger, (int *) arg2, arg3, 
33820 +                                 debugger_syscall, debugger_normal_return, 
33821 +                                 proxy_wait_return))
33822 +                       return(0);
33823 +               break;
33824 +
33825 +       case __NR_kill:
33826 +               if(!debugger->debugee->in_context) 
33827 +                       child = debugger->debugee->pid;
33828 +               if(arg1 == debugger->debugee->pid){
33829 +                       result = kill(child, arg2);
33830 +                       syscall_cancel(debugger->pid, result);
33831 +                       debugger->handle_trace = debugger_syscall;
33832 +                       return(0);
33833 +               }
33834 +               else debugger->handle_trace = debugger_normal_return;
33835 +               break;
33836 +
33837 +       default:
33838 +               debugger->handle_trace = debugger_normal_return;
33839 +       }
33840 +
33841 +       syscall_continue(debugger->pid);
33842 +       return(0);
33843 +}
33844 +
33845 +/* Used by the tracing thread */
33846 +static debugger_state parent;
33847 +static int parent_syscall(debugger_state *debugger, int pid);
33848 +
33849 +int init_parent_proxy(int pid)
33850 +{
33851 +       parent = ((debugger_state) { .pid               = pid,
33852 +                                    .wait_options      = 0,
33853 +                                    .wait_status_ptr   = NULL,
33854 +                                    .waiting           = 0,
33855 +                                    .real_wait         = 0,
33856 +                                    .expecting_child   = 0,
33857 +                                    .handle_trace      = parent_syscall,
33858 +                                    .debugee           = NULL } );
33859 +       return(0);
33860 +}
33861 +
33862 +int parent_normal_return(debugger_state *debugger, pid_t unused)
33863 +{
33864 +       debugger->handle_trace = parent_syscall;
33865 +       syscall_continue(debugger->pid);
33866 +       return(0);
33867 +}
33868 +
33869 +static int parent_syscall(debugger_state *debugger, int pid)
33870 +{
33871 +       long arg1, arg2, arg3, arg4, arg5;
33872 +       int syscall;
33873 +
33874 +       syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5);
33875 +               
33876 +       if((syscall == __NR_waitpid) || (syscall == __NR_wait4)){
33877 +               debugger_wait(&parent, (int *) arg2, arg3, parent_syscall,
33878 +                             parent_normal_return, parent_wait_return);
33879 +       }
33880 +       else ptrace(PTRACE_SYSCALL, pid, 0, 0);
33881 +       return(0);
33882 +}
33883 +
33884 +int debugger_normal_return(debugger_state *debugger, pid_t unused)
33885 +{
33886 +       debugger->handle_trace = debugger_syscall;
33887 +       syscall_continue(debugger->pid);
33888 +       return(0);
33889 +}
33890 +
33891 +void debugger_cancelled_return(debugger_state *debugger, int result)
33892 +{
33893 +       debugger->handle_trace = debugger_syscall;
33894 +       syscall_set_result(debugger->pid, result);
33895 +       syscall_continue(debugger->pid);
33896 +}
33897 +
33898 +/* Used by the tracing thread */
33899 +static debugger_state debugger;
33900 +static debugee_state debugee;
33901 +
33902 +void init_proxy (pid_t debugger_pid, int stopped, int status)
33903 +{
33904 +       debugger.pid = debugger_pid;
33905 +       debugger.handle_trace = debugger_syscall;
33906 +       debugger.debugee = &debugee;
33907 +       debugger.waiting = 0;
33908 +       debugger.real_wait = 0;
33909 +       debugger.expecting_child = 0;
33910 +
33911 +       debugee.pid = 0;
33912 +       debugee.traced = 0;
33913 +       debugee.stopped = stopped;
33914 +       debugee.event = 0;
33915 +       debugee.zombie = 0;
33916 +       debugee.died = 0;
33917 +       debugee.wait_status = status;
33918 +       debugee.in_context = 1;
33919 +}
33920 +
33921 +int debugger_proxy(int status, int pid)
33922 +{
33923 +       int ret = 0, sig;
33924 +
33925 +       if(WIFSTOPPED(status)){
33926 +               sig = WSTOPSIG(status);
33927 +               if (sig == SIGTRAP)
33928 +                       ret = (*debugger.handle_trace)(&debugger, pid);
33929 +                                                      
33930 +               else if(sig == SIGCHLD){
33931 +                       if(debugger.expecting_child){
33932 +                               ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
33933 +                               debugger.expecting_child = 0;
33934 +                       }
33935 +                       else if(debugger.waiting)
33936 +                               real_wait_return(&debugger);
33937 +                       else {
33938 +                               ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
33939 +                               debugger.real_wait = 1;
33940 +                       }
33941 +               }
33942 +               else ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
33943 +       }
33944 +       else if(WIFEXITED(status)){
33945 +               tracer_panic("debugger (pid %d) exited with status %d", 
33946 +                            debugger.pid, WEXITSTATUS(status));
33947 +       }
33948 +       else if(WIFSIGNALED(status)){
33949 +               tracer_panic("debugger (pid %d) exited with signal %d", 
33950 +                            debugger.pid, WTERMSIG(status));
33951 +       }
33952 +       else {
33953 +               tracer_panic("proxy got unknown status (0x%x) on debugger "
33954 +                            "(pid %d)", status, debugger.pid);
33955 +       }
33956 +       return(ret);
33957 +}
33958 +
33959 +void child_proxy(pid_t pid, int status)
33960 +{
33961 +       debugee.event = 1;
33962 +       debugee.wait_status = status;
33963 +
33964 +       if(WIFSTOPPED(status)){
33965 +               debugee.stopped = 1;
33966 +               debugger.expecting_child = 1;
33967 +               kill(debugger.pid, SIGCHLD);
33968 +       }
33969 +       else if(WIFEXITED(status) || WIFSIGNALED(status)){
33970 +               debugee.zombie = 1;
33971 +               debugger.expecting_child = 1;
33972 +               kill(debugger.pid, SIGCHLD);
33973 +       }
33974 +       else panic("proxy got unknown status (0x%x) on child (pid %d)", 
33975 +                  status, pid);
33976 +}
33977 +
33978 +void debugger_parent_signal(int status, int pid)
33979 +{
33980 +       int sig;
33981 +
33982 +       if(WIFSTOPPED(status)){
33983 +               sig = WSTOPSIG(status);
33984 +               if(sig == SIGTRAP) (*parent.handle_trace)(&parent, pid);
33985 +               else ptrace(PTRACE_SYSCALL, pid, 0, sig);
33986 +       }
33987 +}
33988 +
33989 +void fake_child_exit(void)
33990 +{
33991 +       int status, pid;
33992 +
33993 +       child_proxy(1, W_EXITCODE(0, 0));
33994 +       while(debugger.waiting == 1){
33995 +               CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
33996 +               if(pid != debugger.pid){
33997 +                       printk("fake_child_exit - waitpid failed, "
33998 +                              "errno = %d\n", errno);
33999 +                       return;
34000 +               }
34001 +               debugger_proxy(status, debugger.pid);
34002 +       }
34003 +       CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
34004 +       if(pid != debugger.pid){
34005 +               printk("fake_child_exit - waitpid failed, "
34006 +                      "errno = %d\n", errno);
34007 +               return;
34008 +       }
34009 +       if(ptrace(PTRACE_DETACH, debugger.pid, 0, SIGCONT) < 0)
34010 +               printk("fake_child_exit - PTRACE_DETACH failed, errno = %d\n",
34011 +                      errno);
34012 +}
34013 +
34014 +char gdb_init_string[] = 
34015 +"att 1 \n\
34016 +b panic \n\
34017 +b stop \n\
34018 +handle SIGWINCH nostop noprint pass \n\
34019 +";
34020 +
34021 +int start_debugger(char *prog, int startup, int stop, int *fd_out)
34022 +{
34023 +       int slave, child;
34024 +
34025 +       slave = open_gdb_chan();
34026 +       child = fork();
34027 +       if(child == 0){
34028 +               char *tempname = NULL;
34029 +               int fd;
34030 +
34031 +               if(setsid() < 0) perror("setsid");
34032 +               if((dup2(slave, 0) < 0) || (dup2(slave, 1) < 0) || 
34033 +                  (dup2(slave, 2) < 0)){
34034 +                       printk("start_debugger : dup2 failed, errno = %d\n",
34035 +                              errno);
34036 +                       exit(1);
34037 +               }
34038 +               if(ioctl(0, TIOCSCTTY, 0) < 0){
34039 +                       printk("start_debugger : TIOCSCTTY failed, "
34040 +                              "errno = %d\n", errno);
34041 +                       exit(1);
34042 +               }
34043 +               if(tcsetpgrp (1, os_getpid()) < 0){
34044 +                       printk("start_debugger : tcsetpgrp failed, "
34045 +                              "errno = %d\n", errno);
34046 +#ifdef notdef
34047 +                       exit(1);
34048 +#endif
34049 +               }
34050 +               fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
34051 +               if(fd < 0){
34052 +                       printk("start_debugger : make_tempfile failed,"
34053 +                              "err = %d\n", -fd);
34054 +                       exit(1);
34055 +               }
34056 +               os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
34057 +               if(startup){
34058 +                       if(stop){
34059 +                               os_write_file(fd, "b start_kernel\n",
34060 +                                     strlen("b start_kernel\n"));
34061 +                       }
34062 +                       os_write_file(fd, "c\n", strlen("c\n"));
34063 +               }
34064 +               if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
34065 +                       printk("start_debugger :  PTRACE_TRACEME failed, "
34066 +                              "errno = %d\n", errno);
34067 +                       exit(1);
34068 +               }
34069 +               execlp("gdb", "gdb", "--command", tempname, prog, NULL);
34070 +               printk("start_debugger : exec of gdb failed, errno = %d\n",
34071 +                      errno);
34072 +       }
34073 +       if(child < 0){
34074 +               printk("start_debugger : fork for gdb failed, errno = %d\n",
34075 +                      errno);
34076 +               return(-1);
34077 +       }
34078 +       *fd_out = slave;
34079 +       return(child);
34080 +}
34081 +
34082 +/*
34083 + * Overrides for Emacs so that we follow Linus's tabbing style.
34084 + * Emacs will notice this stuff at the end of the file and automatically
34085 + * adjust the settings for this buffer only.  This must remain at the end
34086 + * of the file.
34087 + * ---------------------------------------------------------------------------
34088 + * Local variables:
34089 + * c-file-style: "linux"
34090 + * End:
34091 + */
34092 Index: linux-2.4.29/arch/um/kernel/tt/ptproxy/ptproxy.h
34093 ===================================================================
34094 --- linux-2.4.29.orig/arch/um/kernel/tt/ptproxy/ptproxy.h       1970-01-01 03:00:00.000000000 +0300
34095 +++ linux-2.4.29/arch/um/kernel/tt/ptproxy/ptproxy.h    2005-05-03 22:28:14.529401408 +0300
34096 @@ -0,0 +1,61 @@
34097 +/**********************************************************************
34098 +ptproxy.h
34099 +
34100 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
34101 +terms and conditions.
34102 +**********************************************************************/
34103 +
34104 +#ifndef __PTPROXY_H
34105 +#define __PTPROXY_H
34106 +
34107 +#include <sys/types.h>
34108 +
34109 +typedef struct debugger debugger_state;
34110 +typedef struct debugee debugee_state;
34111 +
34112 +struct debugger
34113 +{
34114 +       pid_t pid;
34115 +       int wait_options;
34116 +       int *wait_status_ptr;
34117 +       unsigned int waiting : 1;
34118 +       unsigned int real_wait : 1;
34119 +       unsigned int expecting_child : 1;
34120 +       int (*handle_trace) (debugger_state *, pid_t);
34121 +
34122 +       debugee_state *debugee;
34123 +};
34124 +
34125 +struct debugee
34126 +{
34127 +       pid_t pid;
34128 +       int wait_status;
34129 +       unsigned int died : 1;
34130 +       unsigned int event : 1;
34131 +       unsigned int stopped : 1;
34132 +       unsigned int trace_singlestep : 1;
34133 +       unsigned int trace_syscall : 1;
34134 +       unsigned int traced : 1;
34135 +       unsigned int zombie : 1;
34136 +       unsigned int in_context : 1;
34137 +};
34138 +
34139 +extern int debugger_syscall(debugger_state *debugger, pid_t pid);
34140 +extern int debugger_normal_return (debugger_state *debugger, pid_t unused);
34141 +
34142 +extern long proxy_ptrace (struct debugger *, int, pid_t, long, long, pid_t,
34143 +                         int *strace_out);
34144 +extern void debugger_cancelled_return(debugger_state *debugger, int result);
34145 +
34146 +#endif
34147 +
34148 +/*
34149 + * Overrides for Emacs so that we follow Linus's tabbing style.
34150 + * Emacs will notice this stuff at the end of the file and automatically
34151 + * adjust the settings for this buffer only.  This must remain at the end
34152 + * of the file.
34153 + * ---------------------------------------------------------------------------
34154 + * Local variables:
34155 + * c-file-style: "linux"
34156 + * End:
34157 + */
34158 Index: linux-2.4.29/arch/um/kernel/tt/ptproxy/ptrace.c
34159 ===================================================================
34160 --- linux-2.4.29.orig/arch/um/kernel/tt/ptproxy/ptrace.c        1970-01-01 03:00:00.000000000 +0300
34161 +++ linux-2.4.29/arch/um/kernel/tt/ptproxy/ptrace.c     2005-05-03 22:28:14.531401104 +0300
34162 @@ -0,0 +1,239 @@
34163 +/**********************************************************************
34164 +ptrace.c
34165 +
34166 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
34167 +terms and conditions.
34168 +
34169 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
34170 +**********************************************************************/
34171 +
34172 +#include <errno.h>
34173 +#include <unistd.h>
34174 +#include <signal.h>
34175 +#include <sys/types.h>
34176 +#include <sys/time.h>
34177 +#include <sys/ptrace.h>
34178 +#include <sys/wait.h>
34179 +#include <asm/ptrace.h>
34180 +
34181 +#include "ptproxy.h"
34182 +#include "debug.h"
34183 +#include "user_util.h"
34184 +#include "kern_util.h"
34185 +#include "ptrace_user.h"
34186 +#include "tt.h"
34187 +
34188 +long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
34189 +                 long arg3, long arg4, pid_t child, int *ret)
34190 +{
34191 +       sigset_t relay;
34192 +       long result;
34193 +       int status;
34194 +
34195 +       *ret = 0;
34196 +       if(debugger->debugee->died) return(-ESRCH);
34197 +
34198 +       switch(arg1){
34199 +       case PTRACE_ATTACH:
34200 +               if(debugger->debugee->traced) return(-EPERM);
34201 +
34202 +               debugger->debugee->pid = arg2;
34203 +               debugger->debugee->traced = 1;
34204 +
34205 +               if(is_valid_pid(arg2) && (arg2 != child)){
34206 +                       debugger->debugee->in_context = 0;
34207 +                       kill(arg2, SIGSTOP);
34208 +                       debugger->debugee->event = 1;
34209 +                       debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);
34210 +               }
34211 +               else {
34212 +                       debugger->debugee->in_context = 1;
34213 +                       if(debugger->debugee->stopped) 
34214 +                               child_proxy(child, W_STOPCODE(SIGSTOP));
34215 +                       else kill(child, SIGSTOP);
34216 +               }
34217 +
34218 +               return(0);
34219 +
34220 +       case PTRACE_DETACH:
34221 +               if(!debugger->debugee->traced) return(-EPERM);
34222 +               
34223 +               debugger->debugee->traced = 0;
34224 +               debugger->debugee->pid = 0;
34225 +               if(!debugger->debugee->in_context)
34226 +                       kill(child, SIGCONT);
34227 +
34228 +               return(0);
34229 +
34230 +       case PTRACE_CONT:
34231 +               if(!debugger->debugee->in_context) return(-EPERM);
34232 +               *ret = PTRACE_CONT;
34233 +               return(ptrace(PTRACE_CONT, child, arg3, arg4));
34234 +
34235 +#ifdef UM_HAVE_GETFPREGS
34236 +       case PTRACE_GETFPREGS:
34237 +       {
34238 +               long regs[FP_FRAME_SIZE];
34239 +               int i, result;
34240 +
34241 +               result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
34242 +               if(result == -1) return(-errno);
34243 +               
34244 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
34245 +                       ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
34246 +                              regs[i]);
34247 +               return(result);
34248 +       }
34249 +#endif
34250 +
34251 +#ifdef UM_HAVE_GETFPXREGS
34252 +       case PTRACE_GETFPXREGS:
34253 +       {
34254 +               long regs[FPX_FRAME_SIZE];
34255 +               int i, result;
34256 +
34257 +               result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
34258 +               if(result == -1) return(-errno);
34259 +               
34260 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
34261 +                       ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
34262 +                              regs[i]);
34263 +               return(result);
34264 +       }
34265 +#endif
34266 +
34267 +#ifdef UM_HAVE_GETREGS
34268 +       case PTRACE_GETREGS:
34269 +       {
34270 +               long regs[FRAME_SIZE];
34271 +               int i, result;
34272 +
34273 +               result = ptrace(PTRACE_GETREGS, child, 0, regs);
34274 +               if(result == -1) return(-errno);
34275 +
34276 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
34277 +                       ptrace (PTRACE_POKEDATA, debugger->pid,
34278 +                               arg4 + 4 * i, regs[i]);
34279 +               return(result);
34280 +       }
34281 +       break;
34282 +#endif
34283 +
34284 +       case PTRACE_KILL:
34285 +               result = ptrace(PTRACE_KILL, child, arg3, arg4);
34286 +               if(result == -1) return(-errno);
34287 +
34288 +               return(result);
34289 +
34290 +       case PTRACE_PEEKDATA:
34291 +       case PTRACE_PEEKTEXT:
34292 +       case PTRACE_PEEKUSER:
34293 +               /* The value being read out could be -1, so we have to 
34294 +                * check errno to see if there's an error, and zero it
34295 +                * beforehand so we're not faked out by an old error
34296 +                */
34297 +
34298 +               errno = 0;
34299 +               result = ptrace(arg1, child, arg3, 0);
34300 +               if((result == -1) && (errno != 0)) return(-errno);
34301 +
34302 +               result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
34303 +               if(result == -1) return(-errno);
34304 +                       
34305 +               return(result);
34306 +
34307 +       case PTRACE_POKEDATA:
34308 +       case PTRACE_POKETEXT:
34309 +       case PTRACE_POKEUSER:
34310 +               result = ptrace(arg1, child, arg3, arg4);
34311 +               if(result == -1) return(-errno);
34312 +
34313 +               if(arg1 == PTRACE_POKEUSER) ptrace_pokeuser(arg3, arg4);
34314 +               return(result);
34315 +
34316 +#ifdef UM_HAVE_SETFPREGS
34317 +       case PTRACE_SETFPREGS:
34318 +       {
34319 +               long regs[FP_FRAME_SIZE];
34320 +               int i;
34321 +
34322 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
34323 +                       regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
34324 +                                         arg4 + 4 * i, 0);
34325 +               result = ptrace(PTRACE_SETFPREGS, child, 0, regs);
34326 +               if(result == -1) return(-errno);
34327 +
34328 +               return(result);
34329 +       }
34330 +#endif
34331 +
34332 +#ifdef UM_HAVE_SETFPXREGS
34333 +       case PTRACE_SETFPXREGS:
34334 +       {
34335 +               long regs[FPX_FRAME_SIZE];
34336 +               int i;
34337 +
34338 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
34339 +                       regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
34340 +                                         arg4 + 4 * i, 0);
34341 +               result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);
34342 +               if(result == -1) return(-errno);
34343 +
34344 +               return(result);
34345 +       }
34346 +#endif
34347 +
34348 +#ifdef UM_HAVE_SETREGS
34349 +       case PTRACE_SETREGS:
34350 +       {
34351 +               long regs[FRAME_SIZE];
34352 +               int i;
34353 +
34354 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
34355 +                       regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,
34356 +                                        arg4 + 4 * i, 0);
34357 +               result = ptrace(PTRACE_SETREGS, child, 0, regs);
34358 +               if(result == -1) return(-errno);
34359 +
34360 +               return(result);
34361 +       }
34362 +#endif
34363 +
34364 +       case PTRACE_SINGLESTEP:
34365 +               if(!debugger->debugee->in_context) return(-EPERM);
34366 +               sigemptyset(&relay);
34367 +               sigaddset(&relay, SIGSEGV);
34368 +               sigaddset(&relay, SIGILL);
34369 +               sigaddset(&relay, SIGBUS);
34370 +               result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4);
34371 +               if(result == -1) return(-errno);
34372 +               
34373 +               status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
34374 +                                      &relay);
34375 +               child_proxy(child, status);
34376 +               return(result);
34377 +
34378 +       case PTRACE_SYSCALL:
34379 +               if(!debugger->debugee->in_context) return(-EPERM);
34380 +               result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);
34381 +               if(result == -1) return(-errno);
34382 +
34383 +               *ret = PTRACE_SYSCALL;
34384 +               return(result);
34385 +
34386 +       case PTRACE_TRACEME:
34387 +       default:
34388 +               return(-EINVAL);
34389 +       }
34390 +}
34391 +
34392 +/*
34393 + * Overrides for Emacs so that we follow Linus's tabbing style.
34394 + * Emacs will notice this stuff at the end of the file and automatically
34395 + * adjust the settings for this buffer only.  This must remain at the end
34396 + * of the file.
34397 + * ---------------------------------------------------------------------------
34398 + * Local variables:
34399 + * c-file-style: "linux"
34400 + * End:
34401 + */
34402 Index: linux-2.4.29/arch/um/kernel/tt/ptproxy/sysdep.c
34403 ===================================================================
34404 --- linux-2.4.29.orig/arch/um/kernel/tt/ptproxy/sysdep.c        1970-01-01 03:00:00.000000000 +0300
34405 +++ linux-2.4.29/arch/um/kernel/tt/ptproxy/sysdep.c     2005-05-03 22:28:14.532400952 +0300
34406 @@ -0,0 +1,72 @@
34407 +/**********************************************************************
34408 +sysdep.c
34409 +
34410 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
34411 +terms and conditions.
34412 +**********************************************************************/
34413 +
34414 +#include <stdio.h>
34415 +#include <string.h>
34416 +#include <stdlib.h>
34417 +#include <signal.h>
34418 +#include <errno.h>
34419 +#include <sys/types.h>
34420 +#include <sys/ptrace.h>
34421 +#include <asm/ptrace.h>
34422 +#include <linux/unistd.h>
34423 +#include "ptrace_user.h"
34424 +#include "user_util.h"
34425 +#include "user.h"
34426 +
34427 +int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4, 
34428 +               long *arg5)
34429 +{
34430 +       *arg1 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG1_OFFSET, 0);
34431 +       *arg2 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG2_OFFSET, 0);
34432 +       *arg3 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG3_OFFSET, 0);
34433 +       *arg4 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG4_OFFSET, 0);
34434 +       *arg5 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG5_OFFSET, 0);
34435 +       return(ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET, 0));
34436 +}
34437 +
34438 +void syscall_cancel(pid_t pid, int result)
34439 +{
34440 +       if((ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
34441 +                  __NR_getpid) < 0) ||
34442 +          (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) ||
34443 +          (wait_for_stop(pid, SIGTRAP, PTRACE_SYSCALL, NULL) < 0) ||
34444 +          (ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result) < 0) ||
34445 +          (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0))
34446 +               printk("ptproxy: couldn't cancel syscall: errno = %d\n", 
34447 +                      errno);
34448 +}
34449 +
34450 +void syscall_set_result(pid_t pid, long result)
34451 +{
34452 +       ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result);
34453 +}
34454 +
34455 +void syscall_continue(pid_t pid)
34456 +{
34457 +       ptrace(PTRACE_SYSCALL, pid, 0, 0);
34458 +}
34459 +
34460 +int syscall_pause(pid_t pid) 
34461 +{
34462 +       if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_pause) < 0){
34463 +               printk("syscall_change - ptrace failed, errno = %d\n", errno);
34464 +               return(-1);
34465 +       }
34466 +       return(0);
34467 +}
34468 +
34469 +/*
34470 + * Overrides for Emacs so that we follow Linus's tabbing style.
34471 + * Emacs will notice this stuff at the end of the file and automatically
34472 + * adjust the settings for this buffer only.  This must remain at the end
34473 + * of the file.
34474 + * ---------------------------------------------------------------------------
34475 + * Local variables:
34476 + * c-file-style: "linux"
34477 + * End:
34478 + */
34479 Index: linux-2.4.29/arch/um/kernel/tt/ptproxy/sysdep.h
34480 ===================================================================
34481 --- linux-2.4.29.orig/arch/um/kernel/tt/ptproxy/sysdep.h        1970-01-01 03:00:00.000000000 +0300
34482 +++ linux-2.4.29/arch/um/kernel/tt/ptproxy/sysdep.h     2005-05-03 22:28:14.533400800 +0300
34483 @@ -0,0 +1,25 @@
34484 +/**********************************************************************
34485 +sysdep.h
34486 +
34487 +Copyright (C) 1999 Lars Brinkhoff.
34488 +Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
34489 +See the file COPYING for licensing terms and conditions.
34490 +**********************************************************************/
34491 +
34492 +extern int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, 
34493 +                      long *arg4, long *arg5);
34494 +extern void syscall_cancel (pid_t pid, long result);
34495 +extern void syscall_set_result (pid_t pid, long result);
34496 +extern void syscall_continue (pid_t pid);
34497 +extern int syscall_pause(pid_t pid);
34498 +
34499 +/*
34500 + * Overrides for Emacs so that we follow Linus's tabbing style.
34501 + * Emacs will notice this stuff at the end of the file and automatically
34502 + * adjust the settings for this buffer only.  This must remain at the end
34503 + * of the file.
34504 + * ---------------------------------------------------------------------------
34505 + * Local variables:
34506 + * c-file-style: "linux"
34507 + * End:
34508 + */
34509 Index: linux-2.4.29/arch/um/kernel/tt/ptproxy/wait.c
34510 ===================================================================
34511 --- linux-2.4.29.orig/arch/um/kernel/tt/ptproxy/wait.c  1970-01-01 03:00:00.000000000 +0300
34512 +++ linux-2.4.29/arch/um/kernel/tt/ptproxy/wait.c       2005-05-03 22:28:14.534400648 +0300
34513 @@ -0,0 +1,88 @@
34514 +/**********************************************************************
34515 +wait.c
34516 +
34517 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
34518 +terms and conditions.
34519 +
34520 +**********************************************************************/
34521 +
34522 +#include <errno.h>
34523 +#include <signal.h>
34524 +#include <sys/wait.h>
34525 +#include <sys/ptrace.h>
34526 +#include <asm/ptrace.h>
34527 +
34528 +#include "ptproxy.h"
34529 +#include "sysdep.h"
34530 +#include "wait.h"
34531 +#include "user_util.h"
34532 +#include "sysdep/ptrace.h"
34533 +#include "sysdep/ptrace_user.h"
34534 +#include "sysdep/sigcontext.h"
34535 +
34536 +int proxy_wait_return(struct debugger *debugger, pid_t unused)
34537 +{
34538 +       debugger->waiting = 0;
34539 +
34540 +       if(debugger->debugee->died || (debugger->wait_options & __WCLONE)){
34541 +               debugger_cancelled_return(debugger, -ECHILD);
34542 +               return(0);
34543 +       }
34544 +
34545 +       if(debugger->debugee->zombie && debugger->debugee->event)
34546 +               debugger->debugee->died = 1;
34547 +
34548 +       if(debugger->debugee->event){
34549 +               debugger->debugee->event = 0;
34550 +               ptrace(PTRACE_POKEDATA, debugger->pid,
34551 +                      debugger->wait_status_ptr, 
34552 +                      debugger->debugee->wait_status);
34553 +               /* if (wait4)
34554 +                  ptrace (PTRACE_POKEDATA, pid, rusage_ptr, ...); */
34555 +               debugger_cancelled_return(debugger, debugger->debugee->pid);
34556 +               return(0);
34557 +       }
34558 +
34559 +       /* pause will return -EINTR, which happens to be right for wait */
34560 +       debugger_normal_return(debugger, -1);
34561 +       return(0);
34562 +}
34563 +
34564 +int parent_wait_return(struct debugger *debugger, pid_t unused)
34565 +{
34566 +       return(debugger_normal_return(debugger, -1));
34567 +}
34568 +
34569 +int real_wait_return(struct debugger *debugger)
34570 +{
34571 +       unsigned long ip;
34572 +       int pid;
34573 +
34574 +       pid = debugger->pid;
34575 +
34576 +       ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
34577 +       IP_RESTART_SYSCALL(ip);
34578 +
34579 +       if(ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip) < 0)
34580 +               tracer_panic("real_wait_return : Failed to restart system "
34581 +                            "call, errno = %d\n", errno);
34582 +
34583 +       if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
34584 +          (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
34585 +          (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
34586 +          debugger_normal_return(debugger, -1))
34587 +               tracer_panic("real_wait_return : gdb failed to wait, "
34588 +                            "errno = %d\n", errno);
34589 +       return(0);
34590 +}
34591 +
34592 +/*
34593 + * Overrides for Emacs so that we follow Linus's tabbing style.
34594 + * Emacs will notice this stuff at the end of the file and automatically
34595 + * adjust the settings for this buffer only.  This must remain at the end
34596 + * of the file.
34597 + * ---------------------------------------------------------------------------
34598 + * Local variables:
34599 + * c-file-style: "linux"
34600 + * End:
34601 + */
34602 Index: linux-2.4.29/arch/um/kernel/tt/ptproxy/wait.h
34603 ===================================================================
34604 --- linux-2.4.29.orig/arch/um/kernel/tt/ptproxy/wait.h  1970-01-01 03:00:00.000000000 +0300
34605 +++ linux-2.4.29/arch/um/kernel/tt/ptproxy/wait.h       2005-05-03 22:28:14.534400648 +0300
34606 @@ -0,0 +1,15 @@
34607 +/**********************************************************************
34608 +wait.h
34609 +
34610 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
34611 +terms and conditions.
34612 +**********************************************************************/
34613 +
34614 +#ifndef __PTPROXY_WAIT_H
34615 +#define __PTPROXY_WAIT_H
34616 +
34617 +extern int proxy_wait_return(struct debugger *debugger, pid_t unused);
34618 +extern int real_wait_return(struct debugger *debugger);
34619 +extern int parent_wait_return(struct debugger *debugger, pid_t unused);
34620 +
34621 +#endif
34622 Index: linux-2.4.29/arch/um/kernel/tt/syscall_kern.c
34623 ===================================================================
34624 --- linux-2.4.29.orig/arch/um/kernel/tt/syscall_kern.c  1970-01-01 03:00:00.000000000 +0300
34625 +++ linux-2.4.29/arch/um/kernel/tt/syscall_kern.c       2005-05-03 22:28:14.536400344 +0300
34626 @@ -0,0 +1,136 @@
34627 +/* 
34628 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
34629 + * Licensed under the GPL
34630 + */
34631 +
34632 +#include "linux/types.h"
34633 +#include "linux/utime.h"
34634 +#include "linux/sys.h"
34635 +#include "asm/unistd.h"
34636 +#include "asm/ptrace.h"
34637 +#include "asm/uaccess.h"
34638 +#include "sysdep/syscalls.h"
34639 +#include "kern_util.h"
34640 +
34641 +static inline int check_area(void *ptr, int size)
34642 +{
34643 +       return(verify_area(VERIFY_WRITE, ptr, size));
34644 +}
34645 +
34646 +static int check_readlink(struct pt_regs *regs)
34647 +{
34648 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
34649 +                         UPT_SYSCALL_ARG2(&regs->regs)));
34650 +}
34651 +
34652 +static int check_utime(struct pt_regs *regs)
34653 +{
34654 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
34655 +                         sizeof(struct utimbuf)));
34656 +}
34657 +
34658 +static int check_oldstat(struct pt_regs *regs)
34659 +{
34660 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
34661 +                         sizeof(struct __old_kernel_stat)));
34662 +}
34663 +
34664 +static int check_stat(struct pt_regs *regs)
34665 +{
34666 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
34667 +                         sizeof(struct stat)));
34668 +}
34669 +
34670 +static int check_stat64(struct pt_regs *regs)
34671 +{
34672 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
34673 +                         sizeof(struct stat64)));
34674 +}
34675 +
34676 +struct bogus {
34677 +       int kernel_ds;
34678 +       int (*check_params)(struct pt_regs *);
34679 +};
34680 +
34681 +struct bogus this_is_bogus[256] = {
34682 +       [ __NR_mknod ] = { 1, NULL },
34683 +       [ __NR_mkdir ] = { 1, NULL },
34684 +       [ __NR_rmdir ] = { 1, NULL },
34685 +       [ __NR_unlink ] = { 1, NULL },
34686 +       [ __NR_symlink ] = { 1, NULL },
34687 +       [ __NR_link ] = { 1, NULL },
34688 +       [ __NR_rename ] = { 1, NULL },
34689 +       [ __NR_umount ] = { 1, NULL },
34690 +       [ __NR_mount ] = { 1, NULL },
34691 +       [ __NR_pivot_root ] = { 1, NULL },
34692 +       [ __NR_chdir ] = { 1, NULL },
34693 +       [ __NR_chroot ] = { 1, NULL },
34694 +       [ __NR_open ] = { 1, NULL },
34695 +       [ __NR_quotactl ] = { 1, NULL },
34696 +       [ __NR_sysfs ] = { 1, NULL },
34697 +       [ __NR_readlink ] = { 1, check_readlink },
34698 +       [ __NR_acct ] = { 1, NULL },
34699 +       [ __NR_execve ] = { 1, NULL },
34700 +       [ __NR_uselib ] = { 1, NULL },
34701 +       [ __NR_statfs ] = { 1, NULL },
34702 +       [ __NR_truncate ] = { 1, NULL },
34703 +       [ __NR_access ] = { 1, NULL },
34704 +       [ __NR_chmod ] = { 1, NULL },
34705 +       [ __NR_chown ] = { 1, NULL },
34706 +       [ __NR_lchown ] = { 1, NULL },
34707 +       [ __NR_utime ] = { 1, check_utime },
34708 +       [ __NR_oldlstat ] = { 1, check_oldstat },
34709 +       [ __NR_oldstat ] = { 1, check_oldstat },
34710 +       [ __NR_stat ] = { 1, check_stat },
34711 +       [ __NR_lstat ] = { 1, check_stat },
34712 +       [ __NR_stat64 ] = { 1, check_stat64 },
34713 +       [ __NR_lstat64 ] = { 1, check_stat64 },
34714 +       [ __NR_chown32 ] = { 1, NULL },
34715 +};
34716 +
34717 +/* sys_utimes */
34718 +
34719 +static int check_bogosity(struct pt_regs *regs)
34720 +{
34721 +       struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(&regs->regs)];
34722 +
34723 +       if(!bogon->kernel_ds) return(0);
34724 +       if(bogon->check_params && (*bogon->check_params)(regs))
34725 +               return(-EFAULT);
34726 +       set_fs(KERNEL_DS);
34727 +       return(0);
34728 +}
34729 +
34730 +extern syscall_handler_t *sys_call_table[];
34731 +
34732 +long execute_syscall_tt(void *r)
34733 +{
34734 +       struct pt_regs *regs = r;
34735 +       long res;
34736 +       int syscall;
34737 +
34738 +       current->thread.nsyscalls++;
34739 +       nsyscalls++;
34740 +       syscall = UPT_SYSCALL_NR(&regs->regs);
34741 +
34742 +       if((syscall >= NR_syscalls) || (syscall < 0))
34743 +               res = -ENOSYS;
34744 +       else if(honeypot && check_bogosity(regs))
34745 +               res = -EFAULT;
34746 +       else res = EXECUTE_SYSCALL(syscall, regs);
34747 +
34748 +       set_fs(USER_DS);
34749 +
34750 +       return(res);
34751 +}
34752 +
34753 +/*
34754 + * Overrides for Emacs so that we follow Linus's tabbing style.
34755 + * Emacs will notice this stuff at the end of the file and automatically
34756 + * adjust the settings for this buffer only.  This must remain at the end
34757 + * of the file.
34758 + * ---------------------------------------------------------------------------
34759 + * Local variables:
34760 + * c-file-style: "linux"
34761 + * End:
34762 + */
34763 Index: linux-2.4.29/arch/um/kernel/tt/syscall_user.c
34764 ===================================================================
34765 --- linux-2.4.29.orig/arch/um/kernel/tt/syscall_user.c  1970-01-01 03:00:00.000000000 +0300
34766 +++ linux-2.4.29/arch/um/kernel/tt/syscall_user.c       2005-05-03 22:28:14.537400192 +0300
34767 @@ -0,0 +1,92 @@
34768 +/* 
34769 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
34770 + * Licensed under the GPL
34771 + */
34772 +
34773 +#include <unistd.h>
34774 +#include <signal.h>
34775 +#include <errno.h>
34776 +#include <sys/ptrace.h>
34777 +#include <asm/unistd.h>
34778 +#include "sysdep/ptrace.h"
34779 +#include "sigcontext.h"
34780 +#include "ptrace_user.h"
34781 +#include "task.h"
34782 +#include "user_util.h"
34783 +#include "kern_util.h"
34784 +#include "syscall_user.h"
34785 +#include "tt.h"
34786 +
34787 +/* XXX Bogus */
34788 +#define ERESTARTSYS    512
34789 +#define ERESTARTNOINTR 513
34790 +#define ERESTARTNOHAND 514
34791 +
34792 +void syscall_handler_tt(int sig, union uml_pt_regs *regs)
34793 +{
34794 +       void *sc;
34795 +       long result;
34796 +       int index, syscall;
34797 +
34798 +       syscall = UPT_SYSCALL_NR(regs);
34799 +       sc = UPT_SC(regs);
34800 +       SC_START_SYSCALL(sc);
34801 +
34802 +       index = record_syscall_start(syscall);
34803 +       syscall_trace();
34804 +       result = execute_syscall(regs);
34805 +
34806 +       /* regs->sc may have changed while the system call ran (there may
34807 +        * have been an interrupt or segfault), so it needs to be refreshed.
34808 +        */
34809 +       UPT_SC(regs) = sc;
34810 +
34811 +       SC_SET_SYSCALL_RETURN(sc, result);
34812 +       if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || 
34813 +          (result == -ERESTARTNOINTR))
34814 +               do_signal(result);
34815 +
34816 +       syscall_trace();
34817 +       record_syscall_end(index, result);
34818 +}
34819 +
34820 +int do_syscall(void *task, int pid)
34821 +{
34822 +       unsigned long proc_regs[FRAME_SIZE];
34823 +       union uml_pt_regs *regs;
34824 +       int syscall;
34825 +
34826 +       if(ptrace_getregs(pid, proc_regs) < 0)
34827 +               tracer_panic("Couldn't read registers");
34828 +       syscall = PT_SYSCALL_NR(proc_regs);
34829 +
34830 +       regs = TASK_REGS(task);
34831 +       UPT_SYSCALL_NR(regs) = syscall;
34832 +
34833 +       if(syscall < 1) return(0);
34834 +
34835 +       if((syscall != __NR_sigreturn) &&
34836 +          ((unsigned long *) PT_IP(proc_regs) >= &_stext) && 
34837 +          ((unsigned long *) PT_IP(proc_regs) <= &_etext))
34838 +               tracer_panic("I'm tracing myself and I can't get out");
34839 +
34840 +       if(use_sysemu) 
34841 +               return(1);
34842 +
34843 +       if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
34844 +                 __NR_getpid) < 0)
34845 +               tracer_panic("do_syscall : Nullifying syscall failed, "
34846 +                            "errno = %d", errno);
34847 +       return(1);
34848 +}
34849 +
34850 +/*
34851 + * Overrides for Emacs so that we follow Linus's tabbing style.
34852 + * Emacs will notice this stuff at the end of the file and automatically
34853 + * adjust the settings for this buffer only.  This must remain at the end
34854 + * of the file.
34855 + * ---------------------------------------------------------------------------
34856 + * Local variables:
34857 + * c-file-style: "linux"
34858 + * End:
34859 + */
34860 Index: linux-2.4.29/arch/um/kernel/tt/sys-i386/Makefile
34861 ===================================================================
34862 --- linux-2.4.29.orig/arch/um/kernel/tt/sys-i386/Makefile       1970-01-01 03:00:00.000000000 +0300
34863 +++ linux-2.4.29/arch/um/kernel/tt/sys-i386/Makefile    2005-05-03 22:28:14.538400040 +0300
34864 @@ -0,0 +1,17 @@
34865 +# 
34866 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34867 +# Licensed under the GPL
34868 +#
34869 +
34870 +O_TARGET = sys-i386.o
34871 +
34872 +obj-y = sigcontext.o
34873 +
34874 +USER_OBJS = sigcontext.o
34875 +
34876 +include $(TOPDIR)/Rules.make
34877 +
34878 +$(USER_OBJS) : %.o: %.c
34879 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
34880 +
34881 +clean :
34882 Index: linux-2.4.29/arch/um/kernel/tt/sys-i386/sigcontext.c
34883 ===================================================================
34884 --- linux-2.4.29.orig/arch/um/kernel/tt/sys-i386/sigcontext.c   1970-01-01 03:00:00.000000000 +0300
34885 +++ linux-2.4.29/arch/um/kernel/tt/sys-i386/sigcontext.c        2005-05-03 22:28:14.539399888 +0300
34886 @@ -0,0 +1,60 @@
34887 +/* 
34888 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34889 + * Licensed under the GPL
34890 + */
34891 +
34892 +#include <stdlib.h>
34893 +#include <asm/sigcontext.h>
34894 +#include "kern_util.h"
34895 +#include "sysdep/frame.h"
34896 +
34897 +int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data)
34898 +{
34899 +       struct arch_frame_data *arch = data;
34900 +       struct sigcontext *to = to_ptr, *from = from_ptr;
34901 +       struct _fpstate *to_fp, *from_fp;
34902 +       unsigned long sigs;
34903 +       int err;
34904 +
34905 +       to_fp = to->fpstate;
34906 +       from_fp = from->fpstate;
34907 +       sigs = to->oldmask;
34908 +       err = copy_from_user_proc(to, from, sizeof(*to));
34909 +       to->oldmask = sigs;
34910 +       if(to_fp != NULL){
34911 +               err |= copy_from_user_proc(&to->fpstate, &to_fp,
34912 +                                          sizeof(to->fpstate));
34913 +               err |= copy_from_user_proc(to_fp, from_fp, arch->fpstate_size);
34914 +       }
34915 +       return(err);
34916 +}
34917 +
34918 +int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data)
34919 +{
34920 +       struct arch_frame_data *arch = data;
34921 +       struct sigcontext *to = to_ptr, *from = from_ptr;
34922 +       struct _fpstate *to_fp, *from_fp;
34923 +       int err;
34924 +
34925 +       to_fp = (struct _fpstate *) 
34926 +               (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
34927 +       from_fp = from->fpstate;
34928 +       err = copy_to_user_proc(to, from, sizeof(*to));
34929 +       if(from_fp != NULL){
34930 +               err |= copy_to_user_proc(&to->fpstate, &to_fp,
34931 +                                        sizeof(to->fpstate));
34932 +               err |= copy_to_user_proc(to_fp, from_fp, arch->fpstate_size);
34933 +       }
34934 +       return(err);
34935 +}
34936 +
34937 +/*
34938 + * Overrides for Emacs so that we follow Linus's tabbing style.
34939 + * Emacs will notice this stuff at the end of the file and automatically
34940 + * adjust the settings for this buffer only.  This must remain at the end
34941 + * of the file.
34942 + * ---------------------------------------------------------------------------
34943 + * Local variables:
34944 + * c-file-style: "linux"
34945 + * End:
34946 + */
34947 Index: linux-2.4.29/arch/um/kernel/tt/time.c
34948 ===================================================================
34949 --- linux-2.4.29.orig/arch/um/kernel/tt/time.c  1970-01-01 03:00:00.000000000 +0300
34950 +++ linux-2.4.29/arch/um/kernel/tt/time.c       2005-05-03 22:28:14.540399736 +0300
34951 @@ -0,0 +1,28 @@
34952 +/* 
34953 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
34954 + * Licensed under the GPL
34955 + */
34956 +
34957 +#include <signal.h>
34958 +#include <sys/time.h>
34959 +#include <time_user.h>
34960 +#include "process.h"
34961 +#include "user.h"
34962 +
34963 +void user_time_init_tt(void)
34964 +{
34965 +       if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
34966 +               panic("Couldn't set SIGVTALRM handler");
34967 +       set_interval(ITIMER_VIRTUAL);
34968 +}
34969 +
34970 +/*
34971 + * Overrides for Emacs so that we follow Linus's tabbing style.
34972 + * Emacs will notice this stuff at the end of the file and automatically
34973 + * adjust the settings for this buffer only.  This must remain at the end
34974 + * of the file.
34975 + * ---------------------------------------------------------------------------
34976 + * Local variables:
34977 + * c-file-style: "linux"
34978 + * End:
34979 + */
34980 Index: linux-2.4.29/arch/um/kernel/tt/tlb.c
34981 ===================================================================
34982 --- linux-2.4.29.orig/arch/um/kernel/tt/tlb.c   1970-01-01 03:00:00.000000000 +0300
34983 +++ linux-2.4.29/arch/um/kernel/tt/tlb.c        2005-05-03 22:28:14.541399584 +0300
34984 @@ -0,0 +1,220 @@
34985 +/* 
34986 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34987 + * Licensed under the GPL
34988 + */
34989 +
34990 +#include "linux/stddef.h"
34991 +#include "linux/kernel.h"
34992 +#include "linux/sched.h"
34993 +#include "asm/page.h"
34994 +#include "asm/pgtable.h"
34995 +#include "asm/uaccess.h"
34996 +#include "user_util.h"
34997 +#include "mem_user.h"
34998 +#include "os.h"
34999 +
35000 +static void fix_range(struct mm_struct *mm, unsigned long start_addr, 
35001 +                     unsigned long end_addr, int force)
35002 +{
35003 +       pgd_t *npgd;
35004 +       pmd_t *npmd;
35005 +       pte_t *npte;
35006 +       unsigned long addr;
35007 +       int r, w, x, err;
35008 +
35009 +       if((current->thread.mode.tt.extern_pid != -1) && 
35010 +          (current->thread.mode.tt.extern_pid != os_getpid()))
35011 +               panic("fix_range fixing wrong address space, current = 0x%p",
35012 +                     current);
35013 +       if(mm == NULL) return;
35014 +       for(addr=start_addr;addr<end_addr;){
35015 +               if(addr == TASK_SIZE){
35016 +                       /* Skip over kernel text, kernel data, and physical
35017 +                        * memory, which don't have ptes, plus kernel virtual
35018 +                        * memory, which is flushed separately, and remap
35019 +                        * the process stack.  The only way to get here is
35020 +                        * if (end_addr == STACK_TOP) > TASK_SIZE, which is
35021 +                        * only true in the honeypot case.
35022 +                        */
35023 +                       addr = STACK_TOP - ABOVE_KMEM;
35024 +                       continue;
35025 +               }
35026 +               npgd = pgd_offset(mm, addr);
35027 +               npmd = pmd_offset(npgd, addr);
35028 +               if(pmd_present(*npmd)){
35029 +                       npte = pte_offset(npmd, addr);
35030 +                       r = pte_read(*npte);
35031 +                       w = pte_write(*npte);
35032 +                       x = pte_exec(*npte);
35033 +                       if(!pte_dirty(*npte)) w = 0;
35034 +                       if(!pte_young(*npte)){
35035 +                               r = 0;
35036 +                               w = 0;
35037 +                       }
35038 +                       if(force || pte_newpage(*npte)){
35039 +                               err = os_unmap_memory((void *) addr, 
35040 +                                                     PAGE_SIZE);
35041 +                               if(err < 0)
35042 +                                       panic("munmap failed, errno = %d\n",
35043 +                                             -err);
35044 +                               if(pte_present(*npte))
35045 +                                       map_memory(addr, 
35046 +                                                  pte_val(*npte) & PAGE_MASK,
35047 +                                                  PAGE_SIZE, r, w, x);
35048 +                       }
35049 +                       else if(pte_newprot(*npte)){
35050 +                               protect_memory(addr, PAGE_SIZE, r, w, x, 1);
35051 +                       }
35052 +                       *npte = pte_mkuptodate(*npte);
35053 +                       addr += PAGE_SIZE;
35054 +               }
35055 +               else {
35056 +                       if(force || pmd_newpage(*npmd)){
35057 +                               err = os_unmap_memory((void *) addr, PMD_SIZE);
35058 +                               if(err < 0)
35059 +                                       panic("munmap failed, errno = %d\n",
35060 +                                             -err);
35061 +                               pmd_mkuptodate(*npmd);
35062 +                       }
35063 +                       addr += PMD_SIZE;
35064 +               }
35065 +       }
35066 +}
35067 +
35068 +atomic_t vmchange_seq = ATOMIC_INIT(1);
35069 +
35070 +static void flush_kernel_vm_range(unsigned long start, unsigned long end,
35071 +                                 int update_seq)
35072 +{
35073 +       struct mm_struct *mm;
35074 +       pgd_t *pgd;
35075 +       pmd_t *pmd;
35076 +       pte_t *pte;
35077 +       unsigned long addr;
35078 +       int updated = 0, err;
35079 +
35080 +       mm = &init_mm;
35081 +       for(addr = start; addr < end;){
35082 +               pgd = pgd_offset(mm, addr);
35083 +               pmd = pmd_offset(pgd, addr);
35084 +               if(pmd_present(*pmd)){
35085 +                       pte = pte_offset(pmd, addr);
35086 +                       if(!pte_present(*pte) || pte_newpage(*pte)){
35087 +                               updated = 1;
35088 +                               err = os_unmap_memory((void *) addr, 
35089 +                                                     PAGE_SIZE);
35090 +                               if(err < 0)
35091 +                                       panic("munmap failed, errno = %d\n",
35092 +                                             -err);
35093 +                               if(pte_present(*pte))
35094 +                                       map_memory(addr, 
35095 +                                                  pte_val(*pte) & PAGE_MASK,
35096 +                                                  PAGE_SIZE, 1, 1, 1);
35097 +                       }
35098 +                       else if(pte_newprot(*pte)){
35099 +                               updated = 1;
35100 +                               protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
35101 +                       }
35102 +                       addr += PAGE_SIZE;
35103 +               }
35104 +               else {
35105 +                       if(pmd_newpage(*pmd)){
35106 +                               updated = 1;
35107 +                               err = os_unmap_memory((void *) addr, PMD_SIZE);
35108 +                               if(err < 0)
35109 +                                       panic("munmap failed, errno = %d\n",
35110 +                                             -err);
35111 +                       }
35112 +                       addr += PMD_SIZE;
35113 +               }
35114 +       }
35115 +       if(updated && update_seq) atomic_inc(&vmchange_seq);
35116 +}
35117 +
35118 +static void protect_vm_page(unsigned long addr, int w, int must_succeed)
35119 +{
35120 +       int err;
35121 +
35122 +       err = protect_memory(addr, PAGE_SIZE, 1, w, 1, must_succeed);
35123 +       if(err == 0) return;
35124 +       else if((err == -EFAULT) || (err == -ENOMEM)){
35125 +               flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
35126 +               protect_vm_page(addr, w, 1);
35127 +       }
35128 +       else panic("protect_vm_page : protect failed, errno = %d\n", err);
35129 +}
35130 +
35131 +void mprotect_kernel_vm(int w)
35132 +{
35133 +       struct mm_struct *mm;
35134 +       pgd_t *pgd;
35135 +       pmd_t *pmd;
35136 +       pte_t *pte;
35137 +       unsigned long addr;
35138 +       
35139 +       mm = &init_mm;
35140 +       for(addr = start_vm; addr < end_vm;){
35141 +               pgd = pgd_offset(mm, addr);
35142 +               pmd = pmd_offset(pgd, addr);
35143 +               if(pmd_present(*pmd)){
35144 +                       pte = pte_offset(pmd, addr);
35145 +                       if(pte_present(*pte)) protect_vm_page(addr, w, 0);
35146 +                       addr += PAGE_SIZE;
35147 +               }
35148 +               else addr += PMD_SIZE;
35149 +       }
35150 +}
35151 +
35152 +void flush_tlb_kernel_vm_tt(void)
35153 +{
35154 +       flush_kernel_vm_range(start_vm, end_vm, 1);
35155 +}
35156 +
35157 +void __flush_tlb_one_tt(unsigned long addr)
35158 +{
35159 +       flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
35160 +}
35161 +
35162 +void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start, 
35163 +                    unsigned long end)
35164 +{
35165 +       if(mm != current->mm) return;
35166 +
35167 +       /* Assumes that the range start ... end is entirely within
35168 +        * either process memory or kernel vm
35169 +        */
35170 +       if((start >= start_vm) && (start < end_vm)) 
35171 +               flush_kernel_vm_range(start, end, 1);
35172 +       else fix_range(mm, start, end, 0);
35173 +}
35174 +
35175 +void flush_tlb_mm_tt(struct mm_struct *mm)
35176 +{
35177 +       unsigned long seq;
35178 +
35179 +       if(mm != current->mm) return;
35180 +
35181 +       fix_range(mm, 0, STACK_TOP, 0);
35182 +
35183 +       seq = atomic_read(&vmchange_seq);
35184 +       if(current->thread.mode.tt.vm_seq == seq) return;
35185 +       current->thread.mode.tt.vm_seq = seq;
35186 +       flush_kernel_vm_range(start_vm, end_vm, 0);
35187 +}
35188 +
35189 +void force_flush_all_tt(void)
35190 +{
35191 +       fix_range(current->mm, 0, STACK_TOP, 1);
35192 +       flush_kernel_vm_range(start_vm, end_vm, 0);
35193 +}
35194 +
35195 +/*
35196 + * Overrides for Emacs so that we follow Linus's tabbing style.
35197 + * Emacs will notice this stuff at the end of the file and automatically
35198 + * adjust the settings for this buffer only.  This must remain at the end
35199 + * of the file.
35200 + * ---------------------------------------------------------------------------
35201 + * Local variables:
35202 + * c-file-style: "linux"
35203 + * End:
35204 + */
35205 Index: linux-2.4.29/arch/um/kernel/tt/tracer.c
35206 ===================================================================
35207 --- linux-2.4.29.orig/arch/um/kernel/tt/tracer.c        1970-01-01 03:00:00.000000000 +0300
35208 +++ linux-2.4.29/arch/um/kernel/tt/tracer.c     2005-05-03 22:28:14.543399280 +0300
35209 @@ -0,0 +1,457 @@
35210 +/* 
35211 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
35212 + * Licensed under the GPL
35213 + */
35214 +
35215 +#include <stdio.h>
35216 +#include <stdlib.h>
35217 +#include <stdarg.h>
35218 +#include <unistd.h>
35219 +#include <signal.h>
35220 +#include <errno.h>
35221 +#include <sched.h>
35222 +#include <string.h>
35223 +#include <sys/mman.h>
35224 +#include <sys/ptrace.h>
35225 +#include <sys/time.h>
35226 +#include <sys/wait.h>
35227 +#include "user.h"
35228 +#include "sysdep/ptrace.h"
35229 +#include "sigcontext.h"
35230 +#include "sysdep/sigcontext.h"
35231 +#include "os.h"
35232 +#include "signal_user.h"
35233 +#include "user_util.h"
35234 +#include "mem_user.h"
35235 +#include "process.h"
35236 +#include "kern_util.h"
35237 +#include "frame.h"
35238 +#include "chan_user.h"
35239 +#include "ptrace_user.h"
35240 +#include "mode.h"
35241 +#include "tt.h"
35242 +
35243 +static int tracer_winch[2];
35244 +
35245 +int is_tracer_winch(int pid, int fd, void *data)
35246 +{
35247 +       if(pid != tracing_pid)
35248 +               return(0);
35249 +
35250 +       register_winch_irq(tracer_winch[0], fd, -1, data);
35251 +       return(1);
35252 +}
35253 +
35254 +static void tracer_winch_handler(int sig)
35255 +{
35256 +       int n;
35257 +       char c = 1;
35258 +
35259 +       n = os_write_file(tracer_winch[1], &c, sizeof(c));
35260 +       if(n != sizeof(c))
35261 +               printk("tracer_winch_handler - write failed, err = %d\n", -n);
35262 +}
35263 +
35264 +/* Called only by the tracing thread during initialization */
35265 +
35266 +static void setup_tracer_winch(void)
35267 +{
35268 +       int err;
35269 +
35270 +       err = os_pipe(tracer_winch, 1, 1);
35271 +       if(err < 0){
35272 +               printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
35273 +               return;
35274 +       }
35275 +       signal(SIGWINCH, tracer_winch_handler);
35276 +}
35277 +
35278 +void attach_process(int pid)
35279 +{
35280 +       if((ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) ||
35281 +          (ptrace(PTRACE_CONT, pid, 0, 0) < 0))
35282 +               tracer_panic("OP_FORK failed to attach pid");
35283 +       wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
35284 +       if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
35285 +               tracer_panic("OP_FORK failed to continue process");
35286 +}
35287 +
35288 +void tracer_panic(char *format, ...)
35289 +{
35290 +       va_list ap;
35291 +
35292 +       va_start(ap, format);
35293 +       vprintf(format, ap);
35294 +       printf("\n");
35295 +       while(1) pause();
35296 +}
35297 +
35298 +static void tracer_segv(int sig, struct sigcontext sc)
35299 +{
35300 +       printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
35301 +              SC_FAULT_ADDR(&sc), SC_IP(&sc));
35302 +       while(1)
35303 +               pause();
35304 +}
35305 +
35306 +/* Changed early in boot, and then only read */
35307 +int debug = 0;
35308 +int debug_stop = 1;
35309 +int debug_parent = 0;
35310 +int honeypot = 0;
35311 +
35312 +static int signal_tramp(void *arg)
35313 +{
35314 +       int (*proc)(void *);
35315 +
35316 +       if(honeypot && munmap((void *) (host_task_size - 0x10000000),
35317 +                             0x10000000)) 
35318 +               panic("Unmapping stack failed");
35319 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
35320 +               panic("ptrace PTRACE_TRACEME failed");
35321 +       os_stop_process(os_getpid());
35322 +       change_sig(SIGWINCH, 0);
35323 +       signal(SIGUSR1, SIG_IGN);
35324 +       change_sig(SIGCHLD, 0);
35325 +       signal(SIGSEGV, (__sighandler_t) sig_handler);
35326 +       set_cmdline("(idle thread)");
35327 +       set_init_pid(os_getpid());
35328 +       proc = arg;
35329 +       return((*proc)(NULL));
35330 +}
35331 +
35332 +static void sleeping_process_signal(int pid, int sig)
35333 +{
35334 +       switch(sig){
35335 +       /* These two result from UML being ^Z-ed and bg-ed.  PTRACE_CONT is
35336 +        * right because the process must be in the kernel already.
35337 +        */
35338 +       case SIGCONT:
35339 +       case SIGTSTP:
35340 +               if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
35341 +                       tracer_panic("sleeping_process_signal : Failed to "
35342 +                                    "continue pid %d, signal = %d, "
35343 +                                    "errno = %d\n", pid, sig, errno);
35344 +               break;
35345 +
35346 +       /* This happens when the debugger (e.g. strace) is doing system call 
35347 +        * tracing on the kernel.  During a context switch, the current task
35348 +        * will be set to the incoming process and the outgoing process will
35349 +        * hop into write and then read.  Since it's not the current process
35350 +        * any more, the trace of those will land here.  So, we need to just 
35351 +        * PTRACE_SYSCALL it.
35352 +        */
35353 +       case SIGTRAP:
35354 +               if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
35355 +                       tracer_panic("sleeping_process_signal : Failed to "
35356 +                                    "PTRACE_SYSCALL pid %d, errno = %d\n",
35357 +                                    pid, errno);
35358 +               break;
35359 +       case SIGSTOP:
35360 +               break;
35361 +       default:
35362 +               tracer_panic("sleeping process %d got unexpected "
35363 +                            "signal : %d\n", pid, sig);
35364 +               break;
35365 +       }
35366 +}
35367 +
35368 +/* Accessed only by the tracing thread */
35369 +int debugger_pid = -1;
35370 +int debugger_parent = -1;
35371 +int debugger_fd = -1;
35372 +int gdb_pid = -1;
35373 +
35374 +struct {
35375 +       int pid;
35376 +       int signal;
35377 +       unsigned long addr;
35378 +       struct timeval time;
35379 +} signal_record[1024][32];
35380 +
35381 +int signal_index[32];
35382 +int nsignals = 0;
35383 +int debug_trace = 0;
35384 +extern int io_nsignals, io_count, intr_count;
35385 +
35386 +extern void signal_usr1(int sig);
35387 +
35388 +int tracing_pid = -1;
35389 +
35390 +int tracer(int (*init_proc)(void *), void *sp)
35391 +{
35392 +       void *task = NULL;
35393 +       unsigned long eip = 0;
35394 +       int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
35395 +       int last_index, proc_id = 0, n, err, old_tracing = 0, strace = 0;
35396 +       int cont_syscall;
35397 +
35398 +       capture_signal_stack();
35399 +       signal(SIGPIPE, SIG_IGN);
35400 +       setup_tracer_winch();
35401 +       tracing_pid = os_getpid();
35402 +       printf("tracing thread pid = %d\n", tracing_pid);
35403 +
35404 +       pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
35405 +       CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
35406 +       if(n < 0){
35407 +               printf("waitpid on idle thread failed, errno = %d\n", errno);
35408 +               exit(1);
35409 +       }
35410 +       if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
35411 +               printf("Failed to continue idle thread, errno = %d\n", errno);
35412 +               exit(1);
35413 +       }
35414 +
35415 +       signal(SIGSEGV, (sighandler_t) tracer_segv);
35416 +       signal(SIGUSR1, signal_usr1);
35417 +       if(debug_trace){
35418 +               printf("Tracing thread pausing to be attached\n");
35419 +               stop();
35420 +       }
35421 +       if(debug){
35422 +               if(gdb_pid != -1) 
35423 +                       debugger_pid = attach_debugger(pid, gdb_pid, 1);
35424 +               else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop);
35425 +               if(debug_parent){
35426 +                       debugger_parent = os_process_parent(debugger_pid);
35427 +                       init_parent_proxy(debugger_parent);
35428 +                       err = attach(debugger_parent);
35429 +                       if(err){
35430 +                               printf("Failed to attach debugger parent %d, "
35431 +                                      "errno = %d\n", debugger_parent, -err);
35432 +                               debugger_parent = -1;
35433 +                       }
35434 +                       else {
35435 +                               if(ptrace(PTRACE_SYSCALL, debugger_parent, 
35436 +                                         0, 0) < 0){
35437 +                                       printf("Failed to continue debugger "
35438 +                                              "parent, errno = %d\n", errno);
35439 +                                       debugger_parent = -1;
35440 +                               }
35441 +                       }
35442 +               }
35443 +       }
35444 +       set_cmdline("(tracing thread)");
35445 +       while(1){
35446 +               CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED));
35447 +               if(pid <= 0){
35448 +                       if(errno != ECHILD){
35449 +                               printf("wait failed - errno = %d\n", errno);
35450 +                       }
35451 +                       continue;
35452 +               }
35453 +               if(pid == debugger_pid){
35454 +                       int cont = 0;
35455 +
35456 +                       if(WIFEXITED(status) || WIFSIGNALED(status))
35457 +                               debugger_pid = -1;
35458 +                       /* XXX Figure out how to deal with gdb and SMP */
35459 +                       else cont = debugger_signal(status, cpu_tasks[0].pid);
35460 +                       if(cont == PTRACE_SYSCALL) strace = 1;
35461 +                       continue;
35462 +               }
35463 +               else if(pid == debugger_parent){
35464 +                       debugger_parent_signal(status, pid);
35465 +                       continue;
35466 +               }
35467 +               nsignals++;
35468 +               if(WIFEXITED(status)) ;
35469 +#ifdef notdef
35470 +               {
35471 +                       printf("Child %d exited with status %d\n", pid, 
35472 +                              WEXITSTATUS(status));
35473 +               }
35474 +#endif
35475 +               else if(WIFSIGNALED(status)){
35476 +                       sig = WTERMSIG(status);
35477 +                       if(sig != 9){
35478 +                               printf("Child %d exited with signal %d\n", pid,
35479 +                                      sig);
35480 +                       }
35481 +               }
35482 +               else if(WIFSTOPPED(status)){
35483 +                       proc_id = pid_to_processor_id(pid);
35484 +                       sig = WSTOPSIG(status);
35485 +                       if(signal_index[proc_id] == 1024){
35486 +                               signal_index[proc_id] = 0;
35487 +                               last_index = 1023;
35488 +                       }
35489 +                       else last_index = signal_index[proc_id] - 1;
35490 +                       if(((sig == SIGPROF) || (sig == SIGVTALRM) || 
35491 +                           (sig == SIGALRM)) &&
35492 +                          (signal_record[proc_id][last_index].signal == sig)&&
35493 +                          (signal_record[proc_id][last_index].pid == pid))
35494 +                               signal_index[proc_id] = last_index;
35495 +                       signal_record[proc_id][signal_index[proc_id]].pid = pid;
35496 +                       gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL);
35497 +                       eip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
35498 +                       signal_record[proc_id][signal_index[proc_id]].addr = eip;
35499 +                       signal_record[proc_id][signal_index[proc_id]++].signal = sig;
35500 +                       
35501 +                       if(proc_id == -1){
35502 +                               sleeping_process_signal(pid, sig);
35503 +                               continue;
35504 +                       }
35505 +
35506 +                       task = cpu_tasks[proc_id].task;
35507 +                       tracing = is_tracing(task);
35508 +                       old_tracing = tracing;
35509 +
35510 +                       cont_syscall = use_sysemu ? PTRACE_SYSEMU : 
35511 +                               PTRACE_SYSCALL;
35512 +                       switch(sig){
35513 +                       case SIGUSR1:
35514 +                               sig = 0;
35515 +                               op = do_proc_op(task, proc_id);
35516 +                               switch(op){
35517 +                               case OP_TRACE_ON:
35518 +                                       arch_leave_kernel(task, pid);
35519 +                                       tracing = 1;
35520 +                                       break;
35521 +                               case OP_REBOOT:
35522 +                               case OP_HALT:
35523 +                                       unmap_physmem();
35524 +                                       kmalloc_ok = 0;
35525 +                                       ptrace(PTRACE_KILL, pid, 0, 0);
35526 +                                       return(op == OP_REBOOT);
35527 +                               case OP_NONE:
35528 +                                       printf("Detaching pid %d\n", pid);
35529 +                                       detach(pid, SIGSTOP);
35530 +                                       continue;
35531 +                               default:
35532 +                                       break;
35533 +                               }
35534 +                               /* OP_EXEC switches host processes on us,
35535 +                                * we want to continue the new one.
35536 +                                */
35537 +                               pid = cpu_tasks[proc_id].pid;
35538 +                               break;
35539 +                       case SIGTRAP:
35540 +                               if(!tracing && (debugger_pid != -1)){
35541 +                                       child_signal(pid, status);
35542 +                                       continue;
35543 +                               }
35544 +                               tracing = 0;
35545 +                               if(do_syscall(task, pid))
35546 +                                       sig = SIGUSR2;
35547 +                               break;
35548 +                       case SIGPROF:
35549 +                               if(tracing) sig = 0;
35550 +                               break;
35551 +                       case SIGCHLD:
35552 +                       case SIGHUP:
35553 +                               sig = 0;
35554 +                               break;
35555 +                       case SIGSEGV:
35556 +                       case SIGIO:
35557 +                       case SIGALRM:
35558 +                       case SIGVTALRM:
35559 +                       case SIGFPE:
35560 +                       case SIGBUS:
35561 +                       case SIGILL:
35562 +                       case SIGWINCH:
35563 +                       default:
35564 +                               tracing = 0;
35565 +                               break;
35566 +                       }
35567 +                       set_tracing(task, tracing);
35568 +
35569 +                       if(!tracing && old_tracing)
35570 +                               arch_enter_kernel(task, pid);
35571 +
35572 +                       if(!tracing && (debugger_pid != -1) && (sig != 0) &&
35573 +                               (sig != SIGALRM) && (sig != SIGVTALRM) &&
35574 +                               (sig != SIGSEGV) && (sig != SIGTRAP) &&
35575 +                               (sig != SIGUSR2) && (sig != SIGIO) &&
35576 +                               (sig != SIGFPE)){
35577 +                               child_signal(pid, status);
35578 +                               continue;
35579 +                       }
35580 +
35581 +                       if(tracing){
35582 +                               if(singlestepping(task))
35583 +                                       cont_type = PTRACE_SINGLESTEP;
35584 +                               else cont_type = cont_syscall;
35585 +                       }
35586 +                       else cont_type = PTRACE_CONT;
35587 +
35588 +                       if((cont_type == PTRACE_CONT) && 
35589 +                          (debugger_pid != -1) && strace)
35590 +                               cont_type = PTRACE_SYSCALL;
35591 +
35592 +                       if(ptrace(cont_type, pid, 0, sig) != 0){
35593 +                               tracer_panic("ptrace failed to continue "
35594 +                                            "process - errno = %d\n", 
35595 +                                            errno);
35596 +                       }
35597 +               }
35598 +       }
35599 +       return(0);
35600 +}
35601 +
35602 +static int __init uml_debug_setup(char *line, int *add)
35603 +{
35604 +       char *next;
35605 +
35606 +       debug = 1;
35607 +       *add = 0;
35608 +       if(*line != '=') return(0);
35609 +       line++;
35610 +
35611 +       while(line != NULL){
35612 +               next = strchr(line, ',');
35613 +               if(next) *next++ = '\0';
35614 +               
35615 +               if(!strcmp(line, "go")) debug_stop = 0;
35616 +               else if(!strcmp(line, "parent")) debug_parent = 1;
35617 +               else printf("Unknown debug option : '%s'\n", line);
35618 +
35619 +               line = next;
35620 +       }
35621 +       return(0);
35622 +}
35623 +
35624 +__uml_setup("debug", uml_debug_setup,
35625 +"debug\n"
35626 +"    Starts up the kernel under the control of gdb. See the \n"
35627 +"    kernel debugging tutorial and the debugging session pages\n"
35628 +"    at http://user-mode-linux.sourceforge.net/ for more information.\n\n"
35629 +);
35630 +
35631 +static int __init uml_debugtrace_setup(char *line, int *add)
35632 +{
35633 +       debug_trace = 1;
35634 +       return 0;
35635 +}
35636 +__uml_setup("debugtrace", uml_debugtrace_setup,
35637 +"debugtrace\n"
35638 +"    Causes the tracing thread to pause until it is attached by a\n"
35639 +"    debugger and continued.  This is mostly for debugging crashes\n"
35640 +"    early during boot, and should be pretty much obsoleted by\n"
35641 +"    the debug switch.\n\n"
35642 +);
35643 +
35644 +static int __init uml_honeypot_setup(char *line, int *add)
35645 +{
35646 +       jail_setup("", add);
35647 +       honeypot = 1;
35648 +       return 0;
35649 +}
35650 +__uml_setup("honeypot", uml_honeypot_setup, 
35651 +"honeypot\n"
35652 +"    This makes UML put process stacks in the same location as they are\n"
35653 +"    on the host, allowing expoits such as stack smashes to work against\n"
35654 +"    UML.  This implies 'jail'.\n\n"
35655 +);
35656 +
35657 +/*
35658 + * Overrides for Emacs so that we follow Linus's tabbing style.
35659 + * Emacs will notice this stuff at the end of the file and automatically
35660 + * adjust the settings for this buffer only.  This must remain at the end
35661 + * of the file.
35662 + * ---------------------------------------------------------------------------
35663 + * Local variables:
35664 + * c-file-style: "linux"
35665 + * End:
35666 + */
35667 Index: linux-2.4.29/arch/um/kernel/tt/trap_user.c
35668 ===================================================================
35669 --- linux-2.4.29.orig/arch/um/kernel/tt/trap_user.c     1970-01-01 03:00:00.000000000 +0300
35670 +++ linux-2.4.29/arch/um/kernel/tt/trap_user.c  2005-05-03 22:28:14.544399128 +0300
35671 @@ -0,0 +1,64 @@
35672 +/* 
35673 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
35674 + * Licensed under the GPL
35675 + */
35676 +
35677 +#include <stdlib.h>
35678 +#include <errno.h>
35679 +#include <signal.h>
35680 +#include <asm/sigcontext.h>
35681 +#include "sysdep/ptrace.h"
35682 +#include "signal_user.h"
35683 +#include "user_util.h"
35684 +#include "kern_util.h"
35685 +#include "task.h"
35686 +#include "tt.h"
35687 +
35688 +void sig_handler_common_tt(int sig, void *sc_ptr)
35689 +{
35690 +       struct sigcontext *sc = sc_ptr;
35691 +       struct tt_regs save_regs, *r;
35692 +       struct signal_info *info;
35693 +       int save_errno = errno, is_user;
35694 +
35695 +       unprotect_kernel_mem();
35696 +
35697 +       /* This is done because to allow SIGSEGV to be delivered inside a SEGV
35698 +        * handler.  This can happen in copy_user, and if SEGV is disabled,
35699 +        * the process will die.
35700 +        */
35701 +       if(sig == SIGSEGV)
35702 +               change_sig(SIGSEGV, 1);
35703 +
35704 +       r = &TASK_REGS(get_current())->tt;
35705 +       save_regs = *r;
35706 +       is_user = user_context(SC_SP(sc));
35707 +       r->sc = sc;
35708 +       if(sig != SIGUSR2) 
35709 +               r->syscall = -1;
35710 +
35711 +       info = &sig_info[sig];
35712 +       if(!info->is_irq) unblock_signals();
35713 +
35714 +       (*info->handler)(sig, (union uml_pt_regs *) r);
35715 +
35716 +       if(is_user){
35717 +               interrupt_end();
35718 +               block_signals();
35719 +               set_user_mode(NULL);
35720 +       }
35721 +       *r = save_regs;
35722 +       errno = save_errno;
35723 +       if(is_user) protect_kernel_mem();
35724 +}
35725 +
35726 +/*
35727 + * Overrides for Emacs so that we follow Linus's tabbing style.
35728 + * Emacs will notice this stuff at the end of the file and automatically
35729 + * adjust the settings for this buffer only.  This must remain at the end
35730 + * of the file.
35731 + * ---------------------------------------------------------------------------
35732 + * Local variables:
35733 + * c-file-style: "linux"
35734 + * End:
35735 + */
35736 Index: linux-2.4.29/arch/um/kernel/tt/uaccess.c
35737 ===================================================================
35738 --- linux-2.4.29.orig/arch/um/kernel/tt/uaccess.c       1970-01-01 03:00:00.000000000 +0300
35739 +++ linux-2.4.29/arch/um/kernel/tt/uaccess.c    2005-05-03 22:28:14.545398976 +0300
35740 @@ -0,0 +1,73 @@
35741 +/* 
35742 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
35743 + * Licensed under the GPL
35744 + */
35745 +
35746 +#include "linux/sched.h"
35747 +#include "asm/uaccess.h"
35748 +
35749 +int copy_from_user_tt(void *to, const void *from, int n)
35750 +{
35751 +       if(!access_ok_tt(VERIFY_READ, from, n)) 
35752 +               return(n);
35753 +
35754 +       return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
35755 +                                  &current->thread.fault_catcher));
35756 +}
35757 +
35758 +int copy_to_user_tt(void *to, const void *from, int n)
35759 +{
35760 +       if(!access_ok_tt(VERIFY_WRITE, to, n))
35761 +               return(n);
35762 +               
35763 +       return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
35764 +                                &current->thread.fault_catcher));
35765 +}
35766 +
35767 +int strncpy_from_user_tt(char *dst, const char *src, int count)
35768 +{
35769 +       int n;
35770 +
35771 +       if(!access_ok_tt(VERIFY_READ, src, 1)) 
35772 +               return(-EFAULT);
35773 +
35774 +       n = __do_strncpy_from_user(dst, src, count, 
35775 +                                  &current->thread.fault_addr,
35776 +                                  &current->thread.fault_catcher);
35777 +       if(n < 0) return(-EFAULT);
35778 +       return(n);
35779 +}
35780 +
35781 +int __clear_user_tt(void *mem, int len)
35782 +{
35783 +       return(__do_clear_user(mem, len,
35784 +                              &current->thread.fault_addr,
35785 +                              &current->thread.fault_catcher));
35786 +}
35787 +
35788 +int clear_user_tt(void *mem, int len)
35789 +{
35790 +       if(!access_ok_tt(VERIFY_WRITE, mem, len))
35791 +               return(len);
35792 +
35793 +       return(__do_clear_user(mem, len, &current->thread.fault_addr,
35794 +                              &current->thread.fault_catcher));
35795 +}
35796 +
35797 +int strnlen_user_tt(const void *str, int len)
35798 +{
35799 +       return(__do_strnlen_user(str, len,
35800 +                                &current->thread.fault_addr,
35801 +                                &current->thread.fault_catcher));
35802 +}
35803 +
35804 +/*
35805 + * Overrides for Emacs so that we follow Linus's tabbing style.
35806 + * Emacs will notice this stuff at the end of the file and automatically
35807 + * adjust the settings for this buffer only.  This must remain at the end
35808 + * of the file.
35809 + * ---------------------------------------------------------------------------
35810 + * Local variables:
35811 + * c-file-style: "linux"
35812 + * End:
35813 + */
35814 Index: linux-2.4.29/arch/um/kernel/tt/uaccess_user.c
35815 ===================================================================
35816 --- linux-2.4.29.orig/arch/um/kernel/tt/uaccess_user.c  1970-01-01 03:00:00.000000000 +0300
35817 +++ linux-2.4.29/arch/um/kernel/tt/uaccess_user.c       2005-05-03 22:28:14.546398824 +0300
35818 @@ -0,0 +1,98 @@
35819 +/* 
35820 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
35821 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
35822 + * Licensed under the GPL
35823 + */
35824 +
35825 +#include <setjmp.h>
35826 +#include <string.h>
35827 +#include "user_util.h"
35828 +#include "uml_uaccess.h"
35829 +#include "task.h"
35830 +#include "kern_util.h"
35831 +
35832 +int __do_copy_from_user(void *to, const void *from, int n,
35833 +                       void **fault_addr, void **fault_catcher)
35834 +{
35835 +       struct tt_regs save = TASK_REGS(get_current())->tt;
35836 +       unsigned long fault;
35837 +       int faulted;
35838 +
35839 +       fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
35840 +                              __do_copy, &faulted);
35841 +       TASK_REGS(get_current())->tt = save;
35842 +
35843 +       if(!faulted) return(0);
35844 +       else return(n - (fault - (unsigned long) from));
35845 +}
35846 +
35847 +static void __do_strncpy(void *dst, const void *src, int count)
35848 +{
35849 +       strncpy(dst, src, count);
35850 +}      
35851 +
35852 +int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
35853 +                          void **fault_addr, void **fault_catcher)
35854 +{
35855 +       struct tt_regs save = TASK_REGS(get_current())->tt;
35856 +       unsigned long fault;
35857 +       int faulted;
35858 +
35859 +       fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
35860 +                              __do_strncpy, &faulted);
35861 +       TASK_REGS(get_current())->tt = save;
35862 +
35863 +       if(!faulted) return(strlen(dst));
35864 +       else return(-1);
35865 +}
35866 +
35867 +static void __do_clear(void *to, const void *from, int n)
35868 +{
35869 +       memset(to, 0, n);
35870 +}      
35871 +
35872 +int __do_clear_user(void *mem, unsigned long len,
35873 +                   void **fault_addr, void **fault_catcher)
35874 +{
35875 +       struct tt_regs save = TASK_REGS(get_current())->tt;
35876 +       unsigned long fault;
35877 +       int faulted;
35878 +
35879 +       fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
35880 +                              __do_clear, &faulted);
35881 +       TASK_REGS(get_current())->tt = save;
35882 +
35883 +       if(!faulted) return(0);
35884 +       else return(len - (fault - (unsigned long) mem));
35885 +}
35886 +
35887 +int __do_strnlen_user(const char *str, unsigned long n,
35888 +                     void **fault_addr, void **fault_catcher)
35889 +{
35890 +       struct tt_regs save = TASK_REGS(get_current())->tt;
35891 +       int ret;
35892 +       unsigned long *faddrp = (unsigned long *)fault_addr;
35893 +       sigjmp_buf jbuf;
35894 +
35895 +       *fault_catcher = &jbuf;
35896 +       if(sigsetjmp(jbuf, 1) == 0)
35897 +               ret = strlen(str) + 1;
35898 +       else ret = *faddrp - (unsigned long) str;
35899 +
35900 +       *fault_addr = NULL;
35901 +       *fault_catcher = NULL;
35902 +
35903 +       TASK_REGS(get_current())->tt = save;
35904 +       return ret;
35905 +}
35906 +
35907 +/*
35908 + * Overrides for Emacs so that we follow Linus's tabbing style.
35909 + * Emacs will notice this stuff at the end of the file and automatically
35910 + * adjust the settings for this buffer only.  This must remain at the end
35911 + * of the file.
35912 + * ---------------------------------------------------------------------------
35913 + * Local variables:
35914 + * c-file-style: "linux"
35915 + * End:
35916 + */
35917 Index: linux-2.4.29/arch/um/kernel/tt/unmap.c
35918 ===================================================================
35919 --- linux-2.4.29.orig/arch/um/kernel/tt/unmap.c 1970-01-01 03:00:00.000000000 +0300
35920 +++ linux-2.4.29/arch/um/kernel/tt/unmap.c      2005-05-03 22:28:14.547398672 +0300
35921 @@ -0,0 +1,31 @@
35922 +/* 
35923 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
35924 + * Licensed under the GPL
35925 + */
35926 +
35927 +#include <sys/mman.h>
35928 +
35929 +int switcheroo(int fd, int prot, void *from, void *to, int size)
35930 +{
35931 +       if(munmap(to, size) < 0){
35932 +               return(-1);
35933 +       }
35934 +       if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
35935 +               return(-1);
35936 +       }
35937 +       if(munmap(from, size) < 0){
35938 +               return(-1);
35939 +       }
35940 +       return(0);
35941 +}
35942 +
35943 +/*
35944 + * Overrides for Emacs so that we follow Linus's tabbing style.
35945 + * Emacs will notice this stuff at the end of the file and automatically
35946 + * adjust the settings for this buffer only.  This must remain at the end
35947 + * of the file.
35948 + * ---------------------------------------------------------------------------
35949 + * Local variables:
35950 + * c-file-style: "linux"
35951 + * End:
35952 + */
35953 Index: linux-2.4.29/arch/um/kernel/tty_log.c
35954 ===================================================================
35955 --- linux-2.4.29.orig/arch/um/kernel/tty_log.c  1970-01-01 03:00:00.000000000 +0300
35956 +++ linux-2.4.29/arch/um/kernel/tty_log.c       2005-05-03 22:28:14.000000000 +0300
35957 @@ -0,0 +1,230 @@
35958 +/* 
35959 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and 
35960 + * geoffrey hing <ghing@net.ohio-state.edu>
35961 + * Licensed under the GPL
35962 + */
35963 +
35964 +#include <errno.h>
35965 +#include <string.h>
35966 +#include <stdio.h>
35967 +#include <stdlib.h>
35968 +#include <unistd.h>
35969 +#include <sys/time.h>
35970 +#include "init.h"
35971 +#include "user.h"
35972 +#include "kern_util.h"
35973 +#include "os.h"
35974 +
35975 +#define TTY_LOG_DIR "./"
35976 +
35977 +/* Set early in boot and then unchanged */
35978 +static char *tty_log_dir = TTY_LOG_DIR;
35979 +static int tty_log_fd = -1;
35980 +
35981 +#define TTY_LOG_OPEN 1
35982 +#define TTY_LOG_CLOSE 2
35983 +#define TTY_LOG_WRITE 3
35984 +#define TTY_LOG_EXEC 4
35985 +
35986 +#define TTY_READ 1
35987 +#define TTY_WRITE 2
35988 +
35989 +struct tty_log_buf {
35990 +       int what;
35991 +       unsigned long tty;
35992 +       int len;
35993 +       int direction;
35994 +       unsigned long sec;
35995 +       unsigned long usec;
35996 +};
35997 +
35998 +int open_tty_log(void *tty, void *current_tty)
35999 +{
36000 +       struct timeval tv;
36001 +       struct tty_log_buf data;
36002 +       char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
36003 +       int fd;
36004 +
36005 +       gettimeofday(&tv, NULL);
36006 +       if(tty_log_fd != -1){
36007 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_OPEN,
36008 +                                              .tty  = (unsigned long) tty,
36009 +                                              .len  = sizeof(current_tty),
36010 +                                              .direction = 0,
36011 +                                              .sec = tv.tv_sec,
36012 +                                              .usec = tv.tv_usec } );
36013 +               os_write_file(tty_log_fd, &data, sizeof(data));
36014 +               os_write_file(tty_log_fd, &current_tty, data.len);
36015 +               return(tty_log_fd);
36016 +       }
36017 +
36018 +       sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
36019 +               (unsigned int) tv.tv_usec);
36020 +
36021 +       fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
36022 +                         0644);
36023 +       if(fd < 0){
36024 +               printk("open_tty_log : couldn't open '%s', errno = %d\n",
36025 +                      buf, -fd);
36026 +       }
36027 +       return(fd);
36028 +}
36029 +
36030 +void close_tty_log(int fd, void *tty)
36031 +{
36032 +       struct tty_log_buf data;
36033 +       struct timeval tv;
36034 +
36035 +       if(tty_log_fd != -1){
36036 +               gettimeofday(&tv, NULL);
36037 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_CLOSE,
36038 +                                              .tty  = (unsigned long) tty,
36039 +                                              .len  = 0,
36040 +                                              .direction = 0,
36041 +                                              .sec = tv.tv_sec,
36042 +                                              .usec = tv.tv_usec } );
36043 +               os_write_file(tty_log_fd, &data, sizeof(data));
36044 +               return;
36045 +       }
36046 +       os_close_file(fd);
36047 +}
36048 +
36049 +static int log_chunk(int fd, const char *buf, int len)
36050 +{
36051 +       int total = 0, try, missed, n;
36052 +       char chunk[64];
36053 +
36054 +       while(len > 0){
36055 +               try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
36056 +               missed = copy_from_user_proc(chunk, (char *) buf, try);
36057 +               try -= missed;
36058 +               n = os_write_file(fd, chunk, try);
36059 +               if(n != try) {
36060 +                       if(n < 0) 
36061 +                               return(n);
36062 +                       return(-EIO);
36063 +               }
36064 +               if(missed != 0)
36065 +                       return(-EFAULT);
36066 +
36067 +               len -= try;
36068 +               total += try;
36069 +               buf += try;
36070 +       }
36071 +
36072 +       return(total);
36073 +}
36074 +
36075 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
36076 +{
36077 +       struct timeval tv;
36078 +       struct tty_log_buf data;
36079 +       int direction;
36080 +
36081 +       if(fd == tty_log_fd){
36082 +               gettimeofday(&tv, NULL);
36083 +               direction = is_read ? TTY_READ : TTY_WRITE;
36084 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_WRITE,
36085 +                                              .tty  = (unsigned long) tty,
36086 +                                              .len  = len,
36087 +                                              .direction = direction,
36088 +                                              .sec = tv.tv_sec,
36089 +                                              .usec = tv.tv_usec } );
36090 +               os_write_file(tty_log_fd, &data, sizeof(data));
36091 +       }
36092 +
36093 +       return(log_chunk(fd, buf, len));
36094 +}
36095 +
36096 +void log_exec(char **argv, void *tty)
36097 +{
36098 +       struct timeval tv;
36099 +       struct tty_log_buf data;
36100 +       char **ptr,*arg;
36101 +       int len;
36102 +       
36103 +       if(tty_log_fd == -1) return;
36104 +
36105 +       gettimeofday(&tv, NULL);
36106 +
36107 +       len = 0;
36108 +       for(ptr = argv; ; ptr++){
36109 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
36110 +                       return;
36111 +               if(arg == NULL) break;
36112 +               len += strlen_user_proc(arg);
36113 +       }
36114 +
36115 +       data = ((struct tty_log_buf) { .what    = TTY_LOG_EXEC,
36116 +                                      .tty  = (unsigned long) tty,
36117 +                                      .len  = len,
36118 +                                      .direction = 0,
36119 +                                      .sec = tv.tv_sec,
36120 +                                      .usec = tv.tv_usec } );
36121 +       os_write_file(tty_log_fd, &data, sizeof(data));
36122 +
36123 +       for(ptr = argv; ; ptr++){
36124 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
36125 +                       return;
36126 +               if(arg == NULL) break;
36127 +               log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
36128 +       }
36129 +}
36130 +
36131 +extern void register_tty_logger(int (*opener)(void *, void *),
36132 +                               int (*writer)(int, const char *, int, 
36133 +                                             void *, int),
36134 +                               void (*closer)(int, void *));
36135 +
36136 +static int register_logger(void)
36137 +{
36138 +       register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
36139 +       return(0);
36140 +}
36141 +
36142 +__uml_initcall(register_logger);
36143 +
36144 +static int __init set_tty_log_dir(char *name, int *add)
36145 +{
36146 +       tty_log_dir = name;
36147 +       return 0;
36148 +}
36149 +
36150 +__uml_setup("tty_log_dir=", set_tty_log_dir,
36151 +"tty_log_dir=<directory>\n"
36152 +"    This is used to specify the directory where the logs of all pty\n"
36153 +"    data from this UML machine will be written.\n\n"
36154 +);
36155 +
36156 +static int __init set_tty_log_fd(char *name, int *add)
36157 +{
36158 +       char *end;
36159 +
36160 +       tty_log_fd = strtoul(name, &end, 0);
36161 +       if((*end != '\0') || (end == name)){
36162 +               printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
36163 +               tty_log_fd = -1;
36164 +       }
36165 +
36166 +       *add = 0;
36167 +       return 0;
36168 +}
36169 +
36170 +__uml_setup("tty_log_fd=", set_tty_log_fd,
36171 +"tty_log_fd=<fd>\n"
36172 +"    This is used to specify a preconfigured file descriptor to which all\n"
36173 +"    tty data will be written.  Preconfigure the descriptor with something\n"
36174 +"    like '10>tty_log tty_log_fd=10'.\n\n"
36175 +);
36176 +
36177 +
36178 +/*
36179 + * Overrides for Emacs so that we follow Linus's tabbing style.
36180 + * Emacs will notice this stuff at the end of the file and automatically
36181 + * adjust the settings for this buffer only.  This must remain at the end
36182 + * of the file.
36183 + * ---------------------------------------------------------------------------
36184 + * Local variables:
36185 + * c-file-style: "linux"
36186 + * End:
36187 + */
36188 Index: linux-2.4.29/arch/um/kernel/uaccess_user.c
36189 ===================================================================
36190 --- linux-2.4.29.orig/arch/um/kernel/uaccess_user.c     1970-01-01 03:00:00.000000000 +0300
36191 +++ linux-2.4.29/arch/um/kernel/uaccess_user.c  2005-05-03 22:28:14.549398368 +0300
36192 @@ -0,0 +1,64 @@
36193 +/* 
36194 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
36195 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
36196 + * Licensed under the GPL
36197 + */
36198 +
36199 +#include <setjmp.h>
36200 +#include <string.h>
36201 +
36202 +/* These are here rather than tt/uaccess.c because skas mode needs them in
36203 + * order to do SIGBUS recovery when a tmpfs mount runs out of room.
36204 + */
36205 +
36206 +unsigned long __do_user_copy(void *to, const void *from, int n,
36207 +                            void **fault_addr, void **fault_catcher,
36208 +                            void (*op)(void *to, const void *from,
36209 +                                       int n), int *faulted_out)
36210 +{
36211 +       unsigned long *faddrp = (unsigned long *) fault_addr, ret;
36212 +
36213 +       sigjmp_buf jbuf;
36214 +       *fault_catcher = &jbuf;
36215 +       if(sigsetjmp(jbuf, 1) == 0){
36216 +               (*op)(to, from, n);
36217 +               ret = 0;
36218 +               *faulted_out = 0;
36219 +       } 
36220 +       else {
36221 +               ret = *faddrp;
36222 +               *faulted_out = 1;
36223 +       }
36224 +       *fault_addr = NULL;
36225 +       *fault_catcher = NULL;
36226 +       return ret;
36227 +}
36228 +
36229 +void __do_copy(void *to, const void *from, int n)
36230 +{
36231 +       memcpy(to, from, n);
36232 +}      
36233 +
36234 +
36235 +int __do_copy_to_user(void *to, const void *from, int n,
36236 +                     void **fault_addr, void **fault_catcher)
36237 +{
36238 +       unsigned long fault;
36239 +       int faulted;
36240 +
36241 +       fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
36242 +                              __do_copy, &faulted);
36243 +       if(!faulted) return(0);
36244 +       else return(n - (fault - (unsigned long) to));
36245 +}
36246 +
36247 +/*
36248 + * Overrides for Emacs so that we follow Linus's tabbing style.
36249 + * Emacs will notice this stuff at the end of the file and automatically
36250 + * adjust the settings for this buffer only.  This must remain at the end
36251 + * of the file.
36252 + * ---------------------------------------------------------------------------
36253 + * Local variables:
36254 + * c-file-style: "linux"
36255 + * End:
36256 + */
36257 Index: linux-2.4.29/arch/um/kernel/um_arch.c
36258 ===================================================================
36259 --- linux-2.4.29.orig/arch/um/kernel/um_arch.c  1970-01-01 03:00:00.000000000 +0300
36260 +++ linux-2.4.29/arch/um/kernel/um_arch.c       2005-05-03 22:28:14.552397912 +0300
36261 @@ -0,0 +1,445 @@
36262 +/* 
36263 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
36264 + * Licensed under the GPL
36265 + */
36266 +
36267 +#include "linux/config.h"
36268 +#include "linux/kernel.h"
36269 +#include "linux/sched.h"
36270 +#include "linux/notifier.h"
36271 +#include "linux/mm.h"
36272 +#include "linux/types.h"
36273 +#include "linux/tty.h"
36274 +#include "linux/init.h"
36275 +#include "linux/bootmem.h"
36276 +#include "linux/spinlock.h"
36277 +#include "linux/utsname.h"
36278 +#include "linux/sysrq.h"
36279 +#include "linux/seq_file.h"
36280 +#include "linux/delay.h"
36281 +#include "asm/page.h"
36282 +#include "asm/pgtable.h"
36283 +#include "asm/ptrace.h"
36284 +#include "asm/elf.h"
36285 +#include "asm/user.h"
36286 +#include "ubd_user.h"
36287 +#include "asm/current.h"
36288 +#include "user_util.h"
36289 +#include "kern_util.h"
36290 +#include "kern.h"
36291 +#include "mem_user.h"
36292 +#include "mem.h"
36293 +#include "umid.h"
36294 +#include "initrd.h"
36295 +#include "init.h"
36296 +#include "os.h"
36297 +#include "choose-mode.h"
36298 +#include "mode_kern.h"
36299 +#include "mode.h"
36300 +
36301 +#define DEFAULT_COMMAND_LINE "root=/dev/ubd0"
36302 +
36303 +struct cpuinfo_um boot_cpu_data = { 
36304 +       .loops_per_jiffy        = 0,
36305 +       .pgd_quick              = NULL,
36306 +       .pmd_quick              = NULL,
36307 +       .pte_quick              = NULL,
36308 +       .pgtable_cache_sz       = 0,
36309 +       .ipi_pipe               = { -1, -1 }
36310 +};
36311 +
36312 +unsigned long thread_saved_pc(struct thread_struct *thread)
36313 +{
36314 +       return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
36315 +                                             thread)));
36316 +}
36317 +
36318 +static int show_cpuinfo(struct seq_file *m, void *v)
36319 +{
36320 +       int index = 0;
36321 +
36322 +#ifdef CONFIG_SMP
36323 +       index = (struct cpuinfo_um *)v - cpu_data;
36324 +       if (!(cpu_online_map & (1 << index)))
36325 +               return 0;
36326 +#endif
36327 +
36328 +       seq_printf(m, "processor\t: %d\n", index);
36329 +       seq_printf(m, "vendor_id\t: User Mode Linux\n");
36330 +       seq_printf(m, "model name\t: UML\n");
36331 +       seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
36332 +       seq_printf(m, "host\t\t: %s\n", host_info);
36333 +       seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
36334 +                  loops_per_jiffy/(500000/HZ),
36335 +                  (loops_per_jiffy/(5000/HZ)) % 100);
36336 +
36337 +       return(0);
36338 +}
36339 +
36340 +static void *c_start(struct seq_file *m, loff_t *pos)
36341 +{
36342 +       return *pos < NR_CPUS ? cpu_data + *pos : NULL;
36343 +}
36344 +
36345 +static void *c_next(struct seq_file *m, void *v, loff_t *pos)
36346 +{
36347 +       ++*pos;
36348 +       return c_start(m, pos);
36349 +}
36350 +
36351 +static void c_stop(struct seq_file *m, void *v)
36352 +{
36353 +}
36354 +
36355 +struct seq_operations cpuinfo_op = {
36356 +       .start  = c_start,
36357 +       .next   = c_next,
36358 +       .stop   = c_stop,
36359 +       .show   = show_cpuinfo,
36360 +};
36361 +
36362 +pte_t * __bad_pagetable(void)
36363 +{
36364 +       panic("Someone should implement __bad_pagetable");
36365 +       return(NULL);
36366 +}
36367 +
36368 +/* Set in linux_main */
36369 +unsigned long host_task_size;
36370 +unsigned long task_size;
36371 +unsigned long uml_start;
36372 +
36373 +/* Set in early boot */
36374 +unsigned long uml_physmem;
36375 +unsigned long uml_reserved;
36376 +unsigned long start_vm;
36377 +unsigned long end_vm;
36378 +int ncpus = 1;
36379 +
36380 +#ifdef CONFIG_MODE_TT
36381 +/* Pointer set in linux_main, the array itself is private to each thread,
36382 + * and changed at address space creation time so this poses no concurrency
36383 + * problems.
36384 + */
36385 +static char *argv1_begin = NULL;
36386 +static char *argv1_end = NULL;
36387 +#endif
36388 +
36389 +/* Set in early boot */
36390 +static int have_root __initdata = 0;
36391 +long physmem_size = 32 * 1024 * 1024;
36392 +
36393 +void set_cmdline(char *cmd)
36394 +{
36395 +#ifdef CONFIG_MODE_TT
36396 +       char *umid, *ptr;
36397 +
36398 +       if(CHOOSE_MODE(honeypot, 0)) return;
36399 +
36400 +       umid = get_umid(1);
36401 +       if(umid != NULL){
36402 +               snprintf(argv1_begin, 
36403 +                        (argv1_end - argv1_begin) * sizeof(*ptr), 
36404 +                        "(%s) ", umid);
36405 +               ptr = &argv1_begin[strlen(argv1_begin)];
36406 +       }
36407 +       else ptr = argv1_begin;
36408 +
36409 +       snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
36410 +       memset(argv1_begin + strlen(argv1_begin), '\0', 
36411 +              argv1_end - argv1_begin - strlen(argv1_begin));
36412 +#endif
36413 +}
36414 +
36415 +static char *usage_string = 
36416 +"User Mode Linux v%s\n"
36417 +"      available at http://user-mode-linux.sourceforge.net/\n\n";
36418 +
36419 +static int __init uml_version_setup(char *line, int *add)
36420 +{
36421 +       printf("%s\n", system_utsname.release);
36422 +       exit(0);
36423 +}
36424 +
36425 +__uml_setup("--version", uml_version_setup,
36426 +"--version\n"
36427 +"    Prints the version number of the kernel.\n\n"
36428 +);
36429 +
36430 +static int __init uml_root_setup(char *line, int *add)
36431 +{
36432 +       have_root = 1;
36433 +       return 0;
36434 +}
36435 +
36436 +__uml_setup("root=", uml_root_setup,
36437 +"root=<file containing the root fs>\n"
36438 +"    This is actually used by the generic kernel in exactly the same\n"
36439 +"    way as in any other kernel. If you configure a number of block\n"
36440 +"    devices and want to boot off something other than ubd0, you \n"
36441 +"    would use something like:\n"
36442 +"        root=/dev/ubd5\n\n"
36443 +);
36444 +
36445 +#ifdef CONFIG_SMP
36446 +static int __init uml_ncpus_setup(char *line, int *add)
36447 +{
36448 +       if (!sscanf(line, "%d", &ncpus)) {
36449 +               printf("Couldn't parse [%s]\n", line);
36450 +               return -1;
36451 +       }
36452 +
36453 +       return 0;
36454 +}
36455 +
36456 +__uml_setup("ncpus=", uml_ncpus_setup,
36457 +"ncpus=<# of desired CPUs>\n"
36458 +"    This tells an SMP kernel how many virtual processors to start.\n\n" 
36459 +);
36460 +#endif
36461 +
36462 +int force_tt = 0;
36463 +
36464 +#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
36465 +#define DEFAULT_TT 0
36466 +
36467 +static int __init mode_tt_setup(char *line, int *add)
36468 +{
36469 +       force_tt = 1;
36470 +       return(0);
36471 +}
36472 +
36473 +#else
36474 +#ifdef CONFIG_MODE_SKAS
36475 +
36476 +#define DEFAULT_TT 0
36477 +
36478 +static int __init mode_tt_setup(char *line, int *add)
36479 +{
36480 +       printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
36481 +       return(0);
36482 +}
36483 +
36484 +#else
36485 +#ifdef CONFIG_MODE_TT
36486 +
36487 +#define DEFAULT_TT 1
36488 +
36489 +static int __init mode_tt_setup(char *line, int *add)
36490 +{
36491 +       printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
36492 +       return(0);
36493 +}
36494 +
36495 +#else
36496 +
36497 +#error Either CONFIG_MODE_TT or CONFIG_MODE_SKAS must be enabled
36498 +
36499 +#endif
36500 +#endif
36501 +#endif
36502 +
36503 +__uml_setup("mode=tt", mode_tt_setup,
36504 +"mode=tt\n"
36505 +"    When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n"
36506 +"    forces UML to run in tt (tracing thread) mode.  It is not the default\n"
36507 +"    because it's slower and less secure than skas mode.\n\n"
36508 +);
36509 +
36510 +int mode_tt = DEFAULT_TT;
36511 +
36512 +static int __init Usage(char *line, int *add)
36513 +{
36514 +       const char **p;
36515 +
36516 +       printf(usage_string, system_utsname.release);
36517 +       p = &__uml_help_start;
36518 +       while (p < &__uml_help_end) {
36519 +               printf("%s", *p);
36520 +               p++;
36521 +       }
36522 +       exit(0);
36523 +}
36524 +
36525 +__uml_setup("--help", Usage,
36526 +"--help\n"
36527 +"    Prints this message.\n\n"
36528 +);
36529 +
36530 +static int __init uml_checksetup(char *line, int *add)
36531 +{
36532 +       struct uml_param *p;
36533 +
36534 +       p = &__uml_setup_start;
36535 +       while(p < &__uml_setup_end) {
36536 +               int n;
36537 +
36538 +               n = strlen(p->str);
36539 +               if(!strncmp(line, p->str, n)){
36540 +                       if (p->setup_func(line + n, add)) return 1;
36541 +               }
36542 +               p++;
36543 +       }
36544 +       return 0;
36545 +}
36546 +
36547 +static void __init uml_postsetup(void)
36548 +{
36549 +       initcall_t *p;
36550 +
36551 +       p = &__uml_postsetup_start;
36552 +       while(p < &__uml_postsetup_end){
36553 +               (*p)();
36554 +               p++;
36555 +       }
36556 +       return;
36557 +}
36558 +
36559 +/* Set during early boot */
36560 +unsigned long brk_start;
36561 +unsigned long end_iomem;
36562 +
36563 +#define MIN_VMALLOC (32 * 1024 * 1024)
36564 +
36565 +int linux_main(int argc, char **argv)
36566 +{
36567 +       unsigned long avail, diff;
36568 +       unsigned long virtmem_size, max_physmem;
36569 +       unsigned int i, add;
36570 +
36571 +       for (i = 1; i < argc; i++){
36572 +               if((i == 1) && (argv[i][0] == ' ')) continue;
36573 +               add = 1;
36574 +               uml_checksetup(argv[i], &add);
36575 +               if(add) add_arg(saved_command_line, argv[i]);
36576 +       }
36577 +       if(have_root == 0) add_arg(saved_command_line, DEFAULT_COMMAND_LINE);
36578 +
36579 +       mode_tt = force_tt ? 1 : !can_do_skas();
36580 +       uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
36581 +                                    &host_task_size, &task_size);
36582 +
36583 +       /* Need to check this early because mmapping happens before the
36584 +        * kernel is running.
36585 +        */
36586 +       check_tmpexec();
36587 +
36588 +       brk_start = (unsigned long) sbrk(0);
36589 +       CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
36590 +       /* Increase physical memory size for exec-shield users
36591 +       so they actually get what they asked for. This should
36592 +       add zero for non-exec shield users */
36593 +       
36594 +       diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
36595 +       if(diff > 1024 * 1024){
36596 +               printf("Adding %ld bytes to physical memory to account for "
36597 +                      "exec-shield gap\n", diff);
36598 +               physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
36599 +       }
36600 +
36601 +       uml_physmem = uml_start;
36602 +
36603 +       /* Reserve up to 4M after the current brk */
36604 +       uml_reserved = ROUND_4M(brk_start) + (1 << 22);
36605 +
36606 +       setup_machinename(system_utsname.machine);
36607 +
36608 +#ifdef CONFIG_MODE_TT
36609 +       argv1_begin = argv[1];
36610 +       argv1_end = &argv[1][strlen(argv[1])];
36611 +#endif
36612 +  
36613 +       highmem = 0;
36614 +       iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
36615 +       max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
36616 +
36617 +       /* Zones have to begin on a 1 << MAX_ORDER page boundary,
36618 +        * so this makes sure that's true for highmem
36619 +        */
36620 +       max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1);
36621 +       if(physmem_size + iomem_size > max_physmem){
36622 +               highmem = physmem_size + iomem_size - max_physmem;
36623 +               physmem_size -= highmem;
36624 +#ifndef CONFIG_HIGHMEM
36625 +               highmem = 0;
36626 +               printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
36627 +                      "to %ld bytes\n", physmem_size);
36628 +#endif
36629 +       }
36630 +
36631 +       high_physmem = uml_physmem + physmem_size;
36632 +       end_iomem = high_physmem + iomem_size;
36633 +       high_memory = (void *) end_iomem;
36634 +
36635 +       start_vm = VMALLOC_START;
36636 +
36637 +       setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
36638 +       if(init_maps(physmem_size, iomem_size, highmem)){
36639 +               printf("Failed to allocate mem_map for %ld bytes of physical "
36640 +                      "memory and %ld bytes of highmem\n", physmem_size,
36641 +                      highmem);
36642 +               exit(1);
36643 +       }
36644 +
36645 +       virtmem_size = physmem_size;
36646 +       avail = get_kmem_end() - start_vm;
36647 +       if(physmem_size > avail) virtmem_size = avail;
36648 +       end_vm = start_vm + virtmem_size;
36649 +
36650 +       if(virtmem_size < physmem_size)
36651 +               printf("Kernel virtual memory size shrunk to %ld bytes\n",
36652 +                      virtmem_size);
36653 +
36654 +       uml_postsetup();
36655 +
36656 +       task_protections((unsigned long) &init_task);
36657 +       os_flush_stdout();
36658 +
36659 +       return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
36660 +}
36661 +
36662 +extern int uml_exitcode;
36663 +
36664 +static int panic_exit(struct notifier_block *self, unsigned long unused1,
36665 +                     void *unused2)
36666 +{
36667 +#ifdef CONFIG_MAGIC_SYSRQ
36668 +       handle_sysrq('p', &current->thread.regs, NULL, NULL);
36669 +#endif
36670 +       uml_exitcode = 1;
36671 +       machine_halt();
36672 +       return(0);
36673 +}
36674 +
36675 +static struct notifier_block panic_exit_notifier = {
36676 +       .notifier_call          = panic_exit,
36677 +       .next                   = NULL,
36678 +       .priority               = 0
36679 +};
36680 +
36681 +void __init setup_arch(char **cmdline_p)
36682 +{
36683 +       notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
36684 +       paging_init();
36685 +       strcpy(command_line, saved_command_line);
36686 +       *cmdline_p = command_line;
36687 +       setup_hostinfo();
36688 +}
36689 +
36690 +void __init check_bugs(void)
36691 +{
36692 +       arch_check_bugs();
36693 +       check_ptrace();
36694 +       check_sigio();
36695 +}
36696 +
36697 +/*
36698 + * Overrides for Emacs so that we follow Linus's tabbing style.
36699 + * Emacs will notice this stuff at the end of the file and automatically
36700 + * adjust the settings for this buffer only.  This must remain at the end
36701 + * of the file.
36702 + * ---------------------------------------------------------------------------
36703 + * Local variables:
36704 + * c-file-style: "linux"
36705 + * End:
36706 + */
36707 Index: linux-2.4.29/arch/um/kernel/umid.c
36708 ===================================================================
36709 --- linux-2.4.29.orig/arch/um/kernel/umid.c     1970-01-01 03:00:00.000000000 +0300
36710 +++ linux-2.4.29/arch/um/kernel/umid.c  2005-05-03 22:28:14.554397608 +0300
36711 @@ -0,0 +1,328 @@
36712 +/* 
36713 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
36714 + * Licensed under the GPL
36715 + */
36716 +
36717 +#include <stdio.h>
36718 +#include <unistd.h>
36719 +#include <errno.h>
36720 +#include <string.h>
36721 +#include <stdlib.h>
36722 +#include <dirent.h>
36723 +#include <signal.h>
36724 +#include <sys/stat.h>
36725 +#include <sys/param.h>
36726 +#include "user.h"
36727 +#include "umid.h"
36728 +#include "init.h"
36729 +#include "os.h"
36730 +#include "user_util.h"
36731 +#include "choose-mode.h"
36732 +
36733 +#define UMID_LEN 64
36734 +#define UML_DIR "~/.uml/"
36735 +
36736 +/* Changed by set_umid and make_umid, which are run early in boot */
36737 +static char umid[UMID_LEN] = { 0 };
36738 +
36739 +/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
36740 +static char *uml_dir = UML_DIR;
36741 +
36742 +/* Changed by set_umid */
36743 +static int umid_is_random = 1;
36744 +static int umid_inited = 0;
36745 +
36746 +static int make_umid(int (*printer)(const char *fmt, ...));
36747 +
36748 +static int __init set_umid(char *name, int is_random, 
36749 +                          int (*printer)(const char *fmt, ...))
36750 +{
36751 +       if(umid_inited){
36752 +               (*printer)("Unique machine name can't be set twice\n");
36753 +               return(-1);
36754 +       }
36755 +
36756 +       if(strlen(name) > UMID_LEN - 1)
36757 +               (*printer)("Unique machine name is being truncated to %d "
36758 +                          "characters\n", UMID_LEN);
36759 +       strncpy(umid, name, UMID_LEN - 1);
36760 +       umid[UMID_LEN - 1] = '\0';
36761 +
36762 +       umid_is_random = is_random;
36763 +       umid_inited = 1;
36764 +       return 0;
36765 +}
36766 +
36767 +static int __init set_umid_arg(char *name, int *add)
36768 +{
36769 +       *add = 0;
36770 +       return(set_umid(name, 0, printf));
36771 +}
36772 +
36773 +__uml_setup("umid=", set_umid_arg,
36774 +"umid=<name>\n"
36775 +"    This is used to assign a unique identity to this UML machine and\n"
36776 +"    is used for naming the pid file and management console socket.\n\n"
36777 +);
36778 +
36779 +int __init umid_file_name(char *name, char *buf, int len)
36780 +{
36781 +       int n;
36782 +
36783 +       if(!umid_inited && make_umid(printk)) return(-1);
36784 +
36785 +       n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
36786 +       if(n > len){
36787 +               printk("umid_file_name : buffer too short\n");
36788 +               return(-1);
36789 +       }
36790 +
36791 +       sprintf(buf, "%s%s/%s", uml_dir, umid, name);
36792 +       return(0);
36793 +}
36794 +
36795 +extern int tracing_pid;
36796 +
36797 +static int __init create_pid_file(void)
36798 +{
36799 +       char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
36800 +       char pid[sizeof("nnnnn\0")];
36801 +       int fd, n;
36802 +
36803 +       if(umid_file_name("pid", file, sizeof(file))) return 0;
36804 +
36805 +       fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
36806 +                         0644);
36807 +       if(fd < 0){
36808 +               printf("Open of machine pid file \"%s\" failed - "
36809 +                      "err = %d\n", file, -fd);
36810 +               return 0;
36811 +       }
36812 +
36813 +       sprintf(pid, "%d\n", os_getpid());
36814 +       n = os_write_file(fd, pid, strlen(pid));
36815 +       if(n != strlen(pid))
36816 +               printf("Write of pid file failed - err = %d\n", -n);
36817 +       os_close_file(fd);
36818 +       return 0;
36819 +}
36820 +
36821 +static int actually_do_remove(char *dir)
36822 +{
36823 +       DIR *directory;
36824 +       struct dirent *ent;
36825 +       int len;
36826 +       char file[256];
36827 +
36828 +       directory = opendir(dir);
36829 +       if(directory == NULL){
36830 +               printk("actually_do_remove : couldn't open directory '%s', "
36831 +                      "errno = %d\n", dir, errno);
36832 +               return(1);
36833 +       }
36834 +       while((ent = readdir(directory)) != NULL){
36835 +               if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
36836 +                       continue;
36837 +               len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
36838 +               if(len > sizeof(file)){
36839 +                       printk("Not deleting '%s' from '%s' - name too long\n",
36840 +                              ent->d_name, dir);
36841 +                       continue;
36842 +               }
36843 +               sprintf(file, "%s/%s", dir, ent->d_name);
36844 +               if(unlink(file) < 0){
36845 +                       printk("actually_do_remove : couldn't remove '%s' "
36846 +                              "from '%s', errno = %d\n", ent->d_name, dir, 
36847 +                              errno);
36848 +                       return(1);
36849 +               }
36850 +       }
36851 +       if(rmdir(dir) < 0){
36852 +               printk("actually_do_remove : couldn't rmdir '%s', "
36853 +                      "errno = %d\n", dir, errno);
36854 +               return(1);
36855 +       }
36856 +       return(0);
36857 +}
36858 +
36859 +void remove_umid_dir(void)
36860 +{
36861 +       char dir[strlen(uml_dir) + UMID_LEN + 1];
36862 +       if(!umid_inited) return;
36863 +
36864 +       sprintf(dir, "%s%s", uml_dir, umid);
36865 +       actually_do_remove(dir);
36866 +}
36867 +
36868 +char *get_umid(int only_if_set)
36869 +{
36870 +       if(only_if_set && umid_is_random) return(NULL);
36871 +       return(umid);
36872 +}
36873 +
36874 +int not_dead_yet(char *dir)
36875 +{
36876 +       char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
36877 +       char pid[sizeof("nnnnn\0")], *end;
36878 +       int dead, fd, p, n;
36879 +
36880 +       sprintf(file, "%s/pid", dir);
36881 +       dead = 0;
36882 +       fd = os_open_file(file, of_read(OPENFLAGS()), 0);
36883 +       if(fd < 0){
36884 +               if(fd != -ENOENT){
36885 +                       printk("not_dead_yet : couldn't open pid file '%s', "
36886 +                              "err = %d\n", file, -fd);
36887 +                       return(1);
36888 +               }
36889 +               dead = 1;
36890 +       }
36891 +       if(fd > 0){
36892 +               n = os_read_file(fd, pid, sizeof(pid));
36893 +               if(n < 0){
36894 +                       printk("not_dead_yet : couldn't read pid file '%s', "
36895 +                              "err = %d\n", file, -n);
36896 +                       return(1);
36897 +               }
36898 +               p = strtoul(pid, &end, 0);
36899 +               if(end == pid){
36900 +                       printk("not_dead_yet : couldn't parse pid file '%s', "
36901 +                              "errno = %d\n", file, errno);
36902 +                       dead = 1;
36903 +               }
36904 +               if(((kill(p, 0) < 0) && (errno == ESRCH)) ||
36905 +                  (p == CHOOSE_MODE(tracing_pid, os_getpid())))
36906 +                       dead = 1;
36907 +       }
36908 +       if(!dead) return(1);
36909 +       return(actually_do_remove(dir));
36910 +}
36911 +
36912 +static int __init set_uml_dir(char *name, int *add)
36913 +{
36914 +       if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
36915 +               uml_dir = malloc(strlen(name) + 2);
36916 +               if(uml_dir == NULL){
36917 +                       printf("Failed to malloc uml_dir - error = %d\n",
36918 +                              errno);
36919 +                       uml_dir = name;
36920 +                       /* Return 0 here because do_initcalls doesn't look at
36921 +                        * the return value.
36922 +                        */
36923 +                       return(0);
36924 +               }
36925 +               sprintf(uml_dir, "%s/", name);
36926 +       }
36927 +       else uml_dir = name;
36928 +       return(0);
36929 +}
36930 +
36931 +static int __init make_uml_dir(void)
36932 +{
36933 +       char dir[MAXPATHLEN + 1] = { '\0' };
36934 +       int len;
36935 +
36936 +       if(*uml_dir == '~'){
36937 +               char *home = getenv("HOME");
36938 +
36939 +               if(home == NULL){
36940 +                       printf("make_uml_dir : no value in environment for "
36941 +                              "$HOME\n");
36942 +                       exit(1);
36943 +               }
36944 +               strncpy(dir, home, sizeof(dir));
36945 +               uml_dir++;
36946 +       }
36947 +       len = strlen(dir);
36948 +       strncat(dir, uml_dir, sizeof(dir) - len);
36949 +       len = strlen(dir);
36950 +       if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){
36951 +               dir[len] = '/';
36952 +               dir[len + 1] = '\0';
36953 +       }
36954 +
36955 +       uml_dir = malloc(strlen(dir) + 1);
36956 +       if(uml_dir == NULL){
36957 +               printf("make_uml_dir : malloc failed, errno = %d\n", errno);
36958 +               exit(1);
36959 +       }
36960 +       strcpy(uml_dir, dir);
36961 +       
36962 +       if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
36963 +               printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
36964 +               return(-1);
36965 +       }
36966 +       return 0;
36967 +}
36968 +
36969 +static int __init make_umid(int (*printer)(const char *fmt, ...))
36970 +{
36971 +       int fd, err;
36972 +       char tmp[strlen(uml_dir) + UMID_LEN + 1];
36973 +
36974 +       strncpy(tmp, uml_dir, sizeof(tmp) - 1);
36975 +       tmp[sizeof(tmp) - 1] = '\0';
36976 +
36977 +       if(!umid_inited){
36978 +               strcat(tmp, "XXXXXX");
36979 +               fd = mkstemp(tmp);
36980 +               if(fd < 0){
36981 +                       (*printer)("make_umid - mkstemp failed, errno = %d\n",
36982 +                                  errno);
36983 +                       return(1);
36984 +               }
36985 +
36986 +               os_close_file(fd);
36987 +               /* There's a nice tiny little race between this unlink and
36988 +                * the mkdir below.  It'd be nice if there were a mkstemp
36989 +                * for directories.
36990 +                */
36991 +               unlink(tmp);
36992 +               set_umid(&tmp[strlen(uml_dir)], 1, printer);
36993 +       }
36994 +       
36995 +       sprintf(tmp, "%s%s", uml_dir, umid);
36996 +
36997 +       err = mkdir(tmp, 0777);
36998 +       if(err < 0){
36999 +               if(errno == EEXIST){
37000 +                       if(not_dead_yet(tmp)){
37001 +                               (*printer)("umid '%s' is in use\n", umid);
37002 +                               return(-1);
37003 +                       }
37004 +                       err = mkdir(tmp, 0777);
37005 +               }
37006 +       }
37007 +       if(err < 0){
37008 +               (*printer)("Failed to create %s - errno = %d\n", umid, errno);
37009 +               return(-1);
37010 +       }
37011 +
37012 +       return(0);
37013 +}
37014 +
37015 +__uml_setup("uml_dir=", set_uml_dir,
37016 +"uml_dir=<directory>\n"
37017 +"    The location to place the pid and umid files.\n\n"
37018 +);
37019 +
37020 +__uml_postsetup(make_uml_dir);
37021 +
37022 +static int __init make_umid_setup(void)
37023 +{
37024 +       return(make_umid(printf));
37025 +}
37026 +
37027 +__uml_postsetup(make_umid_setup);
37028 +__uml_postsetup(create_pid_file);
37029 +
37030 +/*
37031 + * Overrides for Emacs so that we follow Linus's tabbing style.
37032 + * Emacs will notice this stuff at the end of the file and automatically
37033 + * adjust the settings for this buffer only.  This must remain at the end
37034 + * of the file.
37035 + * ---------------------------------------------------------------------------
37036 + * Local variables:
37037 + * c-file-style: "linux"
37038 + * End:
37039 + */
37040 Index: linux-2.4.29/arch/um/kernel/user_syms.c
37041 ===================================================================
37042 --- linux-2.4.29.orig/arch/um/kernel/user_syms.c        1970-01-01 03:00:00.000000000 +0300
37043 +++ linux-2.4.29/arch/um/kernel/user_syms.c     2005-05-03 23:38:38.888201256 +0300
37044 @@ -0,0 +1,85 @@
37045 +#include "linux/types.h"
37046 +#include "linux/module.h"
37047 +
37048 +/* XXX Deleted a number of symbols because they clashed strangely with headers
37049 + * Add them back later.
37050 + */
37051 +
37052 +#if 1
37053 +/* Some of this are builtin function (some are not but could in the future),
37054 + * so I *must* declare good prototypes for them and then EXPORT them.
37055 + * The kernel code uses the macro defined by include/linux/string.h,
37056 + * so I undef macros; the userspace code does not include that and I
37057 + * add an EXPORT for the glibc one.*/
37058 +
37059 +#undef strlen
37060 +#undef memcpy
37061 +#undef memset
37062 +
37063 +//extern size_t strlen(const char *);
37064 +extern void *memcpy(void *, const void *, size_t);
37065 +extern void *memset(void *, int, size_t);
37066 +//extern int printf(const char *, ...);
37067 +
37068 +//EXPORT_SYMBOL(strlen);
37069 +EXPORT_SYMBOL(memset);
37070 +EXPORT_SYMBOL(memcpy);
37071 +#undef strstr
37072 +
37073 +EXPORT_SYMBOL(strstr);
37074 +
37075 +#endif
37076 +
37077 +/* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms.
37078 + * However, the modules will use the CRC defined *here*, no matter if it is 
37079 + * good; so the versions of these symbols will always match
37080 + */
37081 +#define EXPORT_SYMBOL_PROTO(sym)       \
37082 +       int sym(void);                  \
37083 +       EXPORT_SYMBOL(sym);
37084 +
37085 +EXPORT_SYMBOL_PROTO(__errno_location);
37086 +
37087 +EXPORT_SYMBOL_PROTO(access);
37088 +EXPORT_SYMBOL_PROTO(open);
37089 +EXPORT_SYMBOL_PROTO(open64);
37090 +EXPORT_SYMBOL_PROTO(close);
37091 +EXPORT_SYMBOL_PROTO(read);
37092 +EXPORT_SYMBOL_PROTO(write);
37093 +EXPORT_SYMBOL_PROTO(dup2);
37094 +EXPORT_SYMBOL_PROTO(__xstat);
37095 +EXPORT_SYMBOL_PROTO(__lxstat);
37096 +EXPORT_SYMBOL_PROTO(__lxstat64);
37097 +EXPORT_SYMBOL_PROTO(lseek);
37098 +EXPORT_SYMBOL_PROTO(lseek64);
37099 +EXPORT_SYMBOL_PROTO(chown);
37100 +EXPORT_SYMBOL_PROTO(truncate);
37101 +EXPORT_SYMBOL_PROTO(utime);
37102 +EXPORT_SYMBOL_PROTO(chmod);
37103 +EXPORT_SYMBOL_PROTO(rename);
37104 +EXPORT_SYMBOL_PROTO(__xmknod);
37105 +
37106 +EXPORT_SYMBOL_PROTO(symlink);
37107 +EXPORT_SYMBOL_PROTO(link);
37108 +EXPORT_SYMBOL_PROTO(unlink);
37109 +EXPORT_SYMBOL_PROTO(readlink);
37110 +
37111 +EXPORT_SYMBOL_PROTO(mkdir);
37112 +EXPORT_SYMBOL_PROTO(rmdir);
37113 +EXPORT_SYMBOL_PROTO(opendir);
37114 +EXPORT_SYMBOL_PROTO(readdir);
37115 +EXPORT_SYMBOL_PROTO(closedir);
37116 +EXPORT_SYMBOL_PROTO(seekdir);
37117 +EXPORT_SYMBOL_PROTO(telldir);
37118 +
37119 +EXPORT_SYMBOL_PROTO(ioctl);
37120 +
37121 +EXPORT_SYMBOL_PROTO(pread64);
37122 +EXPORT_SYMBOL_PROTO(pwrite64);
37123 +
37124 +EXPORT_SYMBOL_PROTO(statfs);
37125 +EXPORT_SYMBOL_PROTO(statfs64);
37126 +
37127 +EXPORT_SYMBOL_PROTO(getuid);
37128 +
37129 +EXPORT_SYMBOL_PROTO(printf);
37130 Index: linux-2.4.29/arch/um/kernel/user_util.c
37131 ===================================================================
37132 --- linux-2.4.29.orig/arch/um/kernel/user_util.c        1970-01-01 03:00:00.000000000 +0300
37133 +++ linux-2.4.29/arch/um/kernel/user_util.c     2005-05-03 22:28:14.556397304 +0300
37134 @@ -0,0 +1,188 @@
37135 +/* 
37136 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
37137 + * Licensed under the GPL
37138 + */
37139 +
37140 +#include <stdio.h>
37141 +#include <stdlib.h>
37142 +#include <unistd.h>
37143 +#include <limits.h>
37144 +#include <setjmp.h>
37145 +#include <sys/mman.h> 
37146 +#include <sys/stat.h>
37147 +#include <sys/ptrace.h>
37148 +#include <sys/utsname.h>
37149 +#include <sys/param.h>
37150 +#include <sys/time.h>
37151 +#include "asm/types.h"
37152 +#include <ctype.h>
37153 +#include <signal.h>
37154 +#include <wait.h>
37155 +#include <errno.h>
37156 +#include <stdarg.h>
37157 +#include <sched.h>
37158 +#include <termios.h>
37159 +#include <string.h>
37160 +#include "user_util.h"
37161 +#include "kern_util.h"
37162 +#include "user.h"
37163 +#include "mem_user.h"
37164 +#include "init.h"
37165 +#include "helper.h"
37166 +#include "uml-config.h"
37167 +
37168 +#define COMMAND_LINE_SIZE _POSIX_ARG_MAX
37169 +
37170 +/* Changed in linux_main and setup_arch, which run before SMP is started */
37171 +char saved_command_line[COMMAND_LINE_SIZE] = { 0 };
37172 +char command_line[COMMAND_LINE_SIZE] = { 0 };
37173 +
37174 +void add_arg(char *cmd_line, char *arg)
37175 +{
37176 +       if (strlen(cmd_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
37177 +               printf("add_arg: Too much command line!\n");
37178 +               exit(1);
37179 +       }
37180 +       if(strlen(cmd_line) > 0) strcat(cmd_line, " ");
37181 +       strcat(cmd_line, arg);
37182 +}
37183 +
37184 +void stop(void)
37185 +{
37186 +       while(1) sleep(1000000);
37187 +}
37188 +
37189 +void stack_protections(unsigned long address)
37190 +{
37191 +       int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
37192 +
37193 +        if(mprotect((void *) address, page_size(), prot) < 0)
37194 +               panic("protecting stack failed, errno = %d", errno);
37195 +}
37196 +
37197 +void task_protections(unsigned long address)
37198 +{
37199 +       unsigned long guard = address + page_size();
37200 +       unsigned long stack = guard + page_size();
37201 +       int prot = 0, pages;
37202 +#ifdef notdef
37203 +       if(mprotect((void *) guard, page_size(), prot) < 0)
37204 +               panic("protecting guard page failed, errno = %d", errno);
37205 +#endif
37206 +       pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
37207 +       prot = PROT_READ | PROT_WRITE | PROT_EXEC;
37208 +       if(mprotect((void *) stack, pages * page_size(), prot) < 0)
37209 +               panic("protecting stack failed, errno = %d", errno);
37210 +}
37211 +
37212 +int wait_for_stop(int pid, int sig, int cont_type, void *relay)
37213 +{
37214 +       sigset_t *relay_signals = relay;
37215 +       int status, ret;
37216 +
37217 +       while(1){
37218 +               CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED));
37219 +               if((ret < 0) ||
37220 +                  !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
37221 +                       if(ret < 0){
37222 +                               printk("wait failed, errno = %d\n",
37223 +                                      errno);
37224 +                       }
37225 +                       else if(WIFEXITED(status)) 
37226 +                               printk("process %d exited with status %d\n", 
37227 +                                      pid, WEXITSTATUS(status));
37228 +                       else if(WIFSIGNALED(status))
37229 +                               printk("process %d exited with signal %d\n", 
37230 +                                      pid, WTERMSIG(status));
37231 +                       else if((WSTOPSIG(status) == SIGVTALRM) ||
37232 +                               (WSTOPSIG(status) == SIGALRM) ||
37233 +                               (WSTOPSIG(status) == SIGIO) ||
37234 +                               (WSTOPSIG(status) == SIGPROF) ||
37235 +                               (WSTOPSIG(status) == SIGCHLD) ||
37236 +                               (WSTOPSIG(status) == SIGWINCH) ||
37237 +                               (WSTOPSIG(status) == SIGINT)){
37238 +                               ptrace(cont_type, pid, 0, WSTOPSIG(status));
37239 +                               continue;
37240 +                       }
37241 +                       else if((relay_signals != NULL) &&
37242 +                               sigismember(relay_signals, WSTOPSIG(status))){
37243 +                               ptrace(cont_type, pid, 0, WSTOPSIG(status));
37244 +                               continue;
37245 +                       }
37246 +                       else printk("process %d stopped with signal %d\n", 
37247 +                                   pid, WSTOPSIG(status));
37248 +                       panic("wait_for_stop failed to wait for %d to stop "
37249 +                             "with %d\n", pid, sig);
37250 +               }
37251 +               return(status);
37252 +       }
37253 +}
37254 +
37255 +int raw(int fd)
37256 +{
37257 +       struct termios tt;
37258 +       int err;
37259 +
37260 +       CATCH_EINTR(err = tcgetattr(fd, &tt));
37261 +       if (err < 0) {
37262 +               printk("tcgetattr failed, errno = %d\n", errno);
37263 +               return(-errno);
37264 +       }
37265 +
37266 +       cfmakeraw(&tt);
37267 +
37268 +       CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt));
37269 +       if (err < 0) {
37270 +               printk("tcsetattr failed, errno = %d\n", errno);
37271 +               return(-errno);
37272 +       }
37273 +
37274 +       /* XXX tcsetattr could have applied only some changes
37275 +        * (and cfmakeraw() is a set of changes) */
37276 +       return(0);
37277 +}
37278 +
37279 +void setup_machinename(char *machine_out)
37280 +{
37281 +       struct utsname host;
37282 +
37283 +       uname(&host);
37284 +       strcpy(machine_out, host.machine);
37285 +}
37286 +
37287 +char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1];
37288 +
37289 +void setup_hostinfo(void)
37290 +{
37291 +       struct utsname host;
37292 +
37293 +       uname(&host);
37294 +       sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename,
37295 +               host.release, host.version, host.machine);
37296 +}
37297 +
37298 +int setjmp_wrapper(void (*proc)(void *, void *), ...)
37299 +{
37300 +        va_list args;
37301 +       sigjmp_buf buf;
37302 +       int n;
37303 +
37304 +       n = sigsetjmp(buf, 1);
37305 +       if(n == 0){
37306 +               va_start(args, proc);
37307 +               (*proc)(&buf, &args);
37308 +       }
37309 +       va_end(args);
37310 +       return(n);
37311 +}
37312 +
37313 +/*
37314 + * Overrides for Emacs so that we follow Linus's tabbing style.
37315 + * Emacs will notice this stuff at the end of the file and automatically
37316 + * adjust the settings for this buffer only.  This must remain at the end
37317 + * of the file.
37318 + * ---------------------------------------------------------------------------
37319 + * Local variables:
37320 + * c-file-style: "linux"
37321 + * End:
37322 + */
37323 Index: linux-2.4.29/arch/um/Makefile
37324 ===================================================================
37325 --- linux-2.4.29.orig/arch/um/Makefile  1970-01-01 03:00:00.000000000 +0300
37326 +++ linux-2.4.29/arch/um/Makefile       2005-05-03 22:28:14.000000000 +0300
37327 @@ -0,0 +1,191 @@
37328 +# 
37329 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
37330 +# Licensed under the GPL
37331 +#
37332 +
37333 +OS := $(shell uname -s)
37334 +
37335 +ARCH_DIR = arch/um
37336 +
37337 +core-y := kernel sys-$(SUBARCH) os-$(OS)
37338 +drivers-y := fs drivers
37339 +subdir-y := $(core-y) $(drivers-y)
37340 +SUBDIRS += $(foreach dir,$(subdir-y),$(ARCH_DIR)/$(dir))
37341 +
37342 +CORE_FILES += $(foreach dir,$(core-y),$(ARCH_DIR)/$(dir)/built-in.o)
37343 +DRIVERS += $(foreach dir,$(drivers-y),$(ARCH_DIR)/$(dir)/built-in.o)
37344 +
37345 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
37346 +include $(ARCH_DIR)/Makefile-os-$(OS)
37347 +
37348 +MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
37349 +MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
37350 +
37351 +ifneq ($(MAKEFILE-y),)
37352 +  include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
37353 +endif
37354 +
37355 +EXTRAVERSION := $(EXTRAVERSION)-1um
37356 +
37357 +include/linux/version.h: arch/$(ARCH)/Makefile
37358 +
37359 +# We require bash because the vmlinux link and loader script cpp use bash
37360 +# features.
37361 +SHELL := /bin/bash
37362 +
37363 +# Recalculate MODLIB to reflect the EXTRAVERSION changes (via KERNELRELEASE)
37364 +# The way the toplevel Makefile is written EXTRAVERSION is not supposed
37365 +# to be changed outside the toplevel Makefile, but recalculating MODLIB is
37366 +# a sufficient workaround until we no longer need architecture dependent
37367 +# EXTRAVERSION...
37368 +MODLIB := $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
37369 +
37370 +ifeq ($(CONFIG_DEBUGSYM),y)
37371 +CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS))
37372 +endif
37373 +
37374 +CFLAGS-$(CONFIG_DEBUGSYM) += -g
37375 +
37376 +ARCH_INCLUDE = -I$(TOPDIR)/$(ARCH_DIR)/include
37377 +
37378 +# -Derrno=kernel_errno - This turns all kernel references to errno into
37379 +# kernel_errno to separate them from the libc errno.  This allows -fno-common
37380 +# in CFLAGS.  Otherwise, it would cause ld to complain about the two different
37381 +# errnos.
37382 +
37383 +CFLAGS += $(ARCH_CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
37384 +       -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
37385 +       $(MODE_INCLUDE)
37386 +
37387 +check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
37388 +
37389 +CFLAGS += $(call check_gcc,-fno-unit-at-a-time,)
37390 +
37391 +LINKFLAGS += -r
37392 +
37393 +LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
37394 +
37395 +# These are needed for clean and mrproper, since in that case .config is not
37396 +# included; the values here are meaningless
37397 +
37398 +CONFIG_NEST_LEVEL ?= 0
37399 +CONFIG_KERNEL_HALF_GIGS ?= 0
37400 +
37401 +SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
37402 +
37403 +# These aren't in Makefile-tt because they are needed in the !CONFIG_MODE_TT +
37404 +# CONFIG_MODE_SKAS + CONFIG_STATIC_LINK case.
37405 +
37406 +LINK_TT = -static
37407 +LD_SCRIPT_TT := link.ld
37408 +
37409 +ifeq ($(CONFIG_STATIC_LINK),y)
37410 +  LINK-y += $(LINK_TT)
37411 +  LD_SCRIPT-y := $(LD_SCRIPT_TT)
37412 +else
37413 +ifeq ($(CONFIG_MODE_TT),y)
37414 +  LINK-y += $(LINK_TT)
37415 +  LD_SCRIPT-y := $(LD_SCRIPT_TT)
37416 +else
37417 +ifeq ($(CONFIG_MODE_SKAS),y)
37418 +  LINK-y += $(LINK_SKAS)
37419 +  LD_SCRIPT-y := $(LD_SCRIPT_SKAS)
37420 +endif
37421 +endif
37422 +endif
37423 +
37424 +LD_SCRIPT-y := $(ARCH_DIR)/kernel/$(LD_SCRIPT-y)
37425 +M4_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT)
37426 +
37427 +ifndef START
37428 +  START = $$(($(TOP_ADDR) - $(SIZE)))
37429 +endif
37430 +
37431 +$(LD_SCRIPT-y): $(LD_SCRIPT-y).in
37432 +       pages=$$(( 1 << $(CONFIG_KERNEL_STACK_ORDER) )) ; \
37433 +       m4 -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
37434 +               -DELF_FORMAT=$(ELF_FORMAT) $(M4_MODE_TT) \
37435 +               -DKERNEL_STACK_SIZE=$$(( 4096 * $$pages )) $< > $@
37436 +
37437 +SYMLINK_HEADERS = archparam.h system.h sigcontext.h processor.h ptrace.h \
37438 +       arch-signal.h
37439 +SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
37440 +
37441 +ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \
37442 +       $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
37443 +
37444 +ifeq ($(CONFIG_MODE_SKAS), y)
37445 +$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
37446 +endif
37447 +
37448 +GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h 
37449 +
37450 +setup: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) 
37451 +
37452 +linux: setup vmlinux $(LD_SCRIPT-y)
37453 +       mv vmlinux vmlinux.o
37454 +       $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
37455 +               -o linux vmlinux.o -L/usr/lib -lutil
37456 +
37457 +USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
37458 +USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
37459 +USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
37460 +       $(MODE_INCLUDE)
37461 +
37462 +# To get a definition of F_SETSIG
37463 +USER_CFLAGS += -D_GNU_SOURCE
37464 +
37465 +CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/link.ld $(ARCH_DIR)/dyn_link.ld \
37466 +       $(GEN_HEADERS) 
37467 +# $(ARCH_DIR)/include/uml-config.h removed temporarily because this causes
37468 +# make to fail after make clean
37469 +
37470 +archmrproper:
37471 +       rm -f $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
37472 +               $(LD_SCRIPT) $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
37473 +
37474 +archclean: sysclean
37475 +       find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
37476 +               -o -name '*.gcov' \) -type f -print | xargs rm -f
37477 +       cd $(ARCH_DIR) ; \
37478 +       for dir in $(subdir-y) util ; do $(MAKE) -C $$dir clean; done
37479 +
37480 +archdep: 
37481 +
37482 +$(SYMLINK_HEADERS):
37483 +       cd $(TOPDIR)/$(dir $@) ; \
37484 +       ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
37485 +
37486 +include/asm-um/arch:
37487 +       cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
37488 +
37489 +arch/um/include/sysdep:
37490 +       cd $(TOPDIR)/arch/um/include && ln -sf sysdep-$(SUBARCH) sysdep
37491 +
37492 +arch/um/os:
37493 +       cd $(ARCH_DIR) && ln -sf os-$(OS) os
37494 +
37495 +$(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
37496 +       $< > $@
37497 +
37498 +$(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
37499 +       $< > $@
37500 +
37501 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
37502 +       sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
37503 +
37504 +$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/util/mk_task_user.c \
37505 +       $(ARCH_DIR)/util/mk_task_kern.c $(SYS_HEADERS)
37506 +       $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_task
37507 +
37508 +$(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util/mk_constants_user.c \
37509 +       $(ARCH_DIR)/util/mk_constants_kern.c 
37510 +       $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_constants
37511 +
37512 +export SUBARCH USER_CFLAGS OS
37513 +
37514 +all: linux
37515 +
37516 +define archhelp
37517 +  echo  '* linux       - Binary kernel image (./linux)'
37518 +endef
37519 Index: linux-2.4.29/arch/um/Makefile-i386
37520 ===================================================================
37521 --- linux-2.4.29.orig/arch/um/Makefile-i386     1970-01-01 03:00:00.000000000 +0300
37522 +++ linux-2.4.29/arch/um/Makefile-i386  2005-05-03 22:28:14.000000000 +0300
37523 @@ -0,0 +1,46 @@
37524 +ifeq ($(CONFIG_HOST_2G_2G),y)
37525 +TOP_ADDR = 0x80000000
37526 +else
37527 +TOP_ADDR = 0xc0000000
37528 +endif
37529 +
37530 +ifeq ($(CONFIG_MODE_SKAS),y)
37531 +  ifneq ($(CONFIG_MODE_TT),y)
37532 +     START = 0x8048000
37533 +  endif
37534 +endif
37535 +
37536 +ARCH_CFLAGS = -U__$(SUBARCH)__ -U$(SUBARCH)
37537 +
37538 +ifneq ($(CONFIG_GPROF),y)
37539 +ARCH_CFLAGS += -DUM_FASTCALL
37540 +endif
37541 +
37542 +ELF_ARCH = $(SUBARCH)
37543 +ELF_FORMAT = elf32-$(SUBARCH)
37544 +
37545 +I386_H = $(ARCH_DIR)/include/sysdep-i386
37546 +SYS = $(ARCH_DIR)/sys-i386
37547 +UTIL = $(SYS)/util
37548 +SUBDIRS += $(UTIL)
37549 +
37550 +SYS_HEADERS = $(I386_H)/sc.h $(I386_H)/thread.h
37551 +
37552 +$(I386_H)/sc.h : $(UTIL)/mk_sc
37553 +       $(UTIL)/mk_sc > $@
37554 +
37555 +$(I386_H)/thread.h : $(UTIL)/mk_thread
37556 +       $(UTIL)/mk_thread > $@
37557 +
37558 +$(UTIL)/mk_sc : $(UTIL)/mk_sc.c
37559 +       $(MAKE) -C $(UTIL) mk_sc
37560 +
37561 +$(UTIL)/mk_thread : $(UTIL)/mk_thread_user.c $(UTIL)/mk_thread_kern.c \
37562 +       $(I386_H)/sc.h
37563 +       $(MAKE) -C $(UTIL) mk_thread
37564 +
37565 +sysclean :
37566 +       rm -f $(SYS_HEADERS)
37567 +       $(MAKE) -C $(UTIL) clean
37568 +       $(MAKE) -C $(SYS) clean
37569 +
37570 Index: linux-2.4.29/arch/um/Makefile-ia64
37571 ===================================================================
37572 --- linux-2.4.29.orig/arch/um/Makefile-ia64     1970-01-01 03:00:00.000000000 +0300
37573 +++ linux-2.4.29/arch/um/Makefile-ia64  2005-05-03 22:28:14.000000000 +0300
37574 @@ -0,0 +1 @@
37575 +START_ADDR = 0x1000000000000000
37576 Index: linux-2.4.29/arch/um/Makefile-os-Linux
37577 ===================================================================
37578 --- linux-2.4.29.orig/arch/um/Makefile-os-Linux 1970-01-01 03:00:00.000000000 +0300
37579 +++ linux-2.4.29/arch/um/Makefile-os-Linux      2005-05-03 22:28:14.000000000 +0300
37580 @@ -0,0 +1,7 @@
37581 +# 
37582 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
37583 +# Licensed under the GPL
37584 +#
37585 +
37586 +SUBDIRS += $(ARCH_DIR)/os-$(OS)/drivers
37587 +DRIVERS += $(ARCH_DIR)/os-$(OS)/drivers/drivers.o
37588 Index: linux-2.4.29/arch/um/Makefile-ppc
37589 ===================================================================
37590 --- linux-2.4.29.orig/arch/um/Makefile-ppc      1970-01-01 03:00:00.000000000 +0300
37591 +++ linux-2.4.29/arch/um/Makefile-ppc   2005-05-03 22:28:14.000000000 +0300
37592 @@ -0,0 +1,9 @@
37593 +ifeq ($(CONFIG_HOST_2G_2G), y)
37594 +START_ADDR = 0x80000000
37595 +else
37596 +START_ADDR = 0xc0000000
37597 +endif
37598 +ARCH_CFLAGS = -U__powerpc__ -D__UM_PPC__
37599 +
37600 +# The arch is ppc, but the elf32 name is powerpc
37601 +ELF_SUBARCH = powerpc
37602 Index: linux-2.4.29/arch/um/Makefile-skas
37603 ===================================================================
37604 --- linux-2.4.29.orig/arch/um/Makefile-skas     1970-01-01 03:00:00.000000000 +0300
37605 +++ linux-2.4.29/arch/um/Makefile-skas  2005-05-03 22:28:14.000000000 +0300
37606 @@ -0,0 +1,20 @@
37607 +# 
37608 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
37609 +# Licensed under the GPL
37610 +#
37611 +
37612 +PROFILE += -pg
37613 +
37614 +CFLAGS-$(CONFIG_GCOV) += -fprofile-arcs -ftest-coverage
37615 +CFLAGS-$(CONFIG_GPROF) += $(PROFILE)
37616 +LINK-$(CONFIG_GPROF) += $(PROFILE)
37617 +
37618 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/skas/include
37619 +
37620 +LINK_SKAS = -Wl,-rpath,/lib 
37621 +LD_SCRIPT_SKAS = dyn_link.ld
37622 +
37623 +GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
37624 +
37625 +$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
37626 +       $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
37627 Index: linux-2.4.29/arch/um/Makefile-tt
37628 ===================================================================
37629 --- linux-2.4.29.orig/arch/um/Makefile-tt       1970-01-01 03:00:00.000000000 +0300
37630 +++ linux-2.4.29/arch/um/Makefile-tt    2005-05-03 22:28:14.000000000 +0300
37631 @@ -0,0 +1,7 @@
37632 +# 
37633 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
37634 +# Licensed under the GPL
37635 +#
37636 +
37637 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/tt/include
37638 +
37639 Index: linux-2.4.29/arch/um/os-Linux/aio.c
37640 ===================================================================
37641 --- linux-2.4.29.orig/arch/um/os-Linux/aio.c    1970-01-01 03:00:00.000000000 +0300
37642 +++ linux-2.4.29/arch/um/os-Linux/aio.c 2005-05-03 22:28:14.563396240 +0300
37643 @@ -0,0 +1,404 @@
37644 +/* 
37645 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
37646 + * Licensed under the GPL
37647 + */
37648 +
37649 +#include <stdlib.h>
37650 +#include <unistd.h>
37651 +#include <signal.h>
37652 +#include <errno.h>
37653 +#include <sched.h>
37654 +#include <sys/syscall.h>
37655 +#include "os.h"
37656 +#include "helper.h"
37657 +#include "aio.h"
37658 +#include "init.h"
37659 +#include "user.h"
37660 +#include "mode.h"
37661 +
37662 +struct aio_thread_req {
37663 +       enum aio_type type;
37664 +       int io_fd;
37665 +       unsigned long long offset;
37666 +       char *buf;
37667 +       int len;
37668 +       int reply_fd;
37669 +       void *data;
37670 +};
37671 +
37672 +static int aio_req_fd_r = -1;
37673 +static int aio_req_fd_w = -1;
37674 +
37675 +#if defined(HAVE_AIO_ABI)
37676 +#include <linux/aio_abi.h>
37677 +
37678 +/* If we have the headers, we are going to build with AIO enabled.
37679 + * If we don't have aio in libc, we define the necessary stubs here.
37680 + */
37681 +
37682 +#if !defined(HAVE_AIO_LIBC)
37683 +
37684 +#define __NR_io_setup 245
37685 +#define __NR_io_getevents 247
37686 +#define __NR_io_submit 248
37687 +
37688 +static long io_setup(int n, aio_context_t *ctxp)
37689 +{
37690 +  return(syscall(__NR_io_setup, n, ctxp));
37691 +}
37692 +
37693 +static long io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp)
37694 +{
37695 +  return(syscall(__NR_io_submit, ctx, nr, iocbpp));
37696 +}
37697 +
37698 +static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
37699 +                        struct io_event *events, struct timespec *timeout)
37700 +{
37701 +  return(syscall(__NR_io_getevents, ctx_id, min_nr, nr, events, timeout));
37702 +}
37703 +
37704 +#endif
37705 +
37706 +/* The AIO_MMAP cases force the mmapped page into memory here
37707 + * rather than in whatever place first touches the data.  I used
37708 + * to do this by touching the page, but that's delicate because
37709 + * gcc is prone to optimizing that away.  So, what's done here
37710 + * is we read from the descriptor from which the page was 
37711 + * mapped.  The caller is required to pass an offset which is
37712 + * inside the page that was mapped.  Thus, when the read 
37713 + * returns, we know that the page is in the page cache, and
37714 + * that it now backs the mmapped area.
37715 + */
37716 +
37717 +static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf, 
37718 +                 int len, unsigned long long offset, void *data)
37719 +{
37720 +       struct iocb iocb, *iocbp = &iocb;
37721 +       char c;
37722 +       int err;
37723 +
37724 +       iocb = ((struct iocb) { .aio_data       = (unsigned long) data,
37725 +                               .aio_reqprio    = 0,
37726 +                               .aio_fildes     = fd,
37727 +                               .aio_buf        = (unsigned long) buf,
37728 +                               .aio_nbytes     = len,
37729 +                               .aio_offset     = offset,
37730 +                               .aio_reserved1  = 0,
37731 +                               .aio_reserved2  = 0,
37732 +                               .aio_reserved3  = 0 });
37733 +
37734 +       switch(type){
37735 +       case AIO_READ:
37736 +               iocb.aio_lio_opcode = IOCB_CMD_PREAD;
37737 +               err = io_submit(ctx, 1, &iocbp);
37738 +               break;
37739 +       case AIO_WRITE:
37740 +               iocb.aio_lio_opcode = IOCB_CMD_PWRITE;
37741 +               err = io_submit(ctx, 1, &iocbp);
37742 +               break;
37743 +       case AIO_MMAP:
37744 +               iocb.aio_lio_opcode = IOCB_CMD_PREAD;
37745 +               iocb.aio_buf = (unsigned long) &c;
37746 +               iocb.aio_nbytes = sizeof(c);
37747 +               err = io_submit(ctx, 1, &iocbp);
37748 +               break;
37749 +       default:
37750 +               printk("Bogus op in do_aio - %d\n", type);
37751 +               err = -EINVAL;
37752 +               break;
37753 +       }
37754 +       if(err > 0)
37755 +               err = 0;
37756 +
37757 +       return(err);    
37758 +}
37759 +
37760 +static aio_context_t ctx = 0;
37761 +
37762 +static int aio_thread(void *arg)
37763 +{
37764 +       struct aio_thread_reply reply;
37765 +       struct io_event event;
37766 +       int err, n, reply_fd;
37767 +
37768 +       signal(SIGWINCH, SIG_IGN);
37769 +
37770 +       while(1){
37771 +               n = io_getevents(ctx, 1, 1, &event, NULL);
37772 +               if(n < 0){
37773 +                       if(errno == EINTR)
37774 +                               continue;
37775 +                       printk("aio_thread - io_getevents failed, "
37776 +                              "errno = %d\n", errno);
37777 +               }
37778 +               else {
37779 +                       reply = ((struct aio_thread_reply) 
37780 +                               { .data = (void *) event.data,
37781 +                                 .err  = event.res });
37782 +                       reply_fd = 
37783 +                               ((struct aio_context *) event.data)->reply_fd;
37784 +                       err = os_write_file(reply_fd, &reply, sizeof(reply));
37785 +                       if(err != sizeof(reply))
37786 +                               printk("not_aio_thread - write failed, "
37787 +                                      "fd = %d, err = %d\n", 
37788 +                                      aio_req_fd_r, -err);
37789 +               }
37790 +       }
37791 +       return(0);
37792 +}
37793 +
37794 +#endif
37795 +
37796 +static int do_not_aio(struct aio_thread_req *req)
37797 +{
37798 +       char c;
37799 +       int err;
37800 +
37801 +       switch(req->type){
37802 +       case AIO_READ:
37803 +               err = os_seek_file(req->io_fd, req->offset);
37804 +               if(err)
37805 +                       goto out;
37806 +
37807 +               err = os_read_file(req->io_fd, req->buf, req->len);
37808 +               break;
37809 +       case AIO_WRITE:
37810 +               err = os_seek_file(req->io_fd, req->offset);
37811 +               if(err)
37812 +                       goto out;
37813 +
37814 +               err = os_write_file(req->io_fd, req->buf, req->len);
37815 +               break;
37816 +       case AIO_MMAP:
37817 +               err = os_seek_file(req->io_fd, req->offset);
37818 +               if(err)
37819 +                       goto out;
37820 +
37821 +               err = os_read_file(req->io_fd, &c, sizeof(c));
37822 +               break;
37823 +       default:
37824 +               printk("do_not_aio - bad request type : %d\n", req->type);
37825 +               err = -EINVAL;
37826 +               break;
37827 +       }
37828 +
37829 + out:
37830 +       return(err);
37831 +}
37832 +
37833 +static int not_aio_thread(void *arg)
37834 +{
37835 +       struct aio_thread_req req;
37836 +       struct aio_thread_reply reply;
37837 +       int err;
37838 +
37839 +       signal(SIGWINCH, SIG_IGN);
37840 +       while(1){
37841 +               err = os_read_file(aio_req_fd_r, &req, sizeof(req));
37842 +               if(err != sizeof(req)){
37843 +                       if(err < 0)
37844 +                               printk("not_aio_thread - read failed, fd = %d, "
37845 +                                      "err = %d\n", aio_req_fd_r, -err);
37846 +                       else {
37847 +                               printk("not_aio_thread - short read, fd = %d, "
37848 +                                      "length = %d\n", aio_req_fd_r, err);
37849 +                       }
37850 +                       continue;
37851 +               }
37852 +               err = do_not_aio(&req);
37853 +               reply = ((struct aio_thread_reply) { .data      = req.data,
37854 +                                                    .err       = err });
37855 +               err = os_write_file(req.reply_fd, &reply, sizeof(reply));
37856 +               if(err != sizeof(reply))
37857 +                       printk("not_aio_thread - write failed, fd = %d, "
37858 +                              "err = %d\n", aio_req_fd_r, -err);
37859 +       }
37860 +}
37861 +
37862 +static int aio_pid = -1;
37863 +
37864 +static int init_aio_24(void)
37865 +{
37866 +       unsigned long stack;
37867 +       int fds[2], err;
37868 +       
37869 +       err = os_pipe(fds, 1, 1);
37870 +       if(err)
37871 +               goto out;
37872 +
37873 +       aio_req_fd_w = fds[0];
37874 +       aio_req_fd_r = fds[1];
37875 +       err = run_helper_thread(not_aio_thread, NULL, 
37876 +                               CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
37877 +       if(err < 0)
37878 +               goto out_close_pipe;
37879 +
37880 +       aio_pid = err;
37881 +       goto out;
37882 +
37883 + out_close_pipe:
37884 +       os_close_file(fds[0]);
37885 +       os_close_file(fds[1]);
37886 +       aio_req_fd_w = -1;
37887 +       aio_req_fd_r = -1;      
37888 + out:
37889 +       return(0);
37890 +}
37891 +
37892 +#ifdef HAVE_AIO_ABI
37893 +#define DEFAULT_24_AIO 0
37894 +static int init_aio_26(void)
37895 +{
37896 +       unsigned long stack;
37897 +       int err;
37898 +       
37899 +       if(io_setup(256, &ctx)){
37900 +               printk("aio_thread failed to initialize context, err = %d\n",
37901 +                      errno);
37902 +               return(-errno);
37903 +       }
37904 +
37905 +       err = run_helper_thread(aio_thread, NULL, 
37906 +                               CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
37907 +       if(err < 0)
37908 +               return(-errno);
37909 +
37910 +       aio_pid = err;
37911 +       err = 0;
37912 + out:
37913 +       return(err);
37914 +}
37915 +
37916 +int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, 
37917 +                 unsigned long long offset, int reply_fd, void *data)
37918 +{
37919 +       struct aio_thread_reply reply;
37920 +       int err;
37921 +
37922 +       ((struct aio_context *) data)->reply_fd = reply_fd;
37923 +
37924 +       err = do_aio(ctx, type, io_fd, buf, len, offset, data);
37925 +       if(err){
37926 +               reply = ((struct aio_thread_reply) { .data = data,
37927 +                                                    .err  = err });
37928 +               err = os_write_file(reply_fd, &reply, sizeof(reply));
37929 +               if(err != sizeof(reply))
37930 +                       printk("submit_aio_26 - write failed, "
37931 +                              "fd = %d, err = %d\n", reply_fd, -err);
37932 +               else err = 0;
37933 +       }
37934 +
37935 +       return(err);
37936 +}
37937 +
37938 +#else
37939 +#define DEFAULT_24_AIO 1
37940 +static int init_aio_26(void)
37941 +{
37942 +       return(-ENOSYS);
37943 +}
37944 +
37945 +int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, 
37946 +                 unsigned long long offset, int reply_fd, void *data)
37947 +{
37948 +       return(-ENOSYS);
37949 +}
37950 +#endif
37951 +
37952 +static int aio_24 = DEFAULT_24_AIO;
37953 +
37954 +static int __init set_aio_24(char *name, int *add)
37955 +{
37956 +       aio_24 = 1;
37957 +       return(0);
37958 +}
37959 +
37960 +__uml_setup("aio=2.4", set_aio_24,
37961 +"aio=2.4\n"
37962 +"    This is used to force UML to use 2.4-style AIO even when 2.6 AIO is\n"
37963 +"    available.  2.4 AIO is a single thread that handles one request at a\n"
37964 +"    time, synchronously.  2.6 AIO is a thread which uses 2.5 AIO interface\n"
37965 +"    to handle an arbitrary number of pending requests.  2.6 AIO is not\n"
37966 +"    available in tt mode, on 2.4 hosts, or when UML is built with\n"
37967 +"    /usr/include/linux/aio_abi no available.\n\n"
37968 +);
37969 +
37970 +static int init_aio(void)
37971 +{
37972 +       int err;
37973 +
37974 +       CHOOSE_MODE(({ 
37975 +               if(!aio_24){ 
37976 +                       printk("Disabling 2.6 AIO in tt mode\n");
37977 +                       aio_24 = 1;
37978 +               } }), (void) 0);
37979 +
37980 +       if(!aio_24){
37981 +               err = init_aio_26();
37982 +               if(err && (errno == ENOSYS)){
37983 +                       printk("2.6 AIO not supported on the host - "
37984 +                              "reverting to 2.4 AIO\n");
37985 +                       aio_24 = 1;
37986 +               }
37987 +               else return(err);
37988 +       }
37989 +
37990 +       if(aio_24)
37991 +               return(init_aio_24());
37992 +
37993 +       return(0);
37994 +}
37995 +
37996 +__initcall(init_aio);
37997 +
37998 +static void exit_aio(void)
37999 +{
38000 +       if(aio_pid != -1)
38001 +               os_kill_process(aio_pid, 1);
38002 +}
38003 +
38004 +__uml_exitcall(exit_aio);
38005 +
38006 +int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len, 
38007 +                 unsigned long long offset, int reply_fd, void *data)
38008 +{
38009 +       struct aio_thread_req req = { .type             = type,
38010 +                                     .io_fd            = io_fd,
38011 +                                     .offset           = offset,
38012 +                                     .buf              = buf,
38013 +                                     .len              = len,
38014 +                                     .reply_fd         = reply_fd,
38015 +                                     .data             = data,
38016 +       };
38017 +       int err;
38018 +
38019 +       err = os_write_file(aio_req_fd_w, &req, sizeof(req));
38020 +       if(err == sizeof(req))
38021 +               err = 0;
38022 +
38023 +       return(err);
38024 +}
38025 +
38026 +int submit_aio(enum aio_type type, int io_fd, char *buf, int len, 
38027 +              unsigned long long offset, int reply_fd, void *data)
38028 +{
38029 +       if(aio_24)
38030 +               return(submit_aio_24(type, io_fd, buf, len, offset, reply_fd, 
38031 +                                    data));
38032 +       else {
38033 +               return(submit_aio_26(type, io_fd, buf, len, offset, reply_fd, 
38034 +                                    data));
38035 +       }
38036 +}
38037 +
38038 +/*
38039 + * Overrides for Emacs so that we follow Linus's tabbing style.
38040 + * Emacs will notice this stuff at the end of the file and automatically
38041 + * adjust the settings for this buffer only.  This must remain at the end
38042 + * of the file.
38043 + * ---------------------------------------------------------------------------
38044 + * Local variables:
38045 + * c-file-style: "linux"
38046 + * End:
38047 + */
38048 Index: linux-2.4.29/arch/um/os-Linux/drivers/etap.h
38049 ===================================================================
38050 --- linux-2.4.29.orig/arch/um/os-Linux/drivers/etap.h   1970-01-01 03:00:00.000000000 +0300
38051 +++ linux-2.4.29/arch/um/os-Linux/drivers/etap.h        2005-05-03 22:28:14.000000000 +0300
38052 @@ -0,0 +1,27 @@
38053 +/* 
38054 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
38055 + * Licensed under the GPL
38056 + */
38057 +
38058 +#include "net_user.h"
38059 +
38060 +struct ethertap_data {
38061 +       char *dev_name;
38062 +       char *gate_addr;
38063 +       int data_fd;
38064 +       int control_fd;
38065 +       void *dev;
38066 +};
38067 +
38068 +extern struct net_user_info ethertap_user_info;
38069 +
38070 +/*
38071 + * Overrides for Emacs so that we follow Linus's tabbing style.
38072 + * Emacs will notice this stuff at the end of the file and automatically
38073 + * adjust the settings for this buffer only.  This must remain at the end
38074 + * of the file.
38075 + * ---------------------------------------------------------------------------
38076 + * Local variables:
38077 + * c-file-style: "linux"
38078 + * End:
38079 + */
38080 Index: linux-2.4.29/arch/um/os-Linux/drivers/ethertap_kern.c
38081 ===================================================================
38082 --- linux-2.4.29.orig/arch/um/os-Linux/drivers/ethertap_kern.c  1970-01-01 03:00:00.000000000 +0300
38083 +++ linux-2.4.29/arch/um/os-Linux/drivers/ethertap_kern.c       2005-05-03 22:28:14.000000000 +0300
38084 @@ -0,0 +1,121 @@
38085 +/*
38086 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
38087 + * James Leu (jleu@mindspring.net).
38088 + * Copyright (C) 2001 by various other people who didn't put their name here.
38089 + * Licensed under the GPL.
38090 + */
38091 +
38092 +#include "linux/init.h"
38093 +#include "linux/netdevice.h"
38094 +#include "linux/etherdevice.h"
38095 +#include "net_kern.h"
38096 +#include "net_user.h"
38097 +#include "etap.h"
38098 +
38099 +struct ethertap_init {
38100 +       char *dev_name;
38101 +       char *gate_addr;
38102 +};
38103 +
38104 +static void etap_init(struct net_device *dev, void *data)
38105 +{
38106 +       struct uml_net_private *pri;
38107 +       struct ethertap_data *epri;
38108 +       struct ethertap_init *init = data;
38109 +
38110 +       init_etherdev(dev, 0);
38111 +       pri = dev->priv;
38112 +       epri = (struct ethertap_data *) pri->user;
38113 +       *epri = ((struct ethertap_data)
38114 +               { .dev_name             = init->dev_name,
38115 +                 .gate_addr            = init->gate_addr,
38116 +                 .data_fd              = -1,
38117 +                 .control_fd           = -1,
38118 +                 .dev                  = dev });
38119 +
38120 +       printk("ethertap backend - %s", epri->dev_name);
38121 +       if(epri->gate_addr != NULL) 
38122 +               printk(", IP = %s", epri->gate_addr);
38123 +       printk("\n");
38124 +}
38125 +
38126 +static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
38127 +{
38128 +       int len;
38129 +
38130 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
38131 +       if(*skb == NULL) return(-ENOMEM);
38132 +       len = net_recvfrom(fd, (*skb)->mac.raw, 
38133 +                          (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
38134 +       if(len <= 0) return(len);
38135 +       skb_pull(*skb, 2);
38136 +       len -= 2;
38137 +       return(len);
38138 +}
38139 +
38140 +static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
38141 +{
38142 +       if(skb_headroom(*skb) < 2){
38143 +               struct sk_buff *skb2;
38144 +
38145 +               skb2 = skb_realloc_headroom(*skb, 2);
38146 +               dev_kfree_skb(*skb);
38147 +               if (skb2 == NULL) return(-ENOMEM);
38148 +               *skb = skb2;
38149 +       }
38150 +       skb_push(*skb, 2);
38151 +       return(net_send(fd, (*skb)->data, (*skb)->len));
38152 +}
38153 +
38154 +struct net_kern_info ethertap_kern_info = {
38155 +       .init                   = etap_init,
38156 +       .protocol               = eth_protocol,
38157 +       .read                   = etap_read,
38158 +       .write                  = etap_write,
38159 +};
38160 +
38161 +int ethertap_setup(char *str, char **mac_out, void *data)
38162 +{
38163 +       struct ethertap_init *init = data;
38164 +
38165 +       *init = ((struct ethertap_init)
38166 +               { .dev_name     = NULL,
38167 +                 .gate_addr    = NULL });
38168 +       if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
38169 +                           &init->gate_addr))
38170 +               return(0);
38171 +       if(init->dev_name == NULL){
38172 +               printk("ethertap_setup : Missing tap device name\n");
38173 +               return(0);
38174 +       }
38175 +
38176 +       return(1);
38177 +}
38178 +
38179 +static struct transport ethertap_transport = {
38180 +       .list           = LIST_HEAD_INIT(ethertap_transport.list),
38181 +       .name           = "ethertap",
38182 +       .setup          = ethertap_setup,
38183 +       .user           = &ethertap_user_info,
38184 +       .kern           = &ethertap_kern_info,
38185 +       .private_size   = sizeof(struct ethertap_data),
38186 +};
38187 +
38188 +static int register_ethertap(void)
38189 +{
38190 +       register_transport(&ethertap_transport);
38191 +       return(1);
38192 +}
38193 +
38194 +__initcall(register_ethertap);
38195 +
38196 +/*
38197 + * Overrides for Emacs so that we follow Linus's tabbing style.
38198 + * Emacs will notice this stuff at the end of the file and automatically
38199 + * adjust the settings for this buffer only.  This must remain at the end
38200 + * of the file.
38201 + * ---------------------------------------------------------------------------
38202 + * Local variables:
38203 + * c-file-style: "linux"
38204 + * End:
38205 + */
38206 Index: linux-2.4.29/arch/um/os-Linux/drivers/ethertap_user.c
38207 ===================================================================
38208 --- linux-2.4.29.orig/arch/um/os-Linux/drivers/ethertap_user.c  1970-01-01 03:00:00.000000000 +0300
38209 +++ linux-2.4.29/arch/um/os-Linux/drivers/ethertap_user.c       2005-05-03 22:28:14.000000000 +0300
38210 @@ -0,0 +1,240 @@
38211 +/*
38212 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
38213 + * James Leu (jleu@mindspring.net).
38214 + * Copyright (C) 2001 by various other people who didn't put their name here.
38215 + * Licensed under the GPL.
38216 + */
38217 +
38218 +#include <stdio.h>
38219 +#include <unistd.h>
38220 +#include <stddef.h>
38221 +#include <stdlib.h>
38222 +#include <sys/errno.h>
38223 +#include <sys/socket.h>
38224 +#include <sys/wait.h>
38225 +#include <sys/un.h>
38226 +#include <net/if.h>
38227 +#include "user.h"
38228 +#include "kern_util.h"
38229 +#include "user_util.h"
38230 +#include "net_user.h"
38231 +#include "etap.h"
38232 +#include "helper.h"
38233 +#include "os.h"
38234 +
38235 +#define MAX_PACKET ETH_MAX_PACKET
38236 +
38237 +void etap_user_init(void *data, void *dev)
38238 +{
38239 +       struct ethertap_data *pri = data;
38240 +
38241 +       pri->dev = dev;
38242 +}
38243 +
38244 +struct addr_change {
38245 +       enum { ADD_ADDR, DEL_ADDR } what;
38246 +       unsigned char addr[4];
38247 +       unsigned char netmask[4];
38248 +};
38249 +
38250 +static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
38251 +                       int fd)
38252 +{
38253 +       struct addr_change change;
38254 +       void *output;
38255 +       int n;
38256 +
38257 +       change.what = op;
38258 +       memcpy(change.addr, addr, sizeof(change.addr));
38259 +       memcpy(change.netmask, netmask, sizeof(change.netmask));
38260 +       n = os_write_file(fd, &change, sizeof(change));
38261 +       if(n != sizeof(change))
38262 +               printk("etap_change - request failed, err = %d\n", -n);
38263 +       output = um_kmalloc(page_size());
38264 +       if(output == NULL)
38265 +               printk("etap_change : Failed to allocate output buffer\n");
38266 +       read_output(fd, output, page_size());
38267 +       if(output != NULL){
38268 +               printk("%s", output);
38269 +               kfree(output);
38270 +       }
38271 +}
38272 +
38273 +static void etap_open_addr(unsigned char *addr, unsigned char *netmask,
38274 +                          void *arg)
38275 +{
38276 +       etap_change(ADD_ADDR, addr, netmask, *((int *) arg));
38277 +}
38278 +
38279 +static void etap_close_addr(unsigned char *addr, unsigned char *netmask,
38280 +                           void *arg)
38281 +{
38282 +       etap_change(DEL_ADDR, addr, netmask, *((int *) arg));
38283 +}
38284 +
38285 +struct etap_pre_exec_data {
38286 +       int control_remote;
38287 +       int control_me;
38288 +       int data_me;
38289 +};
38290 +
38291 +static void etap_pre_exec(void *arg)
38292 +{
38293 +       struct etap_pre_exec_data *data = arg;
38294 +
38295 +       dup2(data->control_remote, 1);
38296 +       os_close_file(data->data_me);
38297 +       os_close_file(data->control_me);
38298 +}
38299 +
38300 +static int etap_tramp(char *dev, char *gate, int control_me, 
38301 +                     int control_remote, int data_me, int data_remote)
38302 +{
38303 +       struct etap_pre_exec_data pe_data;
38304 +       int pid, status, err, n;
38305 +       char version_buf[sizeof("nnnnn\0")];
38306 +       char data_fd_buf[sizeof("nnnnnn\0")];
38307 +       char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
38308 +       char *setup_args[] = { "uml_net", version_buf, "ethertap", dev,
38309 +                              data_fd_buf, gate_buf, NULL };
38310 +       char *nosetup_args[] = { "uml_net", version_buf, "ethertap", 
38311 +                                dev, data_fd_buf, NULL };
38312 +       char **args, c;
38313 +
38314 +       sprintf(data_fd_buf, "%d", data_remote);
38315 +       sprintf(version_buf, "%d", UML_NET_VERSION);
38316 +       if(gate != NULL){
38317 +               strcpy(gate_buf, gate);
38318 +               args = setup_args;
38319 +       }
38320 +       else args = nosetup_args;
38321 +
38322 +       err = 0;
38323 +       pe_data.control_remote = control_remote;
38324 +       pe_data.control_me = control_me;
38325 +       pe_data.data_me = data_me;
38326 +       pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
38327 +
38328 +       if(pid < 0) err = pid;
38329 +       os_close_file(data_remote);
38330 +       os_close_file(control_remote);
38331 +       n = os_read_file(control_me, &c, sizeof(c));
38332 +       if(n != sizeof(c)){
38333 +               printk("etap_tramp : read of status failed, err = %d\n", -n);
38334 +               return(-EINVAL);
38335 +       }
38336 +       if(c != 1){
38337 +               printk("etap_tramp : uml_net failed\n");
38338 +               err = -EINVAL;
38339 +               CATCH_EINTR(n = waitpid(pid, &status, 0));
38340 +               if(n < 0)
38341 +                       err = -errno;
38342 +               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
38343 +                       printk("uml_net didn't exit with status 1\n");
38344 +       }
38345 +       return(err);
38346 +}
38347 +
38348 +static int etap_open(void *data)
38349 +{
38350 +       struct ethertap_data *pri = data;
38351 +       char *output;
38352 +       int data_fds[2], control_fds[2], err, output_len;
38353 +
38354 +       err = tap_open_common(pri->dev, pri->gate_addr);
38355 +       if(err) return(err);
38356 +
38357 +       err = os_pipe(data_fds, 0, 0);
38358 +       if(err < 0){
38359 +               printk("data os_pipe failed - err = %d\n", -err);
38360 +               return(err);
38361 +       }
38362 +
38363 +       err = os_pipe(control_fds, 1, 0);
38364 +       if(err < 0){
38365 +               printk("control os_pipe failed - err = %d\n", -err);
38366 +               return(err);
38367 +       }
38368 +       
38369 +       err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], 
38370 +                        control_fds[1], data_fds[0], data_fds[1]);
38371 +       output_len = page_size();
38372 +       output = um_kmalloc(output_len);
38373 +       read_output(control_fds[0], output, output_len);
38374 +
38375 +       if(output == NULL)
38376 +               printk("etap_open : failed to allocate output buffer\n");
38377 +       else {
38378 +               printk("%s", output);
38379 +               kfree(output);
38380 +       }
38381 +
38382 +       if(err < 0){
38383 +               printk("etap_tramp failed - err = %d\n", -err);
38384 +               return(err);
38385 +       }
38386 +
38387 +       pri->data_fd = data_fds[0];
38388 +       pri->control_fd = control_fds[0];
38389 +       iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
38390 +       return(data_fds[0]);
38391 +}
38392 +
38393 +static void etap_close(int fd, void *data)
38394 +{
38395 +       struct ethertap_data *pri = data;
38396 +
38397 +       iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
38398 +       os_close_file(fd);
38399 +       os_shutdown_socket(pri->data_fd, 1, 1);
38400 +       os_close_file(pri->data_fd);
38401 +       pri->data_fd = -1;
38402 +       os_close_file(pri->control_fd);
38403 +       pri->control_fd = -1;
38404 +}
38405 +
38406 +static int etap_set_mtu(int mtu, void *data)
38407 +{
38408 +       return(mtu);
38409 +}
38410 +
38411 +static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
38412 +                         void *data)
38413 +{
38414 +       struct ethertap_data *pri = data;
38415 +
38416 +       tap_check_ips(pri->gate_addr, addr);
38417 +       if(pri->control_fd == -1) return;
38418 +       etap_open_addr(addr, netmask, &pri->control_fd);
38419 +}
38420 +
38421 +static void etap_del_addr(unsigned char *addr, unsigned char *netmask, 
38422 +                         void *data)
38423 +{
38424 +       struct ethertap_data *pri = data;
38425 +
38426 +       if(pri->control_fd == -1) return;
38427 +       etap_close_addr(addr, netmask, &pri->control_fd);
38428 +}
38429 +
38430 +struct net_user_info ethertap_user_info = {
38431 +       .init           = etap_user_init,
38432 +       .open           = etap_open,
38433 +       .close          = etap_close,
38434 +       .remove         = NULL,
38435 +       .set_mtu        = etap_set_mtu,
38436 +       .add_address    = etap_add_addr,
38437 +       .delete_address = etap_del_addr,
38438 +       .max_packet     = MAX_PACKET - ETH_HEADER_ETHERTAP
38439 +};
38440 +
38441 +/*
38442 + * Overrides for Emacs so that we follow Linus's tabbing style.
38443 + * Emacs will notice this stuff at the end of the file and automatically
38444 + * adjust the settings for this buffer only.  This must remain at the end
38445 + * of the file.
38446 + * ---------------------------------------------------------------------------
38447 + * Local variables:
38448 + * c-file-style: "linux"
38449 + * End:
38450 + */
38451 Index: linux-2.4.29/arch/um/os-Linux/drivers/Makefile
38452 ===================================================================
38453 --- linux-2.4.29.orig/arch/um/os-Linux/drivers/Makefile 1970-01-01 03:00:00.000000000 +0300
38454 +++ linux-2.4.29/arch/um/os-Linux/drivers/Makefile      2005-05-03 22:28:14.568395480 +0300
38455 @@ -0,0 +1,31 @@
38456 +# 
38457 +# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
38458 +# Licensed under the GPL
38459 +#
38460 +
38461 +O_TARGET := drivers.o
38462 +
38463 +list-multi := tuntap.o ethertap.o
38464 +
38465 +ethertap-objs := ethertap_kern.o ethertap_user.o
38466 +tuntap-objs := tuntap_kern.o tuntap_user.o
38467 +
38468 +obj-y = 
38469 +obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap.o
38470 +obj-$(CONFIG_UML_NET_TUNTAP) += tuntap.o
38471 +
38472 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y)),$($(f)-objs))
38473 +
38474 +USER_OBJS = $(filter %_user.o,$(obj-y) $(USER_SINGLE_OBJS))
38475 +
38476 +include $(TOPDIR)/Rules.make
38477 +
38478 +$(USER_OBJS) : %.o: %.c
38479 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
38480 +
38481 +ethertap.o : $(ethertap-objs)
38482 +
38483 +tuntap.o : $(tuntap-objs)
38484 +
38485 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
38486 +       $(LD) $(LD_RFLAG) -r -o $@ $($(patsubst %.o,%,$@)-objs)
38487 Index: linux-2.4.29/arch/um/os-Linux/drivers/tuntap.h
38488 ===================================================================
38489 --- linux-2.4.29.orig/arch/um/os-Linux/drivers/tuntap.h 1970-01-01 03:00:00.000000000 +0300
38490 +++ linux-2.4.29/arch/um/os-Linux/drivers/tuntap.h      2005-05-03 22:28:14.568395480 +0300
38491 @@ -0,0 +1,32 @@
38492 +/* 
38493 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
38494 + * Licensed under the GPL
38495 + */
38496 +
38497 +#ifndef __UM_TUNTAP_H
38498 +#define __UM_TUNTAP_H
38499 +
38500 +#include "net_user.h"
38501 +
38502 +struct tuntap_data {
38503 +       char *dev_name;
38504 +       int fixed_config;
38505 +       char *gate_addr;
38506 +       int fd;
38507 +       void *dev;
38508 +};
38509 +
38510 +extern struct net_user_info tuntap_user_info;
38511 +
38512 +#endif
38513 +
38514 +/*
38515 + * Overrides for Emacs so that we follow Linus's tabbing style.
38516 + * Emacs will notice this stuff at the end of the file and automatically
38517 + * adjust the settings for this buffer only.  This must remain at the end
38518 + * of the file.
38519 + * ---------------------------------------------------------------------------
38520 + * Local variables:
38521 + * c-file-style: "linux"
38522 + * End:
38523 + */
38524 Index: linux-2.4.29/arch/um/os-Linux/drivers/tuntap_kern.c
38525 ===================================================================
38526 --- linux-2.4.29.orig/arch/um/os-Linux/drivers/tuntap_kern.c    1970-01-01 03:00:00.000000000 +0300
38527 +++ linux-2.4.29/arch/um/os-Linux/drivers/tuntap_kern.c 2005-05-03 22:28:14.569395328 +0300
38528 @@ -0,0 +1,105 @@
38529 +/* 
38530 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
38531 + * Licensed under the GPL
38532 + */
38533 +
38534 +#include "linux/stddef.h"
38535 +#include "linux/netdevice.h"
38536 +#include "linux/etherdevice.h"
38537 +#include "linux/skbuff.h"
38538 +#include "linux/init.h"
38539 +#include "asm/errno.h"
38540 +#include "net_kern.h"
38541 +#include "net_user.h"
38542 +#include "tuntap.h"
38543 +
38544 +struct tuntap_init {
38545 +       char *dev_name;
38546 +       char *gate_addr;
38547 +};
38548 +
38549 +static void tuntap_init(struct net_device *dev, void *data)
38550 +{
38551 +       struct uml_net_private *pri;
38552 +       struct tuntap_data *tpri;
38553 +       struct tuntap_init *init = data;
38554 +
38555 +       init_etherdev(dev, 0);
38556 +       pri = dev->priv;
38557 +       tpri = (struct tuntap_data *) pri->user;
38558 +       *tpri = ((struct tuntap_data)
38559 +               { .dev_name             = init->dev_name,
38560 +                 .fixed_config         = (init->dev_name != NULL),
38561 +                 .gate_addr            = init->gate_addr,
38562 +                 .fd                   = -1,
38563 +                 .dev                  = dev });
38564 +       printk("TUN/TAP backend - ");
38565 +       if(tpri->gate_addr != NULL) 
38566 +               printk("IP = %s", tpri->gate_addr);
38567 +       printk("\n");
38568 +}
38569 +
38570 +static int tuntap_read(int fd, struct sk_buff **skb, 
38571 +                      struct uml_net_private *lp)
38572 +{
38573 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
38574 +       if(*skb == NULL) return(-ENOMEM);
38575 +       return(net_read(fd, (*skb)->mac.raw, 
38576 +                       (*skb)->dev->mtu + ETH_HEADER_OTHER));
38577 +}
38578 +
38579 +static int tuntap_write(int fd, struct sk_buff **skb, 
38580 +                       struct uml_net_private *lp)
38581 +{
38582 +       return(net_write(fd, (*skb)->data, (*skb)->len));
38583 +}
38584 +
38585 +struct net_kern_info tuntap_kern_info = {
38586 +       .init                   = tuntap_init,
38587 +       .protocol               = eth_protocol,
38588 +       .read                   = tuntap_read,
38589 +       .write                  = tuntap_write,
38590 +};
38591 +
38592 +int tuntap_setup(char *str, char **mac_out, void *data)
38593 +{
38594 +       struct tuntap_init *init = data;
38595 +
38596 +       *init = ((struct tuntap_init)
38597 +               { .dev_name     = NULL,
38598 +                 .gate_addr    = NULL });
38599 +       if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
38600 +                           &init->gate_addr))
38601 +               return(0);
38602 +
38603 +       return(1);
38604 +}
38605 +
38606 +static struct transport tuntap_transport = {
38607 +       .list           = LIST_HEAD_INIT(tuntap_transport.list),
38608 +       .name           = "tuntap",
38609 +       .setup          = tuntap_setup,
38610 +       .user           = &tuntap_user_info,
38611 +       .kern           = &tuntap_kern_info,
38612 +       .private_size   = sizeof(struct tuntap_data),
38613 +       .setup_size     = sizeof(struct tuntap_init),
38614 +};
38615 +
38616 +static int register_tuntap(void)
38617 +{
38618 +       register_transport(&tuntap_transport);
38619 +       return(1);
38620 +}
38621 +
38622 +__initcall(register_tuntap);
38623 +
38624 +/*
38625 + * Overrides for Emacs so that we follow Linus's tabbing style.
38626 + * Emacs will notice this stuff at the end of the file and automatically
38627 + * adjust the settings for this buffer only.  This must remain at the end
38628 + * of the file.
38629 + * ---------------------------------------------------------------------------
38630 + * Local variables:
38631 + * c-file-style: "linux"
38632 + * End:
38633 + */
38634 Index: linux-2.4.29/arch/um/os-Linux/drivers/tuntap_user.c
38635 ===================================================================
38636 --- linux-2.4.29.orig/arch/um/os-Linux/drivers/tuntap_user.c    1970-01-01 03:00:00.000000000 +0300
38637 +++ linux-2.4.29/arch/um/os-Linux/drivers/tuntap_user.c 2005-05-03 22:28:14.571395024 +0300
38638 @@ -0,0 +1,225 @@
38639 +/* 
38640 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
38641 + * Licensed under the GPL
38642 + */
38643 +
38644 +#include <stdio.h>
38645 +#include <stddef.h>
38646 +#include <stdlib.h>
38647 +#include <unistd.h>
38648 +#include <errno.h>
38649 +#include <sys/wait.h>
38650 +#include <sys/socket.h>
38651 +#include <sys/un.h>
38652 +#include <sys/uio.h>
38653 +#include <sys/ioctl.h>
38654 +#include <net/if.h>
38655 +#include <linux/if_tun.h>
38656 +#include "net_user.h"
38657 +#include "tuntap.h"
38658 +#include "kern_util.h"
38659 +#include "user_util.h"
38660 +#include "user.h"
38661 +#include "helper.h"
38662 +#include "os.h"
38663 +
38664 +#define MAX_PACKET ETH_MAX_PACKET
38665 +
38666 +void tuntap_user_init(void *data, void *dev)
38667 +{
38668 +       struct tuntap_data *pri = data;
38669 +
38670 +       pri->dev = dev;
38671 +}
38672 +
38673 +static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
38674 +                           void *data)
38675 +{
38676 +       struct tuntap_data *pri = data;
38677 +
38678 +       tap_check_ips(pri->gate_addr, addr);
38679 +       if((pri->fd == -1) || pri->fixed_config) return;
38680 +       open_addr(addr, netmask, pri->dev_name);
38681 +}
38682 +
38683 +static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
38684 +                           void *data)
38685 +{
38686 +       struct tuntap_data *pri = data;
38687 +
38688 +       if((pri->fd == -1) || pri->fixed_config) return;
38689 +       close_addr(addr, netmask, pri->dev_name);
38690 +}
38691 +
38692 +struct tuntap_pre_exec_data {
38693 +       int stdout;
38694 +       int close_me;
38695 +};
38696 +
38697 +static void tuntap_pre_exec(void *arg)
38698 +{
38699 +       struct tuntap_pre_exec_data *data = arg;
38700 +       
38701 +       dup2(data->stdout, 1);
38702 +       os_close_file(data->close_me);
38703 +}
38704 +
38705 +static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
38706 +                            char *buffer, int buffer_len, int *used_out)
38707 +{
38708 +       struct tuntap_pre_exec_data data;
38709 +       char version_buf[sizeof("nnnnn\0")];
38710 +       char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate,
38711 +                        NULL };
38712 +       char buf[CMSG_SPACE(sizeof(*fd_out))];
38713 +       struct msghdr msg;
38714 +       struct cmsghdr *cmsg;
38715 +       struct iovec iov;
38716 +       int pid, n;
38717 +
38718 +       sprintf(version_buf, "%d", UML_NET_VERSION);
38719 +
38720 +       data.stdout = remote;
38721 +       data.close_me = me;
38722 +
38723 +       pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
38724 +
38725 +       if(pid < 0) return(-pid);
38726 +
38727 +       os_close_file(remote);
38728 +
38729 +       msg.msg_name = NULL;
38730 +       msg.msg_namelen = 0;
38731 +       if(buffer != NULL){
38732 +               iov = ((struct iovec) { buffer, buffer_len });
38733 +               msg.msg_iov = &iov;
38734 +               msg.msg_iovlen = 1;
38735 +       }
38736 +       else {
38737 +               msg.msg_iov = NULL;
38738 +               msg.msg_iovlen = 0;
38739 +       }
38740 +       msg.msg_control = buf;
38741 +       msg.msg_controllen = sizeof(buf);
38742 +       msg.msg_flags = 0;
38743 +       n = recvmsg(me, &msg, 0);
38744 +       *used_out = n;
38745 +       if(n < 0){
38746 +               printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", 
38747 +                      errno);
38748 +               return(-errno);
38749 +       }
38750 +       CATCH_EINTR(waitpid(pid, NULL, 0));
38751 +
38752 +       cmsg = CMSG_FIRSTHDR(&msg);
38753 +       if(cmsg == NULL){
38754 +               printk("tuntap_open_tramp : didn't receive a message\n");
38755 +               return(-EINVAL);
38756 +       }
38757 +       if((cmsg->cmsg_level != SOL_SOCKET) || 
38758 +          (cmsg->cmsg_type != SCM_RIGHTS)){
38759 +               printk("tuntap_open_tramp : didn't receive a descriptor\n");
38760 +               return(-EINVAL);
38761 +       }
38762 +       *fd_out = ((int *) CMSG_DATA(cmsg))[0];
38763 +       return(0);
38764 +}
38765 +
38766 +static int tuntap_open(void *data)
38767 +{
38768 +       struct ifreq ifr;
38769 +       struct tuntap_data *pri = data;
38770 +       char *output, *buffer;
38771 +       int err, fds[2], len, used;
38772 +
38773 +       err = tap_open_common(pri->dev, pri->gate_addr);
38774 +       if(err < 0) 
38775 +               return(err);
38776 +
38777 +       if(pri->fixed_config){
38778 +               pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
38779 +               if(pri->fd < 0){
38780 +                       printk("Failed to open /dev/net/tun, err = %d\n",
38781 +                              -pri->fd);
38782 +                       return(pri->fd);
38783 +               }
38784 +               memset(&ifr, 0, sizeof(ifr));
38785 +               ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
38786 +               strncpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name) - 1);
38787 +               if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
38788 +                       printk("TUNSETIFF failed, errno = %d\n", errno);
38789 +                       os_close_file(pri->fd);
38790 +                       return(-errno);
38791 +               }
38792 +       }
38793 +       else {
38794 +               err = os_pipe(fds, 0, 0);
38795 +               if(err < 0){
38796 +                       printk("tuntap_open : os_pipe failed - err = %d\n",
38797 +                              -err);
38798 +                       return(err);
38799 +               }
38800 +
38801 +               buffer = get_output_buffer(&len);
38802 +               if(buffer != NULL) len--;
38803 +               used = 0;
38804 +
38805 +               err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
38806 +                                       fds[1], buffer, len, &used);
38807 +
38808 +               output = buffer;
38809 +               if(err < 0) {
38810 +                       printk("%s", output);
38811 +                       free_output_buffer(buffer);
38812 +                       printk("tuntap_open_tramp failed - err = %d\n", -err);
38813 +                       return(err);
38814 +               }
38815 +
38816 +               pri->dev_name = uml_strdup(buffer);
38817 +               output += IFNAMSIZ;
38818 +               printk("%s", output);
38819 +               free_output_buffer(buffer);
38820 +
38821 +               os_close_file(fds[0]);
38822 +               iter_addresses(pri->dev, open_addr, pri->dev_name);
38823 +       }
38824 +
38825 +       return(pri->fd);
38826 +}
38827 +
38828 +static void tuntap_close(int fd, void *data)
38829 +{
38830 +       struct tuntap_data *pri = data;
38831 +
38832 +       if(!pri->fixed_config) 
38833 +               iter_addresses(pri->dev, close_addr, pri->dev_name);
38834 +       os_close_file(fd);
38835 +       pri->fd = -1;
38836 +}
38837 +
38838 +static int tuntap_set_mtu(int mtu, void *data)
38839 +{
38840 +       return(mtu);
38841 +}
38842 +
38843 +struct net_user_info tuntap_user_info = {
38844 +       .init           = tuntap_user_init,
38845 +       .open           = tuntap_open,
38846 +       .close          = tuntap_close,
38847 +       .remove         = NULL,
38848 +       .set_mtu        = tuntap_set_mtu,
38849 +       .add_address    = tuntap_add_addr,
38850 +       .delete_address = tuntap_del_addr,
38851 +       .max_packet     = MAX_PACKET
38852 +};
38853 +
38854 +/*
38855 + * Overrides for Emacs so that we follow Linus's tabbing style.
38856 + * Emacs will notice this stuff at the end of the file and automatically
38857 + * adjust the settings for this buffer only.  This must remain at the end
38858 + * of the file.
38859 + * ---------------------------------------------------------------------------
38860 + * Local variables:
38861 + * c-file-style: "linux"
38862 + * End:
38863 + */
38864 Index: linux-2.4.29/arch/um/os-Linux/file.c
38865 ===================================================================
38866 --- linux-2.4.29.orig/arch/um/os-Linux/file.c   1970-01-01 03:00:00.000000000 +0300
38867 +++ linux-2.4.29/arch/um/os-Linux/file.c        2005-05-03 22:28:14.574394568 +0300
38868 @@ -0,0 +1,942 @@
38869 +/* 
38870 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38871 + * Licensed under the GPL
38872 + */
38873 +
38874 +#include <stdio.h>
38875 +#include <unistd.h>
38876 +#include <errno.h>
38877 +#include <fcntl.h>
38878 +#include <signal.h>
38879 +#include <utime.h>
38880 +#include <dirent.h>
38881 +#include <linux/kdev_t.h>
38882 +#include <sys/types.h>
38883 +#include <sys/stat.h>
38884 +#include <sys/socket.h>
38885 +#include <sys/un.h>
38886 +#include <sys/ioctl.h>
38887 +#include <sys/mount.h>
38888 +#include <sys/uio.h>
38889 +#include <sys/utsname.h>
38890 +#include <sys/vfs.h>
38891 +#include "os.h"
38892 +#include "user.h"
38893 +#include "kern_util.h"
38894 +
38895 +static void copy_stat(struct uml_stat *dst, struct stat64 *src)
38896 +{
38897 +       *dst = ((struct uml_stat) {
38898 +               .ust_major   = MAJOR(src->st_dev),     /* device */
38899 +               .ust_minor   = MINOR(src->st_dev),
38900 +               .ust_ino     = src->st_ino,     /* inode */
38901 +               .ust_mode    = src->st_mode,    /* protection */
38902 +               .ust_nlink   = src->st_nlink,   /* number of hard links */
38903 +               .ust_uid     = src->st_uid,     /* user ID of owner */
38904 +               .ust_gid     = src->st_gid,     /* group ID of owner */
38905 +               .ust_size    = src->st_size,    /* total size, in bytes */
38906 +               .ust_blksize = src->st_blksize, /* blocksize for filesys I/O */
38907 +               .ust_blocks  = src->st_blocks,  /* number of blocks allocated */
38908 +               .ust_atime   = src->st_atime,   /* time of last access */
38909 +               .ust_mtime   = src->st_mtime,   /* time of last modification */
38910 +               .ust_ctime   = src->st_ctime,   /* time of last change */
38911 +               .ust_rmajor  = MAJOR(src->st_rdev),
38912 +               .ust_rminor  = MINOR(src->st_rdev),
38913 +       });
38914 +}
38915 +
38916 +int os_stat_fd(const int fd, struct uml_stat *ubuf)
38917 +{
38918 +       struct stat64 sbuf;
38919 +       int err;
38920 +
38921 +       do {
38922 +               err = fstat64(fd, &sbuf);
38923 +       } while((err < 0) && (errno == EINTR)) ;
38924 +
38925 +       if(err < 0) 
38926 +               return(-errno);
38927 +
38928 +       if(ubuf != NULL)
38929 +               copy_stat(ubuf, &sbuf);
38930 +       return(err);
38931 +}
38932 +
38933 +int os_stat_file(const char *file_name, struct uml_stat *ubuf)
38934 +{
38935 +       struct stat64 sbuf;
38936 +       int err;
38937 +
38938 +       do {
38939 +               err = stat64(file_name, &sbuf);
38940 +       } while((err < 0) && (errno == EINTR)) ;
38941 +
38942 +       if(err < 0) 
38943 +               return(-errno);
38944 +
38945 +       if(ubuf != NULL)
38946 +               copy_stat(ubuf, &sbuf);
38947 +       return(err);
38948 +}
38949 +
38950 +int os_lstat_file(const char *file_name, struct uml_stat *ubuf)
38951 +{
38952 +       struct stat64 sbuf;
38953 +       int err;
38954 +
38955 +       do {
38956 +               err = lstat64(file_name, &sbuf);
38957 +       } while((err < 0) && (errno == EINTR)) ;
38958 +
38959 +       if(err < 0) 
38960 +               return(-errno);
38961 +
38962 +       if(ubuf != NULL)
38963 +               copy_stat(ubuf, &sbuf);
38964 +       return(err);
38965 +}
38966 +
38967 +int os_access(const char *file, int mode)
38968 +{
38969 +       int amode, err;
38970 +
38971 +       amode=(mode& OS_ACC_R_OK ? R_OK : 0) | (mode& OS_ACC_W_OK ? W_OK : 0) |
38972 +             (mode& OS_ACC_X_OK ? X_OK : 0) | (mode& OS_ACC_F_OK ? F_OK : 0) ;
38973 +
38974 +       err = access(file, amode);
38975 +       if(err < 0)
38976 +               return(-errno);
38977 +
38978 +       return(0);
38979 +}
38980 +
38981 +int os_set_file_time(const char *file, unsigned long access, unsigned long mod)
38982 +{
38983 +       struct utimbuf buf = ((struct utimbuf){ .actime = access, 
38984 +                                               .modtime = mod });
38985 +       int err;
38986 +
38987 +       err = utime(file, &buf);
38988 +       if(err < 0)
38989 +               return(-errno);
38990 +
38991 +       return(0);
38992 +}
38993 +
38994 +int os_set_file_perms(const char *file, int mode)
38995 +{
38996 +       int err;
38997 +
38998 +       err = chmod(file, mode);
38999 +       if(err < 0)
39000 +               return(-errno);
39001 +
39002 +       return(0);
39003 +}
39004 +
39005 +int os_set_file_owner(const char *file, int owner, int group)
39006 +{
39007 +       int err;
39008 +
39009 +       err = chown(file, owner, group);
39010 +       if(err < 0)
39011 +               return(-errno);
39012 +
39013 +       return(0);
39014 +}
39015 +
39016 +void os_print_error(int error, const char* str)
39017 +{
39018 +       errno = error < 0 ? -error : error;
39019 +
39020 +       perror(str);
39021 +}
39022 +
39023 +/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
39024 +int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
39025 +{
39026 +       int err;
39027 +
39028 +       err = ioctl(fd, cmd, arg);
39029 +       if(err < 0)
39030 +               return(-errno);
39031 +
39032 +       return(err);
39033 +}
39034 +
39035 +int os_window_size(int fd, int *rows, int *cols)
39036 +{
39037 +       struct winsize size;
39038 +
39039 +       if(ioctl(fd, TIOCGWINSZ, &size) < 0)
39040 +               return(-errno);
39041 +
39042 +       *rows = size.ws_row;
39043 +       *cols = size.ws_col;
39044 +
39045 +       return(0);
39046 +}
39047 +
39048 +int os_new_tty_pgrp(int fd, int pid)
39049 +{
39050 +       if(ioctl(fd, TIOCSCTTY, 0) < 0){
39051 +               printk("TIOCSCTTY failed, errno = %d\n", errno);
39052 +               return(-errno);
39053 +       }
39054 +
39055 +       if(tcsetpgrp(fd, pid) < 0){
39056 +               printk("tcsetpgrp failed, errno = %d\n", errno);
39057 +               return(-errno);
39058 +       }
39059 +
39060 +       return(0);
39061 +}
39062 +
39063 +/* FIXME: ensure namebuf in os_get_if_name is big enough */
39064 +int os_get_ifname(int fd, char* namebuf)
39065 +{
39066 +       if(ioctl(fd, SIOCGIFNAME, namebuf) < 0)
39067 +               return(-errno);
39068 +
39069 +       return(0);
39070 +}
39071 +
39072 +int os_set_slip(int fd)
39073 +{
39074 +       int disc, sencap;
39075 +
39076 +       disc = N_SLIP;
39077 +       if(ioctl(fd, TIOCSETD, &disc) < 0){
39078 +               printk("Failed to set slip line discipline - "
39079 +                      "errno = %d\n", errno);
39080 +               return(-errno);
39081 +       }
39082 +
39083 +       sencap = 0;
39084 +       if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){
39085 +               printk("Failed to set slip encapsulation - "
39086 +                      "errno = %d\n", errno);
39087 +               return(-errno);
39088 +       }
39089 +
39090 +       return(0);
39091 +}
39092 +
39093 +int os_set_owner(int fd, int pid)
39094 +{
39095 +       if(fcntl(fd, F_SETOWN, pid) < 0){
39096 +               int save_errno = errno;
39097 +
39098 +               if(fcntl(fd, F_GETOWN, 0) != pid)
39099 +                       return(-save_errno);
39100 +       }
39101 +
39102 +       return(0);
39103 +}
39104 +
39105 +/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */ 
39106 +int os_sigio_async(int master, int slave)
39107 +{
39108 +       int flags;
39109 +
39110 +       flags = fcntl(master, F_GETFL);
39111 +       if(flags < 0) {
39112 +               printk("fcntl F_GETFL failed, errno = %d\n", errno);
39113 +               return(-errno);
39114 +       }
39115 +
39116 +       if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
39117 +          (fcntl(master, F_SETOWN, os_getpid()) < 0)){
39118 +               printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", 
39119 +                      errno);
39120 +               return(-errno);
39121 +       }
39122 +
39123 +       if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){
39124 +               printk("fcntl F_SETFL failed, errno = %d\n", errno);
39125 +               return(-errno);
39126 +       }
39127 +
39128 +       return(0);
39129 +}
39130 +
39131 +int os_mode_fd(int fd, int mode)
39132 +{
39133 +       int err;
39134 +
39135 +       do {
39136 +               err = fchmod(fd, mode);
39137 +       } while((err < 0) && (errno==EINTR)) ;
39138 +
39139 +       if(err < 0)
39140 +               return(-errno);
39141 +
39142 +       return(0);
39143 +}
39144 +
39145 +int os_file_type(char *file)
39146 +{
39147 +       struct uml_stat buf;
39148 +       int err;
39149 +
39150 +       err = os_lstat_file(file, &buf);
39151 +       if(err < 0)
39152 +               return(err);
39153 +
39154 +       if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR);
39155 +       else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK);
39156 +       else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV);
39157 +       else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV);
39158 +       else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO);
39159 +       else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK);
39160 +       else return(OS_TYPE_FILE);
39161 +}
39162 +
39163 +int os_file_mode(char *file, struct openflags *mode_out)
39164 +{
39165 +       int err;
39166 +
39167 +       *mode_out = OPENFLAGS();
39168 +
39169 +       err = os_access(file, OS_ACC_W_OK);
39170 +       if((err < 0) && (err != -EACCES))
39171 +               return(err);
39172 +
39173 +       *mode_out = of_write(*mode_out);
39174 +
39175 +       err = os_access(file, OS_ACC_R_OK);
39176 +       if((err < 0) && (err != -EACCES))
39177 +               return(err);
39178 +
39179 +       *mode_out = of_read(*mode_out);
39180 +
39181 +       return(0);
39182 +}
39183 +
39184 +int os_open_file(char *file, struct openflags flags, int mode)
39185 +{
39186 +       int fd, f = 0;
39187 +
39188 +       if(flags.r && flags.w) f = O_RDWR;
39189 +       else if(flags.r) f = O_RDONLY;
39190 +       else if(flags.w) f = O_WRONLY;
39191 +       else f = 0;
39192 +
39193 +       if(flags.s) f |= O_SYNC;
39194 +       if(flags.c) f |= O_CREAT;
39195 +       if(flags.t) f |= O_TRUNC;
39196 +       if(flags.e) f |= O_EXCL;
39197 +       if(flags.d) f |= O_DIRECT;
39198 +
39199 +       fd = open64(file, f, mode);
39200 +       if(fd < 0)
39201 +               return(-errno);
39202 +
39203 +       if(flags.cl && fcntl(fd, F_SETFD, 1)){
39204 +               os_close_file(fd);
39205 +               return(-errno);
39206 +       }
39207 +
39208 +       return(fd);
39209 +}
39210 +
39211 +void *os_open_dir(char *path, int *err_out)
39212 +{
39213 +       void *dir;
39214 +
39215 +       dir = opendir(path);
39216 +       *err_out = -errno;
39217 +       return(dir);
39218 +}
39219 +
39220 +int os_seek_dir(void *stream, unsigned long long pos)
39221 +{
39222 +       seekdir(stream, pos);
39223 +       return(0);
39224 +}
39225 +
39226 +int os_read_dir(void *stream, unsigned long long *ino_out, char **name_out)
39227 +{
39228 +       struct dirent *ent;
39229 +
39230 +       errno = 0;
39231 +       ent = readdir(stream);
39232 +       if(ent == NULL){
39233 +               if(errno != 0)
39234 +                       return(-errno);
39235 +               *name_out = NULL;
39236 +               return(0);
39237 +       }
39238 +
39239 +       *ino_out = ent->d_ino;
39240 +       *name_out = ent->d_name;
39241 +       return(0);
39242 +}
39243 +
39244 +int os_tell_dir(void *stream)
39245 +{
39246 +       return(telldir(stream));
39247 +}
39248 +
39249 +int os_close_dir(void *stream)
39250 +{
39251 +       int err;
39252 +
39253 +       err = closedir(stream);
39254 +       if(err < 0)
39255 +               return(-errno);
39256 +       return(0);
39257 +}
39258 +
39259 +int os_remove_file(const char *file)
39260 +{
39261 +       int err;
39262 +
39263 +       err = unlink(file);
39264 +       if(err)
39265 +               return(-errno);
39266 +
39267 +       return(0);
39268 +}
39269 +
39270 +int os_move_file(const char *from, const char *to)
39271 +{
39272 +       int err;
39273 +
39274 +       err = rename(from, to);
39275 +       if(err)
39276 +               return(-errno);
39277 +
39278 +       return(0);
39279 +}
39280 +
39281 +int os_truncate_fd(int fd, unsigned long long len)
39282 +{
39283 +       int err;
39284 +
39285 +       err = ftruncate64(fd, len);
39286 +       if(err)
39287 +               return(-errno);
39288 +       return(0);
39289 +}
39290 +
39291 +int os_truncate_file(const char *file, unsigned long long len)
39292 +{
39293 +       int err;
39294 +
39295 +       err = truncate64(file, len);
39296 +       if(err)
39297 +               return(-errno);
39298 +       return(0);
39299 +}
39300 +
39301 +int os_connect_socket(char *name)
39302 +{
39303 +       struct sockaddr_un sock;
39304 +       int fd, err;
39305 +
39306 +       sock.sun_family = AF_UNIX;
39307 +       snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
39308 +
39309 +       fd = socket(AF_UNIX, SOCK_STREAM, 0);
39310 +       if(fd < 0)
39311 +               return(fd);
39312 +
39313 +       err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
39314 +       if(err)
39315 +               return(-errno);
39316 +
39317 +       return(fd);
39318 +}
39319 +
39320 +void os_close_file(int fd)
39321 +{
39322 +       close(fd);
39323 +}
39324 +
39325 +int os_seek_file(int fd, __u64 offset)
39326 +{
39327 +       __u64 actual;
39328 +
39329 +       actual = lseek64(fd, offset, SEEK_SET);
39330 +       if(actual != offset)
39331 +               return(-errno);
39332 +       return(0);
39333 +}
39334 +
39335 +static int fault_buffer(void *start, int len, 
39336 +                       int (*copy_proc)(void *addr, void *buf, int len))
39337 +{
39338 +       int page = getpagesize(), i;
39339 +       char c;
39340 +
39341 +       for(i = 0; i < len; i += page){
39342 +               if((*copy_proc)(start + i, &c, sizeof(c)))
39343 +                       return(-EFAULT);
39344 +       }
39345 +       if((len % page) != 0){
39346 +               if((*copy_proc)(start + len - 1, &c, sizeof(c)))
39347 +                       return(-EFAULT);
39348 +       }
39349 +       return(0);
39350 +}
39351 +
39352 +static int file_io(int fd, void *buf, int len,
39353 +                  int (*io_proc)(int fd, void *buf, int len),
39354 +                  int (*copy_user_proc)(void *addr, void *buf, int len))
39355 +{
39356 +       int n, err;
39357 +
39358 +       do {
39359 +               n = (*io_proc)(fd, buf, len);
39360 +               if((n < 0) && (errno == EFAULT)){
39361 +                       err = fault_buffer(buf, len, copy_user_proc);
39362 +                       if(err)
39363 +                               return(err);
39364 +                       n = (*io_proc)(fd, buf, len);
39365 +               }
39366 +       } while((n < 0) && (errno == EINTR));
39367 +
39368 +       if(n < 0)
39369 +               return(-errno);
39370 +       return(n);
39371 +}
39372 +
39373 +int os_read_file(int fd, void *buf, int len)
39374 +{
39375 +       return(file_io(fd, buf, len, (int (*)(int, void *, int)) read, 
39376 +                      copy_from_user_proc));
39377 +}
39378 +
39379 +int os_write_file(int fd, const void *buf, int len)
39380 +{
39381 +       return(file_io(fd, (void *) buf, len, 
39382 +                      (int (*)(int, void *, int)) write, copy_to_user_proc));
39383 +}
39384 +
39385 +int os_file_size(char *file, long long *size_out)
39386 +{
39387 +       struct uml_stat buf;
39388 +       int err;
39389 +
39390 +       err = os_stat_file(file, &buf);
39391 +       if(err < 0){
39392 +               printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
39393 +               return(err);
39394 +       }
39395 +
39396 +       if(S_ISBLK(buf.ust_mode)){
39397 +               int fd, blocks;
39398 +
39399 +               fd = os_open_file(file, of_read(OPENFLAGS()), 0);
39400 +               if(fd < 0){
39401 +                       printk("Couldn't open \"%s\", errno = %d\n", file, -fd);
39402 +                       return(fd);
39403 +               }
39404 +               if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
39405 +                       printk("Couldn't get the block size of \"%s\", "
39406 +                              "errno = %d\n", file, errno);
39407 +                       err = -errno;
39408 +                       os_close_file(fd);
39409 +                       return(err);
39410 +               }
39411 +               *size_out = ((long long) blocks) * 512;
39412 +               os_close_file(fd);
39413 +               return(0);
39414 +       }
39415 +       *size_out = buf.ust_size;
39416 +       return(0);
39417 +}
39418 +
39419 +int os_fd_size(int fd, long long *size_out)
39420 +{
39421 +       struct stat buf;
39422 +       int err;
39423 +
39424 +       err = fstat(fd, &buf);
39425 +       if(err)
39426 +               return(-errno);
39427 +
39428 +       *size_out = buf.st_size;
39429 +       return(0);
39430 +}
39431 +
39432 +int os_file_modtime(char *file, unsigned long *modtime)
39433 +{
39434 +       struct uml_stat buf;
39435 +       int err;
39436 +
39437 +       err = os_stat_file(file, &buf);
39438 +       if(err < 0){
39439 +               printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
39440 +               return(err);
39441 +       }
39442 +
39443 +       *modtime = buf.ust_mtime;
39444 +       return(0);
39445 +}
39446 +
39447 +int os_get_exec_close(int fd, int* close_on_exec)
39448 +{
39449 +       int ret;
39450 +
39451 +       do {
39452 +               ret = fcntl(fd, F_GETFD);
39453 +       } while((ret < 0) && (errno == EINTR)) ;
39454 +
39455 +       if(ret < 0)
39456 +               return(-errno);
39457 +
39458 +       *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0;
39459 +       return(ret);
39460 +}
39461 +
39462 +int os_set_exec_close(int fd, int close_on_exec)
39463 +{
39464 +       int flag, err;
39465 +
39466 +       if(close_on_exec) flag = FD_CLOEXEC;
39467 +       else flag = 0;
39468 +
39469 +       do {
39470 +               err = fcntl(fd, F_SETFD, flag);
39471 +       } while((err < 0) && (errno == EINTR)) ;
39472 +
39473 +       if(err < 0)
39474 +               return(-errno);
39475 +       return(err);
39476 +}
39477 +
39478 +int os_pipe(int *fds, int stream, int close_on_exec)
39479 +{
39480 +       int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
39481 +
39482 +       err = socketpair(AF_UNIX, type, 0, fds);
39483 +       if(err < 0) 
39484 +               return(-errno);
39485 +
39486 +       if(!close_on_exec)
39487 +               return(0);
39488 +
39489 +       err = os_set_exec_close(fds[0], 1);
39490 +       if(err < 0)
39491 +               goto error;
39492 +
39493 +       err = os_set_exec_close(fds[1], 1);
39494 +       if(err < 0)
39495 +               goto error;
39496 +
39497 +       return(0);
39498 +
39499 + error:
39500 +       printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
39501 +       os_close_file(fds[1]);
39502 +       os_close_file(fds[0]);
39503 +       return(err);
39504 +}
39505 +
39506 +int os_set_fd_async(int fd, int owner)
39507 +{
39508 +       /* XXX This should do F_GETFL first */
39509 +       if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){
39510 +               printk("os_set_fd_async : failed to set O_ASYNC and "
39511 +                      "O_NONBLOCK on fd # %d, errno = %d\n", fd, errno);
39512 +               return(-errno);
39513 +       }
39514 +#ifdef notdef
39515 +       if(fcntl(fd, F_SETFD, 1) < 0){
39516 +               printk("os_set_fd_async : Setting FD_CLOEXEC failed, "
39517 +                      "errno = %d\n", errno);
39518 +       }
39519 +#endif
39520 +
39521 +       if((fcntl(fd, F_SETSIG, SIGIO) < 0) ||
39522 +          (fcntl(fd, F_SETOWN, owner) < 0)){
39523 +               printk("os_set_fd_async : Failed to fcntl F_SETOWN "
39524 +                      "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, 
39525 +                      owner, errno);
39526 +               return(-errno);
39527 +       }
39528 +
39529 +       return(0);
39530 +}
39531 +
39532 +int os_clear_fd_async(int fd)
39533 +{
39534 +       int flags = fcntl(fd, F_GETFL);
39535 +
39536 +       flags &= ~(O_ASYNC | O_NONBLOCK);
39537 +       if(fcntl(fd, F_SETFL, flags) < 0)
39538 +               return(-errno);
39539 +       return(0);
39540 +}
39541 +
39542 +int os_set_fd_block(int fd, int blocking)
39543 +{
39544 +       int flags;
39545 +
39546 +       flags = fcntl(fd, F_GETFL);
39547 +
39548 +       if(blocking) flags &= ~O_NONBLOCK;
39549 +       else flags |= O_NONBLOCK;
39550 +
39551 +       if(fcntl(fd, F_SETFL, flags) < 0){
39552 +               printk("Failed to change blocking on fd # %d, errno = %d\n",
39553 +                      fd, errno);
39554 +               return(-errno);
39555 +       }
39556 +       return(0);
39557 +}
39558 +
39559 +int os_accept_connection(int fd)
39560 +{
39561 +       int new;
39562 +
39563 +       new = accept(fd, NULL, 0);
39564 +       if(new < 0) 
39565 +               return(-errno);
39566 +       return(new);
39567 +}
39568 +
39569 +#ifndef SHUT_RD
39570 +#define SHUT_RD 0
39571 +#endif
39572 +
39573 +#ifndef SHUT_WR
39574 +#define SHUT_WR 1
39575 +#endif
39576 +
39577 +#ifndef SHUT_RDWR
39578 +#define SHUT_RDWR 2
39579 +#endif
39580 +
39581 +int os_shutdown_socket(int fd, int r, int w)
39582 +{
39583 +       int what, err;
39584 +
39585 +       if(r && w) what = SHUT_RDWR;
39586 +       else if(r) what = SHUT_RD;
39587 +       else if(w) what = SHUT_WR;
39588 +       else {
39589 +               printk("os_shutdown_socket : neither r or w was set\n");
39590 +               return(-EINVAL);
39591 +       }
39592 +       err = shutdown(fd, what);
39593 +       if(err < 0)
39594 +               return(-errno);
39595 +       return(0);
39596 +}
39597 +
39598 +int os_rcv_fd(int fd, int *helper_pid_out)
39599 +{
39600 +       int new, n;
39601 +       char buf[CMSG_SPACE(sizeof(new))];
39602 +       struct msghdr msg;
39603 +       struct cmsghdr *cmsg;
39604 +       struct iovec iov;
39605 +
39606 +       msg.msg_name = NULL;
39607 +       msg.msg_namelen = 0;
39608 +       iov = ((struct iovec) { .iov_base  = helper_pid_out,
39609 +                               .iov_len   = sizeof(*helper_pid_out) });
39610 +       msg.msg_iov = &iov;
39611 +       msg.msg_iovlen = 1;
39612 +       msg.msg_control = buf;
39613 +       msg.msg_controllen = sizeof(buf);
39614 +       msg.msg_flags = 0;
39615 +
39616 +       n = recvmsg(fd, &msg, 0);
39617 +       if(n < 0)
39618 +               return(-errno);
39619 +
39620 +       else if(n != sizeof(iov.iov_len))
39621 +               *helper_pid_out = -1;
39622 +
39623 +       cmsg = CMSG_FIRSTHDR(&msg);
39624 +       if(cmsg == NULL){
39625 +               printk("rcv_fd didn't receive anything, error = %d\n", errno);
39626 +               return(-1);
39627 +       }
39628 +       if((cmsg->cmsg_level != SOL_SOCKET) || 
39629 +          (cmsg->cmsg_type != SCM_RIGHTS)){
39630 +               printk("rcv_fd didn't receive a descriptor\n");
39631 +               return(-1);
39632 +       }
39633 +
39634 +       new = ((int *) CMSG_DATA(cmsg))[0];
39635 +       return(new);
39636 +}
39637 +
39638 +int os_create_unix_socket(char *file, int len, int close_on_exec)
39639 +{
39640 +       struct sockaddr_un addr;
39641 +       int sock, err;
39642 +
39643 +       sock = socket(PF_UNIX, SOCK_DGRAM, 0);
39644 +       if (sock < 0){
39645 +               printk("create_unix_socket - socket failed, errno = %d\n",
39646 +                      errno);
39647 +               return(-errno);
39648 +       }
39649 +
39650 +       if(close_on_exec) {
39651 +               err = os_set_exec_close(sock, 1);
39652 +               if(err < 0)
39653 +                       printk("create_unix_socket : close_on_exec failed, "
39654 +                      "err = %d", -err);
39655 +       }
39656 +
39657 +       addr.sun_family = AF_UNIX;
39658 +
39659 +       /* XXX Be more careful about overflow */
39660 +       snprintf(addr.sun_path, len, "%s", file);
39661 +
39662 +       err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
39663 +       if (err < 0){
39664 +               printk("create_listening_socket at '%s' - bind failed, "
39665 +                      "errno = %d\n", file, errno);
39666 +               return(-errno);
39667 +       }
39668 +
39669 +       return(sock);
39670 +}
39671 +
39672 +int os_make_symlink(const char *to, const char *from)
39673 +{
39674 +       int err;
39675 +
39676 +       err = symlink(to, from);
39677 +       if(err)
39678 +               return(-errno);
39679 +
39680 +       return(0);
39681 +}
39682 +
39683 +int os_read_symlink(const char *file, char *buf, int size)
39684 +{
39685 +       int err;
39686 +
39687 +       err = readlink(file, buf, size);
39688 +       if(err < 0)
39689 +               return(-errno);
39690 +
39691 +       return(err);
39692 +}
39693 +
39694 +int os_link_file(const char *to, const char *from)
39695 +{
39696 +       int err;
39697 +
39698 +       err = link(to, from);
39699 +       if(err)
39700 +               return(-errno);
39701 +
39702 +       return(0);
39703 +}
39704 +
39705 +int os_make_dir(const char *dir, int mode)
39706 +{
39707 +       int err;
39708 +
39709 +       err = mkdir(dir, mode);
39710 +       if(err)
39711 +               return(-errno);
39712 +
39713 +       return(0);
39714 +}
39715 +
39716 +int os_make_dev(const char *name, int mode, int major, int minor)
39717 +{
39718 +       int err;
39719 +
39720 +       err = mknod(name, mode, MKDEV(major, minor));
39721 +       if(err)
39722 +               return(-errno);
39723 +
39724 +       return(0);
39725 +}
39726 +
39727 +int os_remove_dir(const char *dir)
39728 +{
39729 +       int err;
39730 +
39731 +       err = rmdir(dir);
39732 +       if(err)
39733 +               return(-errno);
39734 +
39735 +       return(0);
39736 +}
39737 +
39738 +void os_flush_stdout(void)
39739 +{
39740 +       fflush(stdout);
39741 +}
39742 +
39743 +int os_lock_file(int fd, int excl)
39744 +{
39745 +       int type = excl ? F_WRLCK : F_RDLCK;
39746 +       struct flock lock = ((struct flock) { .l_type   = type,
39747 +                                             .l_whence = SEEK_SET,
39748 +                                             .l_start  = 0,
39749 +                                             .l_len    = 0 } );
39750 +       int err, save;
39751 +
39752 +       err = fcntl(fd, F_SETLK, &lock);
39753 +       if(!err)
39754 +               goto out;
39755 +
39756 +       save = -errno;
39757 +       err = fcntl(fd, F_GETLK, &lock);
39758 +       if(err){
39759 +               err = -errno;
39760 +               goto out;
39761 +       }
39762 +
39763 +       printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
39764 +       err = save;
39765 + out:
39766 +       return(err);
39767 +}
39768 +
39769 +int os_stat_filesystem(char *path, long *bsize_out, long long *blocks_out, 
39770 +                      long long *bfree_out, long long *bavail_out, 
39771 +                      long long *files_out, long long *ffree_out, 
39772 +                      void *fsid_out, int fsid_size, long *namelen_out, 
39773 +                      long *spare_out)
39774 +{
39775 +       struct statfs64 buf;
39776 +       int err;
39777 +
39778 +       err = statfs64(path, &buf);
39779 +       if(err < 0)
39780 +               return(-errno);
39781 +
39782 +       *bsize_out = buf.f_bsize;
39783 +       *blocks_out = buf.f_blocks;
39784 +       *bfree_out = buf.f_bfree;
39785 +       *bavail_out = buf.f_bavail;
39786 +       *files_out = buf.f_files;
39787 +       *ffree_out = buf.f_ffree;
39788 +       memcpy(fsid_out, &buf.f_fsid, 
39789 +              sizeof(buf.f_fsid) > fsid_size ? fsid_size : 
39790 +              sizeof(buf.f_fsid));
39791 +       *namelen_out = buf.f_namelen;
39792 +       spare_out[0] = buf.f_spare[0];
39793 +       spare_out[1] = buf.f_spare[1];
39794 +       spare_out[2] = buf.f_spare[2];
39795 +       spare_out[3] = buf.f_spare[3];
39796 +       spare_out[4] = buf.f_spare[4];
39797 +       spare_out[5] = buf.f_spare[5];
39798 +       return(0);
39799 +}
39800 +
39801 +/*
39802 + * Overrides for Emacs so that we follow Linus's tabbing style.
39803 + * Emacs will notice this stuff at the end of the file and automatically
39804 + * adjust the settings for this buffer only.  This must remain at the end
39805 + * of the file.
39806 + * ---------------------------------------------------------------------------
39807 + * Local variables:
39808 + * c-file-style: "linux"
39809 + * End:
39810 + */
39811 Index: linux-2.4.29/arch/um/os-Linux/include/file.h
39812 ===================================================================
39813 --- linux-2.4.29.orig/arch/um/os-Linux/include/file.h   1970-01-01 03:00:00.000000000 +0300
39814 +++ linux-2.4.29/arch/um/os-Linux/include/file.h        2005-05-03 22:28:14.575394416 +0300
39815 @@ -0,0 +1,22 @@
39816 +/* 
39817 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39818 + * Licensed under the GPL
39819 + */
39820 +
39821 +#ifndef __OS_FILE_H__
39822 +#define __OS_FILE_H__
39823 +
39824 +#define DEV_NULL "/dev/null"
39825 +
39826 +#endif
39827 +
39828 +/*
39829 + * Overrides for Emacs so that we follow Linus's tabbing style.
39830 + * Emacs will notice this stuff at the end of the file and automatically
39831 + * adjust the settings for this buffer only.  This must remain at the end
39832 + * of the file.
39833 + * ---------------------------------------------------------------------------
39834 + * Local variables:
39835 + * c-file-style: "linux"
39836 + * End:
39837 + */
39838 Index: linux-2.4.29/arch/um/os-Linux/Makefile
39839 ===================================================================
39840 --- linux-2.4.29.orig/arch/um/os-Linux/Makefile 1970-01-01 03:00:00.000000000 +0300
39841 +++ linux-2.4.29/arch/um/os-Linux/Makefile      2005-05-03 22:28:14.575394416 +0300
39842 @@ -0,0 +1,23 @@
39843 +# 
39844 +# Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com)
39845 +# Licensed under the GPL
39846 +#
39847 +
39848 +O_TARGET = built-in.o
39849 +
39850 +obj-y = aio.o file.o process.o time.o tty.o
39851 +
39852 +HAVE_AIO_ABI = $(shell [ -e /usr/include/linux/aio_abi.h ] && \
39853 +       echo -DHAVE_AIO_ABI)
39854 +HAVE_AIO_LIBC = $(shell objdump -T /lib/libc-*.so | grep io_submit && \
39855 +       echo -DHAVE_AIO_LIBC)
39856 +CFLAGS_aio.o = $(HAVE_AIO_ABI) $(HAVE_AIO_LIBC)
39857 +
39858 +include $(TOPDIR)/Rules.make
39859 +
39860 +$(obj-y) : %.o: %.c
39861 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
39862 +
39863 +clean :
39864 +
39865 +archmrproper:
39866 Index: linux-2.4.29/arch/um/os-Linux/process.c
39867 ===================================================================
39868 --- linux-2.4.29.orig/arch/um/os-Linux/process.c        1970-01-01 03:00:00.000000000 +0300
39869 +++ linux-2.4.29/arch/um/os-Linux/process.c     2005-05-03 22:28:14.577394112 +0300
39870 @@ -0,0 +1,151 @@
39871 +/* 
39872 + * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
39873 + * Licensed under the GPL
39874 + */
39875 +
39876 +#include <unistd.h>
39877 +#include <stdio.h>
39878 +#include <errno.h>
39879 +#include <signal.h>
39880 +#include <sys/mman.h>
39881 +#include <sys/wait.h>
39882 +#include "os.h"
39883 +#include "user.h"
39884 +#include "user_util.h"
39885 +
39886 +#define ARBITRARY_ADDR -1
39887 +#define FAILURE_PID    -1
39888 +
39889 +#define STAT_PATH_LEN sizeof("/proc/#######/stat\0")
39890 +#define COMM_SCANF "%*[^)])"
39891 +
39892 +unsigned long os_process_pc(int pid)
39893 +{
39894 +       char proc_stat[STAT_PATH_LEN], buf[256];
39895 +       unsigned long pc;
39896 +       int fd, err;
39897 +
39898 +       sprintf(proc_stat, "/proc/%d/stat", pid);
39899 +       fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
39900 +       if(fd < 0){
39901 +               printk("os_process_pc - couldn't open '%s', err = %d\n", 
39902 +                      proc_stat, -fd);
39903 +               return(ARBITRARY_ADDR);
39904 +       }
39905 +       err = os_read_file(fd, buf, sizeof(buf));
39906 +       if(err < 0){
39907 +               printk("os_process_pc - couldn't read '%s', err = %d\n", 
39908 +                      proc_stat, -err);
39909 +               os_close_file(fd);
39910 +               return(ARBITRARY_ADDR);
39911 +       }
39912 +       os_close_file(fd);
39913 +       pc = ARBITRARY_ADDR;
39914 +       if(sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d "
39915 +                 "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
39916 +                 "%*d %*d %*d %*d %*d %lu", &pc) != 1){
39917 +               printk("os_process_pc - couldn't find pc in '%s'\n", buf);
39918 +       }
39919 +       return(pc);
39920 +}
39921 +
39922 +int os_process_parent(int pid)
39923 +{
39924 +       char stat[STAT_PATH_LEN];
39925 +       char data[256];
39926 +       int parent, n, fd;
39927 +
39928 +       if(pid == -1) return(-1);
39929 +
39930 +       snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
39931 +       fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
39932 +       if(fd < 0){
39933 +               printk("Couldn't open '%s', err = %d\n", stat, -fd);
39934 +               return(FAILURE_PID);
39935 +       }
39936 +
39937 +       n = os_read_file(fd, data, sizeof(data));
39938 +       os_close_file(fd);
39939 +
39940 +       if(n < 0){
39941 +               printk("Couldn't read '%s', err = %d\n", stat, -n);
39942 +               return(FAILURE_PID);
39943 +       }
39944 +
39945 +       parent = FAILURE_PID;
39946 +       n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent);
39947 +       if(n != 1) 
39948 +               printk("Failed to scan '%s'\n", data);
39949 +
39950 +       return(parent);
39951 +}
39952 +
39953 +void os_stop_process(int pid)
39954 +{
39955 +       kill(pid, SIGSTOP);
39956 +}
39957 +
39958 +void os_kill_process(int pid, int reap_child)
39959 +{
39960 +       kill(pid, SIGKILL);
39961 +       if(reap_child)
39962 +               CATCH_EINTR(waitpid(pid, NULL, 0));
39963 +               
39964 +}
39965 +
39966 +void os_usr1_process(int pid)
39967 +{
39968 +       kill(pid, SIGUSR1);
39969 +}
39970 +
39971 +int os_getpid(void)
39972 +{
39973 +       return(getpid());
39974 +}
39975 +
39976 +int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
39977 +                 int r, int w, int x)
39978 +{
39979 +       void *loc;
39980 +       int prot;
39981 +
39982 +       prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
39983 +               (x ? PROT_EXEC : 0);
39984 +
39985 +       loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 
39986 +                    fd, off);
39987 +       if(loc == MAP_FAILED)
39988 +               return(-errno);
39989 +       return(0);
39990 +}
39991 +
39992 +int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
39993 +{
39994 +        int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
39995 +                   (x ? PROT_EXEC : 0));
39996 +
39997 +        if(mprotect(addr, len, prot) < 0)
39998 +               return(-errno);
39999 +        return(0);
40000 +}
40001 +
40002 +int os_unmap_memory(void *addr, int len)
40003 +{
40004 +        int err;
40005 +
40006 +        err = munmap(addr, len);
40007 +       if(err < 0)
40008 +               return(-errno);
40009 +        return(0);
40010 +}
40011 +
40012 +/*
40013 + * Overrides for Emacs so that we follow Linus's tabbing style.
40014 + * Emacs will notice this stuff at the end of the file and automatically
40015 + * adjust the settings for this buffer only.  This must remain at the end
40016 + * of the file.
40017 + * ---------------------------------------------------------------------------
40018 + * Local variables:
40019 + * c-file-style: "linux"
40020 + * End:
40021 + */
40022 Index: linux-2.4.29/arch/um/os-Linux/time.c
40023 ===================================================================
40024 --- linux-2.4.29.orig/arch/um/os-Linux/time.c   1970-01-01 03:00:00.000000000 +0300
40025 +++ linux-2.4.29/arch/um/os-Linux/time.c        2005-05-03 22:28:14.578393960 +0300
40026 @@ -0,0 +1,21 @@
40027 +#include <stdlib.h>
40028 +#include <sys/time.h>
40029 +
40030 +unsigned long long os_usecs(void)
40031 +{
40032 +       struct timeval tv;
40033 +
40034 +       gettimeofday(&tv, NULL);
40035 +       return((unsigned long long) tv.tv_sec * 1000000 + tv.tv_usec);
40036 +}
40037 +
40038 +/*
40039 + * Overrides for Emacs so that we follow Linus's tabbing style.
40040 + * Emacs will notice this stuff at the end of the file and automatically
40041 + * adjust the settings for this buffer only.  This must remain at the end
40042 + * of the file.
40043 + * ---------------------------------------------------------------------------
40044 + * Local variables:
40045 + * c-file-style: "linux"
40046 + * End:
40047 + */
40048 Index: linux-2.4.29/arch/um/os-Linux/tty.c
40049 ===================================================================
40050 --- linux-2.4.29.orig/arch/um/os-Linux/tty.c    1970-01-01 03:00:00.000000000 +0300
40051 +++ linux-2.4.29/arch/um/os-Linux/tty.c 2005-05-03 22:28:14.579393808 +0300
40052 @@ -0,0 +1,61 @@
40053 +/* 
40054 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40055 + * Licensed under the GPL
40056 + */
40057 +
40058 +#include <stdlib.h>
40059 +#include <errno.h>
40060 +#include "os.h"
40061 +#include "user.h"
40062 +#include "kern_util.h"
40063 +
40064 +struct grantpt_info {
40065 +       int fd;
40066 +       int res;
40067 +       int err;
40068 +};
40069 +
40070 +static void grantpt_cb(void *arg)
40071 +{
40072 +       struct grantpt_info *info = arg;
40073 +
40074 +       info->res = grantpt(info->fd);
40075 +       info->err = errno;
40076 +}
40077 +
40078 +int get_pty(void)
40079 +{
40080 +       struct grantpt_info info;
40081 +       int fd;
40082 +
40083 +       fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0);
40084 +       if(fd < 0){
40085 +               printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd);
40086 +               return(fd);
40087 +       }
40088 +
40089 +       info.fd = fd;
40090 +       initial_thread_cb(grantpt_cb, &info);
40091 +
40092 +       if(info.res < 0){
40093 +               printk("get_pty : Couldn't grant pty - errno = %d\n", 
40094 +                      -info.err);
40095 +               return(-1);
40096 +       }
40097 +       if(unlockpt(fd) < 0){
40098 +               printk("get_pty : Couldn't unlock pty - errno = %d\n", errno);
40099 +               return(-1);
40100 +       }
40101 +       return(fd);
40102 +}
40103 +
40104 +/*
40105 + * Overrides for Emacs so that we follow Linus's tabbing style.
40106 + * Emacs will notice this stuff at the end of the file and automatically
40107 + * adjust the settings for this buffer only.  This must remain at the end
40108 + * of the file.
40109 + * ---------------------------------------------------------------------------
40110 + * Local variables:
40111 + * c-file-style: "linux"
40112 + * End:
40113 + */
40114 Index: linux-2.4.29/arch/um/sys-i386/bugs.c
40115 ===================================================================
40116 --- linux-2.4.29.orig/arch/um/sys-i386/bugs.c   1970-01-01 03:00:00.000000000 +0300
40117 +++ linux-2.4.29/arch/um/sys-i386/bugs.c        2005-05-03 22:28:14.580393656 +0300
40118 @@ -0,0 +1,222 @@
40119 +/* 
40120 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40121 + * Licensed under the GPL
40122 + */
40123 +
40124 +#include <unistd.h>
40125 +#include <errno.h>
40126 +#include <string.h>
40127 +#include <sys/signal.h>
40128 +#include <asm/ldt.h>
40129 +#include "kern_util.h"
40130 +#include "user.h"
40131 +#include "sysdep/ptrace.h"
40132 +#include "task.h"
40133 +#include "os.h"
40134 +
40135 +#define MAXTOKEN 64
40136 +
40137 +/* Set during early boot */
40138 +int host_has_cmov = 1;
40139 +int host_has_xmm = 0;
40140 +
40141 +static char token(int fd, char *buf, int len, char stop)
40142 +{
40143 +       int n;
40144 +       char *ptr, *end, c;
40145 +
40146 +       ptr = buf;
40147 +       end = &buf[len];
40148 +       do {
40149 +               n = os_read_file(fd, ptr, sizeof(*ptr));
40150 +               c = *ptr++;
40151 +               if(n != sizeof(*ptr)){
40152 +                       if(n == 0) return(0);
40153 +                       printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
40154 +                       if(n < 0) 
40155 +                               return(n);
40156 +                       else 
40157 +                               return(-EIO);
40158 +               }
40159 +       } while((c != '\n') && (c != stop) && (ptr < end));
40160 +
40161 +       if(ptr == end){
40162 +               printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
40163 +               return(-1);
40164 +       }
40165 +       *(ptr - 1) = '\0';
40166 +       return(c);
40167 +}
40168 +
40169 +static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
40170 +{
40171 +       int n;
40172 +       char c;
40173 +
40174 +       scratch[len - 1] = '\0';
40175 +       while(1){
40176 +               c = token(fd, scratch, len - 1, ':');
40177 +               if(c <= 0)
40178 +                       return(0);
40179 +               else if(c != ':'){
40180 +                       printk("Failed to find ':' in /proc/cpuinfo\n");
40181 +                       return(0);
40182 +               }
40183 +
40184 +               if(!strncmp(scratch, key, strlen(key))) 
40185 +                       return(1);
40186 +
40187 +               do {
40188 +                       n = os_read_file(fd, &c, sizeof(c));
40189 +                       if(n != sizeof(c)){
40190 +                               printk("Failed to find newline in "
40191 +                                      "/proc/cpuinfo, err = %d\n", -n);
40192 +                               return(0);
40193 +                       }
40194 +               } while(c != '\n');
40195 +       }
40196 +       return(0);
40197 +}
40198 +
40199 +int cpu_feature(char *what, char *buf, int len)
40200 +{
40201 +       int fd, ret = 0;
40202 +
40203 +       fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
40204 +       if(fd < 0){
40205 +               printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
40206 +               return(0);
40207 +       }
40208 +
40209 +       if(!find_cpuinfo_line(fd, what, buf, len)){
40210 +               printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
40211 +               goto out_close;
40212 +       }
40213 +
40214 +       token(fd, buf, len, '\n');
40215 +       ret = 1;
40216 +
40217 + out_close:
40218 +       os_close_file(fd);
40219 +       return(ret);
40220 +}
40221 +
40222 +static int check_cpu_flag(char *feature, int *have_it)
40223 +{
40224 +       char buf[MAXTOKEN], c;
40225 +       int fd, len = sizeof(buf)/sizeof(buf[0]);
40226 +
40227 +       printk("Checking for host processor %s support...", feature);
40228 +       fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
40229 +       if(fd < 0){
40230 +               printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
40231 +               return(0);
40232 +       }
40233 +
40234 +       *have_it = 0;
40235 +       if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0])))
40236 +               goto out;
40237 +
40238 +       c = token(fd, buf, len - 1, ' ');
40239 +       if(c < 0) goto out;
40240 +       else if(c != ' '){
40241 +               printk("Failed to find ' ' in /proc/cpuinfo\n");
40242 +               goto out;
40243 +       }
40244 +
40245 +       while(1){
40246 +               c = token(fd, buf, len - 1, ' ');
40247 +               if(c < 0) goto out;
40248 +               else if(c == '\n') break;
40249 +
40250 +               if(!strcmp(buf, feature)){
40251 +                       *have_it = 1;
40252 +                       goto out;
40253 +               }
40254 +       }
40255 + out:
40256 +       if(*have_it == 0) printk("No\n");
40257 +       else if(*have_it == 1) printk("Yes\n");
40258 +       os_close_file(fd);
40259 +       return(1);
40260 +}
40261 +
40262 +#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems
40263 +       * for some people.
40264 +       */
40265 +static void disable_lcall(void)
40266 +{
40267 +       struct modify_ldt_ldt_s ldt;
40268 +       int err;
40269 +
40270 +       bzero(&ldt, sizeof(ldt));
40271 +       ldt.entry_number = 7;
40272 +       ldt.base_addr = 0;
40273 +       ldt.limit = 0;
40274 +       err = modify_ldt(1, &ldt, sizeof(ldt));
40275 +       if(err)
40276 +               printk("Failed to disable lcall7 - errno = %d\n", errno);
40277 +}
40278 +#endif
40279 +
40280 +void arch_init_thread(void)
40281 +{
40282 +#if 0
40283 +       disable_lcall();
40284 +#endif
40285 +}
40286 +
40287 +void arch_check_bugs(void)
40288 +{
40289 +       int have_it;
40290 +
40291 +       if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){
40292 +               printk("/proc/cpuinfo not available - skipping CPU capability "
40293 +                      "checks\n");
40294 +               return;
40295 +       }
40296 +       if(check_cpu_flag("cmov", &have_it)) 
40297 +               host_has_cmov = have_it;
40298 +       if(check_cpu_flag("xmm", &have_it)) 
40299 +               host_has_xmm = have_it;
40300 +}
40301 +
40302 +int arch_handle_signal(int sig, union uml_pt_regs *regs)
40303 +{
40304 +       unsigned char tmp[2];
40305 +
40306 +       /* This is testing for a cmov (0x0f 0x4x) instruction causing a
40307 +        * SIGILL in init.
40308 +        */
40309 +       if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0);
40310 +
40311 +       if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2))
40312 +               panic("SIGILL in init, could not read instructions!\n");
40313 +       if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
40314 +               return(0);
40315 +
40316 +       if(host_has_cmov == 0)
40317 +               panic("SIGILL caused by cmov, which this processor doesn't "
40318 +                     "implement, boot a filesystem compiled for older "
40319 +                     "processors");
40320 +       else if(host_has_cmov == 1)
40321 +               panic("SIGILL caused by cmov, which this processor claims to "
40322 +                     "implement");
40323 +       else if(host_has_cmov == -1)
40324 +               panic("SIGILL caused by cmov, couldn't tell if this processor "
40325 +                     "implements it, boot a filesystem compiled for older "
40326 +                     "processors");
40327 +       else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
40328 +       return(0);
40329 +}
40330 +
40331 +/*
40332 + * Overrides for Emacs so that we follow Linus's tabbing style.
40333 + * Emacs will notice this stuff at the end of the file and automatically
40334 + * adjust the settings for this buffer only.  This must remain at the end
40335 + * of the file.
40336 + * ---------------------------------------------------------------------------
40337 + * Local variables:
40338 + * c-file-style: "linux"
40339 + * End:
40340 + */
40341 Index: linux-2.4.29/arch/um/sys-i386/checksum.S
40342 ===================================================================
40343 --- linux-2.4.29.orig/arch/um/sys-i386/checksum.S       1970-01-01 03:00:00.000000000 +0300
40344 +++ linux-2.4.29/arch/um/sys-i386/checksum.S    2005-05-03 22:28:14.582393352 +0300
40345 @@ -0,0 +1,460 @@
40346 +/*
40347 + * INET                An implementation of the TCP/IP protocol suite for the LINUX
40348 + *             operating system.  INET is implemented using the  BSD Socket
40349 + *             interface as the means of communication with the user level.
40350 + *
40351 + *             IP/TCP/UDP checksumming routines
40352 + *
40353 + * Authors:    Jorge Cwik, <jorge@laser.satlink.net>
40354 + *             Arnt Gulbrandsen, <agulbra@nvg.unit.no>
40355 + *             Tom May, <ftom@netcom.com>
40356 + *              Pentium Pro/II routines:
40357 + *              Alexander Kjeldaas <astor@guardian.no>
40358 + *              Finn Arne Gangstad <finnag@guardian.no>
40359 + *             Lots of code moved from tcp.c and ip.c; see those files
40360 + *             for more names.
40361 + *
40362 + * Changes:     Ingo Molnar, converted csum_partial_copy() to 2.1 exception
40363 + *                          handling.
40364 + *             Andi Kleen,  add zeroing on error
40365 + *                   converted to pure assembler
40366 + *
40367 + *             This program is free software; you can redistribute it and/or
40368 + *             modify it under the terms of the GNU General Public License
40369 + *             as published by the Free Software Foundation; either version
40370 + *             2 of the License, or (at your option) any later version.
40371 + */
40372 +
40373 +#include <linux/config.h>
40374 +#include <asm/errno.h>
40375 +                               
40376 +/*
40377 + * computes a partial checksum, e.g. for TCP/UDP fragments
40378 + */
40379 +
40380 +/*     
40381 +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
40382 + */
40383 +               
40384 +.text
40385 +.align 4
40386 +.globl arch_csum_partial                                                               
40387 +               
40388 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
40389 +
40390 +         /*            
40391 +          * Experiments with Ethernet and SLIP connections show that buff
40392 +          * is aligned on either a 2-byte or 4-byte boundary.  We get at
40393 +          * least a twofold speedup on 486 and Pentium if it is 4-byte aligned.
40394 +          * Fortunately, it is easy to convert 2-byte alignment to 4-byte
40395 +          * alignment for the unrolled loop.
40396 +          */           
40397 +arch_csum_partial:     
40398 +       pushl %esi
40399 +       pushl %ebx
40400 +       movl 20(%esp),%eax      # Function arg: unsigned int sum
40401 +       movl 16(%esp),%ecx      # Function arg: int len
40402 +       movl 12(%esp),%esi      # Function arg: unsigned char *buff
40403 +       testl $2, %esi          # Check alignment.
40404 +       jz 2f                   # Jump if alignment is ok.
40405 +       subl $2, %ecx           # Alignment uses up two bytes.
40406 +       jae 1f                  # Jump if we had at least two bytes.
40407 +       addl $2, %ecx           # ecx was < 2.  Deal with it.
40408 +       jmp 4f
40409 +1:     movw (%esi), %bx
40410 +       addl $2, %esi
40411 +       addw %bx, %ax
40412 +       adcl $0, %eax
40413 +2:
40414 +       movl %ecx, %edx
40415 +       shrl $5, %ecx
40416 +       jz 2f
40417 +       testl %esi, %esi
40418 +1:     movl (%esi), %ebx
40419 +       adcl %ebx, %eax
40420 +       movl 4(%esi), %ebx
40421 +       adcl %ebx, %eax
40422 +       movl 8(%esi), %ebx
40423 +       adcl %ebx, %eax
40424 +       movl 12(%esi), %ebx
40425 +       adcl %ebx, %eax
40426 +       movl 16(%esi), %ebx
40427 +       adcl %ebx, %eax
40428 +       movl 20(%esi), %ebx
40429 +       adcl %ebx, %eax
40430 +       movl 24(%esi), %ebx
40431 +       adcl %ebx, %eax
40432 +       movl 28(%esi), %ebx
40433 +       adcl %ebx, %eax
40434 +       lea 32(%esi), %esi
40435 +       dec %ecx
40436 +       jne 1b
40437 +       adcl $0, %eax
40438 +2:     movl %edx, %ecx
40439 +       andl $0x1c, %edx
40440 +       je 4f
40441 +       shrl $2, %edx           # This clears CF
40442 +3:     adcl (%esi), %eax
40443 +       lea 4(%esi), %esi
40444 +       dec %edx
40445 +       jne 3b
40446 +       adcl $0, %eax
40447 +4:     andl $3, %ecx
40448 +       jz 7f
40449 +       cmpl $2, %ecx
40450 +       jb 5f
40451 +       movw (%esi),%cx
40452 +       leal 2(%esi),%esi
40453 +       je 6f
40454 +       shll $16,%ecx
40455 +5:     movb (%esi),%cl
40456 +6:     addl %ecx,%eax
40457 +       adcl $0, %eax 
40458 +7:     
40459 +       popl %ebx
40460 +       popl %esi
40461 +       ret
40462 +
40463 +#else
40464 +
40465 +/* Version for PentiumII/PPro */
40466 +
40467 +arch_csum_partial:
40468 +       pushl %esi
40469 +       pushl %ebx
40470 +       movl 20(%esp),%eax      # Function arg: unsigned int sum
40471 +       movl 16(%esp),%ecx      # Function arg: int len
40472 +       movl 12(%esp),%esi      # Function arg: const unsigned char *buf
40473 +
40474 +       testl $2, %esi         
40475 +       jnz 30f                 
40476 +10:
40477 +       movl %ecx, %edx
40478 +       movl %ecx, %ebx
40479 +       andl $0x7c, %ebx
40480 +       shrl $7, %ecx
40481 +       addl %ebx,%esi
40482 +       shrl $2, %ebx  
40483 +       negl %ebx
40484 +       lea 45f(%ebx,%ebx,2), %ebx
40485 +       testl %esi, %esi
40486 +       jmp *%ebx
40487 +
40488 +       # Handle 2-byte-aligned regions
40489 +20:    addw (%esi), %ax
40490 +       lea 2(%esi), %esi
40491 +       adcl $0, %eax
40492 +       jmp 10b
40493 +
40494 +30:    subl $2, %ecx          
40495 +       ja 20b                 
40496 +       je 32f
40497 +       movzbl (%esi),%ebx      # csumming 1 byte, 2-aligned
40498 +       addl %ebx, %eax
40499 +       adcl $0, %eax
40500 +       jmp 80f
40501 +32:
40502 +       addw (%esi), %ax        # csumming 2 bytes, 2-aligned
40503 +       adcl $0, %eax
40504 +       jmp 80f
40505 +
40506 +40: 
40507 +       addl -128(%esi), %eax
40508 +       adcl -124(%esi), %eax
40509 +       adcl -120(%esi), %eax
40510 +       adcl -116(%esi), %eax   
40511 +       adcl -112(%esi), %eax   
40512 +       adcl -108(%esi), %eax
40513 +       adcl -104(%esi), %eax
40514 +       adcl -100(%esi), %eax
40515 +       adcl -96(%esi), %eax
40516 +       adcl -92(%esi), %eax
40517 +       adcl -88(%esi), %eax
40518 +       adcl -84(%esi), %eax
40519 +       adcl -80(%esi), %eax
40520 +       adcl -76(%esi), %eax
40521 +       adcl -72(%esi), %eax
40522 +       adcl -68(%esi), %eax
40523 +       adcl -64(%esi), %eax     
40524 +       adcl -60(%esi), %eax     
40525 +       adcl -56(%esi), %eax     
40526 +       adcl -52(%esi), %eax   
40527 +       adcl -48(%esi), %eax   
40528 +       adcl -44(%esi), %eax
40529 +       adcl -40(%esi), %eax
40530 +       adcl -36(%esi), %eax
40531 +       adcl -32(%esi), %eax
40532 +       adcl -28(%esi), %eax
40533 +       adcl -24(%esi), %eax
40534 +       adcl -20(%esi), %eax
40535 +       adcl -16(%esi), %eax
40536 +       adcl -12(%esi), %eax
40537 +       adcl -8(%esi), %eax
40538 +       adcl -4(%esi), %eax
40539 +45:
40540 +       lea 128(%esi), %esi
40541 +       adcl $0, %eax
40542 +       dec %ecx
40543 +       jge 40b
40544 +       movl %edx, %ecx
40545 +50:    andl $3, %ecx
40546 +       jz 80f
40547 +
40548 +       # Handle the last 1-3 bytes without jumping
40549 +       notl %ecx               # 1->2, 2->1, 3->0, higher bits are masked
40550 +       movl $0xffffff,%ebx     # by the shll and shrl instructions
40551 +       shll $3,%ecx
40552 +       shrl %cl,%ebx
40553 +       andl -128(%esi),%ebx    # esi is 4-aligned so should be ok
40554 +       addl %ebx,%eax
40555 +       adcl $0,%eax
40556 +80: 
40557 +       popl %ebx
40558 +       popl %esi
40559 +       ret
40560 +                               
40561 +#endif
40562 +
40563 +/*
40564 +unsigned int csum_partial_copy_generic (const char *src, char *dst,
40565 +                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr)
40566 + */ 
40567 +
40568 +/*
40569 + * Copy from ds while checksumming, otherwise like csum_partial
40570 + *
40571 + * The macros SRC and DST specify the type of access for the instruction.
40572 + * thus we can call a custom exception handler for all access types.
40573 + *
40574 + * FIXME: could someone double-check whether I haven't mixed up some SRC and
40575 + *       DST definitions? It's damn hard to trigger all cases.  I hope I got
40576 + *       them all but there's no guarantee.
40577 + */
40578 +
40579 +#define SRC(y...)                      \
40580 +       9999: y;                        \
40581 +       .section __ex_table, "a";       \
40582 +       .long 9999b, 6001f      ;       \
40583 +       .previous
40584 +
40585 +#define DST(y...)                      \
40586 +       9999: y;                        \
40587 +       .section __ex_table, "a";       \
40588 +       .long 9999b, 6002f      ;       \
40589 +       .previous
40590 +
40591 +.align 4
40592 +.globl csum_partial_copy_generic_i386
40593 +                               
40594 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
40595 +
40596 +#define ARGBASE 16             
40597 +#define FP             12
40598 +               
40599 +csum_partial_copy_generic_i386:
40600 +       subl  $4,%esp   
40601 +       pushl %edi
40602 +       pushl %esi
40603 +       pushl %ebx
40604 +       movl ARGBASE+16(%esp),%eax      # sum
40605 +       movl ARGBASE+12(%esp),%ecx      # len
40606 +       movl ARGBASE+4(%esp),%esi       # src
40607 +       movl ARGBASE+8(%esp),%edi       # dst
40608 +
40609 +       testl $2, %edi                  # Check alignment. 
40610 +       jz 2f                           # Jump if alignment is ok.
40611 +       subl $2, %ecx                   # Alignment uses up two bytes.
40612 +       jae 1f                          # Jump if we had at least two bytes.
40613 +       addl $2, %ecx                   # ecx was < 2.  Deal with it.
40614 +       jmp 4f
40615 +SRC(1: movw (%esi), %bx        )
40616 +       addl $2, %esi
40617 +DST(   movw %bx, (%edi)        )
40618 +       addl $2, %edi
40619 +       addw %bx, %ax   
40620 +       adcl $0, %eax
40621 +2:
40622 +       movl %ecx, FP(%esp)
40623 +       shrl $5, %ecx
40624 +       jz 2f
40625 +       testl %esi, %esi
40626 +SRC(1: movl (%esi), %ebx       )
40627 +SRC(   movl 4(%esi), %edx      )
40628 +       adcl %ebx, %eax
40629 +DST(   movl %ebx, (%edi)       )
40630 +       adcl %edx, %eax
40631 +DST(   movl %edx, 4(%edi)      )
40632 +
40633 +SRC(   movl 8(%esi), %ebx      )
40634 +SRC(   movl 12(%esi), %edx     )
40635 +       adcl %ebx, %eax
40636 +DST(   movl %ebx, 8(%edi)      )
40637 +       adcl %edx, %eax
40638 +DST(   movl %edx, 12(%edi)     )
40639 +
40640 +SRC(   movl 16(%esi), %ebx     )
40641 +SRC(   movl 20(%esi), %edx     )
40642 +       adcl %ebx, %eax
40643 +DST(   movl %ebx, 16(%edi)     )
40644 +       adcl %edx, %eax
40645 +DST(   movl %edx, 20(%edi)     )
40646 +
40647 +SRC(   movl 24(%esi), %ebx     )
40648 +SRC(   movl 28(%esi), %edx     )
40649 +       adcl %ebx, %eax
40650 +DST(   movl %ebx, 24(%edi)     )
40651 +       adcl %edx, %eax
40652 +DST(   movl %edx, 28(%edi)     )
40653 +
40654 +       lea 32(%esi), %esi
40655 +       lea 32(%edi), %edi
40656 +       dec %ecx
40657 +       jne 1b
40658 +       adcl $0, %eax
40659 +2:     movl FP(%esp), %edx
40660 +       movl %edx, %ecx
40661 +       andl $0x1c, %edx
40662 +       je 4f
40663 +       shrl $2, %edx                   # This clears CF
40664 +SRC(3: movl (%esi), %ebx       )
40665 +       adcl %ebx, %eax
40666 +DST(   movl %ebx, (%edi)       )
40667 +       lea 4(%esi), %esi
40668 +       lea 4(%edi), %edi
40669 +       dec %edx
40670 +       jne 3b
40671 +       adcl $0, %eax
40672 +4:     andl $3, %ecx
40673 +       jz 7f
40674 +       cmpl $2, %ecx
40675 +       jb 5f
40676 +SRC(   movw (%esi), %cx        )
40677 +       leal 2(%esi), %esi
40678 +DST(   movw %cx, (%edi)        )
40679 +       leal 2(%edi), %edi
40680 +       je 6f
40681 +       shll $16,%ecx
40682 +SRC(5: movb (%esi), %cl        )
40683 +DST(   movb %cl, (%edi)        )
40684 +6:     addl %ecx, %eax
40685 +       adcl $0, %eax
40686 +7:
40687 +5000:
40688 +
40689 +# Exception handler:
40690 +.section .fixup, "ax"                                                  
40691 +
40692 +6001:
40693 +       movl ARGBASE+20(%esp), %ebx     # src_err_ptr
40694 +       movl $-EFAULT, (%ebx)
40695 +
40696 +       # zero the complete destination - computing the rest
40697 +       # is too much work 
40698 +       movl ARGBASE+8(%esp), %edi      # dst
40699 +       movl ARGBASE+12(%esp), %ecx     # len
40700 +       xorl %eax,%eax
40701 +       rep ; stosb
40702 +
40703 +       jmp 5000b
40704 +
40705 +6002:
40706 +       movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
40707 +       movl $-EFAULT,(%ebx)
40708 +       jmp 5000b
40709 +
40710 +.previous
40711 +
40712 +       popl %ebx
40713 +       popl %esi
40714 +       popl %edi
40715 +       popl %ecx                       # equivalent to addl $4,%esp
40716 +       ret     
40717 +
40718 +#else
40719 +
40720 +/* Version for PentiumII/PPro */
40721 +
40722 +#define ROUND1(x) \
40723 +       SRC(movl x(%esi), %ebx  )       ;       \
40724 +       addl %ebx, %eax                 ;       \
40725 +       DST(movl %ebx, x(%edi)  )       ; 
40726 +
40727 +#define ROUND(x) \
40728 +       SRC(movl x(%esi), %ebx  )       ;       \
40729 +       adcl %ebx, %eax                 ;       \
40730 +       DST(movl %ebx, x(%edi)  )       ;
40731 +
40732 +#define ARGBASE 12
40733 +               
40734 +csum_partial_copy_generic_i386:
40735 +       pushl %ebx
40736 +       pushl %edi
40737 +       pushl %esi
40738 +       movl ARGBASE+4(%esp),%esi       #src
40739 +       movl ARGBASE+8(%esp),%edi       #dst    
40740 +       movl ARGBASE+12(%esp),%ecx      #len
40741 +       movl ARGBASE+16(%esp),%eax      #sum
40742 +#      movl %ecx, %edx  
40743 +       movl %ecx, %ebx  
40744 +       movl %esi, %edx
40745 +       shrl $6, %ecx     
40746 +       andl $0x3c, %ebx  
40747 +       negl %ebx
40748 +       subl %ebx, %esi  
40749 +       subl %ebx, %edi  
40750 +       lea  -1(%esi),%edx
40751 +       andl $-32,%edx
40752 +       lea 3f(%ebx,%ebx), %ebx
40753 +       testl %esi, %esi 
40754 +       jmp *%ebx
40755 +1:     addl $64,%esi
40756 +       addl $64,%edi 
40757 +       SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl)
40758 +       ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52)    
40759 +       ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36)    
40760 +       ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20)    
40761 +       ROUND (-16) ROUND(-12) ROUND(-8)  ROUND(-4)     
40762 +3:     adcl $0,%eax
40763 +       addl $64, %edx
40764 +       dec %ecx
40765 +       jge 1b
40766 +4:     movl ARGBASE+12(%esp),%edx      #len
40767 +       andl $3, %edx
40768 +       jz 7f
40769 +       cmpl $2, %edx
40770 +       jb 5f
40771 +SRC(   movw (%esi), %dx         )
40772 +       leal 2(%esi), %esi
40773 +DST(   movw %dx, (%edi)         )
40774 +       leal 2(%edi), %edi
40775 +       je 6f
40776 +       shll $16,%edx
40777 +5:
40778 +SRC(   movb (%esi), %dl         )
40779 +DST(   movb %dl, (%edi)         )
40780 +6:     addl %edx, %eax
40781 +       adcl $0, %eax
40782 +7:
40783 +.section .fixup, "ax"
40784 +6001:  movl    ARGBASE+20(%esp), %ebx  # src_err_ptr   
40785 +       movl $-EFAULT, (%ebx)
40786 +       # zero the complete destination (computing the rest is too much work)
40787 +       movl ARGBASE+8(%esp),%edi       # dst
40788 +       movl ARGBASE+12(%esp),%ecx      # len
40789 +       xorl %eax,%eax
40790 +       rep; stosb
40791 +       jmp 7b
40792 +6002:  movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
40793 +       movl $-EFAULT, (%ebx)
40794 +       jmp  7b                 
40795 +.previous                              
40796 +
40797 +       popl %esi
40798 +       popl %edi
40799 +       popl %ebx
40800 +       ret
40801 +                               
40802 +#undef ROUND
40803 +#undef ROUND1          
40804 +               
40805 +#endif
40806 Index: linux-2.4.29/arch/um/sys-i386/fault.c
40807 ===================================================================
40808 --- linux-2.4.29.orig/arch/um/sys-i386/fault.c  1970-01-01 03:00:00.000000000 +0300
40809 +++ linux-2.4.29/arch/um/sys-i386/fault.c       2005-05-03 22:28:14.583393200 +0300
40810 @@ -0,0 +1,34 @@
40811 +/* 
40812 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40813 + * Licensed under the GPL
40814 + */
40815 +
40816 +#include <signal.h>
40817 +#include "sysdep/ptrace.h"
40818 +#include "sysdep/sigcontext.h"
40819 +
40820 +extern unsigned long search_exception_table(unsigned long addr);
40821 +
40822 +int arch_fixup(unsigned long address, void *sc_ptr)
40823 +{
40824 +       struct sigcontext *sc = sc_ptr;
40825 +       unsigned long fixup;
40826 +
40827 +       fixup = search_exception_table(address);
40828 +       if(fixup != 0){
40829 +               sc->eip = fixup;
40830 +               return(1);
40831 +       }
40832 +       return(0);
40833 +}
40834 +
40835 +/*
40836 + * Overrides for Emacs so that we follow Linus's tabbing style.
40837 + * Emacs will notice this stuff at the end of the file and automatically
40838 + * adjust the settings for this buffer only.  This must remain at the end
40839 + * of the file.
40840 + * ---------------------------------------------------------------------------
40841 + * Local variables:
40842 + * c-file-style: "linux"
40843 + * End:
40844 + */
40845 Index: linux-2.4.29/arch/um/sys-i386/ksyms.c
40846 ===================================================================
40847 --- linux-2.4.29.orig/arch/um/sys-i386/ksyms.c  1970-01-01 03:00:00.000000000 +0300
40848 +++ linux-2.4.29/arch/um/sys-i386/ksyms.c       2005-05-03 22:28:14.584393048 +0300
40849 @@ -0,0 +1,17 @@
40850 +#include "linux/module.h"
40851 +#include "linux/in6.h"
40852 +#include "linux/rwsem.h"
40853 +#include "asm/byteorder.h"
40854 +#include "asm/semaphore.h"
40855 +#include "asm/uaccess.h"
40856 +#include "asm/checksum.h"
40857 +#include "asm/errno.h"
40858 +
40859 +EXPORT_SYMBOL(__down_failed);
40860 +EXPORT_SYMBOL(__down_failed_interruptible);
40861 +EXPORT_SYMBOL(__down_failed_trylock);
40862 +EXPORT_SYMBOL(__up_wakeup);
40863 +
40864 +/* Networking helper routines. */
40865 +EXPORT_SYMBOL(csum_partial_copy_from);
40866 +EXPORT_SYMBOL(csum_partial_copy_to);
40867 Index: linux-2.4.29/arch/um/sys-i386/ldt.c
40868 ===================================================================
40869 --- linux-2.4.29.orig/arch/um/sys-i386/ldt.c    1970-01-01 03:00:00.000000000 +0300
40870 +++ linux-2.4.29/arch/um/sys-i386/ldt.c 2005-05-03 22:28:14.585392896 +0300
40871 @@ -0,0 +1,94 @@
40872 +/*
40873 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
40874 + * Licensed under the GPL
40875 + */
40876 +
40877 +#include "linux/config.h"
40878 +#include "linux/slab.h"
40879 +#include "asm/uaccess.h"
40880 +#include "asm/ptrace.h"
40881 +#include "choose-mode.h"
40882 +#include "kern.h"
40883 +
40884 +#ifdef CONFIG_MODE_TT
40885 +extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
40886 +
40887 +/* XXX this needs copy_to_user and copy_from_user */
40888 +
40889 +int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
40890 +{
40891 +       if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT);
40892 +       return(modify_ldt(func, ptr, bytecount));
40893 +}
40894 +#endif
40895 +
40896 +#ifdef CONFIG_MODE_SKAS
40897 +extern int userspace_pid;
40898 +
40899 +int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
40900 +{
40901 +       struct ptrace_ldt ldt;
40902 +       void *buf;
40903 +       int res, n;
40904 +
40905 +       buf = kmalloc(bytecount, GFP_KERNEL);
40906 +       if(buf == NULL)
40907 +               return(-ENOMEM);
40908 +
40909 +       res = 0;
40910 +
40911 +       switch(func){
40912 +       case 1:
40913 +       case 0x11:
40914 +               res = copy_from_user(buf, ptr, bytecount);
40915 +               break;
40916 +       }
40917 +
40918 +       if(res != 0){
40919 +               res = -EFAULT;
40920 +               goto out;
40921 +       }
40922 +
40923 +       ldt = ((struct ptrace_ldt) { .func      = func,
40924 +                                    .ptr       = buf,
40925 +                                    .bytecount = bytecount });
40926 +       res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt);
40927 +       if(res < 0)
40928 +               goto out;
40929 +
40930 +       switch(func){
40931 +       case 0:
40932 +       case 2:
40933 +               n = res;
40934 +               res = copy_to_user(ptr, buf, n);
40935 +               if(res != 0)
40936 +                       res = -EFAULT;
40937 +               else 
40938 +                       res = n;
40939 +               break;
40940 +       }
40941 +
40942 + out:
40943 +       kfree(buf);
40944 +       return(res);
40945 +}
40946 +#endif
40947 +
40948 +int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
40949 +{
40950 +       return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func, 
40951 +                               ptr, bytecount));
40952 +}
40953 +
40954 +
40955 +
40956 +/*
40957 + * Overrides for Emacs so that we follow Linus's tabbing style.
40958 + * Emacs will notice this stuff at the end of the file and automatically
40959 + * adjust the settings for this buffer only.  This must remain at the end
40960 + * of the file.
40961 + * ---------------------------------------------------------------------------
40962 + * Local variables:
40963 + * c-file-style: "linux"
40964 + * End:
40965 + */
40966 Index: linux-2.4.29/arch/um/sys-i386/Makefile
40967 ===================================================================
40968 --- linux-2.4.29.orig/arch/um/sys-i386/Makefile 1970-01-01 03:00:00.000000000 +0300
40969 +++ linux-2.4.29/arch/um/sys-i386/Makefile      2005-05-03 22:28:14.586392744 +0300
40970 @@ -0,0 +1,46 @@
40971 +# 
40972 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40973 +# Licensed under the GPL
40974 +#
40975 +
40976 +O_TARGET = built-in.o
40977 +
40978 +obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \
40979 +       ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
40980 +export-objs = ksyms.o
40981 +
40982 +USER_OBJS = bugs.o ptrace_user.o sigcontext.o fault.o
40983 +
40984 +SYMLINKS = semaphore.c extable.c
40985 +
40986 +semaphore.c-dir = kernel
40987 +extable.c-dir = mm
40988 +
40989 +include $(TOPDIR)/Rules.make
40990 +
40991 +$(USER_OBJS) : %.o: %.c
40992 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
40993 +
40994 +define make_link
40995 +       -rm -f $1
40996 +       ln -sf $(TOPDIR)/arch/i386/$($1-dir)/$1 $1
40997 +endef
40998 +
40999 +$(SYMLINKS): 
41000 +       $(call make_link,$@)
41001 +
41002 +clean:
41003 +       $(MAKE) -C util clean
41004 +       rm -f $(SYMLINKS)
41005 +
41006 +fastdep:
41007 +
41008 +dep:
41009 +
41010 +archmrproper:
41011 +
41012 +archclean:
41013 +
41014 +archdep:
41015 +
41016 +modules:
41017 Index: linux-2.4.29/arch/um/sys-i386/ptrace.c
41018 ===================================================================
41019 --- linux-2.4.29.orig/arch/um/sys-i386/ptrace.c 1970-01-01 03:00:00.000000000 +0300
41020 +++ linux-2.4.29/arch/um/sys-i386/ptrace.c      2005-05-03 22:28:14.588392440 +0300
41021 @@ -0,0 +1,367 @@
41022 +/* 
41023 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
41024 + * Licensed under the GPL
41025 + */
41026 +
41027 +#include "linux/sched.h"
41028 +#include "asm/elf.h"
41029 +#include "asm/ptrace.h"
41030 +#include "asm/uaccess.h"
41031 +#include "asm/unistd.h"
41032 +#include "ptrace_user.h"
41033 +#include "sysdep/sigcontext.h"
41034 +#include "sysdep/sc.h"
41035 +
41036 +void arch_switch(void)
41037 +{
41038 +       update_debugregs(current->thread.arch.debugregs_seq);
41039 +}
41040 +
41041 +int is_syscall(unsigned long addr)
41042 +{
41043 +       unsigned short instr;
41044 +       int n;
41045 +
41046 +       n = copy_from_user(&instr, (void *) addr, sizeof(instr));
41047 +       if(n){
41048 +               printk("is_syscall : failed to read instruction from 0x%lx\n", 
41049 +                      addr);
41050 +               return(0);
41051 +       }
41052 +       /* int 0x80 or sysenter */
41053 +       return((instr == 0x80cd) || (instr == 0x340f));
41054 +}
41055 +
41056 +/* determines which flags the user has access to. */
41057 +/* 1 = access 0 = no access */
41058 +#define FLAG_MASK 0x00044dd5
41059 +
41060 +int putreg(struct task_struct *child, int regno, unsigned long value)
41061 +{
41062 +       regno >>= 2;
41063 +       switch (regno) {
41064 +       case FS:
41065 +               if (value && (value & 3) != 3)
41066 +                       return -EIO;
41067 +               PT_REGS_FS(&child->thread.regs) = value;
41068 +               return 0;
41069 +       case GS:
41070 +               if (value && (value & 3) != 3)
41071 +                       return -EIO;
41072 +               PT_REGS_GS(&child->thread.regs) = value;
41073 +               return 0;
41074 +       case DS:
41075 +       case ES:
41076 +               if (value && (value & 3) != 3)
41077 +                       return -EIO;
41078 +               value &= 0xffff;
41079 +               break;
41080 +       case SS:
41081 +       case CS:
41082 +               if ((value & 3) != 3)
41083 +                       return -EIO;
41084 +               value &= 0xffff;
41085 +               break;
41086 +       case EFL:
41087 +               value &= FLAG_MASK;
41088 +               value |= PT_REGS_EFLAGS(&child->thread.regs);
41089 +               break;
41090 +       }
41091 +       PT_REGS_SET(&child->thread.regs, regno, value);
41092 +       return 0;
41093 +}
41094 +
41095 +unsigned long getreg(struct task_struct *child, int regno)
41096 +{
41097 +       unsigned long retval = ~0UL;
41098 +
41099 +       regno >>= 2;
41100 +       switch (regno) {
41101 +       case FS:
41102 +       case GS:
41103 +       case DS:
41104 +       case ES:
41105 +       case SS:
41106 +       case CS:
41107 +               retval = 0xffff;
41108 +               /* fall through */
41109 +       default:
41110 +               retval &= PT_REG(&child->thread.regs, regno);
41111 +       }
41112 +       return retval;
41113 +}
41114 +
41115 +struct i387_fxsave_struct {
41116 +       unsigned short  cwd;
41117 +       unsigned short  swd;
41118 +       unsigned short  twd;
41119 +       unsigned short  fop;
41120 +       long    fip;
41121 +       long    fcs;
41122 +       long    foo;
41123 +       long    fos;
41124 +       long    mxcsr;
41125 +       long    reserved;
41126 +       long    st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
41127 +       long    xmm_space[32];  /* 8*16 bytes for each XMM-reg = 128 bytes */
41128 +       long    padding[56];
41129 +};
41130 +
41131 +/*
41132 + * FPU tag word conversions.
41133 + */
41134 +
41135 +static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
41136 +{
41137 +       unsigned int tmp; /* to avoid 16 bit prefixes in the code */
41138
41139 +       /* Transform each pair of bits into 01 (valid) or 00 (empty) */
41140 +        tmp = ~twd;
41141 +        tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
41142 +        /* and move the valid bits to the lower byte. */
41143 +        tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
41144 +        tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
41145 +        tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
41146 +        return tmp;
41147 +}
41148 +
41149 +static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
41150 +{
41151 +       struct _fpxreg *st = NULL;
41152 +       unsigned long twd = (unsigned long) fxsave->twd;
41153 +       unsigned long tag;
41154 +       unsigned long ret = 0xffff0000;
41155 +       int i;
41156 +
41157 +#define FPREG_ADDR(f, n)       ((char *)&(f)->st_space + (n) * 16);
41158 +
41159 +       for ( i = 0 ; i < 8 ; i++ ) {
41160 +               if ( twd & 0x1 ) {
41161 +                       st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
41162 +
41163 +                       switch ( st->exponent & 0x7fff ) {
41164 +                       case 0x7fff:
41165 +                               tag = 2;                /* Special */
41166 +                               break;
41167 +                       case 0x0000:
41168 +                               if ( !st->significand[0] &&
41169 +                                    !st->significand[1] &&
41170 +                                    !st->significand[2] &&
41171 +                                    !st->significand[3] ) {
41172 +                                       tag = 1;        /* Zero */
41173 +                               } else {
41174 +                                       tag = 2;        /* Special */
41175 +                               }
41176 +                               break;
41177 +                       default:
41178 +                               if ( st->significand[3] & 0x8000 ) {
41179 +                                       tag = 0;        /* Valid */
41180 +                               } else {
41181 +                                       tag = 2;        /* Special */
41182 +                               }
41183 +                               break;
41184 +                       }
41185 +               } else {
41186 +                       tag = 3;                        /* Empty */
41187 +               }
41188 +               ret |= (tag << (2 * i));
41189 +               twd = twd >> 1;
41190 +       }
41191 +       return ret;
41192 +}
41193 +
41194 +/*
41195 + * FXSR floating point environment conversions.
41196 + */
41197 +
41198 +#ifdef CONFIG_MODE_TT
41199 +static inline int convert_fxsr_to_user_tt(struct _fpstate *buf, 
41200 +                                         struct pt_regs *regs)
41201 +{
41202 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
41203 +       unsigned long env[7];
41204 +       struct _fpreg *to;
41205 +       struct _fpxreg *from;
41206 +       int i;
41207 +
41208 +       env[0] = (unsigned long)fxsave->cwd | 0xffff0000;
41209 +       env[1] = (unsigned long)fxsave->swd | 0xffff0000;
41210 +       env[2] = twd_fxsr_to_i387(fxsave);
41211 +       env[3] = fxsave->fip;
41212 +       env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
41213 +       env[5] = fxsave->foo;
41214 +       env[6] = fxsave->fos;
41215 +
41216 +       if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
41217 +               return 1;
41218 +
41219 +       to = &buf->_st[0];
41220 +       from = (struct _fpxreg *) &fxsave->st_space[0];
41221 +       for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
41222 +               if ( __copy_to_user( to, from, sizeof(*to) ) )
41223 +                       return 1;
41224 +       }
41225 +       return 0;
41226 +}
41227 +#endif
41228 +
41229 +static inline int convert_fxsr_to_user(struct _fpstate *buf, 
41230 +                                      struct pt_regs *regs)
41231 +{
41232 +       return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0));
41233 +}
41234 +
41235 +#ifdef CONFIG_MODE_TT
41236 +static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
41237 +                                           struct _fpstate *buf)
41238 +{
41239 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
41240 +       unsigned long env[7];
41241 +       struct _fpxreg *to;
41242 +       struct _fpreg *from;
41243 +       int i;
41244 +
41245 +       if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
41246 +               return 1;
41247 +
41248 +       fxsave->cwd = (unsigned short)(env[0] & 0xffff);
41249 +       fxsave->swd = (unsigned short)(env[1] & 0xffff);
41250 +       fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
41251 +       fxsave->fip = env[3];
41252 +       fxsave->fop = (unsigned short)((env[4] & 0xffff0000) >> 16);
41253 +       fxsave->fcs = (env[4] & 0xffff);
41254 +       fxsave->foo = env[5];
41255 +       fxsave->fos = env[6];
41256 +
41257 +       to = (struct _fpxreg *) &fxsave->st_space[0];
41258 +       from = &buf->_st[0];
41259 +       for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
41260 +               if ( __copy_from_user( to, from, sizeof(*from) ) )
41261 +                       return 1;
41262 +       }
41263 +       return 0;
41264 +}
41265 +#endif
41266 +
41267 +static inline int convert_fxsr_from_user(struct pt_regs *regs, 
41268 +                                        struct _fpstate *buf)
41269 +{
41270 +       return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0));
41271 +}
41272 +
41273 +int get_fpregs(unsigned long buf, struct task_struct *child)
41274 +{
41275 +       int err;
41276 +
41277 +       err = convert_fxsr_to_user((struct _fpstate *) buf, 
41278 +                                  &child->thread.regs);
41279 +       if(err) return(-EFAULT);
41280 +       else return(0);
41281 +}
41282 +
41283 +int set_fpregs(unsigned long buf, struct task_struct *child)
41284 +{
41285 +       int err;
41286 +
41287 +       err = convert_fxsr_from_user(&child->thread.regs, 
41288 +                                    (struct _fpstate *) buf);
41289 +       if(err) return(-EFAULT);
41290 +       else return(0);
41291 +}
41292 +
41293 +#ifdef CONFIG_MODE_TT
41294 +int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
41295 +{
41296 +       struct pt_regs *regs = &tsk->thread.regs;
41297 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
41298 +       int err;
41299 +
41300 +       err = __copy_to_user((void *) buf, fxsave,
41301 +                            sizeof(struct user_fxsr_struct));
41302 +       if(err) return -EFAULT;
41303 +       else return 0;
41304 +}
41305 +#endif
41306 +
41307 +int get_fpxregs(unsigned long buf, struct task_struct *tsk)
41308 +{
41309 +       return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0));
41310 +}
41311 +
41312 +#ifdef CONFIG_MODE_TT
41313 +int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
41314 +{
41315 +       struct pt_regs *regs = &tsk->thread.regs;
41316 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
41317 +       int err;
41318 +
41319 +       err = __copy_from_user(fxsave, (void *) buf,
41320 +                              sizeof(struct user_fxsr_struct) );
41321 +       if(err) return -EFAULT;
41322 +       else return 0;
41323 +}
41324 +#endif
41325 +
41326 +int set_fpxregs(unsigned long buf, struct task_struct *tsk)
41327 +{
41328 +       return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0));
41329 +}
41330 +
41331 +#ifdef notdef
41332 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
41333 +{
41334 +       fpu->cwd = (((SC_FP_CW(PT_REGS_SC(regs)) & 0xffff) << 16) |
41335 +                   (SC_FP_SW(PT_REGS_SC(regs)) & 0xffff));
41336 +       fpu->swd = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
41337 +       fpu->twd = SC_FP_IPOFF(PT_REGS_SC(regs));
41338 +       fpu->fip = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
41339 +       fpu->fcs = SC_FP_DATAOFF(PT_REGS_SC(regs));
41340 +       fpu->foo = SC_FP_DATASEL(PT_REGS_SC(regs));
41341 +       fpu->fos = 0;
41342 +       memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)),
41343 +              sizeof(fpu->st_space));
41344 +       return(1);
41345 +}
41346 +#endif
41347 +
41348 +#ifdef CONFIG_MODE_TT
41349 +static inline void copy_fpu_fxsave_tt(struct pt_regs *regs,
41350 +                                     struct user_i387_struct *buf)
41351 +{
41352 +       struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs));
41353 +       unsigned short *to;
41354 +       unsigned short *from;
41355 +       int i;
41356 +
41357 +       memcpy( buf, fpu, 7 * sizeof(long) );
41358 +
41359 +       to = (unsigned short *) &buf->st_space[0];
41360 +       from = (unsigned short *) &fpu->st_space[0];
41361 +       for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) {
41362 +               memcpy( to, from, 5 * sizeof(unsigned short) );
41363 +       }
41364 +}
41365 +#endif
41366 +
41367 +static inline void copy_fpu_fxsave(struct pt_regs *regs,
41368 +                                  struct user_i387_struct *buf)
41369 +{
41370 +       (void) CHOOSE_MODE(copy_fpu_fxsave_tt(regs, buf), 0);
41371 +}
41372 +
41373 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
41374 +{
41375 +       copy_fpu_fxsave(regs, (struct user_i387_struct *) fpu);
41376 +       return(1);
41377 +}
41378 +
41379 +/*
41380 + * Overrides for Emacs so that we follow Linus's tabbing style.
41381 + * Emacs will notice this stuff at the end of the file and automatically
41382 + * adjust the settings for this buffer only.  This must remain at the end
41383 + * of the file.
41384 + * ---------------------------------------------------------------------------
41385 + * Local variables:
41386 + * c-file-style: "linux"
41387 + * End:
41388 + */
41389 Index: linux-2.4.29/arch/um/sys-i386/ptrace_user.c
41390 ===================================================================
41391 --- linux-2.4.29.orig/arch/um/sys-i386/ptrace_user.c    1970-01-01 03:00:00.000000000 +0300
41392 +++ linux-2.4.29/arch/um/sys-i386/ptrace_user.c 2005-05-03 22:28:14.589392288 +0300
41393 @@ -0,0 +1,118 @@
41394 +/* 
41395 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
41396 + * Licensed under the GPL
41397 + */
41398 +
41399 +#include <stdio.h>
41400 +#include <errno.h>
41401 +#include <unistd.h>
41402 +#include <linux/stddef.h>
41403 +#include <sys/ptrace.h>
41404 +#include <asm/ptrace.h>
41405 +#include <asm/user.h>
41406 +#include "kern_util.h"
41407 +#include "sysdep/thread.h"
41408 +#include "user.h"
41409 +#include "os.h"
41410 +
41411 +int ptrace_getregs(long pid, unsigned long *regs_out)
41412 +{
41413 +       return(ptrace(PTRACE_GETREGS, pid, 0, regs_out));
41414 +}
41415 +
41416 +int ptrace_setregs(long pid, unsigned long *regs)
41417 +{
41418 +       return(ptrace(PTRACE_SETREGS, pid, 0, regs));
41419 +}
41420 +
41421 +int ptrace_getfpregs(long pid, unsigned long *regs)
41422 +{
41423 +       return(ptrace(PTRACE_GETFPREGS, pid, 0, regs));
41424 +}
41425 +
41426 +static void write_debugregs(int pid, unsigned long *regs)
41427 +{
41428 +       struct user *dummy;
41429 +       int nregs, i;
41430 +
41431 +       dummy = NULL;
41432 +       nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
41433 +       for(i = 0; i < nregs; i++){
41434 +               if((i == 4) || (i == 5)) continue;
41435 +               if(ptrace(PTRACE_POKEUSER, pid, &dummy->u_debugreg[i],
41436 +                         regs[i]) < 0)
41437 +                       printk("write_debugregs - ptrace failed on "
41438 +                              "register %d, value = 0x%x, errno = %d\n", i, 
41439 +                              regs[i], errno);
41440 +       }
41441 +}
41442 +
41443 +static void read_debugregs(int pid, unsigned long *regs)
41444 +{
41445 +       struct user *dummy;
41446 +       int nregs, i;
41447 +
41448 +       dummy = NULL;
41449 +       nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
41450 +       for(i = 0; i < nregs; i++){
41451 +               regs[i] = ptrace(PTRACE_PEEKUSER, pid, 
41452 +                                &dummy->u_debugreg[i], 0);
41453 +       }
41454 +}
41455 +
41456 +/* Accessed only by the tracing thread */
41457 +static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
41458 +static int debugregs_seq = 0;
41459 +
41460 +void arch_enter_kernel(void *task, int pid)
41461 +{
41462 +       read_debugregs(pid, TASK_DEBUGREGS(task));
41463 +       write_debugregs(pid, kernel_debugregs);
41464 +}
41465 +
41466 +void arch_leave_kernel(void *task, int pid)
41467 +{
41468 +       read_debugregs(pid, kernel_debugregs);
41469 +       write_debugregs(pid, TASK_DEBUGREGS(task));
41470 +}
41471 +
41472 +void ptrace_pokeuser(unsigned long addr, unsigned long data)
41473 +{
41474 +       if((addr < offsetof(struct user, u_debugreg[0])) ||
41475 +          (addr > offsetof(struct user, u_debugreg[7])))
41476 +               return;
41477 +       addr -= offsetof(struct user, u_debugreg[0]);
41478 +       addr = addr >> 2;
41479 +       if(kernel_debugregs[addr] == data) return;
41480 +
41481 +       kernel_debugregs[addr] = data;
41482 +       debugregs_seq++;
41483 +}
41484 +
41485 +static void update_debugregs_cb(void *arg)
41486 +{
41487 +       int pid = *((int *) arg);
41488 +
41489 +       write_debugregs(pid, kernel_debugregs);
41490 +}
41491 +
41492 +void update_debugregs(int seq)
41493 +{
41494 +       int me;
41495 +
41496 +       if(seq == debugregs_seq) return;
41497 +
41498 +       me = os_getpid();
41499 +       initial_thread_cb(update_debugregs_cb, &me);
41500 +}
41501 +
41502 +/*
41503 + * Overrides for Emacs so that we follow Linus's tabbing style.
41504 + * Emacs will notice this stuff at the end of the file and automatically
41505 + * adjust the settings for this buffer only.  This must remain at the end
41506 + * of the file.
41507 + * ---------------------------------------------------------------------------
41508 + * Local variables:
41509 + * c-file-style: "linux"
41510 + * End:
41511 + */
41512 Index: linux-2.4.29/arch/um/sys-i386/sigcontext.c
41513 ===================================================================
41514 --- linux-2.4.29.orig/arch/um/sys-i386/sigcontext.c     1970-01-01 03:00:00.000000000 +0300
41515 +++ linux-2.4.29/arch/um/sys-i386/sigcontext.c  2005-05-03 22:28:14.590392136 +0300
41516 @@ -0,0 +1,80 @@
41517 +/* 
41518 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
41519 + * Licensed under the GPL
41520 + */
41521 +
41522 +#include <stddef.h>
41523 +#include <string.h>
41524 +#include <asm/ptrace.h>
41525 +#include <asm/sigcontext.h>
41526 +#include "sysdep/ptrace.h"
41527 +#include "kern_util.h"
41528 +#include "frame_user.h"
41529 +
41530 +int sc_size(void *data)
41531 +{
41532 +       struct arch_frame_data *arch = data;
41533 +
41534 +       return(sizeof(struct sigcontext) + arch->fpstate_size);
41535 +}
41536 +
41537 +void sc_to_sc(void *to_ptr, void *from_ptr)
41538 +{
41539 +       struct sigcontext *to = to_ptr, *from = from_ptr;
41540 +       int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size;
41541 +
41542 +       memcpy(to, from, size);
41543 +       if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1);
41544 +}
41545 +
41546 +unsigned long *sc_sigmask(void *sc_ptr)
41547 +{
41548 +       struct sigcontext *sc = sc_ptr;
41549 +
41550 +       return(&sc->oldmask);
41551 +}
41552 +
41553 +int sc_get_fpregs(unsigned long buf, void *sc_ptr)
41554 +{
41555 +       struct sigcontext *sc = sc_ptr;
41556 +       struct _fpstate *from = sc->fpstate, *to = (struct _fpstate *) buf;
41557 +       int err = 0;
41558 +
41559 +       if(from == NULL){
41560 +               err |= clear_user_proc(&to->cw, sizeof(to->cw));
41561 +               err |= clear_user_proc(&to->sw, sizeof(to->sw));
41562 +               err |= clear_user_proc(&to->tag, sizeof(to->tag));
41563 +               err |= clear_user_proc(&to->ipoff, sizeof(to->ipoff));
41564 +               err |= clear_user_proc(&to->cssel, sizeof(to->cssel));
41565 +               err |= clear_user_proc(&to->dataoff, sizeof(to->dataoff));
41566 +               err |= clear_user_proc(&to->datasel, sizeof(to->datasel));
41567 +               err |= clear_user_proc(&to->_st, sizeof(to->_st));
41568 +       }
41569 +       else {
41570 +               err |= copy_to_user_proc(&to->cw, &from->cw, sizeof(to->cw));
41571 +               err |= copy_to_user_proc(&to->sw, &from->sw, sizeof(to->sw));
41572 +               err |= copy_to_user_proc(&to->tag, &from->tag, 
41573 +                                        sizeof(to->tag));
41574 +               err |= copy_to_user_proc(&to->ipoff, &from->ipoff, 
41575 +                                        sizeof(to->ipoff));
41576 +               err |= copy_to_user_proc(&to->cssel,& from->cssel, 
41577 +                                        sizeof(to->cssel));
41578 +               err |= copy_to_user_proc(&to->dataoff, &from->dataoff, 
41579 +                                   sizeof(to->dataoff));
41580 +               err |= copy_to_user_proc(&to->datasel, &from->datasel, 
41581 +                                   sizeof(to->datasel));
41582 +               err |= copy_to_user_proc(to->_st, from->_st, sizeof(to->_st));
41583 +       }
41584 +       return(err);
41585 +}
41586 +
41587 +/*
41588 + * Overrides for Emacs so that we follow Linus's tabbing style.
41589 + * Emacs will notice this stuff at the end of the file and automatically
41590 + * adjust the settings for this buffer only.  This must remain at the end
41591 + * of the file.
41592 + * ---------------------------------------------------------------------------
41593 + * Local variables:
41594 + * c-file-style: "linux"
41595 + * End:
41596 + */
41597 Index: linux-2.4.29/arch/um/sys-i386/syscalls.c
41598 ===================================================================
41599 --- linux-2.4.29.orig/arch/um/sys-i386/syscalls.c       1970-01-01 03:00:00.000000000 +0300
41600 +++ linux-2.4.29/arch/um/sys-i386/syscalls.c    2005-05-03 22:28:14.590392136 +0300
41601 @@ -0,0 +1,68 @@
41602 +/* 
41603 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
41604 + * Licensed under the GPL
41605 + */
41606 +
41607 +#include "asm/mman.h"
41608 +#include "asm/uaccess.h"
41609 +#include "asm/unistd.h"
41610 +
41611 +/*
41612 + * Perform the select(nd, in, out, ex, tv) and mmap() system
41613 + * calls. Linux/i386 didn't use to be able to handle more than
41614 + * 4 system call parameters, so these system calls used a memory
41615 + * block for parameter passing..
41616 + */
41617 +
41618 +struct mmap_arg_struct {
41619 +       unsigned long addr;
41620 +       unsigned long len;
41621 +       unsigned long prot;
41622 +       unsigned long flags;
41623 +       unsigned long fd;
41624 +       unsigned long offset;
41625 +};
41626 +
41627 +extern int old_mmap(unsigned long addr, unsigned long len,
41628 +                   unsigned long prot, unsigned long flags,
41629 +                   unsigned long fd, unsigned long offset);
41630 +
41631 +int old_mmap_i386(struct mmap_arg_struct *arg)
41632 +{
41633 +       struct mmap_arg_struct a;
41634 +       int err = -EFAULT;
41635 +
41636 +       if (copy_from_user(&a, arg, sizeof(a)))
41637 +               goto out;
41638 +
41639 +       err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
41640 + out:
41641 +       return err;
41642 +}
41643 +
41644 +struct sel_arg_struct {
41645 +       unsigned long n;
41646 +       fd_set *inp, *outp, *exp;
41647 +       struct timeval *tvp;
41648 +};
41649 +
41650 +int old_select(struct sel_arg_struct *arg)
41651 +{
41652 +       struct sel_arg_struct a;
41653 +
41654 +       if (copy_from_user(&a, arg, sizeof(a)))
41655 +               return -EFAULT;
41656 +       /* sys_select() does the appropriate kernel locking */
41657 +       return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
41658 +}
41659 +
41660 +/*
41661 + * Overrides for Emacs so that we follow Linus's tabbing style.
41662 + * Emacs will notice this stuff at the end of the file and automatically
41663 + * adjust the settings for this buffer only.  This must remain at the end
41664 + * of the file.
41665 + * ---------------------------------------------------------------------------
41666 + * Local variables:
41667 + * c-file-style: "linux"
41668 + * End:
41669 + */
41670 Index: linux-2.4.29/arch/um/sys-i386/sysrq.c
41671 ===================================================================
41672 --- linux-2.4.29.orig/arch/um/sys-i386/sysrq.c  1970-01-01 03:00:00.000000000 +0300
41673 +++ linux-2.4.29/arch/um/sys-i386/sysrq.c       2005-05-03 22:28:14.591391984 +0300
41674 @@ -0,0 +1,30 @@
41675 +#include "linux/kernel.h"
41676 +#include "linux/smp.h"
41677 +#include "linux/sched.h"
41678 +#include "asm/ptrace.h"
41679 +#include "sysrq.h"
41680 +
41681 +void show_regs(struct pt_regs *regs)
41682 +{
41683 +        printk("\n");
41684 +        printk("EIP: %04lx:[<%08lx>] CPU: %d %s", 
41685 +              0xffff & PT_REGS_CS(regs), PT_REGS_IP(regs),
41686 +              smp_processor_id(), print_tainted());
41687 +        if (PT_REGS_CS(regs) & 3)
41688 +                printk(" ESP: %04lx:%08lx", 0xffff & PT_REGS_SS(regs),
41689 +                      PT_REGS_SP(regs));
41690 +        printk(" EFLAGS: %08lx\n    %s\n", PT_REGS_EFLAGS(regs),
41691 +              print_tainted());
41692 +        printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
41693 +                PT_REGS_EAX(regs), PT_REGS_EBX(regs), 
41694 +              PT_REGS_ECX(regs), 
41695 +              PT_REGS_EDX(regs));
41696 +        printk("ESI: %08lx EDI: %08lx EBP: %08lx",
41697 +              PT_REGS_ESI(regs), PT_REGS_EDI(regs), 
41698 +              PT_REGS_EBP(regs));
41699 +        printk(" DS: %04lx ES: %04lx\n",
41700 +              0xffff & PT_REGS_DS(regs), 
41701 +              0xffff & PT_REGS_ES(regs));
41702 +
41703 +        show_trace((unsigned long *) &regs);
41704 +}
41705 Index: linux-2.4.29/arch/um/sys-i386/util/Makefile
41706 ===================================================================
41707 --- linux-2.4.29.orig/arch/um/sys-i386/util/Makefile    1970-01-01 03:00:00.000000000 +0300
41708 +++ linux-2.4.29/arch/um/sys-i386/util/Makefile 2005-05-03 22:28:14.592391832 +0300
41709 @@ -0,0 +1,28 @@
41710 +EXE = mk_sc mk_thread
41711 +
41712 +include $(TOPDIR)/Rules.make
41713 +
41714 +all : $(EXE)
41715 +
41716 +mk_sc : mk_sc.o
41717 +       $(HOSTCC) -o mk_sc mk_sc.o
41718 +
41719 +mk_sc.o : mk_sc.c
41720 +       $(HOSTCC) -c $< 
41721 +
41722 +mk_thread : mk_thread_user.o mk_thread_kern.o
41723 +       $(HOSTCC) -o mk_thread mk_thread_user.o mk_thread_kern.o
41724 +
41725 +mk_thread_user.o : mk_thread_user.c
41726 +       $(HOSTCC) -c $< 
41727 +
41728 +mk_thread_kern.o : mk_thread_kern.c
41729 +       $(HOSTCC) $(CFLAGS) -c $< 
41730 +
41731 +clean :
41732 +       $(RM) $(EXE) *.o
41733 +
41734 +archmrproper : clean
41735 +
41736 +fastdep :
41737 +
41738 Index: linux-2.4.29/arch/um/sys-i386/util/mk_sc.c
41739 ===================================================================
41740 --- linux-2.4.29.orig/arch/um/sys-i386/util/mk_sc.c     1970-01-01 03:00:00.000000000 +0300
41741 +++ linux-2.4.29/arch/um/sys-i386/util/mk_sc.c  2005-05-03 22:28:14.000000000 +0300
41742 @@ -0,0 +1,52 @@
41743 +#include <stdio.h>
41744 +#include <signal.h>
41745 +#include <linux/stddef.h>
41746 +
41747 +#define SC_OFFSET(name, field) \
41748 +  printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
41749 +        offsetof(struct sigcontext, field))
41750 +
41751 +#define SC_FP_OFFSET(name, field) \
41752 +  printf("#define " name \
41753 +        "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
41754 +        offsetof(struct _fpstate, field))
41755 +
41756 +#define SC_FP_OFFSET_PTR(name, field, type) \
41757 +  printf("#define " name \
41758 +        "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
41759 +        offsetof(struct _fpstate, field))
41760 +
41761 +int main(int argc, char **argv)
41762 +{
41763 +  SC_OFFSET("SC_IP", eip);
41764 +  SC_OFFSET("SC_SP", esp);
41765 +  SC_OFFSET("SC_FS", fs);
41766 +  SC_OFFSET("SC_GS", gs);
41767 +  SC_OFFSET("SC_DS", ds);
41768 +  SC_OFFSET("SC_ES", es);
41769 +  SC_OFFSET("SC_SS", ss);
41770 +  SC_OFFSET("SC_CS", cs);
41771 +  SC_OFFSET("SC_EFLAGS", eflags);
41772 +  SC_OFFSET("SC_EAX", eax);
41773 +  SC_OFFSET("SC_EBX", ebx);
41774 +  SC_OFFSET("SC_ECX", ecx);
41775 +  SC_OFFSET("SC_EDX", edx);
41776 +  SC_OFFSET("SC_EDI", edi);
41777 +  SC_OFFSET("SC_ESI", esi);
41778 +  SC_OFFSET("SC_EBP", ebp);
41779 +  SC_OFFSET("SC_TRAPNO", trapno);
41780 +  SC_OFFSET("SC_ERR", err);
41781 +  SC_OFFSET("SC_CR2", cr2);
41782 +  SC_OFFSET("SC_FPSTATE", fpstate);
41783 +  SC_OFFSET("SC_SIGMASK", oldmask);
41784 +  SC_FP_OFFSET("SC_FP_CW", cw);
41785 +  SC_FP_OFFSET("SC_FP_SW", sw);
41786 +  SC_FP_OFFSET("SC_FP_TAG", tag);
41787 +  SC_FP_OFFSET("SC_FP_IPOFF", ipoff);
41788 +  SC_FP_OFFSET("SC_FP_CSSEL", cssel);
41789 +  SC_FP_OFFSET("SC_FP_DATAOFF", dataoff);
41790 +  SC_FP_OFFSET("SC_FP_DATASEL", datasel);
41791 +  SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate");
41792 +  SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void");
41793 +  return(0);
41794 +}
41795 Index: linux-2.4.29/arch/um/sys-i386/util/mk_thread_kern.c
41796 ===================================================================
41797 --- linux-2.4.29.orig/arch/um/sys-i386/util/mk_thread_kern.c    1970-01-01 03:00:00.000000000 +0300
41798 +++ linux-2.4.29/arch/um/sys-i386/util/mk_thread_kern.c 2005-05-03 22:28:14.000000000 +0300
41799 @@ -0,0 +1,22 @@
41800 +#include "linux/config.h"
41801 +#include "linux/stddef.h"
41802 +#include "linux/sched.h"
41803 +
41804 +extern void print_head(void);
41805 +extern void print_constant_ptr(char *name, int value);
41806 +extern void print_constant(char *name, char *type, int value);
41807 +extern void print_tail(void);
41808 +
41809 +#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
41810 +
41811 +int main(int argc, char **argv)
41812 +{
41813 +  print_head();
41814 +  print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs));
41815 +#ifdef CONFIG_MODE_TT
41816 +  print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
41817 +#endif
41818 +  print_tail();
41819 +  return(0);
41820 +}
41821 +
41822 Index: linux-2.4.29/arch/um/sys-i386/util/mk_thread_user.c
41823 ===================================================================
41824 --- linux-2.4.29.orig/arch/um/sys-i386/util/mk_thread_user.c    1970-01-01 03:00:00.000000000 +0300
41825 +++ linux-2.4.29/arch/um/sys-i386/util/mk_thread_user.c 2005-05-03 22:28:14.000000000 +0300
41826 @@ -0,0 +1,30 @@
41827 +#include <stdio.h>
41828 +
41829 +void print_head(void)
41830 +{
41831 +  printf("/*\n");
41832 +  printf(" * Generated by mk_thread\n");
41833 +  printf(" */\n");
41834 +  printf("\n");
41835 +  printf("#ifndef __UM_THREAD_H\n");
41836 +  printf("#define __UM_THREAD_H\n");
41837 +  printf("\n");
41838 +}
41839 +
41840 +void print_constant_ptr(char *name, int value)
41841 +{
41842 +  printf("#define %s(task) ((unsigned long *) "
41843 +        "&(((char *) (task))[%d]))\n", name, value);
41844 +}
41845 +
41846 +void print_constant(char *name, char *type, int value)
41847 +{
41848 +  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, 
41849 +        value);
41850 +}
41851 +
41852 +void print_tail(void)
41853 +{
41854 +  printf("\n");
41855 +  printf("#endif\n");
41856 +}
41857 Index: linux-2.4.29/arch/um/sys-ia64/Makefile
41858 ===================================================================
41859 --- linux-2.4.29.orig/arch/um/sys-ia64/Makefile 1970-01-01 03:00:00.000000000 +0300
41860 +++ linux-2.4.29/arch/um/sys-ia64/Makefile      2005-05-03 22:28:14.000000000 +0300
41861 @@ -0,0 +1,26 @@
41862 +OBJ = sys.o
41863 +
41864 +OBJS =
41865 +
41866 +all: $(OBJ)
41867 +
41868 +$(OBJ): $(OBJS)
41869 +       rm -f $@
41870 +       $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
41871 +clean:
41872 +       rm -f $(OBJS)
41873 +
41874 +fastdep:
41875 +
41876 +archmrproper:
41877 +
41878 +archclean:
41879 +       rm -f link.ld
41880 +       @$(MAKEBOOT) clean
41881 +
41882 +archdep:
41883 +       @$(MAKEBOOT) dep
41884 +
41885 +modules:
41886 +
41887 +include $(TOPDIR)/Rules.make
41888 Index: linux-2.4.29/arch/um/sys-ppc/Makefile
41889 ===================================================================
41890 --- linux-2.4.29.orig/arch/um/sys-ppc/Makefile  1970-01-01 03:00:00.000000000 +0300
41891 +++ linux-2.4.29/arch/um/sys-ppc/Makefile       2005-05-03 22:28:14.000000000 +0300
41892 @@ -0,0 +1,80 @@
41893 +OBJ = sys.o
41894 +
41895 +.S.o:
41896 +       $(CC) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
41897 +
41898 +OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \
41899 +       ptrace_user.o sysrq.o
41900 +
41901 +EXTRA_AFLAGS := -DCONFIG_ALL_PPC -I. -I$(TOPDIR)/arch/ppc/kernel
41902 +
41903 +all: $(OBJ)
41904 +
41905 +$(OBJ): $(OBJS)
41906 +       rm -f $@
41907 +       $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
41908 +
41909 +ptrace_user.o: ptrace_user.c
41910 +       $(CC) -D__KERNEL__ $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
41911 +
41912 +sigcontext.o: sigcontext.c
41913 +       $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
41914 +
41915 +semaphore.c:
41916 +       rm -f $@
41917 +       ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
41918 +
41919 +checksum.S:
41920 +       rm -f $@
41921 +       ln -s $(TOPDIR)/arch/ppc/lib/$@ $@
41922 +
41923 +mk_defs.c:
41924 +       rm -f $@
41925 +       ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
41926 +
41927 +ppc_defs.head:
41928 +       rm -f $@
41929 +       ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
41930 +
41931 +ppc_defs.h: mk_defs.c ppc_defs.head \
41932 +               $(TOPDIR)/include/asm-ppc/mmu.h \
41933 +               $(TOPDIR)/include/asm-ppc/processor.h \
41934 +               $(TOPDIR)/include/asm-ppc/pgtable.h \
41935 +               $(TOPDIR)/include/asm-ppc/ptrace.h
41936 +#      $(CC) $(CFLAGS) -S mk_defs.c
41937 +       cp ppc_defs.head ppc_defs.h
41938 +# for bk, this way we can write to the file even if it's not checked out
41939 +       echo '#define THREAD 608' >> ppc_defs.h
41940 +       echo '#define PT_REGS 8' >> ppc_defs.h
41941 +       echo '#define CLONE_VM 256' >> ppc_defs.h
41942 +#      chmod u+w ppc_defs.h
41943 +#      grep '^#define' mk_defs.s >> ppc_defs.h
41944 +#      rm mk_defs.s
41945 +
41946 +# the asm link is horrible, and breaks the other targets.  This is also
41947 +# not going to work with parallel makes.
41948 +
41949 +checksum.o: checksum.S
41950 +       rm -f asm
41951 +       ln -s $(TOPDIR)/include/asm-ppc asm
41952 +       $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
41953 +       rm -f asm
41954 +
41955 +misc.o: misc.S ppc_defs.h
41956 +       rm -f asm
41957 +       ln -s $(TOPDIR)/include/asm-ppc asm
41958 +       $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
41959 +       rm -f asm
41960 +
41961 +clean:
41962 +       rm -f $(OBJS)
41963 +       rm -f ppc_defs.h
41964 +       rm -f checksum.S semaphore.c mk_defs.c
41965 +
41966 +fastdep:
41967 +
41968 +dep:
41969 +
41970 +modules:
41971 +
41972 +include $(TOPDIR)/Rules.make
41973 Index: linux-2.4.29/arch/um/sys-ppc/misc.S
41974 ===================================================================
41975 --- linux-2.4.29.orig/arch/um/sys-ppc/misc.S    1970-01-01 03:00:00.000000000 +0300
41976 +++ linux-2.4.29/arch/um/sys-ppc/misc.S 2005-05-03 22:28:14.000000000 +0300
41977 @@ -0,0 +1,116 @@
41978 +/*
41979 + * This file contains miscellaneous low-level functions.
41980 + *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
41981 + *
41982 + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
41983 + * and Paul Mackerras.
41984 + *
41985 + * A couple of functions stolen from arch/ppc/kernel/misc.S for UML
41986 + * by Chris Emerson.
41987 + *
41988 + * This program is free software; you can redistribute it and/or
41989 + * modify it under the terms of the GNU General Public License
41990 + * as published by the Free Software Foundation; either version
41991 + * 2 of the License, or (at your option) any later version.
41992 + *
41993 + */
41994 +
41995 +#include <linux/config.h>
41996 +#include <asm/processor.h>
41997 +#include "ppc_asm.h"
41998 +
41999 +#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
42000 +#define CACHE_LINE_SIZE                16
42001 +#define LG_CACHE_LINE_SIZE     4
42002 +#define MAX_COPY_PREFETCH      1
42003 +#elif !defined(CONFIG_PPC64BRIDGE)
42004 +#define CACHE_LINE_SIZE                32
42005 +#define LG_CACHE_LINE_SIZE     5
42006 +#define MAX_COPY_PREFETCH      4
42007 +#else
42008 +#define CACHE_LINE_SIZE                128
42009 +#define LG_CACHE_LINE_SIZE     7
42010 +#define MAX_COPY_PREFETCH      1
42011 +#endif /* CONFIG_4xx || CONFIG_8xx */
42012 +
42013 +       .text
42014 +
42015 +/*
42016 + * Clear a page using the dcbz instruction, which doesn't cause any
42017 + * memory traffic (except to write out any cache lines which get
42018 + * displaced).  This only works on cacheable memory.
42019 + */
42020 +_GLOBAL(clear_page)
42021 +       li      r0,4096/CACHE_LINE_SIZE
42022 +       mtctr   r0
42023 +#ifdef CONFIG_8xx
42024 +       li      r4, 0
42025 +1:     stw     r4, 0(r3)
42026 +       stw     r4, 4(r3)
42027 +       stw     r4, 8(r3)
42028 +       stw     r4, 12(r3)
42029 +#else
42030 +1:     dcbz    0,r3
42031 +#endif
42032 +       addi    r3,r3,CACHE_LINE_SIZE
42033 +       bdnz    1b
42034 +       blr
42035 +
42036 +/*
42037 + * Copy a whole page.  We use the dcbz instruction on the destination
42038 + * to reduce memory traffic (it eliminates the unnecessary reads of
42039 + * the destination into cache).  This requires that the destination
42040 + * is cacheable.
42041 + */
42042 +#define COPY_16_BYTES          \
42043 +       lwz     r6,4(r4);       \
42044 +       lwz     r7,8(r4);       \
42045 +       lwz     r8,12(r4);      \
42046 +       lwzu    r9,16(r4);      \
42047 +       stw     r6,4(r3);       \
42048 +       stw     r7,8(r3);       \
42049 +       stw     r8,12(r3);      \
42050 +       stwu    r9,16(r3)
42051 +
42052 +_GLOBAL(copy_page)
42053 +       addi    r3,r3,-4
42054 +       addi    r4,r4,-4
42055 +       li      r5,4
42056 +
42057 +#ifndef CONFIG_8xx
42058 +#if MAX_COPY_PREFETCH > 1
42059 +       li      r0,MAX_COPY_PREFETCH
42060 +       li      r11,4
42061 +       mtctr   r0
42062 +11:    dcbt    r11,r4
42063 +       addi    r11,r11,CACHE_LINE_SIZE
42064 +       bdnz    11b
42065 +#else /* MAX_COPY_PREFETCH == 1 */
42066 +       dcbt    r5,r4
42067 +       li      r11,CACHE_LINE_SIZE+4
42068 +#endif /* MAX_COPY_PREFETCH */
42069 +#endif /* CONFIG_8xx */
42070 +
42071 +       li      r0,4096/CACHE_LINE_SIZE
42072 +       mtctr   r0
42073 +1:
42074 +#ifndef CONFIG_8xx
42075 +       dcbt    r11,r4
42076 +       dcbz    r5,r3
42077 +#endif
42078 +       COPY_16_BYTES
42079 +#if CACHE_LINE_SIZE >= 32
42080 +       COPY_16_BYTES
42081 +#if CACHE_LINE_SIZE >= 64
42082 +       COPY_16_BYTES
42083 +       COPY_16_BYTES
42084 +#if CACHE_LINE_SIZE >= 128
42085 +       COPY_16_BYTES
42086 +       COPY_16_BYTES
42087 +       COPY_16_BYTES
42088 +       COPY_16_BYTES
42089 +#endif
42090 +#endif
42091 +#endif
42092 +       bdnz    1b
42093 +       blr
42094 Index: linux-2.4.29/arch/um/sys-ppc/miscthings.c
42095 ===================================================================
42096 --- linux-2.4.29.orig/arch/um/sys-ppc/miscthings.c      1970-01-01 03:00:00.000000000 +0300
42097 +++ linux-2.4.29/arch/um/sys-ppc/miscthings.c   2005-05-03 22:28:14.000000000 +0300
42098 @@ -0,0 +1,53 @@
42099 +#include "linux/threads.h"
42100 +#include "linux/stddef.h"  // for NULL
42101 +#include "linux/elf.h"  // for AT_NULL
42102 +
42103 +/* The following function nicked from arch/ppc/kernel/process.c and
42104 + * adapted slightly */
42105 +/*
42106 + * XXX ld.so expects the auxiliary table to start on
42107 + * a 16-byte boundary, so we have to find it and
42108 + * move it up. :-(
42109 + */
42110 +void shove_aux_table(unsigned long sp)
42111 +{
42112 +       int argc;
42113 +       char *p;
42114 +       unsigned long e;
42115 +       unsigned long aux_start, offset;
42116 +
42117 +       argc = *(int *)sp;
42118 +       sp += sizeof(int) + (argc + 1) * sizeof(char *);
42119 +       /* skip over the environment pointers */
42120 +       do {
42121 +               p = *(char **)sp;
42122 +               sp += sizeof(char *);
42123 +       } while (p != NULL);
42124 +       aux_start = sp;
42125 +       /* skip to the end of the auxiliary table */
42126 +       do {
42127 +               e = *(unsigned long *)sp;
42128 +               sp += 2 * sizeof(unsigned long);
42129 +       } while (e != AT_NULL);
42130 +       offset = ((aux_start + 15) & ~15) - aux_start;
42131 +       if (offset != 0) {
42132 +               do {
42133 +                       sp -= sizeof(unsigned long);
42134 +                       e = *(unsigned long *)sp;
42135 +                       *(unsigned long *)(sp + offset) = e;
42136 +               } while (sp > aux_start);
42137 +       }
42138 +}
42139 +/* END stuff taken from arch/ppc/kernel/process.c */
42140 +
42141 +
42142 +/*
42143 + * Overrides for Emacs so that we follow Linus's tabbing style.
42144 + * Emacs will notice this stuff at the end of the file and automatically
42145 + * adjust the settings for this buffer only.  This must remain at the end
42146 + * of the file.
42147 + * ---------------------------------------------------------------------------
42148 + * Local variables:
42149 + * c-file-style: "linux"
42150 + * End:
42151 + */
42152 Index: linux-2.4.29/arch/um/sys-ppc/ptrace.c
42153 ===================================================================
42154 --- linux-2.4.29.orig/arch/um/sys-ppc/ptrace.c  1970-01-01 03:00:00.000000000 +0300
42155 +++ linux-2.4.29/arch/um/sys-ppc/ptrace.c       2005-05-03 22:28:14.000000000 +0300
42156 @@ -0,0 +1,28 @@
42157 +#include "linux/sched.h"
42158 +#include "asm/ptrace.h"
42159 +
42160 +int putreg(struct task_struct *child, unsigned long regno, 
42161 +                 unsigned long value)
42162 +{
42163 +       child->thread.process_regs.regs[regno >> 2] = value;
42164 +       return 0;
42165 +}
42166 +
42167 +unsigned long getreg(struct task_struct *child, unsigned long regno)
42168 +{
42169 +       unsigned long retval = ~0UL;
42170 +
42171 +       retval &= child->thread.process_regs.regs[regno >> 2];
42172 +       return retval;
42173 +}
42174 +
42175 +/*
42176 + * Overrides for Emacs so that we follow Linus's tabbing style.
42177 + * Emacs will notice this stuff at the end of the file and automatically
42178 + * adjust the settings for this buffer only.  This must remain at the end
42179 + * of the file.
42180 + * ---------------------------------------------------------------------------
42181 + * Local variables:
42182 + * c-file-style: "linux"
42183 + * End:
42184 + */
42185 Index: linux-2.4.29/arch/um/sys-ppc/ptrace_user.c
42186 ===================================================================
42187 --- linux-2.4.29.orig/arch/um/sys-ppc/ptrace_user.c     1970-01-01 03:00:00.000000000 +0300
42188 +++ linux-2.4.29/arch/um/sys-ppc/ptrace_user.c  2005-05-03 22:28:14.000000000 +0300
42189 @@ -0,0 +1,40 @@
42190 +#include <sys/ptrace.h>
42191 +#include <errno.h>
42192 +#include <asm/ptrace.h>
42193 +#include "sysdep/ptrace.h"
42194 +
42195 +int ptrace_getregs(long pid, unsigned long *regs_out)
42196 +{
42197 +    int i;
42198 +    for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
42199 +       errno = 0;
42200 +       regs_out->regs[i] = ptrace(PTRACE_PEEKUSER, pid, i*4, 0);
42201 +       if (errno) {
42202 +           return -errno;
42203 +       }
42204 +    }
42205 +    return 0;
42206 +}
42207 +
42208 +int ptrace_setregs(long pid, unsigned long *regs_in)
42209 +{
42210 +    int i;
42211 +    for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
42212 +       if (i != 34 /* FIXME: PT_ORIG_R3 */ && i <= PT_MQ) {
42213 +           if (ptrace(PTRACE_POKEUSER, pid, i*4, regs_in->regs[i]) < 0) {
42214 +               return -errno;
42215 +           }
42216 +       }
42217 +    }
42218 +    return 0;
42219 +}
42220 +/*
42221 + * Overrides for Emacs so that we follow Linus's tabbing style.
42222 + * Emacs will notice this stuff at the end of the file and automatically
42223 + * adjust the settings for this buffer only.  This must remain at the end
42224 + * of the file.
42225 + * ---------------------------------------------------------------------------
42226 + * Local variables:
42227 + * c-file-style: "linux"
42228 + * End:
42229 + */
42230 Index: linux-2.4.29/arch/um/sys-ppc/sigcontext.c
42231 ===================================================================
42232 --- linux-2.4.29.orig/arch/um/sys-ppc/sigcontext.c      1970-01-01 03:00:00.000000000 +0300
42233 +++ linux-2.4.29/arch/um/sys-ppc/sigcontext.c   2005-05-03 22:28:14.000000000 +0300
42234 @@ -0,0 +1,15 @@
42235 +#include "asm/ptrace.h"
42236 +#include "asm/sigcontext.h"
42237 +#include "sysdep/ptrace.h"
42238 +#include "user_util.h"
42239 +
42240 +/*
42241 + * Overrides for Emacs so that we follow Linus's tabbing style.
42242 + * Emacs will notice this stuff at the end of the file and automatically
42243 + * adjust the settings for this buffer only.  This must remain at the end
42244 + * of the file.
42245 + * ---------------------------------------------------------------------------
42246 + * Local variables:
42247 + * c-file-style: "linux"
42248 + * End:
42249 + */
42250 Index: linux-2.4.29/arch/um/sys-ppc/sysrq.c
42251 ===================================================================
42252 --- linux-2.4.29.orig/arch/um/sys-ppc/sysrq.c   1970-01-01 03:00:00.000000000 +0300
42253 +++ linux-2.4.29/arch/um/sys-ppc/sysrq.c        2005-05-03 22:28:14.000000000 +0300
42254 @@ -0,0 +1,43 @@
42255 +/* 
42256 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
42257 + * Licensed under the GPL
42258 + */
42259 +
42260 +#include "linux/kernel.h"
42261 +#include "linux/smp.h"
42262 +#include "asm/ptrace.h"
42263 +#include "sysrq.h"
42264 +
42265 +void show_regs(struct pt_regs_subarch *regs)
42266 +{
42267 +       printk("\n");
42268 +       printk("show_regs(): insert regs here.\n");
42269 +#if 0
42270 +        printk("\n");
42271 +        printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs, regs->eip,
42272 +              smp_processor_id());
42273 +        if (regs->xcs & 3)
42274 +                printk(" ESP: %04x:%08lx",0xffff & regs->xss, regs->esp);
42275 +        printk(" EFLAGS: %08lx\n", regs->eflags);
42276 +        printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
42277 +                regs->eax, regs->ebx, regs->ecx, regs->edx);
42278 +        printk("ESI: %08lx EDI: %08lx EBP: %08lx",
42279 +                regs->esi, regs->edi, regs->ebp);
42280 +        printk(" DS: %04x ES: %04x\n",
42281 +                0xffff & regs->xds, 0xffff & regs->xes);
42282 +#endif
42283 +
42284 +        show_trace(&regs->gpr[1]);
42285 +}
42286 +
42287 +
42288 +/*
42289 + * Overrides for Emacs so that we follow Linus's tabbing style.
42290 + * Emacs will notice this stuff at the end of the file and automatically
42291 + * adjust the settings for this buffer only.  This must remain at the end
42292 + * of the file.
42293 + * ---------------------------------------------------------------------------
42294 + * Local variables:
42295 + * c-file-style: "linux"
42296 + * End:
42297 + */
42298 Index: linux-2.4.29/arch/um/util/Makefile
42299 ===================================================================
42300 --- linux-2.4.29.orig/arch/um/util/Makefile     1970-01-01 03:00:00.000000000 +0300
42301 +++ linux-2.4.29/arch/um/util/Makefile  2005-05-03 22:28:14.000000000 +0300
42302 @@ -0,0 +1,26 @@
42303 +ALL = mk_task mk_constants
42304 +
42305 +all : $(ALL)
42306 +
42307 +mk_task : mk_task_user.o mk_task_kern.o
42308 +       $(HOSTCC) -o mk_task mk_task_user.o mk_task_kern.o
42309 +
42310 +mk_task_user.o : mk_task_user.c
42311 +       $(HOSTCC) -c $< 
42312 +
42313 +mk_task_kern.o : mk_task_kern.c
42314 +       $(HOSTCC) $(CFLAGS) -c $< 
42315 +
42316 +mk_constants : mk_constants_user.o mk_constants_kern.o
42317 +       $(HOSTCC) -o mk_constants mk_constants_user.o mk_constants_kern.o
42318 +
42319 +mk_constants_user.o : mk_constants_user.c
42320 +       $(HOSTCC) -c $< 
42321 +
42322 +mk_constants_kern.o : mk_constants_kern.c
42323 +       $(HOSTCC) $(CFLAGS) -c $< 
42324 +
42325 +clean :
42326 +       $(RM) $(ALL) *.o *~
42327 +
42328 +archmrproper : clean
42329 Index: linux-2.4.29/arch/um/util/mk_constants_kern.c
42330 ===================================================================
42331 --- linux-2.4.29.orig/arch/um/util/mk_constants_kern.c  1970-01-01 03:00:00.000000000 +0300
42332 +++ linux-2.4.29/arch/um/util/mk_constants_kern.c       2005-05-03 22:28:14.000000000 +0300
42333 @@ -0,0 +1,25 @@
42334 +#include "linux/kernel.h"
42335 +#include "linux/stringify.h"
42336 +#include "asm/page.h"
42337 +
42338 +extern void print_head(void);
42339 +extern void print_constant_str(char *name, char *value);
42340 +extern void print_constant_int(char *name, int value);
42341 +extern void print_tail(void);
42342 +
42343 +int main(int argc, char **argv)
42344 +{
42345 +  print_head();
42346 +  print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
42347 +
42348 +  print_constant_str("UM_KERN_EMERG", KERN_EMERG);
42349 +  print_constant_str("UM_KERN_ALERT", KERN_ALERT);
42350 +  print_constant_str("UM_KERN_CRIT", KERN_CRIT);
42351 +  print_constant_str("UM_KERN_ERR", KERN_ERR);
42352 +  print_constant_str("UM_KERN_WARNING", KERN_WARNING);
42353 +  print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
42354 +  print_constant_str("UM_KERN_INFO", KERN_INFO);
42355 +  print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
42356 +  print_tail();
42357 +  return(0);
42358 +}
42359 Index: linux-2.4.29/arch/um/util/mk_constants_user.c
42360 ===================================================================
42361 --- linux-2.4.29.orig/arch/um/util/mk_constants_user.c  1970-01-01 03:00:00.000000000 +0300
42362 +++ linux-2.4.29/arch/um/util/mk_constants_user.c       2005-05-03 22:28:14.000000000 +0300
42363 @@ -0,0 +1,28 @@
42364 +#include <stdio.h>
42365 +
42366 +void print_head(void)
42367 +{
42368 +  printf("/*\n");
42369 +  printf(" * Generated by mk_constants\n");
42370 +  printf(" */\n");
42371 +  printf("\n");
42372 +  printf("#ifndef __UM_CONSTANTS_H\n");
42373 +  printf("#define __UM_CONSTANTS_H\n");
42374 +  printf("\n");
42375 +}
42376 +
42377 +void print_constant_str(char *name, char *value)
42378 +{
42379 +  printf("#define %s \"%s\"\n", name, value);
42380 +}
42381 +
42382 +void print_constant_int(char *name, int value)
42383 +{
42384 +  printf("#define %s %d\n", name, value);
42385 +}
42386 +
42387 +void print_tail(void)
42388 +{
42389 +  printf("\n");
42390 +  printf("#endif\n");
42391 +}
42392 Index: linux-2.4.29/arch/um/util/mk_task_kern.c
42393 ===================================================================
42394 --- linux-2.4.29.orig/arch/um/util/mk_task_kern.c       1970-01-01 03:00:00.000000000 +0300
42395 +++ linux-2.4.29/arch/um/util/mk_task_kern.c    2005-05-03 22:28:14.000000000 +0300
42396 @@ -0,0 +1,17 @@
42397 +#include "linux/sched.h"
42398 +#include "linux/stddef.h"
42399 +
42400 +extern void print(char *name, char *type, int offset);
42401 +extern void print_ptr(char *name, char *type, int offset);
42402 +extern void print_head(void);
42403 +extern void print_tail(void);
42404 +
42405 +int main(int argc, char **argv)
42406 +{
42407 +  print_head();
42408 +  print_ptr("TASK_REGS", "union uml_pt_regs", 
42409 +           offsetof(struct task_struct, thread.regs));
42410 +  print("TASK_PID", "int", offsetof(struct task_struct, pid));
42411 +  print_tail();
42412 +  return(0);
42413 +}
42414 Index: linux-2.4.29/arch/um/util/mk_task_user.c
42415 ===================================================================
42416 --- linux-2.4.29.orig/arch/um/util/mk_task_user.c       1970-01-01 03:00:00.000000000 +0300
42417 +++ linux-2.4.29/arch/um/util/mk_task_user.c    2005-05-03 22:28:14.000000000 +0300
42418 @@ -0,0 +1,30 @@
42419 +#include <stdio.h>
42420 +
42421 +void print(char *name, char *type, int offset)
42422 +{
42423 +  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
42424 +        offset);
42425 +}
42426 +
42427 +void print_ptr(char *name, char *type, int offset)
42428 +{
42429 +  printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
42430 +        offset);
42431 +}
42432 +
42433 +void print_head(void)
42434 +{
42435 +  printf("/*\n");
42436 +  printf(" * Generated by mk_task\n");
42437 +  printf(" */\n");
42438 +  printf("\n");
42439 +  printf("#ifndef __TASK_H\n");
42440 +  printf("#define __TASK_H\n");
42441 +  printf("\n");
42442 +}
42443 +
42444 +void print_tail(void)
42445 +{
42446 +  printf("\n");
42447 +  printf("#endif\n");
42448 +}
42449 Index: linux-2.4.29/CREDITS
42450 ===================================================================
42451 --- linux-2.4.29.orig/CREDITS   2005-05-03 21:08:24.000000000 +0300
42452 +++ linux-2.4.29/CREDITS        2005-05-03 22:28:14.000000000 +0300
42453 @@ -434,6 +434,7 @@
42454  E: lars@nocrew.org
42455  W: http://lars.nocrew.org/
42456  D: dsp56k device driver
42457 +D: ptrace proxy in user mode kernel port
42458  S: Kopmansg 2
42459  S: 411 13  Goteborg
42460  S: Sweden
42461 @@ -727,7 +728,7 @@
42462  E: jdike@karaya.com
42463  W: http://user-mode-linux.sourceforge.net
42464  D: User mode kernel port
42465 -S: RR1 Box 67C
42466 +S: 375 Tubbs Hill Rd
42467  S: Deering NH 03244
42468  S: USA
42469  
42470 Index: linux-2.4.29/Documentation/Configure.help
42471 ===================================================================
42472 --- linux-2.4.29.orig/Documentation/Configure.help      2005-05-03 21:09:27.000000000 +0300
42473 +++ linux-2.4.29/Documentation/Configure.help   2005-05-03 23:55:57.615290736 +0300
42474 @@ -16184,6 +16184,63 @@
42475    The module will be called speedtch.o. If you want to compile it as
42476    a module, say M here and read <file:Documentation/modules.txt>.
42477  
42478 +Support for /proc/mm
42479 +CONFIG_PROC_MM
42480 +  Enables support for address space separation through /proc/mm.
42481 +  A host kernel needs to have this enabled in order for UML to
42482 +  run in skas mode.  UML kernels do not need to have this option
42483 +  unless they will host sub-UMLs.
42484 +
42485 +  If you don't know what this does just say Y.
42486 +
42487 +Separate Kernel Address Space support
42488 +CONFIG_MODE_SKAS
42489 +  This option controls whether skas (separate kernel address space)
42490 +  support is compiled in.  If you have applied the skas patch to the
42491 +  host and enabled support for /proc/mm in the host kernel, then you
42492 +  certainly want to say Y here (and consider saying N to
42493 +  CONFIG_MODE_TT).  Otherwise, it is safe to say Y.  Disabling this
42494 +  option will shrink the UML binary slightly.
42495 +
42496 +Tracing thread support
42497 +CONFIG_MODE_TT
42498 +  This option controls whether tracing thread support is compiled
42499 +  into UML.  Normally, this should be set to Y.  If you intend to
42500 +  use only skas mode (and the host has the skas patch applied to it),
42501 +  then it is OK to say N here.
42502 +
42503 +Force a static link
42504 +CONFIG_STATIC_LINK
42505 +  If CONFIG_MODE_TT is disabled, then this option gives you the ability
42506 +  to force a static link of UML.  Normally, if only skas mode is built
42507 +  in to UML, it will be linked as a shared binary.  This is inconvenient
42508 +  for use in a chroot jail.  So, if you intend to run UML inside a
42509 +  chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
42510 +  here.
42511 +
42512 +2G/2G host address space split
42513 +CONFIG_HOST_2G_2G
42514 +  Most Linux machines are configured so that the kernel occupies the
42515 +  upper 1G of the 4G address space and processes use the lower 3G.
42516 +  However, some machine are configured with a 2G/2G split, with the
42517 +  kernel occupying the upper 2G and processes using the lower 2G.
42518 +
42519 +  To allow UML to run on a such host you have to say Y here. N should be
42520 +  a safe choice most of the time.
42521 +
42522 +Kernel stack size order
42523 +CONFIG_KERNEL_STACK_ORDER
42524 +  This option determines the size of UML kernel stacks.  They will
42525 +  be 1 << order pages.  The default is OK unless you're running Valgrind
42526 +  on UML, in which case, set this to 3.
42527 +
42528 +UML ubd block driver
42529 +CONFIG_BLK_DEV_UBD
42530 +  The User-Mode Linux port includes a driver called UBD which will let
42531 +  you access arbitrary files on the host computer as block devices.
42532 +  Unless you know that you do not need such virtual block devices say
42533 +  Y here.
42534 +
42535  CONFIG_USB_GADGET
42536    USB is a master/slave protocol, organized with one master
42537    host (such as a PC) controlling up to 127 peripheral devices.
42538 @@ -16289,17 +16346,15 @@
42539  
42540  Always do synchronous disk IO for UBD
42541  CONFIG_BLK_DEV_UBD_SYNC
42542 -  The User-Mode Linux port includes a driver called UBD which will let
42543 -  you access arbitrary files on the host computer as block devices.
42544 -  Writes to such a block device are not immediately written to the
42545 -  host's disk; this may cause problems if, for example, the User-Mode
42546 -  Linux 'Virtual Machine' uses a journalling file system and the host
42547 -  computer crashes.
42548 +  Writes to the virtual block device are not immediately written to the host's
42549 +  disk; this may cause problems if, for example, the User-Mode Linux
42550 +  'Virtual Machine' uses a journalling filesystem and the host computer
42551 +  crashes.
42552  
42553    Synchronous operation (i.e. always writing data to the host's disk
42554    immediately) is configurable on a per-UBD basis by using a special
42555    kernel command line option.  Alternatively, you can say Y here to
42556 -  turn on synchronous operation by default for all block.
42557 +  turn on synchronous operation by default for all block devices.
42558  
42559    If you're running a journalling file system (like reiserfs, for
42560    example) in your virtual machine, you will want to say Y here.  If
42561 @@ -16311,6 +16366,7 @@
42562  CONFIG_PT_PROXY
42563    This option enables a debugging interface which allows gdb to debug
42564    the kernel without needing to actually attach to kernel threads.
42565 +  CONFIG_XTERM_CHAN must be enabled in order to enable CONFIG_PT_PROXY.
42566    If you want to do kernel debugging, say Y here; otherwise say N.
42567  
42568  Management console
42569 @@ -16357,6 +16413,9 @@
42570    See <http://user-mode-linux.sourceforge.net/gprof.html> for more
42571    details.
42572  
42573 +  This option requires that CONFIG_MODE_TT be disabled, as UML will
42574 +  not build with both enabled.
42575 +
42576    If you're involved in UML kernel development and want to use gprof,
42577    say Y.  If you're unsure, say N.
42578  
42579 @@ -16380,6 +16439,19 @@
42580    If you'd like to be able to work with files stored on the host, 
42581    say Y or M here; otherwise say N.
42582  
42583 +HoneyPot ProcFS
42584 +CONFIG_HPPFS
42585 +  hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
42586 +  entries to be overridden, removed, or fabricated from the host.
42587 +  Its purpose is to allow a UML to appear to be a physical machine
42588 +  by removing or changing anything in /proc which gives away the
42589 +  identity of a UML.
42590 +
42591 +  See <http://user-mode-linux.sf.net/hppfs.html> for more information.
42592 +
42593 +  You only need this if you are setting up a UML honeypot.  Otherwise,
42594 +  it is safe to say 'N' here.
42595 +
42596  Example IO Memory driver
42597  CONFIG_MMAPPER
42598    The User-Mode Linux port can provide support for IO Memory
42599 @@ -16395,6 +16467,21 @@
42600    If you'd like to be able to provide a simulated IO port space for
42601    User-Mode Linux processes, say Y.  If unsure, say N.
42602  
42603 +Anonymous Memory support
42604 +CONFIG_DEV_ANON
42605 +  Don't ask. Just say Y.
42606 +
42607 +Support for software watchdog inside UML
42608 +CONFIG_UML_WATCHDOG
42609 +  Support for a virtual hardware watchdog. It's safe to say N here.
42610 +
42611 +COW block device
42612 +CONFIG_COW
42613 +  This is a layered driver which sits above two other block devices.
42614 +  One is read-only, and the other is a read-write layer which stores
42615 +  all changes.  This provides the illusion that the read-only layer
42616 +  can be mounted read-write and changed.
42617 +
42618  Virtual Serial Line
42619  CONFIG_SSL
42620    The User-Mode Linux environment allows you to create virtual serial
42621 @@ -16505,26 +16592,197 @@
42622  
42623  SLIP transport
42624  CONFIG_UML_NET_SLIP
42625 -  The Slip User-Mode Linux network transport allows a running UML to
42626 +  The slip User-Mode Linux network transport allows a running UML to
42627    network with its host over a point-to-point link.  Unlike Ethertap,
42628    which can carry any Ethernet frame (and hence even non-IP packets),
42629 -  the Slip transport can only carry IP packets.
42630 +  the slip transport can only carry IP packets.
42631  
42632 -  To use this, your host must support Slip devices.
42633 +  To use this, your host must support slip devices.
42634  
42635    For more information, see
42636    <http://user-mode-linux.sourceforge.net/networking.html>.  That site
42637 -  has examples of the UML command line to use to enable Slip
42638 +  has examples of the UML command line to use to enable slip
42639    networking, and details of a few quirks with it.
42640  
42641 -  The Ethertap Transport is preferred over Slip because of its
42642 -  limitation.  If you prefer Slip, however, say Y here.  Otherwise
42643 +  The Ethertap Transport is preferred over slip because of its
42644 +  limitations.  If you prefer slip, however, say Y here.  Otherwise
42645    choose the Multicast transport (to network multiple UMLs on 
42646    multiple hosts), Ethertap (to network with the host and the
42647    outside world), and/or the Daemon transport (to network multiple
42648    UMLs on a single host).  You may choose more than one without
42649    conflict.  If you don't need UML networking, say N.
42650  
42651 +SLiRP transport
42652 +CONFIG_UML_NET_SLIRP
42653 +  The SLiRP User-Mode Linux network transport allows a running UML
42654 +  to network by invoking a program that can handle SLIP encapsulated
42655 +  packets.  This is commonly (but not limited to) the application
42656 +  known as SLiRP, a program that can re-socket IP packets back onto
42657 +  the host on which it is run.  Only IP packets are supported,
42658 +  unlike other network transports that can handle all Ethernet
42659 +  frames.  In general, slirp allows the UML the same IP connectivity
42660 +  to the outside world that the host user is permitted, and unlike
42661 +  other transports, SLiRP works without the need of root level
42662 +  privleges, setuid binaries, or SLIP devices on the host.  This
42663 +  also means not every type of connection is possible, but most
42664 +  situations can be accomodated with carefully crafted slirp
42665 +  commands that can be passed along as part of the network device's
42666 +  setup string.  The effect of this transport on the UML is similar
42667 +  that of a host behind a firewall that masquerades all network
42668 +  connections passing through it (but is less secure).
42669 +
42670 +  To use this you should first have slirp compiled somewhere
42671 +  accessible on the host, and have read its documentation.  If you
42672 +  don't need UML networking, say N.
42673 +
42674 +  Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
42675 +
42676 +pcap transport
42677 +CONFIG_UML_NET_PCAP
42678 + The pcap transport makes a pcap packet stream on the host look
42679 +  like an ethernet device inside UML.  This is useful for making
42680 +  UML act as a network monitor for the host.  You must have libcap
42681 +  installed in order to build the pcap transport into UML.
42682 +
42683 +  For more information, see
42684 +  <http://user-mode-linux.sourceforge.net/networking.html>  That site
42685 +  has examples of the UML command line to use to enable this option.
42686 +
42687 +  If you intend to use UML as a network monitor for the host, say
42688 +  Y here.  Otherwise, say N.
42689 +
42690 +Default main console channel initialization
42691 +CONFIG_CON_ZERO_CHAN
42692 +  This is the string describing the channel to which the main console
42693 +  will be attached by default.  This value can be overridden from the
42694 +  command line.  The default value is "fd:0,fd:1", which attaches the
42695 +  main console to stdin and stdout.
42696 +  It is safe to leave this unchanged.
42697 +
42698 +Default console channel initialization
42699 +CONFIG_CON_CHAN
42700 +  This is the string describing the channel to which all consoles
42701 +  except the main console will be attached by default.  This value can
42702 +  be overridden from the command line.  The default value is "xterm",
42703 +  which brings them up in xterms.
42704 +  It is safe to leave this unchanged, although you may wish to change
42705 +  this if you expect the UML that you build to be run in environments
42706 +  which don't have X or xterm available.
42707 +
42708 +Default serial line channel initialization
42709 +CONFIG_SSL_CHAN
42710 +  This is the string describing the channel to which the serial lines
42711 +  will be attached by default.  This value can be overridden from the
42712 +  command line.  The default value is "pty", which attaches them to
42713 +  traditional pseudo-terminals.
42714 +  It is safe to leave this unchanged, although you may wish to change
42715 +  this if you expect the UML that you build to be run in environments
42716 +  which don't have a set of /dev/pty* devices.
42717 +
42718 +Nesting level
42719 +CONFIG_NEST_LEVEL
42720 +  This is set to the number of layers of UMLs that this UML will be run
42721 +  in.  Normally, this is zero, meaning that it will run directly on the
42722 +  host.  Setting it to one will build a UML that can run inside a UML
42723 +  that is running on the host.  Generally, if you intend this UML to run
42724 +  inside another UML, set CONFIG_NEST_LEVEL to one more than the host UML.
42725 +  Note that if the hosting UML has its CONFIG_KERNEL_HALF_GIGS set to 
42726 +  greater than one, then the guest UML should have its CONFIG_NEST_LEVEL 
42727 +  set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
42728 +  Only change this if you are running nested UMLs.
42729 +
42730 +Kernel address space size (in .5G units)
42731 +CONFIG_KERNEL_HALF_GIGS
42732 +  This determines the amount of address space that UML will allocate for
42733 +  its own, measured in half Gigabyte units.  The default is 1.
42734 +  Change this only if you need to boot UML with an unusually large amount
42735 +  of physical memory.
42736 +
42737 +UML sound support
42738 +CONFIG_UML_SOUND
42739 +  This option enables UML sound support.  If enabled, it will pull in
42740 +  soundcore and the UML hostaudio relay, which acts as a intermediary
42741 +  between the host's dsp and mixer devices and the UML sound system.
42742 +  It is safe to say 'Y' here.
42743 +
42744 +UML SMP support
42745 +CONFIG_UML_SMP
42746 +  This option enables UML SMP support.  UML implements virtual SMP by
42747 +  allowing as many processes to run simultaneously on the host as
42748 +  there are virtual processors configured.  Obviously, if the host is
42749 +  a uniprocessor, those processes will timeshare, but, inside UML,
42750 +  will appear to be running simultaneously.  If the host is a
42751 +  multiprocessor, then UML processes may run simultaneously, depending
42752 +  on the host scheduler.
42753 +  CONFIG_SMP will be set to whatever this option is set to.
42754 +  It is safe to leave this unchanged.
42755 +
42756 +file descriptor channel support
42757 +CONFIG_FD_CHAN
42758 +  This option enables support for attaching UML consoles and serial
42759 +  lines to already set up file descriptors.  Generally, the main
42760 +  console is attached to file descriptors 0 and 1 (stdin and stdout),
42761 +  so it would be wise to leave this enabled unless you intend to
42762 +  attach it to some other host device.
42763 +
42764 +null device channel support
42765 +CONFIG_NULL_CHAN
42766 +  This option enables support for attaching UML consoles and serial
42767 +  lines to a device similar to /dev/null.  Data written to it disappears
42768 +  and there is never any data to be read.
42769 +
42770 +port channel support
42771 +CONFIG_PORT_CHAN
42772 +  This option enables support for attaching UML consoles and serial
42773 +  lines to host portals.  They may be accessed with 'telnet <host>
42774 +  <port number>'.  Any number of consoles and serial lines may be
42775 +  attached to a single portal, although what UML device you get when
42776 +  you telnet to that portal will be unpredictable.
42777 +  It is safe to say 'Y' here.
42778 +
42779 +pty channel support
42780 +CONFIG_PTY_CHAN
42781 +  This option enables support for attaching UML consoles and serial
42782 +  lines to host pseudo-terminals.  Access to both traditional
42783 +  pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled
42784 +  with this option.  The assignment of UML devices to host devices
42785 +  will be announced in the kernel message log.
42786 +  It is safe to say 'Y' here.
42787 +
42788 +tty channel support
42789 +CONFIG_TTY_CHAN
42790 +  This option enables support for attaching UML consoles and serial
42791 +  lines to host terminals.  Access to both virtual consoles
42792 +  (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and
42793 +  /dev/pts/*) are controlled by this option.
42794 +  It is safe to say 'Y' here.
42795 +
42796 +xterm channel support
42797 +CONFIG_XTERM_CHAN
42798 +  This option enables support for attaching UML consoles and serial
42799 +  lines to xterms.  Each UML device so assigned will be brought up in
42800 +  its own xterm.
42801 +  If you disable this option, then CONFIG_PT_PROXY will be disabled as
42802 +  well, since UML's gdb currently requires an xterm.
42803 +  It is safe to say 'Y' here.
42804 +
42805 +tty logging
42806 +CONFIG_TTY_LOG
42807 +  This option enables logging of all data going through pseudo-terminals
42808 +  to the host.  This is primarily useful for honeypots, where you want
42809 +  secure keystroke logging that can't be detected or disabled by root.
42810 +  Say 'N' unless you are setting up a UML honeypot or otherwise know that
42811 +  you want this option.
42812 +
42813 +UML real-time clock support
42814 +CONFIG_UML_REAL_TIME_CLOCK
42815 +  This option ties the UML clock to the host clock, so that time passes at
42816 +  the same rate as on the host, regardless of how much CPU time the UML is
42817 +  getting.  This should normally be enabled.  The exception would be if you're
42818 +  debugging UML.  In this case, time spent staring at the debugger with UML
42819 +  stopped will cause lots of timer ticks to be backed up, and UML will spent
42820 +  lots of time calling the timer when it is finally continued.
42821 +
42822  Microtek USB scanner support
42823  CONFIG_USB_MICROTEK
42824    Say Y here if you want support for the Microtek X6USB and
42825 Index: linux-2.4.29/drivers/char/Makefile
42826 ===================================================================
42827 --- linux-2.4.29.orig/drivers/char/Makefile     2005-05-03 21:09:35.000000000 +0300
42828 +++ linux-2.4.29/drivers/char/Makefile  2005-05-03 22:28:14.000000000 +0300
42829 @@ -114,6 +114,12 @@
42830    endif
42831  endif
42832  
42833 +ifeq ($(ARCH),um)
42834 +  KEYMAP   =
42835 +  KEYBD    =
42836 +  CONSOLE  =
42837 +endif
42838 +
42839  ifeq ($(ARCH),sh)
42840    KEYMAP   =
42841    KEYBD    =
42842 Index: linux-2.4.29/drivers/char/mem.c
42843 ===================================================================
42844 --- linux-2.4.29.orig/drivers/char/mem.c        2005-05-03 21:07:25.000000000 +0300
42845 +++ linux-2.4.29/drivers/char/mem.c     2005-05-03 22:28:14.000000000 +0300
42846 @@ -220,7 +220,7 @@
42847         ssize_t read = 0;
42848         ssize_t virtr = 0;
42849         char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
42850 -               
42851 +
42852         if (p < (unsigned long) high_memory) {
42853                 read = count;
42854                 if (count > (unsigned long) high_memory - p)
42855 @@ -292,6 +292,8 @@
42856                         wrote = (unsigned long) high_memory - p;
42857  
42858                 wrote = do_write_mem(file, (void*)p, p, buf, wrote, ppos);
42859 +               if(wrote < 0)
42860 +                       return(wrote);
42861  
42862                 p += wrote;
42863                 buf += wrote;
42864 @@ -664,6 +666,8 @@
42865         write:          write_full,
42866  };
42867  
42868 +extern struct file_operations anon_file_operations;
42869 +
42870  static int memory_open(struct inode * inode, struct file * filp)
42871  {
42872         switch (MINOR(inode->i_rdev)) {
42873 @@ -693,6 +697,9 @@
42874                 case 9:
42875                         filp->f_op = &urandom_fops;
42876                         break;
42877 +               case 10:
42878 +                       filp->f_op = &anon_file_operations;
42879 +                       break;
42880                 default:
42881                         return -ENXIO;
42882         }
42883 @@ -719,7 +726,8 @@
42884         {5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
42885         {7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
42886         {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
42887 -       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops}
42888 +       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops},
42889 +       {10, "anon", S_IRUGO | S_IWUSR,             &anon_file_operations},
42890      };
42891      int i;
42892  
42893 Index: linux-2.4.29/drivers/char/n_tty.c
42894 ===================================================================
42895 --- linux-2.4.29.orig/drivers/char/n_tty.c      2005-05-03 21:05:08.000000000 +0300
42896 +++ linux-2.4.29/drivers/char/n_tty.c   2005-05-03 22:28:14.000000000 +0300
42897 @@ -25,9 +25,11 @@
42898   *             who actually finally proved there really was a race.
42899   *
42900   * 2002/03/18   Implemented n_tty_wakeup to send SIGIO POLL_OUTs to
42901 - *             waiting writing processes-Sapan Bhatia <sapan@corewars.org>.
42902 - *             Also fixed a bug in BLOCKING mode where write_chan returns
42903 - *             EAGAIN
42904 + *             waiting writing processes-Sapan Bhatia <sapan@corewars.org>
42905 + *
42906 + * 2002/03/19   Fixed write_chan to stay put if console driver returns
42907 + *              EAGAIN and not return since it returns an EAGAIN in a 
42908 + *             non-blocking operation-Sapan Bhatia <sapan@corewars.org>
42909   */
42910  
42911  #include <linux/types.h>
42912 @@ -1393,9 +1395,9 @@
42913                 if (O_OPOST(tty) && !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
42914                         while (nr > 0) {
42915                                 ssize_t num = opost_block(tty, b, nr);
42916 -                               if (num < 0) {
42917 -                                       if (num == -EAGAIN)
42918 -                                               break;
42919 +                               if (num < 0){
42920 +                                       if(num == -EAGAIN)
42921 +                                               break;
42922                                         retval = num;
42923                                         goto break_out;
42924                                 }
42925 Index: linux-2.4.29/drivers/char/tty_io.c
42926 ===================================================================
42927 --- linux-2.4.29.orig/drivers/char/tty_io.c     2005-05-03 21:07:50.000000000 +0300
42928 +++ linux-2.4.29/drivers/char/tty_io.c  2005-05-03 22:28:14.000000000 +0300
42929 @@ -967,6 +967,23 @@
42930         tty_wakeup(tty);
42931  }
42932  
42933 +#ifdef CONFIG_TTY_LOG
42934 +
42935 +int (*open_log)(void *, void *) = NULL;
42936 +int (*write_log)(int, const char *, int, void *, int) = NULL;
42937 +void (*close_log)(int, void *) = NULL;
42938 +
42939 +void register_tty_logger(int (*opener)(void *, void *),
42940 +                        int (*writer)(int, const char *, int, void *, int),
42941 +                        void (*closer)(int, void *))
42942 +{
42943 +        open_log = opener;
42944 +       write_log = writer;
42945 +       close_log = closer;
42946 +}
42947 +
42948 +#endif
42949 +
42950  static ssize_t tty_read(struct file * file, char * buf, size_t count, 
42951                         loff_t *ppos)
42952  {
42953 @@ -1012,8 +1029,13 @@
42954                 i = -EIO;
42955         tty_ldisc_deref(ld);
42956         unlock_kernel();
42957 -       if (i > 0)
42958 +       if (i > 0){
42959                 inode->i_atime = CURRENT_TIME;
42960 +#ifdef CONFIG_TTY_LOG
42961 +               if((tty->log_fd >= 0) && (write_log != NULL))
42962 +                       (*write_log)(tty->log_fd, buf, i, tty, 1);
42963 +#endif
42964 +       }
42965         return i;
42966  }
42967  
42968 @@ -1067,6 +1089,10 @@
42969         if (written) {
42970                 file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
42971                 ret = written;
42972 +#ifdef CONFIG_TTY_LOG
42973 +               if((tty->log_fd >= 0) && (write_log != NULL))
42974 +                       (*write_log)(tty->log_fd, buf - ret, ret, tty, 0);
42975 +#endif
42976         }
42977         up(&tty->atomic_write);
42978         return ret;
42979 @@ -1662,6 +1688,11 @@
42980                 tty_set_termios_ldisc(o_tty,N_TTY);
42981         }
42982  
42983 +#ifdef CONFIG_TTY_LOG
42984 +       if((tty->log_fd >= 0) && (close_log != NULL))
42985 +               (*close_log)(tty->log_fd, tty);
42986 +#endif
42987 +
42988         /* 
42989          * The release_mem function takes care of the details of clearing
42990          * the slots and preserving the termios structure.
42991 @@ -1820,6 +1851,11 @@
42992                         nr_warns++;
42993                 }
42994         }
42995 +
42996 +#ifdef CONFIG_TTY_LOG
42997 +       if((tty->log_fd < 0) && (open_log != NULL))
42998 +              tty->log_fd = (*open_log)(tty, current->tty);
42999 +#endif
43000         return 0;
43001  }
43002  
43003 @@ -2467,6 +2503,9 @@
43004         spin_lock_init(&tty->read_lock);
43005         INIT_LIST_HEAD(&tty->tty_files);
43006         INIT_TQUEUE(&tty->SAK_tq, 0, 0);
43007 +#ifdef CONFIG_TTY_LOG
43008 +       tty->log_fd = -1;
43009 +#endif
43010  }
43011  
43012  /*
43013 Index: linux-2.4.29/drivers/net/setup.c
43014 ===================================================================
43015 --- linux-2.4.29.orig/drivers/net/setup.c       2005-05-03 21:09:27.000000000 +0300
43016 +++ linux-2.4.29/drivers/net/setup.c    2005-05-03 22:28:14.000000000 +0300
43017 @@ -28,7 +28,6 @@
43018  extern int lmc_setup(void);
43019  
43020  extern int madgemc_probe(void);
43021 -extern int uml_net_probe(void);
43022  
43023  /* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is string of 9 zeros. */
43024  #define __PAD6 "\0\0\0\0\0\0\0\0\0"
43025 @@ -103,9 +102,6 @@
43026  #ifdef CONFIG_MADGEMC
43027         {madgemc_probe, 0},
43028  #endif
43029 -#ifdef CONFIG_UML_NET
43030 -       {uml_net_probe, 0},
43031 -#endif
43032   
43033         {NULL, 0},
43034  };
43035 Index: linux-2.4.29/fs/bad_inode.c
43036 ===================================================================
43037 --- linux-2.4.29.orig/fs/bad_inode.c    2005-05-03 21:05:44.000000000 +0300
43038 +++ linux-2.4.29/fs/bad_inode.c 2005-05-03 22:28:14.000000000 +0300
43039 @@ -83,6 +83,7 @@
43040   
43041  void make_bad_inode(struct inode * inode) 
43042  {
43043 +       inode->i_state = 0;
43044         inode->i_mode = S_IFREG;
43045         inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
43046         inode->i_op = &bad_inode_ops;   
43047 Index: linux-2.4.29/include/asm-i386/hardirq.h
43048 ===================================================================
43049 --- linux-2.4.29.orig/include/asm-i386/hardirq.h        2005-05-03 21:08:39.000000000 +0300
43050 +++ linux-2.4.29/include/asm-i386/hardirq.h     2005-05-03 23:41:09.908242720 +0300
43051 @@ -4,6 +4,7 @@
43052  #include <linux/config.h>
43053  #include <linux/threads.h>
43054  #include <linux/irq.h>
43055 +#include <asm/processor.h>             /* for cpu_relax */
43056  
43057  /* assembly code in softirq.h is sensitive to the offsets of these fields */
43058  typedef struct {
43059 Index: linux-2.4.29/include/asm-um/a.out.h
43060 ===================================================================
43061 --- linux-2.4.29.orig/include/asm-um/a.out.h    1970-01-01 03:00:00.000000000 +0300
43062 +++ linux-2.4.29/include/asm-um/a.out.h 2005-05-03 22:28:14.909343648 +0300
43063 @@ -0,0 +1,20 @@
43064 +#ifndef __UM_A_OUT_H
43065 +#define __UM_A_OUT_H
43066 +
43067 +#include "linux/config.h"
43068 +#include "asm/arch/a.out.h"
43069 +#include "choose-mode.h"
43070 +
43071 +#undef STACK_TOP
43072 +
43073 +extern unsigned long stacksizelim;
43074 +
43075 +extern unsigned long host_task_size;
43076 +
43077 +#define STACK_ROOM (stacksizelim)
43078 +
43079 +extern int honeypot;
43080 +#define STACK_TOP \
43081 +       CHOOSE_MODE((honeypot ? host_task_size : task_size), task_size)
43082 +
43083 +#endif
43084 Index: linux-2.4.29/include/asm-um/archparam-i386.h
43085 ===================================================================
43086 --- linux-2.4.29.orig/include/asm-um/archparam-i386.h   1970-01-01 03:00:00.000000000 +0300
43087 +++ linux-2.4.29/include/asm-um/archparam-i386.h        2005-05-03 22:28:14.911343344 +0300
43088 @@ -0,0 +1,80 @@
43089 +/* 
43090 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
43091 + * Licensed under the GPL
43092 + */
43093 +
43094 +#ifndef __UM_ARCHPARAM_I386_H
43095 +#define __UM_ARCHPARAM_I386_H
43096 +
43097 +/********* Bits for asm-um/elf.h ************/
43098 +
43099 +#include "user.h"
43100 +
43101 +#define ELF_PLATFORM "i586"
43102 +
43103 +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
43104 +
43105 +typedef struct user_i387_struct elf_fpregset_t;
43106 +typedef unsigned long elf_greg_t;
43107 +
43108 +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
43109 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
43110 +
43111 +#define ELF_DATA        ELFDATA2LSB
43112 +#define ELF_ARCH        EM_386
43113 +
43114 +#define ELF_PLAT_INIT(regs, load_addr) do { \
43115 +       PT_REGS_EBX(regs) = 0; \
43116 +       PT_REGS_ECX(regs) = 0; \
43117 +       PT_REGS_EDX(regs) = 0; \
43118 +       PT_REGS_ESI(regs) = 0; \
43119 +       PT_REGS_EDI(regs) = 0; \
43120 +       PT_REGS_EBP(regs) = 0; \
43121 +       PT_REGS_EAX(regs) = 0; \
43122 +} while(0)
43123 +
43124 +/* Shamelessly stolen from include/asm-i386/elf.h */
43125 +
43126 +#define ELF_CORE_COPY_REGS(pr_reg, regs) do {  \
43127 +       pr_reg[0] = PT_REGS_EBX(regs);          \
43128 +       pr_reg[1] = PT_REGS_ECX(regs);          \
43129 +       pr_reg[2] = PT_REGS_EDX(regs);          \
43130 +       pr_reg[3] = PT_REGS_ESI(regs);          \
43131 +       pr_reg[4] = PT_REGS_EDI(regs);          \
43132 +       pr_reg[5] = PT_REGS_EBP(regs);          \
43133 +       pr_reg[6] = PT_REGS_EAX(regs);          \
43134 +       pr_reg[7] = PT_REGS_DS(regs);           \
43135 +       pr_reg[8] = PT_REGS_ES(regs);           \
43136 +       /* fake once used fs and gs selectors? */       \
43137 +       pr_reg[9] = PT_REGS_DS(regs);           \
43138 +       pr_reg[10] = PT_REGS_DS(regs);          \
43139 +       pr_reg[11] = PT_REGS_SYSCALL_NR(regs);  \
43140 +       pr_reg[12] = PT_REGS_IP(regs);          \
43141 +       pr_reg[13] = PT_REGS_CS(regs);          \
43142 +       pr_reg[14] = PT_REGS_EFLAGS(regs);      \
43143 +       pr_reg[15] = PT_REGS_SP(regs);          \
43144 +       pr_reg[16] = PT_REGS_SS(regs);          \
43145 +} while(0);
43146 +
43147 +/********* Bits for asm-um/delay.h **********/
43148 +
43149 +typedef unsigned long um_udelay_t;
43150 +
43151 +/********* Nothing for asm-um/hardirq.h **********/
43152 +
43153 +/********* Nothing for asm-um/hw_irq.h **********/
43154 +
43155 +/********* Nothing for asm-um/string.h **********/
43156 +
43157 +#endif
43158 +
43159 +/*
43160 + * Overrides for Emacs so that we follow Linus's tabbing style.
43161 + * Emacs will notice this stuff at the end of the file and automatically
43162 + * adjust the settings for this buffer only.  This must remain at the end
43163 + * of the file.
43164 + * ---------------------------------------------------------------------------
43165 + * Local variables:
43166 + * c-file-style: "linux"
43167 + * End:
43168 + */
43169 Index: linux-2.4.29/include/asm-um/archparam-ppc.h
43170 ===================================================================
43171 --- linux-2.4.29.orig/include/asm-um/archparam-ppc.h    1970-01-01 03:00:00.000000000 +0300
43172 +++ linux-2.4.29/include/asm-um/archparam-ppc.h 2005-05-03 22:28:14.000000000 +0300
43173 @@ -0,0 +1,41 @@
43174 +#ifndef __UM_ARCHPARAM_PPC_H
43175 +#define __UM_ARCHPARAM_PPC_H
43176 +
43177 +/********* Bits for asm-um/elf.h ************/
43178 +
43179 +#define ELF_PLATFORM (0)
43180 +
43181 +#define ELF_ET_DYN_BASE (0x08000000)
43182 +
43183 +/* the following stolen from asm-ppc/elf.h */
43184 +#define ELF_NGREG      48      /* includes nip, msr, lr, etc. */
43185 +#define ELF_NFPREG     33      /* includes fpscr */
43186 +/* General registers */
43187 +typedef unsigned long elf_greg_t;
43188 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
43189 +
43190 +/* Floating point registers */
43191 +typedef double elf_fpreg_t;
43192 +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
43193 +
43194 +#define ELF_DATA        ELFDATA2MSB
43195 +#define ELF_ARCH       EM_PPC
43196 +
43197 +/********* Bits for asm-um/delay.h **********/
43198 +
43199 +typedef unsigned int um_udelay_t;
43200 +
43201 +/********* Bits for asm-um/hw_irq.h **********/
43202 +
43203 +struct hw_interrupt_type;
43204 +
43205 +/********* Bits for asm-um/hardirq.h **********/
43206 +
43207 +#define irq_enter(cpu, irq) hardirq_enter(cpu)
43208 +#define irq_exit(cpu, irq) hardirq_exit(cpu)
43209 +
43210 +/********* Bits for asm-um/string.h **********/
43211 +
43212 +#define __HAVE_ARCH_STRRCHR
43213 +
43214 +#endif
43215 Index: linux-2.4.29/include/asm-um/arch-signal-i386.h
43216 ===================================================================
43217 --- linux-2.4.29.orig/include/asm-um/arch-signal-i386.h 1970-01-01 03:00:00.000000000 +0300
43218 +++ linux-2.4.29/include/asm-um/arch-signal-i386.h      2005-05-03 22:28:14.000000000 +0300
43219 @@ -0,0 +1,24 @@
43220 +/* 
43221 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
43222 + * Licensed under the GPL
43223 + */
43224 +
43225 +#ifndef __UM_ARCH_SIGNAL_I386_H
43226 +#define __UM_ARCH_SIGNAL_I386_H
43227 +
43228 +struct arch_signal_context {
43229 +       unsigned long extrasigs[_NSIG_WORDS];
43230 +};
43231 +
43232 +#endif
43233 +
43234 +/*
43235 + * Overrides for Emacs so that we follow Linus's tabbing style.
43236 + * Emacs will notice this stuff at the end of the file and automatically
43237 + * adjust the settings for this buffer only.  This must remain at the end
43238 + * of the file.
43239 + * ---------------------------------------------------------------------------
43240 + * Local variables:
43241 + * c-file-style: "linux"
43242 + * End:
43243 + */
43244 Index: linux-2.4.29/include/asm-um/atomic.h
43245 ===================================================================
43246 --- linux-2.4.29.orig/include/asm-um/atomic.h   1970-01-01 03:00:00.000000000 +0300
43247 +++ linux-2.4.29/include/asm-um/atomic.h        2005-05-03 23:41:08.099517688 +0300
43248 @@ -0,0 +1,6 @@
43249 +#ifndef __UM_ATOMIC_H
43250 +#define __UM_ATOMIC_H
43251 +
43252 +#include "asm/arch/atomic.h"
43253 +
43254 +#endif
43255 Index: linux-2.4.29/include/asm-um/bitops.h
43256 ===================================================================
43257 --- linux-2.4.29.orig/include/asm-um/bitops.h   1970-01-01 03:00:00.000000000 +0300
43258 +++ linux-2.4.29/include/asm-um/bitops.h        2005-05-03 23:41:08.093518600 +0300
43259 @@ -0,0 +1,6 @@
43260 +#ifndef __UM_BITOPS_H
43261 +#define __UM_BITOPS_H
43262 +
43263 +#include "asm/arch/bitops.h"
43264 +
43265 +#endif
43266 Index: linux-2.4.29/include/asm-um/boot.h
43267 ===================================================================
43268 --- linux-2.4.29.orig/include/asm-um/boot.h     1970-01-01 03:00:00.000000000 +0300
43269 +++ linux-2.4.29/include/asm-um/boot.h  2005-05-03 22:28:14.000000000 +0300
43270 @@ -0,0 +1,6 @@
43271 +#ifndef __UM_BOOT_H
43272 +#define __UM_BOOT_H
43273 +
43274 +#include "asm/arch/boot.h"
43275 +
43276 +#endif
43277 Index: linux-2.4.29/include/asm-um/bugs.h
43278 ===================================================================
43279 --- linux-2.4.29.orig/include/asm-um/bugs.h     1970-01-01 03:00:00.000000000 +0300
43280 +++ linux-2.4.29/include/asm-um/bugs.h  2005-05-03 22:28:14.000000000 +0300
43281 @@ -0,0 +1,6 @@
43282 +#ifndef __UM_BUGS_H
43283 +#define __UM_BUGS_H
43284 +
43285 +void check_bugs(void);
43286 +
43287 +#endif
43288 Index: linux-2.4.29/include/asm-um/byteorder.h
43289 ===================================================================
43290 --- linux-2.4.29.orig/include/asm-um/byteorder.h        1970-01-01 03:00:00.000000000 +0300
43291 +++ linux-2.4.29/include/asm-um/byteorder.h     2005-05-03 22:37:45.347623848 +0300
43292 @@ -0,0 +1,6 @@
43293 +#ifndef __UM_BYTEORDER_H
43294 +#define __UM_BYTEORDER_H
43295 +
43296 +#include "asm/arch/byteorder.h"
43297 +
43298 +#endif
43299 Index: linux-2.4.29/include/asm-um/cache.h
43300 ===================================================================
43301 --- linux-2.4.29.orig/include/asm-um/cache.h    1970-01-01 03:00:00.000000000 +0300
43302 +++ linux-2.4.29/include/asm-um/cache.h 2005-05-03 22:28:14.917342432 +0300
43303 @@ -0,0 +1,6 @@
43304 +#ifndef __UM_CACHE_H
43305 +#define __UM_CACHE_H
43306 +
43307 +#define        L1_CACHE_BYTES  32
43308 +
43309 +#endif
43310 Index: linux-2.4.29/include/asm-um/checksum.h
43311 ===================================================================
43312 --- linux-2.4.29.orig/include/asm-um/checksum.h 1970-01-01 03:00:00.000000000 +0300
43313 +++ linux-2.4.29/include/asm-um/checksum.h      2005-05-03 22:28:14.917342432 +0300
43314 @@ -0,0 +1,6 @@
43315 +#ifndef __UM_CHECKSUM_H
43316 +#define __UM_CHECKSUM_H
43317 +
43318 +#include "sysdep/checksum.h"
43319 +
43320 +#endif
43321 Index: linux-2.4.29/include/asm-um/cobalt.h
43322 ===================================================================
43323 --- linux-2.4.29.orig/include/asm-um/cobalt.h   1970-01-01 03:00:00.000000000 +0300
43324 +++ linux-2.4.29/include/asm-um/cobalt.h        2005-05-03 22:28:14.000000000 +0300
43325 @@ -0,0 +1,6 @@
43326 +#ifndef __UM_COBALT_H
43327 +#define __UM_COBALT_H
43328 +
43329 +#include "asm/arch/cobalt.h"
43330 +
43331 +#endif
43332 Index: linux-2.4.29/include/asm-um/current.h
43333 ===================================================================
43334 --- linux-2.4.29.orig/include/asm-um/current.h  1970-01-01 03:00:00.000000000 +0300
43335 +++ linux-2.4.29/include/asm-um/current.h       2005-05-03 23:41:08.083520120 +0300
43336 @@ -0,0 +1,34 @@
43337 +/* 
43338 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
43339 + * Licensed under the GPL
43340 + */
43341 +
43342 +#ifndef __UM_CURRENT_H
43343 +#define __UM_CURRENT_H
43344 +
43345 +#ifndef __ASSEMBLY__
43346 +
43347 +#include "linux/config.h"
43348 +#include "asm/page.h"
43349 +
43350 +struct task_struct;
43351 +
43352 +#define CURRENT_TASK(dummy) (((unsigned long) &dummy) & \
43353 +                            (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
43354 +
43355 +#define current ({ int dummy; (struct task_struct *) CURRENT_TASK(dummy); })
43356 +
43357 +#endif /* __ASSEMBLY__ */
43358 +
43359 +#endif
43360 +
43361 +/*
43362 + * Overrides for Emacs so that we follow Linus's tabbing style.
43363 + * Emacs will notice this stuff at the end of the file and automatically
43364 + * adjust the settings for this buffer only.  This must remain at the end
43365 + * of the file.
43366 + * ---------------------------------------------------------------------------
43367 + * Local variables:
43368 + * c-file-style: "linux"
43369 + * End:
43370 + */
43371 Index: linux-2.4.29/include/asm-um/delay.h
43372 ===================================================================
43373 --- linux-2.4.29.orig/include/asm-um/delay.h    1970-01-01 03:00:00.000000000 +0300
43374 +++ linux-2.4.29/include/asm-um/delay.h 2005-05-03 22:28:14.919342128 +0300
43375 @@ -0,0 +1,7 @@
43376 +#ifndef __UM_DELAY_H
43377 +#define __UM_DELAY_H
43378 +
43379 +#include "asm/arch/delay.h"
43380 +#include "asm/archparam.h"
43381 +
43382 +#endif
43383 Index: linux-2.4.29/include/asm-um/desc.h
43384 ===================================================================
43385 --- linux-2.4.29.orig/include/asm-um/desc.h     1970-01-01 03:00:00.000000000 +0300
43386 +++ linux-2.4.29/include/asm-um/desc.h  2005-05-03 22:28:14.000000000 +0300
43387 @@ -0,0 +1,6 @@
43388 +#ifndef __UM_DESC_H
43389 +#define __UM_DESC_H
43390 +
43391 +#include "asm/arch/desc.h"
43392 +
43393 +#endif
43394 Index: linux-2.4.29/include/asm-um/div64.h
43395 ===================================================================
43396 --- linux-2.4.29.orig/include/asm-um/div64.h    1970-01-01 03:00:00.000000000 +0300
43397 +++ linux-2.4.29/include/asm-um/div64.h 2005-05-03 22:28:14.941338784 +0300
43398 @@ -0,0 +1,6 @@
43399 +#ifndef _UM_DIV64_H
43400 +#define _UM_DIV64_H
43401 +
43402 +#include "asm/arch/div64.h"
43403 +
43404 +#endif
43405 Index: linux-2.4.29/include/asm-um/dma.h
43406 ===================================================================
43407 --- linux-2.4.29.orig/include/asm-um/dma.h      1970-01-01 03:00:00.000000000 +0300
43408 +++ linux-2.4.29/include/asm-um/dma.h   2005-05-03 22:37:48.244183504 +0300
43409 @@ -0,0 +1,10 @@
43410 +#ifndef __UM_DMA_H
43411 +#define __UM_DMA_H
43412 +
43413 +#include "asm/io.h"
43414 +
43415 +extern unsigned long uml_physmem;
43416 +
43417 +#define MAX_DMA_ADDRESS (uml_physmem)
43418 +
43419 +#endif
43420 Index: linux-2.4.29/include/asm-um/elf.h
43421 ===================================================================
43422 --- linux-2.4.29.orig/include/asm-um/elf.h      1970-01-01 03:00:00.000000000 +0300
43423 +++ linux-2.4.29/include/asm-um/elf.h   2005-05-03 22:28:14.943338480 +0300
43424 @@ -0,0 +1,18 @@
43425 +#ifndef __UM_ELF_H
43426 +#define __UM_ELF_H
43427 +
43428 +#include "asm/archparam.h"
43429 +
43430 +#define ELF_HWCAP (0)
43431 +
43432 +#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
43433 +
43434 +#define ELF_EXEC_PAGESIZE 4096
43435 +
43436 +#define elf_check_arch(x) (1)
43437 +
43438 +#define ELF_CLASS ELFCLASS32
43439 +
43440 +#define USE_ELF_CORE_DUMP
43441 +
43442 +#endif
43443 Index: linux-2.4.29/include/asm-um/errno.h
43444 ===================================================================
43445 --- linux-2.4.29.orig/include/asm-um/errno.h    1970-01-01 03:00:00.000000000 +0300
43446 +++ linux-2.4.29/include/asm-um/errno.h 2005-05-03 22:28:14.944338328 +0300
43447 @@ -0,0 +1,6 @@
43448 +#ifndef __UM_ERRNO_H
43449 +#define __UM_ERRNO_H
43450 +
43451 +#include "asm/arch/errno.h"
43452 +
43453 +#endif
43454 Index: linux-2.4.29/include/asm-um/fcntl.h
43455 ===================================================================
43456 --- linux-2.4.29.orig/include/asm-um/fcntl.h    1970-01-01 03:00:00.000000000 +0300
43457 +++ linux-2.4.29/include/asm-um/fcntl.h 2005-05-03 22:28:14.945338176 +0300
43458 @@ -0,0 +1,6 @@
43459 +#ifndef __UM_FCNTL_H
43460 +#define __UM_FCNTL_H
43461 +
43462 +#include "asm/arch/fcntl.h"
43463 +
43464 +#endif
43465 Index: linux-2.4.29/include/asm-um/fixmap.h
43466 ===================================================================
43467 --- linux-2.4.29.orig/include/asm-um/fixmap.h   1970-01-01 03:00:00.000000000 +0300
43468 +++ linux-2.4.29/include/asm-um/fixmap.h        2005-05-03 23:41:11.208045120 +0300
43469 @@ -0,0 +1,89 @@
43470 +#ifndef __UM_FIXMAP_H
43471 +#define __UM_FIXMAP_H
43472 +
43473 +#include <linux/config.h>
43474 +#include <asm/kmap_types.h>
43475 +
43476 +/*
43477 + * Here we define all the compile-time 'special' virtual
43478 + * addresses. The point is to have a constant address at
43479 + * compile time, but to set the physical address only
43480 + * in the boot process. We allocate these special  addresses
43481 + * from the end of virtual memory (0xfffff000) backwards.
43482 + * Also this lets us do fail-safe vmalloc(), we
43483 + * can guarantee that these special addresses and
43484 + * vmalloc()-ed addresses never overlap.
43485 + *
43486 + * these 'compile-time allocated' memory buffers are
43487 + * fixed-size 4k pages. (or larger if used with an increment
43488 + * highger than 1) use fixmap_set(idx,phys) to associate
43489 + * physical memory with fixmap indices.
43490 + *
43491 + * TLB entries of such buffers will not be flushed across
43492 + * task switches.
43493 + */
43494 +
43495 +/*
43496 + * on UP currently we will have no trace of the fixmap mechanizm,
43497 + * no page table allocations, etc. This might change in the
43498 + * future, say framebuffers for the console driver(s) could be
43499 + * fix-mapped?
43500 + */
43501 +enum fixed_addresses {
43502 +#ifdef CONFIG_HIGHMEM
43503 +       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
43504 +       FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
43505 +#endif
43506 +       __end_of_fixed_addresses
43507 +};
43508 +
43509 +extern void __set_fixmap (enum fixed_addresses idx,
43510 +                         unsigned long phys, pgprot_t flags);
43511 +
43512 +#define set_fixmap(idx, phys) \
43513 +               __set_fixmap(idx, phys, PAGE_KERNEL)
43514 +/*
43515 + * Some hardware wants to get fixmapped without caching.
43516 + */
43517 +#define set_fixmap_nocache(idx, phys) \
43518 +               __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
43519 +/*
43520 + * used by vmalloc.c.
43521 + *
43522 + * Leave one empty page between vmalloc'ed areas and
43523 + * the start of the fixmap, and leave one page empty
43524 + * at the top of mem..
43525 + */
43526 +extern unsigned long get_kmem_end(void);
43527 +
43528 +#define FIXADDR_TOP    (get_kmem_end() - 0x2000)
43529 +#define FIXADDR_SIZE   (__end_of_fixed_addresses << PAGE_SHIFT)
43530 +#define FIXADDR_START  (FIXADDR_TOP - FIXADDR_SIZE)
43531 +
43532 +#define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
43533 +
43534 +extern void __this_fixmap_does_not_exist(void);
43535 +
43536 +/*
43537 + * 'index to address' translation. If anyone tries to use the idx
43538 + * directly without tranlation, we catch the bug with a NULL-deference
43539 + * kernel oops. Illegal ranges of incoming indices are caught too.
43540 + */
43541 +static inline unsigned long fix_to_virt(const unsigned int idx)
43542 +{
43543 +       /*
43544 +        * this branch gets completely eliminated after inlining,
43545 +        * except when someone tries to use fixaddr indices in an
43546 +        * illegal way. (such as mixing up address types or using
43547 +        * out-of-range indices).
43548 +        *
43549 +        * If it doesn't get removed, the linker will complain
43550 +        * loudly with a reasonably clear error message..
43551 +        */
43552 +       if (idx >= __end_of_fixed_addresses)
43553 +               __this_fixmap_does_not_exist();
43554 +
43555 +        return __fix_to_virt(idx);
43556 +}
43557 +
43558 +#endif
43559 Index: linux-2.4.29/include/asm-um/floppy.h
43560 ===================================================================
43561 --- linux-2.4.29.orig/include/asm-um/floppy.h   1970-01-01 03:00:00.000000000 +0300
43562 +++ linux-2.4.29/include/asm-um/floppy.h        2005-05-03 22:28:14.000000000 +0300
43563 @@ -0,0 +1,6 @@
43564 +#ifndef __UM_FLOPPY_H
43565 +#define __UM_FLOPPY_H
43566 +
43567 +#include "asm/arch/floppy.h"
43568 +
43569 +#endif
43570 Index: linux-2.4.29/include/asm-um/hardirq.h
43571 ===================================================================
43572 --- linux-2.4.29.orig/include/asm-um/hardirq.h  1970-01-01 03:00:00.000000000 +0300
43573 +++ linux-2.4.29/include/asm-um/hardirq.h       2005-05-03 23:41:09.909242568 +0300
43574 @@ -0,0 +1,6 @@
43575 +#ifndef __UM_HARDIRQ_H
43576 +#define __UM_HARDIRQ_H
43577 +
43578 +#include "asm/arch/hardirq.h"
43579 +
43580 +#endif
43581 Index: linux-2.4.29/include/asm-um/hdreg.h
43582 ===================================================================
43583 --- linux-2.4.29.orig/include/asm-um/hdreg.h    1970-01-01 03:00:00.000000000 +0300
43584 +++ linux-2.4.29/include/asm-um/hdreg.h 2005-05-03 22:28:14.000000000 +0300
43585 @@ -0,0 +1,6 @@
43586 +#ifndef __UM_HDREG_H
43587 +#define __UM_HDREG_H
43588 +
43589 +#include "asm/arch/hdreg.h"
43590 +
43591 +#endif
43592 Index: linux-2.4.29/include/asm-um/highmem.h
43593 ===================================================================
43594 --- linux-2.4.29.orig/include/asm-um/highmem.h  1970-01-01 03:00:00.000000000 +0300
43595 +++ linux-2.4.29/include/asm-um/highmem.h       2005-05-03 23:41:11.210044816 +0300
43596 @@ -0,0 +1,12 @@
43597 +#ifndef __UM_HIGHMEM_H
43598 +#define __UM_HIGHMEM_H
43599 +
43600 +#include "asm/page.h"
43601 +#include "asm/fixmap.h"
43602 +#include "asm/arch/highmem.h"
43603 +
43604 +#undef PKMAP_BASE
43605 +
43606 +#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK)
43607 +
43608 +#endif
43609 Index: linux-2.4.29/include/asm-um/hw_irq.h
43610 ===================================================================
43611 --- linux-2.4.29.orig/include/asm-um/hw_irq.h   1970-01-01 03:00:00.000000000 +0300
43612 +++ linux-2.4.29/include/asm-um/hw_irq.h        2005-05-03 22:37:48.105204632 +0300
43613 @@ -0,0 +1,10 @@
43614 +#ifndef _ASM_UM_HW_IRQ_H
43615 +#define _ASM_UM_HW_IRQ_H
43616 +
43617 +#include "asm/irq.h"
43618 +#include "asm/archparam.h"
43619 +
43620 +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
43621 +{}
43622 +
43623 +#endif
43624 Index: linux-2.4.29/include/asm-um/ide.h
43625 ===================================================================
43626 --- linux-2.4.29.orig/include/asm-um/ide.h      1970-01-01 03:00:00.000000000 +0300
43627 +++ linux-2.4.29/include/asm-um/ide.h   2005-05-03 22:28:14.000000000 +0300
43628 @@ -0,0 +1,6 @@
43629 +#ifndef __UM_IDE_H
43630 +#define __UM_IDE_H
43631 +
43632 +#include "asm/arch/ide.h"
43633 +
43634 +#endif
43635 Index: linux-2.4.29/include/asm-um/init.h
43636 ===================================================================
43637 --- linux-2.4.29.orig/include/asm-um/init.h     1970-01-01 03:00:00.000000000 +0300
43638 +++ linux-2.4.29/include/asm-um/init.h  2005-05-03 22:28:14.000000000 +0300
43639 @@ -0,0 +1,11 @@
43640 +#ifndef _UM_INIT_H
43641 +#define _UM_INIT_H
43642 +
43643 +#ifdef notdef
43644 +#define __init
43645 +#define __initdata
43646 +#define __initfunc(__arginit) __arginit
43647 +#define __cacheline_aligned 
43648 +#endif
43649 +
43650 +#endif
43651 Index: linux-2.4.29/include/asm-um/ioctl.h
43652 ===================================================================
43653 --- linux-2.4.29.orig/include/asm-um/ioctl.h    1970-01-01 03:00:00.000000000 +0300
43654 +++ linux-2.4.29/include/asm-um/ioctl.h 2005-05-03 22:28:14.952337112 +0300
43655 @@ -0,0 +1,6 @@
43656 +#ifndef __UM_IOCTL_H
43657 +#define __UM_IOCTL_H
43658 +
43659 +#include "asm/arch/ioctl.h"
43660 +
43661 +#endif
43662 Index: linux-2.4.29/include/asm-um/ioctls.h
43663 ===================================================================
43664 --- linux-2.4.29.orig/include/asm-um/ioctls.h   1970-01-01 03:00:00.000000000 +0300
43665 +++ linux-2.4.29/include/asm-um/ioctls.h        2005-05-03 22:37:45.509599224 +0300
43666 @@ -0,0 +1,6 @@
43667 +#ifndef __UM_IOCTLS_H
43668 +#define __UM_IOCTLS_H
43669 +
43670 +#include "asm/arch/ioctls.h"
43671 +
43672 +#endif
43673 Index: linux-2.4.29/include/asm-um/io.h
43674 ===================================================================
43675 --- linux-2.4.29.orig/include/asm-um/io.h       1970-01-01 03:00:00.000000000 +0300
43676 +++ linux-2.4.29/include/asm-um/io.h    2005-05-03 22:37:48.176193840 +0300
43677 @@ -0,0 +1,25 @@
43678 +#ifndef __UM_IO_H
43679 +#define __UM_IO_H
43680 +
43681 +#include "asm/page.h"
43682 +
43683 +#define IO_SPACE_LIMIT 0xdeadbeef /* Sure hope nothing uses this */
43684 +
43685 +static inline int inb(unsigned long i) { return(0); }
43686 +static inline void outb(char c, unsigned long i) { }
43687 +
43688 +/*
43689 + * Change virtual addresses to physical addresses and vv.
43690 + * These are pretty trivial
43691 + */
43692 +static inline unsigned long virt_to_phys(volatile void * address)
43693 +{
43694 +       return __pa((void *) address);
43695 +}
43696 +
43697 +static inline void * phys_to_virt(unsigned long address)
43698 +{
43699 +       return __va(address);
43700 +}
43701 +
43702 +#endif
43703 Index: linux-2.4.29/include/asm-um/ipcbuf.h
43704 ===================================================================
43705 --- linux-2.4.29.orig/include/asm-um/ipcbuf.h   1970-01-01 03:00:00.000000000 +0300
43706 +++ linux-2.4.29/include/asm-um/ipcbuf.h        2005-05-03 22:28:14.954336808 +0300
43707 @@ -0,0 +1,6 @@
43708 +#ifndef __UM_IPCBUF_H
43709 +#define __UM_IPCBUF_H
43710 +
43711 +#include "asm/arch/ipcbuf.h"
43712 +
43713 +#endif
43714 Index: linux-2.4.29/include/asm-um/ipc.h
43715 ===================================================================
43716 --- linux-2.4.29.orig/include/asm-um/ipc.h      1970-01-01 03:00:00.000000000 +0300
43717 +++ linux-2.4.29/include/asm-um/ipc.h   2005-05-03 22:28:14.000000000 +0300
43718 @@ -0,0 +1,6 @@
43719 +#ifndef __UM_IPC_H
43720 +#define __UM_IPC_H
43721 +
43722 +#include "asm/arch/ipc.h"
43723 +
43724 +#endif
43725 Index: linux-2.4.29/include/asm-um/irq.h
43726 ===================================================================
43727 --- linux-2.4.29.orig/include/asm-um/irq.h      1970-01-01 03:00:00.000000000 +0300
43728 +++ linux-2.4.29/include/asm-um/irq.h   2005-05-03 22:28:14.956336504 +0300
43729 @@ -0,0 +1,23 @@
43730 +#ifndef __UM_IRQ_H
43731 +#define __UM_IRQ_H
43732 +
43733 +#define TIMER_IRQ              0
43734 +#define UMN_IRQ                        1
43735 +#define CONSOLE_IRQ            2
43736 +#define CONSOLE_WRITE_IRQ      3
43737 +#define UBD_IRQ                        4
43738 +#define UM_ETH_IRQ             5
43739 +#define SSL_IRQ                        6
43740 +#define SSL_WRITE_IRQ          7
43741 +#define ACCEPT_IRQ             8
43742 +#define MCONSOLE_IRQ           9
43743 +#define WINCH_IRQ              10
43744 +#define SIGIO_WRITE_IRQ        11
43745 +#define TELNETD_IRQ            12
43746 +#define XTERM_IRQ              13
43747 +#define HUMFS_IRQ              14
43748 +
43749 +#define LAST_IRQ HUMFS_IRQ
43750 +#define NR_IRQS (LAST_IRQ + 1)
43751 +
43752 +#endif
43753 Index: linux-2.4.29/include/asm-um/keyboard.h
43754 ===================================================================
43755 --- linux-2.4.29.orig/include/asm-um/keyboard.h 1970-01-01 03:00:00.000000000 +0300
43756 +++ linux-2.4.29/include/asm-um/keyboard.h      2005-05-03 22:28:14.000000000 +0300
43757 @@ -0,0 +1,6 @@
43758 +#ifndef __UM_KEYBOARD_H
43759 +#define __UM_KEYBOARD_H
43760 +
43761 +#include "asm/arch/keyboard.h"
43762 +
43763 +#endif
43764 Index: linux-2.4.29/include/asm-um/kmap_types.h
43765 ===================================================================
43766 --- linux-2.4.29.orig/include/asm-um/kmap_types.h       1970-01-01 03:00:00.000000000 +0300
43767 +++ linux-2.4.29/include/asm-um/kmap_types.h    2005-05-03 22:28:14.957336352 +0300
43768 @@ -0,0 +1,11 @@
43769 +/* 
43770 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
43771 + * Licensed under the GPL
43772 + */
43773 +
43774 +#ifndef __UM_KMAP_TYPES_H
43775 +#define __UM_KMAP_TYPES_H
43776 +
43777 +#include "asm/arch/kmap_types.h"
43778 +
43779 +#endif
43780 Index: linux-2.4.29/include/asm-um/linux_logo.h
43781 ===================================================================
43782 --- linux-2.4.29.orig/include/asm-um/linux_logo.h       1970-01-01 03:00:00.000000000 +0300
43783 +++ linux-2.4.29/include/asm-um/linux_logo.h    2005-05-03 22:28:14.000000000 +0300
43784 @@ -0,0 +1,6 @@
43785 +#ifndef __UM_LINUX_LOGO_H
43786 +#define __UM_LINUX_LOGO_H
43787 +
43788 +#include "asm/arch/linux_logo.h"
43789 +
43790 +#endif
43791 Index: linux-2.4.29/include/asm-um/locks.h
43792 ===================================================================
43793 --- linux-2.4.29.orig/include/asm-um/locks.h    1970-01-01 03:00:00.000000000 +0300
43794 +++ linux-2.4.29/include/asm-um/locks.h 2005-05-03 22:28:14.000000000 +0300
43795 @@ -0,0 +1,6 @@
43796 +#ifndef __UM_LOCKS_H
43797 +#define __UM_LOCKS_H
43798 +
43799 +#include "asm/arch/locks.h"
43800 +
43801 +#endif
43802 Index: linux-2.4.29/include/asm-um/mca_dma.h
43803 ===================================================================
43804 --- linux-2.4.29.orig/include/asm-um/mca_dma.h  1970-01-01 03:00:00.000000000 +0300
43805 +++ linux-2.4.29/include/asm-um/mca_dma.h       2005-05-03 22:28:14.000000000 +0300
43806 @@ -0,0 +1,6 @@
43807 +#ifndef mca___UM_DMA_H
43808 +#define mca___UM_DMA_H
43809 +
43810 +#include "asm/arch/mca_dma.h"
43811 +
43812 +#endif
43813 Index: linux-2.4.29/include/asm-um/mman.h
43814 ===================================================================
43815 --- linux-2.4.29.orig/include/asm-um/mman.h     1970-01-01 03:00:00.000000000 +0300
43816 +++ linux-2.4.29/include/asm-um/mman.h  2005-05-03 22:28:14.961335744 +0300
43817 @@ -0,0 +1,6 @@
43818 +#ifndef __UM_MMAN_H
43819 +#define __UM_MMAN_H
43820 +
43821 +#include "asm/arch/mman.h"
43822 +
43823 +#endif
43824 Index: linux-2.4.29/include/asm-um/mmu_context.h
43825 ===================================================================
43826 --- linux-2.4.29.orig/include/asm-um/mmu_context.h      1970-01-01 03:00:00.000000000 +0300
43827 +++ linux-2.4.29/include/asm-um/mmu_context.h   2005-05-03 23:41:09.000000000 +0300
43828 @@ -0,0 +1,72 @@
43829 +/* 
43830 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
43831 + * Licensed under the GPL
43832 + */
43833 +
43834 +#ifndef __UM_MMU_CONTEXT_H
43835 +#define __UM_MMU_CONTEXT_H
43836 +
43837 +#include "linux/sched.h"
43838 +#include "choose-mode.h"
43839 +
43840 +#define get_mmu_context(task) do ; while(0)
43841 +#define activate_context(tsk) do ; while(0)
43842 +
43843 +static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
43844 +{
43845 +}
43846 +
43847 +extern void switch_mm_skas(int mm_fd);
43848 +
43849 +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
43850 +                            struct task_struct *tsk, unsigned cpu)
43851 +{
43852 +       if(prev != next){
43853 +               clear_bit(cpu, &prev->cpu_vm_mask);
43854 +               set_bit(cpu, &next->cpu_vm_mask);
43855 +               if(next != &init_mm)
43856 +                       CHOOSE_MODE((void) 0, 
43857 +                                   switch_mm_skas(next->context.skas.mm_fd));
43858 +       }
43859 +}
43860 +
43861 +static inline void enter_lazy_tlb(struct mm_struct *mm, 
43862 +                                 struct task_struct *tsk, unsigned cpu)
43863 +{
43864 +}
43865 +
43866 +extern int init_new_context_skas(struct task_struct *task, 
43867 +                                struct mm_struct *mm);
43868 +
43869 +static inline int init_new_context_tt(struct task_struct *task, 
43870 +                                     struct mm_struct *mm)
43871 +{
43872 +       return(0);
43873 +}
43874 +
43875 +static inline int init_new_context(struct task_struct *task, 
43876 +                                  struct mm_struct *mm)
43877 +{
43878 +       return(CHOOSE_MODE_PROC(init_new_context_tt, init_new_context_skas, 
43879 +                               task, mm));
43880 +}
43881 +
43882 +extern void destroy_context_skas(struct mm_struct *mm);
43883 +
43884 +static inline void destroy_context(struct mm_struct *mm)
43885 +{
43886 +       CHOOSE_MODE((void) 0, destroy_context_skas(mm));
43887 +}
43888 +
43889 +#endif
43890 +
43891 +/*
43892 + * Overrides for Emacs so that we follow Linus's tabbing style.
43893 + * Emacs will notice this stuff at the end of the file and automatically
43894 + * adjust the settings for this buffer only.  This must remain at the end
43895 + * of the file.
43896 + * ---------------------------------------------------------------------------
43897 + * Local variables:
43898 + * c-file-style: "linux"
43899 + * End:
43900 + */
43901 Index: linux-2.4.29/include/asm-um/mmu.h
43902 ===================================================================
43903 --- linux-2.4.29.orig/include/asm-um/mmu.h      1970-01-01 03:00:00.000000000 +0300
43904 +++ linux-2.4.29/include/asm-um/mmu.h   2005-05-03 22:28:14.962335592 +0300
43905 @@ -0,0 +1,22 @@
43906 +/* 
43907 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
43908 + * Licensed under the GPL
43909 + */
43910 +
43911 +#ifndef __MMU_H
43912 +#define __MMU_H
43913 +
43914 +#include "um_mmu.h"
43915 +
43916 +#endif
43917 +
43918 +/*
43919 + * Overrides for Emacs so that we follow Linus's tabbing style.
43920 + * Emacs will notice this stuff at the end of the file and automatically
43921 + * adjust the settings for this buffer only.  This must remain at the end
43922 + * of the file.
43923 + * ---------------------------------------------------------------------------
43924 + * Local variables:
43925 + * c-file-style: "linux"
43926 + * End:
43927 + */
43928 Index: linux-2.4.29/include/asm-um/module.h
43929 ===================================================================
43930 --- linux-2.4.29.orig/include/asm-um/module.h   1970-01-01 03:00:00.000000000 +0300
43931 +++ linux-2.4.29/include/asm-um/module.h        2005-05-03 22:28:14.000000000 +0300
43932 @@ -0,0 +1,6 @@
43933 +#ifndef __UM_MODULE_H
43934 +#define __UM_MODULE_H
43935 +
43936 +#include "asm/arch/module.h"
43937 +
43938 +#endif
43939 Index: linux-2.4.29/include/asm-um/msgbuf.h
43940 ===================================================================
43941 --- linux-2.4.29.orig/include/asm-um/msgbuf.h   1970-01-01 03:00:00.000000000 +0300
43942 +++ linux-2.4.29/include/asm-um/msgbuf.h        2005-05-03 22:28:14.964335288 +0300
43943 @@ -0,0 +1,6 @@
43944 +#ifndef __UM_MSGBUF_H
43945 +#define __UM_MSGBUF_H
43946 +
43947 +#include "asm/arch/msgbuf.h"
43948 +
43949 +#endif
43950 Index: linux-2.4.29/include/asm-um/mtrr.h
43951 ===================================================================
43952 --- linux-2.4.29.orig/include/asm-um/mtrr.h     1970-01-01 03:00:00.000000000 +0300
43953 +++ linux-2.4.29/include/asm-um/mtrr.h  2005-05-03 22:37:48.000000000 +0300
43954 @@ -0,0 +1,6 @@
43955 +#ifndef __UM_MTRR_H
43956 +#define __UM_MTRR_H
43957 +
43958 +#include "asm/arch/mtrr.h"
43959 +
43960 +#endif
43961 Index: linux-2.4.29/include/asm-um/namei.h
43962 ===================================================================
43963 --- linux-2.4.29.orig/include/asm-um/namei.h    1970-01-01 03:00:00.000000000 +0300
43964 +++ linux-2.4.29/include/asm-um/namei.h 2005-05-03 22:28:14.000000000 +0300
43965 @@ -0,0 +1,6 @@
43966 +#ifndef __UM_NAMEI_H
43967 +#define __UM_NAMEI_H
43968 +
43969 +#include "asm/arch/namei.h"
43970 +
43971 +#endif
43972 Index: linux-2.4.29/include/asm-um/page.h
43973 ===================================================================
43974 --- linux-2.4.29.orig/include/asm-um/page.h     1970-01-01 03:00:00.000000000 +0300
43975 +++ linux-2.4.29/include/asm-um/page.h  2005-05-03 22:37:45.335625672 +0300
43976 @@ -0,0 +1,68 @@
43977 +/* 
43978 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
43979 + * Licensed under the GPL
43980 + */
43981 +
43982 +#ifndef __UM_PAGE_H
43983 +#define __UM_PAGE_H
43984 +
43985 +struct page;
43986 +
43987 +#include "asm/arch/page.h"
43988 +
43989 +#undef BUG
43990 +#undef PAGE_BUG
43991 +#undef __pa
43992 +#undef __va
43993 +#undef virt_to_page
43994 +#undef VALID_PAGE
43995 +#undef PAGE_OFFSET
43996 +#undef KERNELBASE
43997 +
43998 +extern unsigned long uml_physmem;
43999 +
44000 +#define PAGE_OFFSET (uml_physmem)
44001 +#define KERNELBASE PAGE_OFFSET
44002 +
44003 +#ifndef __ASSEMBLY__
44004 +
44005 +extern void stop(void);
44006 +
44007 +#define BUG() do { \
44008 +       panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
44009 +} while (0)
44010 +
44011 +#define PAGE_BUG(page) do { \
44012 +       BUG(); \
44013 +} while (0)
44014 +
44015 +#endif /* __ASSEMBLY__ */
44016 +
44017 +#define __va_space (8*1024*1024)
44018 +
44019 +extern unsigned long to_phys(void *virt);
44020 +extern void *to_virt(unsigned long phys);
44021 +
44022 +#define __pa(virt) to_phys((void *) virt)
44023 +#define __va(phys) to_virt((unsigned long) phys)
44024 +
44025 +#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
44026 +
44027 +extern struct page *arch_validate(struct page *page, int mask, int order);
44028 +#define HAVE_ARCH_VALIDATE
44029 +
44030 +extern void arch_free_page(struct page *page, int order);
44031 +#define HAVE_ARCH_FREE_PAGE
44032 +
44033 +#endif
44034 +
44035 +/*
44036 + * Overrides for Emacs so that we follow Linus's tabbing style.
44037 + * Emacs will notice this stuff at the end of the file and automatically
44038 + * adjust the settings for this buffer only.  This must remain at the end
44039 + * of the file.
44040 + * ---------------------------------------------------------------------------
44041 + * Local variables:
44042 + * c-file-style: "linux"
44043 + * End:
44044 + */
44045 Index: linux-2.4.29/include/asm-um/page_offset.h
44046 ===================================================================
44047 --- linux-2.4.29.orig/include/asm-um/page_offset.h      1970-01-01 03:00:00.000000000 +0300
44048 +++ linux-2.4.29/include/asm-um/page_offset.h   2005-05-03 22:28:14.967334832 +0300
44049 @@ -0,0 +1 @@
44050 +#define PAGE_OFFSET_RAW (uml_physmem)
44051 Index: linux-2.4.29/include/asm-um/param.h
44052 ===================================================================
44053 --- linux-2.4.29.orig/include/asm-um/param.h    1970-01-01 03:00:00.000000000 +0300
44054 +++ linux-2.4.29/include/asm-um/param.h 2005-05-03 22:28:14.968334680 +0300
44055 @@ -0,0 +1,22 @@
44056 +#ifndef _UM_PARAM_H
44057 +#define _UM_PARAM_H
44058 +
44059 +#define HZ 100
44060 +
44061 +#define EXEC_PAGESIZE   4096
44062 +
44063 +#ifndef NGROUPS
44064 +#define NGROUPS         32
44065 +#endif
44066 +
44067 +#ifndef NOGROUP
44068 +#define NOGROUP         (-1)
44069 +#endif
44070 +
44071 +#define MAXHOSTNAMELEN  64      /* max length of hostname */
44072 +
44073 +#ifdef __KERNEL__
44074 +# define CLOCKS_PER_SEC 100    /* frequency at which times() counts */
44075 +#endif
44076 +
44077 +#endif
44078 Index: linux-2.4.29/include/asm-um/pci.h
44079 ===================================================================
44080 --- linux-2.4.29.orig/include/asm-um/pci.h      1970-01-01 03:00:00.000000000 +0300
44081 +++ linux-2.4.29/include/asm-um/pci.h   2005-05-03 22:28:14.000000000 +0300
44082 @@ -0,0 +1,6 @@
44083 +#ifndef __UM_PCI_H
44084 +#define __UM_PCI_H
44085 +
44086 +#define PCI_DMA_BUS_IS_PHYS     (1)
44087 +
44088 +#endif
44089 Index: linux-2.4.29/include/asm-um/pgalloc.h
44090 ===================================================================
44091 --- linux-2.4.29.orig/include/asm-um/pgalloc.h  1970-01-01 03:00:00.000000000 +0300
44092 +++ linux-2.4.29/include/asm-um/pgalloc.h       2005-05-03 23:41:11.209044968 +0300
44093 @@ -0,0 +1,164 @@
44094 +/* 
44095 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
44096 + * Derived from include/asm-i386/pgalloc.h and include/asm-i386/pgtable.h
44097 + * Licensed under the GPL
44098 + */
44099 +
44100 +#ifndef __UM_PGALLOC_H
44101 +#define __UM_PGALLOC_H
44102 +
44103 +#include "linux/config.h"
44104 +#include "linux/mm.h"
44105 +#include "asm/fixmap.h"
44106 +#include "choose-mode.h"
44107 +
44108 +#define pgd_quicklist (current_cpu_data.pgd_quick)
44109 +#define pmd_quicklist (current_cpu_data.pmd_quick)
44110 +#define pte_quicklist (current_cpu_data.pte_quick)
44111 +#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
44112 +
44113 +#define pmd_populate(mm, pmd, pte) set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
44114 +
44115 +/*
44116 + * Allocate and free page tables.
44117 + */
44118 +
44119 +static inline pgd_t *get_pgd_slow_tt(void)
44120 +{
44121 +       pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
44122 +
44123 +       if (pgd) {
44124 +               memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
44125 +               memcpy(pgd + USER_PTRS_PER_PGD, 
44126 +                      swapper_pg_dir + USER_PTRS_PER_PGD, 
44127 +                      (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
44128 +       }
44129 +       return pgd;
44130 +}
44131 +
44132 +static inline pgd_t *get_pgd_slow_skas(void)
44133 +{
44134 +       pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
44135 +
44136 +       if (pgd)
44137 +               memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
44138 +       return pgd;
44139 +}
44140 +
44141 +static inline pgd_t *get_pgd_slow(void)
44142 +{
44143 +       return(CHOOSE_MODE(get_pgd_slow_tt(), get_pgd_slow_skas()));
44144 +}
44145 +
44146 +static inline pgd_t *get_pgd_fast(void)
44147 +{
44148 +       unsigned long *ret;
44149 +
44150 +       ret = pgd_quicklist;
44151 +       if (ret != NULL) {
44152 +               pgd_quicklist = (unsigned long *)(*ret);
44153 +               ret[0] = 0;
44154 +               pgtable_cache_size--;
44155 +       } else
44156 +               ret = (unsigned long *)get_pgd_slow();
44157 +       return (pgd_t *)ret;
44158 +}
44159 +
44160 +static inline void free_pgd_fast(pgd_t *pgd)
44161 +{
44162 +       *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
44163 +       pgd_quicklist = (unsigned long *) pgd;
44164 +       pgtable_cache_size++;
44165 +}
44166 +
44167 +static inline void free_pgd_slow(pgd_t *pgd)
44168 +{
44169 +       free_page((unsigned long)pgd);
44170 +}
44171 +
44172 +static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
44173 +{
44174 +       pte_t *pte;
44175 +
44176 +       pte = (pte_t *) __get_free_page(GFP_KERNEL);
44177 +       if (pte)
44178 +               clear_page(pte);
44179 +       return pte;
44180 +}
44181 +
44182 +static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
44183 +{
44184 +       unsigned long *ret;
44185 +
44186 +       ret = (unsigned long *)pte_quicklist;
44187 +       if (ret != NULL) {
44188 +               pte_quicklist = (unsigned long *)(*ret);
44189 +               ret[0] = ret[1];
44190 +               pgtable_cache_size--;
44191 +       }
44192 +       return (pte_t *)ret;
44193 +}
44194 +
44195 +static inline void pte_free_fast(pte_t *pte)
44196 +{
44197 +       *(unsigned long *)pte = (unsigned long) pte_quicklist;
44198 +       pte_quicklist = (unsigned long *) pte;
44199 +       pgtable_cache_size++;
44200 +}
44201 +
44202 +static inline void pte_free_slow(pte_t *pte)
44203 +{
44204 +       free_page((unsigned long)pte);
44205 +}
44206 +
44207 +#define pte_free(pte)           pte_free_fast(pte)
44208 +#define pgd_free(pgd)           free_pgd_slow(pgd)
44209 +#define pgd_alloc(mm)           get_pgd_fast()
44210 +
44211 +/*
44212 + * allocating and freeing a pmd is trivial: the 1-entry pmd is
44213 + * inside the pgd, so has no extra memory associated with it.
44214 + */
44215 +
44216 +#define pmd_alloc_one_fast(mm, addr)   ({ BUG(); ((pmd_t *)1); })
44217 +#define pmd_alloc_one(mm, addr)                ({ BUG(); ((pmd_t *)2); })
44218 +#define pmd_free_slow(x)               do { } while (0)
44219 +#define pmd_free_fast(x)               do { } while (0)
44220 +#define pmd_free(x)                    do { } while (0)
44221 +#define pgd_populate(mm, pmd, pte)     BUG()
44222 +
44223 +/*
44224 + * TLB flushing:
44225 + *
44226 + *  - flush_tlb() flushes the current mm struct TLBs
44227 + *  - flush_tlb_all() flushes all processes TLBs
44228 + *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
44229 + *  - flush_tlb_page(vma, vmaddr) flushes one page
44230 + *  - flush_tlb_kernel_vm() flushes the kernel vm area
44231 + *  - flush_tlb_range(mm, start, end) flushes a range of pages
44232 + *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
44233 + */
44234 +
44235 +extern void flush_tlb_all(void);
44236 +extern void flush_tlb_mm(struct mm_struct *mm);
44237 +extern void flush_tlb_range(struct mm_struct *mm, unsigned long start, 
44238 +                           unsigned long end);
44239 +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
44240 +extern void flush_tlb_kernel_vm(void);
44241 +
44242 +static inline void flush_tlb_pgtables(struct mm_struct *mm,
44243 +                                     unsigned long start, unsigned long end)
44244 +{
44245 +}
44246 +
44247 +#endif
44248 +/*
44249 + * Overrides for Emacs so that we follow Linus's tabbing style.
44250 + * Emacs will notice this stuff at the end of the file and automatically
44251 + * adjust the settings for this buffer only.  This must remain at the end
44252 + * of the file.
44253 + * ---------------------------------------------------------------------------
44254 + * Local variables:
44255 + * c-file-style: "linux"
44256 + * End:
44257 + */
44258 Index: linux-2.4.29/include/asm-um/pgtable.h
44259 ===================================================================
44260 --- linux-2.4.29.orig/include/asm-um/pgtable.h  1970-01-01 03:00:00.000000000 +0300
44261 +++ linux-2.4.29/include/asm-um/pgtable.h       2005-05-03 23:41:09.906243024 +0300
44262 @@ -0,0 +1,413 @@
44263 +/* 
44264 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
44265 + * Derived from include/asm-i386/pgtable.h
44266 + * Licensed under the GPL
44267 + */
44268 +
44269 +#ifndef __UM_PGTABLE_H
44270 +#define __UM_PGTABLE_H
44271 +
44272 +#include "linux/sched.h"
44273 +#include "asm/processor.h"
44274 +#include "asm/page.h"
44275 +
44276 +extern pgd_t swapper_pg_dir[1024];
44277 +
44278 +#define flush_cache_all() do ; while (0)
44279 +#define flush_cache_mm(mm) do ; while (0)
44280 +#define flush_cache_range(vma, start, end) do ; while (0)
44281 +#define flush_cache_page(vma, vmaddr) do ; while (0)
44282 +#define flush_page_to_ram(page) do ; while (0)
44283 +#define flush_dcache_page(page)        do ; while (0)
44284 +#define flush_icache_range(from, to) do ; while (0)
44285 +#define flush_icache_page(vma,pg) do ; while (0)
44286 +#define flush_icache_user_range(vma,pg,adr,len)        do ; while (0)
44287 +
44288 +extern void __flush_tlb_one(unsigned long addr);
44289 +
44290 +extern void pte_free(pte_t *pte);
44291 +
44292 +extern void pgd_free(pgd_t *pgd);
44293 +
44294 +extern int do_check_pgt_cache(int, int);
44295 +
44296 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
44297 +                            pte_t *pte_out);
44298 +
44299 +/* zero page used for uninitialized stuff */
44300 +extern unsigned long *empty_zero_page;
44301 +
44302 +#define pgtable_cache_init() do ; while (0)
44303 +
44304 +/* PMD_SHIFT determines the size of the area a second-level page table can map */
44305 +#define PMD_SHIFT      22
44306 +#define PMD_SIZE       (1UL << PMD_SHIFT)
44307 +#define PMD_MASK       (~(PMD_SIZE-1))
44308 +
44309 +/* PGDIR_SHIFT determines what a third-level page table entry can map */
44310 +#define PGDIR_SHIFT    22
44311 +#define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
44312 +#define PGDIR_MASK     (~(PGDIR_SIZE-1))
44313 +
44314 +/*
44315 + * entries per page directory level: the i386 is two-level, so
44316 + * we don't really have any PMD directory physically.
44317 + */
44318 +#define PTRS_PER_PTE   1024
44319 +#define PTRS_PER_PMD   1
44320 +#define PTRS_PER_PGD   1024
44321 +#define USER_PTRS_PER_PGD      (TASK_SIZE/PGDIR_SIZE)
44322 +#define FIRST_USER_PGD_NR       0
44323 +
44324 +#define pte_ERROR(e) \
44325 +        printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
44326 +#define pmd_ERROR(e) \
44327 +        printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
44328 +#define pgd_ERROR(e) \
44329 +        printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
44330 +
44331 +/*
44332 + * pgd entries used up by user/kernel:
44333 + */
44334 +
44335 +#define USER_PGD_PTRS (TASK_SIZE >> PGDIR_SHIFT)
44336 +#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
44337 +
44338 +#ifndef __ASSEMBLY__
44339 +/* Just any arbitrary offset to the start of the vmalloc VM area: the
44340 + * current 8MB value just means that there will be a 8MB "hole" after the
44341 + * physical memory until the kernel virtual memory starts.  That means that
44342 + * any out-of-bounds memory accesses will hopefully be caught.
44343 + * The vmalloc() routines leaves a hole of 4kB between each vmalloced
44344 + * area for the same reason. ;)
44345 + */
44346 +
44347 +extern unsigned long end_iomem;
44348 +
44349 +#define VMALLOC_OFFSET (__va_space)
44350 +#define VMALLOC_START  ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
44351 +#define VMALLOC_VMADDR(x) ((unsigned long)(x))
44352 +
44353 +#if CONFIG_HIGHMEM
44354 +# define VMALLOC_END   (PKMAP_BASE-2*PAGE_SIZE)
44355 +#else
44356 +# define VMALLOC_END   (FIXADDR_START-2*PAGE_SIZE)
44357 +#endif
44358 +
44359 +#define _PAGE_PRESENT  0x001
44360 +#define _PAGE_NEWPAGE  0x002
44361 +#define _PAGE_PROTNONE 0x004   /* If not present */
44362 +#define _PAGE_RW       0x008
44363 +#define _PAGE_USER     0x010
44364 +#define _PAGE_ACCESSED 0x020
44365 +#define _PAGE_DIRTY    0x040
44366 +#define _PAGE_NEWPROT   0x080
44367 +
44368 +#define REGION_MASK    0xf0000000
44369 +#define REGION_SHIFT   28
44370 +
44371 +#define _PAGE_TABLE    (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
44372 +#define _KERNPG_TABLE  (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
44373 +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
44374 +
44375 +#define PAGE_NONE      __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
44376 +#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
44377 +#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
44378 +#define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
44379 +#define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
44380 +#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
44381 +
44382 +/*
44383 + * The i386 can't do page protection for execute, and considers that the same are read.
44384 + * Also, write permissions imply read permissions. This is the closest we can get..
44385 + */
44386 +#define __P000 PAGE_NONE
44387 +#define __P001 PAGE_READONLY
44388 +#define __P010 PAGE_COPY
44389 +#define __P011 PAGE_COPY
44390 +#define __P100 PAGE_READONLY
44391 +#define __P101 PAGE_READONLY
44392 +#define __P110 PAGE_COPY
44393 +#define __P111 PAGE_COPY
44394 +
44395 +#define __S000 PAGE_NONE
44396 +#define __S001 PAGE_READONLY
44397 +#define __S010 PAGE_SHARED
44398 +#define __S011 PAGE_SHARED
44399 +#define __S100 PAGE_READONLY
44400 +#define __S101 PAGE_READONLY
44401 +#define __S110 PAGE_SHARED
44402 +#define __S111 PAGE_SHARED
44403 +
44404 +/*
44405 + * Define this if things work differently on an i386 and an i486:
44406 + * it will (on an i486) warn about kernel memory accesses that are
44407 + * done without a 'verify_area(VERIFY_WRITE,..)'
44408 + */
44409 +#undef TEST_VERIFY_AREA
44410 +
44411 +/* page table for 0-4MB for everybody */
44412 +extern unsigned long pg0[1024];
44413 +
44414 +/*
44415 + * BAD_PAGETABLE is used when we need a bogus page-table, while
44416 + * BAD_PAGE is used for a bogus page.
44417 + *
44418 + * ZERO_PAGE is a global shared page that is always zero: used
44419 + * for zero-mapped memory areas etc..
44420 + */
44421 +extern pte_t __bad_page(void);
44422 +extern pte_t * __bad_pagetable(void);
44423 +
44424 +#define BAD_PAGETABLE __bad_pagetable()
44425 +#define BAD_PAGE __bad_page()
44426 +
44427 +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
44428 +
44429 +/* number of bits that fit into a memory pointer */
44430 +#define BITS_PER_PTR                   (8*sizeof(unsigned long))
44431 +
44432 +/* to align the pointer to a pointer address */
44433 +#define PTR_MASK                       (~(sizeof(void*)-1))
44434 +
44435 +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
44436 +/* 64-bit machines, beware!  SRB. */
44437 +#define SIZEOF_PTR_LOG2                        2
44438 +
44439 +/* to find an entry in a page-table */
44440 +#define PAGE_PTR(address) \
44441 +((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
44442 +
44443 +#define pte_none(x)    !(pte_val(x) & ~_PAGE_NEWPAGE)
44444 +#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
44445 +
44446 +#define pte_clear(xp)  do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
44447 +
44448 +#define pmd_none(x)    (!(pmd_val(x) & ~_PAGE_NEWPAGE))
44449 +#define        pmd_bad(x)      ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
44450 +#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
44451 +#define pmd_clear(xp)  do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
44452 +
44453 +#define pmd_newpage(x)  (pmd_val(x) & _PAGE_NEWPAGE)
44454 +#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE)
44455 +
44456 +/*
44457 + * The "pgd_xxx()" functions here are trivial for a folded two-level
44458 + * setup: the pgd is never bad, and a pmd always exists (as it's folded
44459 + * into the pgd entry)
44460 + */
44461 +static inline int pgd_none(pgd_t pgd)          { return 0; }
44462 +static inline int pgd_bad(pgd_t pgd)           { return 0; }
44463 +static inline int pgd_present(pgd_t pgd)       { return 1; }
44464 +static inline void pgd_clear(pgd_t * pgdp)     { }
44465 +
44466 +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
44467 +
44468 +#define pte_page(pte) virt_to_page(__va(pte_val(pte)))
44469 +#define pmd_page(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
44470 +
44471 +extern struct page *phys_to_page(const unsigned long phys);
44472 +extern struct page *__virt_to_page(const unsigned long virt);
44473 +#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
44474 +
44475 +static inline pte_t pte_mknewprot(pte_t pte)
44476 +{
44477 +       pte_val(pte) |= _PAGE_NEWPROT;
44478 +       return(pte);
44479 +}
44480 +
44481 +static inline pte_t pte_mknewpage(pte_t pte)
44482 +{
44483 +       pte_val(pte) |= _PAGE_NEWPAGE;
44484 +       return(pte);
44485 +}
44486 +
44487 +static inline void set_pte(pte_t *pteptr, pte_t pteval)
44488 +{
44489 +       /* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so
44490 +        * fix_range knows to unmap it.  _PAGE_NEWPROT is specific to
44491 +        * mapped pages.
44492 +        */
44493 +       *pteptr = pte_mknewpage(pteval);
44494 +       if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr);
44495 +}
44496 +
44497 +/*
44498 + * (pmds are folded into pgds so this doesnt get actually called,
44499 + * but the define is needed for a generic inline function.)
44500 + */
44501 +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
44502 +#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
44503 +
44504 +/*
44505 + * The following only work if pte_present() is true.
44506 + * Undefined behaviour if not..
44507 + */
44508 +static inline int pte_read(pte_t pte)
44509 +{ 
44510 +       return((pte_val(pte) & _PAGE_USER) && 
44511 +              !(pte_val(pte) & _PAGE_PROTNONE));
44512 +}
44513 +
44514 +static inline int pte_exec(pte_t pte){
44515 +       return((pte_val(pte) & _PAGE_USER) &&
44516 +              !(pte_val(pte) & _PAGE_PROTNONE));
44517 +}
44518 +
44519 +static inline int pte_write(pte_t pte)
44520 +{
44521 +       return((pte_val(pte) & _PAGE_RW) &&
44522 +              !(pte_val(pte) & _PAGE_PROTNONE));
44523 +}
44524 +
44525 +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
44526 +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
44527 +static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
44528 +static inline int pte_newprot(pte_t pte)
44529 +{ 
44530 +       return(pte_present(pte) && (pte_val(pte) & _PAGE_NEWPROT)); 
44531 +}
44532 +
44533 +static inline pte_t pte_rdprotect(pte_t pte)
44534 +{ 
44535 +       pte_val(pte) &= ~_PAGE_USER; 
44536 +       return(pte_mknewprot(pte));
44537 +}
44538 +
44539 +static inline pte_t pte_exprotect(pte_t pte)
44540 +{ 
44541 +       pte_val(pte) &= ~_PAGE_USER;
44542 +       return(pte_mknewprot(pte));
44543 +}
44544 +
44545 +static inline pte_t pte_mkclean(pte_t pte)
44546 +{
44547 +       pte_val(pte) &= ~_PAGE_DIRTY; 
44548 +       return(pte);
44549 +}
44550 +
44551 +static inline pte_t pte_mkold(pte_t pte)       
44552 +{ 
44553 +       pte_val(pte) &= ~_PAGE_ACCESSED; 
44554 +       return(pte);
44555 +}
44556 +
44557 +static inline pte_t pte_wrprotect(pte_t pte)
44558 +{ 
44559 +       pte_val(pte) &= ~_PAGE_RW; 
44560 +       return(pte_mknewprot(pte)); 
44561 +}
44562 +
44563 +static inline pte_t pte_mkread(pte_t pte)
44564 +{ 
44565 +       pte_val(pte) |= _PAGE_USER; 
44566 +       return(pte_mknewprot(pte)); 
44567 +}
44568 +
44569 +static inline pte_t pte_mkexec(pte_t pte)
44570 +{ 
44571 +       pte_val(pte) |= _PAGE_USER; 
44572 +       return(pte_mknewprot(pte)); 
44573 +}
44574 +
44575 +static inline pte_t pte_mkdirty(pte_t pte)
44576 +{ 
44577 +       pte_val(pte) |= _PAGE_DIRTY; 
44578 +       return(pte);
44579 +}
44580 +
44581 +static inline pte_t pte_mkyoung(pte_t pte)
44582 +{
44583 +       pte_val(pte) |= _PAGE_ACCESSED; 
44584 +       return(pte);
44585 +}
44586 +
44587 +static inline pte_t pte_mkwrite(pte_t pte)     
44588 +{
44589 +       pte_val(pte) |= _PAGE_RW; 
44590 +       return(pte_mknewprot(pte)); 
44591 +}
44592 +
44593 +static inline pte_t pte_mkuptodate(pte_t pte)  
44594 +{
44595 +       pte_val(pte) &= ~_PAGE_NEWPAGE;
44596 +       if(pte_present(pte)) pte_val(pte) &= ~_PAGE_NEWPROT;
44597 +       return(pte); 
44598 +}
44599 +
44600 +extern unsigned long page_to_phys(struct page *page);
44601 +
44602 +/*
44603 + * Conversion functions: convert a page and protection to a page entry,
44604 + * and a page entry and page directory to the page they refer to.
44605 + */
44606 +
44607 +extern pte_t mk_pte(struct page *page, pgprot_t pgprot);
44608 +
44609 +/* This takes a physical page address that is used by the remapping 
44610 + * functions 
44611 + */
44612 +#define mk_pte_phys(phys, pgprot) \
44613 +       (pte_mknewpage(mk_pte(virt_to_page(__va(phys)), pgprot)))
44614 +
44615 +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
44616 +{
44617 +       pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
44618 +       if(pte_present(pte)) pte = pte_mknewpage(pte_mknewprot(pte));
44619 +       return pte; 
44620 +}
44621 +
44622 +/* to find an entry in a page-table-directory. */
44623 +#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
44624 +#define __pgd_offset(address) pgd_index(address)
44625 +
44626 +/* to find an entry in a page-table-directory */
44627 +#define pgd_offset(mm, address) \
44628 +((mm)->pgd + ((address) >> PGDIR_SHIFT))
44629 +
44630 +/* to find an entry in a kernel page-table-directory */
44631 +#define pgd_offset_k(address) pgd_offset(&init_mm, address)
44632 +
44633 +#define __pmd_offset(address) \
44634 +               (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
44635 +
44636 +/* Find an entry in the second-level page table.. */
44637 +static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
44638 +{
44639 +       return (pmd_t *) dir;
44640 +}
44641 +
44642 +/* Find an entry in the third-level page table.. */ 
44643 +#define pte_offset(pmd, address) \
44644 +       ((pte_t *) (pmd_page(*pmd) + ((address>>10) & ((PTRS_PER_PTE-1)<<2))))
44645 +
44646 +#define update_mmu_cache(vma,address,pte) do ; while (0)
44647 +
44648 +/* Encode and de-code a swap entry */
44649 +#define SWP_TYPE(x)                    (((x).val >> 3) & 0x7f)
44650 +#define SWP_OFFSET(x)                  ((x).val >> 10)
44651 +
44652 +#define SWP_ENTRY(type, offset) \
44653 +       ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
44654 +#define pte_to_swp_entry(pte) \
44655 +       ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
44656 +#define swp_entry_to_pte(x)            ((pte_t) { (x).val })
44657 +
44658 +#define PageSkip(x) (0)
44659 +#define kern_addr_valid(addr) (1)
44660 +
44661 +#include <asm-generic/pgtable.h>
44662 +
44663 +#endif
44664 +
44665 +#endif
44666 +/*
44667 + * Overrides for Emacs so that we follow Linus's tabbing style.
44668 + * Emacs will notice this stuff at the end of the file and automatically
44669 + * adjust the settings for this buffer only.  This must remain at the end
44670 + * of the file.
44671 + * ---------------------------------------------------------------------------
44672 + * Local variables:
44673 + * c-file-style: "linux"
44674 + * End:
44675 + */
44676 Index: linux-2.4.29/include/asm-um/poll.h
44677 ===================================================================
44678 --- linux-2.4.29.orig/include/asm-um/poll.h     1970-01-01 03:00:00.000000000 +0300
44679 +++ linux-2.4.29/include/asm-um/poll.h  2005-05-03 22:28:14.973333920 +0300
44680 @@ -0,0 +1,6 @@
44681 +#ifndef __UM_POLL_H
44682 +#define __UM_POLL_H
44683 +
44684 +#include "asm/arch/poll.h"
44685 +
44686 +#endif
44687 Index: linux-2.4.29/include/asm-um/posix_types.h
44688 ===================================================================
44689 --- linux-2.4.29.orig/include/asm-um/posix_types.h      1970-01-01 03:00:00.000000000 +0300
44690 +++ linux-2.4.29/include/asm-um/posix_types.h   2005-05-03 22:28:14.974333768 +0300
44691 @@ -0,0 +1,6 @@
44692 +#ifndef __UM_POSIX_TYPES_H
44693 +#define __UM_POSIX_TYPES_H
44694 +
44695 +#include "asm/arch/posix_types.h"
44696 +
44697 +#endif
44698 Index: linux-2.4.29/include/asm-um/processor-generic.h
44699 ===================================================================
44700 --- linux-2.4.29.orig/include/asm-um/processor-generic.h        1970-01-01 03:00:00.000000000 +0300
44701 +++ linux-2.4.29/include/asm-um/processor-generic.h     2005-05-03 23:41:08.094518448 +0300
44702 @@ -0,0 +1,183 @@
44703 +/* 
44704 + * Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com)
44705 + * Licensed under the GPL
44706 + */
44707 +
44708 +#ifndef __UM_PROCESSOR_GENERIC_H
44709 +#define __UM_PROCESSOR_GENERIC_H
44710 +
44711 +struct pt_regs;
44712 +
44713 +struct task_struct;
44714 +
44715 +#include "linux/config.h"
44716 +#include "linux/signal.h"
44717 +#include "asm/ptrace.h"
44718 +#include "asm/siginfo.h"
44719 +#include "choose-mode.h"
44720 +
44721 +struct mm_struct;
44722 +
44723 +#define current_text_addr() ((void *) 0)
44724 +
44725 +#define cpu_relax()    do ; while (0)
44726 +
44727 +struct thread_struct {
44728 +       int forking;
44729 +       int nsyscalls;
44730 +       struct pt_regs regs;
44731 +       unsigned long cr2;
44732 +       int err;
44733 +       unsigned long trap_no;
44734 +       int singlestep_syscall;
44735 +       void *fault_addr;
44736 +       void *fault_catcher;
44737 +       struct task_struct *prev_sched;
44738 +       unsigned long temp_stack;
44739 +       void *exec_buf;
44740 +       struct arch_thread arch;
44741 +       union {
44742 +#ifdef CONFIG_MODE_TT
44743 +               struct {
44744 +                       int extern_pid;
44745 +                       int tracing;
44746 +                       /* XXX This is really two filehandles, but they contain
44747 +                        * lists, and list.h includes processor.h through
44748 +                        * prefetch.h before defining struct list, so this
44749 +                        * makes the lists' sizes unknown at this point.
44750 +                        * So, this is a void *, and allocated separately.
44751 +                        * Check to see if this is fixed in 2.6.
44752 +                        */
44753 +                       void *switch_pipe;
44754 +                       int singlestep_syscall;
44755 +                       int vm_seq;
44756 +               } tt;
44757 +#endif
44758 +#ifdef CONFIG_MODE_SKAS
44759 +               struct {
44760 +                       void *switch_buf;
44761 +                       void *fork_buf;
44762 +                       int mm_count;
44763 +               } skas;
44764 +#endif
44765 +       } mode;
44766 +       struct {
44767 +               int op;
44768 +               union {
44769 +                       struct {
44770 +                               int pid;
44771 +                       } fork, exec;
44772 +                       struct {
44773 +                               int (*proc)(void *);
44774 +                               void *arg;
44775 +                       } thread;
44776 +                       struct {
44777 +                               void (*proc)(void *);
44778 +                               void *arg;
44779 +                       } cb;
44780 +               } u;
44781 +       } request;
44782 +};
44783 +
44784 +#define INIT_THREAD \
44785 +{ \
44786 +       .forking                = 0, \
44787 +       .nsyscalls              = 0, \
44788 +        .regs                  = EMPTY_REGS, \
44789 +       .cr2                    = 0, \
44790 +       .err                    = 0, \
44791 +       .fault_addr             = NULL, \
44792 +       .prev_sched             = NULL, \
44793 +       .temp_stack             = 0, \
44794 +       .exec_buf               = NULL, \
44795 +       .arch                   = INIT_ARCH_THREAD, \
44796 +       .request                = { 0 } \
44797 +}
44798 +
44799 +#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
44800 +
44801 +typedef struct {
44802 +       unsigned long seg;
44803 +} mm_segment_t;
44804 +
44805 +extern struct task_struct *alloc_task_struct(void);
44806 +extern void free_task_struct(struct task_struct *task);
44807 +
44808 +#define get_task_struct(tsk)      atomic_inc(&virt_to_page(tsk)->count)
44809 +
44810 +extern void release_thread(struct task_struct *);
44811 +extern int arch_kernel_thread(int (*fn)(void *), void * arg, 
44812 +                             unsigned long flags);
44813 +extern void dump_thread(struct pt_regs *regs, struct user *u);
44814 +
44815 +extern unsigned long thread_saved_pc(struct thread_struct *t);
44816 +
44817 +static inline void mm_copy_segments(struct mm_struct *from_mm, 
44818 +                                   struct mm_struct *new_mm)
44819 +{
44820 +}
44821 +
44822 +static inline void copy_segments(struct task_struct *p, 
44823 +                                struct mm_struct *new_mm)
44824 +{
44825 +}
44826 +
44827 +static inline void release_segments(struct mm_struct *mm)
44828 +{
44829 +}
44830 +
44831 +#define init_task      (init_task_union.task)
44832 +#define init_stack     (init_task_union.stack)
44833 +
44834 +/*
44835 + * User space process size: 3GB (default).
44836 + */
44837 +extern unsigned long task_size;
44838 +
44839 +#define TASK_SIZE      (task_size)
44840 +
44841 +/* This decides where the kernel will search for a free chunk of vm
44842 + * space during mmap's.
44843 + */
44844 +#define TASK_UNMAPPED_BASE     (0x40000000)
44845 +
44846 +extern void start_thread(struct pt_regs *regs, unsigned long entry, 
44847 +                        unsigned long stack);
44848 +
44849 +struct cpuinfo_um {
44850 +       unsigned long loops_per_jiffy;
44851 +       unsigned long *pgd_quick;
44852 +       unsigned long *pmd_quick;
44853 +       unsigned long *pte_quick;
44854 +       unsigned long pgtable_cache_sz;  
44855 +       int ipi_pipe[2];
44856 +};
44857 +
44858 +extern struct cpuinfo_um boot_cpu_data;
44859 +
44860 +#define my_cpu_data            cpu_data[smp_processor_id()]
44861 +
44862 +#ifdef CONFIG_SMP
44863 +extern struct cpuinfo_um cpu_data[];
44864 +#define current_cpu_data cpu_data[smp_processor_id()]
44865 +#else
44866 +#define cpu_data (&boot_cpu_data)
44867 +#define current_cpu_data boot_cpu_data
44868 +#endif
44869 +
44870 +#define KSTK_EIP(tsk) (PT_REGS_IP(&tsk->thread.regs))
44871 +#define KSTK_ESP(tsk) (PT_REGS_SP(&tsk->thread.regs))
44872 +#define get_wchan(p) (0)
44873 +
44874 +#endif
44875 +
44876 +/*
44877 + * Overrides for Emacs so that we follow Linus's tabbing style.
44878 + * Emacs will notice this stuff at the end of the file and automatically
44879 + * adjust the settings for this buffer only.  This must remain at the end
44880 + * of the file.
44881 + * ---------------------------------------------------------------------------
44882 + * Local variables:
44883 + * c-file-style: "linux"
44884 + * End:
44885 + */
44886 Index: linux-2.4.29/include/asm-um/processor-i386.h
44887 ===================================================================
44888 --- linux-2.4.29.orig/include/asm-um/processor-i386.h   1970-01-01 03:00:00.000000000 +0300
44889 +++ linux-2.4.29/include/asm-um/processor-i386.h        2005-05-03 23:41:08.095518296 +0300
44890 @@ -0,0 +1,35 @@
44891 +/* 
44892 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
44893 + * Licensed under the GPL
44894 + */
44895 +
44896 +#ifndef __UM_PROCESSOR_I386_H
44897 +#define __UM_PROCESSOR_I386_H
44898 +
44899 +extern int cpu_has_xmm;
44900 +extern int cpu_has_cmov;
44901 +
44902 +struct arch_thread {
44903 +       unsigned long debugregs[8];
44904 +       int debugregs_seq;
44905 +};
44906 +
44907 +#define INIT_ARCH_THREAD { .debugregs                  = { [ 0 ... 7 ] = 0 }, \
44908 +                           .debugregs_seq      = 0 }
44909 +
44910 +#include "asm/arch/user.h"
44911 +
44912 +#include "asm/processor-generic.h"
44913 +
44914 +#endif
44915 +
44916 +/*
44917 + * Overrides for Emacs so that we follow Linus's tabbing style.
44918 + * Emacs will notice this stuff at the end of the file and automatically
44919 + * adjust the settings for this buffer only.  This must remain at the end
44920 + * of the file.
44921 + * ---------------------------------------------------------------------------
44922 + * Local variables:
44923 + * c-file-style: "linux"
44924 + * End:
44925 + */
44926 Index: linux-2.4.29/include/asm-um/processor-ppc.h
44927 ===================================================================
44928 --- linux-2.4.29.orig/include/asm-um/processor-ppc.h    1970-01-01 03:00:00.000000000 +0300
44929 +++ linux-2.4.29/include/asm-um/processor-ppc.h 2005-05-03 22:28:14.000000000 +0300
44930 @@ -0,0 +1,15 @@
44931 +#ifndef __UM_PROCESSOR_PPC_H
44932 +#define __UM_PROCESSOR_PPC_H
44933 +
44934 +#if defined(__ASSEMBLY__)
44935 +
44936 +#define CONFIG_ALL_PPC
44937 +#include "arch/processor.h"
44938 +
44939 +#else
44940 +
44941 +#include "asm/processor-generic.h"
44942 +
44943 +#endif
44944 +
44945 +#endif
44946 Index: linux-2.4.29/include/asm-um/ptrace-generic.h
44947 ===================================================================
44948 --- linux-2.4.29.orig/include/asm-um/ptrace-generic.h   1970-01-01 03:00:00.000000000 +0300
44949 +++ linux-2.4.29/include/asm-um/ptrace-generic.h        2005-05-03 23:41:08.084519968 +0300
44950 @@ -0,0 +1,74 @@
44951 +/* 
44952 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
44953 + * Licensed under the GPL
44954 + */
44955 +
44956 +#ifndef __UM_PTRACE_GENERIC_H
44957 +#define __UM_PTRACE_GENERIC_H
44958 +
44959 +#ifndef __ASSEMBLY__
44960 +
44961 +#include "linux/config.h"
44962 +
44963 +#include "asm/current.h"
44964 +
44965 +#define pt_regs pt_regs_subarch
44966 +#define show_regs show_regs_subarch
44967 +
44968 +#include "asm/arch/ptrace.h"
44969 +
44970 +#undef pt_regs
44971 +#undef show_regs
44972 +#undef user_mode
44973 +#undef instruction_pointer
44974 +
44975 +#include "sysdep/ptrace.h"
44976 +#include "skas_ptrace.h"
44977 +
44978 +struct pt_regs {
44979 +       union uml_pt_regs regs;
44980 +};
44981 +
44982 +#define EMPTY_REGS { regs : EMPTY_UML_PT_REGS }
44983 +
44984 +#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
44985 +#define PT_REGS_SP(r) UPT_SP(&(r)->regs)
44986 +
44987 +#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg)
44988 +#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val)
44989 +
44990 +#define PT_REGS_SET_SYSCALL_RETURN(r, res) \
44991 +       UPT_SET_SYSCALL_RETURN(&(r)->regs, res)
44992 +#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs)
44993 +
44994 +#define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs)
44995 +
44996 +#define PT_REGS_SC(r) UPT_SC(&(r)->regs)
44997 +
44998 +struct task_struct;
44999 +
45000 +extern unsigned long getreg(struct task_struct *child, int regno);
45001 +extern int putreg(struct task_struct *child, int regno, unsigned long value);
45002 +extern int get_fpregs(unsigned long buf, struct task_struct *child);
45003 +extern int set_fpregs(unsigned long buf, struct task_struct *child);
45004 +extern int get_fpxregs(unsigned long buf, struct task_struct *child);
45005 +extern int set_fpxregs(unsigned long buf, struct task_struct *tsk);
45006 +
45007 +extern void show_regs(struct pt_regs *regs);
45008 +
45009 +#define INIT_TASK_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
45010 +
45011 +#endif
45012 +
45013 +#endif
45014 +
45015 +/*
45016 + * Overrides for Emacs so that we follow Linus's tabbing style.
45017 + * Emacs will notice this stuff at the end of the file and automatically
45018 + * adjust the settings for this buffer only.  This must remain at the end
45019 + * of the file.
45020 + * ---------------------------------------------------------------------------
45021 + * Local variables:
45022 + * c-file-style: "linux"
45023 + * End:
45024 + */
45025 Index: linux-2.4.29/include/asm-um/ptrace-i386.h
45026 ===================================================================
45027 --- linux-2.4.29.orig/include/asm-um/ptrace-i386.h      1970-01-01 03:00:00.000000000 +0300
45028 +++ linux-2.4.29/include/asm-um/ptrace-i386.h   2005-05-03 23:41:08.085519816 +0300
45029 @@ -0,0 +1,46 @@
45030 +/* 
45031 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
45032 + * Licensed under the GPL
45033 + */
45034 +
45035 +#ifndef __UM_PTRACE_I386_H
45036 +#define __UM_PTRACE_I386_H
45037 +
45038 +#include "sysdep/ptrace.h"
45039 +#include "asm/ptrace-generic.h"
45040 +
45041 +#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
45042 +#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs)
45043 +#define PT_REGS_ECX(r) UPT_ECX(&(r)->regs)
45044 +#define PT_REGS_EDX(r) UPT_EDX(&(r)->regs)
45045 +#define PT_REGS_ESI(r) UPT_ESI(&(r)->regs)
45046 +#define PT_REGS_EDI(r) UPT_EDI(&(r)->regs)
45047 +#define PT_REGS_EBP(r) UPT_EBP(&(r)->regs)
45048 +
45049 +#define PT_REGS_CS(r) UPT_CS(&(r)->regs)
45050 +#define PT_REGS_SS(r) UPT_SS(&(r)->regs)
45051 +#define PT_REGS_DS(r) UPT_DS(&(r)->regs)
45052 +#define PT_REGS_ES(r) UPT_ES(&(r)->regs)
45053 +#define PT_REGS_FS(r) UPT_FS(&(r)->regs)
45054 +#define PT_REGS_GS(r) UPT_GS(&(r)->regs)
45055 +
45056 +#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs)
45057 +
45058 +#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_EAX(r)
45059 +#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r)
45060 +#define PT_FIX_EXEC_STACK(sp) do ; while(0)
45061 +
45062 +#define user_mode(r) UPT_IS_USER(&(r)->regs)
45063 +
45064 +#endif
45065 +
45066 +/*
45067 + * Overrides for Emacs so that we follow Linus's tabbing style.
45068 + * Emacs will notice this stuff at the end of the file and automatically
45069 + * adjust the settings for this buffer only.  This must remain at the end
45070 + * of the file.
45071 + * ---------------------------------------------------------------------------
45072 + * Local variables:
45073 + * c-file-style: "linux"
45074 + * End:
45075 + */
45076 Index: linux-2.4.29/include/asm-um/resource.h
45077 ===================================================================
45078 --- linux-2.4.29.orig/include/asm-um/resource.h 1970-01-01 03:00:00.000000000 +0300
45079 +++ linux-2.4.29/include/asm-um/resource.h      2005-05-03 22:28:14.980332856 +0300
45080 @@ -0,0 +1,6 @@
45081 +#ifndef __UM_RESOURCE_H
45082 +#define __UM_RESOURCE_H
45083 +
45084 +#include "asm/arch/resource.h"
45085 +
45086 +#endif
45087 Index: linux-2.4.29/include/asm-um/rwlock.h
45088 ===================================================================
45089 --- linux-2.4.29.orig/include/asm-um/rwlock.h   1970-01-01 03:00:00.000000000 +0300
45090 +++ linux-2.4.29/include/asm-um/rwlock.h        2005-05-03 22:28:14.000000000 +0300
45091 @@ -0,0 +1,6 @@
45092 +#ifndef __UM_RWLOCK_H
45093 +#define __UM_RWLOCK_H
45094 +
45095 +#include "asm/arch/rwlock.h"
45096 +
45097 +#endif
45098 Index: linux-2.4.29/include/asm-um/rwsem.h
45099 ===================================================================
45100 --- linux-2.4.29.orig/include/asm-um/rwsem.h    1970-01-01 03:00:00.000000000 +0300
45101 +++ linux-2.4.29/include/asm-um/rwsem.h 2005-05-03 23:41:08.109516168 +0300
45102 @@ -0,0 +1,10 @@
45103 +#ifndef __UM_RWSEM_H__
45104 +#define __UM_RWSEM_H__
45105 +
45106 +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
45107 +#define __builtin_expect(exp,c) (exp)
45108 +#endif
45109 +
45110 +#include "asm/arch/rwsem.h"
45111 +
45112 +#endif
45113 Index: linux-2.4.29/include/asm-um/scatterlist.h
45114 ===================================================================
45115 --- linux-2.4.29.orig/include/asm-um/scatterlist.h      1970-01-01 03:00:00.000000000 +0300
45116 +++ linux-2.4.29/include/asm-um/scatterlist.h   2005-05-03 22:28:14.000000000 +0300
45117 @@ -0,0 +1,6 @@
45118 +#ifndef __UM_SCATTERLIST_H
45119 +#define __UM_SCATTERLIST_H
45120 +
45121 +#include "asm/arch/scatterlist.h"
45122 +
45123 +#endif
45124 Index: linux-2.4.29/include/asm-um/segment.h
45125 ===================================================================
45126 --- linux-2.4.29.orig/include/asm-um/segment.h  1970-01-01 03:00:00.000000000 +0300
45127 +++ linux-2.4.29/include/asm-um/segment.h       2005-05-03 22:28:14.983332400 +0300
45128 @@ -0,0 +1,4 @@
45129 +#ifndef __UM_SEGMENT_H
45130 +#define __UM_SEGMENT_H
45131 +
45132 +#endif
45133 Index: linux-2.4.29/include/asm-um/semaphore.h
45134 ===================================================================
45135 --- linux-2.4.29.orig/include/asm-um/semaphore.h        1970-01-01 03:00:00.000000000 +0300
45136 +++ linux-2.4.29/include/asm-um/semaphore.h     2005-05-03 23:41:08.110516016 +0300
45137 @@ -0,0 +1,6 @@
45138 +#ifndef __UM_SEMAPHORE_H
45139 +#define __UM_SEMAPHORE_H
45140 +
45141 +#include "asm/arch/semaphore.h"
45142 +
45143 +#endif
45144 Index: linux-2.4.29/include/asm-um/sembuf.h
45145 ===================================================================
45146 --- linux-2.4.29.orig/include/asm-um/sembuf.h   1970-01-01 03:00:00.000000000 +0300
45147 +++ linux-2.4.29/include/asm-um/sembuf.h        2005-05-03 22:28:14.984332248 +0300
45148 @@ -0,0 +1,6 @@
45149 +#ifndef __UM_SEMBUF_H
45150 +#define __UM_SEMBUF_H
45151 +
45152 +#include "asm/arch/sembuf.h"
45153 +
45154 +#endif
45155 Index: linux-2.4.29/include/asm-um/serial.h
45156 ===================================================================
45157 --- linux-2.4.29.orig/include/asm-um/serial.h   1970-01-01 03:00:00.000000000 +0300
45158 +++ linux-2.4.29/include/asm-um/serial.h        2005-05-03 22:28:14.000000000 +0300
45159 @@ -0,0 +1,6 @@
45160 +#ifndef __UM_SERIAL_H
45161 +#define __UM_SERIAL_H
45162 +
45163 +#include "asm/arch/serial.h"
45164 +
45165 +#endif
45166 Index: linux-2.4.29/include/asm-um/shmbuf.h
45167 ===================================================================
45168 --- linux-2.4.29.orig/include/asm-um/shmbuf.h   1970-01-01 03:00:00.000000000 +0300
45169 +++ linux-2.4.29/include/asm-um/shmbuf.h        2005-05-03 22:28:14.000000000 +0300
45170 @@ -0,0 +1,6 @@
45171 +#ifndef __UM_SHMBUF_H
45172 +#define __UM_SHMBUF_H
45173 +
45174 +#include "asm/arch/shmbuf.h"
45175 +
45176 +#endif
45177 Index: linux-2.4.29/include/asm-um/shmparam.h
45178 ===================================================================
45179 --- linux-2.4.29.orig/include/asm-um/shmparam.h 1970-01-01 03:00:00.000000000 +0300
45180 +++ linux-2.4.29/include/asm-um/shmparam.h      2005-05-03 22:28:14.000000000 +0300
45181 @@ -0,0 +1,6 @@
45182 +#ifndef __UM_SHMPARAM_H
45183 +#define __UM_SHMPARAM_H
45184 +
45185 +#include "asm/arch/shmparam.h"
45186 +
45187 +#endif
45188 Index: linux-2.4.29/include/asm-um/sigcontext-generic.h
45189 ===================================================================
45190 --- linux-2.4.29.orig/include/asm-um/sigcontext-generic.h       1970-01-01 03:00:00.000000000 +0300
45191 +++ linux-2.4.29/include/asm-um/sigcontext-generic.h    2005-05-03 22:28:14.987331792 +0300
45192 @@ -0,0 +1,6 @@
45193 +#ifndef __UM_SIGCONTEXT_GENERIC_H
45194 +#define __UM_SIGCONTEXT_GENERIC_H
45195 +
45196 +#include "asm/arch/sigcontext.h"
45197 +
45198 +#endif
45199 Index: linux-2.4.29/include/asm-um/sigcontext-i386.h
45200 ===================================================================
45201 --- linux-2.4.29.orig/include/asm-um/sigcontext-i386.h  1970-01-01 03:00:00.000000000 +0300
45202 +++ linux-2.4.29/include/asm-um/sigcontext-i386.h       2005-05-03 22:28:14.988331640 +0300
45203 @@ -0,0 +1,6 @@
45204 +#ifndef __UM_SIGCONTEXT_I386_H
45205 +#define __UM_SIGCONTEXT_I386_H
45206 +
45207 +#include "asm/sigcontext-generic.h"
45208 +
45209 +#endif
45210 Index: linux-2.4.29/include/asm-um/sigcontext-ppc.h
45211 ===================================================================
45212 --- linux-2.4.29.orig/include/asm-um/sigcontext-ppc.h   1970-01-01 03:00:00.000000000 +0300
45213 +++ linux-2.4.29/include/asm-um/sigcontext-ppc.h        2005-05-03 22:28:14.000000000 +0300
45214 @@ -0,0 +1,10 @@
45215 +#ifndef __UM_SIGCONTEXT_PPC_H
45216 +#define __UM_SIGCONTEXT_PPC_H
45217 +
45218 +#define pt_regs sys_pt_regs
45219 +
45220 +#include "asm/sigcontext-generic.h"
45221 +
45222 +#undef pt_regs
45223 +
45224 +#endif
45225 Index: linux-2.4.29/include/asm-um/siginfo.h
45226 ===================================================================
45227 --- linux-2.4.29.orig/include/asm-um/siginfo.h  1970-01-01 03:00:00.000000000 +0300
45228 +++ linux-2.4.29/include/asm-um/siginfo.h       2005-05-03 23:41:08.092518752 +0300
45229 @@ -0,0 +1,6 @@
45230 +#ifndef __UM_SIGINFO_H
45231 +#define __UM_SIGINFO_H
45232 +
45233 +#include "asm/arch/siginfo.h"
45234 +
45235 +#endif
45236 Index: linux-2.4.29/include/asm-um/signal.h
45237 ===================================================================
45238 --- linux-2.4.29.orig/include/asm-um/signal.h   1970-01-01 03:00:00.000000000 +0300
45239 +++ linux-2.4.29/include/asm-um/signal.h        2005-05-03 23:41:08.090519056 +0300
45240 @@ -0,0 +1,22 @@
45241 +/* 
45242 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
45243 + * Licensed under the GPL
45244 + */
45245 +
45246 +#ifndef __UM_SIGNAL_H
45247 +#define __UM_SIGNAL_H
45248 +
45249 +#include "asm/arch/signal.h"
45250 +
45251 +#endif
45252 +
45253 +/*
45254 + * Overrides for Emacs so that we follow Linus's tabbing style.
45255 + * Emacs will notice this stuff at the end of the file and automatically
45256 + * adjust the settings for this buffer only.  This must remain at the end
45257 + * of the file.
45258 + * ---------------------------------------------------------------------------
45259 + * Local variables:
45260 + * c-file-style: "linux"
45261 + * End:
45262 + */
45263 Index: linux-2.4.29/include/asm-um/smp.h
45264 ===================================================================
45265 --- linux-2.4.29.orig/include/asm-um/smp.h      1970-01-01 03:00:00.000000000 +0300
45266 +++ linux-2.4.29/include/asm-um/smp.h   2005-05-03 23:41:09.801258984 +0300
45267 @@ -0,0 +1,19 @@
45268 +#ifndef __UM_SMP_H
45269 +#define __UM_SMP_H
45270 +
45271 +#ifdef CONFIG_SMP
45272 +
45273 +#include "linux/config.h"
45274 +#include "asm/current.h"
45275 +
45276 +#define smp_processor_id() (current->processor)
45277 +#define cpu_logical_map(n) (n)
45278 +#define cpu_number_map(n) (n)
45279 +#define PROC_CHANGE_PENALTY    15 /* Pick a number, any number */
45280 +extern int hard_smp_processor_id(void);
45281 +extern unsigned long cpu_online_map;
45282 +#define NO_PROC_ID -1
45283 +
45284 +#endif
45285 +
45286 +#endif
45287 Index: linux-2.4.29/include/asm-um/smplock.h
45288 ===================================================================
45289 --- linux-2.4.29.orig/include/asm-um/smplock.h  1970-01-01 03:00:00.000000000 +0300
45290 +++ linux-2.4.29/include/asm-um/smplock.h       2005-05-03 23:41:09.912242112 +0300
45291 @@ -0,0 +1,6 @@
45292 +#ifndef __UM_SMPLOCK_H
45293 +#define __UM_SMPLOCK_H
45294 +
45295 +#include "asm/arch/smplock.h"
45296 +
45297 +#endif
45298 Index: linux-2.4.29/include/asm-um/socket.h
45299 ===================================================================
45300 --- linux-2.4.29.orig/include/asm-um/socket.h   1970-01-01 03:00:00.000000000 +0300
45301 +++ linux-2.4.29/include/asm-um/socket.h        2005-05-03 22:37:45.384618224 +0300
45302 @@ -0,0 +1,6 @@
45303 +#ifndef __UM_SOCKET_H
45304 +#define __UM_SOCKET_H
45305 +
45306 +#include "asm/arch/socket.h"
45307 +
45308 +#endif
45309 Index: linux-2.4.29/include/asm-um/sockios.h
45310 ===================================================================
45311 --- linux-2.4.29.orig/include/asm-um/sockios.h  1970-01-01 03:00:00.000000000 +0300
45312 +++ linux-2.4.29/include/asm-um/sockios.h       2005-05-03 22:28:14.994330728 +0300
45313 @@ -0,0 +1,6 @@
45314 +#ifndef __UM_SOCKIOS_H
45315 +#define __UM_SOCKIOS_H
45316 +
45317 +#include "asm/arch/sockios.h"
45318 +
45319 +#endif
45320 Index: linux-2.4.29/include/asm-um/softirq.h
45321 ===================================================================
45322 --- linux-2.4.29.orig/include/asm-um/softirq.h  1970-01-01 03:00:00.000000000 +0300
45323 +++ linux-2.4.29/include/asm-um/softirq.h       2005-05-03 23:41:09.910242416 +0300
45324 @@ -0,0 +1,13 @@
45325 +#ifndef __UM_SOFTIRQ_H
45326 +#define __UM_SOFTIRQ_H
45327 +
45328 +#include "linux/smp.h"
45329 +#include "asm/system.h"
45330 +#include "asm/processor.h"
45331 +
45332 +/* A gratuitous name change */
45333 +#define i386_bh_lock um_bh_lock
45334 +#include "asm/arch/softirq.h"
45335 +#undef i386_bh_lock
45336 +
45337 +#endif
45338 Index: linux-2.4.29/include/asm-um/spinlock.h
45339 ===================================================================
45340 --- linux-2.4.29.orig/include/asm-um/spinlock.h 1970-01-01 03:00:00.000000000 +0300
45341 +++ linux-2.4.29/include/asm-um/spinlock.h      2005-05-03 23:41:08.101517384 +0300
45342 @@ -0,0 +1,10 @@
45343 +#ifndef __UM_SPINLOCK_H
45344 +#define __UM_SPINLOCK_H
45345 +
45346 +#include "linux/config.h"
45347 +
45348 +#ifdef CONFIG_SMP
45349 +#include "asm/arch/spinlock.h"
45350 +#endif
45351 +
45352 +#endif
45353 Index: linux-2.4.29/include/asm-um/statfs.h
45354 ===================================================================
45355 --- linux-2.4.29.orig/include/asm-um/statfs.h   1970-01-01 03:00:00.000000000 +0300
45356 +++ linux-2.4.29/include/asm-um/statfs.h        2005-05-03 23:41:08.104516928 +0300
45357 @@ -0,0 +1,6 @@
45358 +#ifndef _UM_STATFS_H
45359 +#define _UM_STATFS_H
45360 +
45361 +#include "asm/arch/statfs.h"
45362 +
45363 +#endif
45364 Index: linux-2.4.29/include/asm-um/stat.h
45365 ===================================================================
45366 --- linux-2.4.29.orig/include/asm-um/stat.h     1970-01-01 03:00:00.000000000 +0300
45367 +++ linux-2.4.29/include/asm-um/stat.h  2005-05-03 22:28:14.997330272 +0300
45368 @@ -0,0 +1,6 @@
45369 +#ifndef __UM_STAT_H
45370 +#define __UM_STAT_H
45371 +
45372 +#include "asm/arch/stat.h"
45373 +
45374 +#endif
45375 Index: linux-2.4.29/include/asm-um/string.h
45376 ===================================================================
45377 --- linux-2.4.29.orig/include/asm-um/string.h   1970-01-01 03:00:00.000000000 +0300
45378 +++ linux-2.4.29/include/asm-um/string.h        2005-05-03 22:28:14.998330120 +0300
45379 @@ -0,0 +1,7 @@
45380 +#ifndef __UM_STRING_H
45381 +#define __UM_STRING_H
45382 +
45383 +#include "asm/arch/string.h"
45384 +#include "asm/archparam.h"
45385 +
45386 +#endif
45387 Index: linux-2.4.29/include/asm-um/system-generic.h
45388 ===================================================================
45389 --- linux-2.4.29.orig/include/asm-um/system-generic.h   1970-01-01 03:00:00.000000000 +0300
45390 +++ linux-2.4.29/include/asm-um/system-generic.h        2005-05-03 23:41:08.098517840 +0300
45391 @@ -0,0 +1,50 @@
45392 +#ifndef __UM_SYSTEM_GENERIC_H
45393 +#define __UM_SYSTEM_GENERIC_H
45394 +
45395 +#include "asm/arch/system.h"
45396 +
45397 +#undef prepare_to_switch
45398 +#undef switch_to
45399 +#undef __save_flags
45400 +#undef save_flags
45401 +#undef __restore_flags
45402 +#undef restore_flags
45403 +#undef __cli
45404 +#undef __sti
45405 +#undef cli
45406 +#undef sti
45407 +#undef local_irq_save
45408 +#undef local_irq_restore
45409 +#undef local_irq_disable
45410 +#undef local_irq_enable
45411 +
45412 +#define prepare_to_switch() do ; while(0)
45413 +
45414 +void *_switch_to(void *prev, void *next);
45415 +
45416 +#define switch_to(prev, next, last) prev = _switch_to(prev, next)
45417 +
45418 +extern int get_signals(void);
45419 +extern int set_signals(int enable);
45420 +extern void block_signals(void);
45421 +extern void unblock_signals(void);
45422 +
45423 +#define local_irq_save(flags) do { (flags) = set_signals(0); } while(0)
45424 +
45425 +#define local_irq_restore(flags) do { set_signals(flags); } while(0)
45426 +
45427 +#define local_irq_enable() unblock_signals()
45428 +#define local_irq_disable() block_signals()
45429 +
45430 +#define __sti() unblock_signals()
45431 +#define sti() unblock_signals()
45432 +#define __cli() block_signals()
45433 +#define cli() block_signals()
45434 +
45435 +#define __save_flags(x) do { (x) = get_signals(); } while(0)
45436 +#define save_flags(x) __save_flags(x)
45437 +
45438 +#define __restore_flags(x) local_irq_restore(x)
45439 +#define restore_flags(x) __restore_flags(x)
45440 +
45441 +#endif
45442 Index: linux-2.4.29/include/asm-um/system-i386.h
45443 ===================================================================
45444 --- linux-2.4.29.orig/include/asm-um/system-i386.h      1970-01-01 03:00:00.000000000 +0300
45445 +++ linux-2.4.29/include/asm-um/system-i386.h   2005-05-03 23:41:08.098517840 +0300
45446 @@ -0,0 +1,8 @@
45447 +#ifndef __UM_SYSTEM_I386_H
45448 +#define __UM_SYSTEM_I386_H
45449 +
45450 +#include "asm/system-generic.h"
45451 +
45452 +#define __HAVE_ARCH_CMPXCHG 1
45453 +
45454 +#endif
45455 Index: linux-2.4.29/include/asm-um/system-ppc.h
45456 ===================================================================
45457 --- linux-2.4.29.orig/include/asm-um/system-ppc.h       1970-01-01 03:00:00.000000000 +0300
45458 +++ linux-2.4.29/include/asm-um/system-ppc.h    2005-05-03 22:28:15.000000000 +0300
45459 @@ -0,0 +1,12 @@
45460 +#ifndef __UM_SYSTEM_PPC_H
45461 +#define __UM_SYSTEM_PPC_H
45462 +
45463 +#define _switch_to _ppc_switch_to
45464 +
45465 +#include "asm/arch/system.h"
45466 +
45467 +#undef _switch_to
45468
45469 +#include "asm/system-generic.h"
45470 +
45471 +#endif
45472 Index: linux-2.4.29/include/asm-um/termbits.h
45473 ===================================================================
45474 --- linux-2.4.29.orig/include/asm-um/termbits.h 1970-01-01 03:00:00.000000000 +0300
45475 +++ linux-2.4.29/include/asm-um/termbits.h      2005-05-03 22:37:45.506599680 +0300
45476 @@ -0,0 +1,6 @@
45477 +#ifndef __UM_TERMBITS_H
45478 +#define __UM_TERMBITS_H
45479 +
45480 +#include "asm/arch/termbits.h"
45481 +
45482 +#endif
45483 Index: linux-2.4.29/include/asm-um/termios.h
45484 ===================================================================
45485 --- linux-2.4.29.orig/include/asm-um/termios.h  1970-01-01 03:00:00.000000000 +0300
45486 +++ linux-2.4.29/include/asm-um/termios.h       2005-05-03 22:37:45.512598768 +0300
45487 @@ -0,0 +1,6 @@
45488 +#ifndef __UM_TERMIOS_H
45489 +#define __UM_TERMIOS_H
45490 +
45491 +#include "asm/arch/termios.h"
45492 +
45493 +#endif
45494 Index: linux-2.4.29/include/asm-um/timex.h
45495 ===================================================================
45496 --- linux-2.4.29.orig/include/asm-um/timex.h    1970-01-01 03:00:00.000000000 +0300
45497 +++ linux-2.4.29/include/asm-um/timex.h 2005-05-03 23:41:09.799259288 +0300
45498 @@ -0,0 +1,18 @@
45499 +#ifndef __UM_TIMEX_H
45500 +#define __UM_TIMEX_H
45501 +
45502 +#include "linux/time.h"
45503 +
45504 +typedef unsigned long cycles_t;
45505 +
45506 +#define cacheflush_time (0)
45507 +
45508 +static inline cycles_t get_cycles (void)
45509 +{
45510 +       return 0;
45511 +}
45512 +
45513 +#define vxtime_lock()          do ; while (0)
45514 +#define vxtime_unlock()                do ; while (0)
45515 +
45516 +#endif
45517 Index: linux-2.4.29/include/asm-um/tlb.h
45518 ===================================================================
45519 --- linux-2.4.29.orig/include/asm-um/tlb.h      1970-01-01 03:00:00.000000000 +0300
45520 +++ linux-2.4.29/include/asm-um/tlb.h   2005-05-03 22:28:15.000000000 +0300
45521 @@ -0,0 +1 @@
45522 +#include <asm-generic/tlb.h>
45523 Index: linux-2.4.29/include/asm-um/types.h
45524 ===================================================================
45525 --- linux-2.4.29.orig/include/asm-um/types.h    1970-01-01 03:00:00.000000000 +0300
45526 +++ linux-2.4.29/include/asm-um/types.h 2005-05-03 22:28:15.006328904 +0300
45527 @@ -0,0 +1,6 @@
45528 +#ifndef __UM_TYPES_H
45529 +#define __UM_TYPES_H
45530 +
45531 +#include "asm/arch/types.h"
45532 +
45533 +#endif
45534 Index: linux-2.4.29/include/asm-um/uaccess.h
45535 ===================================================================
45536 --- linux-2.4.29.orig/include/asm-um/uaccess.h  1970-01-01 03:00:00.000000000 +0300
45537 +++ linux-2.4.29/include/asm-um/uaccess.h       2005-05-03 23:41:09.913241960 +0300
45538 @@ -0,0 +1,99 @@
45539 +/* 
45540 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
45541 + * Licensed under the GPL
45542 + */
45543 +
45544 +#ifndef __UM_UACCESS_H
45545 +#define __UM_UACCESS_H
45546 +
45547 +#include "linux/sched.h"
45548 +
45549 +#define VERIFY_READ 0
45550 +#define VERIFY_WRITE 1
45551 +
45552 +/*
45553 + * The fs value determines whether argument validity checking should be
45554 + * performed or not.  If get_fs() == USER_DS, checking is performed, with
45555 + * get_fs() == KERNEL_DS, checking is bypassed.
45556 + *
45557 + * For historical reasons, these macros are grossly misnamed.
45558 + */
45559 +
45560 +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
45561 +
45562 +#define KERNEL_DS      MAKE_MM_SEG(0xFFFFFFFF)
45563 +#define USER_DS                MAKE_MM_SEG(TASK_SIZE)
45564 +
45565 +#define get_ds()       (KERNEL_DS)
45566 +#define get_fs()       (current->addr_limit)
45567 +#define set_fs(x)      (current->addr_limit = (x))
45568 +
45569 +#define segment_eq(a, b) ((a).seg == (b).seg)
45570 +
45571 +#include "um_uaccess.h"
45572 +
45573 +#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
45574 +
45575 +#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
45576 +
45577 +#define __get_user(x, ptr) \
45578 +({ \
45579 +        const __typeof__(ptr) __private_ptr = ptr; \
45580 +        __typeof__(*(__private_ptr)) __private_val; \
45581 +        int __private_ret = -EFAULT; \
45582 +        (x) = 0; \
45583 +       if (__copy_from_user(&__private_val, (__private_ptr), \
45584 +           sizeof(*(__private_ptr))) == 0) {\
45585 +               (x) = (__typeof__(*(__private_ptr))) __private_val; \
45586 +               __private_ret = 0; \
45587 +       } \
45588 +        __private_ret; \
45589 +}) 
45590 +
45591 +#define get_user(x, ptr) \
45592 +({ \
45593 +        const __typeof__((*ptr)) *private_ptr = (ptr); \
45594 +        (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \
45595 +        __get_user(x, private_ptr) : ((x) = 0, -EFAULT)); \
45596 +})
45597 +
45598 +#define __put_user(x, ptr) \
45599 +({ \
45600 +        __typeof__(ptr) __private_ptr = ptr; \
45601 +        __typeof__(*(__private_ptr)) __private_val; \
45602 +        int __private_ret = -EFAULT; \
45603 +        __private_val = (__typeof__(*(__private_ptr))) (x); \
45604 +        if (__copy_to_user((__private_ptr), &__private_val, \
45605 +                          sizeof(*(__private_ptr))) == 0) { \
45606 +               __private_ret = 0; \
45607 +       } \
45608 +        __private_ret; \
45609 +})
45610 +
45611 +#define put_user(x, ptr) \
45612 +({ \
45613 +        __typeof__(*(ptr)) *private_ptr = (ptr); \
45614 +        (access_ok(VERIFY_WRITE, private_ptr, sizeof(*private_ptr)) ? \
45615 +        __put_user(x, private_ptr) : -EFAULT); \
45616 +})
45617 +
45618 +#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
45619 +
45620 +struct exception_table_entry
45621 +{
45622 +        unsigned long insn;
45623 +       unsigned long fixup;
45624 +};
45625 +
45626 +#endif
45627 +
45628 +/*
45629 + * Overrides for Emacs so that we follow Linus's tabbing style.
45630 + * Emacs will notice this stuff at the end of the file and automatically
45631 + * adjust the settings for this buffer only.  This must remain at the end
45632 + * of the file.
45633 + * ---------------------------------------------------------------------------
45634 + * Local variables:
45635 + * c-file-style: "linux"
45636 + * End:
45637 + */
45638 Index: linux-2.4.29/include/asm-um/ucontext.h
45639 ===================================================================
45640 --- linux-2.4.29.orig/include/asm-um/ucontext.h 1970-01-01 03:00:00.000000000 +0300
45641 +++ linux-2.4.29/include/asm-um/ucontext.h      2005-05-03 22:28:15.008328600 +0300
45642 @@ -0,0 +1,6 @@
45643 +#ifndef _ASM_UM_UCONTEXT_H
45644 +#define _ASM_UM_UCONTEXT_H
45645 +
45646 +#include "asm/arch/ucontext.h"
45647 +
45648 +#endif
45649 Index: linux-2.4.29/include/asm-um/unaligned.h
45650 ===================================================================
45651 --- linux-2.4.29.orig/include/asm-um/unaligned.h        1970-01-01 03:00:00.000000000 +0300
45652 +++ linux-2.4.29/include/asm-um/unaligned.h     2005-05-03 22:28:15.000000000 +0300
45653 @@ -0,0 +1,6 @@
45654 +#ifndef __UM_UNALIGNED_H
45655 +#define __UM_UNALIGNED_H
45656 +
45657 +#include "asm/arch/unaligned.h"
45658 +
45659 +#endif
45660 Index: linux-2.4.29/include/asm-um/unistd.h
45661 ===================================================================
45662 --- linux-2.4.29.orig/include/asm-um/unistd.h   1970-01-01 03:00:00.000000000 +0300
45663 +++ linux-2.4.29/include/asm-um/unistd.h        2005-05-03 23:41:11.206045424 +0300
45664 @@ -0,0 +1,121 @@
45665 +/* 
45666 + * Copyright (C) 2000, 2001  Jeff Dike (jdike@karaya.com)
45667 + * Licensed under the GPL
45668 + */
45669 +
45670 +#ifndef _UM_UNISTD_H_
45671 +#define _UM_UNISTD_H_
45672 +
45673 +#include "linux/resource.h"
45674 +#include "asm/uaccess.h"
45675 +
45676 +extern long sys_open(const char *filename, int flags, int mode);
45677 +extern long sys_dup(unsigned int fildes);
45678 +extern long sys_close(unsigned int fd);
45679 +extern int um_execve(const char *file, char *const argv[], char *const env[]);
45680 +extern long sys_setsid(void);
45681 +extern long sys_waitpid(pid_t pid, unsigned int * stat_addr, int options);
45682 +extern long sys_wait4(pid_t pid,unsigned int *stat_addr, int options, 
45683 +                     struct rusage *ru);
45684 +extern long sys_mount(char *dev_name, char *dir_name, char *type, 
45685 +                     unsigned long flags, void *data);
45686 +extern long sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, 
45687 +                      struct timeval *tvp);
45688 +extern long sys_lseek(unsigned int fildes, unsigned long offset, int whence);
45689 +extern long sys_read(unsigned int fildes, char *buf, int len);
45690 +extern long sys_write(unsigned int fildes, char *buf, int len);
45691 +
45692 +#ifdef __KERNEL_SYSCALLS__
45693 +
45694 +#define KERNEL_CALL(ret_t, sys, args...)       \
45695 +       mm_segment_t fs = get_fs();             \
45696 +       ret_t ret;                              \
45697 +       set_fs(KERNEL_DS);                      \
45698 +       ret = sys(args);                        \
45699 +       set_fs(fs);                             \
45700 +       if (ret >= 0)                           \
45701 +               return ret;                     \
45702 +       errno = -(long)ret;                     \
45703 +       return -1;
45704 +
45705 +static inline long open(const char *pathname, int flags, int mode) 
45706 +{
45707 +       KERNEL_CALL(int, sys_open, pathname, flags, mode)
45708 +}
45709 +
45710 +static inline long dup(unsigned int fd)
45711 +{
45712 +       KERNEL_CALL(int, sys_dup, fd);
45713 +}
45714 +
45715 +static inline long close(unsigned int fd)
45716 +{
45717 +       KERNEL_CALL(int, sys_close, fd);
45718 +}
45719 +
45720 +static inline int execve(const char *filename, char *const argv[], 
45721 +                        char *const envp[])
45722 +{
45723 +       KERNEL_CALL(int, um_execve, filename, argv, envp);
45724 +}
45725 +
45726 +static inline long waitpid(pid_t pid, unsigned int *status, int options)
45727 +{
45728 +       KERNEL_CALL(pid_t, sys_wait4, pid, status, options, NULL)
45729 +}
45730 +
45731 +static inline pid_t wait(int *status)
45732 +{
45733 +       KERNEL_CALL(pid_t, sys_wait4, -1, status, 0, NULL)
45734 +}
45735 +
45736 +static inline pid_t setsid(void)
45737 +{
45738 +       KERNEL_CALL(pid_t, sys_setsid)
45739 +}
45740 +
45741 +static inline long lseek(unsigned int fd, off_t offset, unsigned int whence)
45742 +{
45743 +       KERNEL_CALL(long, sys_lseek, fd, offset, whence)
45744 +}
45745 +
45746 +static inline int read(unsigned int fd, char * buf, int len)
45747 +{
45748 +       KERNEL_CALL(int, sys_read, fd, buf, len)
45749 +}
45750 +
45751 +static inline int write(unsigned int fd, char * buf, int len)
45752 +{
45753 +       KERNEL_CALL(int, sys_write, fd, buf, len)
45754 +}
45755 +
45756 +#endif
45757 +
45758 +/* Save the value of __KERNEL_SYSCALLS__, undefine it, include the underlying
45759 + * arch's unistd.h for the system call numbers, and restore the old 
45760 + * __KERNEL_SYSCALLS__.
45761 + */
45762 +
45763 +#ifdef __KERNEL_SYSCALLS__
45764 +#define __SAVE_KERNEL_SYSCALLS__ __KERNEL_SYSCALLS__
45765 +#endif
45766 +
45767 +#undef __KERNEL_SYSCALLS__
45768 +#include "asm/arch/unistd.h"
45769 +
45770 +#ifdef __KERNEL_SYSCALLS__
45771 +#define __KERNEL_SYSCALLS__ __SAVE_KERNEL_SYSCALLS__
45772 +#endif
45773 +
45774 +#endif
45775 +
45776 +/*
45777 + * Overrides for Emacs so that we follow Linus's tabbing style.
45778 + * Emacs will notice this stuff at the end of the file and automatically
45779 + * adjust the settings for this buffer only.  This must remain at the end
45780 + * of the file.
45781 + * ---------------------------------------------------------------------------
45782 + * Local variables:
45783 + * c-file-style: "linux"
45784 + * End:
45785 + */
45786 Index: linux-2.4.29/include/asm-um/user.h
45787 ===================================================================
45788 --- linux-2.4.29.orig/include/asm-um/user.h     1970-01-01 03:00:00.000000000 +0300
45789 +++ linux-2.4.29/include/asm-um/user.h  2005-05-03 23:43:26.305507184 +0300
45790 @@ -0,0 +1,6 @@
45791 +#ifndef __UM_USER_H
45792 +#define __UM_USER_H
45793 +
45794 +#include "asm/arch/user.h"
45795 +
45796 +#endif
45797 Index: linux-2.4.29/include/asm-um/vga.h
45798 ===================================================================
45799 --- linux-2.4.29.orig/include/asm-um/vga.h      1970-01-01 03:00:00.000000000 +0300
45800 +++ linux-2.4.29/include/asm-um/vga.h   2005-05-03 22:28:15.000000000 +0300
45801 @@ -0,0 +1,6 @@
45802 +#ifndef __UM_VGA_H
45803 +#define __UM_VGA_H
45804 +
45805 +#include "asm/arch/vga.h"
45806 +
45807 +#endif
45808 Index: linux-2.4.29/include/asm-um/xor.h
45809 ===================================================================
45810 --- linux-2.4.29.orig/include/asm-um/xor.h      1970-01-01 03:00:00.000000000 +0300
45811 +++ linux-2.4.29/include/asm-um/xor.h   2005-05-03 22:28:15.000000000 +0300
45812 @@ -0,0 +1,6 @@
45813 +#ifndef __UM_XOR_H
45814 +#define __UM_XOR_H
45815 +
45816 +#include "asm-generic/xor.h"
45817 +
45818 +#endif
45819 Index: linux-2.4.29/include/linux/blk.h
45820 ===================================================================
45821 --- linux-2.4.29.orig/include/linux/blk.h       2005-05-03 21:09:03.000000000 +0300
45822 +++ linux-2.4.29/include/linux/blk.h    2005-05-03 23:41:26.547713136 +0300
45823 @@ -320,6 +320,24 @@
45824  #define DEVICE_REQUEST do_ida_request
45825  #define DEVICE_NR(device) (MINOR(device) >> 4)
45826  
45827 +#elif (MAJOR_NR == UBD_MAJOR)
45828 +
45829 +#define DEVICE_NAME "User-mode block device"
45830 +#define DEVICE_INTR do_ubd
45831 +#define DEVICE_REQUEST do_ubd_request
45832 +#define DEVICE_NR(device) (MINOR(device) >> UBD_SHIFT)
45833 +#define DEVICE_ON(device)
45834 +#define DEVICE_OFF(device)
45835 +
45836 +#elif (MAJOR_NR == COW_MAJOR)
45837 +
45838 +#define DEVICE_NAME "COW device"
45839 +#define DEVICE_INTR do_cow
45840 +#define DEVICE_REQUEST do_cow_request
45841 +#define DEVICE_NR(device) (MINOR(device) >> COW_SHIFT)
45842 +#define DEVICE_ON(device)
45843 +#define DEVICE_OFF(device)
45844 +
45845  #endif /* MAJOR_NR == whatever */
45846  
45847  /* provide DEVICE_xxx defaults, if not explicitly defined
45848 Index: linux-2.4.29/include/linux/fs.h
45849 ===================================================================
45850 --- linux-2.4.29.orig/include/linux/fs.h        2005-05-03 21:06:01.000000000 +0300
45851 +++ linux-2.4.29/include/linux/fs.h     2005-05-03 23:56:00.359873496 +0300
45852 @@ -322,6 +322,8 @@
45853  #include <linux/ncp_fs_i.h>
45854  #include <linux/proc_fs_i.h>
45855  #include <linux/usbdev_fs_i.h>
45856 +#include <linux/hostfs_fs_i.h>
45857 +#include <linux/hppfs_fs_i.h>
45858  #include <linux/jffs2_fs_i.h>
45859  #include <linux/cramfs_fs_sb.h>
45860  
45861 @@ -518,7 +520,9 @@
45862                 struct proc_inode_info          proc_i;
45863                 struct socket                   socket_i;
45864                 struct usbdev_inode_info        usbdev_i;
45865 -               struct jffs2_inode_info         jffs2_i;
45866 +               struct hostfs_inode_info        hostfs_i;
45867 +               struct hppfs_inode_info         hppfs_i;
45868 +               struct jffs2_inode_info         jffs2_i;
45869                 void                            *generic_ip;
45870         } u;
45871  };
45872 @@ -866,6 +870,8 @@
45873         unsigned int (*poll) (struct file *, struct poll_table_struct *);
45874         int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
45875         int (*mmap) (struct file *, struct vm_area_struct *);
45876 +       void (*munmap) (struct file *, struct vm_area_struct *, 
45877 +                       unsigned long start, unsigned long len);
45878         int (*open) (struct inode *, struct file *);
45879         int (*flush) (struct file *);
45880         int (*release) (struct inode *, struct file *);
45881 Index: linux-2.4.29/include/linux/ghash.h
45882 ===================================================================
45883 --- linux-2.4.29.orig/include/linux/ghash.h     2005-05-03 21:09:50.000000000 +0300
45884 +++ linux-2.4.29/include/linux/ghash.h  2005-05-03 22:28:15.000000000 +0300
45885 @@ -153,6 +153,26 @@
45886         return NULL;\
45887  }
45888  
45889 +/* LINKAGE - empty or "static", depending on whether you want the definitions to
45890 + *     be public or not
45891 + * NAME - a string to stick in names to make this hash table type distinct from
45892 + *     any others
45893 + * HASHSIZE - number of buckets
45894 + * TYPE - type of data contained in the buckets - must be a structure, one 
45895 + *     field is of type NAME_ptrs, another is the hash key
45896 + * PTRS - TYPE must contain a field of type NAME_ptrs, PTRS is the name of that
45897 + *     field
45898 + * KEYTYPE - type of the key field within TYPE
45899 + * KEY - name of the key field within TYPE
45900 + * KEYCMP - pointer to function that compares KEYTYPEs to each other - the
45901 + *     prototype is int KEYCMP(KEYTYPE, KEYTYPE), it returns zero for equal, 
45902 + *     non-zero for not equal
45903 + * HASHFN - the hash function - the prototype is int HASHFN(KEYTYPE),
45904 + *     it returns a number in the range 0 ... HASHSIZE - 1
45905 + * Call DEF_HASH_STRUCTS, define your hash table as a NAME_table, then call
45906 + * DEF_HASH.
45907 + */
45908 +
45909  #define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
45910  \
45911  struct NAME##_table {\
45912 @@ -165,7 +185,7 @@
45913         TYPE * prev_hash;\
45914  };
45915  
45916 -#define DEF_HASH(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
45917 +#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\
45918  \
45919  LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
45920  {\
45921 @@ -206,12 +226,10 @@
45922  \
45923  LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
45924  {\
45925 -       int ix = hashfn(pos);\
45926 +       int ix = HASHFN(pos);\
45927         TYPE * ptr = tbl->hashtable[ix];\
45928         while(ptr && KEYCMP(ptr->KEY, pos))\
45929                 ptr = ptr->PTRS.next_hash;\
45930 -       if(ptr && !KEYEQ(ptr->KEY, pos))\
45931 -               ptr = NULL;\
45932         return ptr;\
45933  }
45934  
45935 Index: linux-2.4.29/include/linux/hostfs_fs_i.h
45936 ===================================================================
45937 --- linux-2.4.29.orig/include/linux/hostfs_fs_i.h       1970-01-01 03:00:00.000000000 +0300
45938 +++ linux-2.4.29/include/linux/hostfs_fs_i.h    2005-05-03 22:28:15.053321760 +0300
45939 @@ -0,0 +1,25 @@
45940 +#ifndef _HOSTFS_FS_I
45941 +#define _HOSTFS_FS_I
45942 +
45943 +#include "filehandle.h"
45944 +
45945 +struct externfs_file_ops;
45946 +
45947 +struct hostfs_inode_info {
45948 +       struct externfs_file_ops *ops;
45949 +       struct file_handle *fh;
45950 +       int mode;
45951 +};
45952 +
45953 +#endif
45954 +
45955 +/*
45956 + * Overrides for Emacs so that we follow Linus's tabbing style.
45957 + * Emacs will notice this stuff at the end of the file and automatically
45958 + * adjust the settings for this buffer only.  This must remain at the end
45959 + * of the file.
45960 + * ---------------------------------------------------------------------------
45961 + * Local variables:
45962 + * c-file-style: "linux"
45963 + * End:
45964 + */
45965 Index: linux-2.4.29/include/linux/hppfs_fs_i.h
45966 ===================================================================
45967 --- linux-2.4.29.orig/include/linux/hppfs_fs_i.h        1970-01-01 03:00:00.000000000 +0300
45968 +++ linux-2.4.29/include/linux/hppfs_fs_i.h     2005-05-03 22:28:15.054321608 +0300
45969 @@ -0,0 +1,19 @@
45970 +#ifndef _HPPFS_FS_I
45971 +#define _HPPFS_FS_I
45972 +
45973 +struct hppfs_inode_info {
45974 +       struct dentry *proc_dentry;
45975 +};
45976 +
45977 +#endif
45978 +
45979 +/*
45980 + * Overrides for Emacs so that we follow Linus's tabbing style.
45981 + * Emacs will notice this stuff at the end of the file and automatically
45982 + * adjust the settings for this buffer only.  This must remain at the end
45983 + * of the file.
45984 + * ---------------------------------------------------------------------------
45985 + * Local variables:
45986 + * c-file-style: "linux"
45987 + * End:
45988 + */
45989 Index: linux-2.4.29/include/linux/kernel.h
45990 ===================================================================
45991 --- linux-2.4.29.orig/include/linux/kernel.h    2005-05-03 21:04:57.000000000 +0300
45992 +++ linux-2.4.29/include/linux/kernel.h 2005-05-03 23:41:08.088519360 +0300
45993 @@ -49,7 +49,7 @@
45994  # define ATTRIB_NORET  __attribute__((noreturn))
45995  # define NORET_AND     noreturn,
45996  
45997 -#ifdef __i386__
45998 +#if defined(__i386__) || defined(UM_FASTCALL)
45999  #define FASTCALL(x)    x __attribute__((regparm(3)))
46000  #define fastcall       __attribute__((regparm(3)))
46001  #else
46002 Index: linux-2.4.29/include/linux/kernel_stat.h
46003 ===================================================================
46004 --- linux-2.4.29.orig/include/linux/kernel_stat.h       2005-05-03 21:09:36.000000000 +0300
46005 +++ linux-2.4.29/include/linux/kernel_stat.h    2005-05-03 23:41:09.913241960 +0300
46006 @@ -12,7 +12,7 @@
46007   * used by rstatd/perfmeter
46008   */
46009  
46010 -#define DK_MAX_MAJOR 16
46011 +#define DK_MAX_MAJOR 99
46012  #define DK_MAX_DISK 16
46013  
46014  struct kernel_stat {
46015 Index: linux-2.4.29/include/linux/mm.h
46016 ===================================================================
46017 --- linux-2.4.29.orig/include/linux/mm.h        2005-05-03 21:05:15.000000000 +0300
46018 +++ linux-2.4.29/include/linux/mm.h     2005-05-03 23:55:59.724970016 +0300
46019 @@ -441,6 +441,18 @@
46020  extern struct page * FASTCALL(__alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist));
46021  extern struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order);
46022  
46023 +#ifndef HAVE_ARCH_VALIDATE
46024 +static inline struct page *arch_validate(struct page *page, 
46025 +                                        unsigned int gfp_mask, int order)
46026 +{
46027 +        return(page);
46028 +}
46029 +#endif
46030 +
46031 +#ifndef HAVE_ARCH_FREE_PAGE
46032 +static inline void arch_free_page(struct page *page, int order) { }
46033 +#endif
46034 +
46035  static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
46036  {
46037         /*
46038 @@ -448,7 +460,7 @@
46039          */
46040         if (order >= MAX_ORDER)
46041                 return NULL;
46042 -       return _alloc_pages(gfp_mask, order);
46043 +       return arch_validate(_alloc_pages(gfp_mask, order), gfp_mask, order);
46044  }
46045  
46046  #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
46047 @@ -508,6 +520,9 @@
46048  int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
46049                 int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
46050  
46051 +extern long do_mprotect(struct mm_struct *mm, unsigned long start, 
46052 +                       size_t len, unsigned long prot);
46053 +
46054  /*
46055   * On a two-level page table, this ends up being trivial. Thus the
46056   * inlining and the symmetry break with pte_alloc() that does all
46057 @@ -555,9 +570,10 @@
46058  
46059  extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
46060  
46061 -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
46062 -       unsigned long len, unsigned long prot,
46063 -       unsigned long flag, unsigned long pgoff);
46064 +extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file, 
46065 +                                  unsigned long addr, unsigned long len,
46066 +                                  unsigned long prot, unsigned long flag,
46067 +                                  unsigned long pgoff);
46068  
46069  static inline unsigned long do_mmap(struct file *file, unsigned long addr,
46070         unsigned long len, unsigned long prot,
46071 @@ -567,7 +583,8 @@
46072         if ((offset + PAGE_ALIGN(len)) < offset)
46073                 goto out;
46074         if (!(offset & ~PAGE_MASK))
46075 -               ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
46076 +               ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, 
46077 +                                   offset >> PAGE_SHIFT);
46078  out:
46079         return ret;
46080  }
46081 Index: linux-2.4.29/include/linux/proc_mm.h
46082 ===================================================================
46083 --- linux-2.4.29.orig/include/linux/proc_mm.h   1970-01-01 03:00:00.000000000 +0300
46084 +++ linux-2.4.29/include/linux/proc_mm.h        2005-05-03 23:46:00.225107848 +0300
46085 @@ -0,0 +1,48 @@
46086 +/* 
46087 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
46088 + * Licensed under the GPL
46089 + */
46090 +
46091 +#ifndef __PROC_MM_H
46092 +#define __PROC_MM_H
46093 +
46094 +#include "linux/sched.h"
46095 +
46096 +#define MM_MMAP 54
46097 +#define MM_MUNMAP 55
46098 +#define MM_MPROTECT 56
46099 +#define MM_COPY_SEGMENTS 57
46100 +
46101 +struct mm_mmap {
46102 +       unsigned long addr;
46103 +       unsigned long len;
46104 +       unsigned long prot;
46105 +       unsigned long flags;
46106 +       unsigned long fd;
46107 +       unsigned long offset;
46108 +};
46109 +
46110 +struct mm_munmap {
46111 +       unsigned long addr;
46112 +       unsigned long len;      
46113 +};
46114 +
46115 +struct mm_mprotect {
46116 +       unsigned long addr;
46117 +       unsigned long len;
46118 +        unsigned int prot;
46119 +};
46120 +
46121 +struct proc_mm_op {
46122 +       int op;
46123 +       union {
46124 +               struct mm_mmap mmap;
46125 +               struct mm_munmap munmap;
46126 +               struct mm_mprotect mprotect;
46127 +               int copy_segments;
46128 +       } u;
46129 +};
46130 +
46131 +extern struct mm_struct *proc_mm_get_mm(int fd);
46132 +
46133 +#endif
46134 Index: linux-2.4.29/include/linux/shmem_fs.h
46135 ===================================================================
46136 --- linux-2.4.29.orig/include/linux/shmem_fs.h  2005-05-03 21:09:04.000000000 +0300
46137 +++ linux-2.4.29/include/linux/shmem_fs.h       2005-05-03 22:28:15.082317352 +0300
46138 @@ -22,6 +22,8 @@
46139         unsigned long           next_index;
46140         swp_entry_t             i_direct[SHMEM_NR_DIRECT]; /* for the first blocks */
46141         void                  **i_indirect; /* indirect blocks */
46142 +       unsigned long           map_direct[SHMEM_NR_DIRECT];
46143 +       void                  **map_indirect;
46144         unsigned long           swapped;    /* data pages assigned to swap */
46145         unsigned long           flags;
46146         struct list_head        list;
46147 Index: linux-2.4.29/include/linux/tty.h
46148 ===================================================================
46149 --- linux-2.4.29.orig/include/linux/tty.h       2005-05-03 21:07:23.000000000 +0300
46150 +++ linux-2.4.29/include/linux/tty.h    2005-05-03 23:41:09.901243784 +0300
46151 @@ -310,6 +310,9 @@
46152         spinlock_t read_lock;
46153         /* If the tty has a pending do_SAK, queue it here - akpm */
46154         struct tq_struct SAK_tq;
46155 +#ifdef CONFIG_TTY_LOG
46156 +        int log_fd;
46157 +#endif
46158  };
46159  
46160  /* tty magic number */
46161 @@ -368,6 +371,7 @@
46162  extern int specialix_init(void);
46163  extern int espserial_init(void);
46164  extern int macserial_init(void);
46165 +extern int stdio_init(void);
46166  extern int a2232board_init(void);
46167  
46168  extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
46169 @@ -434,5 +438,7 @@
46170  extern int vt_ioctl(struct tty_struct *tty, struct file * file,
46171                     unsigned int cmd, unsigned long arg);
46172  
46173 +extern void stdio_console_init(void);
46174 +
46175  #endif /* __KERNEL__ */
46176  #endif
46177 Index: linux-2.4.29/init/do_mounts.c
46178 ===================================================================
46179 --- linux-2.4.29.orig/init/do_mounts.c  2005-05-03 21:09:10.000000000 +0300
46180 +++ linux-2.4.29/init/do_mounts.c       2005-05-03 22:28:15.000000000 +0300
46181 @@ -154,6 +154,22 @@
46182         { "pf",         0x2f00 },
46183         { "apblock", APBLOCK_MAJOR << 8},
46184         { "ddv", DDV_MAJOR << 8},
46185 +       { "ubd0", UBD_MAJOR << 8 | 0 << 4},
46186 +       { "ubda", UBD_MAJOR << 8 | 0 << 4},
46187 +       { "ubd1", UBD_MAJOR << 8 | 1 << 4},
46188 +       { "ubdb", UBD_MAJOR << 8 | 1 << 4},
46189 +       { "ubd2", UBD_MAJOR << 8 | 2 << 4},
46190 +       { "ubdc", UBD_MAJOR << 8 | 2 << 4},
46191 +       { "ubd3", UBD_MAJOR << 8 | 3 << 4},
46192 +       { "ubdd", UBD_MAJOR << 8 | 3 << 4},
46193 +       { "ubd4", UBD_MAJOR << 8 | 4 << 4},
46194 +       { "ubde", UBD_MAJOR << 8 | 4 << 4},
46195 +       { "ubd5", UBD_MAJOR << 8 | 5 << 4},
46196 +       { "ubdf", UBD_MAJOR << 8 | 5 << 4},
46197 +       { "ubd6", UBD_MAJOR << 8 | 6 << 4},
46198 +       { "ubdg", UBD_MAJOR << 8 | 6 << 4},
46199 +       { "ubd7", UBD_MAJOR << 8 | 7 << 4},
46200 +       { "ubdh", UBD_MAJOR << 8 | 7 << 4},
46201         { "jsfd",    JSFD_MAJOR << 8},
46202  #if defined(CONFIG_ARCH_S390)
46203         { "dasda", (DASD_MAJOR << MINORBITS) },
46204 Index: linux-2.4.29/kernel/panic.c
46205 ===================================================================
46206 --- linux-2.4.29.orig/kernel/panic.c    2005-05-03 21:09:35.000000000 +0300
46207 +++ linux-2.4.29/kernel/panic.c 2005-05-03 22:28:15.000000000 +0300
46208 @@ -74,7 +74,7 @@
46209         smp_send_stop();
46210  #endif
46211  
46212 -       notifier_call_chain(&panic_notifier_list, 0, NULL);
46213 +       notifier_call_chain(&panic_notifier_list, 0, buf);
46214  
46215         if (panic_timeout > 0)
46216         {
46217 Index: linux-2.4.29/MAINTAINERS
46218 ===================================================================
46219 --- linux-2.4.29.orig/MAINTAINERS       2005-05-03 21:07:57.000000000 +0300
46220 +++ linux-2.4.29/MAINTAINERS    2005-05-03 22:28:15.000000000 +0300
46221 @@ -2120,6 +2120,14 @@
46222  L:     linux-usb-devel@lists.sourceforge.net
46223  W:     http://usb.in.tum.de
46224  S:     Maintained
46225 +
46226 +USER-MODE PORT
46227 +P:     Jeff Dike
46228 +M:     jdike@karaya.com
46229 +L:     user-mode-linux-devel@lists.sourceforge.net
46230 +L:     user-mode-linux-user@lists.sourceforge.net
46231 +W:     http://user-mode-linux.sourceforge.net
46232 +S:     Maintained
46233         
46234  USB "USBNET" DRIVER
46235  P:     David Brownell
46236 Index: linux-2.4.29/Makefile
46237 ===================================================================
46238 --- linux-2.4.29.orig/Makefile  2005-05-03 21:08:14.000000000 +0300
46239 +++ linux-2.4.29/Makefile       2005-05-03 22:28:15.000000000 +0300
46240 @@ -5,7 +5,15 @@
46241  
46242  KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
46243  
46244 -ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
46245 +# SUBARCH tells the usermode build what the underlying arch is.  That is set
46246 +# first, and if a usermode build is happening, the "ARCH=um" on the command
46247 +# line overrides the setting of ARCH below.  If a native build is happening,
46248 +# then ARCH is assigned, getting whatever value it gets normally, and 
46249 +# SUBARCH is subsequently ignored.
46250 +
46251 +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
46252 +ARCH := $(SUBARCH)
46253 +
46254  KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
46255  
46256  CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
46257 Index: linux-2.4.29/mm/Makefile
46258 ===================================================================
46259 --- linux-2.4.29.orig/mm/Makefile       2005-05-03 21:08:06.000000000 +0300
46260 +++ linux-2.4.29/mm/Makefile    2005-05-03 22:28:15.000000000 +0300
46261 @@ -17,5 +17,6 @@
46262             shmem.o
46263  
46264  obj-$(CONFIG_HIGHMEM) += highmem.o
46265 +obj-$(CONFIG_PROC_MM) += proc_mm.o
46266  
46267  include $(TOPDIR)/Rules.make
46268 Index: linux-2.4.29/mm/mmap.c
46269 ===================================================================
46270 --- linux-2.4.29.orig/mm/mmap.c 2005-05-03 21:07:59.000000000 +0300
46271 +++ linux-2.4.29/mm/mmap.c      2005-05-03 22:28:15.000000000 +0300
46272 @@ -391,10 +391,11 @@
46273         return 0;
46274  }
46275  
46276 -unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned long len,
46277 -       unsigned long prot, unsigned long flags, unsigned long pgoff)
46278 +unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file, 
46279 +                           unsigned long addr, unsigned long len,
46280 +                           unsigned long prot, unsigned long flags, 
46281 +                           unsigned long pgoff)
46282  {
46283 -       struct mm_struct * mm = current->mm;
46284         struct vm_area_struct * vma, * prev;
46285         unsigned int vm_flags;
46286         int correct_wcount = 0;
46287 @@ -1000,6 +1001,11 @@
46288                 remove_shared_vm_struct(mpnt);
46289                 mm->map_count--;
46290  
46291 +               if((mpnt->vm_file != NULL) && (mpnt->vm_file->f_op != NULL) &&
46292 +                  (mpnt->vm_file->f_op->munmap != NULL))
46293 +                       mpnt->vm_file->f_op->munmap(mpnt->vm_file, mpnt, st, 
46294 +                                                   size);
46295 +
46296                 zap_page_range(mm, st, size);
46297  
46298                 /*
46299 Index: linux-2.4.29/mm/mprotect.c
46300 ===================================================================
46301 --- linux-2.4.29.orig/mm/mprotect.c     2005-05-03 21:06:44.000000000 +0300
46302 +++ linux-2.4.29/mm/mprotect.c  2005-05-03 22:28:15.000000000 +0300
46303 @@ -264,7 +264,8 @@
46304         return 0;
46305  }
46306  
46307 -asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
46308 +long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
46309 +                unsigned long prot)
46310  {
46311         unsigned long nstart, end, tmp;
46312         struct vm_area_struct * vma, * next, * prev;
46313 @@ -281,9 +282,9 @@
46314         if (end == start)
46315                 return 0;
46316  
46317 -       down_write(&current->mm->mmap_sem);
46318 +       down_write(&mm->mmap_sem);
46319  
46320 -       vma = find_vma_prev(current->mm, start, &prev);
46321 +       vma = find_vma_prev(mm, start, &prev);
46322         error = -ENOMEM;
46323         if (!vma || vma->vm_start > start)
46324                 goto out;
46325 @@ -332,6 +333,11 @@
46326                 prev->vm_mm->map_count--;
46327         }
46328  out:
46329 -       up_write(&current->mm->mmap_sem);
46330 +       up_write(&mm->mmap_sem);
46331         return error;
46332  }
46333 +
46334 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
46335 +{
46336 +        return(do_mprotect(current->mm, start, len, prot));
46337 +}
46338 Index: linux-2.4.29/mm/page_alloc.c
46339 ===================================================================
46340 --- linux-2.4.29.orig/mm/page_alloc.c   2005-05-03 21:05:16.000000000 +0300
46341 +++ linux-2.4.29/mm/page_alloc.c        2005-05-03 22:28:15.000000000 +0300
46342 @@ -116,6 +116,7 @@
46343         struct page *base;
46344         zone_t *zone;
46345  
46346 +       arch_free_page(page, order);
46347         /*
46348          * Yes, think what happens when other parts of the kernel take 
46349          * a reference to a page in order to pin it for io. -ben
46350 Index: linux-2.4.29/mm/proc_mm.c
46351 ===================================================================
46352 --- linux-2.4.29.orig/mm/proc_mm.c      1970-01-01 03:00:00.000000000 +0300
46353 +++ linux-2.4.29/mm/proc_mm.c   2005-05-03 22:28:15.000000000 +0300
46354 @@ -0,0 +1,173 @@
46355 +/* 
46356 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
46357 + * Licensed under the GPL
46358 + */
46359 +
46360 +#include "linux/init.h"
46361 +#include "linux/proc_fs.h"
46362 +#include "linux/proc_mm.h"
46363 +#include "linux/file.h"
46364 +#include "asm/uaccess.h"
46365 +#include "asm/mmu_context.h"
46366 +
46367 +static struct file_operations proc_mm_fops;
46368 +
46369 +struct mm_struct *proc_mm_get_mm(int fd)
46370 +{
46371 +       struct mm_struct *ret = ERR_PTR(-EBADF);
46372 +       struct file *file;
46373 +
46374 +       file = fget(fd);
46375 +       if (!file)
46376 +               goto out;
46377 +
46378 +       ret = ERR_PTR(-EINVAL);
46379 +       if(file->f_op != &proc_mm_fops)
46380 +               goto out_fput;
46381 +
46382 +       ret = file->private_data;
46383 + out_fput:
46384 +       fput(file);
46385 + out:
46386 +       return(ret);
46387 +}
46388 +
46389 +extern long do_mmap2(struct mm_struct *mm, unsigned long addr, 
46390 +                    unsigned long len, unsigned long prot, 
46391 +                    unsigned long flags, unsigned long fd,
46392 +                    unsigned long pgoff);
46393 +
46394 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
46395 +                            size_t count, loff_t *ppos)
46396 +{
46397 +       struct mm_struct *mm = file->private_data;
46398 +       struct proc_mm_op req;
46399 +       int n, ret;
46400 +
46401 +       if(count > sizeof(req))
46402 +               return(-EINVAL);
46403 +
46404 +       n = copy_from_user(&req, buffer, count);
46405 +       if(n != 0)
46406 +               return(-EFAULT);
46407 +
46408 +       ret = count;
46409 +       switch(req.op){
46410 +       case MM_MMAP: {
46411 +               struct mm_mmap *map = &req.u.mmap;
46412 +
46413 +               ret = do_mmap2(mm, map->addr, map->len, map->prot, 
46414 +                              map->flags, map->fd, map->offset >> PAGE_SHIFT);
46415 +               if((ret & ~PAGE_MASK) == 0)
46416 +                       ret = count;
46417 +       
46418 +               break;
46419 +       }
46420 +       case MM_MUNMAP: {
46421 +               struct mm_munmap *unmap = &req.u.munmap;
46422 +
46423 +               down_write(&mm->mmap_sem);
46424 +               ret = do_munmap(mm, unmap->addr, unmap->len);
46425 +               up_write(&mm->mmap_sem);
46426 +
46427 +               if(ret == 0)
46428 +                       ret = count;
46429 +               break;
46430 +       }
46431 +       case MM_MPROTECT: {
46432 +               struct mm_mprotect *protect = &req.u.mprotect;
46433 +
46434 +               ret = do_mprotect(mm, protect->addr, protect->len, 
46435 +                                 protect->prot);
46436 +               if(ret == 0)
46437 +                       ret = count;
46438 +               break;
46439 +       }
46440 +
46441 +       case MM_COPY_SEGMENTS: {
46442 +               struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
46443 +
46444 +               if(IS_ERR(from)){
46445 +                       ret = PTR_ERR(from);
46446 +                       break;
46447 +               }
46448 +
46449 +               mm_copy_segments(from, mm);
46450 +               break;
46451 +       }
46452 +       default:
46453 +               ret = -EINVAL;
46454 +               break;
46455 +       }
46456 +
46457 +       return(ret);
46458 +}
46459 +
46460 +static int open_proc_mm(struct inode *inode, struct file *file)
46461 +{
46462 +       struct mm_struct *mm = mm_alloc();
46463 +       int ret;
46464 +
46465 +       ret = -ENOMEM;
46466 +       if(mm == NULL)
46467 +               goto out_mem;
46468 +
46469 +       ret = init_new_context(current, mm);
46470 +       if(ret)
46471 +               goto out_free;
46472 +
46473 +       spin_lock(&mmlist_lock);
46474 +       list_add(&mm->mmlist, &current->mm->mmlist);
46475 +       mmlist_nr++;
46476 +       spin_unlock(&mmlist_lock);
46477 +
46478 +       file->private_data = mm;
46479 +
46480 +       return(0);
46481 +
46482 + out_free:
46483 +       mmput(mm);
46484 + out_mem:
46485 +       return(ret);
46486 +}
46487 +
46488 +static int release_proc_mm(struct inode *inode, struct file *file)
46489 +{
46490 +       struct mm_struct *mm = file->private_data;
46491 +
46492 +       mmput(mm);
46493 +       return(0);
46494 +}
46495 +
46496 +static struct file_operations proc_mm_fops = {
46497 +       .open           = open_proc_mm,
46498 +       .release        = release_proc_mm,
46499 +       .write          = write_proc_mm,
46500 +};
46501 +
46502 +static int make_proc_mm(void)
46503 +{
46504 +       struct proc_dir_entry *ent;
46505 +
46506 +       ent = create_proc_entry("mm", 0222, &proc_root);
46507 +       if(ent == NULL){
46508 +               printk("make_proc_mm : Failed to register /proc/mm\n");
46509 +               return(0);
46510 +       }
46511 +       ent->proc_fops = &proc_mm_fops;
46512 +
46513 +       return(0);
46514 +}
46515 +
46516 +__initcall(make_proc_mm);
46517 +
46518 +/*
46519 + * Overrides for Emacs so that we follow Linus's tabbing style.
46520 + * Emacs will notice this stuff at the end of the file and automatically
46521 + * adjust the settings for this buffer only.  This must remain at the end
46522 + * of the file.
46523 + * ---------------------------------------------------------------------------
46524 + * Local variables:
46525 + * c-file-style: "linux"
46526 + * End:
46527 + */
46528 Index: linux-2.4.29/mm/shmem.c
46529 ===================================================================
46530 --- linux-2.4.29.orig/mm/shmem.c        2005-05-03 21:06:51.000000000 +0300
46531 +++ linux-2.4.29/mm/shmem.c     2005-05-03 22:28:15.000000000 +0300
46532 @@ -128,16 +128,17 @@
46533   *                    +-> 48-51
46534   *                    +-> 52-55
46535   */
46536 -static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, unsigned long *page)
46537 +static void *shmem_block(unsigned long index, unsigned long *page,
46538 +                        unsigned long *direct, void ***indirect)
46539  {
46540         unsigned long offset;
46541         void **dir;
46542  
46543         if (index < SHMEM_NR_DIRECT)
46544 -               return info->i_direct+index;
46545 -       if (!info->i_indirect) {
46546 +               return direct+index;
46547 +       if (!*indirect) {
46548                 if (page) {
46549 -                       info->i_indirect = (void **) *page;
46550 +                       *indirect = (void **) *page;
46551                         *page = 0;
46552                 }
46553                 return NULL;                    /* need another page */
46554 @@ -146,7 +147,7 @@
46555         index -= SHMEM_NR_DIRECT;
46556         offset = index % ENTRIES_PER_PAGE;
46557         index /= ENTRIES_PER_PAGE;
46558 -       dir = info->i_indirect;
46559 +       dir = *indirect;
46560  
46561         if (index >= ENTRIES_PER_PAGE/2) {
46562                 index -= ENTRIES_PER_PAGE/2;
46563 @@ -169,7 +170,21 @@
46564                 *dir = (void *) *page;
46565                 *page = 0;
46566         }
46567 -       return (swp_entry_t *) *dir + offset;
46568 +       return (unsigned long **) *dir + offset;
46569 +}
46570 +
46571 +static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, unsigned long *page)
46572 +{
46573 +       return((swp_entry_t *) shmem_block(index, page, 
46574 +                                          (unsigned long *) info->i_direct, 
46575 +                                          &info->i_indirect));
46576 +}
46577 +
46578 +static unsigned long *shmem_map_count(struct shmem_inode_info *info, 
46579 +                                     unsigned long index, unsigned long *page)
46580 +{
46581 +       return((unsigned long *) shmem_block(index, page, info->map_direct, 
46582 +                                            &info->map_indirect));
46583  }
46584  
46585  /*
46586 @@ -847,6 +862,7 @@
46587         ops = &shmem_vm_ops;
46588         if (!S_ISREG(inode->i_mode))
46589                 return -EACCES;
46590 +
46591         UPDATE_ATIME(inode);
46592         vma->vm_ops = ops;
46593         return 0;
46594 @@ -1750,4 +1766,125 @@
46595         return 0;
46596  }
46597  
46598 +static int adjust_map_counts(struct shmem_inode_info *info, 
46599 +                            unsigned long offset, unsigned long len, 
46600 +                            int adjust)
46601 +{
46602 +       unsigned long idx, i, *count, page = 0;
46603 +
46604 +       spin_lock(&info->lock);
46605 +       offset >>= PAGE_SHIFT;
46606 +       len >>= PAGE_SHIFT;
46607 +       for(i = 0; i < len; i++){
46608 +               idx = (i + offset) >> (PAGE_CACHE_SHIFT - PAGE_SHIFT);
46609 +
46610 +               while((count = shmem_map_count(info, idx, &page)) == NULL){
46611 +                       spin_unlock(&info->lock);
46612 +                       page = get_zeroed_page(GFP_KERNEL);
46613 +                       if(page == 0)
46614 +                               return(-ENOMEM);
46615 +                       spin_lock(&info->lock);
46616 +               }
46617 +
46618 +               if(page != 0)
46619 +                       free_page(page);
46620 +
46621 +               *count += adjust;
46622 +       }
46623 +       spin_unlock(&info->lock);
46624 +       return(0);
46625 +}
46626 +
46627  EXPORT_SYMBOL(shmem_file_setup);
46628 +
46629 +struct file_operations anon_file_operations;
46630 +
46631 +static int anon_mmap(struct file *file, struct vm_area_struct *vma)
46632 +{
46633 +        struct file *new;
46634 +       struct inode *inode;
46635 +       loff_t size = vma->vm_end - vma->vm_start;
46636 +       int err;
46637 +
46638 +       if(file->private_data == NULL){
46639 +               new = shmem_file_setup("dev/anon", size);
46640 +               if(IS_ERR(new))
46641 +                       return(PTR_ERR(new));
46642 +
46643 +               new->f_op = &anon_file_operations;
46644 +               file->private_data = new;
46645 +       }
46646 +       
46647 +       if (vma->vm_file)
46648 +               fput(vma->vm_file);
46649 +       vma->vm_file = file->private_data;
46650 +       get_file(vma->vm_file);
46651 +
46652 +       inode = vma->vm_file->f_dentry->d_inode;
46653 +       err = adjust_map_counts(SHMEM_I(inode), vma->vm_pgoff, size, 1);
46654 +       if(err)
46655 +               return(err);
46656 +
46657 +       vma->vm_ops = &shmem_vm_ops;
46658 +       return 0;
46659 +}
46660 +
46661 +static void anon_munmap(struct file *file, struct vm_area_struct *vma, 
46662 +                       unsigned long start, unsigned long len)
46663 +{
46664 +       struct inode *inode = file->f_dentry->d_inode;
46665 +       struct shmem_inode_info *info = SHMEM_I(inode);
46666 +       pgd_t *pgd;
46667 +       pmd_t *pmd;
46668 +       pte_t *pte;
46669 +       struct page *page;
46670 +       unsigned long addr, idx, *count;
46671 +
46672 +       for(addr = start; addr < start + len; addr += PAGE_SIZE){
46673 +               idx = (addr - vma->vm_start + vma->vm_pgoff);
46674 +               idx >>= PAGE_CACHE_SHIFT;
46675 +
46676 +               count = shmem_map_count(info, idx, NULL);
46677 +               BUG_ON(count == NULL);
46678 +
46679 +               (*count)--;
46680 +               if(*count > 0)
46681 +                       continue;
46682 +
46683 +               pgd = pgd_offset(vma->vm_mm, addr);
46684 +               if(pgd_none(*pgd))
46685 +                       continue;
46686 +
46687 +               pmd = pmd_offset(pgd, addr);
46688 +               if(pmd_none(*pmd))
46689 +                       continue;
46690 +
46691 +               pte = pte_offset(pmd, addr);
46692 +               if(!pte_present(*pte)) /* XXX need to handle swapped pages */
46693 +                       continue;
46694 +
46695 +               *pte = pte_mkclean(*pte);
46696 +
46697 +               page = pte_page(*pte);
46698 +               LockPage(page);
46699 +               lru_cache_del(page);
46700 +               ClearPageDirty(page);
46701 +               remove_inode_page(page);
46702 +               UnlockPage(page);
46703 +
46704 +               page_cache_release(page);
46705 +       }
46706 +}
46707 +
46708 +int anon_release(struct inode *inode, struct file *file)
46709 +{
46710 +       if(file->private_data != NULL)
46711 +               fput(file->private_data);
46712 +       return(0);
46713 +}
46714 +
46715 +struct file_operations anon_file_operations = {
46716 +       .mmap           = anon_mmap,
46717 +       .munmap         = anon_munmap,
46718 +       .release        = anon_release,
46719 +};