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
6 +mainmenu_option next_comment
7 +comment 'Block Devices'
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
13 +if [ "$CONFIG_BLK_DEV_UBD" = "y" -o "$CONFIG_COW" = "y" ] ; then
14 + define_bool CONFIG_COW_COMMON y
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
23 +dep_bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM
25 +tristate 'Example IO memory driver' CONFIG_MMAPPER
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
33 +mainmenu_option next_comment
34 +comment 'Character Devices'
36 +define_bool CONFIG_STDIO_CONSOLE y
38 +bool 'Virtual serial line' CONFIG_SSL
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 \
48 +string 'Default console channel initialization' CONFIG_CON_CHAN "xterm"
49 +string 'Default serial line channel initialization' CONFIG_SSL_CHAN "pty"
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
57 +bool 'Watchdog Timer Support' CONFIG_WATCHDOG
58 +dep_bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT \
60 +dep_tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG $CONFIG_WATCHDOG
61 +dep_tristate ' UML watchdog' CONFIG_UML_WATCHDOG $CONFIG_WATCHDOG
63 +tristate 'Sound support' CONFIG_UML_SOUND
64 +define_tristate CONFIG_SOUND $CONFIG_UML_SOUND
65 +define_tristate CONFIG_HOSTAUDIO $CONFIG_UML_SOUND
67 +bool 'Enable tty logging' CONFIG_TTY_LOG
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
75 +define_bool CONFIG_USERMODE y
77 +mainmenu_name "Linux/Usermode Kernel Configuration"
79 +define_bool CONFIG_ISA n
80 +define_bool CONFIG_SBUS n
81 +define_bool CONFIG_PCI n
83 +define_bool CONFIG_UID16 y
85 +define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
87 +mainmenu_option next_comment
88 +comment 'Code maturity level options'
89 +bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
92 +mainmenu_option next_comment
93 +comment 'General Setup'
95 +bool 'Separate kernel address space support' CONFIG_MODE_SKAS
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
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
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
115 +tristate 'Host filesystem' CONFIG_HOSTFS
116 +tristate 'Usable host filesystem' CONFIG_HUMFS
118 +if [ "$CONFIG_HOSTFS" = "y" -o "$CONFIG_HUMFS" = "y" ]; then
119 + define_tristate CONFIG_EXTERNFS y
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
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
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
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
151 +source arch/um/config_char.in
153 +source arch/um/config_block.in
155 +define_bool CONFIG_NETDEVICES $CONFIG_NET
157 +if [ "$CONFIG_NET" = "y" ]; then
158 + source arch/um/config_net.in
159 + source net/Config.in
164 +mainmenu_option next_comment
165 +comment 'SCSI support'
167 +tristate 'SCSI support' CONFIG_SCSI
169 +if [ "$CONFIG_SCSI" != "n" ]; then
170 + source arch/um/config_scsi.in
174 +source drivers/md/Config.in
176 +source drivers/mtd/Config.in
178 +source lib/Config.in
180 +source crypto/Config.in
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
189 + define_bool CONFIG_PT_PROXY n
192 +if [ "$CONFIG_MODE_TT" = "n" ]; then
193 + dep_bool 'Enable gprof support' CONFIG_GPROF $CONFIG_DEBUGSYM
196 +dep_bool 'Enable gcov support' CONFIG_GCOV $CONFIG_DEBUGSYM
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
203 +mainmenu_option next_comment
204 +comment 'Network Devices'
206 +# UML virtual driver
207 +bool 'Virtual network device' CONFIG_UML_NET
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
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
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
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
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
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
257 +# Automatically generated make config: don't edit
260 +# CONFIG_ISA is not set
261 +# CONFIG_SBUS is not set
262 +# CONFIG_PCI is not set
264 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
267 +# Code maturity level options
269 +CONFIG_EXPERIMENTAL=y
276 +CONFIG_BSD_PROCESS_ACCT=y
278 +CONFIG_BINFMT_AOUT=y
280 +CONFIG_BINFMT_MISC=y
282 +# CONFIG_HPPFS is not set
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
289 +CONFIG_KERNEL_HALF_GIGS=1
292 +# Loadable module support
300 +CONFIG_STDIO_CONSOLE=y
303 +# CONFIG_NULL_CHAN is not set
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
317 +# CONFIG_TTY_LOG is not set
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
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
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
355 +# Networking options
358 +CONFIG_PACKET_MMAP=y
359 +# CONFIG_NETLINK_DEV is not set
360 +# CONFIG_NETFILTER is not set
361 +# CONFIG_FILTER is not set
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
380 +# CONFIG_IPX is not set
381 +# CONFIG_ATALK is not set
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
398 +# QoS and/or fair queueing
400 +# CONFIG_NET_SCHED is not set
405 +# CONFIG_NET_PKTGEN is not set
413 +CONFIG_REISERFS_FS=m
414 +# CONFIG_REISERFS_CHECK is not set
415 +# CONFIG_REISERFS_PROC_INFO is not set
417 +# CONFIG_ADFS_FS_RW is not set
423 +# CONFIG_JBD_DEBUG is not set
433 +# CONFIG_JOLIET is not set
434 +# CONFIG_ZISOFS is not set
437 +# CONFIG_NTFS_FS is not set
441 +CONFIG_DEVFS_MOUNT=y
442 +# CONFIG_DEVFS_DEBUG is not set
445 +# CONFIG_QNX4FS_RW is not set
450 +# CONFIG_UDF_RW is not set
452 +# CONFIG_UFS_FS_WRITE is not set
455 +# Network File Systems
457 +# CONFIG_CODA_FS is not set
458 +# CONFIG_INTERMEZZO_FS is not set
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
474 +# CONFIG_PARTITION_ADVANCED is not set
475 +CONFIG_MSDOS_PARTITION=y
476 +# CONFIG_SMB_NLS is not set
480 +# Native Language Support
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
527 +# SCSI support type (disk, tape, CD-ROM)
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
535 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
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
544 +# Multi-device support (RAID and LVM)
546 +# CONFIG_MD is not set
549 +# Memory Technology Devices (MTD)
551 +# CONFIG_MTD is not set
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
563 +comment 'SCSI support type (disk, tape, CD-ROM)'
565 +dep_tristate ' SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
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
571 +dep_tristate ' SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
573 +dep_tristate ' SCSI CD-ROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
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
579 +dep_tristate ' SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
581 +comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
583 +#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
584 + bool ' Enable extra checks in new queueing code' CONFIG_SCSI_DEBUG_QUEUES
587 +bool ' Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
589 +bool ' Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
590 +bool ' SCSI logging facility' CONFIG_SCSI_LOGGING
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
599 +# Automatically generated make config: don't edit
602 +# CONFIG_ISA is not set
603 +# CONFIG_SBUS is not set
604 +# CONFIG_PCI is not set
606 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
609 +# Code maturity level options
611 +CONFIG_EXPERIMENTAL=y
620 +CONFIG_BSD_PROCESS_ACCT=y
622 +CONFIG_BINFMT_AOUT=y
624 +CONFIG_BINFMT_MISC=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
635 +CONFIG_KERNEL_HALF_GIGS=1
636 +# CONFIG_HIGHMEM is not set
638 +CONFIG_KERNEL_STACK_ORDER=2
639 +CONFIG_UML_REAL_TIME_CLOCK=y
642 +# Loadable module support
645 +# CONFIG_KMOD is not set
650 +CONFIG_STDIO_CONSOLE=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
670 +# CONFIG_TTY_LOG is not set
675 +CONFIG_BLK_DEV_UBD=y
676 +# CONFIG_BLK_DEV_UBD_SYNC is not set
677 +# CONFIG_COW is not set
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
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
699 +# CONFIG_BONDING is not set
700 +# CONFIG_EQUALIZER is not set
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
712 +# CONFIG_SLIP_COMPRESSED is not set
713 +# CONFIG_SLIP_SMART is not set
714 +# CONFIG_SLIP_MODE_SLIP6 is not set
717 +# Networking options
720 +CONFIG_PACKET_MMAP=y
721 +# CONFIG_NETLINK_DEV is not set
722 +# CONFIG_NETFILTER is not set
723 +# CONFIG_FILTER is not set
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
738 +# SCTP Configuration (EXPERIMENTAL)
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
748 +# CONFIG_IPX is not set
749 +# CONFIG_ATALK is not set
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
767 +# QoS and/or fair queueing
769 +# CONFIG_NET_SCHED is not set
774 +# CONFIG_NET_PKTGEN is not set
780 +# CONFIG_QFMT_V2 is not set
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
796 +# CONFIG_JBD_DEBUG is not set
801 +# CONFIG_EFS_FS is not set
803 +CONFIG_JFFS_FS_VERBOSE=0
804 +CONFIG_JFFS_PROC_FS=y
806 +CONFIG_JFFS2_FS_DEBUG=0
807 +# CONFIG_CRAMFS is not set
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
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
823 +CONFIG_DEVFS_MOUNT=y
824 +# CONFIG_DEVFS_DEBUG is not set
826 +# CONFIG_QNX4FS_FS is not set
827 +# CONFIG_QNX4FS_RW is not set
828 +# CONFIG_ROMFS_FS is not set
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
842 +# Network File Systems
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
870 +# CONFIG_PARTITION_ADVANCED is not set
871 +CONFIG_MSDOS_PARTITION=y
872 +# CONFIG_SMB_NLS is not set
876 +# Native Language Support
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
923 +# SCSI support type (disk, tape, CD-ROM)
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
931 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
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
940 +# Multi-device support (RAID and LVM)
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
952 +# Memory Technology Devices (MTD)
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
962 +# User Modules And Translation Layers
966 +# CONFIG_FTL is not set
967 +# CONFIG_NFTL is not set
970 +# RAM/ROM/Flash chip drivers
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
987 +# Mapping drivers for chip access
989 +# CONFIG_MTD_PHYSMAP is not set
990 +# CONFIG_MTD_PCI is not set
991 +# CONFIG_MTD_PCMCIA is not set
994 +# Self-contained MTD device drivers
996 +# CONFIG_MTD_PMC551 is not set
997 +# CONFIG_MTD_SLRAM is not set
998 +# CONFIG_MTD_MTDRAM is not set
1002 +# Disk-On-Chip Device Drivers
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
1010 +# NAND Flash Device Drivers
1012 +# CONFIG_MTD_NAND is not set
1017 +# CONFIG_CRC32 is not set
1018 +CONFIG_ZLIB_INFLATE=y
1019 +CONFIG_ZLIB_DEFLATE=y
1024 +# CONFIG_DEBUG_SLAB is not set
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
1034 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
1035 + * Licensed under the GPL
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"
1049 +#include "irq_user.h"
1054 +static void *not_configged_init(char *str, int device, struct chan_opts *opts)
1056 + printk(KERN_ERR "Using a channel type which is configured out of "
1061 +static int not_configged_open(int input, int output, int primary, void *data,
1064 + printk(KERN_ERR "Using a channel type which is configured out of "
1069 +static void not_configged_close(int fd, void *data)
1071 + printk(KERN_ERR "Using a channel type which is configured out of "
1075 +static int not_configged_read(int fd, char *c_out, void *data)
1077 + printk(KERN_ERR "Using a channel type which is configured out of "
1082 +static int not_configged_write(int fd, const char *buf, int len, void *data)
1084 + printk(KERN_ERR "Using a channel type which is configured out of "
1089 +static int not_configged_console_write(int fd, const char *buf, int len,
1092 + printk(KERN_ERR "Using a channel type which is configured out of "
1097 +static int not_configged_window_size(int fd, void *data, unsigned short *rows,
1098 + unsigned short *cols)
1100 + printk(KERN_ERR "Using a channel type which is configured out of "
1105 +static void not_configged_free(void *data)
1107 + printk(KERN_ERR "Using a channel type which is configured out of "
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,
1123 +void generic_close(int fd, void *unused)
1125 + os_close_file(fd);
1128 +int generic_read(int fd, char *c_out, void *unused)
1132 + n = os_read_file(fd, c_out, sizeof(*c_out));
1141 +/* XXX Trivial wrapper around os_write_file */
1143 +int generic_write(int fd, const char *buf, int n, void *unused)
1145 + return(os_write_file(fd, buf, n));
1148 +int generic_window_size(int fd, void *unused, unsigned short *rows_out,
1149 + unsigned short *cols_out)
1154 + ret = os_window_size(fd, &rows, &cols);
1158 + ret = ((*rows_out != rows) || (*cols_out != cols));
1166 +void generic_free(void *data)
1171 +static void tty_receive_char(struct tty_struct *tty, char ch)
1173 + if(tty == NULL) return;
1175 + if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
1176 + if(ch == STOP_CHAR(tty)){
1180 + else if(ch == START_CHAR(tty)){
1186 + if((tty->flip.flag_buf_ptr == NULL) ||
1187 + (tty->flip.char_buf_ptr == NULL))
1189 + tty_insert_flip_char(tty, ch, TTY_NORMAL);
1192 +static int open_one_chan(struct chan *chan, int input, int output, int primary)
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,
1200 + if(fd < 0) return(fd);
1207 +int open_chan(struct list_head *chans)
1209 + struct list_head *ele;
1210 + struct chan *chan;
1213 + list_for_each(ele, chans){
1214 + chan = list_entry(ele, struct chan, list);
1215 + ret = open_one_chan(chan, chan->input, chan->output,
1217 + if(chan->primary) err = ret;
1222 +void chan_enable_winch(struct list_head *chans, void *line)
1224 + struct list_head *ele;
1225 + struct chan *chan;
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);
1236 +void enable_chan(struct list_head *chans, void *data)
1238 + struct list_head *ele;
1239 + struct chan *chan;
1241 + list_for_each(ele, chans){
1242 + chan = list_entry(ele, struct chan, list);
1243 + if(!chan->opened) continue;
1245 + line_setup_irq(chan->fd, chan->input, chan->output, data);
1249 +void close_chan(struct list_head *chans)
1251 + struct list_head *ele;
1252 + struct chan *chan;
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.
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);
1269 +int write_chan(struct list_head *chans, const char *buf, int len,
1272 + struct list_head *ele;
1273 + struct chan *chan;
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){
1282 + if((ret == -EAGAIN) || ((ret >= 0) && (ret < len))){
1283 + reactivate_fd(chan->fd, write_irq);
1284 + if(ret == -EAGAIN) ret = 0;
1291 +int console_write_chan(struct list_head *chans, const char *buf, int len)
1293 + struct list_head *ele;
1294 + struct chan *chan;
1297 + list_for_each(ele, chans){
1298 + chan = list_entry(ele, struct chan, list);
1299 + if(!chan->output || (chan->ops->console_write == NULL))
1301 + n = chan->ops->console_write(chan->fd, buf, len, chan->data);
1302 + if(chan->primary) ret = n;
1307 +int chan_window_size(struct list_head *chans, unsigned short *rows_out,
1308 + unsigned short *cols_out)
1310 + struct list_head *ele;
1311 + struct chan *chan;
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));
1324 +void free_one_chan(struct chan *chan)
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);
1334 +void free_chan(struct list_head *chans)
1336 + struct list_head *ele, *next;
1337 + struct chan *chan;
1339 + list_for_each_safe(ele, next, chans){
1340 + chan = list_entry(ele, struct chan, list);
1341 + free_one_chan(chan);
1345 +static int one_chan_config_string(struct chan *chan, char *str, int size,
1351 + CONFIG_CHUNK(str, size, n, "none", 1);
1355 + CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
1357 + if(chan->dev == NULL){
1358 + CONFIG_CHUNK(str, size, n, "", 1);
1362 + CONFIG_CHUNK(str, size, n, ":", 0);
1363 + CONFIG_CHUNK(str, size, n, chan->dev, 0);
1368 +static int chan_pair_config_string(struct chan *in, struct chan *out,
1369 + char *str, int size, char **error_out)
1373 + n = one_chan_config_string(in, str, size, error_out);
1378 + CONFIG_CHUNK(str, size, n, "", 1);
1382 + CONFIG_CHUNK(str, size, n, ",", 1);
1383 + n = one_chan_config_string(out, str, size, error_out);
1386 + CONFIG_CHUNK(str, size, n, "", 1);
1391 +int chan_config_string(struct list_head *chans, char *str, int size,
1394 + struct list_head *ele;
1395 + struct chan *chan, *in = NULL, *out = NULL;
1397 + list_for_each(ele, chans){
1398 + chan = list_entry(ele, struct chan, list);
1399 + if(!chan->primary)
1407 + return(chan_pair_config_string(in, out, str, size, error_out));
1412 + struct chan_ops *ops;
1415 +struct chan_type chan_table[] = {
1416 +#ifdef CONFIG_FD_CHAN
1417 + { "fd", &fd_ops },
1419 + { "fd", ¬_configged_ops },
1422 +#ifdef CONFIG_NULL_CHAN
1423 + { "null", &null_ops },
1425 + { "null", ¬_configged_ops },
1428 +#ifdef CONFIG_PORT_CHAN
1429 + { "port", &port_ops },
1431 + { "port", ¬_configged_ops },
1434 +#ifdef CONFIG_PTY_CHAN
1435 + { "pty", &pty_ops },
1436 + { "pts", &pts_ops },
1438 + { "pty", ¬_configged_ops },
1439 + { "pts", ¬_configged_ops },
1442 +#ifdef CONFIG_TTY_CHAN
1443 + { "tty", &tty_ops },
1445 + { "tty", ¬_configged_ops },
1448 +#ifdef CONFIG_XTERM_CHAN
1449 + { "xterm", &xterm_ops },
1451 + { "xterm", ¬_configged_ops },
1455 +static struct chan *parse_chan(char *str, int pri, int device,
1456 + struct chan_opts *opts)
1458 + struct chan_type *entry;
1459 + struct chan_ops *ops;
1460 + struct chan *chan;
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))){
1470 + str += strlen(entry->key);
1475 + printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n",
1479 + if(ops->init == NULL) return(NULL);
1480 + data = (*ops->init)(str, device, opts);
1481 + if(data == NULL) return(NULL);
1483 + chan = kmalloc(sizeof(*chan), GFP_KERNEL);
1484 + if(chan == NULL) return(NULL);
1485 + *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list),
1497 +int parse_chan_pair(char *str, struct list_head *chans, int pri, int device,
1498 + struct chan_opts *opts)
1500 + struct chan *new, *chan;
1503 + if(!list_empty(chans)){
1504 + chan = list_entry(chans->next, struct chan, list);
1505 + if(chan->pri >= pri) return(0);
1507 + INIT_LIST_HEAD(chans);
1510 + out = strchr(str, ',');
1515 + new = parse_chan(in, pri, device, opts);
1516 + if(new == NULL) return(-1);
1518 + list_add(&new->list, chans);
1520 + new = parse_chan(out, pri, device, opts);
1521 + if(new == NULL) return(-1);
1522 + list_add(&new->list, chans);
1526 + new = parse_chan(str, pri, device, opts);
1527 + if(new == NULL) return(-1);
1528 + list_add(&new->list, chans);
1535 +int chan_out_fd(struct list_head *chans)
1537 + struct list_head *ele;
1538 + struct chan *chan;
1540 + list_for_each(ele, chans){
1541 + chan = list_entry(ele, struct chan, list);
1542 + if(chan->primary && chan->output)
1548 +void chan_interrupt(struct list_head *chans, struct tq_struct *task,
1549 + struct tty_struct *tty, int irq, void *dev)
1551 + struct list_head *ele, *next;
1552 + struct chan *chan;
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;
1560 + if((tty != NULL) &&
1561 + (tty->flip.count >= TTY_FLIPBUF_SIZE)){
1562 + queue_task(task, &tq_timer);
1565 + err = chan->ops->read(chan->fd, &c, chan->data);
1567 + tty_receive_char(tty, c);
1570 + if(err == 0) reactivate_fd(chan->fd, irq);
1572 + if(chan->primary){
1575 + line_disable(dev, irq);
1576 + close_chan(chans);
1581 + if(chan->ops->close != NULL)
1582 + chan->ops->close(chan->fd, chan->data);
1583 + free_one_chan(chan);
1588 + if(tty) tty_flip_buffer_push(tty);
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
1596 + * ---------------------------------------------------------------------------
1597 + * Local variables:
1598 + * c-file-style: "linux"
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
1607 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
1608 + * Licensed under the GPL
1611 +#include <unistd.h>
1612 +#include <stdlib.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"
1624 +#include "helper.h"
1626 +#include "choose-mode.h"
1629 +static void winch_handler(int sig)
1633 +struct winch_data {
1639 +/* XXX This breaks horribly (by hanging UML) when moved to chan_kern.c -
1640 + * needs investigation
1642 +int generic_console_write(int fd, const char *buf, int n, void *unused)
1644 + struct termios save, new;
1648 + tcgetattr(fd, &save);
1650 + new.c_oflag |= OPOST;
1651 + tcsetattr(fd, TCSAFLUSH, &new);
1653 + err = generic_write(fd, buf, n, NULL);
1654 + if(isatty(fd)) tcsetattr(fd, TCSAFLUSH, &save);
1658 +static int winch_thread(void *arg)
1660 + struct winch_data *data = arg;
1662 + int pty_fd, pipe_fd;
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);
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",
1684 + printk("winch_thread : setsid failed, errno = %d\n", errno);
1688 + err = os_new_tty_pgrp(pty_fd, os_getpid());
1690 + printk("winch_thread : new_tty_pgrp failed, err = %d\n", -err);
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);
1702 + count = os_write_file(pipe_fd, &c, sizeof(c));
1703 + if(count != sizeof(c))
1704 + printk("winch_thread : write failed, err = %d\n",
1709 +static int winch_tramp(int fd, void *device_data, int *fd_out)
1711 + struct winch_data data;
1712 + unsigned long stack;
1713 + int fds[2], pid, n, err;
1716 + err = os_pipe(fds, 1, 1);
1718 + printk("winch_tramp : os_pipe failed, err = %d\n", -err);
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);
1727 + printk("fork of winch_thread failed - errno = %d\n", errno);
1731 + os_close_file(fds[1]);
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);
1743 +void register_winch(int fd, void *device_data)
1745 + int pid, thread, thread_fd;
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);
1757 + register_winch_irq(thread_fd, fd, thread, device_data);
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",
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
1773 + * ---------------------------------------------------------------------------
1774 + * Local variables:
1775 + * c-file-style: "linux"
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
1786 +#include <asm/types.h>
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)
1795 +#error "__BYTE_ORDER not defined"
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);
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);
1809 +extern int write_cow_header(char *cow_file, int fd, char *backing_file,
1810 + int sectorsize, int alignment, long long *size);
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);
1819 + * ---------------------------------------------------------------------------
1820 + * Local variables:
1821 + * c-file-style: "linux"
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
1829 +#define COW_MAJOR 60
1830 +#define MAJOR_NR COW_MAJOR
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"
1845 +#include "ubd_user.h"
1847 +#define COW_SHIFT 4
1853 + struct block_device *cow_bdev;
1854 + char *backing_path;
1855 + dev_t backing_dev;
1856 + struct block_device *backing_bdev;
1858 + unsigned long *bitmap;
1859 + unsigned long bitmap_len;
1860 + int bitmap_offset;
1862 + devfs_handle_t devfs;
1863 + struct semaphore sem;
1864 + struct semaphore io_sem;
1866 + spinlock_t io_lock;
1867 + struct buffer_head *bh;
1868 + struct buffer_head *bhtail;
1872 +#define DEFAULT_COW { \
1874 + .cow_path = NULL, \
1876 + .backing_path = NULL, \
1877 + .backing_dev = 0, \
1879 + .bitmap_len = 0, \
1880 + .bitmap_offset = 0, \
1881 + .data_offset = 0, \
1883 + .working = ATOMIC_INIT(0), \
1884 + .io_lock = SPIN_LOCK_UNLOCKED, \
1887 +#define MAX_DEV (8)
1888 +#define MAX_MINOR (MAX_DEV << COW_SHIFT)
1890 +struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
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 };
1896 +/* Protected by cow_lock */
1897 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
1899 +static struct hd_struct cow_part[MAX_MINOR] =
1900 + { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
1902 +/* Protected by io_request_lock */
1903 +static request_queue_t *cow_queue;
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);
1911 +static struct block_device_operations cow_blops = {
1913 + .release = cow_release,
1914 + .ioctl = cow_ioctl,
1915 + .revalidate = cow_revalidate,
1918 +/* Initialized in an initcall, and unchanged thereafter */
1919 +devfs_handle_t cow_dir_handle;
1921 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
1924 + .major_name = name, \
1925 + .minor_shift = shift, \
1926 + .max_p = 1 << shift, \
1928 + .sizes = bsizes, \
1930 + .real_devices = NULL, \
1937 +static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
1939 +static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
1940 + COW_SHIFT, sizes, MAX_DEV,
1943 +static int cow_add(int n)
1945 + struct cow *dev = &cow_dev[n];
1946 + char name[sizeof("nnnnnn\0")];
1947 + int err = -ENODEV;
1949 + if(dev->cow_path == NULL)
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);
1958 + init_MUTEX_LOCKED(&dev->sem);
1959 + init_MUTEX(&dev->io_sem);
1968 + * Add buffer_head to back of pending list
1970 +static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
1972 + unsigned long flags;
1974 + spin_lock_irqsave(&cow->io_lock, flags);
1975 + if(cow->bhtail != NULL){
1976 + cow->bhtail->b_reqnext = bh;
1983 + spin_unlock_irqrestore(&cow->io_lock, flags);
1987 + * Grab first pending buffer
1989 +static struct buffer_head *cow_get_bh(struct cow *cow)
1991 + struct buffer_head *bh;
1993 + spin_lock_irq(&cow->io_lock);
1996 + if(bh == cow->bhtail)
1997 + cow->bhtail = NULL;
1998 + cow->bh = bh->b_reqnext;
1999 + bh->b_reqnext = NULL;
2001 + spin_unlock_irq(&cow->io_lock);
2006 +static void cow_handle_bh(struct cow *cow, struct buffer_head *bh,
2007 + struct buffer_head **cow_bh, int ncow_bh)
2012 + ll_rw_block(WRITE, ncow_bh, cow_bh);
2014 + for(i = 0; i < ncow_bh ; i++){
2015 + wait_on_buffer(cow_bh[i]);
2016 + brelse(cow_bh[i]);
2019 + ll_rw_block(WRITE, 1, &bh);
2023 +static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
2025 + struct buffer_head *bh;
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])),
2034 +/* Copied from loop.c, needed to avoid deadlocking in make_request. */
2036 +static int cow_thread(void *data)
2038 + struct cow *dev = data;
2039 + struct buffer_head *bh;
2042 + exit_files(current);
2044 + sprintf(current->comm, "cow%d", dev - cow_dev);
2046 + spin_lock_irq(¤t->sigmask_lock);
2047 + sigfillset(¤t->blocked);
2048 + flush_signals(current);
2049 + spin_unlock_irq(¤t->sigmask_lock);
2051 + atomic_inc(&dev->working);
2053 + current->policy = SCHED_OTHER;
2054 + current->nice = -20;
2056 + current->flags |= PF_NOIO;
2059 + * up sem, we are running
2064 + int start, len, nbh, i, update_bitmap = 0;
2065 + struct buffer_head *cow_bh[2];
2067 + down_interruptible(&dev->io_sem);
2069 + * could be upped because of tear-down, not because of
2072 + if(!atomic_read(&dev->working))
2075 + bh = cow_get_bh(dev);
2077 + printk(KERN_ERR "cow: missing bh\n");
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))
2088 + update_bitmap = 1;
2089 + ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
2095 + if(update_bitmap){
2096 + cow_bh[0] = cow_new_bh(dev, start);
2098 + if(start / dev->sectorsize !=
2099 + (start + len) / dev->sectorsize){
2100 + cow_bh[1] = cow_new_bh(dev, start + len);
2105 + bh->b_dev = dev->cow_dev;
2106 + bh->b_blocknr += dev->data_offset / dev->sectorsize;
2108 + cow_handle_bh(dev, bh, cow_bh, nbh);
2111 + * upped both for pending work and tear-down, lo_pending
2112 + * will hit zero then
2114 + if(atomic_dec_and_test(&dev->working))
2122 +static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
2127 + minor = MINOR(bh->b_rdev);
2128 + n = minor >> COW_SHIFT;
2129 + dev = &cow_dev[n];
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;
2136 + else if(rw == WRITE){
2137 + bh->b_dev = dev->cow_dev;
2138 + bh->b_blocknr += dev->data_offset / dev->sectorsize;
2140 + cow_add_bh(dev, bh);
2145 + bh->b_rdev = dev->backing_dev;
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);
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);
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);
2170 + add_gendisk(&cow_gendisk);
2172 + for(i=0;i<MAX_DEV;i++)
2178 +__initcall(cow_init);
2180 +static int reader(__u64 start, char *buf, int count, void *arg)
2182 + dev_t dev = *((dev_t *) arg);
2183 + struct buffer_head *bh;
2185 + int cur, offset, left, n, blocksize = get_hardsect_size(dev);
2187 + if(blocksize == 0)
2188 + panic("Zero blocksize");
2190 + block = start / blocksize;
2191 + offset = start % blocksize;
2195 + n = (left > blocksize) ? blocksize : left;
2197 + bh = bread(dev, block, (n < 512) ? 512 : n);
2202 + memcpy(&buf[cur], bh->b_data + offset, n);
2213 +static int cow_open(struct inode *inode, struct file *filp)
2215 + int (*dev_ioctl)(struct inode *, struct file *, unsigned int,
2220 + __u32 version, align;
2222 + char *backing_file;
2223 + int n, offset, err = 0;
2225 + n = DEVICE_NR(inode->i_rdev);
2228 + dev = &cow_dev[n];
2229 + offset = n << COW_SHIFT;
2231 + spin_lock(&cow_lock);
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);
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);
2251 + dev->cow_bdev = bdget(dev->cow_dev);
2252 + if(dev->cow_bdev == NULL){
2253 + printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n",
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);
2267 + err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0,
2270 + printk("cow_open - blkdev_get of COW device failed, "
2271 + "error = %d\n", err);
2275 + err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
2277 + printk("cow_open - blkdev_get of backing device "
2278 + "failed, error = %d\n", err);
2282 + err = read_cow_header(reader, &dev->cow_dev, &version,
2283 + &backing_file, &mtime, &size,
2284 + &dev->sectorsize, &align,
2285 + &dev->bitmap_offset);
2287 + printk(KERN_ERR "cow_open - read_cow_header failed, "
2288 + "err = %d\n", err);
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){
2298 + printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
2301 + flush_tlb_kernel_vm();
2303 + err = reader(dev->bitmap_offset, (char *) dev->bitmap,
2304 + dev->bitmap_len, &dev->cow_dev);
2306 + printk(KERN_ERR "Failed to read COW bitmap\n");
2307 + vfree(dev->bitmap);
2311 + dev_ioctl = dev->backing_bdev->bd_op->ioctl;
2313 + set_fs(KERNEL_DS);
2314 + err = (*dev_ioctl)(inode, filp, BLKGETSIZE,
2315 + (unsigned long) &sizes[offset]);
2318 + printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
2319 + "error = %d\n", err);
2323 + kernel_thread(cow_thread, dev,
2324 + CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
2329 + spin_unlock(&cow_lock);
2333 +static int cow_release(struct inode * inode, struct file * file)
2338 + n = DEVICE_NR(inode->i_rdev);
2341 + dev = &cow_dev[n];
2343 + spin_lock(&cow_lock);
2345 + if(--dev->count > 0)
2348 + err = blkdev_put(dev->cow_bdev, BDEV_RAW);
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;
2355 + err = blkdev_put(dev->backing_bdev, BDEV_RAW);
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;
2363 + spin_unlock(&cow_lock);
2367 +static int cow_ioctl(struct inode * inode, struct file * file,
2368 + unsigned int cmd, unsigned long arg)
2371 + int (*dev_ioctl)(struct inode *, struct file *, unsigned int,
2375 + n = DEVICE_NR(inode->i_rdev);
2378 + dev = &cow_dev[n];
2380 + dev_ioctl = dev->backing_bdev->bd_op->ioctl;
2381 + return((*dev_ioctl)(inode, file, cmd, arg));
2384 +static int cow_revalidate(kdev_t rdev)
2386 + printk(KERN_ERR "Need to implement cow_revalidate\n");
2390 +static int parse_unit(char **ptr)
2392 + char *str = *ptr, *end;
2395 + if(isdigit(*str)) {
2396 + n = simple_strtoul(str, &end, 0);
2401 + else if (('a' <= *str) && (*str <= 'h')) {
2409 +static int cow_setup(char *str)
2412 + char *cow_name, *backing_name;
2415 + unit = parse_unit(&str);
2417 + printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
2422 + printk(KERN_ERR "cow_setup - Missing '=' after unit "
2429 + backing_name = strchr(str, ',');
2430 + if(backing_name == NULL){
2431 + printk(KERN_ERR "cow_setup - missing backing device name\n");
2434 + *backing_name = '\0';
2437 + spin_lock(&cow_lock);
2439 + dev = &cow_dev[unit];
2440 + dev->cow_path = cow_name;
2441 + dev->backing_path = backing_name;
2443 + spin_unlock(&cow_lock);
2447 +__setup("cow", cow_setup);
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
2454 + * ---------------------------------------------------------------------------
2455 + * Local variables:
2456 + * c-file-style: "linux"
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
2464 +#ifndef __COW_SYS_H__
2465 +#define __COW_SYS_H__
2467 +#include "kern_util.h"
2468 +#include "user_util.h"
2472 +static inline void *cow_malloc(int size)
2474 + return(um_kmalloc(size));
2477 +static inline void cow_free(void *ptr)
2482 +#define cow_printf printk
2484 +static inline char *cow_strdup(char *str)
2486 + return(uml_strdup(str));
2489 +static inline int cow_seek_file(int fd, __u64 offset)
2491 + return(os_seek_file(fd, offset));
2494 +static inline int cow_file_size(char *file, __u64 *size_out)
2496 + return(os_file_size(file, size_out));
2499 +static inline int cow_write_file(int fd, char *buf, int size)
2501 + return(os_write_file(fd, buf, size));
2507 + * ---------------------------------------------------------------------------
2508 + * Local variables:
2509 + * c-file-style: "linux"
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
2517 +#include <stddef.h>
2518 +#include <string.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>
2530 +#include "cow_sys.h"
2532 +#define PATH_LEN_V1 256
2534 +struct cow_header_v1 {
2537 + char backing_file[PATH_LEN_V1];
2543 +#define PATH_LEN_V2 MAXPATHLEN
2545 +struct cow_header_v2 {
2548 + char backing_file[PATH_LEN_V2];
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
2557 +#define PATH_LEN_V3 4096
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
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
2583 +struct cow_header_v3 {
2591 + char backing_file[PATH_LEN_V3];
2594 +/* COW format definitions - for now, we have only the usual COW bitmap */
2595 +#define COW_BITMAP 0
2598 + struct cow_header_v1 v1;
2599 + struct cow_header_v2 v2;
2600 + struct cow_header_v3 v3;
2603 +#define COW_MAGIC 0x4f4f4f4d /* MOOO */
2604 +#define COW_VERSION 3
2606 +#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len))
2607 +#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align)
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)
2614 + *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
2616 + *data_offset_out = bitmap_offset + *bitmap_len_out;
2617 + *data_offset_out = (*data_offset_out + sectorsize - 1) /
2619 + *data_offset_out *= sectorsize;
2622 + *bitmap_len_out = DIV_ROUND(size, sectorsize);
2623 + *bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8);
2625 + *data_offset_out = bitmap_offset + *bitmap_len_out;
2626 + *data_offset_out = ROUND_UP(*data_offset_out, align);
2630 +static int absolutize(char *to, int size, char *from)
2632 + char save_cwd[256], *slash;
2635 + if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
2636 + cow_printf("absolutize : unable to get cwd - errno = %d\n",
2640 + slash = strrchr(from, '/');
2641 + if(slash != NULL){
2645 + cow_printf("absolutize : Can't cd to '%s' - "
2646 + "errno = %d\n", from, errno);
2650 + if(getcwd(to, size) == NULL){
2651 + cow_printf("absolutize : unable to get cwd of '%s' - "
2652 + "errno = %d\n", from, errno);
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);
2661 + strcat(to, slash);
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);
2669 + strcpy(to, save_cwd);
2677 +int write_cow_header(char *cow_file, int fd, char *backing_file,
2678 + int sectorsize, int alignment, long long *size)
2680 + struct cow_header_v3 *header;
2681 + unsigned long modtime;
2684 + err = cow_seek_file(fd, 0);
2686 + cow_printf("write_cow_header - lseek failed, err = %d\n", -err);
2691 + header = cow_malloc(sizeof(*header));
2692 + if(header == NULL){
2693 + cow_printf("Failed to allocate COW V3 header\n");
2696 + header->magic = htonl(COW_MAGIC);
2697 + header->version = htonl(COW_VERSION);
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);
2707 + if(absolutize(header->backing_file, sizeof(header->backing_file),
2711 + err = os_file_modtime(header->backing_file, &modtime);
2713 + cow_printf("Backing file '%s' mtime request failed, "
2714 + "err = %d\n", header->backing_file, -err);
2718 + err = cow_file_size(header->backing_file, size);
2720 + cow_printf("Couldn't get size of backing file '%s', "
2721 + "err = %d\n", header->backing_file, -err);
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;
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);
2744 +int file_reader(__u64 offset, char *buf, int len, void *arg)
2746 + int fd = *((int *) arg);
2748 + return(pread(fd, buf, len, offset));
2751 +/* XXX Need to sanity-check the values read from the header */
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)
2759 + union cow_header *header;
2762 + unsigned long version, magic;
2764 + header = cow_malloc(sizeof(*header));
2765 + if(header == NULL){
2766 + cow_printf("read_cow_header - Failed to allocate header\n");
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");
2776 + magic = header->v1.magic;
2777 + if(magic == COW_MAGIC) {
2778 + version = header->v1.version;
2780 + else if(magic == ntohl(COW_MAGIC)){
2781 + version = ntohl(header->v1.version);
2783 + /* No error printed because the non-COW case comes through here */
2786 + *version_out = version;
2789 + if(n < sizeof(header->v1)){
2790 + cow_printf("read_cow_header - failed to read V1 "
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;
2801 + else if(version == 2){
2802 + if(n < sizeof(header->v2)){
2803 + cow_printf("read_cow_header - failed to read V2 "
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;
2814 + else if(version == 3){
2815 + if(n < sizeof(header->v3)){
2816 + cow_printf("read_cow_header - failed to read V2 "
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;
2828 + cow_printf("read_cow_header - invalid COW version\n");
2832 + *backing_file_out = cow_strdup(file);
2833 + if(*backing_file_out == NULL){
2834 + cow_printf("read_cow_header - failed to allocate backing "
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)
2848 + __u64 size, offset;
2852 + err = write_cow_header(cow_file, fd, backing_file, sectorsize,
2853 + alignment, &size);
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);
2861 + offset = *data_offset_out + size - sizeof(zero);
2862 + err = cow_seek_file(fd, offset);
2864 + cow_printf("cow bitmap lseek failed : err = %d\n", -err);
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
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);
2887 + * ---------------------------------------------------------------------------
2888 + * Local variables:
2889 + * c-file-style: "linux"
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
2898 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
2899 + * Licensed under the GPL
2902 +#include "net_user.h"
2904 +#define SWITCH_VERSION 3
2906 +struct daemon_data {
2917 +extern struct net_user_info daemon_user_info;
2919 +extern int daemon_user_write(int fd, void *buf, int len,
2920 + struct daemon_data *pri);
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
2927 + * ---------------------------------------------------------------------------
2928 + * Local variables:
2929 + * c-file-style: "linux"
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
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.
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"
2952 +struct daemon_init {
2957 +void daemon_init(struct net_device *dev, void *data)
2959 + struct uml_net_private *pri;
2960 + struct daemon_data *dpri;
2961 + struct daemon_init *init = data;
2963 + init_etherdev(dev, 0);
2965 + dpri = (struct daemon_data *) pri->user;
2966 + *dpri = ((struct daemon_data)
2967 + { .sock_type = init->sock_type,
2968 + .ctl_sock = init->ctl_sock,
2970 + .data_addr = NULL,
2971 + .local_addr = NULL,
2976 + printk("daemon backend (uml_switch version %d) - %s:%s",
2977 + SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
2981 +static int daemon_read(int fd, struct sk_buff **skb,
2982 + struct uml_net_private *lp)
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));
2990 +static int daemon_write(int fd, struct sk_buff **skb,
2991 + struct uml_net_private *lp)
2993 + return(daemon_user_write(fd, (*skb)->data, (*skb)->len,
2994 + (struct daemon_data *) &lp->user));
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,
3004 +int daemon_setup(char *str, char **mac_out, void *data)
3006 + struct daemon_init *init = data;
3009 + *init = ((struct daemon_init)
3010 + { .sock_type = "unix",
3011 + .ctl_sock = "/tmp/uml.ctl" });
3013 + remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
3015 + if(remain != NULL)
3016 + printk(KERN_WARNING "daemon_setup : Ignoring data socket "
3017 + "specification\n");
3022 +static struct transport daemon_transport = {
3023 + .list = LIST_HEAD_INIT(daemon_transport.list),
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),
3032 +static int register_daemon(void)
3034 + register_transport(&daemon_transport);
3038 +__initcall(register_daemon);
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
3045 + * ---------------------------------------------------------------------------
3046 + * Local variables:
3047 + * c-file-style: "linux"
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
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.
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"
3075 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
3077 +enum request_type { REQ_NEW_CONTROL };
3079 +#define SWITCH_MAGIC 0xfeedface
3081 +struct request_v3 {
3084 + enum request_type type;
3085 + struct sockaddr_un sock;
3088 +static struct sockaddr_un *new_addr(void *name, int len)
3090 + struct sockaddr_un *sun;
3092 + sun = um_kmalloc(sizeof(struct sockaddr_un));
3094 + printk("new_addr: allocation of sockaddr_un failed\n");
3097 + sun->sun_family = AF_UNIX;
3098 + memcpy(sun->sun_path, name, len);
3102 +static int connect_to_switch(struct daemon_data *pri)
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;
3110 + pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
3111 + if(pri->control < 0){
3112 + printk("daemon_open : control socket failed, errno = %d\n",
3117 + if(connect(pri->control, (struct sockaddr *) ctl_addr,
3118 + sizeof(*ctl_addr)) < 0){
3119 + printk("daemon_open : control connect failed, errno = %d\n",
3125 + fd = socket(AF_UNIX, SOCK_DGRAM, 0);
3127 + printk("daemon_open : data socket failed, errno = %d\n",
3132 + if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){
3133 + printk("daemon_open : data bind failed, errno = %d\n",
3139 + sun = um_kmalloc(sizeof(struct sockaddr_un));
3141 + printk("new_addr: allocation of sockaddr_un failed\n");
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",
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",
3166 + pri->data_addr = sun;
3170 + os_close_file(fd);
3172 + os_close_file(pri->control);
3176 +static void daemon_user_init(void *data, void *dev)
3178 + struct daemon_data *pri = data;
3179 + struct timeval tv;
3186 + if(!strcmp(pri->sock_type, "unix"))
3187 + pri->ctl_addr = new_addr(pri->ctl_sock,
3188 + strlen(pri->ctl_sock) + 1);
3190 + name.pid = os_getpid();
3191 + gettimeofday(&tv, NULL);
3192 + name.usecs = tv.tv_usec;
3193 + pri->local_addr = new_addr(&name, sizeof(name));
3195 + pri->fd = connect_to_switch(pri);
3197 + kfree(pri->local_addr);
3198 + pri->local_addr = NULL;
3202 +static int daemon_open(void *data)
3204 + struct daemon_data *pri = data;
3208 +static void daemon_remove(void *data)
3210 + struct daemon_data *pri = data;
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);
3219 +int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
3221 + struct sockaddr_un *data_addr = pri->data_addr;
3223 + return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
3226 +static int daemon_set_mtu(int mtu, void *data)
3231 +struct net_user_info daemon_user_info = {
3232 + .init = daemon_user_init,
3233 + .open = daemon_open,
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
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
3247 + * ---------------------------------------------------------------------------
3248 + * Local variables:
3249 + * c-file-style: "linux"
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
3258 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
3259 + * Licensed under the GPL
3263 +#include <stdlib.h>
3264 +#include <unistd.h>
3265 +#include <termios.h>
3268 +#include "user_util.h"
3269 +#include "chan_user.h"
3274 + struct termios tt;
3275 + char str[sizeof("1234567890\0")];
3278 +void *fd_init(char *str, int device, struct chan_opts *opts)
3280 + struct fd_chan *data;
3285 + printk("fd_init : channel type 'fd' must specify a file "
3290 + n = strtoul(str, &end, 0);
3291 + if((*end != '\0') || (end == str)){
3292 + printk("fd_init : couldn't parse file descriptor '%s'\n", str);
3295 + data = um_kmalloc(sizeof(*data));
3296 + if(data == NULL) return(NULL);
3297 + *data = ((struct fd_chan) { .fd = n,
3298 + .raw = opts->raw });
3302 +int fd_open(int input, int output, int primary, void *d, char **dev_out)
3304 + struct fd_chan *data = d;
3307 + if(data->raw && isatty(data->fd)){
3308 + CATCH_EINTR(err = tcgetattr(data->fd, &data->tt));
3312 + err = raw(data->fd);
3316 + sprintf(data->str, "%d", data->fd);
3317 + *dev_out = data->str;
3321 +void fd_close(int fd, void *d)
3323 + struct fd_chan *data = d;
3326 + if(data->raw && isatty(fd)){
3327 + CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt));
3329 + printk("Failed to restore terminal state - "
3330 + "errno = %d\n", -err);
3335 +int fd_console_write(int fd, const char *buf, int n, void *d)
3337 + struct fd_chan *data = d;
3339 + return(generic_console_write(fd, buf, n, &data->tt));
3342 +struct chan_ops fd_ops = {
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,
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
3360 + * ---------------------------------------------------------------------------
3361 + * Local variables:
3362 + * c-file-style: "linux"
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
3370 +/* UML hardware watchdog, shamelessly stolen from:
3372 + * SoftDog 0.05: A Software Watchdog Device
3374 + * (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
3375 + * http://www.redhat.com
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.
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.
3386 + * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
3388 + * Software only watchdog driver. Unlike its big brother the WDT501P
3389 + * driver this won't always recover a failed machine.
3391 + * 03/96: Angelo Haritsis <ah@doc.ic.ac.uk> :
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
3397 + * 19980911 Alan Cox
3398 + * Made SMP safe for 2.3.x
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.
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"
3421 +MODULE_LICENSE("GPL");
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;
3429 + * Allow only one person to hold it open
3432 +extern int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock);
3434 +static int harddog_open(struct inode *inode, struct file *file)
3437 + char *sock = NULL;
3442 +#ifdef CONFIG_HARDDOG_NOWAYOUT
3443 + MOD_INC_USE_COUNT;
3446 +#ifdef CONFIG_MCONSOLE
3447 + sock = mconsole_notify_socket();
3449 + err = start_watchdog(&harddog_in_fd, &harddog_out_fd, sock);
3450 + if(err) return(err);
3457 +extern void stop_watchdog(int in_fd, int out_fd);
3459 +static int harddog_release(struct inode *inode, struct file *file)
3462 + * Shut off the timer.
3466 + stop_watchdog(harddog_in_fd, harddog_out_fd);
3467 + harddog_in_fd = -1;
3468 + harddog_out_fd = -1;
3475 +extern int ping_watchdog(int fd);
3477 +static ssize_t harddog_write(struct file *file, const char *data, size_t len,
3480 + /* Can't seek (pwrite) on this device */
3481 + if (ppos != &file->f_pos)
3485 + * Refresh the timer.
3488 + return(ping_watchdog(harddog_out_fd));
3492 +static int harddog_ioctl(struct inode *inode, struct file *file,
3493 + unsigned int cmd, unsigned long arg)
3495 + static struct watchdog_info ident = {
3498 + "UML Hardware Watchdog"
3503 + case WDIOC_GETSUPPORT:
3504 + if(copy_to_user((struct harddog_info *)arg, &ident,
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));
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,
3524 +static struct miscdevice harddog_miscdev = {
3525 + .minor = WATCHDOG_MINOR,
3526 + .name = "watchdog",
3527 + .fops = &harddog_fops,
3530 +static char banner[] __initdata = KERN_INFO "UML Watchdog Timer\n";
3532 +static int __init harddog_init(void)
3536 + ret = misc_register(&harddog_miscdev);
3546 +static void __exit harddog_exit(void)
3548 + misc_deregister(&harddog_miscdev);
3551 +module_init(harddog_init);
3552 +module_exit(harddog_exit);
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
3559 + * ---------------------------------------------------------------------------
3560 + * Local variables:
3561 + * c-file-style: "linux"
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
3570 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3571 + * Licensed under the GPL
3575 +#include <unistd.h>
3577 +#include "user_util.h"
3579 +#include "helper.h"
3580 +#include "mconsole.h"
3582 +#include "choose-mode.h"
3591 +static void pre_exec(void *d)
3593 + struct dog_data *data = d;
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]);
3604 +int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
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,
3612 + char **args = NULL;
3614 + err = os_pipe(in_fds, 1, 0);
3616 + printk("harddog_open - os_pipe failed, err = %d\n", -err);
3620 + err = os_pipe(out_fds, 1, 0);
3622 + printk("harddog_open - os_pipe failed, err = %d\n", -err);
3623 + goto out_close_in;
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];
3632 + mconsole_args[2] = sock;
3633 + args = mconsole_args;
3636 + /* XXX The os_getpid() is not SMP correct */
3637 + sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid()));
3641 + pid = run_helper(pre_exec, &data, args, NULL);
3643 + os_close_file(out_fds[0]);
3644 + os_close_file(in_fds[1]);
3648 + printk("harddog_open - run_helper failed, errno = %d\n", -err);
3649 + goto out_close_out;
3652 + n = os_read_file(in_fds[0], &c, sizeof(c));
3654 + printk("harddog_open - EOF on watchdog pipe\n");
3657 + goto out_close_out;
3660 + printk("harddog_open - read of watchdog pipe failed, "
3661 + "err = %d\n", -n);
3664 + goto out_close_out;
3666 + *in_fd_ret = in_fds[0];
3667 + *out_fd_ret = out_fds[1];
3671 + os_close_file(in_fds[0]);
3672 + os_close_file(in_fds[1]);
3674 + os_close_file(out_fds[0]);
3675 + os_close_file(out_fds[1]);
3680 +void stop_watchdog(int in_fd, int out_fd)
3682 + os_close_file(in_fd);
3683 + os_close_file(out_fd);
3686 +int ping_watchdog(int fd)
3691 + n = os_write_file(fd, &c, sizeof(c));
3692 + if(n != sizeof(c)){
3693 + printk("ping_watchdog - write failed, err = %d\n", -n);
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
3707 + * ---------------------------------------------------------------------------
3708 + * Local variables:
3709 + * c-file-style: "linux"
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
3718 + * Copyright (C) 2002 Steve Schmidtke
3719 + * Licensed under the GPL
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"
3734 +struct hostaudio_state {
3738 +struct hostmixer_state {
3742 +#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
3743 +#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
3745 +/* Only changed from linux_main at boot time */
3746 +char *dsp = HOSTAUDIO_DEV_DSP;
3747 +char *mixer = HOSTAUDIO_DEV_MIXER;
3750 +" This is used to specify the host dsp device to the hostaudio driver.\n" \
3751 +" The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
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"
3758 +static int set_dsp(char *name, int *add)
3764 +__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
3766 +static int set_mixer(char *name, int *add)
3772 +__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
3776 +MODULE_PARM(dsp, "s");
3777 +MODULE_PARM_DESC(dsp, DSP_HELP);
3779 +MODULE_PARM(mixer, "s");
3780 +MODULE_PARM_DESC(mixer, MIXER_HELP);
3784 +/* /dev/dsp file operations */
3786 +static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count,
3789 + struct hostaudio_state *state = file->private_data;
3794 + printk("hostaudio: read called, count = %d\n", count);
3797 + kbuf = kmalloc(count, GFP_KERNEL);
3801 + err = os_read_file(state->fd, kbuf, count);
3805 + if(copy_to_user(buffer, kbuf, err))
3813 +static ssize_t hostaudio_write(struct file *file, const char *buffer,
3814 + size_t count, loff_t *ppos)
3816 + struct hostaudio_state *state = file->private_data;
3821 + printk("hostaudio: write called, count = %d\n", count);
3824 + kbuf = kmalloc(count, GFP_KERNEL);
3829 + if(copy_from_user(kbuf, buffer, count))
3832 + err = os_write_file(state->fd, kbuf, count);
3842 +static unsigned int hostaudio_poll(struct file *file,
3843 + struct poll_table_struct *wait)
3845 + unsigned int mask = 0;
3848 + printk("hostaudio: poll called (unimplemented)\n");
3854 +static int hostaudio_ioctl(struct inode *inode, struct file *file,
3855 + unsigned int cmd, unsigned long arg)
3857 + struct hostaudio_state *state = file->private_data;
3858 + unsigned long data = 0;
3862 + printk("hostaudio: ioctl called, cmd = %u\n", 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))
3878 + err = os_ioctl_generic(state->fd, cmd, (unsigned long) &data);
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))
3897 +static int hostaudio_open(struct inode *inode, struct file *file)
3899 + struct hostaudio_state *state;
3904 + printk("hostaudio: open called (host: %s)\n", dsp);
3907 + state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
3911 + if(file->f_mode & FMODE_READ) r = 1;
3912 + if(file->f_mode & FMODE_WRITE) w = 1;
3914 + ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
3921 + file->private_data = state;
3925 +static int hostaudio_release(struct inode *inode, struct file *file)
3927 + struct hostaudio_state *state = file->private_data;
3930 + printk("hostaudio: release called\n");
3933 + os_close_file(state->fd);
3939 +/* /dev/mixer file operations */
3941 +static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file,
3942 + unsigned int cmd, unsigned long arg)
3944 + struct hostmixer_state *state = file->private_data;
3947 + printk("hostmixer: ioctl called\n");
3950 + return(os_ioctl_generic(state->fd, cmd, arg));
3953 +static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
3955 + struct hostmixer_state *state;
3960 + printk("hostmixer: open called (host: %s)\n", mixer);
3963 + state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL);
3964 + if(state == NULL) return(-ENOMEM);
3966 + if(file->f_mode & FMODE_READ) r = 1;
3967 + if(file->f_mode & FMODE_WRITE) w = 1;
3969 + ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
3972 + printk("hostaudio_open_mixdev failed to open '%s', err = %d\n",
3978 + file->private_data = state;
3982 +static int hostmixer_release(struct inode *inode, struct file *file)
3984 + struct hostmixer_state *state = file->private_data;
3987 + printk("hostmixer: release called\n");
3990 + os_close_file(state->fd);
3997 +/* kernel module operations */
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,
4007 + .open = hostaudio_open,
4008 + .release = hostaudio_release,
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,
4024 +MODULE_AUTHOR("Steve Schmidtke");
4025 +MODULE_DESCRIPTION("UML Audio Relay");
4026 +MODULE_LICENSE("GPL");
4028 +static int __init hostaudio_init_module(void)
4030 + printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
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");
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 "
4043 + unregister_sound_dsp(module_data.dev_audio);
4050 +static void __exit hostaudio_cleanup_module (void)
4052 + unregister_sound_mixer(module_data.dev_mixer);
4053 + unregister_sound_dsp(module_data.dev_audio);
4056 +module_init(hostaudio_init_module);
4057 +module_exit(hostaudio_cleanup_module);
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
4064 + * ---------------------------------------------------------------------------
4065 + * Local variables:
4066 + * c-file-style: "linux"
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
4075 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4076 + * Licensed under the GPL
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"
4089 +#include "user_util.h"
4090 +#include "kern_util.h"
4092 +#include "irq_kern.h"
4094 +#define LINE_BUFSIZE 4096
4096 +static void line_interrupt(int irq, void *data, struct pt_regs *unused)
4098 + struct line *dev = data;
4100 + if(dev->count > 0)
4101 + chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq,
4105 +static void line_timer_cb(void *arg)
4107 + struct line *dev = arg;
4109 + line_interrupt(dev->driver->read_irq, dev, NULL);
4112 +static int write_room(struct line *dev)
4116 + if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
4118 + n = dev->head - dev->tail;
4119 + if(n <= 0) n = LINE_BUFSIZE + n;
4123 +static int buffer_data(struct line *line, const char *buf, int len)
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");
4133 + line->head = line->buffer;
4134 + line->tail = line->buffer;
4137 + room = write_room(line);
4138 + len = (len > room) ? room : len;
4140 + end = line->buffer + LINE_BUFSIZE - line->tail;
4142 + memcpy(line->tail, buf, len);
4143 + line->tail += len;
4146 + memcpy(line->tail, buf, end);
4149 + memcpy(line->buffer, buf, len);
4150 + line->tail = line->buffer + len;
4156 +static int flush_buffer(struct line *line)
4160 + if((line->buffer == NULL) || (line->head == line->tail)) return(1);
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;
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);
4180 + return(line->head == line->tail);
4183 +int line_write(struct line *lines, struct tty_struct *tty, int from_user,
4184 + const char *buf, int len)
4186 + struct line *line;
4188 + unsigned long flags;
4189 + int n, err, i, ret = 0;
4191 + if(tty->stopped) return 0;
4194 + new = kmalloc(len, GFP_KERNEL);
4197 + n = copy_from_user(new, buf, len);
4207 + i = minor(tty->device) - tty->driver.minor_start;
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);
4220 + n = write_chan(&line->chan_list, buf, len,
4221 + line->driver->write_irq);
4230 + ret += buffer_data(line, buf + n, len);
4241 +static void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
4243 + struct line *dev = data;
4244 + struct tty_struct *tty = dev->tty;
4247 + err = flush_buffer(dev);
4248 + if(err == 0) return;
4250 + dev->head = dev->buffer;
4251 + dev->tail = dev->buffer;
4254 + if(tty == NULL) return;
4256 + if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
4257 + (tty->ldisc.write_wakeup != NULL))
4258 + (tty->ldisc.write_wakeup)(tty);
4261 + * In blocking mode, everything sleeps on tty->write_wait.
4262 + * Sleeping in the console driver would break non-blocking
4266 + if (waitqueue_active(&tty->write_wait))
4267 + wake_up_interruptible(&tty->write_wait);
4271 +int line_setup_irq(int fd, int input, int output, void *data)
4273 + struct line *line = data;
4274 + struct line_driver *driver = line->driver;
4275 + int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
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;
4288 +void line_disable(struct line *line, int current_irq)
4290 + if(!line->have_irq) return;
4292 + if(line->driver->read_irq == current_irq)
4293 + free_irq_later(line->driver->read_irq, line);
4295 + free_irq(line->driver->read_irq, line);
4297 + if(line->driver->write_irq == current_irq)
4298 + free_irq_later(line->driver->write_irq, line);
4300 + free_irq(line->driver->write_irq, line);
4302 + line->have_irq = 0;
4305 +int line_open(struct line *lines, struct tty_struct *tty,
4306 + struct chan_opts *opts)
4308 + struct line *line;
4311 + if(tty == NULL) n = 0;
4312 + else n = minor(tty->device) - tty->driver.minor_start;
4316 + if(line->count == 0){
4321 + if(list_empty(&line->chan_list)){
4322 + err = parse_chan_pair(line->init_str, &line->chan_list,
4323 + line->init_pri, n, opts);
4325 + err = open_chan(&line->chan_list);
4328 + enable_chan(&line->chan_list, line);
4329 + INIT_TQUEUE(&line->task, line_timer_cb, line);
4333 + chan_enable_winch(&line->chan_list, line);
4337 + /* This is outside the if because the initial console is opened
4338 + * with tty == NULL
4343 + tty->driver_data = line;
4344 + chan_window_size(&line->chan_list, &tty->winsize.ws_row,
4345 + &tty->winsize.ws_col);
4354 +void line_close(struct line *lines, struct tty_struct *tty)
4356 + struct line *line;
4359 + if(tty == NULL) n = 0;
4360 + else n = minor(tty->device) - tty->driver.minor_start;
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.
4372 + if((line->tty != NULL) && (line->tty->count == 1))
4374 + if(line->count == 0)
4375 + line_disable(line, -1);
4379 +void close_lines(struct line *lines, int nlines)
4383 + for(i = 0; i < nlines; i++)
4384 + close_chan(&lines[i].chan_list);
4387 +int line_setup(struct line *lines, int num, char *init, int all_allowed)
4392 + if(*init == '=') n = -1;
4394 + n = simple_strtoul(init, &end, 0);
4396 + printk(KERN_ERR "line_setup failed to parse \"%s\"\n",
4403 + if((n >= 0) && (n >= num)){
4404 + printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
4409 + if(lines[n].count > 0){
4410 + printk("line_setup - device %d is open\n", n);
4413 + if(lines[n].init_pri <= INIT_ONE){
4414 + lines[n].init_pri = INIT_ONE;
4415 + if(!strcmp(init, "none")) lines[n].valid = 0;
4417 + lines[n].init_str = init;
4418 + lines[n].valid = 1;
4422 + else if(!all_allowed){
4423 + printk("line_setup - can't configure all devices from "
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;
4433 + lines[i].init_str = init;
4434 + lines[i].valid = 1;
4442 +int line_config(struct line *lines, int num, char *str)
4444 + char *new = uml_strdup(str);
4447 + printk("line_config - uml_strdup failed\n");
4450 + return(!line_setup(lines, num, new, 0));
4453 +int line_get_config(char *name, struct line *lines, int num, char *str,
4454 + int size, char **error_out)
4456 + struct line *line;
4460 + dev = simple_strtoul(name, &end, 0);
4461 + if((*end != '\0') || (end == name)){
4462 + *error_out = "line_get_config failed to parse device number";
4466 + if((dev < 0) || (dev >= num)){
4467 + *error_out = "device number of of range";
4471 + line = &lines[dev];
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);
4484 +int line_remove(struct line *lines, int num, char *str)
4486 + char config[sizeof("conxxxx=none\0")];
4488 + sprintf(config, "%s=none", str);
4489 + return(!line_setup(lines, num, config, 0));
4492 +static int line_write_room(struct tty_struct *tty)
4494 + struct line *dev = tty->driver_data;
4496 + return(write_room(dev));
4499 +void line_register_devfs(struct lines *set, struct line_driver *line_driver,
4500 + struct tty_driver *driver, struct line *lines,
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;
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]),
4521 + if((driver->table == NULL) || (driver->termios == NULL) ||
4522 + (driver->termios_locked == NULL))
4523 + panic("Failed to allocate driver table");
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]));
4530 + driver->write_room = line_write_room;
4531 + driver->init_termios = tty_std_termios;
4533 + if (tty_register_driver(driver))
4534 + panic("line_register_devfs : Couldn't register driver\n");
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);
4542 + for(i = 0; i < nlines; i++){
4543 + if(!lines[i].valid)
4544 + tty_unregister_devfs(driver, driver->minor_start + i);
4547 + mconsole_register_dev(&line_driver->mc);
4550 +void lines_init(struct line *lines, int nlines)
4552 + struct line *line;
4555 + for(i = 0; i < nlines; 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 "
4569 + struct list_head list;
4573 + struct line *line;
4576 +void winch_interrupt(int irq, void *data, struct pt_regs *unused)
4578 + struct winch *winch = data;
4579 + struct tty_struct *tty;
4583 + if(winch->fd != -1){
4584 + err = generic_read(winch->fd, &c, NULL);
4586 + if(err != -EAGAIN){
4587 + printk("winch_interrupt : read failed, "
4588 + "errno = %d\n", -err);
4589 + printk("fd %d is losing SIGWINCH support\n",
4596 + tty = winch->line->tty;
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);
4604 + if(winch->fd != -1)
4605 + reactivate_fd(winch->fd, WINCH_IRQ);
4608 +DECLARE_MUTEX(winch_handler_sem);
4609 +LIST_HEAD(winch_handlers);
4611 +void register_winch_irq(int fd, int tty_fd, int pid, void *line)
4613 + struct winch *winch;
4615 + down(&winch_handler_sem);
4616 + winch = kmalloc(sizeof(*winch), GFP_KERNEL);
4617 + if(winch == NULL){
4618 + printk("register_winch_irq - kmalloc failed\n");
4621 + *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list),
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");
4632 + up(&winch_handler_sem);
4635 +static void winch_cleanup(void)
4637 + struct list_head *ele;
4638 + struct winch *winch;
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);
4646 + if(winch->pid != -1)
4647 + os_kill_process(winch->pid, 1);
4651 +__uml_exitcall(winch_cleanup);
4653 +char *add_xterm_umid(char *base)
4655 + char *umid, *title;
4658 + umid = get_umid(1);
4659 + if(umid == NULL) return(base);
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");
4668 + strncpy(title, base, len);
4669 + len -= strlen(title);
4670 + snprintf(&title[strlen(title)], len, " (%s)", umid);
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
4679 + * ---------------------------------------------------------------------------
4680 + * Local variables:
4681 + * c-file-style: "linux"
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
4690 +# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
4691 +# Licensed under the GPL
4694 +O_TARGET := built-in.o
4696 +CHAN_OBJS := chan_kern.o chan_user.o line.o
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
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
4714 +export-objs := mconsole_kern.o
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
4738 +CFLAGS_pcap_user.o = -I/usr/include/pcap
4740 +obj-y += stdio_console.o $(CHAN_OBJS)
4742 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
4744 +USER_OBJS = $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
4745 + null.o pty.o tty.o xterm.o
4747 +include $(TOPDIR)/Rules.make
4749 +$(USER_OBJS) : %.o: %.c
4750 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
4762 +daemon.o : $(daemon-objs)
4764 +slip.o : $(slip-objs)
4766 +slirp.o : $(slirp-objs)
4768 +mcast.o : $(mcast-objs)
4770 +pcap.o : $(pcap-objs)
4772 +mconsole.o : $(mconsole-objs)
4774 +net.o : $(net-objs)
4776 +hostaudio.o : $(hostaudio-objs)
4778 +ubd.o : $(ubd-objs)
4780 +port.o : $(port-objs)
4782 +harddog.o : $(harddog-objs)
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
4792 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
4793 + * Licensed under the GPL
4796 +#include "net_user.h"
4798 +struct mcast_data {
4800 + unsigned short port;
4806 +extern struct net_user_info mcast_user_info;
4808 +extern int mcast_user_write(int fd, void *buf, int len,
4809 + struct mcast_data *pri);
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
4816 + * ---------------------------------------------------------------------------
4817 + * Local variables:
4818 + * c-file-style: "linux"
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
4827 + * user-mode-linux networking multicast transport
4828 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
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.
4835 + * Licensed under the GPL.
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"
4848 +struct mcast_init {
4854 +void mcast_init(struct net_device *dev, void *data)
4856 + struct uml_net_private *pri;
4857 + struct mcast_data *dpri;
4858 + struct mcast_init *init = data;
4860 + init_etherdev(dev, 0);
4862 + dpri = (struct mcast_data *) pri->user;
4863 + *dpri = ((struct mcast_data)
4864 + { .addr = init->addr,
4865 + .port = init->port,
4867 + .mcast_addr = NULL,
4869 + printk("mcast backend ");
4870 + printk("multicast adddress: %s:%u, TTL:%u ",
4871 + dpri->addr, dpri->port, dpri->ttl);
4876 +static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
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));
4884 +static int mcast_write(int fd, struct sk_buff **skb,
4885 + struct uml_net_private *lp)
4887 + return mcast_user_write(fd, (*skb)->data, (*skb)->len,
4888 + (struct mcast_data *) &lp->user);
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,
4898 +int mcast_setup(char *str, char **mac_out, void *data)
4900 + struct mcast_init *init = data;
4901 + char *port_str = NULL, *ttl_str = NULL, *remain;
4905 + *init = ((struct mcast_init)
4906 + { .addr = "239.192.168.1",
4910 + remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
4912 + if(remain != NULL){
4913 + printk(KERN_ERR "mcast_setup - Extra garbage on "
4914 + "specification : '%s'\n", remain);
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",
4925 + init->port = htons(n);
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",
4937 + printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
4938 + init->port, init->ttl);
4943 +static struct transport mcast_transport = {
4944 + .list = LIST_HEAD_INIT(mcast_transport.list),
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),
4953 +static int register_mcast(void)
4955 + register_transport(&mcast_transport);
4959 +__initcall(register_mcast);
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
4966 + * ---------------------------------------------------------------------------
4967 + * Local variables:
4968 + * c-file-style: "linux"
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
4977 + * user-mode-linux networking multicast transport
4978 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
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.
4985 + * Licensed under the GPL.
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"
4998 +#include "kern_util.h"
4999 +#include "user_util.h"
5003 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
5005 +static struct sockaddr_in *new_addr(char *addr, unsigned short port)
5007 + struct sockaddr_in *sin;
5009 + sin = um_kmalloc(sizeof(struct sockaddr_in));
5011 + printk("new_addr: allocation of sockaddr_in failed\n");
5014 + sin->sin_family = AF_INET;
5015 + sin->sin_addr.s_addr = in_aton(addr);
5016 + sin->sin_port = port;
5020 +static void mcast_user_init(void *data, void *dev)
5022 + struct mcast_data *pri = data;
5024 + pri->mcast_addr = new_addr(pri->addr, pri->port);
5028 +static int mcast_open(void *data)
5030 + struct mcast_data *pri = data;
5031 + struct sockaddr_in *sin = pri->mcast_addr;
5032 + struct ip_mreq mreq;
5036 + if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) {
5041 + fd = socket(AF_INET, SOCK_DGRAM, 0);
5043 + printk("mcast_open : data socket failed, errno = %d\n",
5049 + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
5050 + printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
5052 + os_close_file(fd);
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",
5062 + os_close_file(fd);
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",
5071 + os_close_file(fd);
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);
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",
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);
5103 +static void mcast_close(int fd, void *data)
5105 + struct ip_mreq mreq;
5106 + struct mcast_data *pri = data;
5107 + struct sockaddr_in *sin = pri->mcast_addr;
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",
5117 + os_close_file(fd);
5120 +int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
5122 + struct sockaddr_in *data_addr = pri->mcast_addr;
5124 + return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
5127 +static int mcast_set_mtu(int mtu, void *data)
5132 +struct net_user_info mcast_user_info = {
5133 + .init = mcast_user_init,
5134 + .open = mcast_open,
5135 + .close = mcast_close,
5137 + .set_mtu = mcast_set_mtu,
5138 + .add_address = NULL,
5139 + .delete_address = NULL,
5140 + .max_packet = MAX_PACKET - ETH_HEADER_OTHER
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
5148 + * ---------------------------------------------------------------------------
5149 + * Local variables:
5150 + * c-file-style: "linux"
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
5159 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
5160 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
5161 + * Licensed under the GPL
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"
5183 +#include "mconsole.h"
5184 +#include "mconsole_kern.h"
5185 +#include "irq_user.h"
5189 +#include "irq_kern.h"
5191 +static int do_unlink_socket(struct notifier_block *notifier,
5192 + unsigned long what, void *data)
5194 + return(mconsole_unlink_socket());
5198 +static struct notifier_block reboot_notifier = {
5199 + .notifier_call = do_unlink_socket,
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.
5208 +LIST_HEAD(mc_requests);
5210 +static void mc_task_proc(void *unused)
5212 + struct mconsole_entry *req;
5213 + unsigned long flags;
5215 + while(!list_empty(&mc_requests)){
5216 + local_irq_save(flags);
5217 + req = list_entry(mc_requests.next, struct mconsole_entry,
5219 + list_del(&req->list);
5220 + local_irq_restore(flags);
5221 + req->request.cmd->handler(&req->request);
5226 +struct tq_struct mconsole_task = {
5227 + .routine = mc_task_proc,
5231 +static void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
5234 + struct mconsole_entry *new;
5235 + struct mc_request req;
5237 + fd = (int) dev_id;
5238 + while (mconsole_get_request(fd, &req)){
5239 + if(req.cmd->context == MCONSOLE_INTR)
5240 + (*req.cmd->handler)(&req);
5242 + new = kmalloc(sizeof(*new), GFP_ATOMIC);
5244 + mconsole_reply(&req, "Out of memory", 1, 0);
5246 + new->request = req;
5247 + list_add(&new->list, &mc_requests);
5252 + if(!list_empty(&mc_requests))
5253 + schedule_task(&mconsole_task);
5254 + reactivate_fd(fd, MCONSOLE_IRQ);
5257 +void mconsole_version(struct mc_request *req)
5259 + char version[256];
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);
5267 +void mconsole_log(struct mc_request *req)
5270 + char *ptr = req->request.data;
5272 + ptr += strlen("log ");
5274 + len = req->len - (ptr - req->request.data);
5275 + printk("%.*s", len, ptr);
5276 + mconsole_reply(req, "", 0, 0);
5279 +void mconsole_proc(struct mc_request *req)
5281 + struct nameidata nd;
5282 + struct file_system_type *proc;
5283 + struct super_block *super;
5284 + struct file *file;
5286 + char *ptr = req->request.data, *buf;
5288 + ptr += strlen("proc");
5289 + while(isspace(*ptr)) ptr++;
5291 + proc = get_fs_type("proc");
5293 + mconsole_reply(req, "procfs not registered", 1, 0);
5297 + super = get_anon_super(proc, NULL, NULL);
5298 + if(super == NULL){
5299 + mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
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);
5310 + up_write(&super->s_umount);
5312 + nd.dentry = super->s_root;
5314 + nd.flags = O_RDONLY + 1;
5315 + nd.last_type = LAST_ROOT;
5317 + err = link_path_walk(ptr, &nd);
5319 + mconsole_reply(req, "Failed to look up file", 1, 0);
5323 + file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
5325 + mconsole_reply(req, "Failed to open file", 1, 0);
5329 + buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
5331 + mconsole_reply(req, "Failed to allocate buffer", 1, 0);
5335 + if((file->f_op != NULL) && (file->f_op->read != NULL)){
5337 + n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1,
5341 + mconsole_reply(req, buf, 0, (n > 0));
5344 + mconsole_reply(req, "Read of file failed",
5350 + else mconsole_reply(req, "", 0, 0);
5357 + kill_super(super);
5359 + /* put_filesystem(proc); */
5363 +#define UML_MCONSOLE_HELPTEXT \
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\
5381 +void mconsole_help(struct mc_request *req)
5383 + mconsole_reply(req, UML_MCONSOLE_HELPTEXT, 0, 0);
5386 +void mconsole_halt(struct mc_request *req)
5388 + mconsole_reply(req, "", 0, 0);
5392 +void mconsole_reboot(struct mc_request *req)
5394 + mconsole_reply(req, "", 0, 0);
5395 + machine_restart(NULL);
5398 +extern void ctrl_alt_del(void);
5400 +void mconsole_cad(struct mc_request *req)
5402 + mconsole_reply(req, "", 0, 0);
5406 +void mconsole_go(struct mc_request *req)
5408 + mconsole_reply(req, "Not stopped", 1, 0);
5411 +void mconsole_stop(struct mc_request *req)
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);
5420 + os_set_fd_block(req->originating_fd, 0);
5421 + reactivate_fd(req->originating_fd, MCONSOLE_IRQ);
5422 + mconsole_reply(req, "", 0, 0);
5425 +/* This list is populated by __initcall routines. */
5427 +LIST_HEAD(mconsole_devices);
5429 +void mconsole_register_dev(struct mc_device *new)
5431 + list_add(&new->list, &mconsole_devices);
5434 +static struct mc_device *mconsole_find_dev(char *name)
5436 + struct list_head *ele;
5437 + struct mc_device *dev;
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)))
5447 +#define CONFIG_BUF_SIZE 64
5449 +static void mconsole_get_config(int (*get_config)(char *, char *, int,
5451 + struct mc_request *req, char *name)
5453 + char default_buf[CONFIG_BUF_SIZE], *error, *buf;
5456 + if(get_config == NULL){
5457 + mconsole_reply(req, "No get_config routine defined", 1, 0);
5462 + size = sizeof(default_buf)/sizeof(default_buf[0]);
5463 + buf = default_buf;
5466 + n = (*get_config)(name, buf, size, &error);
5467 + if(error != NULL){
5468 + mconsole_reply(req, error, 1, 0);
5473 + mconsole_reply(req, buf, 0, 0);
5477 + if(buf != default_buf)
5481 + buf = kmalloc(size, GFP_KERNEL);
5483 + mconsole_reply(req, "Failed to allocate buffer", 1, 0);
5488 + if(buf != default_buf)
5493 +void mconsole_config(struct mc_request *req)
5495 + struct mc_device *dev;
5496 + char *ptr = req->request.data, *name;
5499 + ptr += strlen("config");
5500 + while(isspace(*ptr)) ptr++;
5501 + dev = mconsole_find_dev(ptr);
5503 + mconsole_reply(req, "Bad configuration option", 1, 0);
5507 + name = &ptr[strlen(dev->name)];
5509 + while((*ptr != '=') && (*ptr != '\0'))
5513 + err = (*dev->config)(name);
5514 + mconsole_reply(req, "", err, 0);
5516 + else mconsole_get_config(dev->get_config, req, name);
5519 +void mconsole_remove(struct mc_request *req)
5521 + struct mc_device *dev;
5522 + char *ptr = req->request.data;
5525 + ptr += strlen("remove");
5526 + while(isspace(*ptr)) ptr++;
5527 + dev = mconsole_find_dev(ptr);
5529 + mconsole_reply(req, "Bad remove option", 1, 0);
5532 + err = (*dev->remove)(&ptr[strlen(dev->name)]);
5533 + mconsole_reply(req, "", err, 0);
5536 +#ifdef CONFIG_MAGIC_SYSRQ
5537 +void mconsole_sysrq(struct mc_request *req)
5539 + char *ptr = req->request.data;
5541 + ptr += strlen("sysrq");
5542 + while(isspace(*ptr)) ptr++;
5544 + mconsole_reply(req, "", 0, 0);
5545 + handle_sysrq(*ptr, ¤t->thread.regs, NULL, NULL);
5548 +void mconsole_sysrq(struct mc_request *req)
5550 + mconsole_reply(req, "Sysrq not compiled in", 1, 0);
5554 +/* Changed by mconsole_setup, which is __setup, and called before SMP is
5557 +static char *notify_socket = NULL;
5559 +int mconsole_init(void)
5564 + if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
5565 + snprintf(mconsole_socket_name, sizeof(file), "%s", file);
5567 + sock = os_create_unix_socket(file, sizeof(file), 1);
5569 + printk("Failed to initialize management console\n");
5573 + register_reboot_notifier(&reboot_notifier);
5575 + err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
5576 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
5577 + "mconsole", (void *)sock);
5579 + printk("Failed to get IRQ for management console\n");
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 "
5593 + printk("mconsole (version %d) initialized on %s\n",
5594 + MCONSOLE_VERSION, mconsole_socket_name);
5598 +__initcall(mconsole_init);
5600 +static int write_proc_mconsole(struct file *file, const char *buffer,
5601 + unsigned long count, void *data)
5605 + buf = kmalloc(count + 1, GFP_KERNEL);
5609 + if(copy_from_user(buf, buffer, count)){
5614 + buf[count] = '\0';
5616 + mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
5622 +static int create_proc_mconsole(void)
5624 + struct proc_dir_entry *ent;
5626 + if(notify_socket == NULL) return(0);
5628 + ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
5630 + printk("create_proc_mconsole : create_proc_entry failed\n");
5634 + ent->read_proc = NULL;
5635 + ent->write_proc = write_proc_mconsole;
5639 +static spinlock_t notify_spinlock = SPIN_LOCK_UNLOCKED;
5641 +void lock_notify(void)
5643 + spin_lock(¬ify_spinlock);
5646 +void unlock_notify(void)
5648 + spin_unlock(¬ify_spinlock);
5651 +__initcall(create_proc_mconsole);
5653 +#define NOTIFY "=notify:"
5655 +static int mconsole_setup(char *str)
5657 + if(!strncmp(str, NOTIFY, strlen(NOTIFY))){
5658 + str += strlen(NOTIFY);
5659 + notify_socket = str;
5661 + else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str);
5665 +__setup("mconsole", mconsole_setup);
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"
5675 +static int notify_panic(struct notifier_block *self, unsigned long unused1,
5678 + char *message = ptr;
5680 + if(notify_socket == NULL) return(0);
5682 + mconsole_notify(notify_socket, MCONSOLE_PANIC, message,
5683 + strlen(message) + 1);
5687 +static struct notifier_block panic_exit_notifier = {
5688 + .notifier_call = notify_panic,
5693 +static int add_notifier(void)
5695 + notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
5699 +__initcall(add_notifier);
5701 +char *mconsole_notify_socket(void)
5703 + return(notify_socket);
5706 +EXPORT_SYMBOL(mconsole_notify_socket);
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
5713 + * ---------------------------------------------------------------------------
5714 + * Local variables:
5715 + * c-file-style: "linux"
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
5724 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
5725 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
5726 + * Licensed under the GPL
5730 +#include <stdlib.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>
5739 +#include "mconsole.h"
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 },
5757 +/* Initialized in mconsole_init, which is an initcall */
5758 +char mconsole_socket_name[256];
5760 +int mconsole_reply_v0(struct mc_request *req, char *reply)
5763 + struct msghdr msg;
5765 + iov.iov_base = reply;
5766 + iov.iov_len = strlen(reply);
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;
5776 + return sendmsg(req->originating_fd, &msg, 0);
5779 +static struct mconsole_command *mconsole_parse(struct mc_request *req)
5781 + struct mconsole_command *cmd;
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))){
5794 +#define MIN(a,b) ((a)<(b) ? (a):(b))
5796 +#define STRINGX(x) #x
5797 +#define STRING(x) STRINGX(x)
5799 +int mconsole_get_request(int fd, struct mc_request *req)
5803 + req->originlen = sizeof(req->origin);
5804 + req->len = recvfrom(fd, &req->request, sizeof(req->request), 0,
5805 + (struct sockaddr *) req->origin, &req->originlen);
5809 + req->originating_fd = fd;
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';
5818 + req->request.magic = MCONSOLE_MAGIC;
5819 + req->request.version = 0;
5820 + req->request.len = len;
5822 + mconsole_reply_v0(req, "ERR Version 0 mconsole clients are "
5823 + "not supported by this driver");
5827 + if(req->request.len >= MCONSOLE_MAX_DATA){
5828 + mconsole_reply(req, "Request too large", 1, 0);
5831 + if(req->request.version != MCONSOLE_VERSION){
5832 + mconsole_reply(req, "This driver only supports version "
5833 + STRING(MCONSOLE_VERSION) " clients", 1, 0);
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);
5846 +int mconsole_reply(struct mc_request *req, char *str, int err, int more)
5848 + struct mconsole_reply reply;
5849 + int total, len, n;
5851 + total = strlen(str);
5855 + /* err can only be true on the first packet */
5858 + len = MIN(total, MCONSOLE_MAX_DATA - 1);
5860 + if(len == total) reply.more = more;
5861 + else reply.more = 1;
5863 + memcpy(reply.data, str, len);
5864 + reply.data[len] = '\0';
5867 + reply.len = len + 1;
5869 + len = sizeof(reply) + reply.len - sizeof(reply.data);
5871 + n = sendto(req->originating_fd, &reply, len, 0,
5872 + (struct sockaddr *) req->origin, req->originlen);
5874 + if(n < 0) return(-errno);
5875 + } while(total > 0);
5879 +int mconsole_unlink_socket(void)
5881 + unlink(mconsole_socket_name);
5885 +static int notify_sock = -1;
5887 +int mconsole_notify(char *sock_name, int type, const void *data, int len)
5889 + struct sockaddr_un target;
5890 + struct mconsole_notify packet;
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",
5907 + target.sun_family = AF_UNIX;
5908 + strcpy(target.sun_path, sock_name);
5910 + packet.magic = MCONSOLE_MAGIC;
5911 + packet.version = MCONSOLE_VERSION;
5912 + packet.type = type;
5913 + len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len;
5915 + memcpy(packet.data, data, len);
5918 + len = sizeof(packet) + packet.len - sizeof(packet.data);
5919 + n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target,
5922 + printk("mconsole_notify - sendto failed, errno = %d\n", errno);
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
5933 + * ---------------------------------------------------------------------------
5934 + * Local variables:
5935 + * c-file-style: "linux"
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
5944 + * arch/um/drivers/mmapper_kern.c
5946 + * BRIEF MODULE DESCRIPTION
5948 + * Copyright (C) 2000 RidgeRun, Inc.
5949 + * Author: RidgeRun, Inc.
5950 + * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
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"
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;
5973 +mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos)
5975 + if(*ppos > mmapper_size)
5978 + if(count + *ppos > mmapper_size)
5979 + count = count + *ppos - mmapper_size;
5984 + copy_to_user(buf,&v_buf[*ppos],count);
5990 +mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
5992 + if(*ppos > mmapper_size)
5995 + if(count + *ppos > mmapper_size)
5996 + count = count + *ppos - mmapper_size;
6001 + copy_from_user(&v_buf[*ppos],buf,count);
6007 +mmapper_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
6008 + unsigned long arg)
6010 + return(-ENOIOCTLCMD);
6014 +mmapper_mmap(struct file *file, struct vm_area_struct * vma)
6016 + int ret = -EINVAL;
6020 + if (vma->vm_pgoff != 0)
6023 + size = vma->vm_end - vma->vm_start;
6024 + if(size > mmapper_size) return(-EFAULT);
6026 + /* XXX A comment above remap_page_range says it should only be
6027 + * called when the mm semaphore is held
6029 + if (remap_page_range(vma->vm_start, p_buf, size, vma->vm_page_prot))
6038 +mmapper_open(struct inode *inode, struct file *file)
6044 +mmapper_release(struct inode *inode, struct file *file)
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,
6059 +static int __init mmapper_init(void)
6061 + printk(KERN_INFO "Mapper v0.1\n");
6063 + v_buf = (char *) find_iomem("mmapper", &mmapper_size);
6064 + if(mmapper_size == 0){
6065 + printk(KERN_ERR "mmapper_init - find_iomem failed\n");
6069 + p_buf = __pa(v_buf);
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",
6079 +static void mmapper_exit(void)
6083 +module_init(mmapper_init);
6084 +module_exit(mmapper_exit);
6086 +MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>");
6087 +MODULE_DESCRIPTION("DSPLinux simulator mmapper driver");
6089 + * ---------------------------------------------------------------------------
6090 + * Local variables:
6091 + * c-file-style: "linux"
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
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.
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"
6128 +#include "irq_user.h"
6129 +#include "irq_kern.h"
6131 +static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
6134 +static int uml_net_rx(struct net_device *dev)
6136 + struct uml_net_private *lp = dev->priv;
6138 + struct sk_buff *skb;
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++;
6148 + skb_put(skb, dev->mtu);
6149 + skb->mac.raw = skb->data;
6150 + pkt_len = (*lp->read)(lp->fd, &skb, lp);
6152 + if (pkt_len > 0) {
6153 + skb_trim(skb, pkt_len);
6154 + skb->protocol = (*lp->protocol)(skb);
6157 + lp->stats.rx_bytes += skb->len;
6158 + lp->stats.rx_packets++;
6166 +void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6168 + struct net_device *dev = dev_id;
6169 + struct uml_net_private *lp = dev->priv;
6172 + if(!netif_running(dev))
6175 + spin_lock(&lp->lock);
6176 + while((err = uml_net_rx(dev)) > 0) ;
6179 + "Device '%s' read returned %d, shutting it down\n",
6184 + reactivate_fd(lp->fd, UM_ETH_IRQ);
6187 + spin_unlock(&lp->lock);
6190 +static int uml_net_open(struct net_device *dev)
6192 + struct uml_net_private *lp = dev->priv;
6193 + char addr[sizeof("255.255.255.255\0")];
6196 + spin_lock(&lp->lock);
6203 + if(!lp->have_mac){
6204 + dev_ip_addr(dev, addr, &lp->mac[2]);
6205 + set_ether_mac(dev, lp->mac);
6208 + lp->fd = (*lp->open)(&lp->user);
6214 + err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
6215 + SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
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);
6220 + err = -ENETUNREACH;
6223 + lp->tl.data = (unsigned long) &lp->user;
6224 + netif_start_queue(dev);
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.
6233 + while((err = uml_net_rx(dev)) > 0) ;
6235 + MOD_INC_USE_COUNT;
6237 + spin_unlock(&lp->lock);
6241 +static int uml_net_close(struct net_device *dev)
6243 + struct uml_net_private *lp = dev->priv;
6245 + netif_stop_queue(dev);
6246 + spin_lock(&lp->lock);
6248 + free_irq(dev->irq, dev);
6249 + if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6251 + spin_lock(&opened_lock);
6252 + list_del(&lp->list);
6253 + spin_unlock(&opened_lock);
6255 + MOD_DEC_USE_COUNT;
6256 + spin_unlock(&lp->lock);
6260 +static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
6262 + struct uml_net_private *lp = dev->priv;
6263 + unsigned long flags;
6266 + netif_stop_queue(dev);
6268 + spin_lock_irqsave(&lp->lock, flags);
6270 + len = (*lp->write)(lp->fd, &skb, lp);
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);
6278 + /* this is normally done in the interrupt when tx finishes */
6279 + netif_wake_queue(dev);
6281 + else if(len == 0){
6282 + netif_start_queue(dev);
6283 + lp->stats.tx_dropped++;
6286 + netif_start_queue(dev);
6287 + printk(KERN_ERR "uml_net_start_xmit: failed(%d)\n", len);
6290 + spin_unlock_irqrestore(&lp->lock, flags);
6292 + dev_kfree_skb(skb);
6297 +static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
6299 + struct uml_net_private *lp = dev->priv;
6300 + return &lp->stats;
6303 +static void uml_net_set_multicast_list(struct net_device *dev)
6305 + if (dev->flags & IFF_PROMISC) return;
6306 + else if (dev->mc_count) dev->flags |= IFF_ALLMULTI;
6307 + else dev->flags &= ~IFF_ALLMULTI;
6310 +static void uml_net_tx_timeout(struct net_device *dev)
6312 + dev->trans_start = jiffies;
6313 + netif_wake_queue(dev);
6316 +static int uml_net_set_mac(struct net_device *dev, void *addr)
6318 + struct uml_net_private *lp = dev->priv;
6319 + struct sockaddr *hwaddr = addr;
6321 + spin_lock(&lp->lock);
6322 + memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
6323 + spin_unlock(&lp->lock);
6328 +static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
6330 + struct uml_net_private *lp = dev->priv;
6333 + spin_lock(&lp->lock);
6335 + new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
6341 + dev->mtu = new_mtu;
6344 + spin_unlock(&lp->lock);
6348 +static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6350 + static const struct ethtool_drvinfo info = {
6351 + .cmd = ETHTOOL_GDRVINFO,
6352 + .driver = "uml virtual ethernet",
6360 + useraddr = ifr->ifr_data;
6361 + if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd)))
6364 + case ETHTOOL_GDRVINFO:
6365 + if (copy_to_user(useraddr, &info, sizeof(info)))
6369 + return -EOPNOTSUPP;
6376 +void uml_net_user_timer_expire(unsigned long _conn)
6379 + struct connection *conn = (struct connection *)_conn;
6381 + dprintk(KERN_INFO "uml_net_user_timer_expire [%p]\n", conn);
6387 + * default do nothing hard header packet routines for struct net_device init.
6388 + * real ethernet transports will overwrite with real routines.
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)
6393 + return(0); /* no change */
6396 +static int uml_net_rebuild_header(struct sk_buff *skb)
6398 + return(0); /* ignore */
6401 +static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
6403 + return(-1); /* fail */
6406 +static void uml_net_header_cache_update(struct hh_cache *hh,
6407 + struct net_device *dev, unsigned char * haddr)
6412 +static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
6414 + return(0); /* nothing */
6417 +static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
6418 +static struct list_head devices = LIST_HEAD_INIT(devices);
6420 +static int eth_configure(int n, void *init, char *mac,
6421 + struct transport *transport)
6423 + struct uml_net *device;
6424 + struct net_device *dev;
6425 + struct uml_net_private *lp;
6426 + int save, err, size;
6428 + size = transport->private_size + sizeof(struct uml_net_private) +
6429 + sizeof(((struct uml_net_private *) 0)->user);
6431 + device = kmalloc(sizeof(*device), GFP_KERNEL);
6432 + if(device == NULL){
6433 + printk(KERN_ERR "eth_configure failed to allocate uml_net\n");
6437 + *device = ((struct uml_net) { .list = LIST_HEAD_INIT(device->list),
6440 + .mac = { [ 0 ... 5 ] = 0 },
6443 + spin_lock(&devices_lock);
6444 + list_add(&device->list, &devices);
6445 + spin_unlock(&devices_lock);
6447 + if(setup_etheraddr(mac, device->mac))
6448 + device->have_mac = 1;
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]);
6456 + dev = kmalloc(sizeof(*dev) + size, GFP_KERNEL);
6458 + printk(KERN_ERR "eth_configure: failed to allocate device\n");
6461 + memset(dev, 0, sizeof(*dev) + size);
6463 + snprintf(dev->name, sizeof(dev->name), "eth%d", n);
6464 + dev->priv = (void *) &dev[1];
6465 + device->dev = dev;
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;
6473 + (*transport->kern->init)(dev, init);
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;
6489 + err = register_netdevice(dev);
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.
6500 + save = lp->user[0];
6501 + *lp = ((struct uml_net_private)
6502 + { .list = LIST_HEAD_INIT(lp->list),
6503 + .lock = SPIN_LOCK_UNLOCKED,
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));
6523 + if(transport->user->init)
6524 + (*transport->user->init)(&lp->user, dev);
6526 + if(device->have_mac)
6527 + set_ether_mac(dev, device->mac);
6531 +static struct uml_net *find_device(int n)
6533 + struct uml_net *device;
6534 + struct list_head *ele;
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)
6544 + spin_unlock(&devices_lock);
6548 +static int eth_parse(char *str, int *index_out, char **str_out)
6553 + n = simple_strtoul(str, &end, 0);
6555 + printk(KERN_ERR "eth_setup: Failed to parse '%s'\n", str);
6559 + printk(KERN_ERR "eth_setup: device %d is negative\n", n);
6565 + "eth_setup: expected '=' after device number\n");
6569 + if(find_device(n)){
6570 + printk(KERN_ERR "eth_setup: Device %d already configured\n",
6574 + if(index_out) *index_out = n;
6580 + struct list_head list;
6585 +/* Filled in at boot time. Will need locking if the transports become
6588 +struct list_head transports = LIST_HEAD_INIT(transports);
6590 +/* Filled in during early boot */
6591 +struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
6593 +static int check_transport(struct transport *transport, char *eth, int n,
6594 + void **init_out, char **mac_out)
6598 + len = strlen(transport->name);
6599 + if(strncmp(eth, transport->name, len))
6605 + else if(*eth != '\0')
6608 + *init_out = kmalloc(transport->setup_size, GFP_KERNEL);
6609 + if(*init_out == NULL)
6612 + if(!transport->setup(eth, mac_out, *init_out)){
6619 +void register_transport(struct transport *new)
6621 + struct list_head *ele, *next;
6622 + struct eth_init *eth;
6627 + list_add(&new->list, &transports);
6629 + list_for_each_safe(ele, next, ð_cmd_line){
6630 + eth = list_entry(ele, struct eth_init, list);
6631 + match = check_transport(new, eth->init, eth->index, &init,
6635 + else if(init != NULL){
6636 + eth_configure(eth->index, init, mac, new);
6639 + list_del(ð->list);
6643 +static int eth_setup_common(char *str, int index)
6645 + struct list_head *ele;
6646 + struct transport *transport;
6650 + list_for_each(ele, &transports){
6651 + transport = list_entry(ele, struct transport, list);
6652 + if(!check_transport(transport, str, index, &init, &mac))
6655 + eth_configure(index, init, mac, transport);
6663 +static int eth_setup(char *str)
6665 + struct eth_init *new;
6668 + err = eth_parse(str, &n, &str);
6669 + if(err) return(1);
6671 + new = alloc_bootmem(sizeof(new));
6673 + printk("eth_init : alloc_bootmem failed\n");
6676 + *new = ((struct eth_init) { .list = LIST_HEAD_INIT(new->list),
6679 + list_add_tail(&new->list, ð_cmd_line);
6683 +__setup("eth", eth_setup);
6684 +__uml_help(eth_setup,
6685 +"eth[0-9]+=<transport>,<options>\n"
6686 +" Configure a network device.\n\n"
6689 +static int eth_init(void)
6691 + struct list_head *ele, *next;
6692 + struct eth_init *eth;
6694 + list_for_each_safe(ele, next, ð_cmd_line){
6695 + eth = list_entry(ele, struct eth_init, list);
6697 + if(eth_setup_common(eth->init, eth->index))
6698 + list_del(ð->list);
6704 +__initcall(eth_init);
6706 +static int net_config(char *str)
6710 + err = eth_parse(str, &n, &str);
6711 + if(err) return(err);
6713 + str = uml_strdup(str);
6715 + printk(KERN_ERR "net_config failed to strdup string\n");
6718 + err = !eth_setup_common(str, n);
6724 +static int net_remove(char *str)
6726 + struct uml_net *device;
6727 + struct net_device *dev;
6728 + struct uml_net_private *lp;
6732 + n = simple_strtoul(str, &end, 0);
6733 + if((*end != '\0') || (end == str))
6736 + device = find_device(n);
6737 + if(device == NULL)
6740 + dev = device->dev;
6742 + if(lp->fd > 0) return(-1);
6743 + if(lp->remove != NULL) (*lp->remove)(&lp->user);
6744 + unregister_netdev(dev);
6746 + list_del(&device->list);
6751 +static struct mc_device net_mc = {
6753 + .config = net_config,
6754 + .get_config = NULL,
6755 + .remove = net_remove,
6758 +static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
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];
6769 + if(dev->open != uml_net_open) return(NOTIFY_DONE);
6776 + proc = lp->add_address;
6779 + proc = lp->delete_address;
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);
6793 + return(NOTIFY_DONE);
6796 +struct notifier_block uml_inetaddr_notifier = {
6797 + .notifier_call = uml_inetaddr_event,
6800 +static int uml_net_init(void)
6802 + struct list_head *ele;
6803 + struct uml_net_private *lp;
6804 + struct in_device *ip;
6805 + struct in_ifaddr *in;
6807 + mconsole_register_dev(&net_mc);
6808 + register_inetaddr_notifier(¨_inetaddr_notifier);
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.
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;
6828 +__initcall(uml_net_init);
6830 +static void close_devices(void)
6832 + struct list_head *ele;
6833 + struct uml_net_private *lp;
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);
6842 +__uml_exitcall(close_devices);
6844 +int setup_etheraddr(char *str, unsigned char *addr)
6852 + addr[i] = simple_strtoul(str, &end, 16);
6853 + if((end == str) ||
6854 + ((*end != ':') && (*end != ',') && (*end != '\0'))){
6856 + "setup_etheraddr: failed to parse '%s' "
6857 + "as an ethernet address\n", str);
6864 + "Attempt to assign a broadcast ethernet address to a "
6865 + "device disallowed\n");
6871 +void dev_ip_addr(void *d, char *buf, char *bin_buf)
6873 + struct net_device *dev = d;
6874 + struct in_device *ip = dev->ip_ptr;
6875 + struct in_ifaddr *in;
6878 + if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
6879 + printk(KERN_WARNING "dev_ip_addr - device not assigned an "
6883 + addr = in->ifa_address;
6884 + sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff,
6885 + (addr >> 16) & 0xff, addr >> 24);
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;
6894 +void set_ether_mac(void *d, unsigned char *addr)
6896 + struct net_device *dev = d;
6898 + memcpy(dev->dev_addr, addr, ETH_ALEN);
6901 +struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
6903 + if((skb != NULL) && (skb_tailroom(skb) < extra)){
6904 + struct sk_buff *skb2;
6906 + skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
6907 + dev_kfree_skb(skb);
6910 + if(skb != NULL) skb_put(skb, extra);
6914 +void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
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];
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;
6939 +int dev_netmask(void *d, void *m)
6941 + struct net_device *dev = d;
6942 + struct in_device *ip = dev->ip_ptr;
6943 + struct in_ifaddr *in;
6944 + __u32 *mask_out = m;
6949 + in = ip->ifa_list;
6953 + *mask_out = in->ifa_mask;
6957 +void *get_output_buffer(int *len_out)
6961 + ret = (void *) __get_free_pages(GFP_KERNEL, 0);
6962 + if(ret) *len_out = PAGE_SIZE;
6963 + else *len_out = 0;
6967 +void free_output_buffer(void *buffer)
6969 + free_pages((unsigned long) buffer, 0);
6972 +int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out,
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);
6987 +unsigned short eth_protocol(struct sk_buff *skb)
6989 + return(eth_type_trans(skb, skb->dev));
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
6997 + * ---------------------------------------------------------------------------
6998 + * Local variables:
6999 + * c-file-style: "linux"
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
7008 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7009 + * Licensed under the GPL
7012 +#include <stddef.h>
7013 +#include <stdarg.h>
7014 +#include <unistd.h>
7017 +#include <stdlib.h>
7018 +#include <string.h>
7019 +#include <sys/socket.h>
7020 +#include <sys/wait.h>
7022 +#include "user_util.h"
7023 +#include "kern_util.h"
7024 +#include "net_user.h"
7025 +#include "helper.h"
7028 +int tap_open_common(void *dev, char *gate_addr)
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);
7041 +void tap_check_ips(char *gate_addr, char *eth_addr)
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");
7057 +void read_output(int fd, char *output, int len)
7059 + int remain, n, actual;
7062 + if(output == NULL){
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);
7074 + while(remain != 0){
7075 + n = (remain < len) ? remain : len;
7076 + actual = os_read_file(fd, output, n);
7078 + printk("read_output - read of data failed, "
7079 + "err = %d\n", -actual);
7087 +int net_read(int fd, void *buf, int len)
7091 + n = os_read_file(fd, buf, len);
7096 + return(-ENOTCONN);
7100 +int net_recvfrom(int fd, void *buf, int len)
7104 + while(((n = recvfrom(fd, buf, len, 0, NULL, NULL)) < 0) &&
7105 + (errno == EINTR)) ;
7108 + if(errno == EAGAIN) return(0);
7111 + else if(n == 0) return(-ENOTCONN);
7115 +int net_write(int fd, void *buf, int len)
7119 + n = os_write_file(fd, buf, len);
7124 + return(-ENOTCONN);
7128 +int net_send(int fd, void *buf, int len)
7132 + while(((n = send(fd, buf, len, 0)) < 0) && (errno == EINTR)) ;
7134 + if(errno == EAGAIN) return(0);
7137 + else if(n == 0) return(-ENOTCONN);
7141 +int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
7145 + while(((n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
7146 + sock_len)) < 0) && (errno == EINTR)) ;
7148 + if(errno == EAGAIN) return(0);
7151 + else if(n == 0) return(-ENOTCONN);
7155 +struct change_pre_exec_data {
7160 +static void change_pre_exec(void *arg)
7162 + struct change_pre_exec_data *data = arg;
7164 + os_close_file(data->close_me);
7165 + dup2(data->stdout, 1);
7168 +static int change_tramp(char **argv, char *output, int output_len)
7170 + int pid, fds[2], err;
7171 + struct change_pre_exec_data pe_data;
7173 + err = os_pipe(fds, 1, 0);
7175 + printk("change_tramp - pipe failed, err = %d\n", -err);
7178 + pe_data.close_me = fds[0];
7179 + pe_data.stdout = fds[1];
7180 + pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
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));
7189 +static void change(char *dev, char *what, unsigned char *addr,
7190 + unsigned char *netmask)
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 };
7198 + int output_len, pid;
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]);
7205 + output_len = page_size();
7206 + output = um_kmalloc(output_len);
7207 + if(output == NULL)
7208 + printk("change : failed to allocate output buffer\n");
7210 + pid = change_tramp(argv, output, output_len);
7211 + if(pid < 0) return;
7213 + if(output != NULL){
7214 + printk("%s", output);
7219 +void open_addr(unsigned char *addr, unsigned char *netmask, void *arg)
7221 + change(arg, "add", addr, netmask);
7224 +void close_addr(unsigned char *addr, unsigned char *netmask, void *arg)
7226 + change(arg, "del", addr, netmask);
7229 +char *split_if_spec(char *str, ...)
7234 + va_start(ap, str);
7235 + while((arg = va_arg(ap, char **)) != NULL){
7238 + end = strchr(str, ',');
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
7255 + * ---------------------------------------------------------------------------
7256 + * Local variables:
7257 + * c-file-style: "linux"
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
7266 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7267 + * Licensed under the GPL
7270 +#include <stdlib.h>
7272 +#include "chan_user.h"
7275 +static int null_chan;
7277 +void *null_init(char *str, int device, struct chan_opts *opts)
7279 + return(&null_chan);
7282 +int null_open(int input, int output, int primary, void *d, char **dev_out)
7285 + return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0));
7288 +int null_read(int fd, char *c_out, void *unused)
7293 +void null_free(void *data)
7297 +struct chan_ops null_ops = {
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,
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
7315 + * ---------------------------------------------------------------------------
7316 + * Local variables:
7317 + * c-file-style: "linux"
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
7326 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
7327 + * Licensed under the GPL.
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"
7344 +void pcap_init(struct net_device *dev, void *data)
7346 + struct uml_net_private *pri;
7347 + struct pcap_data *ppri;
7348 + struct pcap_init *init = data;
7350 + init_etherdev(dev, 0);
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,
7362 +static int pcap_read(int fd, struct sk_buff **skb,
7363 + struct uml_net_private *lp)
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));
7372 +static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
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,
7384 +int pcap_setup(char *str, char **mac_out, void *data)
7386 + struct pcap_init *init = data;
7387 + char *remain, *host_if = NULL, *options[2] = { NULL, NULL };
7390 + *init = ((struct pcap_init)
7391 + { .host_if = "eth0",
7394 + .filter = NULL });
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);
7404 + if(host_if != NULL)
7405 + init->host_if = host_if;
7407 + for(i = 0; i < sizeof(options)/sizeof(options[0]); i++){
7408 + if(options[i] == NULL)
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]);
7424 +static struct transport pcap_transport = {
7425 + .list = LIST_HEAD_INIT(pcap_transport.list),
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),
7434 +static int register_pcap(void)
7436 + register_transport(&pcap_transport);
7440 +__initcall(register_pcap);
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
7447 + * ---------------------------------------------------------------------------
7448 + * Local variables:
7449 + * c-file-style: "linux"
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
7458 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
7459 + * Licensed under the GPL.
7462 +#include <unistd.h>
7463 +#include <stdlib.h>
7464 +#include <string.h>
7467 +#include <asm/types.h>
7468 +#include "net_user.h"
7469 +#include "pcap_user.h"
7472 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
7474 +#define PCAP_FD(p) (*(int *)(p))
7476 +static void pcap_user_init(void *data, void *dev)
7478 + struct pcap_data *pri = data;
7480 + char errors[PCAP_ERRBUF_SIZE];
7482 + p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors);
7484 + printk("pcap_user_init : pcap_open_live failed - '%s'\n",
7493 +static int pcap_open(void *data)
7495 + struct pcap_data *pri = data;
7499 + if(pri->pcap == NULL)
7502 + if(pri->filter != NULL){
7503 + err = dev_netmask(pri->dev, &netmask);
7505 + printk("pcap_open : dev_netmask failed\n");
7509 + pri->compiled = um_kmalloc(sizeof(struct bpf_program));
7510 + if(pri->compiled == NULL){
7511 + printk("pcap_open : kmalloc failed\n");
7515 + err = pcap_compile(pri->pcap,
7516 + (struct bpf_program *) pri->compiled,
7517 + pri->filter, pri->optimize, netmask);
7519 + printk("pcap_open : pcap_compile failed - '%s'\n",
7520 + pcap_geterr(pri->pcap));
7524 + err = pcap_setfilter(pri->pcap, pri->compiled);
7526 + printk("pcap_open : pcap_setfilter failed - '%s'\n",
7527 + pcap_geterr(pri->pcap));
7532 + return(PCAP_FD(pri->pcap));
7535 +static void pcap_remove(void *data)
7537 + struct pcap_data *pri = data;
7539 + if(pri->compiled != NULL)
7540 + pcap_freecode(pri->compiled);
7542 + pcap_close(pri->pcap);
7545 +struct pcap_handler_data {
7550 +static void handler(u_char *data, const struct pcap_pkthdr *header,
7551 + const u_char *packet)
7555 + struct pcap_handler_data *hdata = (struct pcap_handler_data *) data;
7557 + len = hdata->len < header->caplen ? hdata->len : header->caplen;
7558 + memcpy(hdata->buffer, packet, len);
7562 +int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
7564 + struct pcap_handler_data hdata = ((struct pcap_handler_data)
7565 + { .buffer = buffer,
7569 + n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
7571 + printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap));
7576 + return(hdata.len);
7579 +struct net_user_info pcap_user_info = {
7580 + .init = pcap_user_init,
7581 + .open = pcap_open,
7583 + .remove = pcap_remove,
7585 + .add_address = NULL,
7586 + .delete_address = NULL,
7587 + .max_packet = MAX_PACKET - ETH_HEADER_OTHER
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
7595 + * ---------------------------------------------------------------------------
7596 + * Local variables:
7597 + * c-file-style: "linux"
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
7606 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7607 + * Licensed under the GPL
7610 +#include "net_user.h"
7622 +extern struct net_user_info pcap_user_info;
7624 +extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
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
7631 + * ---------------------------------------------------------------------------
7632 + * Local variables:
7633 + * c-file-style: "linux"
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
7642 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
7643 + * Licensed under the GPL
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);
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
7666 + * ---------------------------------------------------------------------------
7667 + * Local variables:
7668 + * c-file-style: "linux"
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
7677 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7678 + * Licensed under the GPL
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"
7691 +#include "irq_user.h"
7692 +#include "irq_kern.h"
7698 + struct list_head list;
7699 + int has_connection;
7700 + struct semaphore sem;
7704 + struct list_head pending;
7705 + struct list_head connections;
7709 + struct port_list *port;
7714 +struct connection {
7715 + struct list_head list;
7720 + struct port_list *port;
7723 +static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
7725 + struct connection *conn = data;
7728 + fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
7733 + printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
7735 + os_close_file(conn->fd);
7738 + list_del(&conn->list);
7741 + list_add(&conn->list, &conn->port->connections);
7743 + up(&conn->port->sem);
7746 +static int port_accept(struct port_list *port)
7748 + struct connection *conn;
7749 + int fd, socket[2], pid, ret = 0;
7751 + fd = port_connection(port->fd, socket, &pid);
7754 + printk(KERN_ERR "port_accept : port_connection "
7755 + "returned %d\n", -fd);
7759 + conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
7761 + printk(KERN_ERR "port_accept : failed to allocate "
7765 + *conn = ((struct connection)
7766 + { .list = LIST_HEAD_INIT(conn->list),
7768 + .socket = { socket[0], socket[1] },
7769 + .telnetd_pid = pid,
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 "
7780 + list_add(&conn->list, &port->pending);
7786 + os_close_file(fd);
7788 + os_kill_process(pid, 1);
7793 +DECLARE_MUTEX(ports_sem);
7794 +struct list_head ports = LIST_HEAD_INIT(ports);
7796 +void port_task_proc(void *unused)
7798 + struct port_list *port;
7799 + struct list_head *ele;
7800 + unsigned long flags;
7802 + save_flags(flags);
7803 + list_for_each(ele, &ports){
7804 + port = list_entry(ele, struct port_list, list);
7805 + if(!port->has_connection)
7807 + reactivate_fd(port->fd, ACCEPT_IRQ);
7808 + while(port_accept(port)) ;
7809 + port->has_connection = 0;
7811 + restore_flags(flags);
7814 +struct tq_struct port_task = {
7815 + .routine = port_task_proc,
7819 +static void port_interrupt(int irq, void *data, struct pt_regs *regs)
7821 + struct port_list *port = data;
7823 + port->has_connection = 1;
7824 + schedule_task(&port_task);
7827 +void *port_data(int port_num)
7829 + struct list_head *ele;
7830 + struct port_list *port;
7831 + struct port_dev *dev = NULL;
7835 + list_for_each(ele, &ports){
7836 + port = list_entry(ele, struct port_list, list);
7837 + if(port->port == port_num) goto found;
7839 + port = kmalloc(sizeof(struct port_list), GFP_KERNEL);
7841 + printk(KERN_ERR "Allocation of port list failed\n");
7845 + fd = port_listen_fd(port_num);
7847 + printk(KERN_ERR "binding to port %d failed, errno = %d\n",
7851 + if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
7852 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "port",
7854 + printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
7858 + *port = ((struct port_list)
7859 + { .list = LIST_HEAD_INIT(port->list),
7860 + .has_connection = 0,
7861 + .sem = __SEMAPHORE_INITIALIZER(port->sem,
7863 + .lock = SPIN_LOCK_UNLOCKED,
7866 + .pending = LIST_HEAD_INIT(port->pending),
7867 + .connections = LIST_HEAD_INIT(port->connections) });
7868 + list_add(&port->list, &ports);
7871 + dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL);
7873 + printk(KERN_ERR "Allocation of port device entry failed\n");
7877 + *dev = ((struct port_dev) { .port = port,
7879 + .telnetd_pid = -1 });
7885 + os_close_file(fd);
7891 +int port_wait(void *data)
7893 + struct port_dev *dev = data;
7894 + struct connection *conn;
7895 + struct port_list *port = dev->port;
7899 + if(down_interruptible(&port->sem))
7900 + return(-ERESTARTSYS);
7902 + spin_lock(&port->lock);
7904 + conn = list_entry(port->connections.next, struct connection,
7906 + list_del(&conn->list);
7907 + spin_unlock(&port->lock);
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]);
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.
7920 + free_irq(TELNETD_IRQ, conn);
7922 + if(conn->fd >= 0) break;
7923 + os_close_file(conn->fd);
7928 + dev->helper_pid = conn->helper_pid;
7929 + dev->telnetd_pid = conn->telnetd_pid;
7935 +void port_remove_dev(void *d)
7937 + struct port_dev *dev = d;
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;
7947 +void port_kern_free(void *d)
7949 + struct port_dev *dev = d;
7951 + port_remove_dev(dev);
7955 +static void free_port(void)
7957 + struct list_head *ele;
7958 + struct port_list *port;
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);
7967 +__uml_exitcall(free_port);
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
7974 + * ---------------------------------------------------------------------------
7975 + * Local variables:
7976 + * c-file-style: "linux"
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
7985 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
7986 + * Licensed under the GPL
7990 +#include <stddef.h>
7991 +#include <stdlib.h>
7992 +#include <string.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"
8002 +#include "chan_user.h"
8004 +#include "helper.h"
8009 + struct termios tt;
8010 + void *kernel_data;
8011 + char dev[sizeof("32768\0")];
8014 +void *port_init(char *str, int device, struct chan_opts *opts)
8016 + struct port_chan *data;
8022 + printk("port_init : channel type 'port' must specify a "
8027 + port = strtoul(str, &end, 0);
8028 + if((*end != '\0') || (end == str)){
8029 + printk("port_init : couldn't parse port '%s'\n", str);
8033 + kern_data = port_data(port);
8034 + if(kern_data == NULL)
8037 + data = um_kmalloc(sizeof(*data));
8041 + *data = ((struct port_chan) { .raw = opts->raw,
8042 + .kernel_data = kern_data });
8043 + sprintf(data->dev, "%d", port);
8047 + port_kern_free(kern_data);
8051 +void port_free(void *d)
8053 + struct port_chan *data = d;
8055 + port_kern_free(data->kernel_data);
8059 +int port_open(int input, int output, int primary, void *d, char **dev_out)
8061 + struct port_chan *data = d;
8064 + fd = port_wait(data->kernel_data);
8065 + if((fd >= 0) && data->raw){
8066 + CATCH_EINTR(err = tcgetattr(fd, &data->tt));
8074 + *dev_out = data->dev;
8078 +void port_close(int fd, void *d)
8080 + struct port_chan *data = d;
8082 + port_remove_dev(data->kernel_data);
8083 + os_close_file(fd);
8086 +int port_console_write(int fd, const char *buf, int n, void *d)
8088 + struct port_chan *data = d;
8090 + return(generic_console_write(fd, buf, n, &data->tt));
8093 +struct chan_ops port_ops = {
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,
8106 +int port_listen_fd(int port)
8108 + struct sockaddr_in addr;
8111 + fd = socket(PF_INET, SOCK_STREAM, 0);
8116 + if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0){
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){
8129 + if(listen(fd, 1) < 0){
8134 + err = os_set_fd_block(fd, 0);
8140 + os_close_file(fd);
8144 +struct port_pre_exec_data {
8149 +void port_pre_exec(void *arg)
8151 + struct port_pre_exec_data *data = arg;
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);
8162 +int port_connection(int fd, int *socket, int *pid_out)
8165 + char *argv[] = { "/usr/sbin/in.telnetd", "-L",
8166 + "/usr/lib/uml/port-helper", NULL };
8167 + struct port_pre_exec_data data;
8169 + new = os_accept_connection(fd);
8173 + err = os_pipe(socket, 0, 0);
8177 + data = ((struct port_pre_exec_data)
8179 + .pipe_fd = socket[1] });
8181 + err = run_helper(port_pre_exec, &data, argv, NULL);
8183 + goto 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]);
8194 + os_close_file(new);
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
8203 + * ---------------------------------------------------------------------------
8204 + * Local variables:
8205 + * c-file-style: "linux"
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
8214 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
8215 + * Licensed under the GPL
8219 +#include <unistd.h>
8220 +#include <string.h>
8222 +#include <termios.h>
8223 +#include "chan_user.h"
8225 +#include "user_util.h"
8226 +#include "kern_util.h"
8230 + void (*announce)(char *dev_name, int dev);
8233 + struct termios tt;
8234 + char dev_name[sizeof("/dev/pts/0123456\0")];
8237 +void *pty_chan_init(char *str, int device, struct chan_opts *opts)
8239 + struct pty_chan *data;
8241 + data = um_kmalloc(sizeof(*data));
8242 + if(data == NULL) return(NULL);
8243 + *data = ((struct pty_chan) { .announce = opts->announce,
8245 + .raw = opts->raw });
8249 +int pts_open(int input, int output, int primary, void *d, char **dev_out)
8251 + struct pty_chan *data = d;
8257 + printk("open_pts : Failed to open pts\n");
8261 + CATCH_EINTR(err = tcgetattr(fd, &data->tt));
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);
8277 +int getmaster(char *line)
8279 + char *pty, *bank, *cp;
8282 + pty = &line[strlen("/dev/ptyp")];
8283 + for (bank = "pqrs"; *bank; bank++) {
8284 + line[strlen("/dev/pty")] = *bank;
8286 + if (os_stat_file(line, NULL) < 0)
8288 + for (cp = "0123456789abcdef"; *cp; cp++) {
8290 + master = os_open_file(line, of_rdwr(OPENFLAGS()), 0);
8291 + if (master >= 0) {
8292 + char *tp = &line[strlen("/dev/")];
8294 + /* verify slave side is usable */
8296 + err = os_access(line, OS_ACC_RW_OK);
8298 + if(err == 0) return(master);
8299 + (void) os_close_file(master);
8306 +int pty_open(int input, int output, int primary, void *d, char **dev_out)
8308 + struct pty_chan *data = d;
8310 + char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
8312 + fd = getmaster(dev);
8322 + if(data->announce) (*data->announce)(dev, data->dev);
8324 + sprintf(data->dev_name, "%s", dev);
8325 + *dev_out = data->dev_name;
8329 +int pty_console_write(int fd, const char *buf, int n, void *d)
8331 + struct pty_chan *data = d;
8333 + return(generic_console_write(fd, buf, n, &data->tt));
8336 +struct chan_ops pty_ops = {
8338 + .init = pty_chan_init,
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,
8349 +struct chan_ops pts_ops = {
8351 + .init = pty_chan_init,
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,
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
8367 + * ---------------------------------------------------------------------------
8368 + * Local variables:
8369 + * c-file-style: "linux"
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
8377 +#ifndef __UM_SLIP_H
8378 +#define __UM_SLIP_H
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)
8387 + char name[sizeof("slnnnnn\0")];
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 */
8398 +extern struct net_user_info slip_user_info;
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);
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
8411 + * ---------------------------------------------------------------------------
8412 + * Local variables:
8413 + * c-file-style: "linux"
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
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"
8436 +void slip_init(struct net_device *dev, void *data)
8438 + struct uml_net_private *private;
8439 + struct slip_data *spri;
8440 + struct slip_init *init = data;
8442 + private = dev->priv;
8443 + spri = (struct slip_data *) private->user;
8444 + *spri = ((struct slip_data)
8445 + { .name = { '\0' },
8447 + .gate_addr = init->gate_addr,
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);
8464 +static unsigned short slip_protocol(struct sk_buff *skbuff)
8466 + return(htons(ETH_P_IP));
8469 +static int slip_read(int fd, struct sk_buff **skb,
8470 + struct uml_net_private *lp)
8472 + return(slip_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu,
8473 + (struct slip_data *) &lp->user));
8476 +static int slip_write(int fd, struct sk_buff **skb,
8477 + struct uml_net_private *lp)
8479 + return(slip_user_write(fd, (*skb)->data, (*skb)->len,
8480 + (struct slip_data *) &lp->user));
8483 +struct net_kern_info slip_kern_info = {
8484 + .init = slip_init,
8485 + .protocol = slip_protocol,
8486 + .read = slip_read,
8487 + .write = slip_write,
8490 +static int slip_setup(char *str, char **mac_out, void *data)
8492 + struct slip_init *init = data;
8494 + *init = ((struct slip_init)
8495 + { .gate_addr = NULL });
8497 + if(str[0] != '\0')
8498 + init->gate_addr = str;
8502 +static struct transport slip_transport = {
8503 + .list = LIST_HEAD_INIT(slip_transport.list),
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),
8512 +static int register_slip(void)
8514 + register_transport(&slip_transport);
8518 +__initcall(register_slip);
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
8525 + * ---------------------------------------------------------------------------
8526 + * Local variables:
8527 + * c-file-style: "linux"
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
8536 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
8537 + * Licensed under the GPL
8540 +#ifndef __UM_SLIP_PROTO_H__
8541 +#define __UM_SLIP_PROTO_H__
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' */
8549 +static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc)
8562 + case SLIP_ESC_ESC:
8568 + case SLIP_ESC_END:
8575 + buf[(*pos)++] = c;
8579 +static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
8581 + unsigned char *ptr = d;
8585 + * Send an initial END character to flush out any
8586 + * data that may have accumulated in the receiver
8587 + * due to line noise.
8590 + *ptr++ = SLIP_END;
8593 + * For each byte in the packet, send the appropriate
8594 + * character sequence, according to the SLIP protocol.
8597 + while (len-- > 0) {
8598 + switch(c = *s++) {
8600 + *ptr++ = SLIP_ESC;
8601 + *ptr++ = SLIP_ESC_END;
8604 + *ptr++ = SLIP_ESC;
8605 + *ptr++ = SLIP_ESC_ESC;
8612 + *ptr++ = SLIP_END;
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
8623 + * ---------------------------------------------------------------------------
8624 + * Local variables:
8625 + * c-file-style: "linux"
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
8634 +#include <stdlib.h>
8635 +#include <unistd.h>
8636 +#include <stddef.h>
8638 +#include <string.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"
8646 +#include "net_user.h"
8648 +#include "slip_proto.h"
8649 +#include "helper.h"
8652 +void slip_user_init(void *data, void *dev)
8654 + struct slip_data *pri = data;
8659 +static int set_up_tty(int fd)
8662 + struct termios tios;
8664 + if (tcgetattr(fd, &tios) < 0) {
8665 + printk("could not get initial terminal attributes\n");
8669 + tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
8670 + tios.c_iflag = IGNBRK | IGNPAR;
8673 + for (i = 0; i < NCCS; i++)
8675 + tios.c_cc[VMIN] = 1;
8676 + tios.c_cc[VTIME] = 0;
8678 + cfsetospeed(&tios, B38400);
8679 + cfsetispeed(&tios, B38400);
8681 + if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
8682 + printk("failed to set terminal attributes\n");
8688 +struct slip_pre_exec_data {
8694 +static void slip_pre_exec(void *arg)
8696 + struct slip_pre_exec_data *data = arg;
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);
8703 +static int slip_tramp(char **argv, int fd)
8705 + struct slip_pre_exec_data pe_data;
8707 + int status, pid, fds[2], err, output_len;
8709 + err = os_pipe(fds, 1, 0);
8711 + printk("slip_tramp : pipe failed, err = %d\n", -err);
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);
8721 + if(pid < 0) err = pid;
8723 + output_len = page_size();
8724 + output = um_kmalloc(output_len);
8725 + if(output == NULL)
8726 + printk("slip_tramp : failed to allocate output "
8729 + os_close_file(fds[1]);
8730 + read_output(fds[0], output, output_len);
8731 + if(output != NULL){
8732 + printk("%s", output);
8735 + CATCH_EINTR(err = waitpid(pid, &status, 0));
8738 + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
8739 + printk("'%s' didn't exit with status 0\n", argv[0]);
8746 +static int slip_open(void *data)
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,
8753 + int sfd, mfd, err;
8757 + printk("umn : Failed to open pty, err = %d\n", -mfd);
8760 + sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
8762 + printk("Couldn't open tty for slip line, err = %d\n", -sfd);
8765 + if(set_up_tty(sfd)) return(-1);
8769 + if(pri->gate_addr != NULL){
8770 + sprintf(version_buf, "%d", UML_NET_VERSION);
8771 + strcpy(gate_buf, pri->gate_addr);
8773 + err = slip_tramp(argv, sfd);
8776 + printk("slip_tramp failed - err = %d\n", -err);
8779 + err = os_get_ifname(pri->slave, pri->name);
8781 + printk("get_ifname failed, err = %d\n", -err);
8784 + iter_addresses(pri->dev, open_addr, pri->name);
8787 + err = os_set_slip(sfd);
8789 + printk("Failed to set slip discipline encapsulation - "
8790 + "err = %d\n", -err);
8797 +static void slip_close(int fd, void *data)
8799 + struct slip_data *pri = data;
8800 + char version_buf[sizeof("nnnnn\0")];
8801 + char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
8805 + if(pri->gate_addr != NULL)
8806 + iter_addresses(pri->dev, close_addr, pri->name);
8808 + sprintf(version_buf, "%d", UML_NET_VERSION);
8810 + err = slip_tramp(argv, -1);
8813 + printk("slip_tramp failed - errno = %d\n", -err);
8814 + os_close_file(fd);
8815 + os_close_file(pri->slave);
8819 +int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
8821 + int i, n, size, start;
8825 + while(i < pri->more) {
8826 + size = slip_unesc(pri->ibuf[i++],
8827 + pri->ibuf, &pri->pos, &pri->esc);
8829 + memcpy(buf, pri->ibuf, size);
8830 + memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
8831 + pri->more=pri->more-i;
8838 + n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
8839 + if(n <= 0) return(n);
8842 + for(i = 0; i < n; i++){
8843 + size = slip_unesc(pri->ibuf[start + i],
8844 + pri->ibuf, &pri->pos, &pri->esc);
8846 + memcpy(buf, pri->ibuf, size);
8847 + memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
8848 + pri->more=n-(i+1);
8855 +int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
8859 + actual = slip_esc(buf, pri->obuf, len);
8860 + n = net_write(fd, pri->obuf, actual);
8861 + if(n < 0) return(n);
8865 +static int slip_set_mtu(int mtu, void *data)
8870 +static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
8873 + struct slip_data *pri = data;
8875 + if(pri->slave < 0) return;
8876 + open_addr(addr, netmask, pri->name);
8879 +static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
8882 + struct slip_data *pri = data;
8884 + if(pri->slave < 0) return;
8885 + close_addr(addr, netmask, pri->name);
8888 +struct net_user_info slip_user_info = {
8889 + .init = slip_user_init,
8890 + .open = slip_open,
8891 + .close = slip_close,
8893 + .set_mtu = slip_set_mtu,
8894 + .add_address = slip_add_addr,
8895 + .delete_address = slip_del_addr,
8896 + .max_packet = BUF_SIZE
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
8904 + * ---------------------------------------------------------------------------
8905 + * Local variables:
8906 + * c-file-style: "linux"
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
8914 +#ifndef __UM_SLIRP_H
8915 +#define __UM_SLIRP_H
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)
8922 +#define SLIRP_MAX_ARGS 100
8924 + * XXX this next definition is here because I don't understand why this
8925 + * initializer doesn't work in slirp_kern.c:
8927 + * argv : { init->argv[ 0 ... SLIRP_MAX_ARGS-1 ] },
8929 + * or why I can't typecast like this:
8931 + * argv : (char* [SLIRP_MAX_ARGS])(init->argv),
8933 +struct arg_list_dummy_wrapper { char *argv[SLIRP_MAX_ARGS]; };
8935 +struct slirp_data {
8937 + struct arg_list_dummy_wrapper argw;
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 */
8947 +extern struct net_user_info slirp_user_info;
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);
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
8960 + * ---------------------------------------------------------------------------
8961 + * Local variables:
8962 + * c-file-style: "linux"
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
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"
8980 +struct slirp_init {
8981 + struct arg_list_dummy_wrapper argw; /* XXX should be simpler... */
8984 +void slirp_init(struct net_device *dev, void *data)
8986 + struct uml_net_private *private;
8987 + struct slirp_data *spri;
8988 + struct slirp_init *init = data;
8991 + private = dev->priv;
8992 + spri = (struct slirp_data *) private->user;
8993 + *spri = ((struct slirp_data)
8994 + { .argw = init->argw,
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]);
9016 +static unsigned short slirp_protocol(struct sk_buff *skbuff)
9018 + return(htons(ETH_P_IP));
9021 +static int slirp_read(int fd, struct sk_buff **skb,
9022 + struct uml_net_private *lp)
9024 + return(slirp_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu,
9025 + (struct slirp_data *) &lp->user));
9028 +static int slirp_write(int fd, struct sk_buff **skb,
9029 + struct uml_net_private *lp)
9031 + return(slirp_user_write(fd, (*skb)->data, (*skb)->len,
9032 + (struct slirp_data *) &lp->user));
9035 +struct net_kern_info slirp_kern_info = {
9036 + .init = slirp_init,
9037 + .protocol = slirp_protocol,
9038 + .read = slirp_read,
9039 + .write = slirp_write,
9042 +static int slirp_setup(char *str, char **mac_out, void *data)
9044 + struct slirp_init *init = data;
9047 + *init = ((struct slirp_init)
9048 + { argw : { { "slirp", NULL } } });
9050 + str = split_if_spec(str, mac_out, NULL);
9052 + if(str == NULL) { /* no command line given after MAC addr */
9057 + if(i>=SLIRP_MAX_ARGS-1) {
9058 + printk("slirp_setup: truncating slirp arguments\n");
9061 + init->argw.argv[i++] = str;
9062 + while(*str && *str!=',') {
9063 + if(*str=='_') *str=' ';
9070 + init->argw.argv[i]=NULL;
9074 +static struct transport slirp_transport = {
9075 + .list = LIST_HEAD_INIT(slirp_transport.list),
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),
9084 +static int register_slirp(void)
9086 + register_transport(&slirp_transport);
9090 +__initcall(register_slirp);
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
9097 + * ---------------------------------------------------------------------------
9098 + * Local variables:
9099 + * c-file-style: "linux"
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
9108 +#include <stdlib.h>
9109 +#include <unistd.h>
9110 +#include <stddef.h>
9112 +#include <string.h>
9114 +#include <sys/wait.h>
9115 +#include <sys/signal.h>
9116 +#include "user_util.h"
9117 +#include "kern_util.h"
9119 +#include "net_user.h"
9121 +#include "slip_proto.h"
9122 +#include "helper.h"
9125 +void slirp_user_init(void *data, void *dev)
9127 + struct slirp_data *pri = data;
9132 +struct slirp_pre_exec_data {
9137 +static void slirp_pre_exec(void *arg)
9139 + struct slirp_pre_exec_data *data = arg;
9141 + if(data->stdin != -1) dup2(data->stdin, 0);
9142 + if(data->stdout != -1) dup2(data->stdout, 1);
9145 +static int slirp_tramp(char **argv, int fd)
9147 + struct slirp_pre_exec_data pe_data;
9150 + pe_data.stdin = fd;
9151 + pe_data.stdout = fd;
9152 + pid = run_helper(slirp_pre_exec, &pe_data, argv, NULL);
9157 +/* XXX This is just a trivial wrapper around os_pipe */
9158 +static int slirp_datachan(int *mfd, int *sfd)
9162 + err = os_pipe(fds, 1, 1);
9164 + printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
9173 +static int slirp_open(void *data)
9175 + struct slirp_data *pri = data;
9176 + int sfd, mfd, pid, err;
9178 + err = slirp_datachan(&mfd, &sfd);
9182 + pid = slirp_tramp(pri->argw.argv, sfd);
9185 + printk("slirp_tramp failed - errno = %d\n", -pid);
9186 + os_close_file(sfd);
9187 + os_close_file(mfd);
9200 +static void slirp_close(int fd, void *data)
9202 + struct slirp_data *pri = data;
9205 + os_close_file(fd);
9206 + os_close_file(pri->slave);
9211 + printk("slirp_close: no child process to shut down\n");
9216 + if(kill(pri->pid, SIGHUP)<0) {
9217 + printk("slirp_close: sending hangup to %d failed (%d)\n",
9222 + CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG));
9224 + printk("slirp_close: waitpid returned %d\n", errno);
9229 + printk("slirp_close: process %d has not exited\n");
9236 +int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
9238 + int i, n, size, start;
9242 + while(i < pri->more) {
9243 + size = slip_unesc(pri->ibuf[i++],
9244 + pri->ibuf,&pri->pos,&pri->esc);
9246 + memcpy(buf, pri->ibuf, size);
9247 + memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
9248 + pri->more=pri->more-i;
9255 + n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
9256 + if(n <= 0) return(n);
9259 + for(i = 0; i < n; i++){
9260 + size = slip_unesc(pri->ibuf[start + i],
9261 + pri->ibuf,&pri->pos,&pri->esc);
9263 + memcpy(buf, pri->ibuf, size);
9264 + memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
9265 + pri->more=n-(i+1);
9272 +int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
9276 + actual = slip_esc(buf, pri->obuf, len);
9277 + n = net_write(fd, pri->obuf, actual);
9278 + if(n < 0) return(n);
9282 +static int slirp_set_mtu(int mtu, void *data)
9287 +struct net_user_info slirp_user_info = {
9288 + .init = slirp_user_init,
9289 + .open = slirp_open,
9290 + .close = slirp_close,
9292 + .set_mtu = slirp_set_mtu,
9293 + .add_address = NULL,
9294 + .delete_address = NULL,
9295 + .max_packet = BUF_SIZE
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
9303 + * ---------------------------------------------------------------------------
9304 + * Local variables:
9305 + * c-file-style: "linux"
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
9314 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
9315 + * Licensed under the GPL
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"
9330 +#include "chan_kern.h"
9331 +#include "user_util.h"
9332 +#include "kern_util.h"
9335 +#include "irq_user.h"
9336 +#include "mconsole_kern.h"
9337 +#include "2_5compat.h"
9339 +static int ssl_version = 1;
9341 +/* Referenced only by tty_driver below - presumably it's locked correctly
9342 + * by the tty driver.
9344 +static int ssl_refcount = 0;
9346 +static struct tty_driver ssl_driver;
9348 +#define NR_PORTS 64
9350 +void ssl_announce(char *dev_name, int dev)
9352 + printk(KERN_INFO "Serial line %d assigned device '%s'\n", dev,
9356 +static struct chan_opts opts = {
9357 + .announce = ssl_announce,
9358 + .xterm_title = "Serial Line #%d",
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);
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,
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",
9383 + .config = ssl_config,
9384 + .get_config = ssl_get_config,
9385 + .remove = ssl_remove,
9389 +/* The array is initialized by line_init, which is an initcall. The
9390 + * individual elements are protected by individual semaphores.
9392 +static struct line serial_lines[NR_PORTS] =
9393 + { [0 ... NR_PORTS - 1] = LINE_INIT(CONFIG_SSL_CHAN, &driver) };
9395 +static struct lines lines = LINES_INIT(NR_PORTS);
9397 +static int ssl_config(char *str)
9399 + return(line_config(serial_lines,
9400 + sizeof(serial_lines)/sizeof(serial_lines[0]), str));
9403 +static int ssl_get_config(char *dev, char *str, int size, char **error_out)
9405 + return(line_get_config(dev, serial_lines,
9406 + sizeof(serial_lines)/sizeof(serial_lines[0]),
9407 + str, size, error_out));
9410 +static int ssl_remove(char *str)
9412 + return(line_remove(serial_lines,
9413 + sizeof(serial_lines)/sizeof(serial_lines[0]), str));
9416 +int ssl_open(struct tty_struct *tty, struct file *filp)
9418 + return(line_open(serial_lines, tty, &opts));
9421 +static void ssl_close(struct tty_struct *tty, struct file * filp)
9423 + line_close(serial_lines, tty);
9426 +static int ssl_write(struct tty_struct * tty, int from_user,
9427 + const unsigned char *buf, int count)
9429 + return(line_write(serial_lines, tty, from_user, buf, count));
9432 +static void ssl_put_char(struct tty_struct *tty, unsigned char ch)
9434 + line_write(serial_lines, tty, 0, &ch, sizeof(ch));
9437 +static void ssl_flush_chars(struct tty_struct *tty)
9442 +static int ssl_chars_in_buffer(struct tty_struct *tty)
9447 +static void ssl_flush_buffer(struct tty_struct *tty)
9452 +static int ssl_ioctl(struct tty_struct *tty, struct file * file,
9453 + unsigned int cmd, unsigned long arg)
9469 + ret = -ENOIOCTLCMD;
9473 + "Unimplemented ioctl in ssl_ioctl : 0x%x\n", cmd);
9474 + ret = -ENOIOCTLCMD;
9480 +static void ssl_throttle(struct tty_struct * tty)
9482 + printk(KERN_ERR "Someone should implement ssl_throttle\n");
9485 +static void ssl_unthrottle(struct tty_struct * tty)
9487 + printk(KERN_ERR "Someone should implement ssl_unthrottle\n");
9490 +static void ssl_set_termios(struct tty_struct *tty,
9491 + struct termios *old_termios)
9495 +static void ssl_stop(struct tty_struct *tty)
9497 + printk(KERN_ERR "Someone should implement ssl_stop\n");
9500 +static void ssl_start(struct tty_struct *tty)
9502 + printk(KERN_ERR "Someone should implement ssl_start\n");
9505 +void ssl_hangup(struct tty_struct *tty)
9509 +static struct tty_driver ssl_driver = {
9510 + .refcount = &ssl_refcount,
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,
9523 + .start = ssl_start,
9524 + .hangup = ssl_hangup
9527 +/* Changed by ssl_init and referenced by ssl_exit, which are both serialized
9528 + * by being an initcall and exitcall, respectively.
9530 +static int ssl_init_done = 0;
9532 +static void ssl_console_write(struct console *c, const char *string,
9535 + struct line *line = &serial_lines[c->index];
9538 + console_write_chan(&line->chan_list, string, len);
9543 +static kdev_t ssl_console_device(struct console *c)
9545 + return mk_kdev(TTY_MAJOR, c->index);
9548 +static int ssl_console_setup(struct console *co, char *options)
9553 +static struct console ssl_cons = {
9555 + write: ssl_console_write,
9556 + device: ssl_console_device,
9557 + setup: ssl_console_setup,
9558 + flags: CON_PRINTBUFFER,
9566 + printk(KERN_INFO "Initializing software serial port version %d\n",
9569 + line_register_devfs(&lines, &driver, &ssl_driver, serial_lines,
9570 + sizeof(serial_lines)/sizeof(serial_lines[0]));
9572 + lines_init(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]));
9574 + new_title = add_xterm_umid(opts.xterm_title);
9575 + if(new_title != NULL) opts.xterm_title = new_title;
9577 + register_console(&ssl_cons);
9578 + ssl_init_done = 1;
9582 +__initcall(ssl_init);
9584 +static int ssl_chan_setup(char *str)
9586 + return(line_setup(serial_lines,
9587 + sizeof(serial_lines)/sizeof(serial_lines[0]),
9591 +__setup("ssl", ssl_chan_setup);
9592 +__channel_help(ssl_chan_setup, "ssl");
9594 +static void ssl_exit(void)
9596 + if(!ssl_init_done) return;
9597 + close_lines(serial_lines,
9598 + sizeof(serial_lines)/sizeof(serial_lines[0]));
9601 +__uml_exitcall(ssl_exit);
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
9608 + * ---------------------------------------------------------------------------
9609 + * Local variables:
9610 + * c-file-style: "linux"
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
9619 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9620 + * Licensed under the GPL
9626 +extern int ssl_read(int fd, int line);
9627 +extern void ssl_receive_char(int line, char ch);
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
9636 + * ---------------------------------------------------------------------------
9637 + * Local variables:
9638 + * c-file-style: "linux"
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
9647 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
9648 + * Licensed under the GPL
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"
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"
9677 +#include "2_5compat.h"
9679 +#define MAX_TTYS (8)
9681 +/* Referenced only by tty_driver below - presumably it's locked correctly
9682 + * by the tty driver.
9685 +static struct tty_driver console_driver;
9687 +static int console_refcount = 0;
9689 +static struct chan_ops init_console_ops = {
9690 + .type = "you shouldn't see this",
9696 + .console_write = generic_write,
9697 + .window_size = NULL,
9702 +static struct chan init_console_chan = {
9709 + .pri = INIT_STATIC,
9710 + .ops = &init_console_ops,
9714 +void stdio_announce(char *dev_name, int dev)
9716 + printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
9720 +static struct chan_opts opts = {
9721 + .announce = stdio_announce,
9722 + .xterm_title = "Virtual Console #%d",
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);
9732 +static struct line_driver driver = {
9733 + .name = "UML console",
9734 + .devfs_name = "vc/%d",
9735 + .major = TTY_MAJOR,
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",
9747 + .config = con_config,
9748 + .get_config = con_get_config,
9749 + .remove = con_remove,
9753 +static struct lines console_lines = LINES_INIT(MAX_TTYS);
9755 +/* The array is initialized by line_init, which is an initcall. The
9756 + * individual elements are protected by individual semaphores.
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) };
9762 +static int con_config(char *str)
9764 + return(line_config(vts, sizeof(vts)/sizeof(vts[0]), str));
9767 +static int con_get_config(char *dev, char *str, int size, char **error_out)
9769 + return(line_get_config(dev, vts, sizeof(vts)/sizeof(vts[0]), str,
9770 + size, error_out));
9773 +static int con_remove(char *str)
9775 + return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str));
9778 +static int open_console(struct tty_struct *tty)
9780 + return(line_open(vts, tty, &opts));
9783 +static int con_open(struct tty_struct *tty, struct file *filp)
9785 + return(open_console(tty));
9788 +static void con_close(struct tty_struct *tty, struct file *filp)
9790 + line_close(vts, tty);
9793 +static int con_write(struct tty_struct *tty, int from_user,
9794 + const unsigned char *buf, int count)
9796 + return(line_write(vts, tty, from_user, buf, count));
9799 +static void set_termios(struct tty_struct *tty, struct termios * old)
9803 +static int chars_in_buffer(struct tty_struct *tty)
9808 +static int con_init_done = 0;
9810 +int stdio_init(void)
9814 + printk(KERN_INFO "Initializing stdio console driver\n");
9816 + line_register_devfs(&console_lines, &driver, &console_driver, vts,
9817 + sizeof(vts)/sizeof(vts[0]));
9819 + lines_init(vts, sizeof(vts)/sizeof(vts[0]));
9821 + new_title = add_xterm_umid(opts.xterm_title);
9822 + if(new_title != NULL) opts.xterm_title = new_title;
9824 + open_console(NULL);
9825 + con_init_done = 1;
9829 +__initcall(stdio_init);
9831 +static void console_write(struct console *console, const char *string,
9834 + struct line *line = &vts[console->index];
9838 + console_write_chan(&line->chan_list, string, len);
9843 +static struct tty_driver console_driver = {
9844 + .refcount = &console_refcount,
9846 + .close = con_close,
9847 + .write = con_write,
9848 + .chars_in_buffer = chars_in_buffer,
9849 + .set_termios = set_termios
9852 +static kdev_t console_device(struct console *c)
9854 + return mk_kdev(TTY_MAJOR, c->index);
9857 +static int console_setup(struct console *co, char *options)
9862 +static struct console stdiocons = {
9864 + write: console_write,
9865 + device: console_device,
9866 + setup: console_setup,
9867 + flags: CON_PRINTBUFFER,
9871 +void stdio_console_init(void)
9873 + INIT_LIST_HEAD(&vts[0].chan_list);
9874 + list_add(&init_console_chan.list, &vts[0].chan_list);
9875 + register_console(&stdiocons);
9878 +static int console_chan_setup(char *str)
9880 + return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
9883 +__setup("con", console_chan_setup);
9884 +__channel_help(console_chan_setup, "con");
9886 +static void console_exit(void)
9888 + if(!con_init_done) return;
9889 + close_lines(vts, sizeof(vts)/sizeof(vts[0]));
9892 +__uml_exitcall(console_exit);
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
9899 + * ---------------------------------------------------------------------------
9900 + * Local variables:
9901 + * c-file-style: "linux"
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
9910 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9911 + * Licensed under the GPL
9914 +#ifndef __STDIO_CONSOLE_H
9915 +#define __STDIO_CONSOLE_H
9917 +extern void save_console_flags(void);
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
9925 + * ---------------------------------------------------------------------------
9926 + * Local variables:
9927 + * c-file-style: "linux"
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
9936 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
9937 + * Licensed under the GPL
9941 +#include <termios.h>
9943 +#include <unistd.h>
9944 +#include "chan_user.h"
9945 +#include "user_util.h"
9952 + struct termios tt;
9955 +void *tty_chan_init(char *str, int device, struct chan_opts *opts)
9957 + struct tty_chan *data;
9960 + printk("tty_init : channel type 'tty' must specify "
9966 + data = um_kmalloc(sizeof(*data));
9969 + *data = ((struct tty_chan) { .dev = str,
9970 + .raw = opts->raw });
9975 +int tty_open(int input, int output, int primary, void *d, char **dev_out)
9977 + struct tty_chan *data = d;
9980 + fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0);
9981 + if(fd < 0) return(fd);
9983 + CATCH_EINTR(err = tcgetattr(fd, &data->tt));
9992 + *dev_out = data->dev;
9996 +int tty_console_write(int fd, const char *buf, int n, void *d)
9998 + struct tty_chan *data = d;
10000 + return(generic_console_write(fd, buf, n, &data->tt));
10003 +struct chan_ops tty_ops = {
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,
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
10021 + * ---------------------------------------------------------------------------
10022 + * Local variables:
10023 + * c-file-style: "linux"
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
10032 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
10033 + * Licensed under the GPL
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
10041 +#define MAJOR_NR UBD_MAJOR
10042 +#define UBD_SHIFT 4
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"
10067 +#include "mconsole_kern.h"
10069 +#include "irq_user.h"
10070 +#include "irq_kern.h"
10071 +#include "ubd_user.h"
10072 +#include "2_5compat.h"
10075 +#include "mem_kern.h"
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);
10084 +#define MAX_DEV (8)
10085 +#define MAX_MINOR (MAX_DEV << UBD_SHIFT)
10087 +/* Changed in early boot */
10088 +static int ubd_do_mmap = 0;
10089 +#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
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 };
10095 +/* Protected by ubd_lock */
10096 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
10098 +static struct block_device_operations ubd_blops = {
10099 + .open = ubd_open,
10100 + .release = ubd_release,
10101 + .ioctl = ubd_ioctl,
10102 + .revalidate = ubd_revalidate,
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.
10108 +static struct hd_struct ubd_part[MAX_MINOR] =
10109 + { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
10111 +/* Protected by io_request_lock */
10112 +static request_queue_t *ubd_queue;
10114 +/* Protected by ubd_lock */
10115 +static int fake_major = MAJOR_NR;
10117 +static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
10119 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
10122 + .major_name = name, \
10123 + .minor_shift = shift, \
10124 + .max_p = 1 << shift, \
10126 + .sizes = bsizes, \
10127 + .nr_real = max, \
10128 + .real_devices = NULL, \
10131 + .de_arr = NULL, \
10135 +static struct gendisk ubd_gendisk = INIT_GENDISK(MAJOR_NR, "ubd", ubd_part,
10136 + UBD_SHIFT, sizes, MAX_DEV,
10138 +static struct gendisk fake_gendisk = INIT_GENDISK(0, "ubd", ubd_part,
10139 + UBD_SHIFT, sizes, MAX_DEV,
10142 +#ifdef CONFIG_BLK_DEV_UBD_SYNC
10143 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
10146 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \
10150 +/* Not protected - changed only in ubd_setup_common and then only to
10151 + * to enable O_SYNC.
10153 +static struct openflags global_openflags = OPEN_FLAGS;
10158 + unsigned long *bitmap;
10159 + unsigned long bitmap_len;
10160 + int bitmap_offset;
10169 + struct openflags boot_openflags;
10170 + struct openflags openflags;
10171 + devfs_handle_t devfs;
10177 + int nomap_writes;
10182 +#define DEFAULT_COW { \
10185 + .bitmap = NULL, \
10186 + .bitmap_offset = 0, \
10187 + .data_offset = 0, \
10190 +#define DEFAULT_UBD { \
10195 + .boot_openflags = OPEN_FLAGS, \
10196 + .openflags = OPEN_FLAGS, \
10199 + .cow = DEFAULT_COW, \
10200 + .map_writes = 0, \
10201 + .map_reads = 0, \
10202 + .nomap_writes = 0, \
10203 + .nomap_reads = 0, \
10204 + .write_maps = 0, \
10207 +struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
10209 +static int ubd0_init(void)
10211 + struct ubd *dev = &ubd_dev[0];
10213 + if(dev->file == NULL)
10214 + dev->file = "root_fs";
10218 +__initcall(ubd0_init);
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;
10225 +static void make_proc_ide(void)
10227 + proc_ide_root = proc_mkdir("ide", 0);
10228 + proc_ide = proc_mkdir("ide0", proc_ide_root);
10231 +static int proc_ide_read_media(char *page, char **start, off_t off, int count,
10232 + int *eof, void *data)
10236 + strcpy(page, "disk\n");
10237 + len = strlen("disk\n");
10239 + if (len < count){
10241 + if (len <= 0) return 0;
10243 + else len = count;
10244 + *start = page + off;
10248 +static void make_ide_entries(char *dev_name)
10250 + struct proc_dir_entry *dir, *ent;
10253 + if(!fake_ide) return;
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.
10259 + spin_lock(&ubd_lock);
10260 + if(proc_ide_root == NULL) make_proc_ide();
10261 + spin_unlock(&ubd_lock);
10263 + dir = proc_mkdir(dev_name, proc_ide);
10266 + ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir);
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);
10276 +static int fake_ide_setup(char *str)
10282 +__setup("fake_ide", fake_ide_setup);
10284 +__uml_help(fake_ide_setup,
10286 +" Create ide0 entries that map onto ubd devices.\n\n"
10289 +static int parse_unit(char **ptr)
10291 + char *str = *ptr, *end;
10294 + if(isdigit(*str)) {
10295 + n = simple_strtoul(str, &end, 0);
10300 + else if (('a' <= *str) && (*str <= 'h')) {
10308 +static int ubd_setup_common(char *str, int *index_out)
10310 + struct openflags flags = global_openflags;
10312 + char *backing_file;
10315 + if(index_out) *index_out = -1;
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);
10329 + if(!strcmp(str, "sync")){
10330 + global_openflags.s = 1;
10333 + major = simple_strtoul(str, &end, 0);
10334 + if((*end != '\0') || (end == str)){
10336 + "ubd_setup : didn't parse major number\n");
10341 + spin_lock(&ubd_lock);
10342 + if(fake_major != MAJOR_NR){
10343 + printk(KERN_ERR "Can't assign a fake major twice\n");
10347 + fake_gendisk.major = major;
10348 + fake_major = major;
10350 + printk(KERN_INFO "Setting extra ubd major number to %d\n",
10354 + spin_unlock(&ubd_lock);
10358 + n = parse_unit(&str);
10360 + printk(KERN_ERR "ubd_setup : couldn't parse unit number "
10365 + if(n >= MAX_DEV){
10366 + printk(KERN_ERR "ubd_setup : index %d out of range "
10367 + "(%d devices)\n", n, MAX_DEV);
10372 + spin_lock(&ubd_lock);
10374 + dev = &ubd_dev[n];
10375 + if(dev->file != NULL){
10376 + printk(KERN_ERR "ubd_setup : device already configured\n");
10380 + if(index_out) *index_out = n;
10395 + if(*str++ != '='){
10396 + printk(KERN_ERR "ubd_setup : Expected '='\n");
10401 + backing_file = strchr(str, ',');
10402 + if(backing_file){
10404 + printk(KERN_ERR "Can't specify both 'd' and a "
10407 + *backing_file = '\0';
10412 + dev->cow.file = backing_file;
10413 + dev->boot_openflags = flags;
10415 + spin_unlock(&ubd_lock);
10419 +static int ubd_setup(char *str)
10421 + ubd_setup_common(str, NULL);
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"
10440 +static int fakehd(char *str)
10443 + "fakehd : Changing ubd_gendisk.major_name to \"hd\".\n");
10444 + ubd_gendisk.major_name = "hd";
10448 +__setup("fakehd", fakehd);
10449 +__uml_help(fakehd,
10451 +" Change the ubd device name to \"hd\".\n\n"
10454 +static void do_ubd_request(request_queue_t * q);
10456 +/* Only changed by ubd_init, which is an initcall. */
10457 +int thread_fd = -1;
10459 +/* Changed by ubd_handler, which is serialized because interrupts only
10460 + * happen on CPU 0.
10462 +int intr_count = 0;
10464 +static void ubd_finish(int error)
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;
10481 +static void ubd_handler(void)
10483 + struct io_thread_req req;
10486 + DEVICE_INTR = NULL;
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);
10494 + spin_unlock(&io_request_lock);
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");
10503 + if(req.map_fd != -1){
10504 + err = physmem_subst_mapping(req.buffer, req.map_fd,
10505 + req.map_offset, 1);
10507 + printk("ubd_handler - physmem_subst_mapping failed, "
10508 + "err = %d\n", -err);
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);
10518 +static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
10523 +/* Only changed by ubd_init, which is an initcall. */
10524 +static int io_pid = -1;
10526 +void kill_io_thread(void)
10529 + os_kill_process(io_pid, 1);
10532 +__uml_exitcall(kill_io_thread);
10534 +/* Initialized in an initcall, and unchanged thereafter */
10535 +devfs_handle_t ubd_dir_handle;
10537 +static int ubd_add(int n)
10539 + struct ubd *dev = &ubd_dev[n];
10540 + char name[sizeof("nnnnnn\0")], dev_name[sizeof("ubd0x")];
10541 + int err = -EISDIR;
10543 + if(dev->file == NULL)
10546 + err = ubd_revalidate1(MKDEV(MAJOR_NR, n << UBD_SHIFT));
10550 + if(dev->cow.file == NULL)
10551 + blk_sizes[n] = UBD_MMAP_BLOCK_SIZE;
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);
10559 +#if 0 /* 2.5 ... */
10560 + sprintf(disk->disk_name, "ubd%c", 'a' + unit);
10563 + sprintf(dev_name, "%s%c", ubd_gendisk.major_name,
10566 + make_ide_entries(dev_name);
10573 +static int ubd_config(char *str)
10577 + str = uml_strdup(str);
10579 + printk(KERN_ERR "ubd_config failed to strdup string\n");
10582 + err = ubd_setup_common(str, &n);
10587 + if(n == -1) return(0);
10589 + spin_lock(&ubd_lock);
10590 + err = ubd_add(n);
10592 + ubd_dev[n].file = NULL;
10593 + spin_unlock(&ubd_lock);
10598 +static int ubd_get_config(char *name, char *str, int size, char **error_out)
10604 + n = simple_strtoul(name, &end, 0);
10605 + if((*end != '\0') || (end == name)){
10606 + *error_out = "ubd_get_config : didn't parse device number";
10610 + if((n >= MAX_DEV) || (n < 0)){
10611 + *error_out = "ubd_get_config : device number out of range";
10615 + dev = &ubd_dev[n];
10616 + spin_lock(&ubd_lock);
10618 + if(dev->file == NULL){
10619 + CONFIG_CHUNK(str, size, len, "", 1);
10623 + CONFIG_CHUNK(str, size, len, dev->file, 0);
10625 + if(dev->cow.file != NULL){
10626 + CONFIG_CHUNK(str, size, len, ",", 0);
10627 + CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
10629 + else CONFIG_CHUNK(str, size, len, "", 1);
10632 + spin_unlock(&ubd_lock);
10636 +static int ubd_remove(char *str)
10639 + int n, err = -ENODEV;
10641 + if(isdigit(*str)){
10643 + n = simple_strtoul(str, &end, 0);
10644 + if ((*end != '\0') || (end == str))
10647 + else if (('a' <= *str) && (*str <= 'h'))
10650 + return(err); /* it should be a number 0-7/a-h */
10652 + if((n < 0) || (n >= MAX_DEV))
10655 + dev = &ubd_dev[n];
10657 + spin_lock(&ubd_lock);
10659 + if(dev->file == NULL)
10662 + if(dev->count > 0)
10664 + if(dev->devfs != NULL)
10665 + devfs_unregister(dev->devfs);
10667 + *dev = ((struct ubd) DEFAULT_UBD);
10670 + spin_unlock(&ubd_lock);
10674 +static struct mc_device ubd_mc = {
10676 + .config = ubd_config,
10677 + .get_config = ubd_get_config,
10678 + .remove = ubd_remove,
10681 +static int ubd_mc_init(void)
10683 + mconsole_register_dev(&ubd_mc);
10687 +__initcall(ubd_mc_init);
10689 +static request_queue_t *ubd_get_queue(kdev_t device)
10691 + return(ubd_queue);
10694 +int ubd_init(void)
10696 + unsigned long stack;
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);
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);
10709 + ubd_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
10710 + blk_init_queue(ubd_queue, DEVICE_REQUEST);
10711 + INIT_ELV(ubd_queue, &ubd_queue->elevator);
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;
10724 + /* not auto so normal error */
10725 + printk(KERN_ERR "ubd: error %d getting major %d\n",
10726 + -err, fake_major);
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);
10738 + for(i=0;i<MAX_DEV;i++)
10741 + if(global_openflags.s){
10742 + printk(KERN_INFO "ubd : Synchronous mode\n");
10745 + stack = alloc_stack(0, 0);
10746 + io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
10751 + "ubd : Failed to start I/O thread (errno = %d) - "
10752 + "falling back to synchronous I/O\n", -io_pid);
10755 + err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
10756 + SA_INTERRUPT, "ubd", ubd_dev);
10758 + printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
10762 +__initcall(ubd_init);
10764 +static void ubd_close(struct ubd *dev)
10767 + physmem_forget_descriptor(dev->fd);
10768 + os_close_file(dev->fd);
10769 + if(dev->cow.file != NULL)
10773 + physmem_forget_descriptor(dev->cow.fd);
10774 + os_close_file(dev->cow.fd);
10775 + vfree(dev->cow.bitmap);
10776 + dev->cow.bitmap = NULL;
10779 +static int ubd_open_dev(struct ubd *dev)
10781 + struct openflags flags;
10783 + int err, create_cow, *create_ptr;
10785 + dev->openflags = dev->boot_openflags;
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);
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);
10805 + if(dev->fd < 0) return(dev->fd);
10807 + if(dev->cow.file != NULL){
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");
10814 + flush_tlb_kernel_vm();
10816 + err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
10817 + dev->cow.bitmap_offset,
10818 + dev->cow.bitmap_len);
10822 + flags = dev->openflags;
10824 + err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL,
10826 + if(err < 0) goto error;
10827 + dev->cow.fd = err;
10831 + os_close_file(dev->fd);
10835 +static int ubd_file_size(struct ubd *dev, __u64 *size_out)
10839 + file = dev->cow.file ? dev->cow.file : dev->file;
10840 + return(os_file_size(file, size_out));
10843 +static int ubd_open(struct inode *inode, struct file *filp)
10846 + int n, offset, err = 0;
10848 + n = DEVICE_NR(inode->i_rdev);
10849 + dev = &ubd_dev[n];
10853 + spin_lock(&ubd_lock);
10854 + offset = n << UBD_SHIFT;
10856 + if(dev->count == 0){
10857 + err = ubd_open_dev(dev);
10859 + printk(KERN_ERR "ubd%d: Can't open \"%s\": "
10860 + "errno = %d\n", n, dev->file, -err);
10863 + err = ubd_file_size(dev, &dev->size);
10866 + sizes[offset] = dev->size / BLOCK_SIZE;
10867 + ubd_part[offset].nr_sects = dev->size / hardsect_sizes[offset];
10870 + if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
10871 + if(--dev->count == 0) ubd_close(dev);
10875 + spin_unlock(&ubd_lock);
10879 +static int ubd_release(struct inode * inode, struct file * file)
10883 + n = DEVICE_NR(inode->i_rdev);
10884 + offset = n << UBD_SHIFT;
10888 + spin_lock(&ubd_lock);
10889 + if(--ubd_dev[n].count == 0)
10890 + ubd_close(&ubd_dev[n]);
10891 + spin_unlock(&ubd_lock);
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)
10901 + __u64 sector = io_offset >> 9;
10902 + int i, update_bitmap = 0;
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))
10910 + update_bitmap = 1;
10911 + ubd_set_bit(sector + i, (unsigned char *) bitmap);
10914 + if(!update_bitmap)
10917 + *cow_offset = sector / (sizeof(unsigned long) * 8);
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.
10924 + if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
10925 + sizeof(unsigned long) - 1))
10928 + bitmap_words[0] = bitmap[*cow_offset];
10929 + bitmap_words[1] = bitmap[*cow_offset + 1];
10931 + *cow_offset *= sizeof(unsigned long);
10932 + *cow_offset += bitmap_offset;
10935 +static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
10936 + __u64 bitmap_offset, __u64 bitmap_len)
10938 + __u64 sector = req->offset >> 9;
10941 + if(req->length > (sizeof(req->sector_mask) * 8) << 9)
10942 + panic("Operation too long");
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);
10952 + else cowify_bitmap(req->offset, req->length, &req->sector_mask,
10953 + &req->cow_offset, bitmap, bitmap_offset,
10954 + req->bitmap_words, bitmap_len);
10957 +static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
10960 + unsigned char *bitmap;
10963 + /* mmap must have been requested on the command line */
10967 + /* The buffer must be page aligned */
10968 + if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
10971 + /* The request must be a page long */
10972 + if((req->current_nr_sectors << 9) != PAGE_SIZE)
10975 + if(dev->cow.file == NULL)
10978 + sector = offset >> 9;
10979 + bitmap = (unsigned char *) dev->cow.bitmap;
10980 + bit = ubd_test_bit(sector, bitmap);
10982 + for(i = 1; i < req->current_nr_sectors; i++){
10983 + if(ubd_test_bit(sector + i, bitmap) != bit)
10987 + if(bit || (req->cmd == WRITE))
10988 + offset += dev->cow.data_offset;
10990 + /* The data on disk must be page aligned */
10991 + if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
10994 + return(bit ? dev->fd : dev->cow.fd);
10997 +static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset,
10998 + struct request *req,
10999 + struct io_thread_req *io_req)
11003 + if(req->cmd == WRITE){
11004 + /* Writes are almost no-ops since the new data is already in the
11005 + * host page cache
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);
11018 + if((dev->cow.file != NULL) && (fd == dev->cow.fd))
11020 + else w = dev->openflags.w;
11022 + if((dev->cow.file != NULL) && (fd == dev->fd))
11023 + offset += dev->cow.data_offset;
11025 + err = physmem_subst_mapping(req->buffer, fd, offset, w);
11027 + printk("physmem_subst_mapping failed, err = %d\n",
11031 + dev->map_reads++;
11033 + io_req->op = UBD_MMAP;
11034 + io_req->buffer = req->buffer;
11038 +static int prepare_request(struct request *req, struct io_thread_req *io_req)
11042 + int minor, n, len, fd;
11044 + if(req->rq_status == RQ_INACTIVE) return(1);
11046 + minor = MINOR(req->rq_dev);
11047 + n = minor >> UBD_SHIFT;
11048 + dev = &ubd_dev[n];
11050 + if(IS_WRITE(req) && !dev->openflags.w){
11051 + printk("Write attempted on readonly ubd device %d\n", n);
11056 + req->sector += ubd_part[minor].start_sect;
11057 + offset = ((__u64) req->sector) << 9;
11058 + len = req->current_nr_sectors << 9;
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;
11069 + fd = mmap_fd(req, dev, io_req->offset);
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.
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++;
11082 + else return(prepare_mmap_request(dev, fd, io_req->offset, req,
11086 + if(req->cmd == READ)
11087 + dev->nomap_reads++;
11088 + else dev->nomap_writes++;
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;
11096 + if(dev->cow.file != NULL)
11097 + cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
11098 + dev->cow.bitmap_len);
11102 +static void do_ubd_request(request_queue_t *q)
11104 + struct io_thread_req io_req;
11105 + struct request *req;
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);
11114 + ubd_finish(io_req.error);
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);
11123 + SET_INTR(ubd_handler);
11124 + n = write_ubd_fs(thread_fd, (char *) &io_req,
11126 + if(n != sizeof(io_req))
11127 + printk("write to io thread failed, "
11128 + "errno = %d\n", -n);
11133 +static int ubd_ioctl(struct inode * inode, struct file * file,
11134 + unsigned int cmd, unsigned long arg)
11136 + struct hd_geometry *loc = (struct hd_geometry *) arg;
11138 + int n, minor, err;
11139 + struct hd_driveid ubd_id = {
11145 + if(!inode) return(-EINVAL);
11146 + minor = MINOR(inode->i_rdev);
11147 + n = minor >> UBD_SHIFT;
11150 + dev = &ubd_dev[n];
11152 + struct hd_geometry g;
11153 + struct cdrom_volctrl volume;
11154 + case HDIO_GETGEO:
11155 + if(!loc) return(-EINVAL);
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));
11166 + put_user(ubd_part[minor].nr_sects, (long *) arg);
11168 + case BLKRRPART: /* Re-read partition tables */
11169 + return(ubd_revalidate(inode->i_rdev));
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,
11178 + case CDROMVOLREAD:
11179 + if(copy_from_user(&volume, (char *) arg, sizeof(volume)))
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)))
11190 + return blk_ioctl(inode->i_rdev, cmd, arg);
11194 +static int ubd_revalidate1(kdev_t rdev)
11196 + int i, n, offset, err = 0, pcount = 1 << UBD_SHIFT;
11198 + struct hd_struct *part;
11200 + n = DEVICE_NR(rdev);
11201 + offset = n << UBD_SHIFT;
11202 + dev = &ubd_dev[n];
11204 + part = &ubd_part[offset];
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;
11212 + /* If it already has been opened we can check the partitions
11216 + part->start_sect = 0;
11217 + register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount,
11218 + &ubd_blops, part->nr_sects);
11220 + else if(dev->file){
11221 + err = ubd_open_dev(dev);
11223 + printk(KERN_ERR "unable to open %s for validation\n",
11228 + /* have to recompute sizes since we opened it */
11229 + err = ubd_file_size(dev, &dev->size);
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);
11239 + /* we are done so close it */
11242 + else err = -ENODEV;
11247 +static int ubd_revalidate(kdev_t rdev)
11251 + spin_lock(&ubd_lock);
11252 + err = ubd_revalidate1(rdev);
11253 + spin_unlock(&ubd_lock);
11257 +static int ubd_check_remapped(int fd, unsigned long address, int is_write,
11258 + __u64 offset, int is_user)
11260 + __u64 bitmap_offset;
11261 + unsigned long new_bitmap[2];
11264 + /* This can only fix kernelspace faults */
11268 + /* ubd-mmap is only enabled in skas mode */
11269 + if(CHOOSE_MODE(1, 0))
11272 + /* If it's not a write access, we can't do anything about it */
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];
11280 + if((dev->fd != fd) && (dev->cow.fd != fd))
11283 + /* It's a write to a ubd device */
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
11292 + printk("Write access to mapped page from readonly ubd "
11293 + "device %d\n", i);
11297 + /* It's a write to a writeable ubd device - it must be COWed
11298 + * because, otherwise, the page would have been mapped in
11302 + if(!dev->cow.file)
11303 + panic("Write fault on writeable non-COW ubd device %d",
11306 + /* It should also be an access to the backing file since the
11307 + * COW pages should be mapped in read-write
11310 + if(fd == dev->fd)
11311 + panic("Write fault on a backing page of ubd "
11312 + "device %d\n", i);
11314 + /* So, we do the write, copying the backing data to the COW
11318 + err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
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);
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);
11329 + /* ... updating the COW bitmap... */
11331 + cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset,
11332 + dev->cow.bitmap, dev->cow.bitmap_offset,
11333 + new_bitmap, dev->cow.bitmap_len);
11335 + err = os_seek_file(dev->fd, bitmap_offset);
11337 + panic("Couldn't seek to %lld in COW file of ubd "
11338 + "device %d, err = %d", bitmap_offset, i, -err);
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);
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.
11352 + offset += dev->cow.data_offset;
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.
11359 + if(!physmem_remove_mapping((void *) address))
11360 + panic("Address 0x%lx not remapped by ubd device %d",
11362 + if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
11363 + physmem_subst_mapping((void *) address, dev->fd,
11366 + err = os_seek_file(dev->fd, offset);
11368 + panic("Couldn't seek to %lld in COW file of "
11369 + "ubd device %d, err = %d", offset, i,
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",
11382 + /* It's not a write on a ubd device */
11386 +static struct remapper ubd_remapper = {
11387 + .list = LIST_HEAD_INIT(ubd_remapper.list),
11388 + .proc = ubd_check_remapped,
11391 +static int ubd_remapper_setup(void)
11394 + register_remapper(&ubd_remapper);
11399 +__initcall(ubd_remapper_setup);
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
11406 + * ---------------------------------------------------------------------------
11407 + * Local variables:
11408 + * c-file-style: "linux"
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
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
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"
11437 +#include "ubd_user.h"
11441 +#include <endian.h>
11442 +#include <byteswap.h>
11444 +static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
11446 + struct uml_stat buf1, buf2;
11449 + if(from_cmdline == NULL) return(1);
11450 + if(!strcmp(from_cmdline, from_cow)) return(1);
11452 + err = os_stat_file(from_cmdline, &buf1);
11454 + printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
11457 + err = os_stat_file(from_cow, &buf2);
11459 + printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
11462 + if((buf1.ust_major == buf2.ust_major) &&
11463 + (buf1.ust_minor == buf2.ust_minor) &&
11464 + (buf1.ust_ino == buf2.ust_ino))
11467 + printk("Backing file mismatch - \"%s\" requested,\n"
11468 + "\"%s\" specified in COW header of \"%s\"\n",
11469 + from_cmdline, from_cow, cow);
11473 +static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
11475 + unsigned long modtime;
11476 + long long actual;
11479 + err = os_file_modtime(file, &modtime);
11481 + printk("Failed to get modification time of backing file "
11482 + "\"%s\", err = %d\n", file, -err);
11486 + err = os_file_size(file, &actual);
11488 + printk("Failed to get size of backing file \"%s\", "
11489 + "err = %d\n", file, -err);
11493 + if(actual != size){
11494 + printk("Size mismatch (%ld vs %ld) of COW header vs backing "
11495 + "file\n", size, actual);
11498 + if(modtime != mtime){
11499 + printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
11500 + "file\n", mtime, modtime);
11506 +int read_cow_bitmap(int fd, void *buf, int offset, int len)
11510 + err = os_seek_file(fd, offset);
11514 + err = os_read_file(fd, buf, len);
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)
11528 + __u32 version, align;
11529 + char *backing_file;
11530 + int fd, err, sectorsize, same, mode = 0644;
11532 + fd = os_open_file(file, *openflags, mode);
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);
11544 + err = os_lock_file(fd, openflags->w);
11546 + printk("Failed to lock '%s', err = %d\n", file, -err);
11550 + if(backing_file_out == NULL) return(fd);
11552 + err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
11553 + &size, §orsize, &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);
11559 + if(err) return(fd);
11561 + if(backing_file_out == NULL) return(fd);
11563 + same = same_backing_files(*backing_file_out, backing_file, file);
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);
11570 + printk("Switch failed, errno = %d\n", -err);
11575 + *backing_file_out = backing_file;
11576 + err = backing_file_mismatch(*backing_file_out, size, mtime);
11577 + if(err) goto out_close;
11580 + cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
11581 + bitmap_len_out, data_offset_out);
11585 + os_close_file(fd);
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)
11596 + fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
11599 + printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
11604 + err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
11605 + bitmap_offset_out, bitmap_len_out,
11606 + data_offset_out);
11610 + os_close_file(fd);
11615 +/* XXX Just trivial wrappers around os_read_file and os_write_file */
11616 +int read_ubd_fs(int fd, void *buffer, int len)
11618 + return(os_read_file(fd, buffer, len));
11621 +int write_ubd_fs(int fd, char *buffer, int len)
11623 + return(os_write_file(fd, buffer, len));
11626 +static int update_bitmap(struct io_thread_req *req)
11630 + if(req->cow_offset == -1)
11633 + n = os_seek_file(req->fds[1], req->cow_offset);
11635 + printk("do_io - bitmap lseek failed : err = %d\n", -n);
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,
11650 +void do_io(struct io_thread_req *req)
11653 + unsigned long len;
11654 + int n, nsectors, start, end, bit;
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
11662 + n = *((volatile int *) req->buffer);
11663 + req->error = update_bitmap(req);
11667 + nsectors = req->length / req->sectorsize;
11670 + bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
11672 + while((end < nsectors) &&
11673 + (ubd_test_bit(end, (unsigned char *)
11674 + &req->sector_mask) == bit))
11677 + off = req->offset + req->offsets[bit] +
11678 + start * req->sectorsize;
11679 + len = (end - start) * req->sectorsize;
11680 + buf = &req->buffer[start * req->sectorsize];
11682 + err = os_seek_file(req->fds[bit], off);
11684 + printk("do_io - lseek failed : err = %d\n", -err);
11688 + if(req->op == UBD_READ){
11693 + n = os_read_file(req->fds[bit], buf, len);
11695 + printk("do_io - read failed, err = %d "
11696 + "fd = %d\n", -n, req->fds[bit]);
11700 + } while((n < len) && (n != 0));
11701 + if (n < len) memset(&buf[n], 0, len - n);
11704 + n = os_write_file(req->fds[bit], buf, len);
11706 + printk("do_io - write failed err = %d "
11707 + "fd = %d\n", -n, req->fds[bit]);
11714 + } while(start < nsectors);
11716 + req->error = update_bitmap(req);
11719 +/* Changed in start_io_thread, which is serialized by being called only
11720 + * from ubd_init, which is an initcall.
11722 +int kernel_fd = -1;
11724 +/* Only changed by the io thread */
11727 +int io_thread(void *arg)
11729 + struct io_thread_req req;
11732 + signal(SIGWINCH, SIG_IGN);
11734 + n = os_read_file(kernel_fd, &req, sizeof(req));
11735 + if(n != sizeof(req)){
11737 + printk("io_thread - read failed, fd = %d, "
11738 + "err = %d\n", kernel_fd, -n);
11740 + printk("io_thread - short read, fd = %d, "
11741 + "length = %d\n", kernel_fd, n);
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",
11754 +int start_io_thread(unsigned long sp, int *fd_out)
11756 + int pid, fds[2], err;
11758 + err = os_pipe(fds, 1, 1);
11760 + printk("start_io_thread - os_pipe failed, err = %d\n", -err);
11764 + kernel_fd = fds[0];
11765 + *fd_out = fds[1];
11767 + pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
11770 + printk("start_io_thread - clone failed : errno = %d\n", errno);
11777 + os_close_file(fds[0]);
11778 + os_close_file(fds[1]);
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
11790 + * ---------------------------------------------------------------------------
11791 + * Local variables:
11792 + * c-file-style: "linux"
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
11801 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
11802 + * Licensed under the GPL
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"
11820 +#include "xterm.h"
11822 +struct xterm_chan {
11828 + struct termios tt;
11829 + unsigned long stack;
11833 +void *xterm_init(char *str, int device, struct chan_opts *opts)
11835 + struct xterm_chan *data;
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 } );
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";
11854 +static int __init xterm_setup(char *line, int *add)
11857 + terminal_emulator = line;
11859 + line = strchr(line, ',');
11860 + if(line == NULL) return(0);
11862 + if(*line) title_switch = line;
11864 + line = strchr(line, ',');
11865 + if(line == NULL) return(0);
11867 + if(*line) exec_switch = line;
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"
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)
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",
11896 + if(os_access(argv[4], OS_ACC_X_OK) < 0)
11897 + argv[4] = "port-helper";
11899 + fd = mkstemp(file);
11901 + printk("xterm_open : mkstemp failed, errno = %d\n", errno);
11905 + if(unlink(file)){
11906 + printk("xterm_open : unlink failed, errno = %d\n", errno);
11909 + os_close_file(fd);
11911 + fd = os_create_unix_socket(file, sizeof(file), 1);
11913 + printk("xterm_open : create_unix_socket failed, errno = %d\n",
11918 + sprintf(title, data->title, data->device);
11919 + stack = data->stack;
11920 + pid = run_helper(NULL, NULL, argv, &stack);
11922 + printk("xterm_open : run_helper failed, errno = %d\n", -pid);
11926 + if(data->stack == 0) free_stack(stack, 0);
11928 + if(data->direct_rcv)
11929 + new = os_rcv_fd(fd, &data->helper_pid);
11931 + err = os_set_fd_block(fd, 0);
11933 + printk("xterm_open : failed to set descriptor "
11934 + "non-blocking, err = %d\n", -err);
11937 + new = xterm_fd(fd, &data->helper_pid);
11940 + printk("xterm_open : os_rcv_fd failed, err = %d\n", -new);
11944 + CATCH_EINTR(err = tcgetattr(new, &data->tt));
11965 +void xterm_close(int fd, void *d)
11967 + struct xterm_chan *data = d;
11969 + if(data->pid != -1)
11970 + os_kill_process(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);
11978 +void xterm_free(void *d)
11983 +int xterm_console_write(int fd, const char *buf, int n, void *d)
11985 + struct xterm_chan *data = d;
11987 + return(generic_console_write(fd, buf, n, &data->tt));
11990 +struct chan_ops xterm_ops = {
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,
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
12008 + * ---------------------------------------------------------------------------
12009 + * Local variables:
12010 + * c-file-style: "linux"
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
12019 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
12020 + * Licensed under the GPL
12023 +#ifndef __XTERM_H__
12024 +#define __XTERM_H__
12026 +extern int xterm_fd(int socket, int *pid_out);
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
12035 + * ---------------------------------------------------------------------------
12036 + * Local variables:
12037 + * c-file-style: "linux"
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
12046 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
12047 + * Licensed under the GPL
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"
12058 +#include "xterm.h"
12060 +struct xterm_wait {
12061 + struct semaphore sem;
12067 +static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
12069 + struct xterm_wait *xterm = data;
12072 + fd = os_rcv_fd(xterm->fd, &xterm->pid);
12073 + if(fd == -EAGAIN)
12076 + xterm->new_fd = fd;
12080 +int xterm_fd(int socket, int *pid_out)
12082 + struct xterm_wait *data;
12085 + data = kmalloc(sizeof(*data), GFP_KERNEL);
12086 + if(data == NULL){
12087 + printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
12090 + *data = ((struct xterm_wait)
12091 + { .sem = __SEMAPHORE_INITIALIZER(data->sem, 0),
12096 + err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt,
12097 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
12100 + printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
12101 + "err = %d\n", err);
12105 + down(&data->sem);
12107 + free_irq(XTERM_IRQ, data);
12109 + ret = data->new_fd;
12110 + *pid_out = data->pid;
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
12122 + * ---------------------------------------------------------------------------
12123 + * Local variables:
12124 + * c-file-style: "linux"
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
12133 + * Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com)
12134 + * Licensed under the GPL
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"
12149 +#include "user_util.h"
12150 +#include "2_5compat.h"
12152 +#include "filehandle.h"
12155 + struct list_head list;
12156 + struct externfs_mount_ops *mount_ops;
12157 + struct file_system_type type;
12160 +static inline struct externfs_inode *EXTERNFS_I(struct inode *inode)
12162 + return(inode->u.generic_ip);
12165 +#define file_externfs_i(file) EXTERNFS_I((file)->f_dentry->d_inode)
12167 +int externfs_d_delete(struct dentry *dentry)
12172 +struct dentry_operations externfs_dentry_ops = {
12175 +#define EXTERNFS_SUPER_MAGIC 0x00c0ffee
12177 +static struct inode_operations externfs_iops;
12178 +static struct inode_operations externfs_dir_iops;
12179 +static struct address_space_operations externfs_link_aops;
12181 +static char *dentry_name(struct dentry *dentry, int extra)
12183 + struct dentry *parent;
12189 + while(parent->d_parent != parent){
12190 + len += parent->d_name.len + 1;
12191 + parent = parent->d_parent;
12194 + name = kmalloc(len + extra + 1, GFP_KERNEL);
12195 + if(name == NULL) return(NULL);
12197 + name[len] = '\0';
12199 + while(parent->d_parent != parent){
12200 + len -= parent->d_name.len + 1;
12202 + strncpy(&name[len + 1], parent->d_name.name,
12203 + parent->d_name.len);
12204 + parent = parent->d_parent;
12210 +char *inode_name(struct inode *ino, int extra)
12212 + struct dentry *dentry;
12214 + dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
12215 + return(dentry_name(dentry, extra));
12218 +char *inode_name_prefix(struct inode *inode, char *prefix)
12223 + len = strlen(prefix);
12224 + name = inode_name(inode, len);
12228 + memmove(&name[len], name, strlen(name) + 1);
12229 + memcpy(name, prefix, strlen(prefix));
12233 +static int read_name(struct inode *ino, char *name)
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
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;
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;
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)
12269 + char *name, *resolved, *end;
12274 + name = kmalloc(len, GFP_KERNEL);
12278 + n = (*do_read_link)(link, uid, gid, name, len, ed);
12290 + end = strrchr(link, '/');
12294 + *(end + 1) = '\0';
12295 + len = strlen(link) + strlen(name) + 1;
12297 + resolved = kmalloc(len, GFP_KERNEL);
12298 + if(resolved == NULL){
12303 + sprintf(resolved, "%s%s", link, name);
12305 + return(resolved);
12310 + return(ERR_PTR(n));
12313 +static int read_inode(struct inode *ino)
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;
12321 + name = inode_name(ino, 0);
12325 + type = (*ops->file_type)(name, NULL, ed);
12331 + if(type == OS_TYPE_SYMLINK){
12332 + new = follow_link(name, ops->read_link, current->fsuid,
12333 + current->fsgid, ed);
12335 + err = PTR_ERR(new);
12342 + err = read_name(ino, name);
12349 +void externfs_delete_inode(struct inode *ino)
12351 + struct externfs_inode *ext = EXTERNFS_I(ino);
12352 + struct externfs_file_ops *ops = ext->ops;
12354 + (*ops->close_file)(ext, ino->i_size);
12356 + clear_inode(ino);
12359 +int externfs_statfs(struct super_block *sb, struct statfs *sf)
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
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;
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);
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;
12389 +static struct super_operations externfs_sbops = {
12390 + .delete_inode = externfs_delete_inode,
12391 + .statfs = externfs_statfs,
12394 +int externfs_readdir(struct file *file, void *ent, filldir_t filldir)
12398 + unsigned long long next, ino;
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;
12404 + name = dentry_name(file->f_dentry, 0);
12408 + dir = (*ops->open_dir)(name, current->fsuid, current->fsgid, ed);
12411 + return(PTR_ERR(dir));
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,
12419 + file->f_pos = next;
12421 + (*ops->close_dir)(dir, ed);
12425 +int externfs_file_open(struct inode *ino, struct file *file)
12431 +int externfs_dir_open(struct inode *ino, struct file *file)
12436 +int externfs_dir_release(struct inode *ino, struct file *file)
12441 +int externfs_fsync(struct file *file, struct dentry *dentry, int datasync)
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;
12447 + return((*ops->truncate_file)(EXTERNFS_I(inode), inode->i_size, ed));
12450 +static struct file_operations externfs_file_fops = {
12452 + .read = generic_file_read,
12453 + .write = generic_file_write,
12454 + .mmap = generic_file_mmap,
12455 + .open = externfs_file_open,
12457 + .fsync = externfs_fsync,
12460 +static struct file_operations externfs_dir_fops = {
12462 + .readdir = externfs_readdir,
12463 + .open = externfs_dir_open,
12464 + .release = externfs_dir_release,
12465 + .fsync = externfs_fsync,
12469 + struct page *page;
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;
12479 +static void externfs_finish_writepage(char *buffer, int res, void *arg)
12481 + struct wp_info *wp = arg;
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);
12489 + SetPageError(wp->page);
12490 + ClearPageUptodate(wp->page);
12493 + kunmap(wp->page);
12494 + unlock_page(wp->page);
12498 +static int externfs_writepage(struct page *page)
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;
12506 + unsigned long long base;
12507 + int count = PAGE_CACHE_SIZE;
12508 + int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
12511 + base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
12513 + /* If we are entirely outside the file, then return an error */
12515 + offset = inode->i_size & (PAGE_CACHE_SIZE-1);
12516 + if (page->index > end_index ||
12517 + ((page->index == end_index) && !offset))
12521 + wp = kmalloc(sizeof(*wp), GFP_KERNEL);
12525 + *wp = ((struct wp_info) { .page = page,
12528 + .size = inode->i_size,
12529 + .truncate = ops->truncate_file,
12530 + .ei = EXTERNFS_I(inode),
12533 + buffer = kmap(page);
12534 + err = (*ops->write_file)(EXTERNFS_I(inode), base, buffer, 0,
12535 + count, externfs_finish_writepage, wp, ed);
12540 + unlock_page(page);
12544 +static void externfs_finish_readpage(char *buffer, int res, void *arg)
12546 + struct page *page = arg;
12547 + struct inode *inode;
12550 + SetPageError(page);
12554 + inode = page->mapping->host;
12555 + if(inode->i_size >> PAGE_CACHE_SHIFT == page->index)
12556 + res = inode->i_size % PAGE_CACHE_SIZE;
12558 + memset(&buffer[res], 0, PAGE_CACHE_SIZE - res);
12560 + flush_dcache_page(page);
12561 + SetPageUptodate(page);
12562 + if (PageError(page))
12563 + ClearPageError(page);
12566 + unlock_page(page);
12569 +static int externfs_readpage(struct file *file, struct page *page)
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;
12578 + start = (long long) page->index << PAGE_CACHE_SHIFT;
12579 + buffer = kmap(page);
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,
12587 + err = PAGE_CACHE_SIZE;
12589 + else err = (*ops->read_file)(file_externfs_i(file), start, buffer,
12590 + PAGE_CACHE_SIZE, 0, 0,
12591 + externfs_finish_readpage, page, ed);
12598 +struct writepage_info {
12599 + struct semaphore sem;
12603 +static void externfs_finish_prepare(char *buffer, int res, void *arg)
12605 + struct writepage_info *wp = arg;
12611 +int externfs_prepare_write(struct file *file, struct page *page,
12612 + unsigned int from, unsigned int to)
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;
12621 + struct writepage_info wp;
12623 + if(Page_Uptodate(page))
12626 + start = (long long) page->index << PAGE_CACHE_SHIFT;
12627 + buffer = kmap(page);
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,
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);
12649 + memset(buffer, 0, from);
12650 + if(to < PAGE_CACHE_SIZE)
12651 + memset(buffer + to, 0, PAGE_CACHE_SIZE - to);
12653 + SetPageUptodate(page);
12660 +static int externfs_commit_write(struct file *file, struct page *page,
12661 + unsigned from, unsigned to)
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;
12670 + start = (long long) (page->index << PAGE_CACHE_SHIFT);
12672 + if(ops->map_file_page != NULL)
12675 + size = start + to;
12676 + if(size > inode->i_size){
12677 + inode->i_size = size;
12678 + mark_inode_dirty(inode);
12682 + set_page_dirty(page);
12683 + return(to - from);
12686 +static void externfs_removepage(struct page *page)
12688 + physmem_remove_mapping(page_address(page));
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
12700 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
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;
12710 + name = dentry_name(dentry, 0);
12713 + type = (*ed->file_ops->file_type)(name, &rdev, ed);
12715 + else type = OS_TYPE_DIR;
12717 + inode = new_inode(sb);
12718 + if(inode == NULL)
12721 + insert_inode_hash(inode);
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;
12729 + if(type == OS_TYPE_DIR) inode->i_fop = &externfs_dir_fops;
12730 + else inode->i_fop = &externfs_file_fops;
12732 + if(type == OS_TYPE_SYMLINK)
12733 + inode->i_mapping->a_ops = &externfs_link_aops;
12734 + else inode->i_mapping->a_ops = &externfs_aops;
12737 + case OS_TYPE_CHARDEV:
12738 + init_special_inode(inode, S_IFCHR, rdev);
12740 + case OS_TYPE_BLOCKDEV:
12741 + init_special_inode(inode, S_IFBLK, rdev);
12743 + case OS_TYPE_FIFO:
12744 + init_special_inode(inode, S_IFIFO, 0);
12746 + case OS_TYPE_SOCK:
12747 + init_special_inode(inode, S_IFSOCK, 0);
12749 + case OS_TYPE_SYMLINK:
12750 + inode->i_mode = S_IFLNK | S_IRWXUGO;
12754 + struct externfs_inode *ei;
12757 + ei = (*ops->init_file)(ed);
12761 + *ei = ((struct externfs_inode) { .ops = ed->file_ops });
12762 + inode->u.generic_ip = ei;
12764 + err = (*ed->file_ops->open_file)(ei, name, current->fsuid,
12765 + current->fsgid, inode, ed);
12766 + if(err && ((err != -ENOENT) && (err != -EISDIR)))
12777 + return(ERR_PTR(err));
12780 +int externfs_create(struct inode *dir, struct dentry *dentry, int mode)
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;
12787 + int err = -ENOMEM;
12789 + name = dentry_name(dentry, 0);
12793 + inode = get_inode(dir->i_sb, dentry, 0);
12794 + if(IS_ERR(inode)){
12795 + err = PTR_ERR(inode);
12799 + ei = (*ed->mount_ops->init_file)(ed);
12801 + /* XXX need a free_file() */
12804 + *ei = ((struct externfs_inode) { .ops = ed->file_ops });
12805 + inode->u.generic_ip = ei;
12807 + err = (*ops->create_file)(ei, name, mode, current->fsuid,
12808 + current->fsuid, inode, ed);
12812 + err = read_name(inode, name);
12816 + inode->i_nlink++;
12817 + d_instantiate(dentry, inode);
12824 + (*ops->unlink_file)(name, ed);
12826 + inode->i_nlink = 0;
12831 +struct dentry *externfs_lookup(struct inode *ino, struct dentry *dentry)
12833 + struct inode *inode;
12837 + inode = get_inode(ino->i_sb, dentry, 1);
12838 + if(IS_ERR(inode)){
12839 + err = PTR_ERR(inode);
12844 + name = dentry_name(dentry, 0);
12848 + err = read_name(inode, name);
12851 + if(err != -ENOENT)
12854 + inode->i_nlink = 0;
12858 + d_add(dentry, inode);
12859 + dentry->d_op = &externfs_dentry_ops;
12863 + inode->i_nlink = 0;
12866 + return(ERR_PTR(err));
12869 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
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';
12883 +int externfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
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;
12890 + from_name = inode_dentry_name(ino, from);
12891 + if(from_name == NULL)
12894 + to_name = dentry_name(to, 0);
12895 + if(to_name == NULL)
12896 + goto out_free_from;
12898 + err = (*ops->link_file)(to_name, from_name, current->fsuid,
12899 + current->fsgid, ed);
12901 + goto out_free_to;
12903 + d_instantiate(from, to->d_inode);
12904 + to->d_inode->i_nlink++;
12905 + atomic_inc(&to->d_inode->i_count);
12910 + kfree(from_name);
12915 +int externfs_unlink(struct inode *ino, struct dentry *dentry)
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;
12923 + file = inode_dentry_name(ino, dentry);
12927 + inode = dentry->d_inode;
12928 + if((inode->i_nlink == 1) && (ops->invisible != NULL))
12929 + (*ops->invisible)(EXTERNFS_I(inode));
12931 + err = (*ops->unlink_file)(file, ed);
12934 + inode->i_nlink--;
12939 +int externfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
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;
12947 + file = inode_dentry_name(ino, dentry);
12950 + err = (*ops->make_symlink)(file, to, current->fsuid, current->fsgid,
12954 + inode = get_inode(ino->i_sb, dentry, 1);
12955 + if(IS_ERR(inode)){
12956 + err = PTR_ERR(inode);
12960 + d_instantiate(dentry, inode);
12961 + inode->i_nlink++;
12967 +int externfs_make_dir(struct inode *ino, struct dentry *dentry, int mode)
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;
12975 + file = inode_dentry_name(ino, dentry);
12978 + err = (*ops->make_dir)(file, mode, current->fsuid, current->fsgid, ed);
12980 + inode = get_inode(ino->i_sb, dentry, 1);
12981 + if(IS_ERR(inode)){
12982 + err = PTR_ERR(inode);
12986 + err = read_name(inode, file);
12991 + d_instantiate(dentry, inode);
12992 + inode->i_nlink = 2;
12993 + inode->i_mode = S_IFDIR | mode;
13002 + inode->i_nlink = 0;
13007 +int externfs_remove_dir(struct inode *ino, struct dentry *dentry)
13009 + struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
13010 + void *mount = ino->i_sb->u.generic_sbp;
13014 + file = inode_dentry_name(ino, dentry);
13017 + err = (*ops->remove_dir)(file, current->fsuid, current->fsgid, mount);
13020 + dentry->d_inode->i_nlink = 0;
13025 +int externfs_make_node(struct inode *dir, struct dentry *dentry, int mode,
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;
13032 + int err = -ENOMEM;
13034 + name = dentry_name(dentry, 0);
13038 + inode = get_inode(dir->i_sb, dentry, 1);
13039 + if(IS_ERR(inode)){
13040 + err = PTR_ERR(inode);
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),
13051 + err = read_name(inode, name);
13055 + d_instantiate(dentry, inode);
13062 + (*ops->unlink_file)(name, ed);
13064 + inode->i_nlink = 0;
13069 +int externfs_rename(struct inode *from_ino, struct dentry *from,
13070 + struct inode *to_ino, struct dentry *to)
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;
13077 + from_name = inode_dentry_name(from_ino, from);
13078 + if(from_name == NULL)
13080 + to_name = inode_dentry_name(to_ino, to);
13081 + if(to_name == NULL){
13082 + kfree(from_name);
13085 + err = (*ops->rename_file)(from_name, to_name, ed);
13086 + kfree(from_name);
13089 + from_ino->i_nlink--;
13090 + to_ino->i_nlink++;
13094 +void externfs_truncate(struct inode *ino)
13096 + struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
13097 + struct externfs_data *ed = ino->i_sb->u.generic_sbp;
13099 + (*ops->truncate_file)(EXTERNFS_I(ino), ino->i_size, ed);
13102 +int externfs_permission(struct inode *ino, int desired)
13104 + struct externfs_file_ops *ops = EXTERNFS_I(ino)->ops;
13105 + struct externfs_data *ed = ino->i_sb->u.generic_sbp;
13107 + int r = 0, w = 0, x = 0, err;
13109 + if(ops->access_file == NULL)
13110 + return(vfs_permission(ino, desired));
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);
13119 + err = (*ops->access_file)(name, r, w, x, current->fsuid,
13120 + current->fsgid, ed);
13124 + err = vfs_permission(ino, desired);
13128 +int externfs_setattr(struct dentry *dentry, struct iattr *attr)
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;
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;
13141 + if(attr->ia_valid & ATTR_UID){
13142 + attrs.ia_valid |= EXTERNFS_ATTR_UID;
13143 + attrs.ia_uid = attr->ia_uid;
13145 + if(attr->ia_valid & ATTR_GID){
13146 + attrs.ia_valid |= EXTERNFS_ATTR_GID;
13147 + attrs.ia_gid = attr->ia_gid;
13149 + if(attr->ia_valid & ATTR_SIZE){
13150 + attrs.ia_valid |= EXTERNFS_ATTR_SIZE;
13151 + attrs.ia_size = attr->ia_size;
13153 + if(attr->ia_valid & ATTR_ATIME){
13154 + attrs.ia_valid |= EXTERNFS_ATTR_ATIME;
13155 + attrs.ia_atime = attr->ia_atime;
13157 + if(attr->ia_valid & ATTR_MTIME){
13158 + attrs.ia_valid |= EXTERNFS_ATTR_MTIME;
13159 + attrs.ia_mtime = attr->ia_mtime;
13161 + if(attr->ia_valid & ATTR_CTIME){
13162 + attrs.ia_valid |= EXTERNFS_ATTR_CTIME;
13163 + attrs.ia_ctime = attr->ia_ctime;
13165 + if(attr->ia_valid & ATTR_ATIME_SET){
13166 + attrs.ia_valid |= EXTERNFS_ATTR_ATIME_SET;
13168 + if(attr->ia_valid & ATTR_MTIME_SET){
13169 + attrs.ia_valid |= EXTERNFS_ATTR_MTIME_SET;
13171 + name = dentry_name(dentry, 0);
13174 + err = (*ops->set_attr)(name, &attrs, ed);
13179 + return(inode_setattr(dentry->d_inode, attr));
13182 +int externfs_getattr(struct dentry *dentry, struct iattr *attr)
13184 + not_implemented();
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,
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,
13219 +int externfs_link_readpage(struct file *file, struct page *page)
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;
13228 + start = page->index << PAGE_CACHE_SHIFT;
13229 + buffer = kmap(page);
13230 + name = inode_name(ino, 0);
13234 + err = (*ops->read_link)(name, current->fsuid, current->fsgid, buffer,
13235 + PAGE_CACHE_SIZE, ed);
13238 + if(err == PAGE_CACHE_SIZE)
13240 + else if(err > 0){
13241 + flush_dcache_page(page);
13242 + SetPageUptodate(page);
13243 + if (PageError(page)) ClearPageError(page);
13247 + UnlockPage(page);
13251 +static int externfs_flushpage(struct page *page, unsigned long offset)
13253 + return(externfs_writepage(page));
13256 +struct externfs_data *inode_externfs_info(struct inode *inode)
13258 + return(inode->i_sb->u.generic_sbp);
13261 +static struct address_space_operations externfs_link_aops = {
13262 + .readpage = externfs_link_readpage,
13263 + .removepage = externfs_removepage,
13264 + .flushpage = externfs_flushpage,
13267 +DECLARE_MUTEX(externfs_sem);
13268 +struct list_head externfses = LIST_HEAD_INIT(externfses);
13270 +static struct externfs *find_externfs(struct file_system_type *type)
13272 + struct list_head *ele;
13273 + struct externfs *fs;
13275 + down(&externfs_sem);
13276 + list_for_each(ele, &externfses){
13277 + fs = list_entry(ele, struct externfs, list);
13278 + if(&fs->type == type)
13283 + up(&externfs_sem);
13287 +#define DEFAULT_ROOT "/"
13289 +char *host_root_filename(char *mount_arg)
13291 + char *root = DEFAULT_ROOT;
13293 + if((mount_arg != NULL) && (*mount_arg != '\0'))
13294 + root = mount_arg;
13296 + return(uml_strdup(root));
13299 +struct super_block *externfs_read_super(struct super_block *sb, void *data,
13302 + struct externfs *fs;
13303 + struct inode *root_inode;
13304 + struct externfs_data *sb_data;
13305 + int err = -EINVAL;
13307 + sb->s_blocksize = 1024;
13308 + sb->s_blocksize_bits = 10;
13309 + sb->s_magic = EXTERNFS_SUPER_MAGIC;
13310 + sb->s_op = &externfs_sbops;
13312 + fs = find_externfs(sb->s_type);
13314 + printk("Couldn't find externfs for filesystem '%s'\n",
13315 + sb->s_type->name);
13319 + sb_data = (*fs->mount_ops->mount)(data);
13320 + if(IS_ERR(sb_data)){
13321 + err = PTR_ERR(sb_data);
13325 + sb->u.generic_sbp = sb_data;
13326 + sb_data->mount_ops = fs->mount_ops;
13328 + root_inode = get_inode(sb, NULL, 1);
13329 + if(IS_ERR(root_inode))
13332 + sb->s_root = d_alloc_root(root_inode);
13333 + if(sb->s_root == NULL)
13336 + if(read_inode(root_inode))
13341 + /* dput frees the inode */
13342 + dput(sb->s_root);
13345 + root_inode->i_nlink = 0;
13346 + make_bad_inode(root_inode);
13347 + iput(root_inode);
13352 +void init_externfs(struct externfs_data *ed, struct externfs_file_ops *ops)
13354 + ed->file_ops = ops;
13357 +int register_externfs(char *name, struct externfs_mount_ops *mount_ops)
13359 + struct externfs *new;
13360 + int err = -ENOMEM;
13362 + new = kmalloc(sizeof(*new), GFP_KERNEL);
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,
13372 + .owner = THIS_MODULE } });
13373 + list_add(&new->list, &externfses);
13375 + err = register_filesystem(&new->type);
13381 + list_del(&new->list);
13387 +void unregister_externfs(char *name)
13389 + struct list_head *ele;
13390 + struct externfs *fs;
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)){
13397 + up(&externfs_sem);
13401 + up(&externfs_sem);
13402 + printk("Unregister_externfs - filesystem '%s' not found\n", name);
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
13410 + * ---------------------------------------------------------------------------
13411 + * Local variables:
13412 + * c-file-style: "linux"
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
13421 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
13422 + * Licensed under the GPL
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"
13434 +extern int append;
13436 +char *get_path(const char *path[], char *buf, int size)
13442 + for(s = path; *s != NULL; s++){
13443 + new += strlen(*s);
13444 + if((*(s + 1) != NULL) && (strlen(*s) > 0) &&
13445 + ((*s)[strlen(*s) - 1] != '/'))
13450 + buf = kmalloc(new, GFP_KERNEL);
13456 + for(s = path; *s != NULL; s++){
13459 + if((*(s + 1) != NULL) && (strlen(*s) > 0) &&
13460 + ((*s)[strlen(*s) - 1] != '/'))
13461 + strcpy(p++, "/");
13467 +void free_path(const char *buf, char *tmp)
13469 + if((buf != tmp) && (buf != NULL))
13470 + kfree((char *) buf);
13473 +int host_open_file(const char *path[], int r, int w, struct file_handle *fh)
13475 + char tmp[HOSTFS_BUFSIZE], *file;
13476 + int mode = 0, err;
13477 + struct openflags flags = OPENFLAGS();
13480 + flags = of_read(flags);
13482 + flags = of_write(flags);
13484 + flags = of_append(flags);
13487 + file = get_path(path, tmp, sizeof(tmp));
13491 + err = open_filehandle(file, flags, mode, fh);
13493 + free_path(file, tmp);
13497 +void *host_open_dir(const char *path[])
13499 + char tmp[HOSTFS_BUFSIZE], *file;
13500 + void *dir = ERR_PTR(-ENOMEM);
13502 + file = get_path(path, tmp, sizeof(tmp));
13506 + dir = open_dir(file);
13508 + free_path(file, tmp);
13512 +char *host_read_dir(void *stream, unsigned long long *pos,
13513 + unsigned long long *ino_out, int *len_out)
13518 + err = os_seek_dir(stream, *pos);
13520 + return(ERR_PTR(err));
13522 + err = os_read_dir(stream, ino_out, &name);
13524 + return(ERR_PTR(err));
13529 + *len_out = strlen(name);
13530 + *pos = os_tell_dir(stream);
13534 +int host_file_type(const char *path[], int *rdev)
13536 + char tmp[HOSTFS_BUFSIZE], *file;
13537 + struct uml_stat buf;
13541 + file = get_path(path, tmp, sizeof(tmp));
13545 + if(rdev != NULL){
13546 + ret = os_lstat_file(file, &buf);
13549 + *rdev = MKDEV(buf.ust_rmajor, buf.ust_rminor);
13552 + ret = os_file_type(file);
13554 + free_path(file, tmp);
13558 +int host_create_file(const char *path[], int mode, struct file_handle *fh)
13560 + char tmp[HOSTFS_BUFSIZE], *file;
13561 + int err = -ENOMEM;
13563 + file = get_path(path, tmp, sizeof(tmp));
13567 + err = open_filehandle(file, of_create(of_rdwr(OPENFLAGS())), mode, fh);
13569 + free_path(file, tmp);
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)
13580 + struct uml_stat buf;
13583 + err = os_lstat_file(path, &buf);
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;
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)
13610 + char tmp[HOSTFS_BUFSIZE], *file;
13614 + file = get_path(path, tmp, sizeof(tmp));
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);
13622 + free_path(file, tmp);
13626 +int host_set_attr(const char *path[], struct externfs_iattr *attrs)
13628 + char tmp[HOSTFS_BUFSIZE], *file;
13629 + unsigned long time;
13632 + if(append && (attrs->ia_valid & EXTERNFS_ATTR_SIZE))
13636 + file = get_path(path, tmp, sizeof(tmp));
13640 + if(attrs->ia_valid & EXTERNFS_ATTR_MODE){
13641 + err = os_set_file_perms(file, attrs->ia_mode);
13645 + if(attrs->ia_valid & EXTERNFS_ATTR_UID){
13646 + err = os_set_file_owner(file, attrs->ia_uid, -1);
13650 + if(attrs->ia_valid & EXTERNFS_ATTR_GID){
13651 + err = os_set_file_owner(file, -1, attrs->ia_gid);
13655 + if(attrs->ia_valid & EXTERNFS_ATTR_SIZE){
13656 + err = os_truncate_file(file, attrs->ia_size);
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);
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);
13674 + err = os_set_file_time(file, attrs->ia_atime, time);
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);
13685 + err = os_set_file_time(file, time, attrs->ia_mtime);
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);
13701 + free_path(file, tmp);
13705 +int host_make_symlink(const char *from[], const char *to)
13707 + char tmp[HOSTFS_BUFSIZE], *file;
13708 + int err = -ENOMEM;
13710 + file = get_path(from, tmp, sizeof(tmp));
13714 + err = os_make_symlink(to, file);
13716 + free_path(file, tmp);
13720 +int host_unlink_file(const char *path[])
13722 + char tmp[HOSTFS_BUFSIZE], *file;
13723 + int err = -ENOMEM;
13728 + file = get_path(path, tmp, sizeof(tmp));
13732 + err = os_remove_file(file);
13734 + free_path(file, tmp);
13738 +int host_make_dir(const char *path[], int mode)
13740 + char tmp[HOSTFS_BUFSIZE], *file;
13741 + int err = -ENOMEM;
13743 + file = get_path(path, tmp, sizeof(tmp));
13747 + err = os_make_dir(file, mode);
13749 + free_path(file, tmp);
13753 +int host_remove_dir(const char *path[])
13755 + char tmp[HOSTFS_BUFSIZE], *file;
13756 + int err = -ENOMEM;
13758 + file = get_path(path, tmp, sizeof(tmp));
13762 + err = os_remove_dir(file);
13764 + free_path(file, tmp);
13768 +int host_link_file(const char *to[], const char *from[])
13770 + char from_tmp[HOSTFS_BUFSIZE], *f, to_tmp[HOSTFS_BUFSIZE], *t;
13771 + int err = -ENOMEM;
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))
13778 + err = os_link_file(t, f);
13780 + free_path(f, from_tmp);
13781 + free_path(t, to_tmp);
13785 +int host_read_link(const char *path[], char *buf, int size)
13787 + char tmp[HOSTFS_BUFSIZE], *file;
13790 + file = get_path(path, tmp, sizeof(tmp));
13794 + n = os_read_symlink(file, buf, size);
13798 + free_path(file, tmp);
13802 +int host_rename_file(const char *from[], const char *to[])
13804 + char from_tmp[HOSTFS_BUFSIZE], *f, to_tmp[HOSTFS_BUFSIZE], *t;
13805 + int err = -ENOMEM;
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))
13812 + err = os_move_file(f, t);
13814 + free_path(f, from_tmp);
13815 + free_path(t, to_tmp);
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)
13824 + char tmp[HOSTFS_BUFSIZE], *file;
13825 + int err = -ENOMEM;
13827 + file = get_path(path, tmp, sizeof(tmp));
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);
13835 + free_path(file, tmp);
13839 +char *generic_host_read_dir(void *stream, unsigned long long *pos,
13840 + unsigned long long *ino_out, int *len_out,
13843 + return(host_read_dir(stream, pos, ino_out, len_out));
13846 +int generic_host_truncate_file(struct file_handle *fh, __u64 size, void *m)
13848 + return(truncate_file(fh, size));
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
13856 + * ---------------------------------------------------------------------------
13857 + * Local variables:
13858 + * c-file-style: "linux"
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
13867 + * Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com)
13868 + * Licensed under the GPL
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"
13882 +#include "kern_util.h"
13883 +#include "filehandle.h"
13886 +/* Changed in hostfs_args before the kernel starts running */
13887 +static char *jail_dir = "/";
13890 +static int __init hostfs_args(char *options, int *add)
13894 + ptr = strchr(options, ',');
13897 + if(*options != '\0')
13898 + jail_dir = options;
13902 + ptr = strchr(options, ',');
13905 + if(*options != '\0'){
13906 + if(!strcmp(options, "append"))
13908 + else printf("hostfs_args - unsupported option - %s\n",
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"
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"
13927 +struct hostfs_data {
13928 + struct externfs_data ext;
13932 +struct hostfs_file {
13933 + struct externfs_inode ext;
13934 + struct file_handle fh;
13937 +static int hostfs_access_file(char *file, int r, int w, int x, int uid,
13938 + int gid, struct externfs_data *ed)
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;
13945 + if(r) mode = OS_ACC_R_OK;
13946 + if(w) mode |= OS_ACC_W_OK;
13947 + if(x) mode |= OS_ACC_X_OK;
13950 + file = get_path(path, tmp, sizeof(tmp));
13954 + err = os_access(file, mode);
13955 + free_path(file, tmp);
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)
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;
13969 + file = get_path(path, tmp, sizeof(tmp));
13973 + /* XXX Pass type in an OS-independent way */
13976 + err = os_make_dev(file, mode, major, minor);
13977 + free_path(file, tmp);
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)
13990 + char *mount = container_of(ed, struct hostfs_data, ext)->mount;
13991 + const char *path[] = { jail_dir, mount, file, NULL };
13993 + /* XXX Why pretend everything is owned by root? */
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));
14001 +static int hostfs_file_type(const char *file, int *rdev,
14002 + struct externfs_data *ed)
14004 + char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14005 + const char *path[] = { jail_dir, mount, file, NULL };
14007 + return(host_file_type(path, rdev));
14010 +static char *hostfs_name(struct inode *inode)
14012 + struct externfs_data *ed = inode_externfs_info(inode);
14013 + char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14015 + return(inode_name_prefix(inode, mount));
14018 +static struct externfs_inode *hostfs_init_file(struct externfs_data *ed)
14020 + struct hostfs_file *hf;
14022 + hf = kmalloc(sizeof(*hf), GFP_KERNEL);
14027 + return(&hf->ext);
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)
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 };
14039 + err = host_open_file(path, 1, 1, &hf->fh);
14040 + if(err == -EISDIR)
14043 + if(err == -EACCES)
14044 + err = host_open_file(path, 1, 0, &hf->fh);
14049 + is_reclaimable(&hf->fh, hostfs_name, inode);
14054 +static void *hostfs_open_dir(char *file, int uid, int gid,
14055 + struct externfs_data *ed)
14057 + char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14058 + const char *path[] = { jail_dir, mount, file, NULL };
14060 + return(host_open_dir(path));
14063 +static void hostfs_close_dir(void *stream, struct externfs_data *ed)
14065 + os_close_dir(stream);
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)
14072 + char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14074 + return(generic_host_read_dir(stream, pos, ino_out, len_out, mount));
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)
14083 + struct hostfs_file *hf = container_of(ext, struct hostfs_file, ext);
14086 + if(ignore_start != 0){
14087 + err = read_file(&hf->fh, offset, buf, ignore_start);
14092 + if(ignore_end != len)
14093 + err = read_file(&hf->fh, offset + ignore_end, buf + ignore_end,
14094 + len - ignore_end);
14098 + (*completion)(buf, err, arg);
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)
14110 + struct file_handle *fh;
14113 + fh = &container_of(ext, struct hostfs_file, ext)->fh;
14114 + err = write_file(fh, offset + start, buf + start, len);
14116 + (*completion)((char *) buf, err, arg);
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)
14127 + struct hostfs_file *hf = container_of(ext, struct hostfs_file,
14129 + char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14130 + const char *path[] = { jail_dir, mount, file, NULL };
14131 + int err = -ENOMEM;
14133 + err = host_create_file(path, mode, &hf->fh);
14137 + is_reclaimable(&hf->fh, hostfs_name, inode);
14142 +static int hostfs_set_attr(const char *file, struct externfs_iattr *attrs,
14143 + struct externfs_data *ed)
14145 + char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14146 + const char *path[] = { jail_dir, mount, file, NULL };
14148 + return(host_set_attr(path, attrs));
14151 +static int hostfs_make_symlink(const char *from, const char *to, int uid,
14152 + int gid, struct externfs_data *ed)
14154 + char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14155 + const char *path[] = { jail_dir, mount, from, NULL };
14157 + return(host_make_symlink(path, to));
14160 +static int hostfs_link_file(const char *to, const char *from, int uid, int gid,
14161 + struct externfs_data *ed)
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 };
14167 + return(host_link_file(to_path, from_path));
14170 +static int hostfs_unlink_file(const char *file, struct externfs_data *ed)
14172 + char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14173 + const char *path[] = { jail_dir, mount, file, NULL };
14175 + return(host_unlink_file(path));
14178 +static int hostfs_make_dir(const char *file, int mode, int uid, int gid,
14179 + struct externfs_data *ed)
14181 + char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14182 + const char *path[] = { jail_dir, mount, file, NULL };
14184 + return(host_make_dir(path, mode));
14187 +static int hostfs_remove_dir(const char *file, int uid, int gid,
14188 + struct externfs_data *ed)
14190 + char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14191 + const char *path[] = { jail_dir, mount, file, NULL };
14193 + return(host_remove_dir(path));
14196 +static int hostfs_read_link(char *file, int uid, int gid, char *buf, int size,
14197 + struct externfs_data *ed)
14199 + char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14200 + const char *path[] = { jail_dir, mount, file, NULL };
14202 + return(host_read_link(path, buf, size));
14205 +static int hostfs_rename_file(char *from, char *to, struct externfs_data *ed)
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 };
14211 + return(host_rename_file(from_path, to_path));
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)
14220 + char *mount = container_of(ed, struct hostfs_data, ext)->mount;
14221 + const char *path[] = { jail_dir, mount, NULL };
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));
14228 +static void hostfs_close_file(struct externfs_inode *ext,
14229 + unsigned long long size)
14231 + struct hostfs_file *hf = container_of(ext, struct hostfs_file, ext);
14233 + if(hf->fh.fd == -1)
14236 + truncate_file(&hf->fh, size);
14237 + close_file(&hf->fh);
14240 +static int hostfs_truncate_file(struct externfs_inode *ext, __u64 size,
14241 + struct externfs_data *ed)
14243 + struct hostfs_file *hf = container_of(ext, struct hostfs_file, ext);
14245 + return(truncate_file(&hf->fh, size));
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
14275 +static struct externfs_data *mount_fs(char *mount_arg)
14277 + struct hostfs_data *hd;
14278 + int err = -ENOMEM;
14280 + hd = kmalloc(sizeof(*hd), GFP_KERNEL);
14284 + hd->mount = host_root_filename(mount_arg);
14285 + if(hd->mount == NULL)
14288 + init_externfs(&hd->ext, &hostfs_file_ops);
14290 + return(&hd->ext);
14294 + return(ERR_PTR(err));
14297 +static struct externfs_mount_ops hostfs_mount_ops = {
14298 + .init_file = hostfs_init_file,
14299 + .mount = mount_fs,
14302 +static int __init init_hostfs(void)
14304 + return(register_externfs("hostfs", &hostfs_mount_ops));
14307 +static void __exit exit_hostfs(void)
14309 + unregister_externfs("hostfs");
14312 +__initcall(init_hostfs);
14313 +__exitcall(exit_hostfs);
14316 +module_init(init_hostfs)
14317 +module_exit(exit_hostfs)
14318 +MODULE_LICENSE("GPL");
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
14326 + * ---------------------------------------------------------------------------
14327 + * Local variables:
14328 + * c-file-style: "linux"
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
14337 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
14338 + * Licensed under the GPL
14341 +#ifndef __UM_FS_HOSTFS
14342 +#define __UM_FS_HOSTFS
14344 +#include "linux/fs.h"
14345 +#include "linux/blkdev.h"
14346 +#include "filehandle.h"
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.
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
14366 + * container_of - cast a member of a structure out to the containing structure
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.
14373 +#define container_of(ptr, type, member) ({ \
14374 + const typeof( ((type *)0)->member ) *__mptr = (ptr); \
14375 + (type *)( (char *)__mptr - offsetof(type,member) );})
14377 +struct externfs_iattr {
14378 + unsigned int ia_valid;
14386 + unsigned int ia_attr_flags;
14389 +struct externfs_data {
14390 + struct externfs_file_ops *file_ops;
14391 + struct externfs_mount_ops *mount_ops;
14394 +struct externfs_inode {
14395 + struct externfs_file_ops *ops;
14398 +struct externfs_mount_ops {
14399 + struct externfs_data *(*mount)(char *mount_arg);
14400 + struct externfs_inode *(*init_file)(struct externfs_data *ed);
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);
14468 +#define HOSTFS_BUFSIZE 64
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);
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,
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);
14512 +extern char *generic_host_read_dir(void *stream, unsigned long long *pos,
14513 + unsigned long long *ino_out, int *len_out,
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,
14519 +extern int generic_host_truncate_file(struct file_handle *fh, __u64 size,
14522 +extern char *inode_name_prefix(struct inode *inode, char *prefix);
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
14531 + * ---------------------------------------------------------------------------
14532 + * Local variables:
14533 + * c-file-style: "linux"
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
14542 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
14543 + * Licensed under the GPL
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"
14562 +#include "irq_user.h"
14563 +#include "irq_kern.h"
14564 +#include "filehandle.h"
14565 +#include "metadata.h"
14567 +#define HUMFS_VERSION 2
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)
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;
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);
14588 + err = (*mount->meta->ownerships)(path, &perms, uid_out, gid_out,
14589 + &type, &major, &minor, mount);
14593 + *mode_out = (*mode_out & ~S_IRWXUGO) | perms;
14611 + *mode_out = (*mode_out & ~S_IFMT) | mode;
14616 +static int meta_type(const char *path, int *dev_out, void *m)
14618 + struct humfs *mount = m;
14619 + int err, type, maj, min;
14622 + err = (*mount->meta->ownerships)(path, NULL, NULL, NULL, &c, &maj,
14631 + *dev_out = MKDEV(maj, min);
14635 + type = OS_TYPE_CHARDEV;
14638 + type = OS_TYPE_BLOCKDEV;
14641 + type = OS_TYPE_FIFO;
14644 + type = OS_TYPE_SOCK;
14654 +static int humfs_file_type(const char *path, int *dev_out,
14655 + struct externfs_data *ed)
14657 + struct humfs *mount = container_of(ed, struct humfs, ext);
14658 + const char *data_path[3] = { mount->data, path, NULL };
14661 + type = meta_type(path, dev_out, mount);
14665 + return(host_file_type(data_path, dev_out));
14668 +static char *humfs_data_name(struct inode *inode)
14670 + struct externfs_data *ed = inode_externfs_info(inode);
14671 + struct humfs *mount = container_of(ed, struct humfs, ext);
14673 + return(inode_name_prefix(inode, mount->data));
14676 +static struct externfs_inode *humfs_init_file(struct externfs_data *ed)
14678 + struct humfs *mount = container_of(ed, struct humfs, ext);
14679 + struct humfs_file *hf;
14681 + hf = (*mount->meta->init_file)();
14683 + return((struct externfs_inode *) hf);
14685 + hf->data.fd = -1;
14686 + return(&hf->ext);
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)
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;
14700 + file = get_path(data_path, tmp, sizeof(tmp));
14704 + flags = of_rdwr(OPENFLAGS());
14705 + if(mount->direct)
14706 + flags = of_direct(flags);
14710 + err = (*mount->meta->open_file)(hf, path, inode, mount);
14714 + err = open_filehandle(file, flags, 0, &hf->data);
14715 + if(err == -EISDIR)
14717 + else if(err == -EPERM){
14718 + flags = of_set_rw(flags, 1, 0);
14719 + err = open_filehandle(file, flags, 0, &hf->data);
14725 + hf->mount = mount;
14726 + is_reclaimable(&hf->data, humfs_data_name, inode);
14729 + free_path(file, tmp);
14734 + (*mount->meta->close_file)(hf);
14738 +static void *humfs_open_dir(char *path, int uid, int gid,
14739 + struct externfs_data *ed)
14741 + struct humfs *mount = container_of(ed, struct humfs, ext);
14742 + const char *data_path[3] = { mount->data, path, NULL };
14744 + return(host_open_dir(data_path));
14747 +static void humfs_close_dir(void *stream, struct externfs_data *ed)
14749 + os_close_dir(stream);
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)
14756 + struct humfs *mount = container_of(ed, struct humfs, ext);
14758 + return(generic_host_read_dir(stream, pos, ino_out, len_out, mount));
14761 +LIST_HEAD(humfs_replies);
14763 +struct humfs_aio {
14764 + struct aio_context aio;
14765 + struct list_head list;
14766 + void (*completion)(char *, int, void *);
14773 +static int humfs_reply_fd = -1;
14775 +struct humfs_aio last_task_aio, last_intr_aio;
14776 +struct humfs_aio *last_task_aio_ptr, *last_intr_aio_ptr;
14778 +void humfs_task_proc(void *unused)
14780 + struct humfs_aio *aio;
14781 + unsigned long flags;
14783 + while(!list_empty(&humfs_replies)){
14784 + local_irq_save(flags);
14785 + aio = list_entry(humfs_replies.next, struct humfs_aio, list);
14787 + last_task_aio = *aio;
14788 + last_task_aio_ptr = aio;
14790 + list_del(&aio->list);
14791 + local_irq_restore(flags);
14793 + if(aio->err >= 0)
14794 + aio->err = aio->real_len;
14795 + (*aio->completion)(aio->buf, aio->err, aio->data);
14800 +struct tq_struct humfs_task = {
14801 + .routine = humfs_task_proc,
14805 +static void humfs_interrupt(int irq, void *dev_id, struct pt_regs *unused)
14807 + struct aio_thread_reply reply;
14808 + struct humfs_aio *aio;
14809 + int err, fd = (int) dev_id;
14812 + err = os_read_file(fd, &reply, sizeof(reply));
14814 + if(err == -EAGAIN)
14816 + printk("humfs_interrupt - read returned err %d\n",
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;
14827 + if(!list_empty(&humfs_replies))
14828 + schedule_task(&humfs_task);
14829 + reactivate_fd(fd, HUMFS_IRQ);
14832 +static int init_humfs_aio(void)
14836 + err = os_pipe(fds, 1, 1);
14838 + printk("init_humfs_aio - pipe failed, err = %d\n", -err);
14842 + err = um_request_irq(HUMFS_IRQ, fds[0], IRQ_READ, humfs_interrupt,
14843 + SA_INTERRUPT | SA_SAMPLE_RANDOM, "humfs",
14844 + (void *) fds[0]);
14846 + printk("init_humfs_aio - : um_request_irq failed, err = %d\n",
14851 + humfs_reply_fd = fds[1];
14855 + os_close_file(fds[0]);
14856 + os_close_file(fds[1]);
14861 +__initcall(init_humfs_aio);
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)
14867 + struct humfs_aio *aio;
14868 + int err = -ENOMEM;
14870 + aio = kmalloc(sizeof(*aio), GFP_KERNEL);
14873 + *aio = ((struct humfs_aio) { .aio = INIT_AIO_CONTEXT,
14874 + .list = LIST_HEAD_INIT(aio->list),
14875 + .completion= completion,
14878 + .real_len = real_len,
14881 + err = submit_aio(type, fd, buf, len, offset, humfs_reply_fd, aio);
14883 + (*completion)(buf, err, arg);
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)
14895 + struct humfs_file *hf = container_of(ext, struct humfs_file, ext);
14896 + int fd = filehandle_fd(&hf->data);
14899 + (*completion)(buf, fd, arg);
14903 + return(humfs_aio(AIO_READ, fd, offset, buf, len, len, completion,
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)
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);
14918 + (*completion)((char *) buf, fd, arg);
14922 + if(mount->direct)
14929 + err = humfs_aio(AIO_WRITE, fd, offset, (char *) buf, len, orig_len,
14930 + completion, arg);
14935 + if(mount->direct)
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)
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);
14952 + err = os_fd_size(fd, &size);
14956 + need = offset + PAGE_SIZE;
14958 + err = os_truncate_fd(fd, need);
14963 + return(physmem_subst_mapping(buf, fd, offset, w));
14966 +static void humfs_close_file(struct externfs_inode *ext,
14967 + unsigned long long size)
14969 + struct humfs_file *hf = container_of(ext, struct humfs_file, ext);
14972 + if(hf->data.fd == -1)
14975 + fd = filehandle_fd(&hf->data);
14976 + physmem_forget_descriptor(fd);
14977 + truncate_file(&hf->data, size);
14978 + close_file(&hf->data);
14980 + (*hf->mount->meta->close_file)(hf);
14983 +/* XXX Assumes that you can't make a normal file */
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)
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 };
14995 + err = host_create_file(data_path, S_IRWXUGO, &fh);
15016 + printk("humfs_make_node - bad node type : %d\n", type);
15020 + err = (*mount->meta->make_node)(path, mode, uid, gid, t, major, minor,
15029 + host_unlink_file(data_path);
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)
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 };
15042 + err = (*mount->meta->create_file)(hf, path, mode, uid, gid, inode,
15047 + err = host_create_file(data_path, S_IRWXUGO, &hf->data);
15052 + is_reclaimable(&hf->data, humfs_data_name, inode);
15057 + (*mount->meta->remove_file)(path, mount);
15058 + (*mount->meta->close_file)(hf);
15063 +static int humfs_set_attr(const char *path, struct externfs_iattr *attrs,
15064 + struct externfs_data *ed)
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 *);
15071 + chown = mount->meta->change_ownerships;
15072 + if(attrs->ia_valid & EXTERNFS_ATTR_MODE){
15073 + err = (*chown)(path, attrs->ia_mode, -1, -1, mount);
15077 + if(attrs->ia_valid & EXTERNFS_ATTR_UID){
15078 + err = (*chown)(path, -1, attrs->ia_uid, -1, mount);
15082 + if(attrs->ia_valid & EXTERNFS_ATTR_GID){
15083 + err = (*chown)(path, -1, -1, attrs->ia_gid, mount);
15088 + attrs->ia_valid &= ~(EXTERNFS_ATTR_MODE | EXTERNFS_ATTR_UID |
15089 + EXTERNFS_ATTR_GID);
15091 + return(host_set_attr(data_path, attrs));
15094 +static int humfs_make_symlink(const char *from, const char *to, int uid,
15095 + int gid, struct externfs_data *ed)
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;
15102 + hf = (*mount->meta->init_file)();
15106 + err = (*mount->meta->create_file)(hf, from, S_IRWXUGO, uid, gid, NULL,
15111 + err = host_make_symlink(data_path, to);
15113 + (*mount->meta->remove_file)(from, mount);
15116 + (*mount->meta->close_file)(hf);
15121 +static int humfs_link_file(const char *to, const char *from, int uid, int gid,
15122 + struct externfs_data *ed)
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 };
15129 + err = (*mount->meta->create_link)(to, from, mount);
15133 + err = host_link_file(data_path_to, data_path_from);
15135 + (*mount->meta->remove_file)(from, mount);
15140 +static int humfs_unlink_file(const char *path, struct externfs_data *ed)
15142 + struct humfs *mount = container_of(ed, struct humfs, ext);
15143 + const char *data_path[3] = { mount->data, path, NULL };
15146 + err = (*mount->meta->remove_file)(path, mount);
15150 + (*mount->meta->remove_file)(path, mount);
15151 + return(host_unlink_file(data_path));
15154 +static void humfs_invisible(struct externfs_inode *ext)
15156 + struct humfs_file *hf = container_of(ext, struct humfs_file, ext);
15157 + struct humfs *mount = hf->mount;
15159 + (*mount->meta->invisible)(hf);
15160 + not_reclaimable(&hf->data);
15163 +static int humfs_make_dir(const char *path, int mode, int uid, int gid,
15164 + struct externfs_data *ed)
15166 + struct humfs *mount = container_of(ed, struct humfs, ext);
15167 + const char *data_path[3] = { mount->data, path, NULL };
15170 + err = (*mount->meta->create_dir)(path, mode, uid, gid, mount);
15174 + err = host_make_dir(data_path, S_IRWXUGO);
15176 + (*mount->meta->remove_dir)(path, mount);
15181 +static int humfs_remove_dir(const char *path, int uid, int gid,
15182 + struct externfs_data *ed)
15184 + struct humfs *mount = container_of(ed, struct humfs, ext);
15185 + const char *data_path[3] = { mount->data, path, NULL };
15188 + err = host_remove_dir(data_path);
15192 + (*mount->meta->remove_dir)(path, mount);
15197 +static int humfs_read_link(char *file, int uid, int gid, char *buf, int size,
15198 + struct externfs_data *ed)
15200 + struct humfs *mount = container_of(ed, struct humfs, ext);
15201 + const char *data_path[3] = { mount->data, file, NULL };
15203 + return(host_read_link(data_path, buf, size));
15206 +struct humfs *inode_humfs_info(struct inode *inode)
15208 + return(container_of(inode_externfs_info(inode), struct humfs, ext));
15211 +static int humfs_rename_file(char *from, char *to, struct externfs_data *ed)
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 };
15218 + err = (*mount->meta->rename_file)(from, to, mount);
15222 + err = host_rename_file(data_path_from, data_path_to);
15224 + (*mount->meta->rename_file)(to, from, mount);
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)
15235 + struct humfs *mount = container_of(ed, struct humfs, ext);
15236 + const char *data_path[3] = { mount->data, NULL };
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);
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;
15252 +int humfs_truncate_file(struct externfs_inode *ext, __u64 size,
15253 + struct externfs_data *ed)
15255 + struct humfs_file *hf = container_of(ext, struct humfs_file, ext);
15257 + return(truncate_file(&hf->data, size));
15260 +char *humfs_path(char *dir, char *file)
15262 + int need_slash, len = strlen(dir) + strlen(file);
15265 + need_slash = (dir[strlen(dir) - 1] != '/');
15269 + new = kmalloc(len + 1, GFP_KERNEL);
15273 + strcpy(new, dir);
15275 + strcat(new, "/");
15276 + strcat(new, file);
15281 +DECLARE_MUTEX(meta_sem);
15282 +struct list_head metas = LIST_HEAD_INIT(metas);
15284 +static struct humfs_meta_ops *find_meta(const char *name)
15286 + struct list_head *ele;
15287 + struct humfs_meta_ops *m;
15290 + list_for_each(ele, &metas){
15291 + m = list_entry(ele, struct humfs_meta_ops, list);
15292 + if(!strcmp(m->name, name))
15301 +void register_meta(struct humfs_meta_ops *ops)
15304 + list_add(&ops->list, &metas);
15308 +void unregister_meta(struct humfs_meta_ops *ops)
15311 + list_del(&ops->list);
15315 +static struct humfs *read_superblock(char *root)
15317 + struct humfs *mount;
15318 + struct humfs_meta_ops *meta = NULL;
15319 + struct file_handle *fh;
15320 + const char *path[] = { root, "superblock", NULL };
15322 + char meta_buf[33], line[HOSTFS_BUFSIZE], *newline;
15323 + unsigned long long pos;
15324 + int version, i, n, err;
15326 + fh = kmalloc(sizeof(*fh), GFP_KERNEL);
15328 + return(ERR_PTR(-ENOMEM));
15330 + err = host_open_file(path, 1, 0, fh);
15332 + printk("Failed to open %s/%s, errno = %d\n", path[0],
15334 + return(ERR_PTR(err));
15342 + n = read_file(fh, pos, &line[i], sizeof(line) - i - 1);
15343 + if((n == 0) && (i == 0))
15346 + return(ERR_PTR(n));
15350 + line[n + i] = '\0';
15352 + newline = strchr(line, '\n');
15353 + if(newline == NULL){
15354 + printk("read_superblock - line too long : '%s'\n",
15356 + return(ERR_PTR(-EINVAL));
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,
15365 + return(ERR_PTR(-EINVAL));
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));
15380 + printk("read_superblock - bogus line : '%s'\n", line);
15381 + return(ERR_PTR(-EINVAL));
15384 + i = newline - line;
15385 + memmove(line, newline, sizeof(line) - i);
15386 + i = strlen(line);
15390 + printk("read_superblock - used not specified or set to "
15392 + return(ERR_PTR(-EINVAL));
15395 + printk("read_superblock - total not specified or set to "
15397 + return(ERR_PTR(-EINVAL));
15399 + if(used > total){
15400 + printk("read_superblock - used is greater than total\n");
15401 + return(ERR_PTR(-EINVAL));
15404 + if(meta == NULL){
15405 + meta = find_meta("shadow_fs");
15408 + if(meta == NULL){
15409 + printk("read_superblock - valid meta api was not specified\n");
15410 + return(ERR_PTR(-EINVAL));
15413 + mount = (*meta->init_mount)(root);
15414 + if(IS_ERR(mount))
15417 + *mount = ((struct humfs) { .total = total,
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
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
15477 +static struct externfs_data *mount_fs(char *mount_arg)
15479 + char *root, *data, *flags;
15480 + struct humfs *mount;
15481 + struct externfs_file_ops *file_ops;
15482 + int err, do_mmap = 0;
15484 + if(mount_arg == NULL){
15485 + printk("humfs - no host directory specified\n");
15489 + flags = strchr((char *) mount_arg, ',');
15490 + if(flags != NULL){
15494 + if(!strcmp(flags, "mmap"))
15497 + flags = strchr(flags, ',');
15498 + } while(flags != NULL);
15502 + root = host_root_filename(mount_arg);
15506 + mount = read_superblock(root);
15507 + if(IS_ERR(mount)){
15508 + err = PTR_ERR(mount);
15509 + goto err_free_root;
15512 + data = humfs_path(root, "data/");
15514 + goto err_free_mount;
15516 + if(CHOOSE_MODE(do_mmap, 0)){
15517 + printk("humfs doesn't support mmap in tt mode\n");
15521 + mount->data = data;
15522 + mount->mmap = do_mmap;
15524 + file_ops = do_mmap ? &humfs_mmap_file_ops : &humfs_no_mmap_file_ops;
15525 + init_externfs(&mount->ext, file_ops);
15527 + return(&mount->ext);
15537 +struct externfs_mount_ops humfs_mount_ops = {
15538 + .init_file = humfs_init_file,
15539 + .mount = mount_fs,
15542 +static int __init init_humfs(void)
15544 + return(register_externfs("humfs", &humfs_mount_ops));
15547 +static void __exit exit_humfs(void)
15549 + unregister_externfs("humfs");
15552 +__initcall(init_humfs);
15553 +__exitcall(exit_humfs);
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
15560 + * ---------------------------------------------------------------------------
15561 + * Local variables:
15562 + * c-file-style: "linux"
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
15571 +# Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com)
15572 +# Licensed under the GPL
15575 +O_TARGET := hostfs.o
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
15581 +obj-m = $(O_TARGET)
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
15590 + * Copyright (C) 2004 Piotr Neuman (sikkh@wp.pl) and
15591 + * Jeff Dike (jdike@addtoit.com)
15592 + * Licensed under the GPL
15595 +#ifndef __UM_FS_METADATA
15596 +#define __UM_FS_METADATA
15598 +#include "linux/fs.h"
15599 +#include "linux/list.h"
15601 +#include "hostfs.h"
15602 +#include "filehandle.h"
15604 +#define container_of(ptr, type, member) ({ \
15605 + const typeof( ((type *)0)->member ) *__mptr = (ptr); \
15606 + (type *)( (char *)__mptr - offsetof(type,member) );})
15609 + struct externfs_data ext;
15615 + struct humfs_meta_ops *meta;
15618 +struct humfs_file {
15619 + struct humfs *mount;
15620 + struct file_handle data;
15621 + struct externfs_inode ext;
15624 +struct humfs_meta_ops {
15625 + struct list_head list;
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);
15654 +void register_meta(struct humfs_meta_ops *ops);
15655 +void unregister_meta(struct humfs_meta_ops *ops);
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);
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
15668 + * ---------------------------------------------------------------------------
15669 + * Local variables:
15670 + * c-file-style: "linux"
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
15679 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
15680 + * Licensed under the GPL
15683 +#include <linux/slab.h>
15684 +#include "hostfs.h"
15685 +#include "metadata.h"
15686 +#include "kern_util.h"
15688 +#define METADATA_FILE_PATH(meta) (meta)->root, "file_metadata"
15689 +#define METADATA_DIR_PATH(meta) (meta)->root, "dir_metadata"
15692 + struct humfs humfs;
15696 +struct meta_file {
15697 + struct humfs_file humfs;
15698 + struct file_handle fh;
15701 +static int meta_file_path(const char *path, struct meta_fs *meta,
15702 + const char *path_out[])
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));
15708 + if(data_file == NULL)
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;
15719 + path_out[1] = "file_metadata";
15720 + path_out[3] = NULL;
15726 +static int open_meta_file(const char *path, struct humfs *humfs,
15727 + struct file_handle *fh)
15729 + struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
15730 + const char *meta_path[5];
15731 + char meta_tmp[HOSTFS_BUFSIZE];
15735 + err = meta_file_path(path, meta, meta_path);
15739 + meta_file = get_path(meta_path, meta_tmp, sizeof(meta_tmp));
15740 + if(meta_file == NULL)
15743 + err = open_filehandle(meta_file, of_rdwr(OPENFLAGS()), 0, fh);
15749 +static char *meta_fs_name(struct inode *inode)
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;
15756 + if(meta_file_path("", meta, metadata_path))
15759 + file = get_path(metadata_path, tmp, sizeof(tmp));
15763 + name = inode_name_prefix(inode, file);
15765 + free_path(file, tmp);
15769 +static void metafs_invisible(struct humfs_file *hf)
15771 + struct meta_file *mf = container_of(hf, struct meta_file, humfs);
15773 + not_reclaimable(&mf->fh);
15776 +static struct humfs_file *metafs_init_file(void)
15778 + struct meta_file *mf;
15779 + int err = -ENOMEM;
15781 + mf = kmalloc(sizeof(*mf), GFP_KERNEL);
15783 + return(ERR_PTR(err));
15785 + return(&mf->humfs);
15788 +static int metafs_open_file(struct humfs_file *hf, const char *path,
15789 + struct inode *inode, struct humfs *humfs)
15791 + struct meta_file *mf = container_of(hf, struct meta_file, humfs);
15794 + err = open_meta_file(path, humfs, &mf->fh);
15798 + is_reclaimable(&mf->fh, meta_fs_name, inode);
15803 +static void metafs_close_file(struct humfs_file *hf)
15805 + struct meta_file *meta = container_of(hf, struct meta_file, humfs);
15807 + close_file(&meta->fh);
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)
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;
15826 + err = open_filehandle(file, of_write(of_create(OPENFLAGS())), 0644,
15829 + goto out_free_path;
15831 + if(inode != NULL)
15832 + is_reclaimable(&mf->fh, meta_fs_name, inode);
15834 + sprintf(buf, "%d %d %d\n", mode & S_IRWXUGO, uid, gid);
15835 + err = write_file(&mf->fh, 0, buf, strlen(buf));
15839 + free_path(file, tmp);
15843 + close_file(&mf->fh);
15844 + os_remove_file(file);
15846 + free_path(file, tmp);
15851 +static int metafs_create_link(const char *to, const char *from,
15852 + struct humfs *humfs)
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 };
15858 + return(host_link_file(path_to, path_from));
15861 +static int metafs_remove_file(const char *path, struct humfs *humfs)
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;
15872 + err = os_remove_file(file);
15875 + free_path(file, tmp);
15879 +static int metafs_create_directory(const char *path, int mode, int uid,
15880 + int gid, struct humfs *humfs)
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,
15887 + char *file, dir_meta[sizeof("mmmm uuuuuuuuuu gggggggggg\n")];
15890 + err = host_make_dir(dir_path, 0755);
15894 + err = host_make_dir(file_path, 0755);
15898 + /* This to make the index independent of the number of elements in
15899 + * METADATA_DIR_PATH().
15901 + dir_path[sizeof(dir_path) / sizeof(dir_path[0]) - 2] = "metadata";
15904 + file = get_path(dir_path, tmp, sizeof(tmp));
15908 + fd = os_open_file(file, of_create(of_rdwr(OPENFLAGS())), 0644);
15914 + sprintf(dir_meta, "%d %d %d\n", mode & S_IRWXUGO, uid, gid);
15915 + err = os_write_file(fd, dir_meta, strlen(dir_meta));
15919 + os_close_file(fd);
15922 + free_path(file, tmp);
15924 + host_remove_dir(dir_path);
15929 +static int metafs_remove_directory(const char *path, struct humfs *humfs)
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",
15935 + const char *file_path[] = { METADATA_FILE_PATH(meta), path, NULL };
15940 + file = get_path(dir_path, tmp, sizeof(tmp));
15944 + err = os_remove_file(file);
15948 + slash = strrchr(file, '/');
15949 + if(slash == NULL){
15950 + printk("remove_shadow_directory failed to find last slash\n");
15954 + err = os_remove_dir(file);
15955 + free_path(file, tmp);
15957 + file = get_path(file_path, tmp, sizeof(tmp));
15961 + err = os_remove_dir(file);
15968 + free_path(file, tmp);
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)
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 };
15980 + char buf[sizeof("mmmm uuuuuuuuuu gggggggggg x nnn mmm\n")], *file;
15982 + sprintf(buf, "%d %d %d %c %d %d\n", mode & S_IRWXUGO, uid, gid, type,
15986 + file = get_path(metadata_path, tmp, sizeof(tmp));
15990 + err = open_filehandle(file,
15991 + of_create(of_rdwr(OPENFLAGS())), 0644, &fh);
15995 + err = write_file(&fh, 0, buf, strlen(buf));
16002 + free_path(file, tmp);
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)
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;
16016 + err = open_meta_file(path, humfs, &fh);
16020 + err = os_read_file(fh.fd, buf, sizeof(buf) - 1);
16027 + n = sscanf(buf, "%d %d %d %c %d %d", &mode, &uid, &gid, &type, &maj,
16038 + if(mode_out != NULL)
16039 + *mode_out = mode;
16040 + if(uid_out != NULL)
16042 + if(gid_out != NULL)
16044 + if(type_out != NULL)
16045 + *type_out = type;
16046 + if(maj_out != NULL)
16048 + if(min_out != NULL)
16057 +static int metafs_change_ownerships(const char *path, int mode, int uid,
16058 + int gid, struct humfs *humfs)
16060 + struct file_handle fh;
16062 + char buf[sizeof("mmmm uuuuuuuuuu gggggggggg x nnn mmm\n")];
16063 + int err = -ENOMEM, old_mode, old_uid, old_gid, n, maj, min;
16065 + err = open_meta_file(path, humfs, &fh);
16069 + err = read_file(&fh, 0, buf, sizeof(buf) - 1);
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)){
16090 + sprintf(buf, "%d %d %d\n", mode & S_IRWXUGO, uid, gid);
16092 + sprintf(buf, "%d %d %d %c %d %d\n", mode & S_IRWXUGO, uid, gid,
16095 + err = write_file(&fh, 0, buf, strlen(buf));
16099 + err = truncate_file(&fh, strlen(buf));
16107 +static int metafs_rename_file(const char *from, const char *to,
16108 + struct humfs *humfs)
16110 + struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
16111 + const char *metadata_path_from[5], *metadata_path_to[5];
16114 + err = meta_file_path(from, meta, metadata_path_from);
16118 + err = meta_file_path(to, meta, metadata_path_to);
16122 + return(host_rename_file(metadata_path_from, metadata_path_to));
16125 +static struct humfs *metafs_init_mount(char *root)
16127 + struct meta_fs *meta;
16128 + int err = -ENOMEM;
16130 + meta = kmalloc(sizeof(*meta), GFP_KERNEL);
16134 + meta->root = uml_strdup(root);
16135 + if(meta->root == NULL)
16136 + goto out_free_meta;
16138 + return(&meta->humfs);
16143 + return(ERR_PTR(err));
16146 +static void metafs_free_mount(struct humfs *humfs)
16148 + struct meta_fs *meta = container_of(humfs, struct meta_fs, humfs);
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,
16173 +static int __init init_meta_fs(void)
16175 + register_meta(&hum_fs_meta_fs_ops);
16179 +static void __exit exit_meta_fs(void)
16181 + unregister_meta(&hum_fs_meta_fs_ops);
16184 +__initcall(init_meta_fs);
16185 +__exitcall(exit_meta_fs);
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
16192 + * ---------------------------------------------------------------------------
16193 + * Local variables:
16194 + * c-file-style: "linux"
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
16203 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16204 + * Licensed under the GPL
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>
16216 +struct hppfs_data {
16217 + struct list_head list;
16218 + char contents[PAGE_SIZE - sizeof(struct list_head)];
16221 +struct hppfs_private {
16222 + struct file proc_file;
16225 + struct hppfs_data *contents;
16228 +#define HPPFS_SUPER_MAGIC 0xb00000ee
16230 +static struct super_operations hppfs_sbops;
16232 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
16235 +static int is_pid(struct dentry *dentry)
16237 + struct super_block *sb;
16240 + sb = dentry->d_sb;
16241 + if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
16244 + for(i = 0; i < dentry->d_name.len; i++){
16245 + if(!isdigit(dentry->d_name.name[i]))
16251 +static char *dentry_name(struct dentry *dentry, int extra)
16253 + struct dentry *parent;
16254 + char *root, *name;
16255 + const char *seg_name;
16256 + int len, seg_len;
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;
16268 + len += strlen(root);
16269 + name = kmalloc(len + extra + 1, GFP_KERNEL);
16270 + if(name == NULL) return(NULL);
16272 + name[len] = '\0';
16274 + while(parent->d_parent != parent){
16275 + if(is_pid(parent)){
16276 + seg_name = "pid";
16277 + seg_len = strlen("pid");
16280 + seg_name = parent->d_name.name;
16281 + seg_len = parent->d_name.len;
16284 + len -= seg_len + 1;
16286 + strncpy(&name[len + 1], seg_name, seg_len);
16287 + parent = parent->d_parent;
16289 + strncpy(name, root, strlen(root));
16293 +struct dentry_operations hppfs_dentry_ops = {
16296 +static int file_removed(struct dentry *dentry, const char *file)
16302 + if(file != NULL) extra += strlen(file) + 1;
16304 + host_file = dentry_name(dentry, extra + strlen("/remove"));
16305 + if(host_file == NULL){
16306 + printk("file_removed : allocation failed\n");
16310 + if(file != NULL){
16311 + strcat(host_file, "/");
16312 + strcat(host_file, file);
16314 + strcat(host_file, "/remove");
16316 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
16317 + kfree(host_file);
16319 + os_close_file(fd);
16325 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry)
16327 + struct dentry *proc_dentry;
16328 + struct inode *inode;
16329 + int err, deleted;
16331 + deleted = file_removed(dentry, NULL);
16333 + return(ERR_PTR(deleted));
16335 + return(ERR_PTR(-ENOENT));
16337 + proc_dentry = lookup_hash(&dentry->d_name, ino->u.hppfs_i.proc_dentry);
16338 + if(IS_ERR(proc_dentry))
16339 + return(proc_dentry);
16341 + inode = get_inode(ino->i_sb, proc_dentry, &err);
16343 + return(ERR_PTR(err));
16345 + d_add(dentry, inode);
16346 + dentry->d_op = &hppfs_dentry_ops;
16350 +static struct inode_operations hppfs_file_iops = {
16353 +static struct inode_operations hppfs_dir_iops = {
16354 + .lookup = hppfs_lookup,
16357 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count,
16358 + loff_t *ppos, int is_user)
16360 + ssize_t (*read)(struct file *, char *, size_t, loff_t *);
16363 + read = file->f_dentry->d_inode->i_fop->read;
16365 + return(-EOPNOTSUPP);
16368 + set_fs(KERNEL_DS);
16370 + n = (*read)(file, buf, count, &file->f_pos);
16375 + if(ppos) *ppos = file->f_pos;
16379 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
16386 + new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
16387 + if(new_buf == NULL){
16388 + printk("hppfs_read_file : kmalloc failed\n");
16392 + while(count > 0){
16393 + cur = min_t(ssize_t, count, PAGE_SIZE);
16394 + err = os_read_file(fd, new_buf, cur);
16396 + printk("hppfs_read : read failed, err = %d\n", -err);
16400 + else if(err == 0)
16403 + if(copy_to_user(buf, new_buf, err)){
16416 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
16419 + struct hppfs_private *hppfs = file->private_data;
16420 + struct hppfs_data *data;
16424 + if(hppfs->contents != NULL){
16425 + if(*ppos >= hppfs->len) return(0);
16427 + data = hppfs->contents;
16429 + while(off >= sizeof(data->contents)){
16430 + data = list_entry(data->list.next, struct hppfs_data,
16432 + off -= sizeof(data->contents);
16435 + if(off + count > hppfs->len)
16436 + count = hppfs->len - off;
16437 + copy_to_user(buf, &data->contents[off], count);
16440 + else if(hppfs->host_fd != -1){
16441 + err = os_seek_file(hppfs->host_fd, *ppos);
16443 + printk("hppfs_read : seek failed, err = %d\n", -err);
16446 + count = hppfs_read_file(hppfs->host_fd, buf, count);
16450 + else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
16455 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len,
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 *);
16463 + write = proc_file->f_dentry->d_inode->i_fop->write;
16464 + if(write == NULL)
16465 + return(-EOPNOTSUPP);
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;
16474 +static int open_host_sock(char *host_file, int *filter_out)
16479 + end = &host_file[strlen(host_file)];
16480 + strcpy(end, "/rw");
16482 + fd = os_connect_socket(host_file);
16486 + strcpy(end, "/r");
16488 + fd = os_connect_socket(host_file);
16492 +static void free_contents(struct hppfs_data *head)
16494 + struct hppfs_data *data;
16495 + struct list_head *ele, *next;
16497 + if(head == NULL) return;
16499 + list_for_each_safe(ele, next, &head->list){
16500 + data = list_entry(ele, struct hppfs_data, list);
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)
16511 + struct hppfs_data *data, *new, *head;
16515 + data = kmalloc(sizeof(*data), GFP_KERNEL);
16516 + if(data == NULL){
16517 + printk("hppfs_get_data : head allocation failed\n");
16521 + INIT_LIST_HEAD(&data->list);
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);
16531 + printk("hppfs_get_data : failed to write out "
16532 + "%d bytes, err = %d\n", n, -err);
16534 + err = os_shutdown_socket(fd, 0, 1);
16536 + printk("hppfs_get_data : failed to shut down "
16538 + goto failed_free;
16542 + n = os_read_file(fd, data->contents, sizeof(data->contents));
16545 + printk("hppfs_get_data : read failed, err = %d\n", -n);
16546 + goto failed_free;
16553 + if(n < sizeof(data->contents))
16556 + new = kmalloc(sizeof(*data), GFP_KERNEL);
16558 + printk("hppfs_get_data : data allocation failed\n");
16560 + goto failed_free;
16563 + INIT_LIST_HEAD(&new->list);
16564 + list_add(&new->list, &data->list);
16570 + free_contents(head);
16572 + return(ERR_PTR(err));
16575 +static struct hppfs_private *hppfs_data(void)
16577 + struct hppfs_private *data;
16579 + data = kmalloc(sizeof(*data), GFP_KERNEL);
16583 + *data = ((struct hppfs_private ) { .host_fd = -1,
16585 + .contents = NULL } );
16589 +static int hppfs_open(struct inode *inode, struct file *file)
16591 + struct hppfs_private *data;
16592 + struct dentry *proc_dentry;
16594 + int err, fd, type, filter;
16597 + data = hppfs_data();
16601 + host_file = dentry_name(file->f_dentry, strlen("/rw"));
16602 + if(host_file == NULL)
16605 + proc_dentry = inode->u.hppfs_i.proc_dentry;
16606 + err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
16610 + type = os_file_type(host_file);
16611 + if(type == OS_TYPE_FILE){
16612 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
16614 + data->host_fd = fd;
16615 + else printk("hppfs_open : failed to open '%s', err = %d\n",
16618 + data->contents = NULL;
16620 + else if(type == OS_TYPE_DIR){
16621 + fd = open_host_sock(host_file, &filter);
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;
16629 + else printk("hppfs_open : failed to open a socket in "
16630 + "'%s', err = %d\n", host_file, -fd);
16632 + kfree(host_file);
16634 + file->private_data = data;
16638 + kfree(host_file);
16640 + free_contents(data->contents);
16646 +static int hppfs_dir_open(struct inode *inode, struct file *file)
16648 + struct hppfs_private *data;
16649 + struct dentry *proc_dentry;
16653 + data = hppfs_data();
16657 + proc_dentry = inode->u.hppfs_i.proc_dentry;
16658 + err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
16662 + file->private_data = data;
16671 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
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);
16678 + llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
16679 + if(llseek != NULL){
16680 + ret = (*llseek)(proc_file, off, where);
16685 + return(default_llseek(file, off, where));
16688 +struct hppfs_dirent {
16689 + void *vfs_dirent;
16690 + filldir_t filldir;
16691 + struct dentry *dentry;
16694 +static int hppfs_filldir(void *d, const char *name, int size,
16695 + loff_t offset, ino_t inode, unsigned int type)
16697 + struct hppfs_dirent *dirent = d;
16699 + if(file_removed(dirent->dentry, name))
16702 + return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
16706 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
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 } );
16717 + readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
16718 + if(readdir == NULL)
16719 + return(-EOPNOTSUPP);
16721 + proc_file->f_pos = file->f_pos;
16722 + err = (*readdir)(proc_file, &dirent, hppfs_filldir);
16723 + file->f_pos = proc_file->f_pos;
16728 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
16733 +static struct file_operations hppfs_file_fops = {
16735 + .llseek = hppfs_llseek,
16736 + .read = hppfs_read,
16737 + .write = hppfs_write,
16738 + .open = hppfs_open,
16741 +static struct file_operations hppfs_dir_fops = {
16743 + .readdir = hppfs_readdir,
16744 + .open = hppfs_dir_open,
16745 + .fsync = hppfs_fsync,
16748 +static int hppfs_statfs(struct super_block *sb, struct statfs *sf)
16750 + sf->f_blocks = 0;
16752 + sf->f_bavail = 0;
16755 + sf->f_type = HPPFS_SUPER_MAGIC;
16759 +static struct super_operations hppfs_sbops = {
16760 + .put_inode = force_delete,
16761 + .delete_inode = NULL,
16762 + .statfs = hppfs_statfs,
16765 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
16767 + struct file proc_file;
16768 + struct dentry *proc_dentry;
16769 + int (*readlink)(struct dentry *, char *, int);
16772 + proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
16773 + err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
16777 + readlink = proc_dentry->d_inode->i_op->readlink;
16778 + if(readlink == NULL)
16779 + return(-EOPNOTSUPP);
16780 + n = (*readlink)(proc_dentry, buffer, buflen);
16782 + if(proc_file.f_op->release)
16783 + (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
16788 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
16790 + struct file proc_file;
16791 + struct dentry *proc_dentry;
16792 + int (*follow_link)(struct dentry *, struct nameidata *);
16795 + proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
16796 + err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
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);
16805 + if(proc_file.f_op->release)
16806 + (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
16811 +static struct inode_operations hppfs_link_iops = {
16812 + .readlink = hppfs_readlink,
16813 + .follow_link = hppfs_follow_link,
16816 +static void read_inode(struct inode *ino)
16818 + struct inode *proc_ino;
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;
16835 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
16838 + struct inode *inode;
16839 + int err = -ENOMEM;
16841 + inode = new_inode(sb);
16842 + if(inode == NULL)
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;
16850 + else if(S_ISLNK(dentry->d_inode->i_mode)){
16851 + inode->i_op = &hppfs_link_iops;
16852 + inode->i_fop = &hppfs_file_fops;
16855 + inode->i_op = &hppfs_file_iops;
16856 + inode->i_fop = &hppfs_file_fops;
16859 + inode->i_sb = sb;
16860 + inode->u.hppfs_i.proc_dentry = dentry;
16862 + read_inode(inode);
16865 + if(error) *error = err;
16868 + if(error) *error = err;
16872 +static struct super_block *hppfs_read_super(struct super_block *sb, void *d,
16875 + struct inode *root_inode;
16876 + struct file_system_type *procfs;
16877 + struct super_block *proc_sb;
16879 + procfs = get_fs_type("proc");
16880 + if(procfs == NULL)
16883 + if(list_empty(&procfs->fs_supers))
16886 + proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
16889 + sb->s_blocksize = 1024;
16890 + sb->s_blocksize_bits = 10;
16891 + sb->s_magic = HPPFS_SUPER_MAGIC;
16892 + sb->s_op = &hppfs_sbops;
16894 + dget(proc_sb->s_root);
16895 + root_inode = get_inode(sb, proc_sb->s_root, NULL);
16896 + if(root_inode == NULL)
16899 + sb->s_root = d_alloc_root(root_inode);
16900 + if(sb->s_root == NULL)
16906 + iput(root_inode);
16908 + dput(proc_sb->s_root);
16913 +DECLARE_FSTYPE(hppfs_type, "hppfs", hppfs_read_super, 0);
16915 +static int __init init_hppfs(void)
16917 + return(register_filesystem(&hppfs_type));
16920 +static void __exit exit_hppfs(void)
16922 + unregister_filesystem(&hppfs_type);
16925 +module_init(init_hppfs)
16926 +module_exit(exit_hppfs)
16927 +MODULE_LICENSE("GPL");
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
16934 + * ---------------------------------------------------------------------------
16935 + * Local variables:
16936 + * c-file-style: "linux"
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
16944 +O_TARGET := hppfs.o
16945 +obj-y = hppfs_kern.o #hppfs_user.o
16946 +obj-m = $(O_TARGET)
16948 +CFLAGS_hppfs_kern.o := $(CFLAGS)
16949 +#CFLAGS_hppfs_user.o := $(USER_CFLAGS)
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
16960 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16961 +# Licensed under the GPL
16964 +O_TARGET := built-in.o
16969 +subdir-$(CONFIG_HOSTFS) += hostfs
16970 +subdir-$(CONFIG_HPPFS) += hppfs
16972 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
16973 +obj-m += $(join $(subdir-m),$(subdir-m:%=/%.o))
16975 +include $(TOPDIR)/Rules.make
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
16988 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
16989 + * Licensed under the GPL
16992 +#ifndef __2_5_COMPAT_H__
16993 +#define __2_5_COMPAT_H__
16995 +#include "linux/version.h"
16997 +#define INIT_ELV(queue, elv) elevator_init(elv, ELV_NOOP)
16999 +#define ELV_NOOP ELEVATOR_NOOP
17001 +#define INIT_HARDSECT(arr, maj, sizes) arr[maj] = sizes
17003 +#define IS_WRITE(req) ((req)->cmd == WRITE)
17005 +#define SET_PRI(task) \
17006 + do { (task)->nice = 20; (task)->counter = -100; } while(0);
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
17015 + * ---------------------------------------------------------------------------
17016 + * Local variables:
17017 + * c-file-style: "linux"
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
17026 + * Copyright (C) 2004 Jeff Dike (jdike@karaya.com)
17027 + * Licensed under the GPL
17033 +enum aio_type { AIO_READ, AIO_WRITE, AIO_MMAP };
17035 +struct aio_thread_reply {
17040 +struct aio_context {
17044 +#define INIT_AIO_CONTEXT { .reply_fd = -1 }
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);
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
17056 + * ---------------------------------------------------------------------------
17057 + * Local variables:
17058 + * c-file-style: "linux"
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
17067 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
17068 + * Licensed under the GPL
17071 +#ifndef __CHAN_KERN_H__
17072 +#define __CHAN_KERN_H__
17074 +#include "linux/tty.h"
17075 +#include "linux/list.h"
17076 +#include "chan_user.h"
17079 + struct list_head list;
17081 + unsigned int primary:1;
17082 + unsigned int input:1;
17083 + unsigned int output:1;
17084 + unsigned int opened:1;
17086 + enum chan_init_pri pri;
17087 + struct chan_ops *ops;
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,
17098 +extern int console_write_chan(struct list_head *chans, const char *buf,
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);
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
17117 + * ---------------------------------------------------------------------------
17118 + * Local variables:
17119 + * c-file-style: "linux"
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
17128 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
17129 + * Licensed under the GPL
17132 +#ifndef __CHAN_USER_H__
17133 +#define __CHAN_USER_H__
17137 +struct chan_opts {
17138 + void (*announce)(char *dev_name, int dev);
17139 + char *xterm_title;
17141 + unsigned long tramp_stack;
17145 +enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE };
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 *);
17160 +extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops,
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);
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);
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" \
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
17188 + * ---------------------------------------------------------------------------
17189 + * Local variables:
17190 + * c-file-style: "linux"
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
17199 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17200 + * Licensed under the GPL
17203 +#ifndef __CHOOSE_MODE_H__
17204 +#define __CHOOSE_MODE_H__
17206 +#include "uml-config.h"
17208 +#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS)
17209 +#define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas))
17211 +#elif defined(UML_CONFIG_MODE_SKAS)
17212 +#define CHOOSE_MODE(tt, skas) (skas)
17214 +#elif defined(UML_CONFIG_MODE_TT)
17215 +#define CHOOSE_MODE(tt, skas) (tt)
17218 +#define CHOOSE_MODE_PROC(tt, skas, args...) \
17219 + CHOOSE_MODE(tt(args), skas(args))
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
17228 + * ---------------------------------------------------------------------------
17229 + * Local variables:
17230 + * c-file-style: "linux"
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
17239 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
17240 + * Licensed under the GPL
17243 +#ifndef __FILEHANDLE_H__
17244 +#define __FILEHANDLE_H__
17246 +#include "linux/list.h"
17247 +#include "linux/fs.h"
17250 +struct file_handle {
17251 + struct list_head list;
17253 + char *(*get_name)(struct inode *);
17254 + struct inode *inode;
17255 + struct openflags flags;
17258 +extern struct file_handle bad_filehandle;
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);
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
17284 + * ---------------------------------------------------------------------------
17285 + * Local variables:
17286 + * c-file-style: "linux"
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
17295 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17296 + * Licensed under the GPL
17299 +#ifndef __FRAME_H_
17300 +#define __FRAME_H_
17302 +#include "sysdep/frame.h"
17304 +struct frame_common {
17311 + struct arch_frame_data arch;
17315 + struct frame_common common;
17319 +extern struct sc_frame signal_frame_sc;
17321 +extern struct sc_frame signal_frame_sc_sr;
17324 + struct frame_common common;
17331 +extern struct si_frame signal_frame_si;
17333 +extern void capture_signal_stack(void);
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
17342 + * ---------------------------------------------------------------------------
17343 + * Local variables:
17344 + * c-file-style: "linux"
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
17353 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17354 + * Licensed under the GPL
17357 +#ifndef __FRAME_KERN_H_
17358 +#define __FRAME_KERN_H_
17360 +#include "frame.h"
17361 +#include "sysdep/frame_kern.h"
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,
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,
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
17381 + * ---------------------------------------------------------------------------
17382 + * Local variables:
17383 + * c-file-style: "linux"
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
17392 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17393 + * Licensed under the GPL
17396 +#ifndef __FRAME_USER_H_
17397 +#define __FRAME_USER_H_
17399 +#include "sysdep/frame_user.h"
17400 +#include "frame.h"
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
17409 + * ---------------------------------------------------------------------------
17410 + * Local variables:
17411 + * c-file-style: "linux"
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
17420 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17421 + * Licensed under the GPL
17424 +#ifndef __HELPER_H__
17425 +#define __HELPER_H__
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);
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
17441 + * ---------------------------------------------------------------------------
17442 + * Local variables:
17443 + * c-file-style: "linux"
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
17451 +#ifndef _LINUX_UML_INIT_H
17452 +#define _LINUX_UML_INIT_H
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
17463 + * You should add __init immediately before the function name, like:
17465 + * static void __init initme(int x, int y)
17467 + * extern int z; z = x * y;
17470 + * If the function has a prototype somewhere, you can also add
17471 + * __init between closing brace of the prototype and semicolon:
17473 + * extern int initialize_foobar_device(int, int, int) __init;
17475 + * For initialized data:
17476 + * You should insert __initdata between the variable name and equal
17477 + * sign followed by value, e.g.:
17479 + * static int init_variable __initdata = 0;
17480 + * static char linux_logo[] __initdata = { 0x32, 0x36, ... };
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
17486 + * Also note, that this data cannot be "const".
17489 +#ifndef _LINUX_INIT_H
17490 +typedef int (*initcall_t)(void);
17491 +typedef void (*exitcall_t)(void);
17493 +#define __init __attribute__ ((__section__ (".text.init")))
17494 +#define __exit __attribute__ ((unused, __section__(".text.exit")))
17495 +#define __initdata __attribute__ ((__section__ (".data.init")))
17500 +struct uml_param {
17502 + int (*setup_func)(char *, int *);
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;
17510 +#define __uml_initcall(fn) \
17511 + static initcall_t __uml_initcall_##fn __uml_init_call = fn
17513 +#define __uml_exitcall(fn) \
17514 + static exitcall_t __uml_exitcall_##fn __uml_exit_call = fn
17516 +extern struct uml_param __uml_setup_start, __uml_setup_end;
17518 +#define __uml_postsetup(fn) \
17519 + static initcall_t __uml_postsetup_##fn __uml_postsetup_call = fn
17521 +#define __non_empty_string(dummyname,string) \
17522 + struct __uml_non_empty_string_struct_##dummyname \
17524 + char _string[sizeof(string)-2]; \
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 }
17534 +#define __uml_setup(str, fn, help...) \
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
17544 + * Mark functions and data as being only used at initialization
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")))
17553 +#ifndef __KERNEL__
17555 +#define __initcall(fn) static initcall_t __initcall_##fn __init_call = fn
17556 +#define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn
17558 +#define __init_call __attribute__ ((unused,__section__ (".initcall.init")))
17559 +#define __exit_call __attribute__ ((unused,__section__ (".exitcall.exit")))
17563 +#endif /* _LINUX_UML_INIT_H */
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
17570 + * ---------------------------------------------------------------------------
17571 + * Local variables:
17572 + * c-file-style: "linux"
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
17581 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17582 + * Licensed under the GPL
17585 +#ifndef __INITRD_USER_H__
17586 +#define __INITRD_USER_H__
17588 +extern int load_initrd(char *filename, void *buf, int size);
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
17597 + * ---------------------------------------------------------------------------
17598 + * Local variables:
17599 + * c-file-style: "linux"
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
17608 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17609 + * Licensed under the GPL
17612 +#ifndef __IRQ_KERN_H__
17613 +#define __IRQ_KERN_H__
17615 +#include "linux/interrupt.h"
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,
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
17629 + * ---------------------------------------------------------------------------
17630 + * Local variables:
17631 + * c-file-style: "linux"
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
17640 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17641 + * Licensed under the GPL
17644 +#ifndef __IRQ_USER_H__
17645 +#define __IRQ_USER_H__
17647 +enum { IRQ_READ, IRQ_WRITE };
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);
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
17670 + * ---------------------------------------------------------------------------
17671 + * Local variables:
17672 + * c-file-style: "linux"
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
17681 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17682 + * Licensed under the GPL
17685 +#ifndef __KERN_H__
17686 +#define __KERN_H__
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
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);
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
17723 + * ---------------------------------------------------------------------------
17724 + * Local variables:
17725 + * c-file-style: "linux"
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
17734 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
17735 + * Licensed under the GPL
17738 +#ifndef __KERN_UTIL_H__
17739 +#define __KERN_UTIL_H__
17741 +#include "sysdep/ptrace.h"
17744 +extern char *linux_prog;
17745 +extern char *gdb_init;
17746 +extern int kmalloc_ok;
17747 +extern int timer_irq_inited;
17749 +extern int nsyscalls;
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)
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,
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);
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
17851 + * ---------------------------------------------------------------------------
17852 + * Local variables:
17853 + * c-file-style: "linux"
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
17862 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17863 + * Licensed under the GPL
17866 +#ifndef __LINE_H__
17867 +#define __LINE_H__
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"
17876 +struct line_driver {
17878 + char *devfs_name;
17880 + short minor_start;
17884 + char *read_irq_name;
17886 + char *write_irq_name;
17887 + char *symlink_from;
17888 + char *symlink_to;
17889 + struct mc_device mc;
17895 + struct list_head chan_list;
17898 + struct tty_struct *tty;
17899 + struct semaphore sem;
17904 + struct tq_struct task;
17905 + struct line_driver *driver;
17909 +#define LINE_INIT(str, d) \
17910 + { init_str : str, \
17911 + init_pri : INIT_STATIC, \
17912 + chan_list : { }, \
17928 +#define LINES_INIT(n) { num : n }
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,
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);
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
17959 + * ---------------------------------------------------------------------------
17960 + * Local variables:
17961 + * c-file-style: "linux"
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
17971 +sc.h : ../util/mk_sc
17972 + ../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
17982 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
17983 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17984 + * Licensed under the GPL
17987 +#ifndef __MCONSOLE_H__
17988 +#define __MCONSOLE_H__
17990 +#ifndef __KERNEL__
17991 +#include <stdint.h>
17992 +#define u32 uint32_t
17995 +#define MCONSOLE_MAGIC (0xcafebabe)
17996 +#define MCONSOLE_MAX_DATA (512)
17997 +#define MCONSOLE_VERSION 2
17999 +struct mconsole_request {
18003 + char data[MCONSOLE_MAX_DATA];
18006 +struct mconsole_reply {
18010 + char data[MCONSOLE_MAX_DATA];
18013 +struct mconsole_notify {
18016 + enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
18017 + MCONSOLE_USER_NOTIFY } type;
18019 + char data[MCONSOLE_MAX_DATA];
18022 +struct mc_request;
18024 +enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
18026 +struct mconsole_command
18029 + void (*handler)(struct mc_request *req);
18030 + enum mc_context context;
18036 + int as_interrupt;
18038 + int originating_fd;
18040 + unsigned char origin[128]; /* sockaddr_un */
18042 + struct mconsole_request request;
18043 + struct mconsole_command *cmd;
18046 +extern char mconsole_socket_name[];
18048 +extern int mconsole_unlink_socket(void);
18049 +extern int mconsole_reply(struct mc_request *req, char *reply, int err,
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);
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,
18068 +extern char *mconsole_notify_socket(void);
18069 +extern void lock_notify(void);
18070 +extern void unlock_notify(void);
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
18079 + * ---------------------------------------------------------------------------
18080 + * Local variables:
18081 + * c-file-style: "linux"
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
18090 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
18091 + * Licensed under the GPL
18094 +#ifndef __MCONSOLE_KERN_H__
18095 +#define __MCONSOLE_KERN_H__
18097 +#include "linux/config.h"
18098 +#include "linux/list.h"
18099 +#include "mconsole.h"
18101 +struct mconsole_entry {
18102 + struct list_head list;
18103 + struct mc_request request;
18106 +struct mc_device {
18107 + struct list_head list;
18109 + int (*config)(char *);
18110 + int (*get_config)(char *, char *, int, char **);
18111 + int (*remove)(char *);
18114 +#define CONFIG_CHUNK(str, size, current, chunk, end) \
18116 + current += strlen(chunk); \
18117 + if(current >= size) \
18119 + if(str != NULL){ \
18120 + strcpy(str, chunk); \
18121 + str += strlen(chunk); \
18127 +#ifdef CONFIG_MCONSOLE
18129 +extern void mconsole_register_dev(struct mc_device *new);
18133 +static inline void mconsole_register_dev(struct mc_device *new)
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
18146 + * ---------------------------------------------------------------------------
18147 + * Local variables:
18148 + * c-file-style: "linux"
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
18157 + * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com)
18158 + * Licensed under the GPL
18164 +#include "linux/types.h"
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);
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
18180 + * ---------------------------------------------------------------------------
18181 + * Local variables:
18182 + * c-file-style: "linux"
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
18191 + * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com)
18192 + * Licensed under the GPL
18195 +#ifndef __MEM_KERN_H__
18196 +#define __MEM_KERN_H__
18198 +#include "linux/list.h"
18199 +#include "linux/types.h"
18202 + struct list_head list;
18203 + int (*proc)(int, unsigned long, int, __u64, int);
18206 +extern void register_remapper(struct remapper *info);
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
18215 + * ---------------------------------------------------------------------------
18216 + * Local variables:
18217 + * c-file-style: "linux"
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
18226 + * arch/um/include/mem_user.h
18228 + * BRIEF MODULE DESCRIPTION
18229 + * user side memory interface for support IO memory inside user mode linux
18231 + * Copyright (C) 2001 RidgeRun, Inc.
18232 + * Author: RidgeRun, Inc.
18233 + * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
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.
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.
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.
18256 +#ifndef _MEM_USER_H
18257 +#define _MEM_USER_H
18259 +struct iomem_region {
18260 + struct iomem_region *next;
18264 + unsigned long phys;
18265 + unsigned long virt;
18268 +extern struct iomem_region *iomem_regions;
18269 +extern int iomem_size;
18271 +#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
18273 +extern unsigned long host_task_size;
18274 +extern unsigned long task_size;
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);
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
18302 + * ---------------------------------------------------------------------------
18303 + * Local variables:
18304 + * c-file-style: "linux"
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
18313 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18314 + * Licensed under the GPL
18317 +#ifndef __MODE_H__
18318 +#define __MODE_H__
18320 +#include "uml-config.h"
18322 +#ifdef UML_CONFIG_MODE_TT
18323 +#include "../kernel/tt/include/mode.h"
18326 +#ifdef UML_CONFIG_MODE_SKAS
18327 +#include "../kernel/skas/include/mode.h"
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
18337 + * ---------------------------------------------------------------------------
18338 + * Local variables:
18339 + * c-file-style: "linux"
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
18348 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18349 + * Licensed under the GPL
18352 +#ifndef __MODE_KERN_H__
18353 +#define __MODE_KERN_H__
18355 +#include "linux/config.h"
18357 +#ifdef CONFIG_MODE_TT
18358 +#include "../kernel/tt/include/mode_kern.h"
18361 +#ifdef CONFIG_MODE_SKAS
18362 +#include "../kernel/skas/include/mode_kern.h"
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
18372 + * ---------------------------------------------------------------------------
18373 + * Local variables:
18374 + * c-file-style: "linux"
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
18383 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18384 + * Licensed under the GPL
18387 +#ifndef __UM_NET_KERN_H
18388 +#define __UM_NET_KERN_H
18390 +#include "linux/netdevice.h"
18391 +#include "linux/skbuff.h"
18392 +#include "linux/socket.h"
18393 +#include "linux/list.h"
18396 + struct list_head list;
18397 + struct net_device *dev;
18399 + unsigned char mac[ETH_ALEN];
18403 +struct uml_net_private {
18404 + struct list_head list;
18406 + struct net_device *dev;
18407 + struct timer_list tl;
18408 + struct net_device_stats stats;
18410 + unsigned char mac[ETH_ALEN];
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 *);
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 *);
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 *);
18432 +struct transport {
18433 + struct list_head list;
18435 + int (*setup)(char *, char **, void *);
18436 + struct net_user_info *user;
18437 + struct net_kern_info *kern;
18438 + int private_size;
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);
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
18458 + * ---------------------------------------------------------------------------
18459 + * Local variables:
18460 + * c-file-style: "linux"
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
18469 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18470 + * Licensed under the GPL
18473 +#ifndef __UM_NET_USER_H__
18474 +#define __UM_NET_USER_H__
18476 +#define ETH_ADDR_LEN (6)
18477 +#define ETH_HEADER_ETHERTAP (16)
18478 +#define ETH_HEADER_OTHER (14)
18479 +#define ETH_MAX_PACKET (1500)
18481 +#define UML_NET_VERSION (4)
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 *);
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 *),
18501 +extern void *get_output_buffer(int *len_out);
18502 +extern void free_output_buffer(void *buffer);
18504 +extern int tap_open_common(void *dev, char *gate_addr);
18505 +extern void tap_check_ips(char *gate_addr, char *eth_addr);
18507 +extern void read_output(int fd, char *output_out, int len);
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);
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);
18518 +extern char *split_if_spec(char *str, ...);
18520 +extern int dev_netmask(void *d, void *m);
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
18529 + * ---------------------------------------------------------------------------
18530 + * Local variables:
18531 + * c-file-style: "linux"
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
18540 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18541 + * Licensed under the GPL
18547 +#include "asm/types.h"
18548 +#include "../os/include/file.h"
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
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 */
18566 + * types taken from stat_file() in hostfs_user.c
18567 + * (if they are wrong here, they are wrong there...).
18570 + int ust_major; /* device */
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 */
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 */
18599 +#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
18600 + .t = 0, .a = 0, .e = 0, .cl = 0, \
18603 +static inline struct openflags of_read(struct openflags flags)
18609 +static inline struct openflags of_write(struct openflags flags)
18615 +static inline struct openflags of_rdwr(struct openflags flags)
18617 + return(of_read(of_write(flags)));
18620 +static inline struct openflags of_set_rw(struct openflags flags, int r, int w)
18627 +static inline struct openflags of_sync(struct openflags flags)
18633 +static inline struct openflags of_create(struct openflags flags)
18639 +static inline struct openflags of_trunc(struct openflags flags)
18645 +static inline struct openflags of_append(struct openflags flags)
18651 +static inline struct openflags of_excl(struct openflags flags)
18657 +static inline struct openflags of_cloexec(struct openflags flags)
18663 +static inline struct openflags of_direct(struct openflags flags)
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);
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);
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);
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);
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
18755 + * ---------------------------------------------------------------------------
18756 + * Local variables:
18757 + * c-file-style: "linux"
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
18766 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
18767 + * Licensed under the GPL
18770 +#ifndef __PROCESS_H__
18771 +#define __PROCESS_H__
18773 +#include <asm/sigcontext.h>
18775 +extern void sig_handler(int sig, struct sigcontext sc);
18776 +extern void alarm_handler(int sig, struct sigcontext sc);
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
18785 + * ---------------------------------------------------------------------------
18786 + * Local variables:
18787 + * c-file-style: "linux"
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
18796 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
18797 + * Licensed under the GPL
18800 +#ifndef __PTRACE_USER_H__
18801 +#define __PTRACE_USER_H__
18803 +#include "sysdep/ptrace_user.h"
18805 +/* syscall emulation path in ptrace */
18806 +#ifndef PTRACE_SYSEMU
18807 +#define PTRACE_SYSEMU 31
18810 +extern int use_sysemu;
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);
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
18826 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
18827 + * Licensed under the GPL
18830 +#ifndef __UML_SIGCONTEXT_H__
18831 +#define __UML_SIGCONTEXT_H__
18833 +#include "sysdep/sigcontext.h"
18835 +extern int sc_size(void *data);
18836 +extern void sc_to_sc(void *to_ptr, void *from_ptr);
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
18845 + * ---------------------------------------------------------------------------
18846 + * Local variables:
18847 + * c-file-style: "linux"
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
18856 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18857 + * Licensed under the GPL
18860 +#ifndef __SIGIO_H__
18861 +#define __SIGIO_H__
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);
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
18878 + * ---------------------------------------------------------------------------
18879 + * Local variables:
18880 + * c-file-style: "linux"
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
18889 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
18890 + * Licensed under the GPL
18893 +#ifndef __SIGNAL_KERN_H__
18894 +#define __SIGNAL_KERN_H__
18896 +extern int have_signals(void *t);
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
18905 + * ---------------------------------------------------------------------------
18906 + * Local variables:
18907 + * c-file-style: "linux"
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
18916 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
18917 + * Licensed under the GPL
18920 +#ifndef __SIGNAL_USER_H__
18921 +#define __SIGNAL_USER_H__
18923 +extern int signal_stack_size;
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, ...);
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
18936 + * ---------------------------------------------------------------------------
18937 + * Local variables:
18938 + * c-file-style: "linux"
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
18947 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
18948 + * Licensed under the GPL
18951 +#ifndef __SKAS_PTRACE_H
18952 +#define __SKAS_PTRACE_H
18954 +struct ptrace_faultinfo {
18956 + unsigned long addr;
18959 +struct ptrace_ldt {
18962 + unsigned long bytecount;
18965 +#define PTRACE_FAULTINFO 52
18966 +#define PTRACE_SIGPENDING 53
18967 +#define PTRACE_LDT 54
18968 +#define PTRACE_SWITCH_MM 55
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
18977 + * ---------------------------------------------------------------------------
18978 + * Local variables:
18979 + * c-file-style: "linux"
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
18988 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18989 + * Licensed under the GPL
18992 +#ifndef __SYSCALL_USER_H
18993 +#define __SYSCALL_USER_H
18995 +extern int record_syscall_start(int syscall);
18996 +extern void record_syscall_end(int index, int result);
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
19005 + * ---------------------------------------------------------------------------
19006 + * Local variables:
19007 + * c-file-style: "linux"
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
19016 + * Licensed under the GPL
19019 +#ifndef __UM_SYSDEP_CHECKSUM_H
19020 +#define __UM_SYSDEP_CHECKSUM_H
19022 +#include "linux/string.h"
19023 +#include "asm/uaccess.h"
19026 + * computes the checksum of a memory block at buff, length len,
19027 + * and adds in "sum" (32-bit)
19029 + * returns a 32-bit number suitable for feeding into itself
19030 + * or csum_tcpudp_magic
19032 + * this function must be called with even lengths, except
19033 + * for the last fragment, which may be odd
19035 + * it's best to have buff aligned on a 32-bit boundary
19037 +unsigned int csum_partial(const unsigned char * buff, int len,
19038 + unsigned int sum);
19041 + * the same as csum_partial, but copies from src while it
19042 + * checksums, and handles user-space pointer exceptions correctly, when needed.
19044 + * here even more important to align src and dst on a 32-bit (or even
19045 + * better 64-bit) boundary
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);
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.
19057 + * If you use these functions directly please don't forget the
19062 +unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
19063 + int len, int sum)
19065 + memcpy(dst, src, len);
19066 + return(csum_partial(dst, len, sum));
19070 +unsigned int csum_partial_copy_from_user(const char *src, char *dst,
19071 + int len, int sum, int *err_ptr)
19073 + return csum_partial_copy_from(src, dst, len, sum, err_ptr);
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.
19080 + * these functions should go away after some time.
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);
19087 + * This is a version of ip_compute_csum() optimized for IP headers,
19088 + * which always checksum on 4 octet boundaries.
19090 + * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
19091 + * Arnt Gulbrandsen.
19093 +static inline unsigned short ip_fast_csum(unsigned char * iph,
19094 + unsigned int ihl)
19096 + unsigned int sum;
19098 + __asm__ __volatile__(
19099 + "movl (%1), %0 ;\n"
19100 + "subl $4, %2 ;\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"
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"
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));
19125 + * Fold a partial checksum
19128 +static inline unsigned int csum_fold(unsigned int sum)
19131 + "addl %1, %0 ;\n"
19132 + "adcl $0xffff, %0 ;\n"
19134 + : "r" (sum << 16), "0" (sum & 0xffff0000)
19136 + return (~sum) >> 16;
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)
19146 + "addl %1, %0 ;\n"
19147 + "adcl %2, %0 ;\n"
19148 + "adcl %3, %0 ;\n"
19149 + "adcl $0, %0 ;\n"
19151 + : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum));
19156 + * computes the checksum of the TCP/UDP pseudo-header
19157 + * returns a 16-bit checksum, already complemented
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)
19165 + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
19169 + * this routine is used for miscellaneous IP-like checksums, mainly
19173 +static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
19175 + return csum_fold (csum_partial(buff, len, 0));
19178 +#define _HAVE_ARCH_IPV6_CSUM
19179 +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
19180 + struct in6_addr *daddr,
19182 + unsigned short proto,
19183 + unsigned int sum)
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"
19198 + : "r" (saddr), "r" (daddr),
19199 + "r"(htonl(len)), "r"(htonl(proto)), "0"(sum));
19201 + return csum_fold(sum);
19205 + * Copy and checksum to user
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)
19212 + if (access_ok(VERIFY_WRITE, dst, len))
19213 + return(csum_partial_copy_to(src, dst, len, sum, err_ptr));
19216 + *err_ptr = -EFAULT;
19218 + return -1; /* invalid checksum */
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
19228 + * ---------------------------------------------------------------------------
19229 + * Local variables:
19230 + * c-file-style: "linux"
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
19239 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
19240 + * Licensed under the GPL
19243 +#ifndef __FRAME_I386_H
19244 +#define __FRAME_I386_H
19246 +struct arch_frame_data_raw {
19247 + unsigned long fp_start;
19248 + unsigned long sr;
19251 +struct arch_frame_data {
19252 + int fpstate_size;
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
19262 + * ---------------------------------------------------------------------------
19263 + * Local variables:
19264 + * c-file-style: "linux"
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
19273 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
19274 + * Licensed under the GPL
19277 +#ifndef __FRAME_KERN_I386_H
19278 +#define __FRAME_KERN_I386_H
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
19285 +static inline void *sp_to_sc(unsigned long sp)
19287 + return((void *) sp);
19290 +static inline void *sp_to_uc(unsigned long sp)
19292 + unsigned long uc;
19294 + uc = sp + signal_frame_si.uc_index -
19295 + signal_frame_si.common.sp_index - 4;
19296 + return((void *) uc);
19299 +static inline void *sp_to_rt_sc(unsigned long sp)
19301 + unsigned long sc;
19303 + sc = sp - signal_frame_si.common.sp_index +
19304 + signal_frame_si.common.len - 4;
19305 + return((void *) sc);
19308 +static inline void *sp_to_mask(unsigned long sp)
19310 + unsigned long mask;
19312 + mask = sp - signal_frame_sc.common.sp_index +
19313 + signal_frame_sc.common.len - 8;
19314 + return((void *) mask);
19317 +extern int sc_size(void *data);
19319 +static inline void *sp_to_rt_mask(unsigned long sp)
19321 + unsigned long mask;
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);
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
19336 + * ---------------------------------------------------------------------------
19337 + * Local variables:
19338 + * c-file-style: "linux"
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
19347 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
19348 + * Licensed under the GPL
19351 +#ifndef __FRAME_USER_I386_H
19352 +#define __FRAME_USER_I386_H
19354 +#include <asm/page.h>
19355 +#include "sysdep/frame.h"
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.
19372 +static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data,
19373 + void *end, unsigned long srp)
19375 + unsigned long sr = *((unsigned long *) srp);
19377 + data->fp_start = (unsigned long) end;
19378 + if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK))
19380 + else data->sr = 0;
19383 +static inline void setup_arch_frame(struct arch_frame_data_raw *in,
19384 + struct arch_frame_data *out)
19386 + unsigned long fpstate_start = in->fp_start;
19389 + fpstate_start &= ~PAGE_MASK;
19390 + out->fpstate_size = PAGE_SIZE - fpstate_start;
19393 + out->fpstate_size = in->sr - fpstate_start;
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).
19404 +#define frame_restorer() \
19406 + unsigned long *fp; \
19408 + fp = __builtin_frame_address(0); \
19409 + ((unsigned long) (fp + 1)); \
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
19417 +#define frame_sp() \
19419 + unsigned long *fp; \
19421 + fp = __builtin_frame_address(0); \
19422 + ((unsigned long) (fp + 1)); \
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
19432 + * ---------------------------------------------------------------------------
19433 + * Local variables:
19434 + * c-file-style: "linux"
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
19443 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
19444 + * Licensed under the GPL
19447 +#ifndef __SYSDEP_I386_PTRACE_H
19448 +#define __SYSDEP_I386_PTRACE_H
19450 +#include "uml-config.h"
19452 +#ifdef UML_CONFIG_MODE_TT
19453 +#include "ptrace-tt.h"
19456 +#ifdef UML_CONFIG_MODE_SKAS
19457 +#include "ptrace-skas.h"
19460 +#include "choose-mode.h"
19462 +union uml_pt_regs {
19463 +#ifdef UML_CONFIG_MODE_TT
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;
19483 +#define EMPTY_UML_PT_REGS { }
19485 +extern int mode_tt;
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))
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)
19530 +extern int user_context(unsigned long sp);
19532 +#define UPT_IS_USER(r) \
19533 + CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
19535 +struct syscall_args {
19536 + unsigned long args[6];
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) } } )
19547 +#define UPT_REG(regs, reg) \
19548 + ({ unsigned long val; \
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; \
19568 + panic("Bad register in UPT_REG : %d\n", reg); \
19575 +#define UPT_SET(regs, reg, val) \
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; \
19596 + panic("Bad register in UPT_SET : %d\n", reg); \
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)))
19605 +#define UPT_RESTART_SYSCALL(r) \
19606 + CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
19607 + REGS_RESTART_SYSCALL((r)->skas.regs))
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)
19613 +#define UPT_SEGV_IS_FIXABLE(r) \
19614 + CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
19615 + REGS_SEGV_IS_FIXABLE(&r->skas))
19617 +#define UPT_FAULT_ADDR(r) \
19618 + CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
19620 +#define UPT_FAULT_WRITE(r) \
19621 + CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
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
19630 + * ---------------------------------------------------------------------------
19631 + * Local variables:
19632 + * c-file-style: "linux"
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
19641 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
19642 + * Licensed under the GPL
19645 +#ifndef __SYSDEP_I386_PTRACE_USER_H__
19646 +#define __SYSDEP_I386_PTRACE_USER_H__
19648 +#include <asm/ptrace.h>
19650 +#define PT_OFFSET(r) ((r) * sizeof(long))
19652 +#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX])
19653 +#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX)
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)
19661 +#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX)
19663 +#define PT_IP_OFFSET PT_OFFSET(EIP)
19664 +#define PT_IP(regs) ((regs)[EIP])
19665 +#define PT_SP(regs) ((regs)[UESP])
19667 +#ifndef FRAME_SIZE
19668 +#define FRAME_SIZE (17)
19670 +#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long))
19672 +#define FP_FRAME_SIZE (27)
19673 +#define FPX_FRAME_SIZE (128)
19675 +#ifdef PTRACE_GETREGS
19676 +#define UM_HAVE_GETREGS
19679 +#ifdef PTRACE_SETREGS
19680 +#define UM_HAVE_SETREGS
19683 +#ifdef PTRACE_GETFPREGS
19684 +#define UM_HAVE_GETFPREGS
19687 +#ifdef PTRACE_SETFPREGS
19688 +#define UM_HAVE_SETFPREGS
19691 +#ifdef PTRACE_GETFPXREGS
19692 +#define UM_HAVE_GETFPXREGS
19695 +#ifdef PTRACE_SETFPXREGS
19696 +#define UM_HAVE_SETFPXREGS
19699 +extern void update_debugregs(int seq);
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
19708 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
19709 + * Licensed under the GPL
19712 +#ifndef __SYS_SIGCONTEXT_I386_H
19713 +#define __SYS_SIGCONTEXT_I386_H
19717 +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
19719 +#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
19720 +#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
19722 +#define SC_FAULT_ADDR(sc) SC_CR2(sc)
19723 +#define SC_FAULT_TYPE(sc) SC_ERR(sc)
19725 +#define FAULT_WRITE(err) (err & 2)
19726 +#define TO_SC_ERR(is_write) ((is_write) ? 2 : 0)
19728 +#define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc)))
19730 +#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
19732 +/* ptrace expects that, at the start of a system call, %eax contains
19733 + * -ENOSYS, so this makes it so.
19735 +#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
19737 +/* This is Page Fault */
19738 +#define SEGV_IS_FIXABLE(trap) (trap == 14)
19740 +#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
19742 +extern unsigned long *sc_sigmask(void *sc_ptr);
19743 +extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
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
19751 + * ---------------------------------------------------------------------------
19752 + * Local variables:
19753 + * c-file-style: "linux"
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
19762 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19763 + * Licensed under the GPL
19766 +#include "asm/unistd.h"
19767 +#include "sysdep/ptrace.h"
19769 +typedef long syscall_handler_t(struct pt_regs);
19771 +#define EXECUTE_SYSCALL(syscall, regs) \
19772 + ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs))
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;
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,
19808 +/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
19810 +#define LAST_ARCH_SYSCALL 222
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
19817 + * ---------------------------------------------------------------------------
19818 + * Local variables:
19819 + * c-file-style: "linux"
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
19828 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19829 + * Licensed under the GPL
19832 +#ifndef __SYSDEP_IA64_PTRACE_H
19833 +#define __SYSDEP_IA64_PTRACE_H
19835 +struct sys_pt_regs {
19839 +#define EMPTY_REGS { 0 }
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
19848 + * ---------------------------------------------------------------------------
19849 + * Local variables:
19850 + * c-file-style: "linux"
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
19859 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19860 + * Licensed under the GPL
19863 +#ifndef __SYSDEP_IA64_SIGCONTEXT_H
19864 +#define __SYSDEP_IA64_SIGCONTEXT_H
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
19873 + * ---------------------------------------------------------------------------
19874 + * Local variables:
19875 + * c-file-style: "linux"
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
19884 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19885 + * Licensed under the GPL
19888 +#ifndef __SYSDEP_IA64_SYSCALLS_H
19889 +#define __SYSDEP_IA64_SYSCALLS_H
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
19898 + * ---------------------------------------------------------------------------
19899 + * Local variables:
19900 + * c-file-style: "linux"
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
19909 + * Licensed under the GPL
19912 +#ifndef __SYS_PTRACE_PPC_H
19913 +#define __SYS_PTRACE_PPC_H
19915 +#include "linux/config.h"
19916 +#include "linux/types.h"
19918 +/* the following taken from <asm-ppc/ptrace.h> */
19920 +#ifdef CONFIG_PPC64
19921 +#define PPC_REG unsigned long /*long*/
19923 +#define PPC_REG unsigned long
19925 +struct sys_pt_regs_s {
19929 + PPC_REG orig_gpr3; /* Used for restarting system calls */
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 */
19939 + PPC_REG result; /* Result of a system call */
19942 +#define NUM_REGS (sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG))
19944 +struct sys_pt_regs {
19945 + PPC_REG regs[sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG)];
19948 +#define UM_MAX_REG (PT_FPR0)
19949 +#define UM_MAX_REG_OFFSET (UM_MAX_REG * sizeof(PPC_REG))
19951 +#define EMPTY_REGS { { [ 0 ... NUM_REGS - 1] = 0 } }
19953 +#define UM_REG(r, n) ((r)->regs[n])
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)
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))
19979 +#define UM_SET_SYSCALL_RETURN(_regs, result) \
19981 + if (result < 0) { \
19982 + (_regs)->regs[PT_CCR] |= 0x10000000; \
19983 + UM_SYSCALL_RET((_regs)) = -result; \
19985 + UM_SYSCALL_RET((_regs)) = result; \
19989 +extern void shove_aux_table(unsigned long sp);
19990 +#define UM_FIX_EXEC_STACK(sp) shove_aux_table(sp);
19992 +/* These aren't actually defined. The undefs are just to make sure
19993 + * everyone's clear on the concept.
19995 +#undef UML_HAVE_GETREGS
19996 +#undef UML_HAVE_GETFPREGS
19997 +#undef UML_HAVE_SETREGS
19998 +#undef UML_HAVE_SETFPREGS
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
20007 + * ---------------------------------------------------------------------------
20008 + * Local variables:
20009 + * c-file-style: "linux"
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
20018 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
20019 + * Licensed under the GPL
20022 +#ifndef __SYS_SIGCONTEXT_PPC_H
20023 +#define __SYS_SIGCONTEXT_PPC_H
20025 +#define DSISR_WRITE 0x02000000
20027 +#define SC_FAULT_ADDR(sc) ({ \
20028 + struct sigcontext *_sc = (sc); \
20029 + long retval = -1; \
20030 + switch (_sc->regs->trap) { \
20032 + /* data exception */ \
20033 + retval = _sc->regs->dar; \
20036 + /* instruction exception */ \
20037 + retval = _sc->regs->nip; \
20040 + panic("SC_FAULT_ADDR: unhandled trap type\n"); \
20045 +#define SC_FAULT_WRITE(sc) ({ \
20046 + struct sigcontext *_sc = (sc); \
20047 + long retval = -1; \
20048 + switch (_sc->regs->trap) { \
20050 + /* data exception */ \
20051 + retval = !!(_sc->regs->dsisr & DSISR_WRITE); \
20054 + /* instruction exception: not a write */ \
20058 + panic("SC_FAULT_ADDR: unhandled trap type\n"); \
20063 +#define SC_IP(sc) ((sc)->regs->nip)
20064 +#define SC_SP(sc) ((sc)->regs->gpr[1])
20065 +#define SEGV_IS_FIXABLE(sc) (1)
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
20074 + * ---------------------------------------------------------------------------
20075 + * Local variables:
20076 + * c-file-style: "linux"
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
20085 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
20086 + * Licensed under the GPL
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);
20093 +#define EXECUTE_SYSCALL(syscall, regs) \
20094 + (*sys_call_table[syscall])(UM_SYSCALL_ARG1(®s), \
20095 + UM_SYSCALL_ARG2(®s), \
20096 + UM_SYSCALL_ARG3(®s), \
20097 + UM_SYSCALL_ARG4(®s), \
20098 + UM_SYSCALL_ARG5(®s), \
20099 + UM_SYSCALL_ARG6(®s))
20101 +extern syscall_handler_t sys_mincore;
20102 +extern syscall_handler_t sys_madvise;
20104 +/* old_mmap needs the correct prototype since syscall_kern.c includes
20107 +int old_mmap(unsigned long addr, unsigned long len,
20108 + unsigned long prot, unsigned long flags,
20109 + unsigned long fd, unsigned long offset);
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,
20122 +#define LAST_ARCH_SYSCALL __NR_mincore
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
20129 + * ---------------------------------------------------------------------------
20130 + * Local variables:
20131 + * c-file-style: "linux"
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
20139 +#ifndef __UM_SYSRQ_H
20140 +#define __UM_SYSRQ_H
20142 +extern void show_trace(unsigned long *stack);
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
20151 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
20152 + * Licensed under the GPL
20155 +#ifndef __TEMPFILE_H__
20156 +#define __TEMPFILE_H__
20158 +extern int make_tempfile(const char *template, char **tempname, int do_unlink);
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
20166 + * ---------------------------------------------------------------------------
20167 + * Local variables:
20168 + * c-file-style: "linux"
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
20177 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
20178 + * Licensed under the GPL
20181 +#ifndef __TIME_USER_H__
20182 +#define __TIME_USER_H__
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);
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
20200 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
20201 + * Licensed under the GPL
20207 +extern void mprotect_kernel_vm(int w);
20208 +extern void force_flush_all(void);
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
20217 + * ---------------------------------------------------------------------------
20218 + * Local variables:
20219 + * c-file-style: "linux"
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
20228 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
20229 + * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com)
20230 + * Licensed under the GPL
20233 +#ifndef __UM_UBD_USER_H
20234 +#define __UM_UBD_USER_H
20238 +enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
20240 +struct io_thread_req {
20243 + unsigned long offsets[2];
20244 + unsigned long long offset;
20245 + unsigned long length;
20248 + unsigned long sector_mask;
20249 + unsigned long long cow_offset;
20250 + unsigned long bitmap_words[2];
20252 + unsigned long long map_offset;
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);
20271 +static inline int ubd_test_bit(__u64 bit, unsigned char *data)
20276 + bits = sizeof(data[0]) * 8;
20278 + off = bit % bits;
20279 + return((data[n] & (1 << off)) != 0);
20282 +static inline void ubd_set_bit(__u64 bit, unsigned char *data)
20287 + bits = sizeof(data[0]) * 8;
20289 + off = bit % bits;
20290 + data[n] |= (1 << off);
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
20301 + * ---------------------------------------------------------------------------
20302 + * Local variables:
20303 + * c-file-style: "linux"
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
20312 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
20313 + * Licensed under the GPL
20316 +#ifndef __UMID_H__
20317 +#define __UMID_H__
20319 +extern int umid_file_name(char *name, char *buf, int len);
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
20328 + * ---------------------------------------------------------------------------
20329 + * Local variables:
20330 + * c-file-style: "linux"
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
20339 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
20340 + * Licensed under the GPL
20343 +#ifndef __UML_UACCESS_H__
20344 +#define __UML_UACCESS_H__
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);
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
20361 + * ---------------------------------------------------------------------------
20362 + * Local variables:
20363 + * c-file-style: "linux"
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
20372 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
20373 + * Licensed under the GPL
20376 +#ifndef __ARCH_UM_MMU_H
20377 +#define __ARCH_UM_MMU_H
20379 +#include "linux/config.h"
20380 +#include "choose-mode.h"
20382 +#ifdef CONFIG_MODE_TT
20383 +#include "../kernel/tt/include/mmu.h"
20386 +#ifdef CONFIG_MODE_SKAS
20387 +#include "../kernel/skas/include/mmu.h"
20391 +#ifdef CONFIG_MODE_TT
20392 + struct mmu_context_tt tt;
20394 +#ifdef CONFIG_MODE_SKAS
20395 + struct mmu_context_skas skas;
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
20406 + * ---------------------------------------------------------------------------
20407 + * Local variables:
20408 + * c-file-style: "linux"
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
20417 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
20418 + * Licensed under the GPL
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);
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
20438 + * ---------------------------------------------------------------------------
20439 + * Local variables:
20440 + * c-file-style: "linux"
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
20449 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
20450 + * Licensed under the GPL
20453 +#ifndef __ARCH_UM_UACCESS_H
20454 +#define __ARCH_UM_UACCESS_H
20456 +#include "linux/config.h"
20457 +#include "choose-mode.h"
20459 +#ifdef CONFIG_MODE_TT
20460 +#include "../kernel/tt/include/uaccess.h"
20463 +#ifdef CONFIG_MODE_SKAS
20464 +#include "../kernel/skas/include/uaccess.h"
20467 +#define access_ok(type, addr, size) \
20468 + CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
20470 +static inline int verify_area(int type, const void * addr, unsigned long size)
20472 + return(CHOOSE_MODE_PROC(verify_area_tt, verify_area_skas, type, addr,
20476 +static inline int copy_from_user(void *to, const void *from, int n)
20478 + return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to,
20482 +static inline int copy_to_user(void *to, const void *from, int n)
20484 + return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to,
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.
20495 + * Copies a NUL-terminated string from userspace to kernel space.
20497 + * On success, returns the length of the string (not including the trailing
20500 + * If access to userspace fails, returns -EFAULT (some data may have been
20503 + * If @count is smaller than the length of the string, copies @count bytes
20504 + * and returns @count.
20507 +static inline int strncpy_from_user(char *dst, const char *src, int count)
20509 + return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
20510 + dst, src, count));
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.
20518 + * Zero a block of memory in user space. Caller must check
20519 + * the specified block with access_ok() before calling this function.
20521 + * Returns number of bytes that could not be cleared.
20522 + * On success, this will be zero.
20524 +static inline int __clear_user(void *mem, int len)
20526 + return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
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.
20534 + * Zero a block of memory in user space.
20536 + * Returns number of bytes that could not be cleared.
20537 + * On success, this will be zero.
20539 +static inline int clear_user(void *mem, int len)
20541 + return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
20545 + * strlen_user: - Get the size of a string in user space.
20546 + * @str: The string to measure.
20547 + * @n: The maximum valid length
20549 + * Get the size of a NUL-terminated string in user space.
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.
20555 +static inline int strnlen_user(const void *str, int len)
20557 + return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
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
20567 + * ---------------------------------------------------------------------------
20568 + * Local variables:
20569 + * c-file-style: "linux"
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
20578 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
20579 + * Licensed under the GPL
20582 +#ifndef __USER_H__
20583 +#define __USER_H__
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);
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
20603 + * ---------------------------------------------------------------------------
20604 + * Local variables:
20605 + * c-file-style: "linux"
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
20614 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
20615 + * Licensed under the GPL
20618 +#ifndef __USER_UTIL_H__
20619 +#define __USER_UTIL_H__
20621 +#include "sysdep/ptrace.h"
20623 +#define CATCH_EINTR(expr) while (((expr) < 0) && (errno == EINTR))
20625 +extern int mode_tt;
20627 +extern int grantpt(int __fd);
20628 +extern int unlockpt(int __fd);
20629 +extern char *ptsname(int __fd);
20636 +extern struct cpu_task cpu_tasks[];
20638 +struct signal_info {
20639 + void (*handler)(int, union uml_pt_regs *);
20643 +extern struct signal_info sig_info[];
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;
20653 +extern char host_info[];
20655 +extern char saved_command_line[];
20656 +extern char command_line[];
20658 +extern char *tempdir;
20660 +extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
20661 +extern unsigned long _unprotected_end;
20662 +extern unsigned long brk_start;
20664 +extern int pty_output_sigio;
20665 +extern int pty_close_sigio;
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);
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
20713 + * ---------------------------------------------------------------------------
20714 + * Local variables:
20715 + * c-file-style: "linux"
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
20723 +#include "asm/uaccess.h"
20724 +#include "linux/errno.h"
20726 +extern unsigned int arch_csum_partial(const char *buff, int len, int sum);
20728 +extern unsigned int csum_partial(char *buff, int len, int sum)
20730 + return(arch_csum_partial(buff, len, sum));
20733 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len,
20734 + int sum, int *err_ptr)
20736 + if(copy_to_user(dst, src, len)){
20737 + *err_ptr = -EFAULT;
20741 + return(arch_csum_partial(src, len, sum));
20744 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len,
20745 + int sum, int *err_ptr)
20747 + if(copy_from_user(dst, src, len)){
20748 + *err_ptr = -EFAULT;
20752 + return(arch_csum_partial(dst, len, sum));
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
20760 + * ---------------------------------------------------------------------------
20761 + * Local variables:
20762 + * c-file-style: "linux"
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
20770 + .kstrtab : { *(.kstrtab) }
20772 + . = ALIGN(16); /* Exception table */
20773 + __start___ex_table = .;
20774 + __ex_table : { *(__ex_table) }
20775 + __stop___ex_table = .;
20777 + __start___ksymtab = .; /* Kernel symbol table */
20778 + __ksymtab : { *(__ksymtab) }
20779 + __stop___ksymtab = .;
20781 + .unprotected : { *(.unprotected) }
20783 + PROVIDE (_unprotected_end = .);
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) }
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 = .;
20805 + __exitcall_begin = .;
20806 + .exitcall : { *(.exitcall.exit) }
20807 + __exitcall_end = .;
20808 + __uml_exitcall_begin = .;
20809 + .uml.exitcall : { *(.uml.exitcall.exit) }
20810 + __uml_exitcall_end = .;
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 = .;
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
20829 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
20830 + * Licensed under the GPL
20833 +#include <stdio.h>
20834 +#include <stdlib.h>
20837 +static __initdata char *config = "CONFIG";
20839 +static int __init print_config(char *line, int *add)
20841 + printf("%s", config);
20845 +__uml_setup("--showconfig", print_config,
20847 +" Prints the config file that this UML binary was generated from.\n\n"
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
20855 + * ---------------------------------------------------------------------------
20856 + * Local variables:
20857 + * c-file-style: "linux"
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
20865 +OUTPUT_FORMAT("ELF_FORMAT")
20866 +OUTPUT_ARCH(ELF_ARCH)
20871 + . = START() + SIZEOF_HEADERS;
20872 + .interp : { *(.interp) }
20873 + __binary_start = .;
20874 + . = ALIGN(4096); /* Init code and data */
20876 + __init_begin = .;
20877 + .text.init : { *(.text.init) }
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) }
20915 + .plt : { *(.plt) }
20917 + *(.text .stub .text.* .gnu.linkonce.t.*)
20918 + /* .gnu.warning sections are handled specially by elf32.em. */
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) }
20934 + PROVIDE (_sdata = .);
20936 +include(`arch/um/kernel/common.ld.in')
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) }
20947 + . = ALIGN(KERNEL_STACK_SIZE); /* init_task */
20948 + *(.data.init_task)
20949 + *(.data .data.* .gnu.linkonce.d.*)
20950 + SORT(CONSTRUCTORS)
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) }
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
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.*)))
20978 + KEEP (*crtbegin.o(.dtors))
20979 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
20980 + KEEP (*(SORT(.dtors.*)))
20983 + .jcr : { KEEP (*(.jcr)) }
20984 + .got : { *(.got.plt) *(.got) }
20986 + PROVIDE (edata = .);
20990 + *(.bss .bss.* .gnu.linkonce.b.*)
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);
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. */
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) }
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) }
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
21040 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
21041 + * Licensed under the GPL
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"
21054 +#include "irq_user.h"
21056 +#include "2_5compat.h"
21058 +#include "time_user.h"
21059 +#include "choose-mode.h"
21060 +#include "mode_kern.h"
21062 +void flush_thread(void)
21064 + CHOOSE_MODE(flush_thread_tt(), flush_thread_skas());
21067 +void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
21069 + CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
21072 +extern void log_exec(char **argv, void *tty);
21074 +static int execve1(char *file, char **argv, char **env)
21078 +#ifdef CONFIG_TTY_LOG
21079 + log_exec(argv, current->tty);
21081 + error = do_execve(file, argv, env, ¤t->thread.regs);
21083 + current->ptrace &= ~PT_DTRACE;
21084 + set_cmdline(current_cmd());
21089 +int um_execve(char *file, char **argv, char **env)
21093 + err = execve1(file, argv, env);
21095 + do_longjmp(current->thread.exec_buf, 1);
21099 +int sys_execve(char *file, char **argv, char **env)
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);
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
21120 + * ---------------------------------------------------------------------------
21121 + * Local variables:
21122 + * c-file-style: "linux"
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
21131 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
21132 + * Licensed under the GPL
21135 +#include "linux/init.h"
21136 +#include "linux/ctype.h"
21137 +#include "linux/proc_fs.h"
21138 +#include "asm/uaccess.h"
21140 +/* If read and write race, the read will still atomically read a valid
21143 +int uml_exitcode = 0;
21145 +static int read_proc_exitcode(char *page, char **start, off_t off,
21146 + int count, int *eof, void *data)
21150 + len = sprintf(page, "%d\n", uml_exitcode);
21152 + if(len <= off+count) *eof = 1;
21153 + *start = page + off;
21154 + if(len > count) len = count;
21155 + if(len < 0) len = 0;
21159 +static int write_proc_exitcode(struct file *file, const char *buffer,
21160 + unsigned long count, void *data)
21162 + char *end, buf[sizeof("nnnnn\0")];
21165 + if(copy_from_user(buf, buffer, count))
21167 + tmp = simple_strtol(buf, &end, 0);
21168 + if((*end != '\0') && !isspace(*end))
21170 + uml_exitcode = tmp;
21174 +static int make_proc_exitcode(void)
21176 + struct proc_dir_entry *ent;
21178 + ent = create_proc_entry("exitcode", 0600, &proc_root);
21180 + printk("make_proc_exitcode : Failed to register "
21181 + "/proc/exitcode\n");
21185 + ent->read_proc = read_proc_exitcode;
21186 + ent->write_proc = write_proc_exitcode;
21191 +__initcall(make_proc_exitcode);
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
21198 + * ---------------------------------------------------------------------------
21199 + * Local variables:
21200 + * c-file-style: "linux"
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
21209 + * Copyright (C) 2004 Jeff Dike (jdike@karaya.com)
21210 + * Licensed under the GPL
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"
21220 +#include "kern_util.h"
21222 +static spinlock_t open_files_lock = SPIN_LOCK_UNLOCKED;
21223 +static struct list_head open_files = LIST_HEAD_INIT(open_files);
21225 +#define NUM_RECLAIM 128
21227 +static void reclaim_fds(void)
21229 + struct file_handle *victim;
21230 + int closed = NUM_RECLAIM;
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);
21237 + list_del_init(&victim->list);
21239 + spin_unlock(&open_files_lock);
21242 +int open_file(char *name, struct openflags flags, int mode)
21246 + fd = os_open_file(name, flags, mode);
21247 + if(fd != -EMFILE)
21251 + fd = os_open_file(name, flags, mode);
21256 +void *open_dir(char *file)
21261 + dir = os_open_dir(file, &err);
21264 + if(err != -EMFILE)
21265 + return(ERR_PTR(err));
21269 + dir = os_open_dir(file, &err);
21271 + dir = ERR_PTR(err);
21276 +void not_reclaimable(struct file_handle *fh)
21280 + if(fh->get_name == NULL)
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);
21289 + else printk("File descriptor %d has no name\n", fh->fd);
21292 + spin_lock(&open_files_lock);
21293 + list_del_init(&fh->list);
21294 + spin_unlock(&open_files_lock);
21298 +void is_reclaimable(struct file_handle *fh, char *(name_proc)(struct inode *),
21299 + struct inode *inode)
21301 + fh->get_name = name_proc;
21302 + fh->inode = inode;
21304 + spin_lock(&open_files_lock);
21305 + list_add(&fh->list, &open_files);
21306 + spin_unlock(&open_files_lock);
21309 +static int active_handle(struct file_handle *fh)
21314 + if(!list_empty(&fh->list))
21315 + list_move(&fh->list, &open_files);
21320 + if(fh->inode == NULL)
21323 + name = (*fh->get_name)(fh->inode);
21327 + fd = open_file(name, fh->flags, 0);
21333 + is_reclaimable(fh, fh->get_name, fh->inode);
21338 +int filehandle_fd(struct file_handle *fh)
21342 + err = active_handle(fh);
21349 +static void init_fh(struct file_handle *fh, int fd, struct openflags flags)
21352 + *fh = ((struct file_handle) { .list = LIST_HEAD_INIT(fh->list),
21354 + .get_name = NULL,
21356 + .flags = flags });
21359 +int open_filehandle(char *name, struct openflags flags, int mode,
21360 + struct file_handle *fh)
21364 + fd = open_file(name, flags, mode);
21368 + init_fh(fh, fd, flags);
21372 +int close_file(struct file_handle *fh)
21374 + spin_lock(&open_files_lock);
21375 + list_del(&fh->list);
21376 + spin_unlock(&open_files_lock);
21378 + os_close_file(fh->fd);
21384 +int read_file(struct file_handle *fh, unsigned long long offset, char *buf,
21389 + err = active_handle(fh);
21393 + err = os_seek_file(fh->fd, offset);
21397 + return(os_read_file(fh->fd, buf, len));
21400 +int write_file(struct file_handle *fh, unsigned long long offset,
21401 + const char *buf, int len)
21405 + err = active_handle(fh);
21410 + err = os_seek_file(fh->fd, offset);
21414 + return(os_write_file(fh->fd, buf, len));
21417 +int truncate_file(struct file_handle *fh, unsigned long long size)
21421 + err = active_handle(fh);
21425 + return(os_truncate_fd(fh->fd, size));
21428 +int make_pipe(struct file_handle *fhs)
21432 + err = os_pipe(fds, 1, 1);
21433 + if(err && (err != -EMFILE))
21438 + err = os_pipe(fds, 1, 1);
21443 + init_fh(&fhs[0], fds[0], OPENFLAGS());
21444 + init_fh(&fhs[1], fds[1], OPENFLAGS());
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
21453 + * ---------------------------------------------------------------------------
21454 + * Local variables:
21455 + * c-file-style: "linux"
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
21464 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
21465 + * Licensed under the GPL
21468 +#include <stdio.h>
21469 +#include <stdlib.h>
21470 +#include <unistd.h>
21471 +#include <string.h>
21472 +#include <signal.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"
21490 +static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
21491 + unsigned long top, void **data_out)
21493 + unsigned long regs[FRAME_SIZE];
21494 + int pid, status, n, len;
21496 + /* Start the child as a thread */
21497 + pid = clone(child, sp, CLONE_VM | SIGCHLD, arg);
21499 + printf("capture_stack : clone failed - errno = %d\n", errno);
21503 + /* Wait for it to stop itself and continue it with a SIGUSR1 to force
21504 + * it into the signal handler.
21506 + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
21508 + printf("capture_stack : waitpid failed - errno = %d\n", errno);
21511 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
21512 + fprintf(stderr, "capture_stack : Expected SIGSTOP, "
21513 + "got status = 0x%x\n", status);
21516 + if(ptrace(PTRACE_CONT, pid, 0, SIGUSR1) < 0){
21517 + printf("capture_stack : PTRACE_CONT failed - errno = %d\n",
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.
21526 + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
21528 + printf("capture_stack : waitpid failed - errno = %d\n", errno);
21531 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
21532 + fprintf(stderr, "capture_stack : Expected SIGSTOP, "
21533 + "got status = 0x%x\n", status);
21536 + if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0){
21537 + printf("capture_stack : PTRACE_GETREGS failed - errno = %d\n",
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",
21548 + CATCH_EINTR(n = waitpid(pid, &status, 0));
21550 + printf("capture_stack : waitpid failed - errno = %d\n", errno);
21553 + if(!WIFSIGNALED(status) || (WTERMSIG(status) != 9)){
21554 + printf("capture_stack : Expected exit signal 9, "
21555 + "got status = 0x%x\n", status);
21559 + /* The frame that we want is the top of the signal stack */
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);
21567 + memcpy(*data_out, (void *) PT_SP(regs), len);
21572 +struct common_raw {
21575 + unsigned long sig;
21576 + unsigned long sr;
21577 + unsigned long sp;
21578 + struct arch_frame_data_raw arch;
21581 +#define SA_RESTORER (0x04000000)
21583 +typedef unsigned long old_sigset_t;
21585 +struct old_sigaction {
21586 + __sighandler_t handler;
21587 + old_sigset_t sa_mask;
21588 + unsigned long sa_flags;
21589 + void (*sa_restorer)(void);
21592 +static void child_common(struct common_raw *common, sighandler_t handler,
21593 + int restorer, int flags)
21595 + stack_t ss = ((stack_t) { .ss_sp = common->stack,
21597 + .ss_size = common->size });
21600 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
21601 + printf("PTRACE_TRACEME failed, errno = %d\n", errno);
21603 + if(sigaltstack(&ss, NULL) < 0){
21604 + printf("sigaltstack failed - errno = %d\n", errno);
21605 + kill(getpid(), SIGKILL);
21609 + struct sigaction sa;
21611 + sa.sa_handler = handler;
21612 + sigemptyset(&sa.sa_mask);
21613 + sa.sa_flags = SA_ONSTACK | flags;
21614 + err = sigaction(SIGUSR1, &sa, NULL);
21617 + struct old_sigaction sa;
21619 + sa.handler = handler;
21621 + sa.sa_flags = (SA_ONSTACK | flags) & ~SA_RESTORER;
21622 + err = syscall(__NR_sigaction, SIGUSR1, &sa, NULL);
21626 + printf("sigaction failed - errno = %d\n", errno);
21627 + kill(getpid(), SIGKILL);
21630 + os_stop_process(os_getpid());
21633 +/* Changed only during early boot */
21634 +struct sc_frame signal_frame_sc;
21636 +struct sc_frame signal_frame_sc_sr;
21638 +struct sc_frame_raw {
21639 + struct common_raw common;
21640 + unsigned long sc;
21644 +/* Changed only during early boot */
21645 +static struct sc_frame_raw *raw_sc = NULL;
21647 +static void sc_handler(int sig, struct sigcontext sc)
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) ≻
21653 + setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr);
21655 + os_stop_process(os_getpid());
21656 + kill(getpid(), SIGKILL);
21659 +static int sc_child(void *arg)
21662 + child_common(&raw_sc->common, (sighandler_t) sc_handler,
21663 + raw_sc->restorer, 0);
21667 +/* Changed only during early boot */
21668 +struct si_frame signal_frame_si;
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;
21678 +/* Changed only during early boot */
21679 +static struct si_frame_raw *raw_si = NULL;
21681 +static void si_handler(int sig, siginfo_t *si, struct ucontext *ucontext)
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);
21693 + os_stop_process(os_getpid());
21694 + kill(getpid(), SIGKILL);
21697 +static int si_child(void *arg)
21700 + child_common(&raw_si->common, (sighandler_t) si_handler, 1,
21705 +static int relative_sr(unsigned long sr, int sr_index, void *stack,
21708 + unsigned long *srp = (unsigned long *) sr;
21709 + unsigned long frame = (unsigned long) framep;
21711 + if((*srp & PAGE_MASK) == (unsigned long) stack){
21713 + *((unsigned long *) (frame + sr_index)) = *srp;
21719 +static unsigned long capture_stack_common(int (*proc)(void *), void *arg,
21720 + struct common_raw *common_in,
21721 + void *top, void *sigstack,
21723 + struct frame_common *common_out)
21725 + unsigned long sig_top = (unsigned long) sigstack + stack_len, base;
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);
21741 +void capture_signal_stack(void)
21743 + struct sc_frame_raw raw_sc;
21744 + struct si_frame_raw raw_si;
21745 + void *stack, *sigstack;
21746 + unsigned long top, base;
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",
21758 + top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
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);
21766 + signal_frame_sc.sc_index = raw_sc.sc - base;
21767 + setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc.common.arch);
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);
21777 + /* And the siginfo layout */
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);
21788 + if((munmap(stack, PAGE_SIZE) < 0) ||
21789 + (munmap(sigstack, PAGE_SIZE) < 0)){
21790 + printf("capture_signal_stack : munmap failed - errno = %d\n",
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
21801 + * ---------------------------------------------------------------------------
21802 + * Local variables:
21803 + * c-file-style: "linux"
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
21812 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
21813 + * Licensed under the GPL
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"
21826 +int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
21828 + if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
21830 + if (from->si_code < 0)
21831 + return __copy_to_user(to, from, sizeof(siginfo_t));
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:
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);
21853 + err |= __put_user(from->si_uid, &to->si_uid);
21860 +static int copy_restorer(void (*restorer)(void), unsigned long start,
21861 + unsigned long sr_index, int sr_relative)
21863 + unsigned long sr;
21866 + sr = (unsigned long) restorer;
21867 + sr += start + sr_index;
21868 + restorer = (void (*)(void)) sr;
21871 + return(copy_to_user((void *) (start + sr_index), &restorer,
21872 + sizeof(restorer)));
21875 +extern int userspace_pid[];
21877 +static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from,
21878 + struct arch_frame_data *arch)
21880 + return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
21882 + copy_sc_to_user_skas(userspace_pid[0], to, fp,
21884 + current->thread.cr2,
21885 + current->thread.err)));
21888 +static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set,
21889 + unsigned long sp)
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, ¤t->thread.regs,
21897 + &signal_frame_si.common.arch);
21898 + err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
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,
21907 + unsigned long start;
21908 + void *sip, *ucp, *fp;
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));
21915 + if(restorer == NULL)
21916 + panic("setup_signal_stack_si - no restorer");
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,
21925 + copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) ||
21926 + copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp,
21928 + copy_restorer(restorer, start, signal_frame_si.common.sr_index,
21929 + signal_frame_si.common.sr_relative))
21932 + PT_REGS_IP(regs) = handler;
21933 + PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
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)
21941 + struct frame_common *frame = &signal_frame_sc_sr.common;
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;
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);
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,
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))
21968 + PT_REGS_IP(regs) = handler;
21969 + PT_REGS_SP(regs) = start + frame->sp_index;
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
21979 + * ---------------------------------------------------------------------------
21980 + * Local variables:
21981 + * c-file-style: "linux"
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
21990 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
21991 + * Licensed under the GPL
21994 +#include "linux/module.h"
21996 +extern void __bb_init_func(void *);
21997 +EXPORT_SYMBOL(__bb_init_func);
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
22004 + * ---------------------------------------------------------------------------
22005 + * Local variables:
22006 + * c-file-style: "linux"
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
22015 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
22016 + * Licensed under the GPL
22019 +#include "linux/module.h"
22021 +extern void mcount(void);
22022 +EXPORT_SYMBOL(mcount);
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
22029 + * ---------------------------------------------------------------------------
22030 + * Local variables:
22031 + * c-file-style: "linux"
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
22040 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22041 + * Licensed under the GPL
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>
22052 +#include "kern_util.h"
22053 +#include "user_util.h"
22056 +struct helper_data {
22057 + void (*pre_exec)(void*);
22063 +/* Debugging aid, changed only from gdb */
22064 +int helper_pause = 0;
22066 +static void helper_hup(int sig)
22070 +static int helper_child(void *arg)
22072 + struct helper_data *data = arg;
22073 + char **argv = data->argv;
22076 + if(helper_pause){
22077 + signal(SIGHUP, helper_hup);
22080 + if(data->pre_exec != NULL)
22081 + (*data->pre_exec)(data->pre_data);
22082 + execvp(argv[0], argv);
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);
22090 +/* XXX The alloc_stack here breaks if this is called in the tracing thread */
22092 +int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
22093 + unsigned long *stack_out)
22095 + struct helper_data data;
22096 + unsigned long stack, sp;
22097 + int pid, fds[2], err, n;
22099 + if((stack_out != NULL) && (*stack_out != 0))
22100 + stack = *stack_out;
22101 + else stack = alloc_stack(0, um_in_interrupt());
22105 + err = os_pipe(fds, 1, 0);
22107 + printk("run_helper : pipe failed, err = %d\n", -err);
22111 + err = os_set_exec_close(fds[1], 1);
22113 + printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
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);
22125 + printk("run_helper : clone failed, errno = %d\n", errno);
22130 + os_close_file(fds[1]);
22131 + n = os_read_file(fds[0], &err, sizeof(err));
22133 + printk("run_helper : read on pipe failed, err = %d\n", -n);
22135 + os_kill_process(pid, 1);
22138 + CATCH_EINTR(n = waitpid(pid, NULL, 0));
22144 + os_close_file(fds[0]);
22146 + if(stack_out == NULL)
22147 + free_stack(stack, 0);
22148 + else *stack_out = stack;
22152 +int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
22153 + unsigned long *stack_out, int stack_order)
22155 + unsigned long stack, sp;
22158 + stack = alloc_stack(stack_order, um_in_interrupt());
22159 + if(stack == 0) return(-ENOMEM);
22161 + sp = stack + (page_size() << stack_order) - sizeof(void *);
22162 + pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
22164 + printk("run_helper_thread : clone failed, errno = %d\n",
22168 + if(stack_out == NULL){
22169 + CATCH_EINTR(pid = waitpid(pid, &status, 0));
22171 + printk("run_helper_thread - wait failed, errno = %d\n",
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);
22180 + else *stack_out = stack;
22184 +int helper_wait(int pid, int block)
22188 + CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG));
22190 + printk("helper_wait : waitpid failed, errno = %d\n", errno);
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
22201 + * ---------------------------------------------------------------------------
22202 + * Local variables:
22203 + * c-file-style: "linux"
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
22212 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
22213 + * Licensed under the GPL
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"
22226 +/* Changed by uml_initrd_setup, which is a setup */
22227 +static char *initrd __initdata = NULL;
22229 +static int __init read_initrd(void)
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;
22246 +__uml_postsetup(read_initrd);
22248 +static int __init uml_initrd_setup(char *line, int *add)
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"
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
22265 + * ---------------------------------------------------------------------------
22266 + * Local variables:
22267 + * c-file-style: "linux"
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
22276 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
22277 + * Licensed under the GPL
22280 +#include <unistd.h>
22281 +#include <sys/types.h>
22282 +#include <sys/stat.h>
22283 +#include <errno.h>
22285 +#include "user_util.h"
22286 +#include "kern_util.h"
22288 +#include "initrd.h"
22291 +int load_initrd(char *filename, void *buf, int size)
22295 + fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
22297 + printk("Opening '%s' failed - err = %d\n", filename, -fd);
22300 + n = os_read_file(fd, buf, size);
22302 + printk("Read of %d bytes from '%s' failed, err = %d\n", size,
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
22314 + * ---------------------------------------------------------------------------
22315 + * Local variables:
22316 + * c-file-style: "linux"
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
22325 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
22326 + * Licensed under the GPL
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"
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);
22344 + * Initial task structure.
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..
22351 +union task_union init_task_union
22352 +__attribute__((__section__(".data.init_task"))) =
22353 +{ INIT_TASK(init_task_union.task) };
22355 +struct task_struct *alloc_task_struct(void)
22357 + return((struct task_struct *)
22358 + __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
22361 +void unprotect_stack(unsigned long stack)
22363 + protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
22367 +void free_task_struct(struct task_struct *task)
22369 + /* free_pages decrements the page counter and only actually frees
22370 + * the pages if they are now not accessed by anything.
22372 + free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
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
22380 + * ---------------------------------------------------------------------------
22381 + * Local variables:
22382 + * c-file-style: "linux"
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
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
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"
22422 +static void register_irq_proc (unsigned int irq);
22424 +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
22425 + { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
22428 + * Generic no controller code
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)
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.
22442 + printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
22443 +#ifdef CONFIG_X86_LOCAL_APIC
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
22457 +/* startup is the same as "enable", shutdown is same as "disable" */
22458 +#define shutdown_none disable_none
22459 +#define end_none enable_none
22461 +struct hw_interrupt_type no_irq_type = {
22472 + * Generic, controller-independent functions:
22475 +int get_irq_list(char *buf)
22478 + unsigned long flags;
22479 + struct irqaction * action;
22482 + p += sprintf(p, " ");
22483 + for (j=0; j<smp_num_cpus; j++)
22484 + p += sprintf(p, "CPU%d ",j);
22487 + for (i = 0 ; i < NR_IRQS ; i++) {
22488 + spin_lock_irqsave(&irq_desc[i].lock, flags);
22489 + action = irq_desc[i].action;
22492 + p += sprintf(p, "%3d: ",i);
22493 +#ifndef CONFIG_SMP
22494 + p += sprintf(p, "%10u ", kstat_irqs(i));
22496 + for (j = 0; j < smp_num_cpus; j++)
22497 + p += sprintf(p, "%10u ",
22498 + kstat.irqs[cpu_logical_map(j)][i]);
22500 + p += sprintf(p, " %14s", irq_desc[i].handler->typename);
22501 + p += sprintf(p, " %s", action->name);
22503 + for (action=action->next; action; action = action->next)
22504 + p += sprintf(p, ", %s", action->name);
22507 + spin_unlock_irqrestore(&irq_desc[i].lock, flags);
22509 + p += sprintf(p, "\n");
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");
22519 + p += sprintf(p, "ERR: %10lu\n", 0L);
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
22530 +int handle_IRQ_event(unsigned int irq, struct pt_regs * regs,
22531 + struct irqaction * action)
22534 + int cpu = smp_processor_id();
22536 + irq_enter(cpu, irq);
22538 + status = 1; /* Force the "do bottom halves" bit */
22540 + if (!(action->flags & SA_INTERRUPT))
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);
22552 + irq_exit(cpu, irq);
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.
22565 + * disable_irq_nosync - disable an irq without waiting
22566 + * @irq: Interrupt to disable
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.
22572 + * This function may be called from IRQ context.
22575 +void inline disable_irq_nosync(unsigned int irq)
22577 + irq_desc_t *desc = irq_desc + irq;
22578 + unsigned long flags;
22580 + spin_lock_irqsave(&desc->lock, flags);
22581 + if (!desc->depth++) {
22582 + desc->status |= IRQ_DISABLED;
22583 + desc->handler->disable(irq);
22585 + spin_unlock_irqrestore(&desc->lock, flags);
22589 + * disable_irq - disable an irq and wait for completion
22590 + * @irq: Interrupt to disable
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.
22598 + * This function may be called - with care - from IRQ context.
22601 +void disable_irq(unsigned int irq)
22603 + disable_irq_nosync(irq);
22605 + if (!local_irq_count(smp_processor_id())) {
22608 + } while (irq_desc[irq].status & IRQ_INPROGRESS);
22613 + * enable_irq - enable interrupt handling on an irq
22614 + * @irq: Interrupt to enable
22616 + * Re-enables the processing of interrupts on this IRQ line
22617 + * providing no disable_irq calls are now in effect.
22619 + * This function may be called from IRQ context.
22622 +void enable_irq(unsigned int irq)
22624 + irq_desc_t *desc = irq_desc + irq;
22625 + unsigned long flags;
22627 + spin_lock_irqsave(&desc->lock, flags);
22628 + switch (desc->depth) {
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);
22636 + desc->handler->enable(irq);
22637 + /* fall-through */
22643 + printk(KERN_ERR "enable_irq() unbalanced from %p\n",
22644 + __builtin_return_address(0));
22646 + spin_unlock_irqrestore(&desc->lock, flags);
22650 + * do_IRQ handles all normal device IRQ's (the special
22651 + * SMP cross-CPU interrupts have their own specific
22654 +unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
22657 + * 0 return value means that this irq is already being
22658 + * handled by some other CPU. (or is disabled)
22660 + int cpu = smp_processor_id();
22661 + irq_desc_t *desc = irq_desc + irq;
22662 + struct irqaction * action;
22663 + unsigned int status;
22665 + kstat.irqs[cpu][irq]++;
22666 + spin_lock(&desc->lock);
22667 + desc->handler->ack(irq);
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
22672 + status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
22673 + status |= IRQ_PENDING; /* we _want_ to handle it */
22676 + * If the IRQ is disabled for whatever reason, we cannot
22677 + * use the action we have.
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 */
22685 + desc->status = status;
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.
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.
22707 + spin_unlock(&desc->lock);
22708 + handle_IRQ_event(irq, (struct pt_regs *) regs, action);
22709 + spin_lock(&desc->lock);
22711 + if (!(desc->status & IRQ_PENDING))
22713 + desc->status &= ~IRQ_PENDING;
22715 + desc->status &= ~IRQ_INPROGRESS;
22718 + * The ->end() handler has to deal with interrupts which got
22719 + * disabled while the handler was running.
22721 + desc->handler->end(irq);
22722 + spin_unlock(&desc->lock);
22724 + if (softirq_pending(cpu))
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
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.
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.
22748 + * If your interrupt is shared you must pass a non NULL dev_id
22749 + * as this is required when freeing the interrupt.
22753 + * SA_SHIRQ Interrupt is shared
22755 + * SA_INTERRUPT Disable local interrupts while processing
22757 + * SA_SAMPLE_RANDOM The interrupt can be used for entropy
22761 +int request_irq(unsigned int irq,
22762 + void (*handler)(int, void *, struct pt_regs *),
22763 + unsigned long irqflags,
22764 + const char * devname,
22768 + struct irqaction * action;
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).
22777 + if (irqflags & SA_SHIRQ) {
22779 + printk(KERN_ERR "Bad boy: %s (at 0x%x) called us "
22780 + "without a dev_id!\n", devname, (&irq)[-1]);
22784 + if (irq >= NR_IRQS)
22789 + action = (struct irqaction *)
22790 + kmalloc(sizeof(struct irqaction), GFP_KERNEL);
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;
22801 + retval = setup_irq(irq, action);
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,
22814 + err = request_irq(irq, handler, irqflags, devname, dev_id);
22819 + err = activate_fd(irq, fd, type, dev_id);
22823 +/* this was setup_x86_irq but it seems pretty generic */
22824 +int setup_irq(unsigned int irq, struct irqaction * new)
22827 + unsigned long flags;
22828 + struct irqaction *old, **p;
22829 + irq_desc_t *desc = irq_desc + irq;
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.
22836 + if (new->flags & SA_SAMPLE_RANDOM) {
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.
22845 + rand_initialize_irq(irq);
22849 + * The following block of code has to be executed atomically
22851 + spin_lock_irqsave(&desc->lock,flags);
22852 + p = &desc->action;
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);
22861 + /* add new interrupt at end of irq queue */
22873 + desc->status &= ~IRQ_DISABLED;
22874 + desc->handler->startup(irq);
22876 + spin_unlock_irqrestore(&desc->lock,flags);
22878 + register_irq_proc(irq);
22883 + * free_irq - free an interrupt
22884 + * @irq: Interrupt line to free
22885 + * @dev_id: Device identity to free
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.
22894 + * This function may be called from interrupt context.
22896 + * Bugs: Attempting to free an irq in a handler for the same irq hangs
22900 +void free_irq(unsigned int irq, void *dev_id)
22902 + irq_desc_t *desc;
22903 + struct irqaction **p;
22904 + unsigned long flags;
22906 + if (irq >= NR_IRQS)
22909 + desc = irq_desc + irq;
22910 + spin_lock_irqsave(&desc->lock,flags);
22911 + p = &desc->action;
22913 + struct irqaction * action = *p;
22915 + struct irqaction **pp = p;
22916 + p = &action->next;
22917 + if (action->dev_id != dev_id)
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);
22926 + free_irq_by_irq_and_dev(irq, dev_id);
22927 + spin_unlock_irqrestore(&desc->lock,flags);
22930 + /* Wait to make sure it's not being used on another CPU */
22931 + while (desc->status & IRQ_INPROGRESS)
22937 + printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
22938 + spin_unlock_irqrestore(&desc->lock,flags);
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];
22948 +/* These are read and written as longs, so a read won't see a partial write
22949 + * even during a race.
22951 +static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
22953 +#define HEX_DIGITS 8
22955 +static int irq_affinity_read_proc (char *page, char **start, off_t off,
22956 + int count, int *eof, void *data)
22958 + if (count < HEX_DIGITS+1)
22960 + return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
22963 +static unsigned int parse_hex_value (const char *buffer,
22964 + unsigned long count, unsigned long *ret)
22966 + unsigned char hexnum [HEX_DIGITS];
22967 + unsigned long value;
22972 + if (count > HEX_DIGITS)
22973 + count = HEX_DIGITS;
22974 + if (copy_from_user(hexnum, buffer, count))
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.
22983 + for (i = 0; i < count; i++) {
22984 + unsigned int c = hexnum[i];
22987 + case '0' ... '9': c -= '0'; break;
22988 + case 'a' ... 'f': c -= 'a'-10; break;
22989 + case 'A' ... 'F': c -= 'A'-10; break;
22993 + value = (value << 4) | c;
23000 +static int irq_affinity_write_proc (struct file *file, const char *buffer,
23001 + unsigned long count, void *data)
23003 + int irq = (long) data, full_count = count, err;
23004 + unsigned long new_value;
23006 + if (!irq_desc[irq].handler->set_affinity)
23009 + err = parse_hex_value(buffer, count, &new_value);
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.
23017 + if (!(new_value & cpu_online_map))
23021 + irq_affinity[irq] = new_value;
23022 + irq_desc[irq].handler->set_affinity(irq, new_value);
23024 + return full_count;
23027 +static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
23028 + int count, int *eof, void *data)
23030 + unsigned long *mask = (unsigned long *) data;
23031 + if (count < HEX_DIGITS+1)
23033 + return sprintf (page, "%08lx\n", *mask);
23036 +static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
23037 + unsigned long count, void *data)
23039 + unsigned long *mask = (unsigned long *) data, full_count = count, err;
23040 + unsigned long new_value;
23042 + err = parse_hex_value(buffer, count, &new_value);
23046 + *mask = new_value;
23047 + return full_count;
23050 +#define MAX_NAMELEN 10
23052 +static void register_irq_proc (unsigned int irq)
23054 + struct proc_dir_entry *entry;
23055 + char name [MAX_NAMELEN];
23057 + if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
23061 + memset(name, 0, MAX_NAMELEN);
23062 + sprintf(name, "%d", irq);
23064 + /* create /proc/irq/1234 */
23065 + irq_dir[irq] = proc_mkdir(name, root_irq_dir);
23067 + /* create /proc/irq/1234/smp_affinity */
23068 + entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
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;
23075 + smp_affinity_entry[irq] = entry;
23078 +/* Read and written as a long */
23079 +unsigned long prof_cpu_mask = -1;
23081 +void __init init_irq_proc (void)
23083 + struct proc_dir_entry *entry;
23086 + /* create /proc/irq */
23087 + root_irq_dir = proc_mkdir("irq", 0);
23089 + /* create /proc/irq/prof_cpu_mask */
23090 + entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
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;
23098 + * Create entries for all existing IRQs.
23100 + for (i = 0; i < NR_IRQS; i++)
23101 + register_irq_proc(i);
23104 +static spinlock_t irq_spinlock = SPIN_LOCK_UNLOCKED;
23106 +unsigned long irq_lock(void)
23108 + unsigned long flags;
23110 + spin_lock_irqsave(&irq_spinlock, flags);
23114 +void irq_unlock(unsigned long flags)
23116 + spin_unlock_irqrestore(&irq_spinlock, flags);
23119 +unsigned long probe_irq_on(void)
23124 +int probe_irq_off(unsigned long val)
23129 +static unsigned int startup_SIGIO_irq(unsigned int irq)
23134 +static void shutdown_SIGIO_irq(unsigned int irq)
23138 +static void enable_SIGIO_irq(unsigned int irq)
23142 +static void disable_SIGIO_irq(unsigned int irq)
23146 +static void mask_and_ack_SIGIO(unsigned int irq)
23150 +static void end_SIGIO_irq(unsigned int irq)
23154 +static unsigned int startup_SIGVTALRM_irq(unsigned int irq)
23159 +static void shutdown_SIGVTALRM_irq(unsigned int irq)
23163 +static void enable_SIGVTALRM_irq(unsigned int irq)
23167 +static void disable_SIGVTALRM_irq(unsigned int irq)
23171 +static void mask_and_ack_SIGVTALRM(unsigned int irq)
23175 +static void end_SIGVTALRM_irq(unsigned int irq)
23179 +static struct hw_interrupt_type SIGIO_irq_type = {
23181 + startup_SIGIO_irq,
23182 + shutdown_SIGIO_irq,
23183 + enable_SIGIO_irq,
23184 + disable_SIGIO_irq,
23185 + mask_and_ack_SIGIO,
23190 +static struct hw_interrupt_type SIGVTALRM_irq_type = {
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,
23201 +void __init init_IRQ(void)
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;
23217 + init_irq_signals(0);
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
23225 + * ---------------------------------------------------------------------------
23226 + * Local variables:
23227 + * c-file-style: "linux"
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
23236 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
23237 + * Licensed under the GPL
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"
23251 +#include "process.h"
23252 +#include "signal_user.h"
23253 +#include "sigio.h"
23254 +#include "irq_user.h"
23258 + struct irq_fd *next;
23265 + int current_events;
23269 +static struct irq_fd *active_fds = NULL;
23270 +static struct irq_fd **last_irq_ptr = &active_fds;
23272 +static struct pollfd *pollfds = NULL;
23273 +static int pollfds_num = 0;
23274 +static int pollfds_size = 0;
23276 +extern int io_count, intr_count;
23278 +void sigio_handler(int sig, union uml_pt_regs *regs)
23280 + struct irq_fd *irq_fd, *next;
23283 + if(smp_sigio_handler()) return;
23285 + n = poll(pollfds, pollfds_num, 0);
23287 + if(errno == EINTR) continue;
23288 + printk("sigio_handler : poll returned %d, "
23289 + "errno = %d\n", n, errno);
23292 + if(n == 0) break;
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;
23300 + irq_fd = irq_fd->next;
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);
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
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.
23319 + next = irq_fd->next;
23320 + if(irq_fd->freed)
23321 + free_irq(irq_fd->irq, irq_fd->id);
23327 +int activate_ipi(int fd, int pid)
23329 + return(os_set_fd_async(fd, pid));
23332 +static void maybe_sigio_broken(int fd, int type)
23335 + if((type == IRQ_WRITE) && !pty_output_sigio){
23336 + write_sigio_workaround();
23337 + add_sigio_fd(fd, 0);
23339 + else if((type == IRQ_READ) && !pty_close_sigio){
23340 + write_sigio_workaround();
23341 + add_sigio_fd(fd, 1);
23346 +int activate_fd(int irq, int fd, int type, void *dev_id)
23348 + struct pollfd *tmp_pfd;
23349 + struct irq_fd *new_fd, *irq_fd;
23350 + unsigned long flags;
23351 + int pid, events, err, n, size;
23353 + pid = os_getpid();
23354 + err = os_set_fd_async(fd, pid);
23358 + new_fd = um_kmalloc(sizeof(*new_fd));
23360 + if(new_fd == NULL)
23363 + if(type == IRQ_READ) events = POLLIN | POLLPRI;
23364 + else events = POLLOUT;
23365 + *new_fd = ((struct irq_fd) { .next = NULL,
23371 + .events = events,
23372 + .current_events = 0,
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.
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
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);
23399 + if(n == pollfds_size){
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.
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)
23412 + if(n == pollfds_size)
23416 + if(pollfds != NULL){
23417 + memcpy(tmp_pfd, pollfds,
23418 + sizeof(pollfds[0]) * pollfds_size);
23421 + pollfds = tmp_pfd;
23425 + if(type == IRQ_WRITE)
23428 + pollfds[pollfds_num] = ((struct pollfd) { .fd = fd,
23429 + .events = events,
23433 + *last_irq_ptr = new_fd;
23434 + last_irq_ptr = &new_fd->next;
23436 + irq_unlock(flags);
23438 + /* This calls activate_fd, so it has to be outside the critical
23441 + maybe_sigio_broken(fd, type);
23446 + irq_unlock(flags);
23452 +static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
23454 + struct irq_fd **prev;
23455 + unsigned long flags;
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);
23470 + memcpy(&pollfds[i], &pollfds[i + 1],
23471 + (pollfds_num - i - 1) * sizeof(pollfds[0]));
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);
23481 + prev = &(*prev)->next;
23485 + irq_unlock(flags);
23488 +struct irq_and_dev {
23493 +static int same_irq_and_dev(struct irq_fd *irq, void *d)
23495 + struct irq_and_dev *data = d;
23497 + return((irq->irq == data->irq) && (irq->id == data->dev));
23500 +void free_irq_by_irq_and_dev(int irq, void *dev)
23502 + struct irq_and_dev data = ((struct irq_and_dev) { .irq = irq,
23505 + free_irq_by_cb(same_irq_and_dev, &data);
23508 +static int same_fd(struct irq_fd *irq, void *fd)
23510 + return(irq->fd == *((int *) fd));
23513 +void free_irq_by_fd(int fd)
23515 + free_irq_by_cb(same_fd, &fd);
23518 +static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
23520 + struct irq_fd *irq;
23523 + for(irq=active_fds; irq != NULL; irq = irq->next){
23524 + if((irq->fd == fd) && (irq->irq == irqnum)) break;
23528 + printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
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);
23543 +void free_irq_later(int irq, void *dev_id)
23545 + struct irq_fd *irq_fd;
23546 + unsigned long flags;
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))
23553 + if(irq_fd == NULL){
23554 + printk("free_irq_later found no irq, irq = %d, "
23555 + "dev_id = 0x%p\n", irq, dev_id);
23558 + irq_fd->freed = 1;
23560 + irq_unlock(flags);
23563 +void reactivate_fd(int fd, int irqnum)
23565 + struct irq_fd *irq;
23566 + unsigned long flags;
23569 + flags = irq_lock();
23570 + irq = find_irq_by_fd(fd, irqnum, &i);
23572 + irq_unlock(flags);
23576 + pollfds[i].fd = irq->fd;
23578 + irq_unlock(flags);
23580 + /* This calls activate_fd, so it has to be outside the critical
23583 + maybe_sigio_broken(fd, irq->type);
23586 +void deactivate_fd(int fd, int irqnum)
23588 + struct irq_fd *irq;
23589 + unsigned long flags;
23592 + flags = irq_lock();
23593 + irq = find_irq_by_fd(fd, irqnum, &i);
23596 + pollfds[i].fd = -1;
23598 + irq_unlock(flags);
23601 +int deactivate_all_fds(void)
23603 + struct irq_fd *irq;
23606 + for(irq=active_fds;irq != NULL;irq = irq->next){
23607 + err = os_clear_fd_async(irq->fd);
23615 +void forward_ipi(int fd, int pid)
23619 + err = os_set_owner(fd, pid);
23621 + printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
23622 + "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
23625 +void forward_interrupts(int pid)
23627 + struct irq_fd *irq;
23628 + unsigned long flags;
23631 + flags = irq_lock();
23632 + for(irq=active_fds;irq != NULL;irq = irq->next){
23633 + err = os_set_owner(irq->fd, pid);
23635 + /* XXX Just remove the irq rather than
23636 + * print out an infinite stream of these
23638 + printk("Failed to forward %d to pid %d, err = %d\n",
23639 + irq->fd, pid, -err);
23644 + irq_unlock(flags);
23647 +void init_irq_signals(int on_sigstack)
23649 + __sighandler_t h;
23652 + flags = on_sigstack ? SA_ONSTACK : 0;
23653 + if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
23654 + else h = boot_timer_handler;
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);
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
23668 + * ---------------------------------------------------------------------------
23669 + * Local variables:
23670 + * c-file-style: "linux"
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
23679 + * Copyright (C) 2001 - 2004 Jeff Dike (jdike@addtoit.com)
23680 + * Licensed under the GPL
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"
23699 +#include "helper.h"
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);
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);
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);
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);
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);
23769 +/* This is here because UML expands open to sys_open, not to a system
23770 + * call instruction.
23772 +EXPORT_SYMBOL(sys_open);
23773 +EXPORT_SYMBOL(sys_lseek);
23774 +EXPORT_SYMBOL(sys_read);
23775 +EXPORT_SYMBOL(sys_wait4);
23779 +/* required for SMP */
23781 +extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
23782 +EXPORT_SYMBOL_NOVERS(__write_lock_failed);
23784 +extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
23785 +EXPORT_SYMBOL_NOVERS(__read_lock_failed);
23787 +EXPORT_SYMBOL(kernel_flag_cacheline);
23788 +EXPORT_SYMBOL(smp_num_cpus);
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
23797 + * ---------------------------------------------------------------------------
23798 + * Local variables:
23799 + * c-file-style: "linux"
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
23807 +OUTPUT_FORMAT("elf32-i386")
23813 + . = 2684354560 + SIZEOF_HEADERS;
23815 + __binary_start = .;
23817 + .thread_private : {
23818 + __start_thread_private = .;
23821 + arch/um/kernel/tt/unmap_fin.o (.data)
23822 + __end_thread_private = .;
23825 + .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
23827 + . = ALIGN(4096); /* Init code and data */
23829 + __init_begin = .;
23830 + .text.init : { *(.text.init) }
23835 + /* .gnu.warning sections are handled specially by elf32.em. */
23837 + *(.gnu.linkonce.t*)
23839 + .fini : { *(.fini) } =0x9090
23840 + .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
23841 + .rodata1 : { *(.rodata1) }
23843 + PROVIDE (etext = .);
23846 + PROVIDE (_sdata = .);
23848 + .kstrtab : { *(.kstrtab) }
23850 + . = ALIGN(16); /* Exception table */
23851 + __start___ex_table = .;
23852 + __ex_table : { *(__ex_table) }
23853 + __stop___ex_table = .;
23855 + __start___ksymtab = .; /* Kernel symbol table */
23856 + __ksymtab : { *(__ksymtab) }
23857 + __stop___ksymtab = .;
23859 + .unprotected : { *(.unprotected) }
23861 + PROVIDE (_unprotected_end = .);
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) }
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 = .;
23883 + __exitcall_begin = .;
23884 + .exitcall : { *(.exitcall.exit) }
23885 + __exitcall_end = .;
23886 + __uml_exitcall_begin = .;
23887 + .uml.exitcall : { *(.uml.exitcall.exit) }
23888 + __uml_exitcall_end = .;
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 = .;
23900 + .data.init : { *(.data.init) }
23905 + . = ALIGN(32768); /* init_task */
23906 + *(.data.init_task)
23908 + *(.gnu.linkonce.d*)
23911 + .data1 : { *(.data1) }
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) }
23928 + PROVIDE (edata = .);
23929 + . = ALIGN(0x1000);
23933 + PROVIDE(_bss_start = .);
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) }
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
23959 +OUTPUT_FORMAT("ELF_FORMAT")
23960 +OUTPUT_ARCH(ELF_ARCH)
23965 + . = START() + SIZEOF_HEADERS;
23967 + __binary_start = .;
23968 +ifdef(`MODE_TT', `
23969 + .thread_private : {
23970 + __start_thread_private = .;
23973 + arch/um/kernel/tt/unmap_fin.o (.data)
23974 + __end_thread_private = .;
23977 + .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
23979 + . = ALIGN(4096); /* Init code and data */
23981 + __init_begin = .;
23982 + .text.init : { *(.text.init) }
23987 + /* .gnu.warning sections are handled specially by elf32.em. */
23989 + *(.gnu.linkonce.t*)
23991 + .fini : { *(.fini) } =0x9090
23992 + .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
23993 + .rodata1 : { *(.rodata1) }
23995 + PROVIDE (etext = .);
23998 + PROVIDE (_sdata = .);
24000 +include(`arch/um/kernel/common.ld.in')
24004 + . = ALIGN(KERNEL_STACK_SIZE); /* init_task */
24005 + *(.data.init_task)
24007 + *(.gnu.linkonce.d*)
24010 + .data1 : { *(.data1) }
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) }
24027 + PROVIDE (edata = .);
24028 + . = ALIGN(0x1000);
24032 + PROVIDE(_bss_start = .);
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) }
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
24059 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
24060 + * Licensed under the GPL
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"
24082 +#include "choose-mode.h"
24083 +#include "uml-config.h"
24085 +/* Set in set_stklim, which is called from main and __wrap_malloc.
24086 + * __wrap_malloc only calls it if main hasn't started.
24088 +unsigned long stacksizelim;
24093 +#define PGD_BOUND (4 * 1024 * 1024)
24094 +#define STACKSIZE (8 * 1024 * 1024)
24095 +#define THREAD_NAME_LEN (256)
24097 +static void set_stklim(void)
24099 + struct rlimit lim;
24101 + if(getrlimit(RLIMIT_STACK, &lim) < 0){
24102 + perror("getrlimit");
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");
24112 + stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1);
24115 +static __init void do_uml_initcalls(void)
24117 + initcall_t *call;
24119 + call = &__uml_initcall_start;
24120 + while (call < &__uml_initcall_end){;
24126 +static void last_ditch_exit(int sig)
24128 + CHOOSE_MODE(kmalloc_ok = 0, (void) 0);
24129 + signal(SIGINT, SIG_DFL);
24130 + signal(SIGTERM, SIG_DFL);
24131 + signal(SIGHUP, SIG_DFL);
24136 +extern int uml_exitcode;
24138 +int main(int argc, char **argv, char **envp)
24144 + /* Enable all signals except SIGIO - in some environments, we can
24145 + * enter with some signals blocked
24148 + sigemptyset(&mask);
24149 + sigaddset(&mask, SIGIO);
24150 + if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){
24151 + perror("sigprocmask");
24155 +#ifdef UML_CONFIG_MODE_TT
24156 + /* Allocate memory for thread command lines */
24157 + if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
24159 + char padding[THREAD_NAME_LEN] = {
24160 + [ 0 ... THREAD_NAME_LEN - 2] = ' ', '\0'
24163 + new_argv = malloc((argc + 2) * sizeof(char*));
24165 + perror("Allocating extended argv");
24169 + new_argv[0] = argv[0];
24170 + new_argv[1] = padding;
24172 + for(i = 2; i <= argc; i++)
24173 + new_argv[i] = argv[i - 1];
24174 + new_argv[argc + 1] = NULL;
24176 + execvp(new_argv[0], new_argv);
24177 + perror("execing with extended args");
24182 + linux_prog = argv[0];
24186 + new_argv = malloc((argc + 1) * sizeof(char *));
24187 + if(new_argv == NULL){
24188 + perror("Mallocing argv");
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");
24198 + new_argv[argc] = NULL;
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);
24204 + do_uml_initcalls();
24205 + ret = linux_main(argc, argv);
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.
24217 + unblock_signals();
24219 + err = deactivate_all_fds();
24221 + printf("deactivate_all_fds failed, errno = %d\n", -err);
24223 + execvp(new_argv[0], new_argv);
24224 + perror("Failed to exec kernel");
24228 + return(uml_exitcode);
24231 +#define CAN_KMALLOC() \
24232 + (kmalloc_ok && CHOOSE_MODE((getpid() != tracing_pid), 1))
24234 +extern void *__real_malloc(int);
24236 +void *__wrap_malloc(int size)
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);
24246 + /* glibc people insist that if malloc fails, errno should be
24247 + * set by malloc as well. So we do.
24255 +void *__wrap_calloc(int n, int size)
24257 + void *ptr = __wrap_malloc(n * size);
24259 + if(ptr == NULL) return(NULL);
24260 + memset(ptr, 0, n * size);
24264 +extern void __real_free(void *);
24266 +extern unsigned long high_physmem;
24268 +void __wrap_free(void *ptr)
24270 + unsigned long addr = (unsigned long) ptr;
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
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.
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
24287 + if((addr >= uml_physmem) && (addr < high_physmem)){
24288 + if(CAN_KMALLOC())
24291 + else if((addr >= start_vm) && (addr < end_vm)){
24292 + if(CAN_KMALLOC())
24295 + else __real_free(ptr);
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
24303 + * ---------------------------------------------------------------------------
24304 + * Local variables:
24305 + * c-file-style: "linux"
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
24314 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24315 +# Licensed under the GPL
24318 +O_TARGET = built-in.o
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
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
24333 +subdir-$(CONFIG_MODE_TT) += tt
24334 +subdir-$(CONFIG_MODE_SKAS) += skas
24336 +user-objs-$(CONFIG_TTY_LOG) += tty_log.o
24338 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
24340 +# user_syms.o not included here because Rules.make has its own ideas about
24341 +# building anything in export-objs
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
24346 +DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__
24347 +DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__
24349 +export-objs-$(CONFIG_GPROF) += gprof_syms.o
24350 +export-objs-$(CONFIG_GCOV) += gmon_syms.o
24352 +export-objs = ksyms.o process_kern.o signal_kern.o user_syms.o $(export-objs-y)
24354 +CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \
24355 + -I/usr/include -I../include
24357 +CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
24359 +include $(TOPDIR)/Rules.make
24361 +$(USER_OBJS) : %.o: %.c
24362 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
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.
24368 + $(CC) $(CFLAGS_$@) -c -o $@ $<
24370 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
24372 +config.c : config.c.in $(TOPDIR)/.config
24373 + $(PERL) -e $(QUOTE) < config.c.in > $@
24377 + for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
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
24392 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
24393 + * Licensed under the GPL
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"
24407 +#include "mem_user.h"
24408 +#include "uml_uaccess.h"
24411 +extern char __binary_start;
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;
24420 +static unsigned long brk_end;
24421 +static unsigned long totalram_pages = 0;
24423 +void unmap_physmem(void)
24425 + os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
24428 +static void map_cb(void *unused)
24430 + map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
24433 +#ifdef CONFIG_HIGHMEM
24434 +static void setup_highmem(unsigned long highmem_start,
24435 + unsigned long highmem_len)
24437 + struct page *page;
24438 + unsigned long highmem_pfn;
24441 + highmem_start_page = virt_to_page(highmem_start);
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);
24454 +void mem_init(void)
24456 + unsigned long start;
24458 + /* clear the zero-page */
24459 + memset((void *) empty_zero_page, 0, PAGE_SIZE);
24461 + /* Map in the area just after the brk now that kmalloc is about
24462 + * to be turned on.
24464 + brk_end = (unsigned long) UML_ROUND_UP(sbrk(0));
24466 + initial_thread_cb(map_cb, NULL);
24467 + free_bootmem(__pa(brk_end), uml_reserved - brk_end);
24468 + uml_reserved = brk_end;
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,
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));
24485 +#ifdef CONFIG_HIGHMEM
24486 + setup_highmem(end_iomem, highmem);
24490 +static void __init fixrange_init(unsigned long start, unsigned long end,
24497 + unsigned long vaddr;
24500 + i = __pgd_offset(vaddr);
24501 + j = __pmd_offset(vaddr);
24502 + pgd = pgd_base + i;
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))
24514 + vaddr += PMD_SIZE;
24520 +#ifdef CONFIG_HIGHMEM
24522 +pgprot_t kmap_prot;
24524 +#define kmap_get_fixmap_pte(vaddr) \
24525 + pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
24527 +void __init kmap_init(void)
24529 + unsigned long kmap_vstart;
24531 + /* cache the first kmap pte */
24532 + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
24533 + kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
24535 + kmap_prot = PAGE_KERNEL;
24538 +static void init_highmem(void)
24543 + unsigned long vaddr;
24546 + * Permanent kmaps:
24548 + vaddr = PKMAP_BASE;
24549 + fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, swapper_pg_dir);
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;
24559 +#endif /* CONFIG_HIGHMEM */
24561 +void paging_init(void)
24563 + unsigned long zones_size[MAX_NR_ZONES], vaddr;
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);
24575 + * Fixed mappings, only the page table structure has to be
24576 + * created - mappings will be set by set_fixmap():
24578 + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
24579 + fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir);
24581 +#if CONFIG_HIGHMEM
24586 +struct page *arch_validate(struct page *page, int mask, int order)
24588 + unsigned long addr, zero = 0;
24592 + if(page == NULL) return(page);
24593 + if(PageHighMem(page)) return(page);
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,
24600 + ¤t->thread.fault_addr,
24601 + ¤t->thread.fault_catcher)){
24602 + if(!(mask & __GFP_WAIT)) return(NULL);
24605 + addr += PAGE_SIZE;
24607 + if(i == (1 << order)) return(page);
24608 + page = _alloc_pages(mask, order);
24612 +/* This can't do anything because nothing in the kernel image can be freed
24613 + * since it's not in kernel physical memory.
24616 +void free_initmem(void)
24620 +#ifdef CONFIG_BLK_DEV_INITRD
24622 +void free_initrd_mem(unsigned long start, unsigned long 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++;
24637 +int do_check_pgt_cache(int low, int high)
24640 + if(pgtable_cache_size > high) {
24642 + if (pgd_quicklist) {
24643 + free_pgd_slow(get_pgd_fast());
24646 + if (pmd_quicklist) {
24647 + pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
24650 + if (pte_quicklist) {
24651 + pte_free_slow(pte_alloc_one_fast(NULL, 0));
24654 + } while(pgtable_cache_size > low);
24659 +void show_mem(void)
24661 + int i, total = 0, reserved = 0;
24662 + int shared = 0, cached = 0;
24665 + printk("Mem-info:\n");
24666 + show_free_areas();
24667 + printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
24671 + if(PageHighMem(mem_map + i))
24673 + if(PageReserved(mem_map + i))
24675 + else if(PageSwapCache(mem_map + i))
24677 + else if(page_count(mem_map + i))
24678 + shared += page_count(mem_map + i) - 1;
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);
24689 +/* Changed by meminfo_compat, which is a setup */
24690 +static int meminfo_22 = 0;
24692 +static int meminfo_compat(char *str)
24698 +__setup("22_meminfo", meminfo_compat);
24700 +void si_meminfo(struct sysinfo *val)
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;
24710 + val->freeram <<= PAGE_SHIFT;
24711 + val->bufferram <<= PAGE_SHIFT;
24712 + val->totalram <<= PAGE_SHIFT;
24713 + val->sharedram <<= PAGE_SHIFT;
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
24722 + * ---------------------------------------------------------------------------
24723 + * Local variables:
24724 + * c-file-style: "linux"
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
24733 + * arch/um/kernel/mem_user.c
24735 + * BRIEF MODULE DESCRIPTION
24736 + * user side memory routines for supporting IO memory inside user mode linux
24738 + * Copyright (C) 2001 RidgeRun, Inc.
24739 + * Author: RidgeRun, Inc.
24740 + * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
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.
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.
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.
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"
24775 +#include "user_util.h"
24776 +#include "mem_user.h"
24779 +#include "tempfile.h"
24780 +#include "kern_constants.h"
24782 +extern struct mem_region physmem_region;
24784 +#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
24786 +static int create_tmp_file(unsigned long len)
24791 + fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
24793 + os_print_error(fd, "make_tempfile");
24797 + err = os_mode_fd(fd, 0777);
24799 + os_print_error(err, "os_mode_fd");
24802 + err = os_seek_file(fd, len);
24804 + os_print_error(err, "os_seek_file");
24808 + err = os_write_file(fd, &zero, 1);
24810 + os_print_error(err, "os_write_file");
24817 +void check_tmpexec(void)
24820 + int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
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...");
24826 + if(addr == MAP_FAILED){
24828 + perror("failed");
24830 + printf("/tmp must be not mounted noexec\n");
24834 + munmap(addr, UM_KERN_PAGE_SIZE);
24837 +static int have_devanon(void)
24841 + printk("Checking for /dev/anon on the host...");
24842 + fd = open("/dev/anon", O_RDWR);
24844 + printk("Not available (open failed with errno %d)\n", errno);
24852 +static int create_anon_file(unsigned long len)
24857 + fd = open("/dev/anon", O_RDWR);
24859 + os_print_error(fd, "opening /dev/anon");
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");
24868 + munmap(addr, len);
24873 +int create_mem_file(unsigned long len)
24877 + if(have_devanon())
24878 + fd = create_anon_file(len);
24879 + else fd = create_tmp_file(len);
24881 + err = os_set_exec_close(fd, 1);
24883 + os_print_error(err, "exec_close");
24887 +struct iomem_region *iomem_regions = NULL;
24888 +int iomem_size = 0;
24890 +static int __init parse_iomem(char *str, int *add)
24892 + struct iomem_region *new;
24893 + struct uml_stat buf;
24894 + char *file, *driver;
24895 + int fd, err, size;
24898 + file = strchr(str,',');
24899 + if(file == NULL){
24900 + printf("parse_iomem : failed to parse iomem\n");
24905 + fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
24907 + os_print_error(fd, "parse_iomem - Couldn't open io file");
24911 + err = os_stat_fd(fd, &buf);
24913 + os_print_error(err, "parse_iomem - cannot stat_fd file");
24917 + new = malloc(sizeof(*new));
24919 + perror("Couldn't allocate iomem_region struct");
24923 + size = (buf.ust_size + UM_KERN_PAGE_SIZE) & ~(UM_KERN_PAGE_SIZE - 1);
24925 + *new = ((struct iomem_region) { .next = iomem_regions,
24926 + .driver = driver,
24931 + iomem_regions = new;
24932 + iomem_size += new->size + UM_KERN_PAGE_SIZE;
24936 + os_close_file(fd);
24941 +__uml_setup("iomem=", parse_iomem,
24942 +"iomem=<name>,<file>\n"
24943 +" Configure <file> as an IO memory region named <name>.\n\n"
24946 +int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
24947 + int must_succeed)
24951 + err = os_protect_memory((void *) addr, len, r, w, x);
24954 + panic("protect failed, err = %d", -err);
24955 + else return(err);
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.
24967 +int logging_fd = -1;
24969 +int logging_line = 0;
24970 +char logging_buf[512];
24972 +void log(char *fmt, ...)
24975 + struct timeval tv;
24976 + struct openflags flags;
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);
24983 + gettimeofday(&tv, NULL);
24984 + sprintf(logging_buf, "%d\t %u.%u ", logging_line++, tv.tv_sec,
24986 + va_start(ap, fmt);
24987 + vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
24989 + write(logging_fd, logging_buf, strlen(logging_buf));
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
24998 + * ---------------------------------------------------------------------------
24999 + * Local variables:
25000 + * c-file-style: "linux"
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
25009 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
25010 + * Licensed under the GPL
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"
25024 +#include "mem_user.h"
25029 +struct phys_desc {
25030 + struct rb_node_s rb;
25034 + unsigned long phys;
25035 + struct list_head list;
25038 +static struct rb_root_s phys_mappings = RB_ROOT;
25040 +static struct rb_node_s **find_rb(void *virt)
25042 + struct rb_node_s **n = &phys_mappings.rb_node;
25043 + struct phys_desc *d;
25045 + while(*n != NULL){
25046 + d = rb_entry(n, struct phys_desc, rb);
25047 + if(d->virt == virt)
25050 + if(d->virt > virt)
25051 + n = &(*n)->rb_left;
25053 + n = &(*n)->rb_right;
25059 +static struct phys_desc *find_phys_mapping(void *virt)
25061 + struct rb_node_s **n = find_rb(virt);
25066 + return(rb_entry(n, struct phys_desc, rb));
25069 +static void insert_phys_mapping(struct phys_desc *desc)
25071 + struct rb_node_s **n = find_rb(desc->virt);
25074 + panic("Physical remapping for %p already present",
25077 + rb_link_node(&desc->rb, (*n)->rb_parent, n);
25078 + rb_insert_color(&desc->rb, &phys_mappings);
25081 +LIST_HEAD(descriptor_mappings);
25083 +struct desc_mapping {
25085 + struct list_head list;
25086 + struct list_head pages;
25089 +static struct desc_mapping *find_mapping(int fd)
25091 + struct desc_mapping *desc;
25092 + struct list_head *ele;
25094 + list_for_each(ele, &descriptor_mappings){
25095 + desc = list_entry(ele, struct desc_mapping, list);
25096 + if(desc->fd == fd)
25103 +static struct desc_mapping *descriptor_mapping(int fd)
25105 + struct desc_mapping *desc;
25107 + desc = find_mapping(fd);
25111 + desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
25115 + *desc = ((struct desc_mapping)
25117 + .list = LIST_HEAD_INIT(desc->list),
25118 + .pages = LIST_HEAD_INIT(desc->pages) });
25119 + list_add(&desc->list, &descriptor_mappings);
25124 +int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
25126 + struct desc_mapping *fd_maps;
25127 + struct phys_desc *desc;
25128 + unsigned long phys;
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);
25140 + fd_maps = descriptor_mapping(fd);
25141 + if(fd_maps == NULL)
25145 + desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
25149 + *desc = ((struct phys_desc)
25151 + .offset = offset,
25153 + .phys = __pa(virt),
25154 + .list = LIST_HEAD_INIT(desc->list) });
25155 + insert_phys_mapping(desc);
25157 + list_add(&desc->list, &fd_maps->pages);
25159 + virt = (void *) ((unsigned long) virt & PAGE_MASK);
25160 + err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
25164 + rb_erase(&desc->rb, &phys_mappings);
25170 +static int physmem_fd = -1;
25172 +static void remove_mapping(struct phys_desc *desc)
25174 + void *virt = desc->virt;
25177 + rb_erase(&desc->rb, &phys_mappings);
25178 + list_del(&desc->list);
25181 + err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
25183 + panic("Failed to unmap block device page from physical memory, "
25184 + "errno = %d", -err);
25187 +int physmem_remove_mapping(void *virt)
25189 + struct phys_desc *desc;
25191 + virt = (void *) ((unsigned long) virt & PAGE_MASK);
25192 + desc = find_phys_mapping(virt);
25196 + remove_mapping(desc);
25200 +void physmem_forget_descriptor(int fd)
25202 + struct desc_mapping *desc;
25203 + struct phys_desc *page;
25204 + struct list_head *ele, *next;
25209 + desc = find_mapping(fd);
25213 + if(!list_empty(&desc->pages))
25214 + printk("Still have mapped pages on fd %d\n", fd);
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);
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);
25228 + panic("physmem_forget_descriptor - failed to read "
25229 + "from fd %d to 0x%p, error = %d\n",
25233 + list_del(&desc->list);
25237 +void arch_free_page(struct page *page, int order)
25242 + for(i = 0; i < (1 << order); i++){
25243 + virt = __va(page_to_phys(page + i));
25244 + physmem_remove_mapping(virt);
25248 +int is_remapped(const void *virt, int fd, __u64 offset)
25250 + struct phys_desc *desc;
25252 + desc = find_phys_mapping((void *) virt);
25255 + if(offset != desc->offset)
25256 + printk("offset mismatch\n");
25257 + return(find_phys_mapping((void *) virt) != NULL);
25260 +/* Changed during early boot */
25261 +unsigned long high_physmem;
25263 +extern unsigned long physmem_size;
25265 +void *to_virt(unsigned long phys)
25267 + return((void *) uml_physmem + phys);
25270 +unsigned long to_phys(void *virt)
25272 + return(((unsigned long) virt) - uml_physmem);
25275 +int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
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;
25282 + phys_pages = physmem >> PAGE_SHIFT;
25283 + phys_len = phys_pages * sizeof(struct page);
25285 + iomem_pages = iomem >> PAGE_SHIFT;
25286 + iomem_len = iomem_pages * sizeof(struct page);
25288 + highmem_pages = highmem >> PAGE_SHIFT;
25289 + highmem_len = highmem_pages * sizeof(struct page);
25291 + total_pages = phys_pages + iomem_pages + highmem_pages;
25292 + total_len = phys_len + iomem_pages + highmem_len;
25295 + map = kmalloc(total_len, GFP_KERNEL);
25297 + map = vmalloc(total_len);
25299 + else map = alloc_bootmem_low_pages(total_len);
25304 + for(i = 0; i < total_pages; i++){
25306 + set_page_count(p, 0);
25307 + SetPageReserved(p);
25308 + INIT_LIST_HEAD(&p->list);
25312 + max_mapnr = total_pages;
25316 +struct page *phys_to_page(const unsigned long phys)
25318 + return(&mem_map[phys >> PAGE_SHIFT]);
25321 +struct page *__virt_to_page(const unsigned long virt)
25323 + return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
25326 +unsigned long page_to_phys(struct page *page)
25328 + return((page - mem_map) << PAGE_SHIFT);
25331 +pte_t mk_pte(struct page *page, pgprot_t pgprot)
25335 + pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot);
25336 + if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte));
25340 +/* Changed during early boot */
25341 +static unsigned long kmem_top = 0;
25343 +unsigned long get_kmem_end(void)
25345 + if(kmem_top == 0)
25346 + kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
25347 + return(kmem_top);
25350 +void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
25351 + int r, int w, int x)
25356 + fd = phys_mapping(phys, &offset);
25357 + err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
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);
25363 +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
25365 +void setup_physmem(unsigned long start, unsigned long reserve_end,
25366 + unsigned long len, unsigned long highmem)
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;
25373 + physmem_fd = create_mem_file(len + highmem);
25375 + offset = uml_reserved - uml_physmem;
25376 + err = os_map_memory((void *) uml_reserved, physmem_fd, offset,
25377 + len - offset, 1, 1, 0);
25379 + os_print_error(err, "Mapping memory");
25383 + bootmap_size = init_bootmem(pfn, pfn + delta);
25384 + free_bootmem(__pa(reserve_end) + bootmap_size,
25385 + len - bootmap_size - reserve);
25388 +int phys_mapping(unsigned long phys, __u64 *offset_out)
25390 + struct phys_desc *desc = find_phys_mapping(__va(phys & PAGE_MASK));
25393 + if(desc != NULL){
25395 + *offset_out = desc->offset;
25397 + else if(phys < physmem_size){
25399 + *offset_out = phys;
25401 + else if(phys < __pa(end_iomem)){
25402 + struct iomem_region *region = iomem_regions;
25404 + while(region != NULL){
25405 + if((phys >= region->phys) &&
25406 + (phys < region->phys + region->size)){
25408 + *offset_out = phys - region->phys;
25411 + region = region->next;
25414 + else if(phys < __pa(end_iomem) + highmem){
25416 + *offset_out = phys - iomem_size;
25422 +static int __init uml_mem_setup(char *line, int *add)
25425 + physmem_size = memparse(line,&retptr);
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"
25438 +unsigned long find_iomem(char *driver, unsigned long *len_out)
25440 + struct iomem_region *region = iomem_regions;
25442 + while(region != NULL){
25443 + if(!strcmp(region->driver, driver)){
25444 + *len_out = region->size;
25445 + return(region->virt);
25452 +int setup_iomem(void)
25454 + struct iomem_region *region = iomem_regions;
25455 + unsigned long iomem_start = high_physmem + PAGE_SIZE;
25458 + while(region != NULL){
25459 + err = os_map_memory((void *) iomem_start, region->fd, 0,
25460 + region->size, 1, 1, 0);
25462 + printk("Mapping iomem region for driver '%s' failed, "
25463 + "errno = %d\n", region->driver, -err);
25465 + region->virt = iomem_start;
25466 + region->phys = __pa(region->virt);
25469 + iomem_start += region->size + PAGE_SIZE;
25470 + region = region->next;
25476 +__initcall(setup_iomem);
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
25483 + * ---------------------------------------------------------------------------
25484 + * Local variables:
25485 + * c-file-style: "linux"
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
25494 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
25495 + * Licensed under the GPL
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"
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"
25528 +#include "uml-config.h"
25529 +#include "choose-mode.h"
25531 +#ifdef UML_CONFIG_MODE_SKAS
25533 +#include "skas_ptrace.h"
25536 +void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
25538 + int flags = 0, pages;
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;
25545 + if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
25548 +void init_new_thread_signals(int altstack)
25550 + int flags = altstack ? SA_ONSTACK : 0;
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);
25568 + init_irq_signals(altstack);
25572 + int (*tramp)(void *);
25573 + void *tramp_data;
25574 + unsigned long temp_stack;
25579 +/* See above for why sigkill is here */
25581 +int sigkill = SIGKILL;
25583 +int outer_tramp(void *arg)
25586 + int sig = sigkill;
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);
25596 +int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
25597 + int clone_flags, int (*tramp)(void *))
25599 + struct tramp arg;
25600 + unsigned long sp;
25601 + int new_pid, status, err;
25603 + /* The trampoline will run on the temporary stack */
25604 + sp = stack_sp(temp_stack);
25606 + clone_flags |= CLONE_FILES | SIGCHLD;
25608 + arg.tramp = tramp;
25609 + arg.tramp_data = thread_arg;
25610 + arg.temp_stack = temp_stack;
25611 + arg.flags = clone_flags;
25613 + /* Start the process and wait for it to kill itself */
25614 + new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
25618 + CATCH_EINTR(err = waitpid(new_pid, &status, 0));
25620 + panic("Waiting for outer trampoline failed - errno = %d",
25623 + if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
25624 + panic("outer trampoline didn't exit with SIGKILL, "
25625 + "status = %d", status);
25630 +static int ptrace_child(void *arg)
25632 + int pid = os_getpid();
25634 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
25635 + perror("ptrace");
25636 + os_kill_process(pid, 0);
25638 + os_stop_process(pid);
25639 + _exit(os_getpid() == pid);
25642 +static int start_ptraced_child(void **stack_out)
25645 + unsigned long sp;
25646 + int pid, n, status;
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);
25655 + panic("check_ptrace : clone failed, errno = %d", errno);
25656 + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
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",
25663 + *stack_out = stack;
25667 +static void stop_ptraced_child(int pid, void *stack, int exitcode)
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);
25677 + if(munmap(stack, PAGE_SIZE) < 0)
25678 + panic("check_ptrace : munmap failed, errno = %d", errno);
25681 +int use_sysemu = 0;
25683 +void __init check_ptrace(void)
25686 + int pid, syscall, n, status;
25688 + printk("Checking that ptrace can change system call numbers...");
25689 + pid = start_ptraced_child(&stack);
25692 + if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
25693 + panic("check_ptrace : ptrace failed, errno = %d",
25695 + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
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);
25702 + syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET,
25704 + if(syscall == __NR_getpid){
25705 + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
25708 + panic("check_ptrace : failed to modify system "
25709 + "call, errno = %d", errno);
25713 + stop_ptraced_child(pid, stack, 0);
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));
25721 + panic("check_ptrace : wait failed, errno = %d", errno);
25723 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
25724 + panic("check_ptrace : expected SIGTRAP, "
25725 + "got status = %d", status);
25728 + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET,
25731 + panic("check_ptrace : failed to modify system "
25732 + "call return, errno = %d", errno);
25734 + stop_ptraced_child(pid, stack, 0);
25740 + printk("missing\n");
25741 + stop_ptraced_child(pid, stack, 1);
25745 +int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
25751 + n = sigsetjmp(buf, 1);
25758 +int can_do_skas(void)
25760 +#ifdef UML_CONFIG_MODE_SKAS
25761 + struct ptrace_faultinfo fi;
25763 + int pid, n, ret = 1;
25765 + printf("Checking for the skas3 patch in the host...");
25766 + pid = start_ptraced_child(&stack);
25768 + n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
25771 + printf("not found\n");
25772 + else printf("No (unexpected errno - %d)\n", errno);
25775 + else printf("found\n");
25777 + init_registers(pid);
25778 + stop_ptraced_child(pid, stack, 1);
25780 + printf("Checking for /proc/mm...");
25781 + if(os_access("/proc/mm", OS_ACC_W_OK) < 0){
25782 + printf("not found\n");
25785 + else printf("found\n");
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
25798 + * ---------------------------------------------------------------------------
25799 + * Local variables:
25800 + * c-file-style: "linux"
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
25809 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
25810 + * Licensed under the GPL
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"
25841 +#include "signal_kern.h"
25842 +#include "signal_user.h"
25844 +#include "irq_user.h"
25845 +#include "mem_user.h"
25846 +#include "time_user.h"
25848 +#include "frame_kern.h"
25849 +#include "sigcontext.h"
25850 +#include "2_5compat.h"
25853 +#include "mode_kern.h"
25854 +#include "choose-mode.h"
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
25860 +struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
25862 +struct task_struct *get_task(int pid, int require)
25864 + struct task_struct *ret;
25866 + read_lock(&tasklist_lock);
25867 + ret = find_task_by_pid(pid);
25868 + read_unlock(&tasklist_lock);
25870 + if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
25874 +int external_pid(void *t)
25876 + struct task_struct *task = t ? t : current;
25878 + return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
25881 +int pid_to_processor_id(int pid)
25885 + for(i = 0; i < smp_num_cpus; i++){
25886 + if(cpu_tasks[i].pid == pid) return(i);
25891 +void free_stack(unsigned long stack, int order)
25893 + free_pages(stack, order);
25896 +unsigned long alloc_stack(int order, int atomic)
25898 + unsigned long page;
25899 + int flags = GFP_KERNEL;
25901 + if(atomic) flags |= GFP_ATOMIC;
25902 + page = __get_free_pages(flags, order);
25905 + stack_protections(page);
25909 +int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
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);
25920 + panic("do_fork failed in kernel_thread, errno = %d", pid);
25924 +void switch_mm(struct mm_struct *prev, struct mm_struct *next,
25925 + struct task_struct *tsk, unsigned cpu)
25927 + if (prev != next)
25928 + clear_bit(cpu, &prev->cpu_vm_mask);
25929 + set_bit(cpu, &next->cpu_vm_mask);
25932 +void set_current(void *t)
25934 + struct task_struct *task = t;
25936 + cpu_tasks[task->processor] = ((struct cpu_task)
25937 + { external_pid(task), task });
25940 +void *_switch_to(void *prev, void *next)
25942 + return(CHOOSE_MODE(_switch_to_tt(prev, next),
25943 + _switch_to_skas(prev, next)));
25946 +void interrupt_end(void)
25948 + if(current->need_resched) schedule();
25949 + if(current->sigpending != 0) do_signal(0);
25952 +void release_thread(struct task_struct *task)
25954 + CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
25957 +void exit_thread(void)
25959 + CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
25960 + unprotect_stack((unsigned long) current);
25963 +void *get_current(void)
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)
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));
25977 +void initial_thread_cb(void (*proc)(void *), void *arg)
25979 + int save_kmalloc_ok = kmalloc_ok;
25982 + CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc,
25984 + kmalloc_ok = save_kmalloc_ok;
25987 +unsigned long stack_sp(unsigned long page)
25989 + return(page + PAGE_SIZE - sizeof(void *));
25992 +int current_pid(void)
25994 + return(current->pid);
25997 +void cpu_idle(void)
25999 + CHOOSE_MODE(init_idle_tt(), init_idle_skas());
26001 + atomic_inc(&init_mm.mm_count);
26002 + current->mm = &init_mm;
26003 + current->active_mm = &init_mm;
26006 + /* endless idle loop with no priority at all */
26007 + SET_PRI(current);
26010 + * although we are an idle CPU, we do not want to
26011 + * get into the scheduler unnecessarily.
26013 + if (current->need_resched) {
26015 + check_pgt_cache();
26021 +int page_size(void)
26023 + return(PAGE_SIZE);
26026 +int page_mask(void)
26028 + return(PAGE_MASK);
26031 +void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
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)
26049 + return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK));
26052 +char *current_cmd(void)
26054 +#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
26055 + return("(Unknown)");
26057 + void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
26058 + return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
26062 +void force_sigbus(void)
26064 + printk(KERN_ERR "Killing pid %d because of a lack of memory\n",
26067 + sigaddset(¤t->pending.signal, SIGBUS);
26068 + recalc_sigpending(current);
26069 + current->flags |= PF_SIGNALED;
26070 + do_exit(SIGBUS | 0x80);
26073 +void dump_thread(struct pt_regs *regs, struct user *u)
26077 +void enable_hlt(void)
26079 + panic("enable_hlt");
26082 +void disable_hlt(void)
26084 + panic("disable_hlt");
26087 +extern int signal_frame_size;
26089 +void *um_kmalloc(int size)
26091 + return(kmalloc(size, GFP_KERNEL));
26094 +void *um_kmalloc_atomic(int size)
26096 + return(kmalloc(size, GFP_ATOMIC));
26099 +void *um_vmalloc(int size)
26101 + return(vmalloc(size));
26104 +unsigned long get_fault_addr(void)
26106 + return((unsigned long) current->thread.fault_addr);
26109 +EXPORT_SYMBOL(get_fault_addr);
26111 +void not_implemented(void)
26113 + printk(KERN_DEBUG "Something isn't implemented in here\n");
26116 +EXPORT_SYMBOL(not_implemented);
26118 +int user_context(unsigned long sp)
26120 + unsigned long stack;
26122 + stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
26123 + return(stack != current);
26126 +extern void remove_umid_dir(void);
26128 +__uml_exitcall(remove_umid_dir);
26130 +extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
26132 +void do_uml_exitcalls(void)
26134 + exitcall_t *call;
26136 + call = &__uml_exitcall_end;
26137 + while (--call >= &__uml_exitcall_begin)
26141 +char *uml_strdup(char *string)
26145 + new = kmalloc(strlen(string) + 1, GFP_KERNEL);
26146 + if(new == NULL) return(NULL);
26147 + strcpy(new, string);
26151 +void *get_init_task(void)
26153 + return(&init_task_union.task);
26156 +int copy_to_user_proc(void *to, void *from, int size)
26158 + return(copy_to_user(to, from, size));
26161 +int copy_from_user_proc(void *to, void *from, int size)
26163 + return(copy_from_user(to, from, size));
26166 +int clear_user_proc(void *buf, int size)
26168 + return(clear_user(buf, size));
26171 +int strlen_user_proc(char *str)
26173 + return(strlen_user(str));
26176 +int smp_sigio_handler(void)
26179 + int cpu = current->processor;
26181 + IPI_handler(cpu);
26188 +int um_in_interrupt(void)
26190 + return(in_interrupt());
26195 + return(current->processor);
26198 +int singlestepping(void * t)
26200 + struct task_struct *task = t ? t : current;
26202 + if ( ! (task->ptrace & PT_DTRACE) )
26205 + if (task->thread.singlestep_syscall)
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
26216 + * ---------------------------------------------------------------------------
26217 + * Local variables:
26218 + * c-file-style: "linux"
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
26227 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
26228 + * Licensed under the GPL
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"
26238 +#include "asm/ptrace.h"
26239 +#include "asm/uaccess.h"
26240 +#include "kern_util.h"
26241 +#include "ptrace_user.h"
26244 + * Called by kernel/ptrace.c when detaching..
26246 +void ptrace_disable(struct task_struct *child)
26248 + child->ptrace &= ~PT_DTRACE;
26249 + child->thread.singlestep_syscall = 0;
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);
26257 +int sys_ptrace(long request, long pid, long addr, long data)
26259 + struct task_struct *child;
26264 + if (request == PTRACE_TRACEME) {
26265 + /* are we already being traced? */
26266 + if (current->ptrace & PT_PTRACED)
26268 + /* set the ptrace bit in the process flags. */
26269 + current->ptrace |= PT_PTRACED;
26274 + read_lock(&tasklist_lock);
26275 + child = find_task_by_pid(pid);
26277 + get_task_struct(child);
26278 + read_unlock(&tasklist_lock);
26283 + if (pid == 1) /* you may not mess with init */
26286 + if (request == PTRACE_ATTACH) {
26287 + ret = ptrace_attach(child);
26291 + ret = ptrace_check_attach(child, request == PTRACE_KILL);
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;
26303 + copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
26304 + if (copied != sizeof(tmp))
26306 + ret = put_user(tmp,(unsigned long *) data);
26310 + /* read the word at location addr in the USER area. */
26311 + case PTRACE_PEEKUSR: {
26312 + unsigned long tmp;
26315 + if ((addr & 3) || addr < 0)
26318 + tmp = 0; /* Default return condition */
26319 + if(addr < FRAME_SIZE_OFFSET){
26320 + tmp = getreg(child, addr);
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];
26328 + ret = put_user(tmp, (unsigned long *) data);
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:
26336 + if (access_process_vm(child, addr, &data, sizeof(data),
26337 + 1) != sizeof(data))
26342 + case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
26344 + if ((addr & 3) || addr < 0)
26347 + if (addr < FRAME_SIZE_OFFSET) {
26348 + ret = putreg(child, addr, data);
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;
26362 + case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
26363 + case PTRACE_CONT: { /* restart after signal. */
26365 + if ((unsigned long) data > _NSIG)
26368 + child->ptrace &= ~PT_DTRACE;
26369 + child->thread.singlestep_syscall = 0;
26371 + if (request == PTRACE_SYSCALL)
26372 + child->ptrace |= PT_TRACESYS;
26374 + child->ptrace &= ~PT_TRACESYS;
26375 + child->exit_code = data;
26376 + wake_up_process(child);
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
26386 + case PTRACE_KILL: {
26388 + if (child->state == TASK_ZOMBIE) /* already dead */
26391 + child->ptrace &= ~PT_DTRACE;
26392 + child->thread.singlestep_syscall = 0;
26393 + child->exit_code = SIGKILL;
26394 + wake_up_process(child);
26398 + case PTRACE_SINGLESTEP: { /* set the trap flag. */
26400 + if ((unsigned long) data > _NSIG)
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);
26412 + case PTRACE_DETACH:
26413 + /* detach a process that was attached. */
26414 + ret = ptrace_detach(child, data);
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)) {
26424 + for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
26425 + __put_user(getreg(child, i), (unsigned long *) data);
26426 + data += sizeof(long);
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)) {
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);
26449 +#ifdef PTRACE_GETFPREGS
26450 + case PTRACE_GETFPREGS: /* Get the child FPU state. */
26451 + ret = get_fpregs(data, child);
26454 +#ifdef PTRACE_SETFPREGS
26455 + case PTRACE_SETFPREGS: /* Set the child FPU state. */
26456 + ret = set_fpregs(data, child);
26459 +#ifdef PTRACE_GETFPXREGS
26460 + case PTRACE_GETFPXREGS: /* Get the child FPU state. */
26461 + ret = get_fpxregs(data, child);
26464 +#ifdef PTRACE_SETFPXREGS
26465 + case PTRACE_SETFPXREGS: /* Set the child FPU state. */
26466 + ret = set_fpxregs(data, child);
26469 + case PTRACE_FAULTINFO: {
26470 + struct ptrace_faultinfo fault;
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,
26481 + case PTRACE_SIGPENDING:
26482 + ret = copy_to_user((unsigned long *) data,
26483 + &child->pending.signal,
26484 + sizeof(child->pending.signal));
26487 + case PTRACE_LDT: {
26488 + struct ptrace_ldt ldt;
26490 + if(copy_from_user(&ldt, (unsigned long *) data,
26496 + /* This one is confusing, so just punt and return -EIO for
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);
26508 + ret = PTR_ERR(new);
26512 + atomic_inc(&new->mm_users);
26514 + child->active_mm = new;
26525 + free_task_struct(child);
26531 +void syscall_trace(void)
26533 + int is_singlestep = (current->ptrace & PT_DTRACE);
26535 + if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
26536 + != (PT_PTRACED|PT_TRACESYS) && !is_singlestep)
26538 + current->exit_code = SIGTRAP;
26539 + current->state = TASK_STOPPED;
26540 + notify_parent(current, SIGCHLD);
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
26548 + if (current->exit_code) {
26549 + send_sig(current->exit_code, current, 1);
26550 + current->exit_code = 0;
26553 + if(is_syscall(PT_REGS_IP(¤t->thread.regs)))
26554 + current->thread.singlestep_syscall = 1;
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
26562 + * ---------------------------------------------------------------------------
26563 + * Local variables:
26564 + * c-file-style: "linux"
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
26573 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
26574 + * Licensed under the GPL
26577 +#include "linux/sched.h"
26578 +#include "user_util.h"
26579 +#include "kern_util.h"
26583 +#include "choose-mode.h"
26586 +static void kill_idlers(int me)
26588 +#ifdef CONFIG_MODE_TT
26589 + struct task_struct *p;
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);
26602 +static void kill_off_processes(void)
26604 + CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas());
26606 + kill_idlers(os_getpid());
26610 +void uml_cleanup(void)
26612 + kill_off_processes();
26613 + do_uml_exitcalls();
26616 +void machine_restart(char * __unused)
26618 + do_uml_exitcalls();
26619 + kill_off_processes();
26620 + CHOOSE_MODE(reboot_tt(), reboot_skas());
26623 +void machine_power_off(void)
26625 + do_uml_exitcalls();
26626 + kill_off_processes();
26627 + CHOOSE_MODE(halt_tt(), halt_skas());
26630 +void machine_halt(void)
26632 + machine_power_off();
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
26640 + * ---------------------------------------------------------------------------
26641 + * Local variables:
26642 + * c-file-style: "linux"
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
26651 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
26652 + * Licensed under the GPL
26655 +#include "linux/pci.h"
26657 +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
26658 + unsigned long start, unsigned long size)
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
26668 + * ---------------------------------------------------------------------------
26669 + * Local variables:
26670 + * c-file-style: "linux"
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
26679 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
26680 + * Licensed under the GPL
26683 +#include "linux/kernel.h"
26684 +#include "linux/list.h"
26685 +#include "linux/slab.h"
26686 +#include "asm/irq.h"
26688 +#include "sigio.h"
26689 +#include "irq_user.h"
26690 +#include "irq_kern.h"
26692 +/* Protected by sigio_lock() called from write_sigio_workaround */
26693 +static int sigio_irq_fd = -1;
26695 +static void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
26697 + read_sigio_fd(sigio_irq_fd);
26698 + reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
26701 +int write_sigio_irq(int fd)
26705 + err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
26706 + SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio",
26709 + printk("write_sigio_irq : um_request_irq failed, err = %d\n",
26713 + sigio_irq_fd = fd;
26717 +static spinlock_t sigio_spinlock = SPIN_LOCK_UNLOCKED;
26719 +void sigio_lock(void)
26721 + spin_lock(&sigio_spinlock);
26724 +void sigio_unlock(void)
26726 + spin_unlock(&sigio_spinlock);
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
26734 + * ---------------------------------------------------------------------------
26735 + * Local variables:
26736 + * c-file-style: "linux"
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
26745 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
26746 + * Licensed under the GPL
26749 +#include <unistd.h>
26750 +#include <stdlib.h>
26751 +#include <termios.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>
26761 +#include "kern_util.h"
26762 +#include "user_util.h"
26763 +#include "sigio.h"
26764 +#include "helper.h"
26767 +/* Changed during early boot */
26768 +int pty_output_sigio = 0;
26769 +int pty_close_sigio = 0;
26771 +/* Used as a flag during SIGIO testing early in boot */
26772 +static volatile int got_sigio = 0;
26774 +void __init handler(int sig)
26779 +struct openpty_arg {
26785 +static void openpty_cb(void *arg)
26787 + struct openpty_arg *info = arg;
26790 + if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
26791 + info->err = -errno;
26794 +void __init check_one_sigio(void (*proc)(int, int))
26796 + struct sigaction old, new;
26797 + struct openpty_arg pty = { .master = -1, .slave = -1 };
26798 + int master, slave, err;
26800 + initial_thread_cb(openpty_cb, &pty);
26802 + printk("openpty failed, errno = %d\n", -pty.err);
26806 + master = pty.master;
26807 + slave = pty.slave;
26809 + if((master == -1) || (slave == -1)){
26810 + printk("openpty failed to allocate a pty\n");
26814 + /* Not now, but complain so we now where we failed. */
26815 + err = raw(master);
26817 + panic("check_sigio : __raw failed, errno = %d\n", -err);
26819 + err = os_sigio_async(master, slave);
26821 + panic("tty_fds : sigio_async failed, err = %d\n", -err);
26823 + if(sigaction(SIGIO, NULL, &old) < 0)
26824 + panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
26826 + new.sa_handler = handler;
26827 + if(sigaction(SIGIO, &new, NULL) < 0)
26828 + panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
26831 + (*proc)(master, slave);
26833 + os_close_file(master);
26834 + os_close_file(slave);
26836 + if(sigaction(SIGIO, &old, NULL) < 0)
26837 + panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
26840 +static void tty_output(int master, int slave)
26845 + printk("Checking that host ptys support output SIGIO...");
26847 + memset(buf, 0, sizeof(buf));
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) ;
26856 + pty_output_sigio = 1;
26858 + else if(n == -EAGAIN) printk("No, enabling workaround\n");
26859 + else panic("check_sigio : read failed, err = %d\n", n);
26862 +static void tty_close(int master, int slave)
26864 + printk("Checking that host ptys support SIGIO on close...");
26866 + os_close_file(slave);
26869 + pty_close_sigio = 1;
26871 + else printk("No, enabling workaround\n");
26874 +void __init check_sigio(void)
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 "
26882 + check_one_sigio(tty_output);
26883 + check_one_sigio(tty_close);
26886 +/* Protected by sigio_lock(), also used by sigio_cleanup, which is an
26889 +static int write_sigio_pid = -1;
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.
26895 +static int write_sigio_fds[2] = { -1, -1 };
26896 +static int sigio_private[2] = { -1, -1 };
26899 + struct pollfd *poll;
26904 +/* Protected by sigio_lock(). Used by the sigio thread, but the UML thread
26905 + * synchronizes with it.
26907 +struct pollfds current_poll = {
26913 +struct pollfds next_poll = {
26919 +static int write_sigio_thread(void *unused)
26921 + struct pollfds *fds, tmp;
26922 + struct pollfd *p;
26923 + int i, n, respond_fd;
26926 + fds = ¤t_poll;
26928 + n = poll(fds->poll, fds->used, -1);
26930 + if(errno == EINTR) continue;
26931 + printk("write_sigio_thread : poll returned %d, "
26932 + "errno = %d\n", n, errno);
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;
26945 + respond_fd = sigio_private[1];
26948 + respond_fd = write_sigio_fds[1];
26950 + memmove(&fds->poll[i], &fds->poll[i + 1],
26951 + (fds->used - i) * sizeof(*fds->poll));
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);
26962 +static int need_poll(int n)
26964 + if(n <= next_poll.size){
26965 + next_poll.used = n;
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;
26976 + next_poll.size = n;
26977 + next_poll.used = n;
26981 +static void update_thread(void)
26983 + unsigned long flags;
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);
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);
27000 + set_signals(flags);
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]);
27012 + set_signals(flags);
27015 +int add_sigio_fd(int fd, int read)
27017 + int err = 0, i, n, events;
27020 + for(i = 0; i < current_poll.used; i++){
27021 + if(current_poll.poll[i].fd == fd)
27025 + n = current_poll.used + 1;
27026 + err = need_poll(n);
27030 + for(i = 0; i < current_poll.used; i++)
27031 + next_poll.poll[i] = current_poll.poll[i];
27033 + if(read) events = POLLIN;
27034 + else events = POLLOUT;
27036 + next_poll.poll[n - 1] = ((struct pollfd) { .fd = fd,
27037 + .events = events,
27045 +int ignore_sigio_fd(int fd)
27047 + struct pollfd *p;
27048 + int err = 0, i, n = 0;
27051 + for(i = 0; i < current_poll.used; i++){
27052 + if(current_poll.poll[i].fd == fd) break;
27054 + if(i == current_poll.used)
27057 + err = need_poll(current_poll.used - 1);
27061 + for(i = 0; i < current_poll.used; i++){
27062 + p = ¤t_poll.poll[i];
27063 + if(p->fd != fd) next_poll.poll[n++] = current_poll.poll[i];
27066 + printk("ignore_sigio_fd : fd %d not found\n", fd);
27077 +static int setup_initial_poll(int fd)
27079 + struct pollfd *p;
27081 + p = um_kmalloc(sizeof(struct pollfd));
27083 + printk("setup_initial_poll : failed to allocate poll\n");
27086 + *p = ((struct pollfd) { .fd = fd,
27087 + .events = POLLIN,
27089 + current_poll = ((struct pollfds) { .poll = p,
27095 +void write_sigio_workaround(void)
27097 + unsigned long stack;
27101 + if(write_sigio_pid != -1)
27104 + err = os_pipe(write_sigio_fds, 1, 1);
27106 + printk("write_sigio_workaround - os_pipe 1 failed, "
27107 + "err = %d\n", -err);
27110 + err = os_pipe(sigio_private, 1, 1);
27112 + printk("write_sigio_workaround - os_pipe 2 failed, "
27113 + "err = %d\n", -err);
27116 + if(setup_initial_poll(sigio_private[1]))
27119 + write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
27120 + CLONE_FILES | CLONE_VM, &stack, 0);
27122 + if(write_sigio_pid < 0) goto out_close2;
27124 + if(write_sigio_irq(write_sigio_fds[0]))
27132 + os_kill_process(write_sigio_pid, 1);
27133 + write_sigio_pid = -1;
27135 + os_close_file(sigio_private[0]);
27136 + os_close_file(sigio_private[1]);
27138 + os_close_file(write_sigio_fds[0]);
27139 + os_close_file(write_sigio_fds[1]);
27143 +int read_sigio_fd(int fd)
27148 + n = os_read_file(fd, &c, sizeof(c));
27149 + if(n != sizeof(c)){
27151 + printk("read_sigio_fd - read failed, err = %d\n", -n);
27155 + printk("read_sigio_fd - short read, bytes = %d\n", n);
27162 +static void sigio_cleanup(void)
27164 + if(write_sigio_pid != -1)
27165 + os_kill_process(write_sigio_pid, 1);
27168 +__uml_exitcall(sigio_cleanup);
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
27175 + * ---------------------------------------------------------------------------
27176 + * Local variables:
27177 + * c-file-style: "linux"
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
27186 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
27187 + * Licensed under the GPL
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"
27207 +#include "frame_kern.h"
27208 +#include "sigcontext.h"
27211 +EXPORT_SYMBOL(block_signals);
27212 +EXPORT_SYMBOL(unblock_signals);
27214 +static void force_segv(int sig)
27216 + if(sig == SIGSEGV){
27217 + struct k_sigaction *ka;
27219 + ka = ¤t->sig->action[SIGSEGV - 1];
27220 + ka->sa.sa_handler = SIG_DFL;
27222 + force_sig(SIGSEGV, current);
27225 +#define _S(nr) (1<<((nr)-1))
27227 +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
27230 + * OK, we're invoking a handler
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)
27236 + __sighandler_t handler;
27237 + void (*restorer)(void);
27238 + unsigned long sp;
27242 + err = PT_REGS_SYSCALL_RET(¤t->thread.regs);
27245 + case -ERESTARTNOHAND:
27249 + case -ERESTARTSYS:
27250 + if (!(ka->sa.sa_flags & SA_RESTART)) {
27254 + /* fallthrough */
27255 + case -ERESTARTNOINTR:
27256 + PT_REGS_RESTART_SYSCALL(regs);
27257 + PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
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.
27266 + ret = PT_REGS_SYSCALL_NR(regs);
27270 + handler = ka->sa.sa_handler;
27273 + if (ka->sa.sa_flags & SA_ONESHOT)
27274 + ka->sa.sa_handler = SIG_DFL;
27276 + if (!(ka->sa.sa_flags & SA_NODEFER)) {
27277 + spin_lock_irq(¤t->sigmask_lock);
27278 + sigorsets(¤t->blocked, ¤t->blocked,
27279 + &ka->sa.sa_mask);
27280 + sigaddset(¤t->blocked, signr);
27281 + recalc_sigpending(current);
27282 + spin_unlock_irq(¤t->sigmask_lock);
27285 + sp = PT_REGS_SP(regs);
27287 + if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
27288 + sp = current->sas_ss_sp + current->sas_ss_size;
27291 + PT_REGS_SET_SYSCALL_RETURN(regs, ret);
27293 + if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer;
27294 + else restorer = NULL;
27296 + if(ka->sa.sa_flags & SA_SIGINFO)
27297 + err = setup_signal_stack_si(sp, signr, (unsigned long) handler,
27298 + restorer, regs, info, &save);
27300 + err = setup_signal_stack_sc(sp, signr, (unsigned long) handler,
27301 + restorer, regs, &save);
27303 + force_segv(signr);
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
27312 +static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error)
27315 + struct k_sigaction *ka;
27318 + oldset = ¤t->blocked;
27321 + unsigned long signr;
27323 + spin_lock_irq(¤t->sigmask_lock);
27324 + signr = dequeue_signal(¤t->blocked, &info);
27325 + spin_unlock_irq(¤t->sigmask_lock);
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);
27337 + /* We're back. Did the debugger cancel the sig? */
27338 + signr = current->exit_code;
27341 + current->exit_code = 0;
27343 + /* The debugger continued. Ignore SIGSTOP. */
27344 + if (signr == SIGSTOP)
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;
27356 + /* If the (new) signal is now blocked, requeue it. */
27357 + if (sigismember(¤t->blocked, signr)) {
27358 + send_sig_info(signr, &info, current);
27363 + ka = ¤t->sig->action[signr-1];
27364 + if (ka->sa.sa_handler == SIG_IGN) {
27365 + if (signr != SIGCHLD)
27367 + /* Check for SIGCHLD: it's special. */
27368 + while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
27373 + if (ka->sa.sa_handler == SIG_DFL) {
27374 + int exit_code = signr;
27376 + /* Init gets no signals it doesn't want. */
27377 + if (current->pid == 1)
27381 + case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
27384 + case SIGTSTP: case SIGTTIN: case SIGTTOU:
27385 + if (is_orphaned_pgrp(current->pgrp))
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);
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, ¤t->thread.regs))
27403 + exit_code |= 0x80;
27407 + sig_exit(signr, exit_code, &info);
27412 + /* Whee! Actually deliver the signal. */
27413 + handle_signal(regs, signr, ka, &info, oldset, error);
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);
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.
27435 + if((current->ptrace & PT_DTRACE) &&
27436 + is_syscall(PT_REGS_IP(¤t->thread.regs)))
27437 + current->thread.singlestep_syscall = 1;
27442 +int do_signal(int error)
27444 + return(kern_do_signal(¤t->thread.regs, NULL, error));
27448 + * Atomically swap in the new signal mask, and wait for a signal.
27450 +int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
27452 + sigset_t saveset;
27454 + mask &= _BLOCKABLE;
27455 + spin_lock_irq(¤t->sigmask_lock);
27456 + saveset = current->blocked;
27457 + siginitset(¤t->blocked, mask);
27458 + recalc_sigpending(current);
27459 + spin_unlock_irq(¤t->sigmask_lock);
27461 + PT_REGS_SYSCALL_RET(¤t->thread.regs) = -EINTR;
27463 + current->state = TASK_INTERRUPTIBLE;
27465 + if(kern_do_signal(¤t->thread.regs, &saveset, -EINTR))
27470 +int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
27472 + sigset_t saveset, newset;
27474 + /* XXX: Don't preclude handling different sized sigset_t's. */
27475 + if (sigsetsize != sizeof(sigset_t))
27478 + if (copy_from_user(&newset, unewset, sizeof(newset)))
27480 + sigdelsetmask(&newset, ~_BLOCKABLE);
27482 + spin_lock_irq(¤t->sigmask_lock);
27483 + saveset = current->blocked;
27484 + current->blocked = newset;
27485 + recalc_sigpending(current);
27486 + spin_unlock_irq(¤t->sigmask_lock);
27488 + PT_REGS_SYSCALL_RET(¤t->thread.regs) = -EINTR;
27490 + current->state = TASK_INTERRUPTIBLE;
27492 + if (kern_do_signal(¤t->thread.regs, &saveset, -EINTR))
27497 +extern int userspace_pid[];
27499 +static int copy_sc_from_user(struct pt_regs *to, void *from,
27500 + struct arch_frame_data *arch)
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));
27510 +int sys_sigreturn(struct pt_regs regs)
27512 + void *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
27513 + void *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
27514 + int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
27516 + spin_lock_irq(¤t->sigmask_lock);
27517 + copy_from_user(¤t->blocked.sig[0], sc_sigmask(sc),
27518 + sizeof(current->blocked.sig[0]));
27519 + copy_from_user(¤t->blocked.sig[1], mask, sig_size);
27520 + sigdelsetmask(¤t->blocked, ~_BLOCKABLE);
27521 + recalc_sigpending(current);
27522 + spin_unlock_irq(¤t->sigmask_lock);
27523 + copy_sc_from_user(¤t->thread.regs, sc,
27524 + &signal_frame_sc.common.arch);
27525 + return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
27528 +int sys_rt_sigreturn(struct pt_regs regs)
27530 + struct ucontext *uc = sp_to_uc(PT_REGS_SP(¤t->thread.regs));
27531 + int sig_size = _NSIG_WORDS * sizeof(unsigned long);
27533 + spin_lock_irq(¤t->sigmask_lock);
27534 + copy_from_user(¤t->blocked, &uc->uc_sigmask, sig_size);
27535 + sigdelsetmask(¤t->blocked, ~_BLOCKABLE);
27536 + recalc_sigpending(current);
27537 + spin_unlock_irq(¤t->sigmask_lock);
27538 + copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext,
27539 + &signal_frame_si.common.arch);
27540 + return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
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
27548 + * ---------------------------------------------------------------------------
27549 + * Local variables:
27550 + * c-file-style: "linux"
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
27559 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
27560 + * Licensed under the GPL
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"
27574 +#include "signal_user.h"
27575 +#include "signal_kern.h"
27576 +#include "sysdep/sigcontext.h"
27577 +#include "sigcontext.h"
27579 +void set_sigstack(void *sig_stack, int size)
27581 + stack_t stack = ((stack_t) { .ss_flags = 0,
27582 + .ss_sp = (__ptr_t) sig_stack,
27583 + .ss_size = size - sizeof(void *) });
27585 + if(sigaltstack(&stack, NULL) != 0)
27586 + panic("enabling signal stack failed, errno = %d\n", errno);
27589 +void set_handler(int sig, void (*handler)(int), int flags, ...)
27591 + struct sigaction action;
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);
27601 + action.sa_flags = flags;
27602 + action.sa_restorer = NULL;
27603 + if(sigaction(sig, &action, NULL) < 0)
27604 + panic("sigaction failed");
27607 +int change_sig(int signal, int on)
27609 + sigset_t sigset, old;
27611 + sigemptyset(&sigset);
27612 + sigaddset(&sigset, signal);
27613 + sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
27614 + return(!sigismember(&old, signal));
27617 +static void change_signals(int type)
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);
27630 +void block_signals(void)
27632 + change_signals(SIG_BLOCK);
27635 +void unblock_signals(void)
27637 + change_signals(SIG_UNBLOCK);
27640 +#define SIGIO_BIT 0
27641 +#define SIGVTALRM_BIT 1
27643 +static int enable_mask(sigset_t *mask)
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;
27653 +int get_signals(void)
27657 + if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
27658 + panic("Failed to get signal mask");
27659 + return(enable_mask(&mask));
27662 +int set_signals(int enable)
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);
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);
27684 + if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
27685 + panic("Failed to block signals");
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
27695 + * ---------------------------------------------------------------------------
27696 + * Local variables:
27697 + * c-file-style: "linux"
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
27706 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27707 + * Licensed under the GPL
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"
27722 +void flush_thread_skas(void)
27724 + force_flush_all();
27725 + switch_mm_skas(current->mm->context.skas.mm_fd);
27728 +void start_thread_skas(struct pt_regs *regs, unsigned long eip,
27729 + unsigned long esp)
27732 + PT_REGS_IP(regs) = eip;
27733 + PT_REGS_SP(regs) = esp;
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
27741 + * ---------------------------------------------------------------------------
27742 + * Local variables:
27743 + * c-file-style: "linux"
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
27752 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27753 + * Licensed under the GPL
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>
27763 +#include "kern_util.h"
27764 +#include "user_util.h"
27766 +#include "time_user.h"
27768 +static int user_thread_tramp(void *arg)
27770 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
27771 + panic("user_thread_tramp - PTRACE_TRACEME failed, "
27772 + "errno = %d\n", errno);
27774 + os_stop_process(os_getpid());
27778 +int user_thread(unsigned long stack, int flags)
27780 + int pid, status, err;
27782 + pid = clone(user_thread_tramp, (void *) stack_sp(stack),
27783 + flags | CLONE_FILES | SIGCHLD, NULL);
27785 + printk("user_thread - clone failed, errno = %d\n", errno);
27789 + CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
27791 + printk("user_thread - waitpid failed, errno = %d\n", errno);
27795 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
27796 + printk("user_thread - trampoline didn't stop, status = %d\n",
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
27809 + * ---------------------------------------------------------------------------
27810 + * Local variables:
27811 + * c-file-style: "linux"
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
27820 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27821 + * Licensed under the GPL
27824 +#ifndef __SKAS_MMU_H
27825 +#define __SKAS_MMU_H
27827 +#include "linux/list.h"
27828 +#include "linux/spinlock.h"
27830 +struct mmu_context_skas {
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
27841 + * ---------------------------------------------------------------------------
27842 + * Local variables:
27843 + * c-file-style: "linux"
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
27852 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27853 + * Licensed under the GPL
27856 +#ifndef __MODE_SKAS_H__
27857 +#define __MODE_SKAS_H__
27859 +#include <sysdep/ptrace.h>
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;
27866 +extern void user_time_init_skas(void);
27867 +extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs,
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);
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
27885 + * ---------------------------------------------------------------------------
27886 + * Local variables:
27887 + * c-file-style: "linux"
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
27896 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27897 + * Licensed under the GPL
27900 +#ifndef __SKAS_MODE_KERN_H__
27901 +#define __SKAS_MODE_KERN_H__
27903 +#include "linux/sched.h"
27904 +#include "asm/page.h"
27905 +#include "asm/ptrace.h"
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);
27932 +#define kmem_end_skas (host_task_size - 1024 * 1024)
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
27941 + * ---------------------------------------------------------------------------
27942 + * Local variables:
27943 + * c-file-style: "linux"
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
27952 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27953 + * Licensed under the GPL
27956 +#ifndef __SKAS_PROC_MM_H
27957 +#define __SKAS_PROC_MM_H
27959 +#define MM_MMAP 54
27960 +#define MM_MUNMAP 55
27961 +#define MM_MPROTECT 56
27962 +#define MM_COPY_SEGMENTS 57
27965 + unsigned long addr;
27966 + unsigned long len;
27967 + unsigned long prot;
27968 + unsigned long flags;
27969 + unsigned long fd;
27970 + unsigned long offset;
27973 +struct mm_munmap {
27974 + unsigned long addr;
27975 + unsigned long len;
27978 +struct mm_mprotect {
27979 + unsigned long addr;
27980 + unsigned long len;
27981 + unsigned int prot;
27984 +struct proc_mm_op {
27987 + struct mm_mmap mmap;
27988 + struct mm_munmap munmap;
27989 + struct mm_mprotect mprotect;
27990 + int copy_segments;
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
28001 + * ---------------------------------------------------------------------------
28002 + * Local variables:
28003 + * c-file-style: "linux"
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
28012 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28013 + * Licensed under the GPL
28016 +#ifndef __PTRACE_SKAS_H
28017 +#define __PTRACE_SKAS_H
28019 +#include "uml-config.h"
28021 +#ifdef UML_CONFIG_MODE_SKAS
28023 +#include "skas_ptregs.h"
28025 +#define HOST_FRAME_SIZE 17
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])
28044 +#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res)
28046 +#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
28048 +#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
28050 +#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
28052 +#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
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
28063 + * ---------------------------------------------------------------------------
28064 + * Local variables:
28065 + * c-file-style: "linux"
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
28074 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28075 + * Licensed under the GPL
28081 +#include "sysdep/ptrace.h"
28083 +extern int userspace_pid[];
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);
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
28116 + * ---------------------------------------------------------------------------
28117 + * Local variables:
28118 + * c-file-style: "linux"
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
28127 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28128 + * Licensed under the GPL
28131 +#ifndef __SKAS_UACCESS_H
28132 +#define __SKAS_UACCESS_H
28134 +#include "asm/errno.h"
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)))
28141 +static inline int verify_area_skas(int type, const void * addr,
28142 + unsigned long size)
28144 + return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
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);
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
28161 + * ---------------------------------------------------------------------------
28162 + * Local variables:
28163 + * c-file-style: "linux"
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
28172 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28173 +# Licensed under the GPL
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 \
28182 +subdir-y = sys-$(SUBARCH)
28184 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
28186 +USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
28188 +include $(TOPDIR)/Rules.make
28190 +include/skas_ptregs.h : util/mk_ptregs
28191 + util/mk_ptregs > $@
28196 +$(USER_OBJS) : %.o: %.c
28197 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
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
28208 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28209 + * Licensed under the GPL
28212 +#include "linux/config.h"
28213 +#include "linux/mm.h"
28214 +#include "mem_user.h"
28216 +unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
28217 + unsigned long *task_size_out)
28219 + /* Round up to the nearest 4M */
28220 + unsigned long top = ROUND_4M((unsigned long) &arg);
28222 + *host_size_out = top;
28223 + *task_size_out = top;
28224 + return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
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
28232 + * ---------------------------------------------------------------------------
28233 + * Local variables:
28234 + * c-file-style: "linux"
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
28243 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28244 + * Licensed under the GPL
28247 +#include <errno.h>
28248 +#include <sys/mman.h>
28249 +#include <sys/ptrace.h>
28250 +#include "mem_user.h"
28254 +#include "proc_mm.h"
28256 +void map(int fd, unsigned long virt, unsigned long phys, unsigned long len,
28257 + int r, int w, int x)
28259 + struct proc_mm_op map;
28261 + int prot, n, phys_fd;
28263 + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
28264 + (x ? PROT_EXEC : 0);
28265 + phys_fd = phys_mapping(phys, &offset);
28267 + map = ((struct proc_mm_op) { .op = MM_MMAP,
28273 + .flags = MAP_SHARED |
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);
28283 +int unmap(int fd, void *addr, int len)
28285 + struct proc_mm_op unmap;
28288 + unmap = ((struct proc_mm_op) { .op = MM_MUNMAP,
28291 + { .addr = (unsigned long) addr,
28292 + .len = len } } } );
28293 + n = os_write_file(fd, &unmap, sizeof(unmap));
28294 + if(n != sizeof(unmap)) {
28304 +int protect(int fd, unsigned long addr, unsigned long len, int r, int w,
28305 + int x, int must_succeed)
28307 + struct proc_mm_op protect;
28310 + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
28311 + (x ? PROT_EXEC : 0);
28313 + protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
28316 + { .addr = (unsigned long) addr,
28318 + .prot = prot } } } );
28320 + n = os_write_file(fd, &protect, sizeof(protect));
28321 + if(n != sizeof(protect)) {
28322 + if(n == 0) return(0);
28325 + panic("protect failed, err = %d", -n);
28333 +void before_mem_skas(unsigned long unused)
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
28342 + * ---------------------------------------------------------------------------
28343 + * Local variables:
28344 + * c-file-style: "linux"
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
28353 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28354 + * Licensed under the GPL
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"
28365 +int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
28369 + if((current->mm != NULL) && (current->mm != &init_mm))
28370 + from = current->mm->context.skas.mm_fd;
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);
28383 +void destroy_context_skas(struct mm_struct *mm)
28385 + os_close_file(mm->context.skas.mm_fd);
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
28393 + * ---------------------------------------------------------------------------
28394 + * Local variables:
28395 + * c-file-style: "linux"
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
28404 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28405 + * Licensed under the GPL
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>
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"
28426 +#include "sysdep/sigcontext.h"
28428 +#include "proc_mm.h"
28429 +#include "skas_ptrace.h"
28430 +#include "chan_user.h"
28432 +int is_skas_winch(int pid, int fd, void *data)
28434 + if(pid != getpid())
28437 + register_winch_irq(-1, fd, -1, data);
28441 +/* These are set once at boot time and not changed thereafter */
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;
28448 +static void handle_segv(int pid)
28450 + struct ptrace_faultinfo fault;
28453 + err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault);
28455 + panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n",
28458 + segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
28461 +static void handle_trap(int pid, union uml_pt_regs *regs)
28463 + int err, syscall_nr, status;
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);
28473 + err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
28476 + panic("handle_trap - nullifying syscall failed, "
28477 + "errno = %d\n", errno);
28479 + err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
28481 + panic("handle_trap - continuing to end of syscall "
28482 + "failed, errno = %d\n", errno);
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,
28492 + handle_syscall(regs);
28495 +static int userspace_tramp(void *arg)
28497 + init_new_thread_signals(0);
28499 + ptrace(PTRACE_TRACEME, 0, 0, 0);
28500 + os_stop_process(os_getpid());
28504 +/* Each element set once, and only accessed by a single processor anyway */
28506 +int userspace_pid[NR_CPUS];
28508 +void start_userspace(int cpu)
28511 + unsigned long sp;
28512 + int pid, status, n;
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 *);
28520 + pid = clone(userspace_tramp, (void *) sp,
28521 + CLONE_FILES | CLONE_VM | SIGCHLD, NULL);
28523 + panic("start_userspace : clone failed, errno = %d", errno);
28526 + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
28528 + panic("start_userspace : wait failed, errno = %d",
28530 + } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
28532 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
28533 + panic("start_userspace : expected SIGSTOP, got status = %d",
28536 + if(munmap(stack, PAGE_SIZE) < 0)
28537 + panic("start_userspace : munmap failed, errno = %d\n", errno);
28539 + userspace_pid[cpu] = pid;
28542 +void userspace(union uml_pt_regs *regs)
28544 + int err, status, op, do_syscall, pid = userspace_pid[0];
28546 + do_syscall = use_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;
28547 + restore_registers(regs);
28549 + err = ptrace(do_syscall, pid, 0, 0);
28551 + panic("userspace - PTRACE_SYSCALL failed, errno = %d\n",
28554 + CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
28556 + panic("userspace - waitpid failed, errno = %d\n",
28559 + regs->skas.is_user = 1;
28560 + save_registers(regs);
28562 + if(WIFSTOPPED(status)){
28563 + switch(WSTOPSIG(status)){
28565 + handle_segv(pid);
28568 + handle_trap(pid, regs);
28576 + user_signal(WSTOPSIG(status), regs);
28579 + printk("userspace - child stopped with signal "
28580 + "%d\n", WSTOPSIG(status));
28585 + restore_registers(regs);
28587 + op = singlestepping(NULL) ? PTRACE_SINGLESTEP : do_syscall;
28588 + err = ptrace(op, pid, 0, 0);
28590 + panic("userspace - PTRACE_SYSCALL failed, "
28591 + "errno = %d\n", errno);
28595 +void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
28596 + void (*handler)(int))
28598 + sigjmp_buf switch_buf, fork_buf;
28600 + *switch_buf_ptr = &switch_buf;
28601 + *fork_buf_ptr = &fork_buf;
28603 + if(sigsetjmp(fork_buf, 1) == 0)
28604 + new_thread_proc(stack, handler);
28606 + remove_sigstack();
28609 +void thread_wait(void *sw, void *fb)
28611 + sigjmp_buf buf, **switch_buf = sw, *fork_buf;
28613 + *switch_buf = &buf;
28615 + if(sigsetjmp(buf, 1) == 0)
28616 + siglongjmp(*fork_buf, 1);
28619 +static int move_registers(int pid, int int_op, int fp_op,
28620 + union uml_pt_regs *regs, unsigned long *fp_regs)
28622 + if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
28624 + if(ptrace(fp_op, pid, 0, fp_regs) < 0)
28629 +void save_registers(union uml_pt_regs *regs)
28631 + unsigned long *fp_regs;
28634 + if(have_fpx_regs){
28635 + fp_op = PTRACE_GETFPXREGS;
28636 + fp_regs = regs->skas.xfp;
28639 + fp_op = PTRACE_GETFPREGS;
28640 + fp_regs = regs->skas.fp;
28643 + err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs,
28646 + panic("save_registers - saving registers failed, errno = %d\n",
28650 +void restore_registers(union uml_pt_regs *regs)
28652 + unsigned long *fp_regs;
28655 + if(have_fpx_regs){
28656 + fp_op = PTRACE_SETFPXREGS;
28657 + fp_regs = regs->skas.xfp;
28660 + fp_op = PTRACE_SETFPREGS;
28661 + fp_regs = regs->skas.fp;
28664 + err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs,
28667 + panic("restore_registers - saving registers failed, "
28668 + "errno = %d\n", -err);
28671 +void switch_threads(void *me, void *next)
28673 + sigjmp_buf my_buf, **me_ptr = me, *next_buf = next;
28675 + *me_ptr = &my_buf;
28676 + if(sigsetjmp(my_buf, 1) == 0)
28677 + siglongjmp(*next_buf, 1);
28680 +static sigjmp_buf initial_jmpbuf;
28682 +/* XXX Make these percpu */
28683 +static void (*cb_proc)(void *arg);
28684 +static void *cb_arg;
28685 +static sigjmp_buf *cb_back;
28687 +int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
28689 + sigjmp_buf **switch_buf = switch_buf_ptr;
28692 + *fork_buf_ptr = &initial_jmpbuf;
28693 + n = sigsetjmp(initial_jmpbuf, 1);
28695 + new_thread_proc((void *) stack, new_thread_handler);
28697 + remove_sigstack();
28699 + (*cb_proc)(cb_arg);
28700 + siglongjmp(*cb_back, 1);
28710 + siglongjmp(**switch_buf, 1);
28713 +void remove_sigstack(void)
28715 + stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE,
28719 + if(sigaltstack(&stack, NULL) != 0)
28720 + panic("disabling signal stack failed, errno = %d\n", errno);
28723 +void initial_thread_cb_skas(void (*proc)(void *), void *arg)
28732 + if(sigsetjmp(here, 1) == 0)
28733 + siglongjmp(initial_jmpbuf, 2);
28734 + unblock_signals();
28741 +void halt_skas(void)
28744 + siglongjmp(initial_jmpbuf, 3);
28747 +void reboot_skas(void)
28750 + siglongjmp(initial_jmpbuf, 4);
28753 +void switch_mm_skas(int mm_fd)
28757 +#warning need cpu pid in switch_mm_skas
28758 + err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd);
28760 + panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
28764 +void kill_off_processes_skas(void)
28766 +#warning need to loop over userspace_pids in kill_off_processes_skas
28767 + os_kill_process(userspace_pid[0], 1);
28770 +void init_registers(int pid)
28774 + if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0)
28775 + panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
28778 + err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
28782 + have_fpx_regs = 0;
28784 + panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
28787 + err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
28789 + panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
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
28798 + * ---------------------------------------------------------------------------
28799 + * Local variables:
28800 + * c-file-style: "linux"
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
28809 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28810 + * Licensed under the GPL
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"
28820 +#include "user_util.h"
28822 +#include "frame.h"
28825 +#include "filehandle.h"
28826 +#include "proc_mm.h"
28828 +void *_switch_to_skas(void *prev, void *next)
28830 + struct task_struct *from, *to;
28835 + /* XXX need to check runqueues[cpu].idle */
28836 + if(current->pid == 0)
28837 + switch_timers(0);
28839 + to->thread.prev_sched = from;
28842 + switch_threads(&from->thread.mode.skas.switch_buf,
28843 + to->thread.mode.skas.switch_buf);
28845 + if(current->pid == 0)
28846 + switch_timers(1);
28848 + return(current->thread.prev_sched);
28851 +extern void schedule_tail(struct task_struct *prev);
28853 +void new_thread_handler(int sig)
28855 + int (*fn)(void *), n;
28858 + fn = current->thread.request.u.thread.proc;
28859 + arg = current->thread.request.u.thread.arg;
28860 + change_sig(SIGUSR1, 1);
28861 + thread_wait(¤t->thread.mode.skas.switch_buf,
28862 + current->thread.mode.skas.fork_buf);
28864 + if(current->thread.prev_sched != NULL)
28865 + schedule_tail(current->thread.prev_sched);
28866 + current->thread.prev_sched = NULL;
28868 + /* The return value is 1 if the kernel thread execs a process,
28869 + * 0 if it just exits
28871 + n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf);
28873 + userspace(¤t->thread.regs.regs);
28877 +void new_thread_proc(void *stack, void (*handler)(int sig))
28879 + init_new_thread_stack(stack, handler);
28880 + os_usr1_process(os_getpid());
28883 +void release_thread_skas(struct task_struct *task)
28887 +void exit_thread_skas(void)
28891 +void fork_handler(int sig)
28893 + change_sig(SIGUSR1, 1);
28894 + thread_wait(¤t->thread.mode.skas.switch_buf,
28895 + current->thread.mode.skas.fork_buf);
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();
28903 + userspace(¤t->thread.regs.regs);
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)
28910 + void (*handler)(int);
28912 + if(current->thread.forking){
28913 + memcpy(&p->thread.regs.regs.skas,
28914 + ¤t->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;
28919 + handler = fork_handler;
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;
28932 + new_thread(p, &p->thread.mode.skas.switch_buf,
28933 + &p->thread.mode.skas.fork_buf, handler);
28937 +int new_mm(int from)
28939 + struct proc_mm_op copy;
28941 + int fd = open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
28947 + copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS,
28949 + { .copy_segments = from } } );
28950 + n = os_write_file(fd, ©, sizeof(copy));
28951 + if(n != sizeof(copy))
28952 + printk("new_mm : /proc/mm copy_segments failed, "
28953 + "err = %d\n", -n);
28959 +void init_idle_skas(void)
28961 + cpu_tasks[current->processor].pid = os_getpid();
28964 +extern void start_kernel(void);
28966 +static int start_kernel_proc(void *unused)
28971 + pid = os_getpid();
28973 + cpu_tasks[0].pid = pid;
28974 + cpu_tasks[0].task = current;
28976 + cpu_online_map = 1;
28982 +int start_uml_skas(void)
28984 + start_userspace(0);
28985 + capture_signal_stack();
28987 + init_new_thread_signals(1);
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));
28997 +int external_pid_skas(struct task_struct *task)
28999 +#warning Need to look up userspace_pid by cpu
29000 + return(userspace_pid[0]);
29003 +int thread_pid_skas(struct thread_struct *thread)
29005 +#warning Need to look up userspace_pid by cpu
29006 + return(userspace_pid[0]);
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
29014 + * ---------------------------------------------------------------------------
29015 + * Local variables:
29016 + * c-file-style: "linux"
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
29025 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
29026 + * Licensed under the GPL
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"
29038 +extern syscall_handler_t *sys_call_table[];
29040 +long execute_syscall_skas(void *r)
29042 + struct pt_regs *regs = r;
29046 + current->thread.nsyscalls++;
29048 + syscall = UPT_SYSCALL_NR(®s->regs);
29050 + if((syscall >= NR_syscalls) || (syscall < 1))
29052 + else res = EXECUTE_SYSCALL(syscall, regs);
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
29062 + * ---------------------------------------------------------------------------
29063 + * Local variables:
29064 + * c-file-style: "linux"
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
29073 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29074 + * Licensed under the GPL
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"
29085 +#define ERESTARTSYS 512
29086 +#define ERESTARTNOINTR 513
29087 +#define ERESTARTNOHAND 514
29089 +void handle_syscall(union uml_pt_regs *regs)
29094 + index = record_syscall_start(UPT_SYSCALL_NR(regs));
29097 + result = execute_syscall(regs);
29099 + REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
29100 + if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) ||
29101 + (result == -ERESTARTNOINTR))
29102 + do_signal(result);
29105 + record_syscall_end(index, result);
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
29113 + * ---------------------------------------------------------------------------
29114 + * Local variables:
29115 + * c-file-style: "linux"
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
29124 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29125 +# Licensed under the GPL
29128 +O_TARGET = sys-i386.o
29130 +obj-y = sigcontext.o
29132 +USER_OBJS = sigcontext.o
29134 +include $(TOPDIR)/Rules.make
29136 +$(USER_OBJS) : %.o: %.c
29137 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
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
29146 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29147 + * Licensed under the GPL
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"
29158 +#include "sigcontext.h"
29161 +int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr)
29163 + struct sigcontext sc, *from = from_ptr;
29164 + unsigned long fpregs[FP_FRAME_SIZE];
29167 + err = copy_from_user_proc(&sc, from, sizeof(sc));
29168 + err |= copy_from_user_proc(fpregs, sc.fpstate, sizeof(fpregs));
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;
29192 + err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
29194 + printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
29195 + "errno = %d\n", errno);
29202 +int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp,
29203 + union uml_pt_regs *regs, unsigned long fault_addr,
29206 + struct sigcontext sc, *to = to_ptr;
29207 + struct _fpstate *to_fp;
29208 + unsigned long fpregs[FP_FRAME_SIZE];
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;
29232 + err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
29234 + printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
29235 + "errno = %d\n", errno);
29238 + to_fp = (struct _fpstate *)
29239 + (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
29240 + sc.fpstate = to_fp;
29245 + return(copy_to_user_proc(to, &sc, sizeof(sc)) ||
29246 + copy_to_user_proc(to_fp, fpregs, sizeof(fpregs)));
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
29254 + * ---------------------------------------------------------------------------
29255 + * Local variables:
29256 + * c-file-style: "linux"
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
29265 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29266 + * Licensed under the GPL
29269 +#include <sys/signal.h>
29270 +#include <sys/time.h>
29271 +#include "time_user.h"
29272 +#include "process.h"
29275 +void user_time_init_skas(void)
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);
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
29289 + * ---------------------------------------------------------------------------
29290 + * Local variables:
29291 + * c-file-style: "linux"
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
29300 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29301 + * Licensed under the GPL
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"
29314 +static void fix_range(struct mm_struct *mm, unsigned long start_addr,
29315 + unsigned long end_addr, int force)
29320 + unsigned long addr;
29321 + int r, w, x, err, fd;
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)){
29338 + if(force || pte_newpage(*npte)){
29339 + err = unmap(fd, (void *) addr, PAGE_SIZE);
29341 + panic("munmap failed, errno = %d\n",
29343 + if(pte_present(*npte))
29345 + pte_val(*npte) & PAGE_MASK,
29346 + PAGE_SIZE, r, w, x);
29348 + else if(pte_newprot(*npte)){
29349 + protect(fd, addr, PAGE_SIZE, r, w, x, 1);
29351 + *npte = pte_mkuptodate(*npte);
29352 + addr += PAGE_SIZE;
29355 + if(force || pmd_newpage(*npmd)){
29356 + err = unmap(fd, (void *) addr, PMD_SIZE);
29358 + panic("munmap failed, errno = %d\n",
29360 + pmd_mkuptodate(*npmd);
29362 + addr += PMD_SIZE;
29367 +static void flush_kernel_vm_range(unsigned long start, unsigned long end)
29369 + struct mm_struct *mm;
29373 + unsigned long addr;
29374 + int updated = 0, err;
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)){
29384 + err = os_unmap_memory((void *) addr,
29387 + panic("munmap failed, errno = %d\n",
29389 + if(pte_present(*pte))
29391 + pte_val(*pte) & PAGE_MASK,
29392 + PAGE_SIZE, 1, 1, 1);
29394 + else if(pte_newprot(*pte)){
29396 + protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
29398 + addr += PAGE_SIZE;
29401 + if(pmd_newpage(*pmd)){
29403 + err = os_unmap_memory((void *) addr, PMD_SIZE);
29405 + panic("munmap failed, errno = %d\n",
29408 + addr += PMD_SIZE;
29413 +void flush_tlb_kernel_vm_skas(void)
29415 + flush_kernel_vm_range(start_vm, end_vm);
29418 +void __flush_tlb_one_skas(unsigned long addr)
29420 + flush_kernel_vm_range(addr, addr + PAGE_SIZE);
29423 +void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start,
29424 + unsigned long end)
29427 + flush_kernel_vm_range(start, end);
29428 + else fix_range(mm, start, end, 0);
29431 +void flush_tlb_mm_skas(struct mm_struct *mm)
29433 + flush_tlb_kernel_vm_skas();
29434 + fix_range(mm, 0, host_task_size, 0);
29437 +void force_flush_all_skas(void)
29439 + fix_range(current->mm, 0, host_task_size, 1);
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
29447 + * ---------------------------------------------------------------------------
29448 + * Local variables:
29449 + * c-file-style: "linux"
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
29458 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
29459 + * Licensed under the GPL
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"
29470 +#include "sigcontext.h"
29472 +void sig_handler_common_skas(int sig, void *sc_ptr)
29474 + struct sigcontext *sc = sc_ptr;
29475 + struct skas_regs *r;
29476 + struct signal_info *info;
29477 + int save_errno = errno;
29480 + r = &TASK_REGS(get_current())->skas;
29481 + save_user = r->is_user;
29483 + r->fault_addr = SC_FAULT_ADDR(sc);
29484 + r->fault_type = SC_FAULT_TYPE(sc);
29485 + r->trap_type = SC_TRAP_TYPE(sc);
29487 + change_sig(SIGUSR1, 1);
29488 + info = &sig_info[sig];
29489 + if(!info->is_irq) unblock_signals();
29491 + (*info->handler)(sig, (union uml_pt_regs *) r);
29493 + errno = save_errno;
29494 + r->is_user = save_user;
29497 +extern int missed_ticks[];
29499 +void user_signal(int sig, union uml_pt_regs *regs)
29501 + struct signal_info *info;
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);
29510 + unblock_signals();
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
29518 + * ---------------------------------------------------------------------------
29519 + * Local variables:
29520 + * c-file-style: "linux"
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
29529 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
29530 + * Licensed under the GPL
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"
29544 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
29547 +static unsigned long maybe_map(unsigned long virt, int is_write)
29551 + void *phys = um_virt_to_phys(current, virt, &pte);
29554 + if(IS_ERR(phys) || (is_write && !pte_write(pte))){
29555 + if(!handle_page_fault(virt, 0, is_write, 1, &dummy_code))
29557 + phys = um_virt_to_phys(current, virt, NULL);
29559 + return((unsigned long) phys);
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)
29565 + struct page *page;
29568 + addr = maybe_map(addr, is_write);
29572 + page = phys_to_page(addr);
29573 + addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
29574 + n = (*op)(addr, len, arg);
29580 +static void do_buffer_op(void *jmpbuf, void *arg_ptr)
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;
29592 + current->thread.fault_catcher = jmpbuf;
29593 + n = do_op(addr, size, is_write, op, arg);
29595 + *res = (n < 0 ? remain : 0);
29606 + while(addr < ((addr + remain) & PAGE_MASK)){
29607 + n = do_op(addr, PAGE_SIZE, is_write, op, arg);
29609 + *res = (n < 0 ? remain : 0);
29613 + addr += PAGE_SIZE;
29614 + remain -= PAGE_SIZE;
29621 + n = do_op(addr, remain, is_write, op, arg);
29623 + *res = (n < 0 ? remain : 0);
29626 + current->thread.fault_catcher = NULL;
29629 +static int buffer_op(unsigned long addr, int len, int is_write,
29630 + int (*op)(unsigned long addr, int len, void *arg),
29633 + int faulted, res;
29635 + faulted = setjmp_wrapper(do_buffer_op, addr, len, is_write, op, arg,
29640 + return(addr + len - (unsigned long) current->thread.fault_addr);
29643 +static int copy_chunk_from_user(unsigned long from, int len, void *arg)
29645 + unsigned long *to_ptr = arg, to = *to_ptr;
29647 + memcpy((void *) to, (void *) from, len);
29652 +int copy_from_user_skas(void *to, const void *from, int n)
29654 + if(segment_eq(get_fs(), KERNEL_DS)){
29655 + memcpy(to, from, n);
29659 + return(access_ok_skas(VERIFY_READ, from, n) ?
29660 + buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
29664 +static int copy_chunk_to_user(unsigned long to, int len, void *arg)
29666 + unsigned long *from_ptr = arg, from = *from_ptr;
29668 + memcpy((void *) to, (void *) from, len);
29669 + *from_ptr += len;
29673 +int copy_to_user_skas(void *to, const void *from, int n)
29675 + if(segment_eq(get_fs(), KERNEL_DS)){
29676 + memcpy(to, from, n);
29680 + return(access_ok_skas(VERIFY_WRITE, to, n) ?
29681 + buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
29685 +static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
29687 + char **to_ptr = arg, *to = *to_ptr;
29690 + strncpy(to, (void *) from, len);
29691 + n = strnlen(to, len);
29699 +int strncpy_from_user_skas(char *dst, const char *src, int count)
29704 + if(segment_eq(get_fs(), KERNEL_DS)){
29705 + strncpy(dst, src, count);
29706 + return(strnlen(dst, count));
29709 + if(!access_ok_skas(VERIFY_READ, src, 1))
29712 + n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
29716 + return(strnlen(dst, count));
29719 +static int clear_chunk(unsigned long addr, int len, void *unused)
29721 + memset((void *) addr, 0, len);
29725 +int __clear_user_skas(void *mem, int len)
29727 + return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
29730 +int clear_user_skas(void *mem, int len)
29732 + if(segment_eq(get_fs(), KERNEL_DS)){
29733 + memset(mem, 0, len);
29737 + return(access_ok_skas(VERIFY_WRITE, mem, len) ?
29738 + buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
29741 +static int strnlen_chunk(unsigned long str, int len, void *arg)
29743 + int *len_ptr = arg, n;
29745 + n = strnlen((void *) str, len);
29753 +int strnlen_user_skas(const void *str, int len)
29755 + int count = 0, n;
29757 + if(segment_eq(get_fs(), KERNEL_DS))
29758 + return(strnlen(str, len) + 1);
29760 + n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
29762 + return(count + 1);
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
29771 + * ---------------------------------------------------------------------------
29772 + * Local variables:
29773 + * c-file-style: "linux"
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
29783 +mk_ptregs : mk_ptregs.o
29784 + $(HOSTCC) -o mk_ptregs mk_ptregs.o
29786 +mk_ptregs.o : mk_ptregs.c
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
29796 +#include <stdio.h>
29797 +#include <asm/ptrace.h>
29798 +#include <asm/user.h>
29800 +#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val))
29802 +int main(int argc, char **argv)
29804 + printf("/* Automatically generated by "
29805 + "arch/um/kernel/skas/util/mk_ptregs */\n");
29807 + printf("#ifndef __SKAS_PT_REGS_\n");
29808 + printf("#define __SKAS_PT_REGS_\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));
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);
29833 + printf("#endif\n");
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
29842 + * ---------------------------------------------------------------------------
29843 + * Local variables:
29844 + * c-file-style: "linux"
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
29853 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
29854 + * Licensed under the GPL
29857 +#include "linux/config.h"
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"
29876 +/* Total count of live CPUs, set by smp_boot_cpus */
29877 +int smp_num_cpus = 1;
29879 +/* The 'big kernel lock' */
29880 +spinlock_cacheline_t kernel_flag_cacheline = {SPIN_LOCK_UNLOCKED};
29882 +/* Per CPU bogomips and other parameters */
29884 +/* The only piece used here is the ipi pipe, which is set before SMP is
29885 + * started and never changed.
29887 +struct cpuinfo_um cpu_data[NR_CPUS];
29889 +/* CPU online map, set by smp_boot_cpus */
29890 +unsigned long cpu_online_map;
29892 +atomic_t global_bh_count;
29894 +/* Set when the idlers are all forked */
29895 +int smp_threads_ready = 0;
29897 +/* Not used by UML */
29898 +unsigned char global_irq_holder = 0;
29899 +unsigned volatile long global_irq_lock;
29901 +/* A statistic, can be a little off */
29902 +static int num_reschedules_sent = 0;
29904 +mmu_gather_t mmu_gathers[NR_CPUS];
29906 +void smp_send_reschedule(int cpu)
29908 + os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1);
29909 + num_reschedules_sent++;
29912 +static void show(char * str)
29914 + int cpu = smp_processor_id();
29916 + printk(KERN_INFO "\n%s, CPU %d:\n", str, cpu);
29919 +#define MAXCOUNT 100000000
29921 +static inline void wait_on_bh(void)
29923 + int count = MAXCOUNT;
29926 + show("wait_on_bh");
29929 + /* nothing .. wait for the other bh's to go away */
29930 + } while (atomic_read(&global_bh_count) != 0);
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.
29938 + * Don't wait if we're already running in an interrupt
29939 + * context or are inside a bh handler.
29941 +void synchronize_bh(void)
29943 + if (atomic_read(&global_bh_count) && !in_interrupt())
29947 +void smp_send_stop(void)
29951 + printk(KERN_INFO "Stopping all CPUs...");
29952 + for(i = 0; i < ncpus; i++){
29953 + if(i == current->processor)
29955 + os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
29957 + printk("done\n");
29961 +static atomic_t smp_commenced = ATOMIC_INIT(0);
29962 +static volatile unsigned long smp_callin_map = 0;
29964 +void smp_commence(void)
29966 + printk("All CPUs are go!\n");
29969 + atomic_set(&smp_commenced, 1);
29972 +static int idle_proc(void *unused)
29976 + set_current(current);
29977 + del_from_runqueue(current);
29978 + unhash_process(current);
29980 + cpu = current->processor;
29981 + err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
29983 + panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
29985 + activate_ipi(cpu_data[cpu].ipi_pipe[0],
29986 + current->thread.mode.tt.extern_pid);
29989 + if (test_and_set_bit(current->processor, &smp_callin_map)) {
29990 + printk("huh, CPU#%d already present??\n", current->processor);
29994 + while (!atomic_read(&smp_commenced))
30002 +static int idle_thread(int (*fn)(void *), int cpu)
30004 + struct task_struct *new_task;
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);
30012 + panic("do_fork failed in idle_thread");
30013 + new_task = get_task(pid, 1);
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);
30029 +void smp_boot_cpus(void)
30033 + set_bit(0, &cpu_online_map);
30034 + set_bit(0, &smp_callin_map);
30036 + err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
30038 + panic("CPU#0 failed to create IPI pipe, err = %d", -err);
30040 + activate_ipi(cpu_data[0].ipi_pipe[0],
30041 + current->thread.mode.tt.extern_pid);
30044 + printk(KERN_INFO "ncpus set to 1\n");
30047 + else if(ncpus > NR_CPUS){
30049 + "ncpus can't be greater than NR_CPUS, set to %d\n",
30057 + printk(KERN_INFO "Starting up other processors:\n");
30058 + for(i=1;i<ncpus;i++){
30061 + /* Do this early, for hard_smp_processor_id() */
30062 + cpu_tasks[i].pid = -1;
30063 + set_bit(i, &cpu_online_map);
30066 + pid = idle_thread(idle_proc, i);
30067 + printk(KERN_INFO "\t#%d - idle thread pid = %d.. ",
30070 + waittime = 200000000;
30071 + while (waittime-- && !test_bit(i, &smp_callin_map))
30074 + if (test_bit(i, &smp_callin_map))
30075 + printk("online\n");
30077 + printk("failed\n");
30078 + clear_bit(i, &cpu_online_map);
30084 +int setup_profiling_timer(unsigned int multiplier)
30086 + printk(KERN_INFO "setup_profiling_timer\n");
30090 +void smp_call_function_slave(int cpu);
30092 +void IPI_handler(int cpu)
30097 + fd = cpu_data[cpu].ipi_pipe[0];
30098 + while (os_read_file(fd, &c, 1) == 1) {
30101 + smp_call_function_slave(cpu);
30105 + current->need_resched = 1;
30109 + printk("CPU#%d stopping\n", cpu);
30115 + printk("CPU#%d received unknown IPI [%c]!\n", cpu, c);
30121 +int hard_smp_processor_id(void)
30123 + return(pid_to_processor_id(os_getpid()));
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;
30132 +void smp_call_function_slave(int cpu)
30134 + atomic_inc(&scf_started);
30136 + atomic_inc(&scf_finished);
30139 +int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic,
30142 + int cpus = smp_num_cpus - 1;
30148 + spin_lock_bh(&call_lock);
30149 + atomic_set(&scf_started, 0);
30150 + atomic_set(&scf_finished, 0);
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);
30158 + while (atomic_read(&scf_started) != cpus)
30162 + while (atomic_read(&scf_finished) != cpus)
30165 + spin_unlock_bh(&call_lock);
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
30176 + * ---------------------------------------------------------------------------
30177 + * Local variables:
30178 + * c-file-style: "linux"
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
30187 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
30188 + * Licensed under the GPL
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"
30211 +/* Unlocked, I don't care if this is a bit off */
30212 +int nsyscalls = 0;
30214 +long um_mount(char * dev_name, char * dir_name, char * type,
30215 + unsigned long new_flags, void * data)
30217 + if(type == NULL) type = "";
30218 + return(sys_mount(dev_name, dir_name, type, new_flags, data));
30221 +long sys_fork(void)
30225 + current->thread.forking = 1;
30226 + ret = do_fork(SIGCHLD, 0, NULL, 0);
30227 + current->thread.forking = 0;
30231 +long sys_clone(unsigned long clone_flags, unsigned long newsp)
30235 + current->thread.forking = 1;
30236 + ret = do_fork(clone_flags, newsp, NULL, 0);
30237 + current->thread.forking = 0;
30241 +long sys_vfork(void)
30245 + current->thread.forking = 1;
30246 + ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0);
30247 + current->thread.forking = 0;
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)
30256 + int error = -EBADF;
30257 + struct file * file = NULL;
30259 + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
30260 + if (!(flags & MAP_ANONYMOUS)) {
30266 + down_write(&mm->mmap_sem);
30267 + error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
30268 + up_write(&mm->mmap_sem);
30276 +long sys_mmap2(unsigned long addr, unsigned long len,
30277 + unsigned long prot, unsigned long flags,
30278 + unsigned long fd, unsigned long pgoff)
30280 + return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
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..
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;
30299 +int old_mmap(unsigned long addr, unsigned long len,
30300 + unsigned long prot, unsigned long flags,
30301 + unsigned long fd, unsigned long offset)
30303 + int err = -EINVAL;
30304 + if (offset & ~PAGE_MASK)
30307 + err = do_mmap2(current->mm, addr, len, prot, flags, fd,
30308 + offset >> PAGE_SHIFT);
30313 + * sys_pipe() is the normal C calling standard for creating
30314 + * a pipe. It's not the way unix traditionally does this, though.
30316 +int sys_pipe(unsigned long * fildes)
30321 + error = do_pipe(fd);
30323 + if (copy_to_user(fildes, fd, sizeof(fd)))
30329 +int sys_pause(void)
30331 + current->state = TASK_INTERRUPTIBLE;
30333 + return -ERESTARTNOHAND;
30336 +int sys_sigaction(int sig, const struct old_sigaction *act,
30337 + struct old_sigaction *oact)
30339 + struct k_sigaction new_ka, old_ka;
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))
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);
30353 + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
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))
30360 + __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
30361 + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
30368 + * sys_ipc() is the de-multiplexer for the SysV IPC calls..
30370 + * This is really horribly ugly.
30372 +int sys_ipc (uint call, int first, int second,
30373 + int third, void *ptr, long fifth)
30375 + int version, ret;
30377 + version = call >> 16; /* hack for backward compatibility */
30382 + return sys_semop (first, (struct sembuf *)ptr, second);
30384 + return sys_semget (first, second, third);
30386 + union semun fourth;
30389 + if (get_user(fourth.__pad, (void **) ptr))
30391 + return sys_semctl (first, second, third, fourth);
30395 + return sys_msgsnd (first, (struct msgbuf *) ptr,
30398 + switch (version) {
30400 + struct ipc_kludge tmp;
30404 + if (copy_from_user(&tmp,
30405 + (struct ipc_kludge *) ptr,
30408 + return sys_msgrcv (first, tmp.msgp, second,
30409 + tmp.msgtyp, third);
30412 + panic("msgrcv with version != 0");
30413 + return sys_msgrcv (first,
30414 + (struct msgbuf *) ptr,
30415 + second, fifth, third);
30418 + return sys_msgget ((key_t) first, second);
30420 + return sys_msgctl (first, second, (struct msqid_ds *) ptr);
30423 + switch (version) {
30426 + ret = sys_shmat (first, (char *) ptr, second, &raddr);
30429 + return put_user (raddr, (ulong *) third);
30431 + case 1: /* iBCS2 emulator entry point */
30432 + if (!segment_eq(get_fs(), get_ds()))
30434 + return sys_shmat (first, (char *) ptr, second, (ulong *) third);
30437 + return sys_shmdt ((char *)ptr);
30439 + return sys_shmget (first, second, third);
30441 + return sys_shmctl (first, second,
30442 + (struct shmid_ds *) ptr);
30448 +int sys_uname(struct old_utsname * name)
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;
30459 +int sys_olduname(struct oldold_utsname * name)
30465 + if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
30468 + down_read(&uts_sem);
30470 + error = __copy_to_user(&name->sysname,&system_utsname.sysname,
30472 + error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
30473 + error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
30475 + error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
30476 + error |= __copy_to_user(&name->release,&system_utsname.release,
30478 + error |= __put_user(0,name->release+__OLD_UTS_LEN);
30479 + error |= __copy_to_user(&name->version,&system_utsname.version,
30481 + error |= __put_user(0,name->version+__OLD_UTS_LEN);
30482 + error |= __copy_to_user(&name->machine,&system_utsname.machine,
30484 + error |= __put_user(0,name->machine+__OLD_UTS_LEN);
30486 + up_read(&uts_sem);
30488 + error = error ? -EFAULT : 0;
30493 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
30495 + return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
30498 +long execute_syscall(void *r)
30500 + return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
30503 +spinlock_t syscall_lock = SPIN_LOCK_UNLOCKED;
30505 +static int syscall_index = 0;
30507 +int next_syscall_index(int limit)
30511 + spin_lock(&syscall_lock);
30512 + ret = syscall_index;
30513 + if(++syscall_index == limit)
30514 + syscall_index = 0;
30515 + spin_unlock(&syscall_lock);
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
30524 + * ---------------------------------------------------------------------------
30525 + * Local variables:
30526 + * c-file-style: "linux"
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
30535 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
30536 + * Licensed under the GPL
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"
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;
30769 +extern syscall_handler_t um_mount;
30770 +extern syscall_handler_t um_time;
30771 +extern syscall_handler_t um_stime;
30773 +#define LAST_GENERIC_SYSCALL __NR_exit_group
30775 +#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
30776 +#define LAST_SYSCALL LAST_GENERIC_SYSCALL
30778 +#define LAST_SYSCALL LAST_ARCH_SYSCALL
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,
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,
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,
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,
31016 + [ LAST_SYSCALL + 1 ... NR_syscalls ] =
31017 + (syscall_handler_t *) sys_ni_syscall
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
31025 + * ---------------------------------------------------------------------------
31026 + * Local variables:
31027 + * c-file-style: "linux"
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
31036 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
31037 + * Licensed under the GPL
31040 +#include <stdlib.h>
31041 +#include <sys/time.h>
31042 +#include "kern_util.h"
31043 +#include "syscall_user.h"
31049 + struct timeval start;
31050 + struct timeval end;
31051 +} syscall_record[1024];
31053 +int record_syscall_start(int syscall)
31057 + max = sizeof(syscall_record)/sizeof(syscall_record[0]);
31058 + index = next_syscall_index(max);
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);
31067 +void record_syscall_end(int index, int result)
31069 + syscall_record[index].result = result;
31070 + gettimeofday(&syscall_record[index].end, NULL);
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
31078 + * ---------------------------------------------------------------------------
31079 + * Local variables:
31080 + * c-file-style: "linux"
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
31089 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
31090 + * Licensed under the GPL
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"
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
31107 +#ifdef CONFIG_MODULES
31109 +extern struct module *module_list;
31110 +extern struct module kernel_module;
31112 +static inline int kernel_text_address(unsigned long addr)
31115 + struct module *mod;
31117 + if (addr >= (unsigned long) &_stext &&
31118 + addr <= (unsigned long) &_etext)
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)) {
31136 +static inline int kernel_text_address(unsigned long addr)
31138 + return (addr >= (unsigned long) &_stext &&
31139 + addr <= (unsigned long) &_etext);
31144 +void show_trace(unsigned long * stack)
31147 + unsigned long addr;
31150 + stack = (unsigned long*) &stack;
31152 + printk("Call Trace: ");
31154 + while (((long) stack & (THREAD_SIZE-1)) != 0) {
31156 + if (kernel_text_address(addr)) {
31157 + if (i && ((i % 6) == 0))
31159 + printk("[<%08lx>] ", addr);
31166 +void show_trace_task(struct task_struct *tsk)
31168 + unsigned long esp = PT_REGS_SP(&tsk->thread.regs);
31170 + /* User space on another CPU? */
31171 + if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
31173 + show_trace((unsigned long *)esp);
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
31181 + * ---------------------------------------------------------------------------
31182 + * Local variables:
31183 + * c-file-style: "linux"
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
31192 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
31193 + * Licensed under the GPL
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>
31204 +/* Modified from create_mem_file and start_debugger */
31205 +static char *tempdir = NULL;
31207 +static void __init find_tempdir(void)
31209 + char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
31211 + char *dir = NULL;
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'))
31219 + if((dir == NULL) || (*dir == '\0'))
31222 + tempdir = malloc(strlen(dir) + 2);
31223 + if(tempdir == NULL){
31224 + fprintf(stderr, "Failed to malloc tempdir, "
31225 + "errno = %d\n", errno);
31228 + strcpy(tempdir, dir);
31229 + strcat(tempdir, "/");
31232 +int make_tempfile(const char *template, char **out_tempname, int do_unlink)
31234 + char tempname[MAXPATHLEN];
31238 + if (*template != '/')
31239 + strcpy(tempname, tempdir);
31242 + strcat(tempname, template);
31243 + fd = mkstemp(tempname);
31245 + fprintf(stderr, "open - cannot create %s: %s\n", tempname,
31246 + strerror(errno));
31249 + if(do_unlink && (unlink(tempname) < 0)){
31250 + perror("unlink");
31253 + if(out_tempname){
31254 + *out_tempname = strdup(tempname);
31255 + if(*out_tempname == NULL){
31256 + perror("strdup");
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
31268 + * ---------------------------------------------------------------------------
31269 + * Local variables:
31270 + * c-file-style: "linux"
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
31279 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
31280 + * Licensed under the GPL
31283 +#include <stdio.h>
31284 +#include <stdlib.h>
31285 +#include <unistd.h>
31287 +#include <sys/time.h>
31288 +#include <signal.h>
31289 +#include <errno.h>
31290 +#include "user_util.h"
31291 +#include "kern_util.h"
31293 +#include "process.h"
31294 +#include "signal_user.h"
31295 +#include "time_user.h"
31297 +extern struct timeval xtime;
31299 +struct timeval local_offset = { 0, 0 };
31303 + gettimeofday(&xtime, NULL);
31304 + timeradd(&xtime, &local_offset, &xtime);
31307 +void set_interval(int timer_type)
31309 + int usec = 1000000/hz();
31310 + struct itimerval interval = ((struct itimerval) { { 0, usec },
31313 + if(setitimer(timer_type, &interval, NULL) == -1)
31314 + panic("setitimer failed - errno = %d\n", errno);
31317 +void enable_timer(void)
31319 + int usec = 1000000/hz();
31320 + struct itimerval enable = ((struct itimerval) { { 0, usec },
31322 + if(setitimer(ITIMER_VIRTUAL, &enable, NULL))
31323 + printk("enable_timer - setitimer failed, errno = %d\n",
31327 +void disable_timer(void)
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",
31336 +void switch_timers(int to_real)
31338 + struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
31339 + struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
31340 + { 0, 1000000/hz() }});
31344 + old = ITIMER_VIRTUAL;
31345 + new = ITIMER_REAL;
31348 + old = ITIMER_REAL;
31349 + new = ITIMER_VIRTUAL;
31352 + if((setitimer(old, &disable, NULL) < 0) ||
31353 + (setitimer(new, &enable, NULL)))
31354 + printk("switch_timers - setitimer failed, errno = %d\n",
31358 +void idle_timer(void)
31360 + if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
31361 + panic("Couldn't unset SIGVTALRM handler");
31363 + set_handler(SIGALRM, (__sighandler_t) alarm_handler,
31364 + SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
31365 + set_interval(ITIMER_REAL);
31368 +void time_init(void)
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.
31377 + if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
31378 + panic("Couldn't set SIGVTALRM handler");
31379 + set_interval(ITIMER_VIRTUAL);
31382 +void do_gettimeofday(struct timeval *tv)
31384 + unsigned long flags;
31386 + flags = time_lock();
31387 + gettimeofday(tv, NULL);
31388 + timeradd(tv, &local_offset, tv);
31389 + time_unlock(flags);
31392 +void do_settimeofday(struct timeval *tv)
31394 + struct timeval now;
31395 + unsigned long flags;
31397 + flags = time_lock();
31398 + gettimeofday(&now, NULL);
31399 + timersub(tv, &now, &local_offset);
31400 + time_unlock(flags);
31403 +void idle_sleep(int secs)
31405 + struct timespec ts;
31407 + ts.tv_sec = secs;
31409 + nanosleep(&ts, NULL);
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
31417 + * ---------------------------------------------------------------------------
31418 + * Local variables:
31419 + * c-file-style: "linux"
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
31428 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
31429 + * Licensed under the GPL
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"
31449 +extern rwlock_t xtime_lock;
31456 +/* Changed at early boot */
31457 +int timer_irq_inited = 0;
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
31463 +int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
31465 +static int first_tick;
31466 +static unsigned long long prev_usecs;
31467 +static long long delta; /* Deviation per interval */
31469 +#define MILLION 1000000
31471 +void timer_irq(union uml_pt_regs *regs)
31473 + unsigned long long ticks = 0;
31475 + if(!timer_irq_inited){
31476 + /* This is to ensure that ticks don't pile up when
31477 + * the timer handler is suspended */
31483 +#if defined(CONFIG_UML_REAL_TIME_CLOCK)
31484 + /* We've had 1 tick */
31485 + unsigned long long usecs = os_usecs();
31487 + delta += usecs - prev_usecs;
31488 + prev_usecs = usecs;
31490 + /* Protect against the host clock being set backwards */
31494 + ticks += (delta * HZ) / MILLION;
31495 + delta -= (ticks * MILLION) / HZ;
31501 + prev_usecs = os_usecs();
31505 + while(ticks > 0){
31506 + do_IRQ(TIMER_IRQ, regs);
31511 +void boot_timer_handler(int sig)
31513 + struct pt_regs regs;
31515 + CHOOSE_MODE((void)
31516 + (UPT_SC(®s.regs) = (struct sigcontext *) (&sig + 1)),
31517 + (void) (regs.regs.skas.is_user = 0));
31521 +void um_timer(int irq, void *dev, struct pt_regs *regs)
31524 + write_lock(&xtime_lock);
31528 + write_unlock(&xtime_lock);
31531 +long um_time(int * tloc)
31533 + struct timeval now;
31535 + do_gettimeofday(&now);
31537 + if (put_user(now.tv_sec,tloc))
31538 + now.tv_sec = -EFAULT;
31540 + return now.tv_sec;
31543 +long um_stime(int * tptr)
31546 + struct timeval new;
31548 + if (get_user(value, tptr))
31550 + new.tv_sec = value;
31552 + do_settimeofday(&new);
31556 +/* XXX Needs to be moved under sys-i386 */
31557 +void __delay(um_udelay_t time)
31559 + /* Stolen from the i386 __loop_delay */
31561 + __asm__ __volatile__(
31566 + "2:\tdecl %0\n\tjns 2b"
31571 +void __udelay(um_udelay_t usecs)
31575 + n = (loops_per_jiffy * HZ * usecs) / MILLION;
31576 + for(i=0;i<n;i++) ;
31579 +void __const_udelay(um_udelay_t usecs)
31583 + n = (loops_per_jiffy * HZ * usecs) / MILLION;
31584 + for(i=0;i<n;i++) ;
31587 +void timer_handler(int sig, union uml_pt_regs *regs)
31590 + update_process_times(user_context(UPT_SP(regs)));
31592 + if(current->processor == 0)
31596 +static spinlock_t timer_spinlock = SPIN_LOCK_UNLOCKED;
31598 +unsigned long time_lock(void)
31600 + unsigned long flags;
31602 + spin_lock_irqsave(&timer_spinlock, flags);
31606 +void time_unlock(unsigned long flags)
31608 + spin_unlock_irqrestore(&timer_spinlock, flags);
31611 +int __init timer_init(void)
31615 + CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
31616 + err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
31618 + printk(KERN_ERR "timer_init : request_irq failed - "
31619 + "errno = %d\n", -err);
31620 + timer_irq_inited = 1;
31624 +__initcall(timer_init);
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
31631 + * ---------------------------------------------------------------------------
31632 + * Local variables:
31633 + * c-file-style: "linux"
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
31642 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
31643 + * Licensed under the GPL
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"
31652 +void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
31654 + address &= PAGE_MASK;
31655 + flush_tlb_range(vma->vm_mm, address, address + PAGE_SIZE);
31658 +void flush_tlb_all(void)
31660 + flush_tlb_mm(current->mm);
31663 +void flush_tlb_kernel_vm(void)
31665 + CHOOSE_MODE(flush_tlb_kernel_vm_tt(), flush_tlb_kernel_vm_skas());
31668 +void __flush_tlb_one(unsigned long addr)
31670 + CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
31673 +void flush_tlb_range(struct mm_struct *mm, unsigned long start,
31674 + unsigned long end)
31676 + CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, mm, start,
31680 +void flush_tlb_mm(struct mm_struct *mm)
31682 + CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
31685 +void force_flush_all(void)
31687 + CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
31691 +pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
31693 + return(pgd_offset(mm, address));
31696 +pmd_t *pmd_offset_proc(pgd_t *pgd, unsigned long address)
31698 + return(pmd_offset(pgd, address));
31701 +pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
31703 + return(pte_offset(pmd, address));
31706 +pte_t *addr_pte(struct task_struct *task, unsigned long addr)
31708 + return(pte_offset(pmd_offset(pgd_offset(task->mm, addr), addr), addr));
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
31716 + * ---------------------------------------------------------------------------
31717 + * Local variables:
31718 + * c-file-style: "linux"
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
31727 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
31728 + * Licensed under the GPL
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"
31746 +#include "chan_kern.h"
31747 +#include "mconsole_kern.h"
31748 +#include "2_5compat.h"
31750 +#include "mem_kern.h"
31752 +unsigned long handle_page_fault(unsigned long address, unsigned long ip,
31753 + int is_write, int is_user, int *code_out)
31755 + struct mm_struct *mm = current->mm;
31756 + struct vm_area_struct *vma;
31760 + unsigned long page;
31763 + *code_out = SEGV_MAPERR;
31764 + down_read(&mm->mmap_sem);
31765 + vma = find_vma(mm, address);
31768 + else if(vma->vm_start <= address)
31770 + else if(!(vma->vm_flags & VM_GROWSDOWN))
31772 + else if(expand_stack(vma, address))
31776 + *code_out = SEGV_ACCERR;
31777 + if(is_write && !(vma->vm_flags & VM_WRITE))
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);
31786 + switch (handle_mm_fault(mm, vma, address, is_write)) {
31788 + current->min_flt++;
31791 + current->maj_flt++;
31794 + if (current->pid == 1) {
31795 + up_read(&mm->mmap_sem);
31797 + down_read(&mm->mmap_sem);
31800 + /* Fall through to bad area case */
31804 + pte = pte_offset(pmd, page);
31805 + } while(!pte_present(*pte));
31807 + *pte = pte_mkyoung(*pte);
31808 + if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
31809 + flush_tlb_page(vma, page);
31811 + up_read(&mm->mmap_sem);
31815 +LIST_HEAD(physmem_remappers);
31817 +void register_remapper(struct remapper *info)
31819 + list_add(&info->list, &physmem_remappers);
31822 +static int check_remapped_addr(unsigned long address, int is_write, int is_user)
31824 + struct remapper *remapper;
31825 + struct list_head *ele;
31829 + fd = phys_mapping(__pa(address), &offset);
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))
31842 +unsigned long segv(unsigned long address, unsigned long ip, int is_write,
31843 + int is_user, void *sc)
31845 + struct siginfo si;
31849 + if(!is_user && (address >= start_vm) && (address < end_vm)){
31850 + flush_tlb_kernel_vm();
31853 + else if(check_remapped_addr(address & PAGE_MASK, is_write, is_user))
31855 + else if(current->mm == NULL)
31856 + panic("Segfault with no mm");
31858 + handled = handle_page_fault(address, ip, is_write, is_user,
31861 + catcher = current->thread.fault_catcher;
31864 + else if(catcher != NULL){
31865 + current->thread.fault_addr = (void *) address;
31866 + do_longjmp(catcher, 1);
31868 + else if(current->thread.fault_addr != NULL)
31869 + panic("fault_addr set but no fault catcher");
31870 + else if(arch_fixup(ip, sc))
31874 + panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
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);
31884 +void bad_segv(unsigned long address, unsigned long ip, int is_write)
31886 + struct siginfo si;
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);
31896 +void relay_signal(int sig, union uml_pt_regs *regs)
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);
31904 +void bus_handler(int sig, union uml_pt_regs *regs)
31906 + if(current->thread.fault_catcher != NULL)
31907 + do_longjmp(current->thread.fault_catcher, 1);
31908 + else relay_signal(sig, regs);
31911 +void winch(int sig, union uml_pt_regs *regs)
31913 + do_IRQ(WINCH_IRQ, regs);
31916 +void trap_init(void)
31920 +spinlock_t trap_lock = SPIN_LOCK_UNLOCKED;
31922 +static int trap_index = 0;
31924 +int next_trap_index(int limit)
31928 + spin_lock(&trap_lock);
31929 + ret = trap_index;
31930 + if(++trap_index == limit)
31932 + spin_unlock(&trap_lock);
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
31941 + * ---------------------------------------------------------------------------
31942 + * Local variables:
31943 + * c-file-style: "linux"
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
31952 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
31953 + * Licensed under the GPL
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>
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"
31976 +#include "choose-mode.h"
31977 +#include "kern_util.h"
31978 +#include "user_util.h"
31981 +void kill_child_dead(int pid)
31983 + kill(pid, SIGKILL);
31984 + kill(pid, SIGCONT);
31987 + CATCH_EINTR(n = waitpid(pid, NULL, 0));
31989 + kill(pid, SIGCONT);
31995 +/* Unlocked - don't care if this is a bit off */
31996 +int nsegfaults = 0;
31999 + unsigned long address;
32002 + unsigned long sp;
32004 +} segfault_record[1024];
32006 +void segv_handler(int sig, union uml_pt_regs *regs)
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));
32015 + max = sizeof(segfault_record)/sizeof(segfault_record[0]);
32016 + index = next_trap_index(max);
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);
32028 +void usr2_handler(int sig, union uml_pt_regs *regs)
32030 + CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
32033 +struct signal_info sig_info[] = {
32034 + [ SIGTRAP ] { .handler = relay_signal,
32036 + [ SIGFPE ] { .handler = relay_signal,
32038 + [ SIGILL ] { .handler = relay_signal,
32040 + [ SIGWINCH ] { .handler = winch,
32042 + [ SIGBUS ] { .handler = bus_handler,
32044 + [ SIGSEGV] { .handler = segv_handler,
32046 + [ SIGIO ] { .handler = sigio_handler,
32048 + [ SIGVTALRM ] { .handler = timer_handler,
32050 + [ SIGALRM ] { .handler = timer_handler,
32052 + [ SIGUSR2 ] { .handler = usr2_handler,
32056 +void sig_handler(int sig, struct sigcontext sc)
32058 + CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
32062 +extern int timer_irq_inited, missed_ticks[];
32064 +void alarm_handler(int sig, struct sigcontext sc)
32066 + if(!timer_irq_inited) return;
32067 + missed_ticks[cpu()]++;
32069 + if(sig == SIGALRM)
32070 + switch_timers(0);
32072 + CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
32075 + if(sig == SIGALRM)
32076 + switch_timers(1);
32079 +void do_longjmp(void *b, int val)
32081 + sigjmp_buf *buf = b;
32083 + siglongjmp(*buf, val);
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
32091 + * ---------------------------------------------------------------------------
32092 + * Local variables:
32093 + * c-file-style: "linux"
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
32102 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32103 + * Licensed under the GPL
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"
32122 +static int exec_tramp(void *sig_stack)
32124 + init_new_thread_stack(sig_stack, NULL);
32125 + init_new_thread_signals(1);
32126 + os_stop_process(os_getpid());
32130 +void flush_thread_tt(void)
32132 + unsigned long stack;
32135 + stack = alloc_stack(0, 0);
32138 + "flush_thread : failed to allocate temporary stack\n");
32139 + do_exit(SIGKILL);
32142 + new_pid = start_fork_tramp(current, stack, 0, exec_tramp);
32145 + "flush_thread : new thread failed, errno = %d\n",
32147 + do_exit(SIGKILL);
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);
32158 + change_sig(SIGUSR1, 0);
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();
32167 +void start_thread_tt(struct pt_regs *regs, unsigned long eip,
32168 + unsigned long esp)
32171 + flush_tlb_mm(current->mm);
32172 + PT_REGS_IP(regs) = eip;
32173 + PT_REGS_SP(regs) = esp;
32174 + PT_FIX_EXEC_STACK(esp);
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
32182 + * ---------------------------------------------------------------------------
32183 + * Local variables:
32184 + * c-file-style: "linux"
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
32193 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
32194 + * Licensed under the GPL
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"
32208 +#include "ptrace_user.h"
32210 +void do_exec(int old_pid, int new_pid)
32212 + unsigned long regs[FRAME_SIZE];
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",
32220 + CATCH_EINTR(err = waitpid(new_pid, 0, WUNTRACED));
32222 + tracer_panic("do_exec failed to attach proc in waitpid - errno = %d",
32225 + if(ptrace_getregs(old_pid, regs) < 0)
32226 + tracer_panic("do_exec failed to get registers - errno = %d",
32229 + kill(old_pid, SIGKILL);
32231 + if(ptrace_setregs(new_pid, regs) < 0)
32232 + tracer_panic("do_exec failed to start new proc - errno = %d",
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
32241 + * ---------------------------------------------------------------------------
32242 + * Local variables:
32243 + * c-file-style: "linux"
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
32252 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32253 + * Licensed under the GPL
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"
32268 +#include "debug.h"
32269 +#include "kern_util.h"
32270 +#include "user_util.h"
32272 +#include "sysdep/thread.h"
32274 +extern int debugger_pid;
32275 +extern int debugger_fd;
32276 +extern int debugger_parent;
32278 +int detach(int pid, int sig)
32280 + return(ptrace(PTRACE_DETACH, pid, 0, sig));
32283 +int attach(int pid)
32287 + err = ptrace(PTRACE_ATTACH, pid, 0, 0);
32288 + if(err < 0) return(-errno);
32289 + else return(err);
32294 + return(ptrace(PTRACE_CONT, pid, 0, 0));
32297 +#ifdef UML_CONFIG_PT_PROXY
32299 +int debugger_signal(int status, pid_t pid)
32301 + return(debugger_proxy(status, pid));
32304 +void child_signal(pid_t pid, int status)
32306 + child_proxy(pid, status);
32309 +static void gdb_announce(char *dev_name, int dev)
32311 + printf("gdb assigned device '%s'\n", dev_name);
32314 +static struct chan_opts opts = {
32315 + .announce = gdb_announce,
32316 + .xterm_title = "UML kernel debugger",
32318 + .tramp_stack = 0,
32322 +/* Accessed by the tracing thread, which automatically serializes access */
32323 +static void *xterm_data;
32324 +static int xterm_fd;
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 *);
32330 +int open_gdb_chan(void)
32332 + char stack[UM_KERN_PAGE_SIZE], *dummy;
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);
32340 +static void exit_debugger_cb(void *unused)
32342 + if(debugger_pid != -1){
32343 + if(gdb_pid != -1){
32344 + fake_child_exit();
32347 + else kill_child_dead(debugger_pid);
32348 + debugger_pid = -1;
32349 + if(debugger_parent != -1)
32350 + detach(debugger_parent, SIGINT);
32352 + if(xterm_data != NULL) xterm_close(xterm_fd, xterm_data);
32355 +static void exit_debugger(void)
32357 + initial_thread_cb(exit_debugger_cb, NULL);
32360 +__uml_exitcall(exit_debugger);
32367 +static void config_gdb_cb(void *arg)
32369 + struct gdb_data *data = arg;
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){
32387 + debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
32388 + init_proxy(debugger_pid, 0, 0);
32391 +int gdb_config(char *str)
32393 + struct gdb_data data;
32395 + if(*str++ != '=') return(-1);
32397 + initial_thread_cb(config_gdb_cb, &data);
32398 + return(data.err);
32401 +void remove_gdb_cb(void *unused)
32403 + exit_debugger_cb(NULL);
32406 +int gdb_remove(char *unused)
32408 + initial_thread_cb(remove_gdb_cb, NULL);
32412 +void signal_usr1(int sig)
32414 + if(debugger_pid != -1){
32415 + printk(UM_KERN_ERR "The debugger is already running\n");
32418 + debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
32419 + init_proxy(debugger_pid, 0, 0);
32422 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
32426 + pid = start_debugger(linux_prog, startup, stop, &debugger_fd);
32427 + status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
32432 + init_proxy(pid, 1, status);
32436 +int attach_debugger(int idle_pid, int pid, int stop)
32438 + int status = 0, err;
32440 + err = attach(pid);
32442 + printf("Failed to attach pid %d, errno = %d\n", pid, -err);
32445 + if(stop) status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
32446 + init_proxy(pid, 1, status);
32450 +#ifdef notdef /* Put this back in when it does something useful */
32451 +static int __init uml_gdb_init_setup(char *line, int *add)
32453 + gdb_init = uml_strdup(line);
32457 +__uml_setup("gdb=", uml_gdb_init_setup,
32458 +"gdb=<channel description>\n\n"
32462 +static int __init uml_gdb_pid_setup(char *line, int *add)
32464 + gdb_pid = strtoul(line, NULL, 0);
32469 +__uml_setup("gdb-pid=", uml_gdb_pid_setup,
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"
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)
32481 + printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
32482 + kill_child_dead(idle_pid);
32486 +void signal_usr1(int sig)
32488 + printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
32491 +int attach_debugger(int idle_pid, int pid, int stop)
32493 + printk(UM_KERN_ERR "attach_debugger called when CONFIG_PT_PROXY "
32498 +int config_gdb(char *str)
32503 +int remove_gdb(void)
32508 +int init_parent_proxy(int pid)
32513 +void debugger_parent_signal(int status, int pid)
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
32524 + * ---------------------------------------------------------------------------
32525 + * Local variables:
32526 + * c-file-style: "linux"
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
32535 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32536 + * Licensed under the GPL
32539 +#include "linux/init.h"
32540 +#include "linux/config.h"
32541 +#include "mconsole_kern.h"
32543 +#ifdef CONFIG_MCONSOLE
32545 +extern int gdb_config(char *str);
32546 +extern int gdb_remove(char *unused);
32548 +static struct mc_device gdb_mc = {
32550 + .config = gdb_config,
32551 + .remove = gdb_remove,
32554 +int gdb_mc_init(void)
32556 + mconsole_register_dev(&gdb_mc);
32560 +__initcall(gdb_mc_init);
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
32569 + * ---------------------------------------------------------------------------
32570 + * Local variables:
32571 + * c-file-style: "linux"
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
32580 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) and
32581 + * Lars Brinkhoff.
32582 + * Licensed under the GPL
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);
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
32603 + * ---------------------------------------------------------------------------
32604 + * Local variables:
32605 + * c-file-style: "linux"
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
32614 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32615 + * Licensed under the GPL
32618 +#ifndef __TT_MMU_H
32619 +#define __TT_MMU_H
32621 +struct mmu_context_tt {
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
32631 + * ---------------------------------------------------------------------------
32632 + * Local variables:
32633 + * c-file-style: "linux"
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
32642 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32643 + * Licensed under the GPL
32646 +#ifndef __MODE_TT_H__
32647 +#define __MODE_TT_H__
32649 +#include "sysdep/ptrace.h"
32651 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
32653 +extern int tracing_pid;
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,
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);
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
32674 + * ---------------------------------------------------------------------------
32675 + * Local variables:
32676 + * c-file-style: "linux"
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
32685 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32686 + * Licensed under the GPL
32689 +#ifndef __TT_MODE_KERN_H__
32690 +#define __TT_MODE_KERN_H__
32692 +#include "linux/sched.h"
32693 +#include "asm/page.h"
32694 +#include "asm/ptrace.h"
32695 +#include "asm/uaccess.h"
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);
32722 +#define kmem_end_tt (host_task_size - ABOVE_KMEM)
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
32731 + * ---------------------------------------------------------------------------
32732 + * Local variables:
32733 + * c-file-style: "linux"
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
32742 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
32743 + * Licensed under the GPL
32746 +#ifndef __PTRACE_TT_H
32747 +#define __PTRACE_TT_H
32749 +#include "uml-config.h"
32751 +#ifdef UML_CONFIG_MODE_TT
32752 +#include "sysdep/sc.h"
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
32762 + * ---------------------------------------------------------------------------
32763 + * Local variables:
32764 + * c-file-style: "linux"
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
32773 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32774 + * Licensed under the GPL
32780 +#include "sysdep/ptrace.h"
32782 +extern int gdb_pid;
32784 +extern int debug_stop;
32785 +extern int debug_trace;
32787 +extern int honeypot;
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);
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
32811 + * ---------------------------------------------------------------------------
32812 + * Local variables:
32813 + * c-file-style: "linux"
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
32822 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
32823 + * Licensed under the GPL
32826 +#ifndef __TT_UACCESS_H
32827 +#define __TT_UACCESS_H
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"
32837 +#define ABOVE_KMEM (16 * 1024 * 1024)
32839 +extern unsigned long end_vm;
32840 +extern unsigned long uml_physmem;
32842 +#define under_task_size(addr, size) \
32843 + (((unsigned long) (addr) < TASK_SIZE) && \
32844 + (((unsigned long) (addr) + (size)) < TASK_SIZE))
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))
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))))
32856 +static inline int verify_area_tt(int type, const void * addr,
32857 + unsigned long size)
32859 + return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
32862 +extern unsigned long get_fault_addr(void);
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);
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);
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
32887 + * ---------------------------------------------------------------------------
32888 + * Local variables:
32889 + * c-file-style: "linux"
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
32898 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32899 + * Licensed under the GPL
32902 +#include "linux/module.h"
32903 +#include "asm/uaccess.h"
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);
32912 +EXPORT_SYMBOL(tracing_pid);
32913 +EXPORT_SYMBOL(honeypot);
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
32920 + * ---------------------------------------------------------------------------
32921 + * Local variables:
32922 + * c-file-style: "linux"
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
32931 +# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
32932 +# Licensed under the GPL
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
32941 +obj-$(CONFIG_PT_PROXY) += gdb_kern.o
32943 +subdir-y = sys-$(SUBARCH)
32944 +subdir-$(CONFIG_PT_PROXY) += ptproxy
32946 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
32948 +export-objs = ksyms.o
32950 +USER_OBJS = $(filter %_user.o,$(obj-y)) gdb.o time.o tracer.o
32952 +UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS))
32953 +UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS))
32955 +include $(TOPDIR)/Rules.make
32957 +$(USER_OBJS) : %.o: %.c
32958 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
32960 +$(O_TARGET) : unmap_fin.o
32963 + $(CC) $(UNMAP_CFLAGS) -c -o $@ $<
32965 +unmap_fin.o : unmap.o
32966 + ld -r -o $@ $< -lc -L/usr/lib
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
32975 + * Copyright (C) 2002 - 2004 Jeff Dike (jdike@karaya.com)
32976 + * Licensed under the GPL
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"
32989 +void before_mem_tt(unsigned long brk_start)
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);
32997 +#ifdef CONFIG_HOST_2G_2G
32998 +#define TOP 0x80000000
33000 +#define TOP 0xc0000000
33003 +#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
33004 +#define START (TOP - SIZE)
33006 +unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
33007 + unsigned long *task_size_out)
33009 + /* Round up to the nearest 4M */
33010 + *host_size_out = ROUND_4M((unsigned long) &arg);
33011 + *task_size_out = START;
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
33020 + * ---------------------------------------------------------------------------
33021 + * Local variables:
33022 + * c-file-style: "linux"
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
33031 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33032 + * Licensed under the GPL
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>
33042 +#include "mem_user.h"
33043 +#include "user_util.h"
33045 +void remap_data(void *segment_start, void *segment_end, int w)
33048 + unsigned long size;
33051 + if(w) prot = PROT_WRITE;
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");
33062 + memcpy(addr, segment_start, size);
33063 + if(switcheroo(data, prot, addr, segment_start, size) < 0){
33064 + printf("switcheroo failed\n");
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
33074 + * ---------------------------------------------------------------------------
33075 + * Local variables:
33076 + * c-file-style: "linux"
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
33085 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33086 + * Licensed under the GPL
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"
33102 +#include "sigcontext.h"
33103 +#include "time_user.h"
33104 +#include "mem_user.h"
33109 +#include "filehandle.h"
33111 +void *_switch_to_tt(void *prev, void *next)
33113 + struct task_struct *from, *to, *prev_sched;
33114 + struct file_handle *pipe;
33115 + unsigned long flags;
33116 + int err, vtalrm, alrm, prof, cpu;
33118 + /* jailing and SMP are incompatible, so this doesn't need to be
33121 + static int reading;
33126 + to->thread.prev_sched = from;
33128 + cpu = from->processor;
33130 + forward_interrupts(to->thread.mode.tt.extern_pid);
33132 + forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid);
33134 + local_irq_save(flags);
33136 + vtalrm = change_sig(SIGVTALRM, 0);
33137 + alrm = change_sig(SIGALRM, 0);
33138 + prof = change_sig(SIGPROF, 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);
33150 + if(from->state == TASK_ZOMBIE)
33151 + os_kill_process(os_getpid(), 0);
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);
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.
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);
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.
33184 + while(!reading) sched_yield();
33187 + change_sig(SIGVTALRM, vtalrm);
33188 + change_sig(SIGALRM, alrm);
33189 + change_sig(SIGPROF, prof);
33194 + local_irq_restore(flags);
33196 + return(current->thread.prev_sched);
33199 +void release_thread_tt(struct task_struct *task)
33201 + os_kill_process(task->thread.mode.tt.extern_pid, 0);
33204 +void exit_thread_tt(void)
33206 + struct file_handle *pipe = current->thread.mode.tt.switch_pipe;
33208 + close_file(&pipe[0]);
33209 + close_file(&pipe[1]);
33213 +static void suspend_new_thread(struct file_handle *fh)
33217 + os_stop_process(os_getpid());
33219 + if(read_file(fh, -1, &c, sizeof(c)) != sizeof(c))
33220 + panic("read failed in suspend_new_thread");
33223 +extern void schedule_tail(struct task_struct *prev);
33225 +static void new_thread_handler(int sig)
33227 + struct file_handle *pipe;
33228 + unsigned long disable;
33229 + int (*fn)(void *);
33232 + fn = current->thread.request.u.thread.proc;
33233 + arg = current->thread.request.u.thread.arg;
33235 + UPT_SC(¤t->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(¤t->thread.regs.regs)) &= ~disable;
33240 + pipe = current->thread.mode.tt.switch_pipe;
33241 + suspend_new_thread(&pipe[0]);
33243 + init_new_thread_signals(1);
33245 + free_page(current->thread.temp_stack);
33246 + set_cmdline("(kernel thread)");
33247 + force_flush_all();
33249 + if(current->thread.prev_sched != NULL)
33250 + schedule_tail(current->thread.prev_sched);
33251 + current->thread.prev_sched = NULL;
33253 + change_sig(SIGUSR1, 1);
33254 + change_sig(SIGVTALRM, 1);
33255 + change_sig(SIGPROF, 1);
33257 + if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf))
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.
33267 +static int new_thread_proc(void *stack)
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.
33283 + init_new_thread_stack(stack, new_thread_handler);
33284 + os_usr1_process(os_getpid());
33285 + change_sig(SIGUSR1, 1);
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.
33298 +static void finish_fork_handler(int sig)
33300 + struct file_handle *pipe = current->thread.mode.tt.switch_pipe;
33302 + UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
33303 + suspend_new_thread(&pipe[0]);
33305 + init_new_thread_signals(1);
33308 + force_flush_all();
33309 + if(current->mm != current->p_pptr->mm)
33310 + protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
33312 + task_protections((unsigned long) current);
33314 + if(current->thread.prev_sched != NULL)
33315 + schedule_tail(current->thread.prev_sched);
33316 + current->thread.prev_sched = NULL;
33318 + free_page(current->thread.temp_stack);
33320 + change_sig(SIGUSR1, 0);
33321 + set_user_mode(current);
33324 +int fork_tramp(void *stack)
33327 + arch_init_thread();
33328 + init_new_thread_stack(stack, finish_fork_handler);
33329 + os_usr1_process(os_getpid());
33330 + change_sig(SIGUSR1, 1);
33334 +struct file_handle *make_switch_pipe(void)
33336 + struct file_handle *pipe;
33339 + pipe = kmalloc(sizeof(struct file_handle [2]), GFP_KERNEL);
33340 + if(pipe == NULL){
33341 + pipe = ERR_PTR(-ENOMEM);
33345 + err = make_pipe(pipe);
33354 + pipe = ERR_PTR(err);
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)
33362 + int (*tramp)(void *);
33363 + int new_pid, err;
33364 + unsigned long stack;
33366 + if(current->thread.forking)
33367 + tramp = fork_tramp;
33369 + tramp = new_thread_proc;
33370 + p->thread.request.u.thread = current->thread.request.u.thread;
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);
33379 + stack = alloc_stack(0, 0);
33381 + printk(KERN_ERR "copy_thread : failed to allocate "
33382 + "temporary stack\n");
33387 + clone_flags &= CLONE_VM;
33388 + p->thread.temp_stack = stack;
33389 + new_pid = start_fork_tramp(p, stack, clone_flags, tramp);
33391 + printk(KERN_ERR "copy_thread : clone failed - errno = %d\n",
33397 + if(current->thread.forking){
33398 + sc_to_sc(UPT_SC(&p->thread.regs.regs),
33399 + UPT_SC(¤t->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;
33403 + p->thread.mode.tt.extern_pid = new_pid;
33405 + current->thread.request.op = OP_FORK;
33406 + current->thread.request.u.fork.pid = new_pid;
33407 + os_usr1_process(os_getpid());
33409 + /* Enable the signal and then disable it to ensure that it is handled
33410 + * here, and nowhere else.
33412 + change_sig(SIGUSR1, 1);
33414 + change_sig(SIGUSR1, 0);
33421 + free_stack(stack, 0);
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);
33429 +void reboot_tt(void)
33431 + current->thread.request.op = OP_REBOOT;
33432 + os_usr1_process(os_getpid());
33433 + change_sig(SIGUSR1, 1);
33436 +void halt_tt(void)
33438 + current->thread.request.op = OP_HALT;
33439 + os_usr1_process(os_getpid());
33440 + change_sig(SIGUSR1, 1);
33443 +void kill_off_processes_tt(void)
33445 + struct task_struct *p;
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);
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);
33459 +void initial_thread_cb_tt(void (*proc)(void *), void *arg)
33461 + if(os_getpid() == tracing_pid){
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);
33471 + change_sig(SIGUSR1, 0);
33475 +int do_proc_op(void *t, int proc_id)
33477 + struct task_struct *task;
33478 + struct thread_struct *thread;
33482 + thread = &task->thread;
33483 + op = thread->request.op;
33486 + case OP_TRACE_ON:
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;
33495 + attach_process(thread->request.u.fork.pid);
33498 + (*thread->request.u.cb.proc)(thread->request.u.cb.arg);
33504 + tracer_panic("Bad op in do_proc_op");
33507 + thread->request.op = OP_NONE;
33511 +void init_idle_tt(void)
33516 +/* Changed by jail_setup, which is a setup */
33519 +int __init jail_setup(char *line, int *add)
33523 + if(jail) return(0);
33525 + printf("'jail' may not used used in a kernel with CONFIG_SMP "
33529 +#ifdef CONFIG_HOSTFS
33530 + printf("'jail' may not used used in a kernel with CONFIG_HOSTFS "
33534 +#ifdef CONFIG_MODULES
33535 + printf("'jail' may not used used in a kernel with CONFIG_MODULES "
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.
33545 + cap_lower(cap_bset, CAP_SYS_RAWIO);
33550 +__uml_setup("jail", jail_setup,
33552 +" Enables the protection of kernel memory from processes.\n\n"
33555 +static void mprotect_kernel_mem(int w)
33557 + unsigned long start, end;
33560 + if(!jail || (current == &init_task)) return;
33562 + pages = (1 << CONFIG_KERNEL_STACK_ORDER);
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);
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);
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);
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);
33581 + mprotect_kernel_vm(w);
33584 +void unprotect_kernel_mem(void)
33586 + mprotect_kernel_mem(1);
33589 +void protect_kernel_mem(void)
33591 + mprotect_kernel_mem(0);
33594 +extern void start_kernel(void);
33596 +static int start_kernel_proc(void *unused)
33601 + pid = os_getpid();
33603 + cpu_tasks[0].pid = pid;
33604 + cpu_tasks[0].task = current;
33606 + cpu_online_map = 1;
33608 + if(debug) os_stop_process(pid);
33613 +void set_tracing(void *task, int tracing)
33615 + ((struct task_struct *) task)->thread.mode.tt.tracing = tracing;
33618 +int is_tracing(void *t)
33620 + return (((struct task_struct *) t)->thread.mode.tt.tracing);
33623 +int set_user_mode(void *t)
33625 + struct task_struct *task;
33627 + task = t ? t : current;
33628 + if(task->thread.mode.tt.tracing)
33630 + task->thread.request.op = OP_TRACE_ON;
33631 + os_usr1_process(os_getpid());
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
33639 +static struct file_handle init_switch_pipe[2];
33641 +void set_init_pid(int pid)
33645 + init_task.thread.mode.tt.extern_pid = pid;
33647 + err = make_pipe(init_switch_pipe);
33649 + panic("set_init_pid - make_pipe failed, errno = %d", err);
33650 + init_task.thread.mode.tt.switch_pipe = init_switch_pipe;
33653 +int start_uml_tt(void)
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));
33664 +int external_pid_tt(struct task_struct *task)
33666 + return(task->thread.mode.tt.extern_pid);
33669 +int thread_pid_tt(struct thread_struct *thread)
33671 + return(thread->mode.tt.extern_pid);
33674 +int is_valid_pid(int pid)
33676 + struct task_struct *task;
33678 + read_lock(&tasklist_lock);
33679 + for_each_task(task){
33680 + if(task->thread.mode.tt.extern_pid == pid){
33681 + read_unlock(&tasklist_lock);
33685 + read_unlock(&tasklist_lock);
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
33694 + * ---------------------------------------------------------------------------
33695 + * Local variables:
33696 + * c-file-style: "linux"
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
33704 +O_TARGET = ptproxy.o
33706 +obj-y = proxy.o ptrace.o sysdep.o wait.o
33708 +USER_OBJS = $(obj-y)
33710 +include $(TOPDIR)/Rules.make
33712 +$(USER_OBJS) : %.o: %.c
33713 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
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
33721 +/**********************************************************************
33724 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
33725 +terms and conditions.
33727 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
33728 +**********************************************************************/
33730 +/* XXX This file shouldn't refer to CONFIG_* */
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>
33745 +#include "ptproxy.h"
33746 +#include "sysdep.h"
33749 +#include "user_util.h"
33752 +#include "tempfile.h"
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,
33758 + int (*wait_return)(debugger_state *debugger,
33761 + if(debugger->real_wait){
33762 + debugger->handle_trace = normal_return;
33763 + syscall_continue(debugger->pid);
33764 + debugger->real_wait = 0;
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,
33773 + (*wait_return)(debugger, -1);
33776 + else if(debugger->wait_options & WNOHANG){
33777 + syscall_cancel(debugger->pid, 0);
33778 + debugger->handle_trace = syscall;
33782 + syscall_pause(debugger->pid);
33783 + debugger->handle_trace = wait_return;
33784 + debugger->waiting = 1;
33790 + * Handle debugger trap, i.e. syscall.
33793 +int debugger_syscall(debugger_state *debugger, pid_t child)
33795 + long arg1, arg2, arg3, arg4, arg5, result;
33796 + int syscall, ret = 0;
33798 + syscall = get_syscall(debugger->pid, &arg1, &arg2, &arg3, &arg4,
33802 + case __NR_execve:
33803 + /* execve never returns */
33804 + debugger->handle_trace = debugger_syscall;
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,
33813 + syscall_cancel(debugger->pid, result);
33814 + debugger->handle_trace = debugger_syscall;
33817 + case __NR_waitpid:
33819 + if(!debugger_wait(debugger, (int *) arg2, arg3,
33820 + debugger_syscall, debugger_normal_return,
33821 + proxy_wait_return))
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;
33834 + else debugger->handle_trace = debugger_normal_return;
33838 + debugger->handle_trace = debugger_normal_return;
33841 + syscall_continue(debugger->pid);
33845 +/* Used by the tracing thread */
33846 +static debugger_state parent;
33847 +static int parent_syscall(debugger_state *debugger, int pid);
33849 +int init_parent_proxy(int pid)
33851 + parent = ((debugger_state) { .pid = pid,
33852 + .wait_options = 0,
33853 + .wait_status_ptr = NULL,
33856 + .expecting_child = 0,
33857 + .handle_trace = parent_syscall,
33858 + .debugee = NULL } );
33862 +int parent_normal_return(debugger_state *debugger, pid_t unused)
33864 + debugger->handle_trace = parent_syscall;
33865 + syscall_continue(debugger->pid);
33869 +static int parent_syscall(debugger_state *debugger, int pid)
33871 + long arg1, arg2, arg3, arg4, arg5;
33874 + syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5);
33876 + if((syscall == __NR_waitpid) || (syscall == __NR_wait4)){
33877 + debugger_wait(&parent, (int *) arg2, arg3, parent_syscall,
33878 + parent_normal_return, parent_wait_return);
33880 + else ptrace(PTRACE_SYSCALL, pid, 0, 0);
33884 +int debugger_normal_return(debugger_state *debugger, pid_t unused)
33886 + debugger->handle_trace = debugger_syscall;
33887 + syscall_continue(debugger->pid);
33891 +void debugger_cancelled_return(debugger_state *debugger, int result)
33893 + debugger->handle_trace = debugger_syscall;
33894 + syscall_set_result(debugger->pid, result);
33895 + syscall_continue(debugger->pid);
33898 +/* Used by the tracing thread */
33899 +static debugger_state debugger;
33900 +static debugee_state debugee;
33902 +void init_proxy (pid_t debugger_pid, int stopped, int status)
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;
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;
33921 +int debugger_proxy(int status, int pid)
33923 + int ret = 0, sig;
33925 + if(WIFSTOPPED(status)){
33926 + sig = WSTOPSIG(status);
33927 + if (sig == SIGTRAP)
33928 + ret = (*debugger.handle_trace)(&debugger, pid);
33930 + else if(sig == SIGCHLD){
33931 + if(debugger.expecting_child){
33932 + ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
33933 + debugger.expecting_child = 0;
33935 + else if(debugger.waiting)
33936 + real_wait_return(&debugger);
33938 + ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
33939 + debugger.real_wait = 1;
33942 + else ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
33944 + else if(WIFEXITED(status)){
33945 + tracer_panic("debugger (pid %d) exited with status %d",
33946 + debugger.pid, WEXITSTATUS(status));
33948 + else if(WIFSIGNALED(status)){
33949 + tracer_panic("debugger (pid %d) exited with signal %d",
33950 + debugger.pid, WTERMSIG(status));
33953 + tracer_panic("proxy got unknown status (0x%x) on debugger "
33954 + "(pid %d)", status, debugger.pid);
33959 +void child_proxy(pid_t pid, int status)
33961 + debugee.event = 1;
33962 + debugee.wait_status = status;
33964 + if(WIFSTOPPED(status)){
33965 + debugee.stopped = 1;
33966 + debugger.expecting_child = 1;
33967 + kill(debugger.pid, SIGCHLD);
33969 + else if(WIFEXITED(status) || WIFSIGNALED(status)){
33970 + debugee.zombie = 1;
33971 + debugger.expecting_child = 1;
33972 + kill(debugger.pid, SIGCHLD);
33974 + else panic("proxy got unknown status (0x%x) on child (pid %d)",
33978 +void debugger_parent_signal(int status, int pid)
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);
33989 +void fake_child_exit(void)
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);
34001 + debugger_proxy(status, debugger.pid);
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);
34009 + if(ptrace(PTRACE_DETACH, debugger.pid, 0, SIGCONT) < 0)
34010 + printk("fake_child_exit - PTRACE_DETACH failed, errno = %d\n",
34014 +char gdb_init_string[] =
34018 +handle SIGWINCH nostop noprint pass \n\
34021 +int start_debugger(char *prog, int startup, int stop, int *fd_out)
34023 + int slave, child;
34025 + slave = open_gdb_chan();
34028 + char *tempname = NULL;
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",
34038 + if(ioctl(0, TIOCSCTTY, 0) < 0){
34039 + printk("start_debugger : TIOCSCTTY failed, "
34040 + "errno = %d\n", errno);
34043 + if(tcsetpgrp (1, os_getpid()) < 0){
34044 + printk("start_debugger : tcsetpgrp failed, "
34045 + "errno = %d\n", errno);
34050 + fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
34052 + printk("start_debugger : make_tempfile failed,"
34053 + "err = %d\n", -fd);
34056 + os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
34059 + os_write_file(fd, "b start_kernel\n",
34060 + strlen("b start_kernel\n"));
34062 + os_write_file(fd, "c\n", strlen("c\n"));
34064 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
34065 + printk("start_debugger : PTRACE_TRACEME failed, "
34066 + "errno = %d\n", errno);
34069 + execlp("gdb", "gdb", "--command", tempname, prog, NULL);
34070 + printk("start_debugger : exec of gdb failed, errno = %d\n",
34074 + printk("start_debugger : fork for gdb failed, errno = %d\n",
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
34087 + * ---------------------------------------------------------------------------
34088 + * Local variables:
34089 + * c-file-style: "linux"
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
34097 +/**********************************************************************
34100 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
34101 +terms and conditions.
34102 +**********************************************************************/
34104 +#ifndef __PTPROXY_H
34105 +#define __PTPROXY_H
34107 +#include <sys/types.h>
34109 +typedef struct debugger debugger_state;
34110 +typedef struct debugee debugee_state;
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);
34122 + debugee_state *debugee;
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;
34139 +extern int debugger_syscall(debugger_state *debugger, pid_t pid);
34140 +extern int debugger_normal_return (debugger_state *debugger, pid_t unused);
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);
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
34153 + * ---------------------------------------------------------------------------
34154 + * Local variables:
34155 + * c-file-style: "linux"
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
34163 +/**********************************************************************
34166 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
34167 +terms and conditions.
34169 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
34170 +**********************************************************************/
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>
34181 +#include "ptproxy.h"
34182 +#include "debug.h"
34183 +#include "user_util.h"
34184 +#include "kern_util.h"
34185 +#include "ptrace_user.h"
34188 +long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
34189 + long arg3, long arg4, pid_t child, int *ret)
34196 + if(debugger->debugee->died) return(-ESRCH);
34199 + case PTRACE_ATTACH:
34200 + if(debugger->debugee->traced) return(-EPERM);
34202 + debugger->debugee->pid = arg2;
34203 + debugger->debugee->traced = 1;
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);
34212 + debugger->debugee->in_context = 1;
34213 + if(debugger->debugee->stopped)
34214 + child_proxy(child, W_STOPCODE(SIGSTOP));
34215 + else kill(child, SIGSTOP);
34220 + case PTRACE_DETACH:
34221 + if(!debugger->debugee->traced) return(-EPERM);
34223 + debugger->debugee->traced = 0;
34224 + debugger->debugee->pid = 0;
34225 + if(!debugger->debugee->in_context)
34226 + kill(child, SIGCONT);
34230 + case PTRACE_CONT:
34231 + if(!debugger->debugee->in_context) return(-EPERM);
34232 + *ret = PTRACE_CONT;
34233 + return(ptrace(PTRACE_CONT, child, arg3, arg4));
34235 +#ifdef UM_HAVE_GETFPREGS
34236 + case PTRACE_GETFPREGS:
34238 + long regs[FP_FRAME_SIZE];
34241 + result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
34242 + if(result == -1) return(-errno);
34244 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
34245 + ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
34251 +#ifdef UM_HAVE_GETFPXREGS
34252 + case PTRACE_GETFPXREGS:
34254 + long regs[FPX_FRAME_SIZE];
34257 + result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
34258 + if(result == -1) return(-errno);
34260 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
34261 + ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
34267 +#ifdef UM_HAVE_GETREGS
34268 + case PTRACE_GETREGS:
34270 + long regs[FRAME_SIZE];
34273 + result = ptrace(PTRACE_GETREGS, child, 0, regs);
34274 + if(result == -1) return(-errno);
34276 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
34277 + ptrace (PTRACE_POKEDATA, debugger->pid,
34278 + arg4 + 4 * i, regs[i]);
34284 + case PTRACE_KILL:
34285 + result = ptrace(PTRACE_KILL, child, arg3, arg4);
34286 + if(result == -1) return(-errno);
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
34299 + result = ptrace(arg1, child, arg3, 0);
34300 + if((result == -1) && (errno != 0)) return(-errno);
34302 + result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
34303 + if(result == -1) return(-errno);
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);
34313 + if(arg1 == PTRACE_POKEUSER) ptrace_pokeuser(arg3, arg4);
34316 +#ifdef UM_HAVE_SETFPREGS
34317 + case PTRACE_SETFPREGS:
34319 + long regs[FP_FRAME_SIZE];
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);
34332 +#ifdef UM_HAVE_SETFPXREGS
34333 + case PTRACE_SETFPXREGS:
34335 + long regs[FPX_FRAME_SIZE];
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);
34348 +#ifdef UM_HAVE_SETREGS
34349 + case PTRACE_SETREGS:
34351 + long regs[FRAME_SIZE];
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);
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);
34373 + status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
34375 + child_proxy(child, status);
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);
34383 + *ret = PTRACE_SYSCALL;
34386 + case PTRACE_TRACEME:
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
34397 + * ---------------------------------------------------------------------------
34398 + * Local variables:
34399 + * c-file-style: "linux"
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
34407 +/**********************************************************************
34410 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
34411 +terms and conditions.
34412 +**********************************************************************/
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"
34427 +int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4,
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));
34438 +void syscall_cancel(pid_t pid, int result)
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",
34450 +void syscall_set_result(pid_t pid, long result)
34452 + ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result);
34455 +void syscall_continue(pid_t pid)
34457 + ptrace(PTRACE_SYSCALL, pid, 0, 0);
34460 +int syscall_pause(pid_t pid)
34462 + if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_pause) < 0){
34463 + printk("syscall_change - ptrace failed, errno = %d\n", errno);
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
34474 + * ---------------------------------------------------------------------------
34475 + * Local variables:
34476 + * c-file-style: "linux"
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
34484 +/**********************************************************************
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 +**********************************************************************/
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);
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
34504 + * ---------------------------------------------------------------------------
34505 + * Local variables:
34506 + * c-file-style: "linux"
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
34514 +/**********************************************************************
34517 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
34518 +terms and conditions.
34520 +**********************************************************************/
34522 +#include <errno.h>
34523 +#include <signal.h>
34524 +#include <sys/wait.h>
34525 +#include <sys/ptrace.h>
34526 +#include <asm/ptrace.h>
34528 +#include "ptproxy.h"
34529 +#include "sysdep.h"
34531 +#include "user_util.h"
34532 +#include "sysdep/ptrace.h"
34533 +#include "sysdep/ptrace_user.h"
34534 +#include "sysdep/sigcontext.h"
34536 +int proxy_wait_return(struct debugger *debugger, pid_t unused)
34538 + debugger->waiting = 0;
34540 + if(debugger->debugee->died || (debugger->wait_options & __WCLONE)){
34541 + debugger_cancelled_return(debugger, -ECHILD);
34545 + if(debugger->debugee->zombie && debugger->debugee->event)
34546 + debugger->debugee->died = 1;
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);
34554 + ptrace (PTRACE_POKEDATA, pid, rusage_ptr, ...); */
34555 + debugger_cancelled_return(debugger, debugger->debugee->pid);
34559 + /* pause will return -EINTR, which happens to be right for wait */
34560 + debugger_normal_return(debugger, -1);
34564 +int parent_wait_return(struct debugger *debugger, pid_t unused)
34566 + return(debugger_normal_return(debugger, -1));
34569 +int real_wait_return(struct debugger *debugger)
34571 + unsigned long ip;
34574 + pid = debugger->pid;
34576 + ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
34577 + IP_RESTART_SYSCALL(ip);
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);
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);
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
34597 + * ---------------------------------------------------------------------------
34598 + * Local variables:
34599 + * c-file-style: "linux"
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
34607 +/**********************************************************************
34610 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
34611 +terms and conditions.
34612 +**********************************************************************/
34614 +#ifndef __PTPROXY_WAIT_H
34615 +#define __PTPROXY_WAIT_H
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);
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
34628 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
34629 + * Licensed under the GPL
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"
34641 +static inline int check_area(void *ptr, int size)
34643 + return(verify_area(VERIFY_WRITE, ptr, size));
34646 +static int check_readlink(struct pt_regs *regs)
34648 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
34649 + UPT_SYSCALL_ARG2(®s->regs)));
34652 +static int check_utime(struct pt_regs *regs)
34654 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
34655 + sizeof(struct utimbuf)));
34658 +static int check_oldstat(struct pt_regs *regs)
34660 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
34661 + sizeof(struct __old_kernel_stat)));
34664 +static int check_stat(struct pt_regs *regs)
34666 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
34667 + sizeof(struct stat)));
34670 +static int check_stat64(struct pt_regs *regs)
34672 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
34673 + sizeof(struct stat64)));
34678 + int (*check_params)(struct pt_regs *);
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 },
34719 +static int check_bogosity(struct pt_regs *regs)
34721 + struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(®s->regs)];
34723 + if(!bogon->kernel_ds) return(0);
34724 + if(bogon->check_params && (*bogon->check_params)(regs))
34726 + set_fs(KERNEL_DS);
34730 +extern syscall_handler_t *sys_call_table[];
34732 +long execute_syscall_tt(void *r)
34734 + struct pt_regs *regs = r;
34738 + current->thread.nsyscalls++;
34740 + syscall = UPT_SYSCALL_NR(®s->regs);
34742 + if((syscall >= NR_syscalls) || (syscall < 0))
34744 + else if(honeypot && check_bogosity(regs))
34746 + else res = EXECUTE_SYSCALL(syscall, regs);
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
34758 + * ---------------------------------------------------------------------------
34759 + * Local variables:
34760 + * c-file-style: "linux"
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
34769 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
34770 + * Licensed under the GPL
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"
34782 +#include "user_util.h"
34783 +#include "kern_util.h"
34784 +#include "syscall_user.h"
34788 +#define ERESTARTSYS 512
34789 +#define ERESTARTNOINTR 513
34790 +#define ERESTARTNOHAND 514
34792 +void syscall_handler_tt(int sig, union uml_pt_regs *regs)
34796 + int index, syscall;
34798 + syscall = UPT_SYSCALL_NR(regs);
34799 + sc = UPT_SC(regs);
34800 + SC_START_SYSCALL(sc);
34802 + index = record_syscall_start(syscall);
34804 + result = execute_syscall(regs);
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.
34809 + UPT_SC(regs) = sc;
34811 + SC_SET_SYSCALL_RETURN(sc, result);
34812 + if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) ||
34813 + (result == -ERESTARTNOINTR))
34814 + do_signal(result);
34817 + record_syscall_end(index, result);
34820 +int do_syscall(void *task, int pid)
34822 + unsigned long proc_regs[FRAME_SIZE];
34823 + union uml_pt_regs *regs;
34826 + if(ptrace_getregs(pid, proc_regs) < 0)
34827 + tracer_panic("Couldn't read registers");
34828 + syscall = PT_SYSCALL_NR(proc_regs);
34830 + regs = TASK_REGS(task);
34831 + UPT_SYSCALL_NR(regs) = syscall;
34833 + if(syscall < 1) return(0);
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");
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);
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
34855 + * ---------------------------------------------------------------------------
34856 + * Local variables:
34857 + * c-file-style: "linux"
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
34866 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34867 +# Licensed under the GPL
34870 +O_TARGET = sys-i386.o
34872 +obj-y = sigcontext.o
34874 +USER_OBJS = sigcontext.o
34876 +include $(TOPDIR)/Rules.make
34878 +$(USER_OBJS) : %.o: %.c
34879 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
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
34888 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34889 + * Licensed under the GPL
34892 +#include <stdlib.h>
34893 +#include <asm/sigcontext.h>
34894 +#include "kern_util.h"
34895 +#include "sysdep/frame.h"
34897 +int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data)
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;
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);
34918 +int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data)
34920 + struct arch_frame_data *arch = data;
34921 + struct sigcontext *to = to_ptr, *from = from_ptr;
34922 + struct _fpstate *to_fp, *from_fp;
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);
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
34942 + * ---------------------------------------------------------------------------
34943 + * Local variables:
34944 + * c-file-style: "linux"
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
34953 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
34954 + * Licensed under the GPL
34957 +#include <signal.h>
34958 +#include <sys/time.h>
34959 +#include <time_user.h>
34960 +#include "process.h"
34963 +void user_time_init_tt(void)
34965 + if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
34966 + panic("Couldn't set SIGVTALRM handler");
34967 + set_interval(ITIMER_VIRTUAL);
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
34975 + * ---------------------------------------------------------------------------
34976 + * Local variables:
34977 + * c-file-style: "linux"
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
34986 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34987 + * Licensed under the GPL
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"
35000 +static void fix_range(struct mm_struct *mm, unsigned long start_addr,
35001 + unsigned long end_addr, int force)
35006 + unsigned long addr;
35007 + int r, w, x, err;
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",
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.
35023 + addr = STACK_TOP - ABOVE_KMEM;
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)){
35038 + if(force || pte_newpage(*npte)){
35039 + err = os_unmap_memory((void *) addr,
35042 + panic("munmap failed, errno = %d\n",
35044 + if(pte_present(*npte))
35046 + pte_val(*npte) & PAGE_MASK,
35047 + PAGE_SIZE, r, w, x);
35049 + else if(pte_newprot(*npte)){
35050 + protect_memory(addr, PAGE_SIZE, r, w, x, 1);
35052 + *npte = pte_mkuptodate(*npte);
35053 + addr += PAGE_SIZE;
35056 + if(force || pmd_newpage(*npmd)){
35057 + err = os_unmap_memory((void *) addr, PMD_SIZE);
35059 + panic("munmap failed, errno = %d\n",
35061 + pmd_mkuptodate(*npmd);
35063 + addr += PMD_SIZE;
35068 +atomic_t vmchange_seq = ATOMIC_INIT(1);
35070 +static void flush_kernel_vm_range(unsigned long start, unsigned long end,
35073 + struct mm_struct *mm;
35077 + unsigned long addr;
35078 + int updated = 0, err;
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)){
35088 + err = os_unmap_memory((void *) addr,
35091 + panic("munmap failed, errno = %d\n",
35093 + if(pte_present(*pte))
35095 + pte_val(*pte) & PAGE_MASK,
35096 + PAGE_SIZE, 1, 1, 1);
35098 + else if(pte_newprot(*pte)){
35100 + protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
35102 + addr += PAGE_SIZE;
35105 + if(pmd_newpage(*pmd)){
35107 + err = os_unmap_memory((void *) addr, PMD_SIZE);
35109 + panic("munmap failed, errno = %d\n",
35112 + addr += PMD_SIZE;
35115 + if(updated && update_seq) atomic_inc(&vmchange_seq);
35118 +static void protect_vm_page(unsigned long addr, int w, int must_succeed)
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);
35128 + else panic("protect_vm_page : protect failed, errno = %d\n", err);
35131 +void mprotect_kernel_vm(int w)
35133 + struct mm_struct *mm;
35137 + unsigned long addr;
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;
35148 + else addr += PMD_SIZE;
35152 +void flush_tlb_kernel_vm_tt(void)
35154 + flush_kernel_vm_range(start_vm, end_vm, 1);
35157 +void __flush_tlb_one_tt(unsigned long addr)
35159 + flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
35162 +void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start,
35163 + unsigned long end)
35165 + if(mm != current->mm) return;
35167 + /* Assumes that the range start ... end is entirely within
35168 + * either process memory or kernel vm
35170 + if((start >= start_vm) && (start < end_vm))
35171 + flush_kernel_vm_range(start, end, 1);
35172 + else fix_range(mm, start, end, 0);
35175 +void flush_tlb_mm_tt(struct mm_struct *mm)
35177 + unsigned long seq;
35179 + if(mm != current->mm) return;
35181 + fix_range(mm, 0, STACK_TOP, 0);
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);
35189 +void force_flush_all_tt(void)
35191 + fix_range(current->mm, 0, STACK_TOP, 1);
35192 + flush_kernel_vm_range(start_vm, end_vm, 0);
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
35200 + * ---------------------------------------------------------------------------
35201 + * Local variables:
35202 + * c-file-style: "linux"
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
35211 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
35212 + * Licensed under the GPL
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>
35228 +#include "sysdep/ptrace.h"
35229 +#include "sigcontext.h"
35230 +#include "sysdep/sigcontext.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"
35243 +static int tracer_winch[2];
35245 +int is_tracer_winch(int pid, int fd, void *data)
35247 + if(pid != tracing_pid)
35250 + register_winch_irq(tracer_winch[0], fd, -1, data);
35254 +static void tracer_winch_handler(int sig)
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);
35264 +/* Called only by the tracing thread during initialization */
35266 +static void setup_tracer_winch(void)
35270 + err = os_pipe(tracer_winch, 1, 1);
35272 + printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
35275 + signal(SIGWINCH, tracer_winch_handler);
35278 +void attach_process(int pid)
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");
35288 +void tracer_panic(char *format, ...)
35292 + va_start(ap, format);
35293 + vprintf(format, ap);
35295 + while(1) pause();
35298 +static void tracer_segv(int sig, struct sigcontext sc)
35300 + printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
35301 + SC_FAULT_ADDR(&sc), SC_IP(&sc));
35306 +/* Changed early in boot, and then only read */
35308 +int debug_stop = 1;
35309 +int debug_parent = 0;
35312 +static int signal_tramp(void *arg)
35314 + int (*proc)(void *);
35316 + if(honeypot && munmap((void *) (host_task_size - 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());
35329 + return((*proc)(NULL));
35332 +static void sleeping_process_signal(int pid, int 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.
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);
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.
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",
35362 + tracer_panic("sleeping process %d got unexpected "
35363 + "signal : %d\n", pid, sig);
35368 +/* Accessed only by the tracing thread */
35369 +int debugger_pid = -1;
35370 +int debugger_parent = -1;
35371 +int debugger_fd = -1;
35377 + unsigned long addr;
35378 + struct timeval time;
35379 +} signal_record[1024][32];
35381 +int signal_index[32];
35383 +int debug_trace = 0;
35384 +extern int io_nsignals, io_count, intr_count;
35386 +extern void signal_usr1(int sig);
35388 +int tracing_pid = -1;
35390 +int tracer(int (*init_proc)(void *), void *sp)
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;
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);
35404 + pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
35405 + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
35407 + printf("waitpid on idle thread failed, errno = %d\n", errno);
35410 + if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
35411 + printf("Failed to continue idle thread, errno = %d\n", errno);
35415 + signal(SIGSEGV, (sighandler_t) tracer_segv);
35416 + signal(SIGUSR1, signal_usr1);
35418 + printf("Tracing thread pausing to be attached\n");
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);
35430 + printf("Failed to attach debugger parent %d, "
35431 + "errno = %d\n", debugger_parent, -err);
35432 + debugger_parent = -1;
35435 + if(ptrace(PTRACE_SYSCALL, debugger_parent,
35437 + printf("Failed to continue debugger "
35438 + "parent, errno = %d\n", errno);
35439 + debugger_parent = -1;
35444 + set_cmdline("(tracing thread)");
35446 + CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED));
35448 + if(errno != ECHILD){
35449 + printf("wait failed - errno = %d\n", errno);
35453 + if(pid == debugger_pid){
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;
35463 + else if(pid == debugger_parent){
35464 + debugger_parent_signal(status, pid);
35468 + if(WIFEXITED(status)) ;
35471 + printf("Child %d exited with status %d\n", pid,
35472 + WEXITSTATUS(status));
35475 + else if(WIFSIGNALED(status)){
35476 + sig = WTERMSIG(status);
35478 + printf("Child %d exited with signal %d\n", pid,
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;
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;
35501 + if(proc_id == -1){
35502 + sleeping_process_signal(pid, sig);
35506 + task = cpu_tasks[proc_id].task;
35507 + tracing = is_tracing(task);
35508 + old_tracing = tracing;
35510 + cont_syscall = use_sysemu ? PTRACE_SYSEMU :
35515 + op = do_proc_op(task, proc_id);
35517 + case OP_TRACE_ON:
35518 + arch_leave_kernel(task, pid);
35525 + ptrace(PTRACE_KILL, pid, 0, 0);
35526 + return(op == OP_REBOOT);
35528 + printf("Detaching pid %d\n", pid);
35529 + detach(pid, SIGSTOP);
35534 + /* OP_EXEC switches host processes on us,
35535 + * we want to continue the new one.
35537 + pid = cpu_tasks[proc_id].pid;
35540 + if(!tracing && (debugger_pid != -1)){
35541 + child_signal(pid, status);
35545 + if(do_syscall(task, pid))
35549 + if(tracing) sig = 0;
35567 + set_tracing(task, tracing);
35569 + if(!tracing && old_tracing)
35570 + arch_enter_kernel(task, pid);
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);
35582 + if(singlestepping(task))
35583 + cont_type = PTRACE_SINGLESTEP;
35584 + else cont_type = cont_syscall;
35586 + else cont_type = PTRACE_CONT;
35588 + if((cont_type == PTRACE_CONT) &&
35589 + (debugger_pid != -1) && strace)
35590 + cont_type = PTRACE_SYSCALL;
35592 + if(ptrace(cont_type, pid, 0, sig) != 0){
35593 + tracer_panic("ptrace failed to continue "
35594 + "process - errno = %d\n",
35602 +static int __init uml_debug_setup(char *line, int *add)
35608 + if(*line != '=') return(0);
35611 + while(line != NULL){
35612 + next = strchr(line, ',');
35613 + if(next) *next++ = '\0';
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);
35624 +__uml_setup("debug", uml_debug_setup,
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"
35631 +static int __init uml_debugtrace_setup(char *line, int *add)
35636 +__uml_setup("debugtrace", uml_debugtrace_setup,
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"
35644 +static int __init uml_honeypot_setup(char *line, int *add)
35646 + jail_setup("", add);
35650 +__uml_setup("honeypot", uml_honeypot_setup,
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"
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
35662 + * ---------------------------------------------------------------------------
35663 + * Local variables:
35664 + * c-file-style: "linux"
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
35673 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
35674 + * Licensed under the GPL
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"
35688 +void sig_handler_common_tt(int sig, void *sc_ptr)
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;
35695 + unprotect_kernel_mem();
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.
35701 + if(sig == SIGSEGV)
35702 + change_sig(SIGSEGV, 1);
35704 + r = &TASK_REGS(get_current())->tt;
35706 + is_user = user_context(SC_SP(sc));
35708 + if(sig != SIGUSR2)
35711 + info = &sig_info[sig];
35712 + if(!info->is_irq) unblock_signals();
35714 + (*info->handler)(sig, (union uml_pt_regs *) r);
35719 + set_user_mode(NULL);
35722 + errno = save_errno;
35723 + if(is_user) protect_kernel_mem();
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
35731 + * ---------------------------------------------------------------------------
35732 + * Local variables:
35733 + * c-file-style: "linux"
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
35742 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
35743 + * Licensed under the GPL
35746 +#include "linux/sched.h"
35747 +#include "asm/uaccess.h"
35749 +int copy_from_user_tt(void *to, const void *from, int n)
35751 + if(!access_ok_tt(VERIFY_READ, from, n))
35754 + return(__do_copy_from_user(to, from, n, ¤t->thread.fault_addr,
35755 + ¤t->thread.fault_catcher));
35758 +int copy_to_user_tt(void *to, const void *from, int n)
35760 + if(!access_ok_tt(VERIFY_WRITE, to, n))
35763 + return(__do_copy_to_user(to, from, n, ¤t->thread.fault_addr,
35764 + ¤t->thread.fault_catcher));
35767 +int strncpy_from_user_tt(char *dst, const char *src, int count)
35771 + if(!access_ok_tt(VERIFY_READ, src, 1))
35774 + n = __do_strncpy_from_user(dst, src, count,
35775 + ¤t->thread.fault_addr,
35776 + ¤t->thread.fault_catcher);
35777 + if(n < 0) return(-EFAULT);
35781 +int __clear_user_tt(void *mem, int len)
35783 + return(__do_clear_user(mem, len,
35784 + ¤t->thread.fault_addr,
35785 + ¤t->thread.fault_catcher));
35788 +int clear_user_tt(void *mem, int len)
35790 + if(!access_ok_tt(VERIFY_WRITE, mem, len))
35793 + return(__do_clear_user(mem, len, ¤t->thread.fault_addr,
35794 + ¤t->thread.fault_catcher));
35797 +int strnlen_user_tt(const void *str, int len)
35799 + return(__do_strnlen_user(str, len,
35800 + ¤t->thread.fault_addr,
35801 + ¤t->thread.fault_catcher));
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
35809 + * ---------------------------------------------------------------------------
35810 + * Local variables:
35811 + * c-file-style: "linux"
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
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
35825 +#include <setjmp.h>
35826 +#include <string.h>
35827 +#include "user_util.h"
35828 +#include "uml_uaccess.h"
35830 +#include "kern_util.h"
35832 +int __do_copy_from_user(void *to, const void *from, int n,
35833 + void **fault_addr, void **fault_catcher)
35835 + struct tt_regs save = TASK_REGS(get_current())->tt;
35836 + unsigned long fault;
35839 + fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
35840 + __do_copy, &faulted);
35841 + TASK_REGS(get_current())->tt = save;
35843 + if(!faulted) return(0);
35844 + else return(n - (fault - (unsigned long) from));
35847 +static void __do_strncpy(void *dst, const void *src, int count)
35849 + strncpy(dst, src, count);
35852 +int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
35853 + void **fault_addr, void **fault_catcher)
35855 + struct tt_regs save = TASK_REGS(get_current())->tt;
35856 + unsigned long fault;
35859 + fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
35860 + __do_strncpy, &faulted);
35861 + TASK_REGS(get_current())->tt = save;
35863 + if(!faulted) return(strlen(dst));
35867 +static void __do_clear(void *to, const void *from, int n)
35869 + memset(to, 0, n);
35872 +int __do_clear_user(void *mem, unsigned long len,
35873 + void **fault_addr, void **fault_catcher)
35875 + struct tt_regs save = TASK_REGS(get_current())->tt;
35876 + unsigned long fault;
35879 + fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
35880 + __do_clear, &faulted);
35881 + TASK_REGS(get_current())->tt = save;
35883 + if(!faulted) return(0);
35884 + else return(len - (fault - (unsigned long) mem));
35887 +int __do_strnlen_user(const char *str, unsigned long n,
35888 + void **fault_addr, void **fault_catcher)
35890 + struct tt_regs save = TASK_REGS(get_current())->tt;
35892 + unsigned long *faddrp = (unsigned long *)fault_addr;
35895 + *fault_catcher = &jbuf;
35896 + if(sigsetjmp(jbuf, 1) == 0)
35897 + ret = strlen(str) + 1;
35898 + else ret = *faddrp - (unsigned long) str;
35900 + *fault_addr = NULL;
35901 + *fault_catcher = NULL;
35903 + TASK_REGS(get_current())->tt = save;
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
35912 + * ---------------------------------------------------------------------------
35913 + * Local variables:
35914 + * c-file-style: "linux"
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
35923 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
35924 + * Licensed under the GPL
35927 +#include <sys/mman.h>
35929 +int switcheroo(int fd, int prot, void *from, void *to, int size)
35931 + if(munmap(to, size) < 0){
35934 + if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
35937 + if(munmap(from, size) < 0){
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
35948 + * ---------------------------------------------------------------------------
35949 + * Local variables:
35950 + * c-file-style: "linux"
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
35959 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and
35960 + * geoffrey hing <ghing@net.ohio-state.edu>
35961 + * Licensed under the GPL
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>
35972 +#include "kern_util.h"
35975 +#define TTY_LOG_DIR "./"
35977 +/* Set early in boot and then unchanged */
35978 +static char *tty_log_dir = TTY_LOG_DIR;
35979 +static int tty_log_fd = -1;
35981 +#define TTY_LOG_OPEN 1
35982 +#define TTY_LOG_CLOSE 2
35983 +#define TTY_LOG_WRITE 3
35984 +#define TTY_LOG_EXEC 4
35986 +#define TTY_READ 1
35987 +#define TTY_WRITE 2
35989 +struct tty_log_buf {
35991 + unsigned long tty;
35994 + unsigned long sec;
35995 + unsigned long usec;
35998 +int open_tty_log(void *tty, void *current_tty)
36000 + struct timeval tv;
36001 + struct tty_log_buf data;
36002 + char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
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),
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, ¤t_tty, data.len);
36015 + return(tty_log_fd);
36018 + sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
36019 + (unsigned int) tv.tv_usec);
36021 + fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
36024 + printk("open_tty_log : couldn't open '%s', errno = %d\n",
36030 +void close_tty_log(int fd, void *tty)
36032 + struct tty_log_buf data;
36033 + struct timeval tv;
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,
36041 + .sec = tv.tv_sec,
36042 + .usec = tv.tv_usec } );
36043 + os_write_file(tty_log_fd, &data, sizeof(data));
36046 + os_close_file(fd);
36049 +static int log_chunk(int fd, const char *buf, int len)
36051 + int total = 0, try, missed, n;
36055 + try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
36056 + missed = copy_from_user_proc(chunk, (char *) buf, try);
36058 + n = os_write_file(fd, chunk, try);
36075 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
36077 + struct timeval tv;
36078 + struct tty_log_buf data;
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,
36087 + .direction = direction,
36088 + .sec = tv.tv_sec,
36089 + .usec = tv.tv_usec } );
36090 + os_write_file(tty_log_fd, &data, sizeof(data));
36093 + return(log_chunk(fd, buf, len));
36096 +void log_exec(char **argv, void *tty)
36098 + struct timeval tv;
36099 + struct tty_log_buf data;
36103 + if(tty_log_fd == -1) return;
36105 + gettimeofday(&tv, NULL);
36108 + for(ptr = argv; ; ptr++){
36109 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
36111 + if(arg == NULL) break;
36112 + len += strlen_user_proc(arg);
36115 + data = ((struct tty_log_buf) { .what = TTY_LOG_EXEC,
36116 + .tty = (unsigned long) tty,
36119 + .sec = tv.tv_sec,
36120 + .usec = tv.tv_usec } );
36121 + os_write_file(tty_log_fd, &data, sizeof(data));
36123 + for(ptr = argv; ; ptr++){
36124 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
36126 + if(arg == NULL) break;
36127 + log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
36131 +extern void register_tty_logger(int (*opener)(void *, void *),
36132 + int (*writer)(int, const char *, int,
36134 + void (*closer)(int, void *));
36136 +static int register_logger(void)
36138 + register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
36142 +__uml_initcall(register_logger);
36144 +static int __init set_tty_log_dir(char *name, int *add)
36146 + tty_log_dir = name;
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"
36156 +static int __init set_tty_log_fd(char *name, int *add)
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);
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"
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
36183 + * ---------------------------------------------------------------------------
36184 + * Local variables:
36185 + * c-file-style: "linux"
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
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
36199 +#include <setjmp.h>
36200 +#include <string.h>
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.
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)
36211 + unsigned long *faddrp = (unsigned long *) fault_addr, ret;
36214 + *fault_catcher = &jbuf;
36215 + if(sigsetjmp(jbuf, 1) == 0){
36216 + (*op)(to, from, n);
36218 + *faulted_out = 0;
36222 + *faulted_out = 1;
36224 + *fault_addr = NULL;
36225 + *fault_catcher = NULL;
36229 +void __do_copy(void *to, const void *from, int n)
36231 + memcpy(to, from, n);
36235 +int __do_copy_to_user(void *to, const void *from, int n,
36236 + void **fault_addr, void **fault_catcher)
36238 + unsigned long fault;
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));
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
36252 + * ---------------------------------------------------------------------------
36253 + * Local variables:
36254 + * c-file-style: "linux"
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
36263 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
36264 + * Licensed under the GPL
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"
36291 +#include "mem_user.h"
36294 +#include "initrd.h"
36297 +#include "choose-mode.h"
36298 +#include "mode_kern.h"
36301 +#define DEFAULT_COMMAND_LINE "root=/dev/ubd0"
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 }
36312 +unsigned long thread_saved_pc(struct thread_struct *thread)
36314 + return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
36318 +static int show_cpuinfo(struct seq_file *m, void *v)
36323 + index = (struct cpuinfo_um *)v - cpu_data;
36324 + if (!(cpu_online_map & (1 << index)))
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);
36340 +static void *c_start(struct seq_file *m, loff_t *pos)
36342 + return *pos < NR_CPUS ? cpu_data + *pos : NULL;
36345 +static void *c_next(struct seq_file *m, void *v, loff_t *pos)
36348 + return c_start(m, pos);
36351 +static void c_stop(struct seq_file *m, void *v)
36355 +struct seq_operations cpuinfo_op = {
36356 + .start = c_start,
36359 + .show = show_cpuinfo,
36362 +pte_t * __bad_pagetable(void)
36364 + panic("Someone should implement __bad_pagetable");
36368 +/* Set in linux_main */
36369 +unsigned long host_task_size;
36370 +unsigned long task_size;
36371 +unsigned long uml_start;
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;
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
36385 +static char *argv1_begin = NULL;
36386 +static char *argv1_end = NULL;
36389 +/* Set in early boot */
36390 +static int have_root __initdata = 0;
36391 +long physmem_size = 32 * 1024 * 1024;
36393 +void set_cmdline(char *cmd)
36395 +#ifdef CONFIG_MODE_TT
36396 + char *umid, *ptr;
36398 + if(CHOOSE_MODE(honeypot, 0)) return;
36400 + umid = get_umid(1);
36401 + if(umid != NULL){
36402 + snprintf(argv1_begin,
36403 + (argv1_end - argv1_begin) * sizeof(*ptr),
36405 + ptr = &argv1_begin[strlen(argv1_begin)];
36407 + else ptr = argv1_begin;
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));
36415 +static char *usage_string =
36416 +"User Mode Linux v%s\n"
36417 +" available at http://user-mode-linux.sourceforge.net/\n\n";
36419 +static int __init uml_version_setup(char *line, int *add)
36421 + printf("%s\n", system_utsname.release);
36425 +__uml_setup("--version", uml_version_setup,
36427 +" Prints the version number of the kernel.\n\n"
36430 +static int __init uml_root_setup(char *line, int *add)
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"
36446 +static int __init uml_ncpus_setup(char *line, int *add)
36448 + if (!sscanf(line, "%d", &ncpus)) {
36449 + printf("Couldn't parse [%s]\n", line);
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"
36464 +#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
36465 +#define DEFAULT_TT 0
36467 +static int __init mode_tt_setup(char *line, int *add)
36474 +#ifdef CONFIG_MODE_SKAS
36476 +#define DEFAULT_TT 0
36478 +static int __init mode_tt_setup(char *line, int *add)
36480 + printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
36485 +#ifdef CONFIG_MODE_TT
36487 +#define DEFAULT_TT 1
36489 +static int __init mode_tt_setup(char *line, int *add)
36491 + printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
36497 +#error Either CONFIG_MODE_TT or CONFIG_MODE_SKAS must be enabled
36503 +__uml_setup("mode=tt", mode_tt_setup,
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"
36510 +int mode_tt = DEFAULT_TT;
36512 +static int __init Usage(char *line, int *add)
36516 + printf(usage_string, system_utsname.release);
36517 + p = &__uml_help_start;
36518 + while (p < &__uml_help_end) {
36519 + printf("%s", *p);
36525 +__uml_setup("--help", Usage,
36527 +" Prints this message.\n\n"
36530 +static int __init uml_checksetup(char *line, int *add)
36532 + struct uml_param *p;
36534 + p = &__uml_setup_start;
36535 + while(p < &__uml_setup_end) {
36538 + n = strlen(p->str);
36539 + if(!strncmp(line, p->str, n)){
36540 + if (p->setup_func(line + n, add)) return 1;
36547 +static void __init uml_postsetup(void)
36551 + p = &__uml_postsetup_start;
36552 + while(p < &__uml_postsetup_end){
36559 +/* Set during early boot */
36560 +unsigned long brk_start;
36561 +unsigned long end_iomem;
36563 +#define MIN_VMALLOC (32 * 1024 * 1024)
36565 +int linux_main(int argc, char **argv)
36567 + unsigned long avail, diff;
36568 + unsigned long virtmem_size, max_physmem;
36569 + unsigned int i, add;
36571 + for (i = 1; i < argc; i++){
36572 + if((i == 1) && (argv[i][0] == ' ')) continue;
36574 + uml_checksetup(argv[i], &add);
36575 + if(add) add_arg(saved_command_line, argv[i]);
36577 + if(have_root == 0) add_arg(saved_command_line, DEFAULT_COMMAND_LINE);
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);
36583 + /* Need to check this early because mmapping happens before the
36584 + * kernel is running.
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 */
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);
36601 + uml_physmem = uml_start;
36603 + /* Reserve up to 4M after the current brk */
36604 + uml_reserved = ROUND_4M(brk_start) + (1 << 22);
36606 + setup_machinename(system_utsname.machine);
36608 +#ifdef CONFIG_MODE_TT
36609 + argv1_begin = argv[1];
36610 + argv1_end = &argv[1][strlen(argv[1])];
36614 + iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
36615 + max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
36617 + /* Zones have to begin on a 1 << MAX_ORDER page boundary,
36618 + * so this makes sure that's true for highmem
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
36626 + printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
36627 + "to %ld bytes\n", physmem_size);
36631 + high_physmem = uml_physmem + physmem_size;
36632 + end_iomem = high_physmem + iomem_size;
36633 + high_memory = (void *) end_iomem;
36635 + start_vm = VMALLOC_START;
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,
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;
36650 + if(virtmem_size < physmem_size)
36651 + printf("Kernel virtual memory size shrunk to %ld bytes\n",
36656 + task_protections((unsigned long) &init_task);
36657 + os_flush_stdout();
36659 + return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
36662 +extern int uml_exitcode;
36664 +static int panic_exit(struct notifier_block *self, unsigned long unused1,
36667 +#ifdef CONFIG_MAGIC_SYSRQ
36668 + handle_sysrq('p', ¤t->thread.regs, NULL, NULL);
36670 + uml_exitcode = 1;
36675 +static struct notifier_block panic_exit_notifier = {
36676 + .notifier_call = panic_exit,
36681 +void __init setup_arch(char **cmdline_p)
36683 + notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
36685 + strcpy(command_line, saved_command_line);
36686 + *cmdline_p = command_line;
36687 + setup_hostinfo();
36690 +void __init check_bugs(void)
36692 + arch_check_bugs();
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
36702 + * ---------------------------------------------------------------------------
36703 + * Local variables:
36704 + * c-file-style: "linux"
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
36713 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
36714 + * Licensed under the GPL
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>
36730 +#include "user_util.h"
36731 +#include "choose-mode.h"
36733 +#define UMID_LEN 64
36734 +#define UML_DIR "~/.uml/"
36736 +/* Changed by set_umid and make_umid, which are run early in boot */
36737 +static char umid[UMID_LEN] = { 0 };
36739 +/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
36740 +static char *uml_dir = UML_DIR;
36742 +/* Changed by set_umid */
36743 +static int umid_is_random = 1;
36744 +static int umid_inited = 0;
36746 +static int make_umid(int (*printer)(const char *fmt, ...));
36748 +static int __init set_umid(char *name, int is_random,
36749 + int (*printer)(const char *fmt, ...))
36752 + (*printer)("Unique machine name can't be set twice\n");
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';
36762 + umid_is_random = is_random;
36767 +static int __init set_umid_arg(char *name, int *add)
36770 + return(set_umid(name, 0, printf));
36773 +__uml_setup("umid=", set_umid_arg,
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"
36779 +int __init umid_file_name(char *name, char *buf, int len)
36783 + if(!umid_inited && make_umid(printk)) return(-1);
36785 + n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
36787 + printk("umid_file_name : buffer too short\n");
36791 + sprintf(buf, "%s%s/%s", uml_dir, umid, name);
36795 +extern int tracing_pid;
36797 +static int __init create_pid_file(void)
36799 + char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
36800 + char pid[sizeof("nnnnn\0")];
36803 + if(umid_file_name("pid", file, sizeof(file))) return 0;
36805 + fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
36808 + printf("Open of machine pid file \"%s\" failed - "
36809 + "err = %d\n", file, -fd);
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);
36821 +static int actually_do_remove(char *dir)
36824 + struct dirent *ent;
36828 + directory = opendir(dir);
36829 + if(directory == NULL){
36830 + printk("actually_do_remove : couldn't open directory '%s', "
36831 + "errno = %d\n", dir, errno);
36834 + while((ent = readdir(directory)) != NULL){
36835 + if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
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);
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,
36851 + if(rmdir(dir) < 0){
36852 + printk("actually_do_remove : couldn't rmdir '%s', "
36853 + "errno = %d\n", dir, errno);
36859 +void remove_umid_dir(void)
36861 + char dir[strlen(uml_dir) + UMID_LEN + 1];
36862 + if(!umid_inited) return;
36864 + sprintf(dir, "%s%s", uml_dir, umid);
36865 + actually_do_remove(dir);
36868 +char *get_umid(int only_if_set)
36870 + if(only_if_set && umid_is_random) return(NULL);
36874 +int not_dead_yet(char *dir)
36876 + char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
36877 + char pid[sizeof("nnnnn\0")], *end;
36878 + int dead, fd, p, n;
36880 + sprintf(file, "%s/pid", dir);
36882 + fd = os_open_file(file, of_read(OPENFLAGS()), 0);
36884 + if(fd != -ENOENT){
36885 + printk("not_dead_yet : couldn't open pid file '%s', "
36886 + "err = %d\n", file, -fd);
36892 + n = os_read_file(fd, pid, sizeof(pid));
36894 + printk("not_dead_yet : couldn't read pid file '%s', "
36895 + "err = %d\n", file, -n);
36898 + p = strtoul(pid, &end, 0);
36900 + printk("not_dead_yet : couldn't parse pid file '%s', "
36901 + "errno = %d\n", file, errno);
36904 + if(((kill(p, 0) < 0) && (errno == ESRCH)) ||
36905 + (p == CHOOSE_MODE(tracing_pid, os_getpid())))
36908 + if(!dead) return(1);
36909 + return(actually_do_remove(dir));
36912 +static int __init set_uml_dir(char *name, int *add)
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",
36920 + /* Return 0 here because do_initcalls doesn't look at
36921 + * the return value.
36925 + sprintf(uml_dir, "%s/", name);
36927 + else uml_dir = name;
36931 +static int __init make_uml_dir(void)
36933 + char dir[MAXPATHLEN + 1] = { '\0' };
36936 + if(*uml_dir == '~'){
36937 + char *home = getenv("HOME");
36939 + if(home == NULL){
36940 + printf("make_uml_dir : no value in environment for "
36944 + strncpy(dir, home, sizeof(dir));
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] != '/')){
36952 + dir[len + 1] = '\0';
36955 + uml_dir = malloc(strlen(dir) + 1);
36956 + if(uml_dir == NULL){
36957 + printf("make_uml_dir : malloc failed, errno = %d\n", errno);
36960 + strcpy(uml_dir, dir);
36962 + if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
36963 + printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
36969 +static int __init make_umid(int (*printer)(const char *fmt, ...))
36972 + char tmp[strlen(uml_dir) + UMID_LEN + 1];
36974 + strncpy(tmp, uml_dir, sizeof(tmp) - 1);
36975 + tmp[sizeof(tmp) - 1] = '\0';
36977 + if(!umid_inited){
36978 + strcat(tmp, "XXXXXX");
36979 + fd = mkstemp(tmp);
36981 + (*printer)("make_umid - mkstemp failed, errno = %d\n",
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.
36992 + set_umid(&tmp[strlen(uml_dir)], 1, printer);
36995 + sprintf(tmp, "%s%s", uml_dir, umid);
36997 + err = mkdir(tmp, 0777);
36999 + if(errno == EEXIST){
37000 + if(not_dead_yet(tmp)){
37001 + (*printer)("umid '%s' is in use\n", umid);
37004 + err = mkdir(tmp, 0777);
37008 + (*printer)("Failed to create %s - errno = %d\n", umid, errno);
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"
37020 +__uml_postsetup(make_uml_dir);
37022 +static int __init make_umid_setup(void)
37024 + return(make_umid(printf));
37027 +__uml_postsetup(make_umid_setup);
37028 +__uml_postsetup(create_pid_file);
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
37035 + * ---------------------------------------------------------------------------
37036 + * Local variables:
37037 + * c-file-style: "linux"
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
37045 +#include "linux/types.h"
37046 +#include "linux/module.h"
37048 +/* XXX Deleted a number of symbols because they clashed strangely with headers
37049 + * Add them back later.
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.*/
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 *, ...);
37068 +//EXPORT_SYMBOL(strlen);
37069 +EXPORT_SYMBOL(memset);
37070 +EXPORT_SYMBOL(memcpy);
37073 +EXPORT_SYMBOL(strstr);
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
37081 +#define EXPORT_SYMBOL_PROTO(sym) \
37083 + EXPORT_SYMBOL(sym);
37085 +EXPORT_SYMBOL_PROTO(__errno_location);
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);
37106 +EXPORT_SYMBOL_PROTO(symlink);
37107 +EXPORT_SYMBOL_PROTO(link);
37108 +EXPORT_SYMBOL_PROTO(unlink);
37109 +EXPORT_SYMBOL_PROTO(readlink);
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);
37119 +EXPORT_SYMBOL_PROTO(ioctl);
37121 +EXPORT_SYMBOL_PROTO(pread64);
37122 +EXPORT_SYMBOL_PROTO(pwrite64);
37124 +EXPORT_SYMBOL_PROTO(statfs);
37125 +EXPORT_SYMBOL_PROTO(statfs64);
37127 +EXPORT_SYMBOL_PROTO(getuid);
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
37136 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
37137 + * Licensed under the GPL
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>
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"
37163 +#include "mem_user.h"
37165 +#include "helper.h"
37166 +#include "uml-config.h"
37168 +#define COMMAND_LINE_SIZE _POSIX_ARG_MAX
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 };
37174 +void add_arg(char *cmd_line, char *arg)
37176 + if (strlen(cmd_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
37177 + printf("add_arg: Too much command line!\n");
37180 + if(strlen(cmd_line) > 0) strcat(cmd_line, " ");
37181 + strcat(cmd_line, arg);
37186 + while(1) sleep(1000000);
37189 +void stack_protections(unsigned long address)
37191 + int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
37193 + if(mprotect((void *) address, page_size(), prot) < 0)
37194 + panic("protecting stack failed, errno = %d", errno);
37197 +void task_protections(unsigned long address)
37199 + unsigned long guard = address + page_size();
37200 + unsigned long stack = guard + page_size();
37201 + int prot = 0, pages;
37203 + if(mprotect((void *) guard, page_size(), prot) < 0)
37204 + panic("protecting guard page failed, errno = %d", errno);
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);
37212 +int wait_for_stop(int pid, int sig, int cont_type, void *relay)
37214 + sigset_t *relay_signals = relay;
37218 + CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED));
37220 + !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
37222 + printk("wait failed, errno = %d\n",
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));
37241 + else if((relay_signals != NULL) &&
37242 + sigismember(relay_signals, WSTOPSIG(status))){
37243 + ptrace(cont_type, pid, 0, WSTOPSIG(status));
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);
37257 + struct termios tt;
37260 + CATCH_EINTR(err = tcgetattr(fd, &tt));
37262 + printk("tcgetattr failed, errno = %d\n", errno);
37268 + CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt));
37270 + printk("tcsetattr failed, errno = %d\n", errno);
37274 + /* XXX tcsetattr could have applied only some changes
37275 + * (and cfmakeraw() is a set of changes) */
37279 +void setup_machinename(char *machine_out)
37281 + struct utsname host;
37284 + strcpy(machine_out, host.machine);
37287 +char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1];
37289 +void setup_hostinfo(void)
37291 + struct utsname host;
37294 + sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename,
37295 + host.release, host.version, host.machine);
37298 +int setjmp_wrapper(void (*proc)(void *, void *), ...)
37304 + n = sigsetjmp(buf, 1);
37306 + va_start(args, proc);
37307 + (*proc)(&buf, &args);
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
37318 + * ---------------------------------------------------------------------------
37319 + * Local variables:
37320 + * c-file-style: "linux"
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
37329 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
37330 +# Licensed under the GPL
37333 +OS := $(shell uname -s)
37335 +ARCH_DIR = arch/um
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))
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)
37345 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
37346 +include $(ARCH_DIR)/Makefile-os-$(OS)
37348 +MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
37349 +MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
37351 +ifneq ($(MAKEFILE-y),)
37352 + include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
37355 +EXTRAVERSION := $(EXTRAVERSION)-1um
37357 +include/linux/version.h: arch/$(ARCH)/Makefile
37359 +# We require bash because the vmlinux link and loader script cpp use bash
37361 +SHELL := /bin/bash
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
37368 +MODLIB := $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
37370 +ifeq ($(CONFIG_DEBUGSYM),y)
37371 +CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS))
37374 +CFLAGS-$(CONFIG_DEBUGSYM) += -g
37376 +ARCH_INCLUDE = -I$(TOPDIR)/$(ARCH_DIR)/include
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
37383 +CFLAGS += $(ARCH_CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
37384 + -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
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)
37389 +CFLAGS += $(call check_gcc,-fno-unit-at-a-time,)
37393 +LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
37395 +# These are needed for clean and mrproper, since in that case .config is not
37396 +# included; the values here are meaningless
37398 +CONFIG_NEST_LEVEL ?= 0
37399 +CONFIG_KERNEL_HALF_GIGS ?= 0
37401 +SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
37403 +# These aren't in Makefile-tt because they are needed in the !CONFIG_MODE_TT +
37404 +# CONFIG_MODE_SKAS + CONFIG_STATIC_LINK case.
37407 +LD_SCRIPT_TT := link.ld
37409 +ifeq ($(CONFIG_STATIC_LINK),y)
37410 + LINK-y += $(LINK_TT)
37411 + LD_SCRIPT-y := $(LD_SCRIPT_TT)
37413 +ifeq ($(CONFIG_MODE_TT),y)
37414 + LINK-y += $(LINK_TT)
37415 + LD_SCRIPT-y := $(LD_SCRIPT_TT)
37417 +ifeq ($(CONFIG_MODE_SKAS),y)
37418 + LINK-y += $(LINK_SKAS)
37419 + LD_SCRIPT-y := $(LD_SCRIPT_SKAS)
37424 +LD_SCRIPT-y := $(ARCH_DIR)/kernel/$(LD_SCRIPT-y)
37425 +M4_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT)
37428 + START = $$(($(TOP_ADDR) - $(SIZE)))
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 )) $< > $@
37437 +SYMLINK_HEADERS = archparam.h system.h sigcontext.h processor.h ptrace.h \
37439 +SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
37441 +ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \
37442 + $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
37444 +ifeq ($(CONFIG_MODE_SKAS), y)
37445 +$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
37448 +GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
37450 +setup: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS)
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
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) \
37462 +# To get a definition of F_SETSIG
37463 +USER_CFLAGS += -D_GNU_SOURCE
37465 +CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/link.ld $(ARCH_DIR)/dyn_link.ld \
37467 +# $(ARCH_DIR)/include/uml-config.h removed temporarily because this causes
37468 +# make to fail after make clean
37471 + rm -f $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
37472 + $(LD_SCRIPT) $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
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
37482 +$(SYMLINK_HEADERS):
37483 + cd $(TOPDIR)/$(dir $@) ; \
37484 + ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
37486 +include/asm-um/arch:
37487 + cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
37489 +arch/um/include/sysdep:
37490 + cd $(TOPDIR)/arch/um/include && ln -sf sysdep-$(SUBARCH) sysdep
37493 + cd $(ARCH_DIR) && ln -sf os-$(OS) os
37495 +$(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
37498 +$(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
37501 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
37502 + sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
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
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
37512 +export SUBARCH USER_CFLAGS OS
37517 + echo '* linux - Binary kernel image (./linux)'
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
37524 +ifeq ($(CONFIG_HOST_2G_2G),y)
37525 +TOP_ADDR = 0x80000000
37527 +TOP_ADDR = 0xc0000000
37530 +ifeq ($(CONFIG_MODE_SKAS),y)
37531 + ifneq ($(CONFIG_MODE_TT),y)
37532 + START = 0x8048000
37536 +ARCH_CFLAGS = -U__$(SUBARCH)__ -U$(SUBARCH)
37538 +ifneq ($(CONFIG_GPROF),y)
37539 +ARCH_CFLAGS += -DUM_FASTCALL
37542 +ELF_ARCH = $(SUBARCH)
37543 +ELF_FORMAT = elf32-$(SUBARCH)
37545 +I386_H = $(ARCH_DIR)/include/sysdep-i386
37546 +SYS = $(ARCH_DIR)/sys-i386
37547 +UTIL = $(SYS)/util
37548 +SUBDIRS += $(UTIL)
37550 +SYS_HEADERS = $(I386_H)/sc.h $(I386_H)/thread.h
37552 +$(I386_H)/sc.h : $(UTIL)/mk_sc
37553 + $(UTIL)/mk_sc > $@
37555 +$(I386_H)/thread.h : $(UTIL)/mk_thread
37556 + $(UTIL)/mk_thread > $@
37558 +$(UTIL)/mk_sc : $(UTIL)/mk_sc.c
37559 + $(MAKE) -C $(UTIL) mk_sc
37561 +$(UTIL)/mk_thread : $(UTIL)/mk_thread_user.c $(UTIL)/mk_thread_kern.c \
37563 + $(MAKE) -C $(UTIL) mk_thread
37566 + rm -f $(SYS_HEADERS)
37567 + $(MAKE) -C $(UTIL) clean
37568 + $(MAKE) -C $(SYS) clean
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
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
37582 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
37583 +# Licensed under the GPL
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
37593 +ifeq ($(CONFIG_HOST_2G_2G), y)
37594 +START_ADDR = 0x80000000
37596 +START_ADDR = 0xc0000000
37598 +ARCH_CFLAGS = -U__powerpc__ -D__UM_PPC__
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
37608 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
37609 +# Licensed under the GPL
37614 +CFLAGS-$(CONFIG_GCOV) += -fprofile-arcs -ftest-coverage
37615 +CFLAGS-$(CONFIG_GPROF) += $(PROFILE)
37616 +LINK-$(CONFIG_GPROF) += $(PROFILE)
37618 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/skas/include
37620 +LINK_SKAS = -Wl,-rpath,/lib
37621 +LD_SCRIPT_SKAS = dyn_link.ld
37623 +GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
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
37633 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
37634 +# Licensed under the GPL
37637 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/tt/include
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
37645 + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
37646 + * Licensed under the GPL
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>
37656 +#include "helper.h"
37662 +struct aio_thread_req {
37663 + enum aio_type type;
37665 + unsigned long long offset;
37672 +static int aio_req_fd_r = -1;
37673 +static int aio_req_fd_w = -1;
37675 +#if defined(HAVE_AIO_ABI)
37676 +#include <linux/aio_abi.h>
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.
37682 +#if !defined(HAVE_AIO_LIBC)
37684 +#define __NR_io_setup 245
37685 +#define __NR_io_getevents 247
37686 +#define __NR_io_submit 248
37688 +static long io_setup(int n, aio_context_t *ctxp)
37690 + return(syscall(__NR_io_setup, n, ctxp));
37693 +static long io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp)
37695 + return(syscall(__NR_io_submit, ctx, nr, iocbpp));
37698 +static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
37699 + struct io_event *events, struct timespec *timeout)
37701 + return(syscall(__NR_io_getevents, ctx_id, min_nr, nr, events, timeout));
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.
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)
37720 + struct iocb iocb, *iocbp = &iocb;
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 });
37736 + iocb.aio_lio_opcode = IOCB_CMD_PREAD;
37737 + err = io_submit(ctx, 1, &iocbp);
37740 + iocb.aio_lio_opcode = IOCB_CMD_PWRITE;
37741 + err = io_submit(ctx, 1, &iocbp);
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);
37750 + printk("Bogus op in do_aio - %d\n", type);
37760 +static aio_context_t ctx = 0;
37762 +static int aio_thread(void *arg)
37764 + struct aio_thread_reply reply;
37765 + struct io_event event;
37766 + int err, n, reply_fd;
37768 + signal(SIGWINCH, SIG_IGN);
37771 + n = io_getevents(ctx, 1, 1, &event, NULL);
37773 + if(errno == EINTR)
37775 + printk("aio_thread - io_getevents failed, "
37776 + "errno = %d\n", errno);
37779 + reply = ((struct aio_thread_reply)
37780 + { .data = (void *) event.data,
37781 + .err = event.res });
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);
37796 +static int do_not_aio(struct aio_thread_req *req)
37801 + switch(req->type){
37803 + err = os_seek_file(req->io_fd, req->offset);
37807 + err = os_read_file(req->io_fd, req->buf, req->len);
37810 + err = os_seek_file(req->io_fd, req->offset);
37814 + err = os_write_file(req->io_fd, req->buf, req->len);
37817 + err = os_seek_file(req->io_fd, req->offset);
37821 + err = os_read_file(req->io_fd, &c, sizeof(c));
37824 + printk("do_not_aio - bad request type : %d\n", req->type);
37833 +static int not_aio_thread(void *arg)
37835 + struct aio_thread_req req;
37836 + struct aio_thread_reply reply;
37839 + signal(SIGWINCH, SIG_IGN);
37841 + err = os_read_file(aio_req_fd_r, &req, sizeof(req));
37842 + if(err != sizeof(req)){
37844 + printk("not_aio_thread - read failed, fd = %d, "
37845 + "err = %d\n", aio_req_fd_r, -err);
37847 + printk("not_aio_thread - short read, fd = %d, "
37848 + "length = %d\n", aio_req_fd_r, err);
37852 + err = do_not_aio(&req);
37853 + reply = ((struct aio_thread_reply) { .data = req.data,
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);
37862 +static int aio_pid = -1;
37864 +static int init_aio_24(void)
37866 + unsigned long stack;
37869 + err = os_pipe(fds, 1, 1);
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);
37878 + goto 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;
37892 +#ifdef HAVE_AIO_ABI
37893 +#define DEFAULT_24_AIO 0
37894 +static int init_aio_26(void)
37896 + unsigned long stack;
37899 + if(io_setup(256, &ctx)){
37900 + printk("aio_thread failed to initialize context, err = %d\n",
37905 + err = run_helper_thread(aio_thread, NULL,
37906 + CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
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)
37919 + struct aio_thread_reply reply;
37922 + ((struct aio_context *) data)->reply_fd = reply_fd;
37924 + err = do_aio(ctx, type, io_fd, buf, len, offset, data);
37926 + reply = ((struct aio_thread_reply) { .data = data,
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);
37939 +#define DEFAULT_24_AIO 1
37940 +static int init_aio_26(void)
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)
37952 +static int aio_24 = DEFAULT_24_AIO;
37954 +static int __init set_aio_24(char *name, int *add)
37960 +__uml_setup("aio=2.4", set_aio_24,
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"
37970 +static int init_aio(void)
37976 + printk("Disabling 2.6 AIO in tt mode\n");
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");
37987 + else return(err);
37991 + return(init_aio_24());
37996 +__initcall(init_aio);
37998 +static void exit_aio(void)
38000 + if(aio_pid != -1)
38001 + os_kill_process(aio_pid, 1);
38004 +__uml_exitcall(exit_aio);
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)
38009 + struct aio_thread_req req = { .type = type,
38011 + .offset = offset,
38014 + .reply_fd = reply_fd,
38019 + err = os_write_file(aio_req_fd_w, &req, sizeof(req));
38020 + if(err == sizeof(req))
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)
38030 + return(submit_aio_24(type, io_fd, buf, len, offset, reply_fd,
38033 + return(submit_aio_26(type, io_fd, buf, len, offset, reply_fd,
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
38043 + * ---------------------------------------------------------------------------
38044 + * Local variables:
38045 + * c-file-style: "linux"
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
38054 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
38055 + * Licensed under the GPL
38058 +#include "net_user.h"
38060 +struct ethertap_data {
38068 +extern struct net_user_info ethertap_user_info;
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
38075 + * ---------------------------------------------------------------------------
38076 + * Local variables:
38077 + * c-file-style: "linux"
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
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.
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"
38099 +struct ethertap_init {
38104 +static void etap_init(struct net_device *dev, void *data)
38106 + struct uml_net_private *pri;
38107 + struct ethertap_data *epri;
38108 + struct ethertap_init *init = data;
38110 + init_etherdev(dev, 0);
38112 + epri = (struct ethertap_data *) pri->user;
38113 + *epri = ((struct ethertap_data)
38114 + { .dev_name = init->dev_name,
38115 + .gate_addr = init->gate_addr,
38117 + .control_fd = -1,
38120 + printk("ethertap backend - %s", epri->dev_name);
38121 + if(epri->gate_addr != NULL)
38122 + printk(", IP = %s", epri->gate_addr);
38126 +static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
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);
38140 +static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
38142 + if(skb_headroom(*skb) < 2){
38143 + struct sk_buff *skb2;
38145 + skb2 = skb_realloc_headroom(*skb, 2);
38146 + dev_kfree_skb(*skb);
38147 + if (skb2 == NULL) return(-ENOMEM);
38150 + skb_push(*skb, 2);
38151 + return(net_send(fd, (*skb)->data, (*skb)->len));
38154 +struct net_kern_info ethertap_kern_info = {
38155 + .init = etap_init,
38156 + .protocol = eth_protocol,
38157 + .read = etap_read,
38158 + .write = etap_write,
38161 +int ethertap_setup(char *str, char **mac_out, void *data)
38163 + struct ethertap_init *init = data;
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))
38171 + if(init->dev_name == NULL){
38172 + printk("ethertap_setup : Missing tap device name\n");
38179 +static struct transport ethertap_transport = {
38180 + .list = LIST_HEAD_INIT(ethertap_transport.list),
38181 + .name = "ethertap",
38182 + .setup = ethertap_setup,
38183 + .user = ðertap_user_info,
38184 + .kern = ðertap_kern_info,
38185 + .private_size = sizeof(struct ethertap_data),
38188 +static int register_ethertap(void)
38190 + register_transport(ðertap_transport);
38194 +__initcall(register_ethertap);
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
38201 + * ---------------------------------------------------------------------------
38202 + * Local variables:
38203 + * c-file-style: "linux"
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
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.
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>
38228 +#include "kern_util.h"
38229 +#include "user_util.h"
38230 +#include "net_user.h"
38232 +#include "helper.h"
38235 +#define MAX_PACKET ETH_MAX_PACKET
38237 +void etap_user_init(void *data, void *dev)
38239 + struct ethertap_data *pri = data;
38244 +struct addr_change {
38245 + enum { ADD_ADDR, DEL_ADDR } what;
38246 + unsigned char addr[4];
38247 + unsigned char netmask[4];
38250 +static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
38253 + struct addr_change change;
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);
38273 +static void etap_open_addr(unsigned char *addr, unsigned char *netmask,
38276 + etap_change(ADD_ADDR, addr, netmask, *((int *) arg));
38279 +static void etap_close_addr(unsigned char *addr, unsigned char *netmask,
38282 + etap_change(DEL_ADDR, addr, netmask, *((int *) arg));
38285 +struct etap_pre_exec_data {
38286 + int control_remote;
38291 +static void etap_pre_exec(void *arg)
38293 + struct etap_pre_exec_data *data = arg;
38295 + dup2(data->control_remote, 1);
38296 + os_close_file(data->data_me);
38297 + os_close_file(data->control_me);
38300 +static int etap_tramp(char *dev, char *gate, int control_me,
38301 + int control_remote, int data_me, int data_remote)
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 };
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;
38320 + else args = nosetup_args;
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);
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);
38337 + printk("etap_tramp : uml_net failed\n");
38339 + CATCH_EINTR(n = waitpid(pid, &status, 0));
38342 + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
38343 + printk("uml_net didn't exit with status 1\n");
38348 +static int etap_open(void *data)
38350 + struct ethertap_data *pri = data;
38352 + int data_fds[2], control_fds[2], err, output_len;
38354 + err = tap_open_common(pri->dev, pri->gate_addr);
38355 + if(err) return(err);
38357 + err = os_pipe(data_fds, 0, 0);
38359 + printk("data os_pipe failed - err = %d\n", -err);
38363 + err = os_pipe(control_fds, 1, 0);
38365 + printk("control os_pipe failed - err = %d\n", -err);
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);
38375 + if(output == NULL)
38376 + printk("etap_open : failed to allocate output buffer\n");
38378 + printk("%s", output);
38383 + printk("etap_tramp failed - err = %d\n", -err);
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]);
38393 +static void etap_close(int fd, void *data)
38395 + struct ethertap_data *pri = data;
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;
38406 +static int etap_set_mtu(int mtu, void *data)
38411 +static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
38414 + struct ethertap_data *pri = data;
38416 + tap_check_ips(pri->gate_addr, addr);
38417 + if(pri->control_fd == -1) return;
38418 + etap_open_addr(addr, netmask, &pri->control_fd);
38421 +static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
38424 + struct ethertap_data *pri = data;
38426 + if(pri->control_fd == -1) return;
38427 + etap_close_addr(addr, netmask, &pri->control_fd);
38430 +struct net_user_info ethertap_user_info = {
38431 + .init = etap_user_init,
38432 + .open = etap_open,
38433 + .close = etap_close,
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
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
38446 + * ---------------------------------------------------------------------------
38447 + * Local variables:
38448 + * c-file-style: "linux"
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
38457 +# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
38458 +# Licensed under the GPL
38461 +O_TARGET := drivers.o
38463 +list-multi := tuntap.o ethertap.o
38465 +ethertap-objs := ethertap_kern.o ethertap_user.o
38466 +tuntap-objs := tuntap_kern.o tuntap_user.o
38469 +obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap.o
38470 +obj-$(CONFIG_UML_NET_TUNTAP) += tuntap.o
38472 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y)),$($(f)-objs))
38474 +USER_OBJS = $(filter %_user.o,$(obj-y) $(USER_SINGLE_OBJS))
38476 +include $(TOPDIR)/Rules.make
38478 +$(USER_OBJS) : %.o: %.c
38479 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
38481 +ethertap.o : $(ethertap-objs)
38483 +tuntap.o : $(tuntap-objs)
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
38493 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
38494 + * Licensed under the GPL
38497 +#ifndef __UM_TUNTAP_H
38498 +#define __UM_TUNTAP_H
38500 +#include "net_user.h"
38502 +struct tuntap_data {
38504 + int fixed_config;
38510 +extern struct net_user_info tuntap_user_info;
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
38519 + * ---------------------------------------------------------------------------
38520 + * Local variables:
38521 + * c-file-style: "linux"
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
38530 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
38531 + * Licensed under the GPL
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"
38544 +struct tuntap_init {
38549 +static void tuntap_init(struct net_device *dev, void *data)
38551 + struct uml_net_private *pri;
38552 + struct tuntap_data *tpri;
38553 + struct tuntap_init *init = data;
38555 + init_etherdev(dev, 0);
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,
38564 + printk("TUN/TAP backend - ");
38565 + if(tpri->gate_addr != NULL)
38566 + printk("IP = %s", tpri->gate_addr);
38570 +static int tuntap_read(int fd, struct sk_buff **skb,
38571 + struct uml_net_private *lp)
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));
38579 +static int tuntap_write(int fd, struct sk_buff **skb,
38580 + struct uml_net_private *lp)
38582 + return(net_write(fd, (*skb)->data, (*skb)->len));
38585 +struct net_kern_info tuntap_kern_info = {
38586 + .init = tuntap_init,
38587 + .protocol = eth_protocol,
38588 + .read = tuntap_read,
38589 + .write = tuntap_write,
38592 +int tuntap_setup(char *str, char **mac_out, void *data)
38594 + struct tuntap_init *init = data;
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))
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),
38616 +static int register_tuntap(void)
38618 + register_transport(&tuntap_transport);
38622 +__initcall(register_tuntap);
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
38629 + * ---------------------------------------------------------------------------
38630 + * Local variables:
38631 + * c-file-style: "linux"
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
38640 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
38641 + * Licensed under the GPL
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"
38661 +#include "helper.h"
38664 +#define MAX_PACKET ETH_MAX_PACKET
38666 +void tuntap_user_init(void *data, void *dev)
38668 + struct tuntap_data *pri = data;
38673 +static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
38676 + struct tuntap_data *pri = data;
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);
38683 +static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
38686 + struct tuntap_data *pri = data;
38688 + if((pri->fd == -1) || pri->fixed_config) return;
38689 + close_addr(addr, netmask, pri->dev_name);
38692 +struct tuntap_pre_exec_data {
38697 +static void tuntap_pre_exec(void *arg)
38699 + struct tuntap_pre_exec_data *data = arg;
38701 + dup2(data->stdout, 1);
38702 + os_close_file(data->close_me);
38705 +static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
38706 + char *buffer, int buffer_len, int *used_out)
38708 + struct tuntap_pre_exec_data data;
38709 + char version_buf[sizeof("nnnnn\0")];
38710 + char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate,
38712 + char buf[CMSG_SPACE(sizeof(*fd_out))];
38713 + struct msghdr msg;
38714 + struct cmsghdr *cmsg;
38715 + struct iovec iov;
38718 + sprintf(version_buf, "%d", UML_NET_VERSION);
38720 + data.stdout = remote;
38721 + data.close_me = me;
38723 + pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
38725 + if(pid < 0) return(-pid);
38727 + os_close_file(remote);
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;
38737 + msg.msg_iov = NULL;
38738 + msg.msg_iovlen = 0;
38740 + msg.msg_control = buf;
38741 + msg.msg_controllen = sizeof(buf);
38742 + msg.msg_flags = 0;
38743 + n = recvmsg(me, &msg, 0);
38746 + printk("tuntap_open_tramp : recvmsg failed - errno = %d\n",
38750 + CATCH_EINTR(waitpid(pid, NULL, 0));
38752 + cmsg = CMSG_FIRSTHDR(&msg);
38753 + if(cmsg == NULL){
38754 + printk("tuntap_open_tramp : didn't receive a message\n");
38757 + if((cmsg->cmsg_level != SOL_SOCKET) ||
38758 + (cmsg->cmsg_type != SCM_RIGHTS)){
38759 + printk("tuntap_open_tramp : didn't receive a descriptor\n");
38762 + *fd_out = ((int *) CMSG_DATA(cmsg))[0];
38766 +static int tuntap_open(void *data)
38768 + struct ifreq ifr;
38769 + struct tuntap_data *pri = data;
38770 + char *output, *buffer;
38771 + int err, fds[2], len, used;
38773 + err = tap_open_common(pri->dev, pri->gate_addr);
38777 + if(pri->fixed_config){
38778 + pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
38780 + printk("Failed to open /dev/net/tun, err = %d\n",
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);
38794 + err = os_pipe(fds, 0, 0);
38796 + printk("tuntap_open : os_pipe failed - err = %d\n",
38801 + buffer = get_output_buffer(&len);
38802 + if(buffer != NULL) len--;
38805 + err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
38806 + fds[1], buffer, len, &used);
38810 + printk("%s", output);
38811 + free_output_buffer(buffer);
38812 + printk("tuntap_open_tramp failed - err = %d\n", -err);
38816 + pri->dev_name = uml_strdup(buffer);
38817 + output += IFNAMSIZ;
38818 + printk("%s", output);
38819 + free_output_buffer(buffer);
38821 + os_close_file(fds[0]);
38822 + iter_addresses(pri->dev, open_addr, pri->dev_name);
38828 +static void tuntap_close(int fd, void *data)
38830 + struct tuntap_data *pri = data;
38832 + if(!pri->fixed_config)
38833 + iter_addresses(pri->dev, close_addr, pri->dev_name);
38834 + os_close_file(fd);
38838 +static int tuntap_set_mtu(int mtu, void *data)
38843 +struct net_user_info tuntap_user_info = {
38844 + .init = tuntap_user_init,
38845 + .open = tuntap_open,
38846 + .close = tuntap_close,
38848 + .set_mtu = tuntap_set_mtu,
38849 + .add_address = tuntap_add_addr,
38850 + .delete_address = tuntap_del_addr,
38851 + .max_packet = MAX_PACKET
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
38859 + * ---------------------------------------------------------------------------
38860 + * Local variables:
38861 + * c-file-style: "linux"
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
38870 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38871 + * Licensed under the GPL
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>
38893 +#include "kern_util.h"
38895 +static void copy_stat(struct uml_stat *dst, struct stat64 *src)
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),
38916 +int os_stat_fd(const int fd, struct uml_stat *ubuf)
38918 + struct stat64 sbuf;
38922 + err = fstat64(fd, &sbuf);
38923 + } while((err < 0) && (errno == EINTR)) ;
38929 + copy_stat(ubuf, &sbuf);
38933 +int os_stat_file(const char *file_name, struct uml_stat *ubuf)
38935 + struct stat64 sbuf;
38939 + err = stat64(file_name, &sbuf);
38940 + } while((err < 0) && (errno == EINTR)) ;
38946 + copy_stat(ubuf, &sbuf);
38950 +int os_lstat_file(const char *file_name, struct uml_stat *ubuf)
38952 + struct stat64 sbuf;
38956 + err = lstat64(file_name, &sbuf);
38957 + } while((err < 0) && (errno == EINTR)) ;
38963 + copy_stat(ubuf, &sbuf);
38967 +int os_access(const char *file, int mode)
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) ;
38974 + err = access(file, amode);
38981 +int os_set_file_time(const char *file, unsigned long access, unsigned long mod)
38983 + struct utimbuf buf = ((struct utimbuf){ .actime = access,
38984 + .modtime = mod });
38987 + err = utime(file, &buf);
38994 +int os_set_file_perms(const char *file, int mode)
38998 + err = chmod(file, mode);
39005 +int os_set_file_owner(const char *file, int owner, int group)
39009 + err = chown(file, owner, group);
39016 +void os_print_error(int error, const char* str)
39018 + errno = error < 0 ? -error : error;
39023 +/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
39024 +int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
39028 + err = ioctl(fd, cmd, arg);
39035 +int os_window_size(int fd, int *rows, int *cols)
39037 + struct winsize size;
39039 + if(ioctl(fd, TIOCGWINSZ, &size) < 0)
39042 + *rows = size.ws_row;
39043 + *cols = size.ws_col;
39048 +int os_new_tty_pgrp(int fd, int pid)
39050 + if(ioctl(fd, TIOCSCTTY, 0) < 0){
39051 + printk("TIOCSCTTY failed, errno = %d\n", errno);
39055 + if(tcsetpgrp(fd, pid) < 0){
39056 + printk("tcsetpgrp failed, errno = %d\n", errno);
39063 +/* FIXME: ensure namebuf in os_get_if_name is big enough */
39064 +int os_get_ifname(int fd, char* namebuf)
39066 + if(ioctl(fd, SIOCGIFNAME, namebuf) < 0)
39072 +int os_set_slip(int fd)
39074 + int disc, sencap;
39077 + if(ioctl(fd, TIOCSETD, &disc) < 0){
39078 + printk("Failed to set slip line discipline - "
39079 + "errno = %d\n", errno);
39084 + if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){
39085 + printk("Failed to set slip encapsulation - "
39086 + "errno = %d\n", errno);
39093 +int os_set_owner(int fd, int pid)
39095 + if(fcntl(fd, F_SETOWN, pid) < 0){
39096 + int save_errno = errno;
39098 + if(fcntl(fd, F_GETOWN, 0) != pid)
39099 + return(-save_errno);
39105 +/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */
39106 +int os_sigio_async(int master, int slave)
39110 + flags = fcntl(master, F_GETFL);
39112 + printk("fcntl F_GETFL failed, errno = %d\n", errno);
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",
39123 + if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){
39124 + printk("fcntl F_SETFL failed, errno = %d\n", errno);
39131 +int os_mode_fd(int fd, int mode)
39136 + err = fchmod(fd, mode);
39137 + } while((err < 0) && (errno==EINTR)) ;
39145 +int os_file_type(char *file)
39147 + struct uml_stat buf;
39150 + err = os_lstat_file(file, &buf);
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);
39163 +int os_file_mode(char *file, struct openflags *mode_out)
39167 + *mode_out = OPENFLAGS();
39169 + err = os_access(file, OS_ACC_W_OK);
39170 + if((err < 0) && (err != -EACCES))
39173 + *mode_out = of_write(*mode_out);
39175 + err = os_access(file, OS_ACC_R_OK);
39176 + if((err < 0) && (err != -EACCES))
39179 + *mode_out = of_read(*mode_out);
39184 +int os_open_file(char *file, struct openflags flags, int mode)
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;
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;
39199 + fd = open64(file, f, mode);
39203 + if(flags.cl && fcntl(fd, F_SETFD, 1)){
39204 + os_close_file(fd);
39211 +void *os_open_dir(char *path, int *err_out)
39215 + dir = opendir(path);
39216 + *err_out = -errno;
39220 +int os_seek_dir(void *stream, unsigned long long pos)
39222 + seekdir(stream, pos);
39226 +int os_read_dir(void *stream, unsigned long long *ino_out, char **name_out)
39228 + struct dirent *ent;
39231 + ent = readdir(stream);
39235 + *name_out = NULL;
39239 + *ino_out = ent->d_ino;
39240 + *name_out = ent->d_name;
39244 +int os_tell_dir(void *stream)
39246 + return(telldir(stream));
39249 +int os_close_dir(void *stream)
39253 + err = closedir(stream);
39259 +int os_remove_file(const char *file)
39263 + err = unlink(file);
39270 +int os_move_file(const char *from, const char *to)
39274 + err = rename(from, to);
39281 +int os_truncate_fd(int fd, unsigned long long len)
39285 + err = ftruncate64(fd, len);
39291 +int os_truncate_file(const char *file, unsigned long long len)
39295 + err = truncate64(file, len);
39301 +int os_connect_socket(char *name)
39303 + struct sockaddr_un sock;
39306 + sock.sun_family = AF_UNIX;
39307 + snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
39309 + fd = socket(AF_UNIX, SOCK_STREAM, 0);
39313 + err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
39320 +void os_close_file(int fd)
39325 +int os_seek_file(int fd, __u64 offset)
39329 + actual = lseek64(fd, offset, SEEK_SET);
39330 + if(actual != offset)
39335 +static int fault_buffer(void *start, int len,
39336 + int (*copy_proc)(void *addr, void *buf, int len))
39338 + int page = getpagesize(), i;
39341 + for(i = 0; i < len; i += page){
39342 + if((*copy_proc)(start + i, &c, sizeof(c)))
39345 + if((len % page) != 0){
39346 + if((*copy_proc)(start + len - 1, &c, sizeof(c)))
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))
39359 + n = (*io_proc)(fd, buf, len);
39360 + if((n < 0) && (errno == EFAULT)){
39361 + err = fault_buffer(buf, len, copy_user_proc);
39364 + n = (*io_proc)(fd, buf, len);
39366 + } while((n < 0) && (errno == EINTR));
39373 +int os_read_file(int fd, void *buf, int len)
39375 + return(file_io(fd, buf, len, (int (*)(int, void *, int)) read,
39376 + copy_from_user_proc));
39379 +int os_write_file(int fd, const void *buf, int len)
39381 + return(file_io(fd, (void *) buf, len,
39382 + (int (*)(int, void *, int)) write, copy_to_user_proc));
39385 +int os_file_size(char *file, long long *size_out)
39387 + struct uml_stat buf;
39390 + err = os_stat_file(file, &buf);
39392 + printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
39396 + if(S_ISBLK(buf.ust_mode)){
39399 + fd = os_open_file(file, of_read(OPENFLAGS()), 0);
39401 + printk("Couldn't open \"%s\", errno = %d\n", file, -fd);
39404 + if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
39405 + printk("Couldn't get the block size of \"%s\", "
39406 + "errno = %d\n", file, errno);
39408 + os_close_file(fd);
39411 + *size_out = ((long long) blocks) * 512;
39412 + os_close_file(fd);
39415 + *size_out = buf.ust_size;
39419 +int os_fd_size(int fd, long long *size_out)
39424 + err = fstat(fd, &buf);
39428 + *size_out = buf.st_size;
39432 +int os_file_modtime(char *file, unsigned long *modtime)
39434 + struct uml_stat buf;
39437 + err = os_stat_file(file, &buf);
39439 + printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
39443 + *modtime = buf.ust_mtime;
39447 +int os_get_exec_close(int fd, int* close_on_exec)
39452 + ret = fcntl(fd, F_GETFD);
39453 + } while((ret < 0) && (errno == EINTR)) ;
39458 + *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0;
39462 +int os_set_exec_close(int fd, int close_on_exec)
39466 + if(close_on_exec) flag = FD_CLOEXEC;
39470 + err = fcntl(fd, F_SETFD, flag);
39471 + } while((err < 0) && (errno == EINTR)) ;
39478 +int os_pipe(int *fds, int stream, int close_on_exec)
39480 + int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
39482 + err = socketpair(AF_UNIX, type, 0, fds);
39486 + if(!close_on_exec)
39489 + err = os_set_exec_close(fds[0], 1);
39493 + err = os_set_exec_close(fds[1], 1);
39500 + printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
39501 + os_close_file(fds[1]);
39502 + os_close_file(fds[0]);
39506 +int os_set_fd_async(int fd, int owner)
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);
39515 + if(fcntl(fd, F_SETFD, 1) < 0){
39516 + printk("os_set_fd_async : Setting FD_CLOEXEC failed, "
39517 + "errno = %d\n", errno);
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,
39532 +int os_clear_fd_async(int fd)
39534 + int flags = fcntl(fd, F_GETFL);
39536 + flags &= ~(O_ASYNC | O_NONBLOCK);
39537 + if(fcntl(fd, F_SETFL, flags) < 0)
39542 +int os_set_fd_block(int fd, int blocking)
39546 + flags = fcntl(fd, F_GETFL);
39548 + if(blocking) flags &= ~O_NONBLOCK;
39549 + else flags |= O_NONBLOCK;
39551 + if(fcntl(fd, F_SETFL, flags) < 0){
39552 + printk("Failed to change blocking on fd # %d, errno = %d\n",
39559 +int os_accept_connection(int fd)
39563 + new = accept(fd, NULL, 0);
39578 +#define SHUT_RDWR 2
39581 +int os_shutdown_socket(int fd, int r, int w)
39585 + if(r && w) what = SHUT_RDWR;
39586 + else if(r) what = SHUT_RD;
39587 + else if(w) what = SHUT_WR;
39589 + printk("os_shutdown_socket : neither r or w was set\n");
39592 + err = shutdown(fd, what);
39598 +int os_rcv_fd(int fd, int *helper_pid_out)
39601 + char buf[CMSG_SPACE(sizeof(new))];
39602 + struct msghdr msg;
39603 + struct cmsghdr *cmsg;
39604 + struct iovec iov;
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;
39616 + n = recvmsg(fd, &msg, 0);
39620 + else if(n != sizeof(iov.iov_len))
39621 + *helper_pid_out = -1;
39623 + cmsg = CMSG_FIRSTHDR(&msg);
39624 + if(cmsg == NULL){
39625 + printk("rcv_fd didn't receive anything, error = %d\n", errno);
39628 + if((cmsg->cmsg_level != SOL_SOCKET) ||
39629 + (cmsg->cmsg_type != SCM_RIGHTS)){
39630 + printk("rcv_fd didn't receive a descriptor\n");
39634 + new = ((int *) CMSG_DATA(cmsg))[0];
39638 +int os_create_unix_socket(char *file, int len, int close_on_exec)
39640 + struct sockaddr_un addr;
39643 + sock = socket(PF_UNIX, SOCK_DGRAM, 0);
39645 + printk("create_unix_socket - socket failed, errno = %d\n",
39650 + if(close_on_exec) {
39651 + err = os_set_exec_close(sock, 1);
39653 + printk("create_unix_socket : close_on_exec failed, "
39654 + "err = %d", -err);
39657 + addr.sun_family = AF_UNIX;
39659 + /* XXX Be more careful about overflow */
39660 + snprintf(addr.sun_path, len, "%s", file);
39662 + err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
39664 + printk("create_listening_socket at '%s' - bind failed, "
39665 + "errno = %d\n", file, errno);
39672 +int os_make_symlink(const char *to, const char *from)
39676 + err = symlink(to, from);
39683 +int os_read_symlink(const char *file, char *buf, int size)
39687 + err = readlink(file, buf, size);
39694 +int os_link_file(const char *to, const char *from)
39698 + err = link(to, from);
39705 +int os_make_dir(const char *dir, int mode)
39709 + err = mkdir(dir, mode);
39716 +int os_make_dev(const char *name, int mode, int major, int minor)
39720 + err = mknod(name, mode, MKDEV(major, minor));
39727 +int os_remove_dir(const char *dir)
39731 + err = rmdir(dir);
39738 +void os_flush_stdout(void)
39743 +int os_lock_file(int fd, int excl)
39745 + int type = excl ? F_WRLCK : F_RDLCK;
39746 + struct flock lock = ((struct flock) { .l_type = type,
39747 + .l_whence = SEEK_SET,
39752 + err = fcntl(fd, F_SETLK, &lock);
39757 + err = fcntl(fd, F_GETLK, &lock);
39763 + printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
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,
39775 + struct statfs64 buf;
39778 + err = statfs64(path, &buf);
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];
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
39806 + * ---------------------------------------------------------------------------
39807 + * Local variables:
39808 + * c-file-style: "linux"
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
39817 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39818 + * Licensed under the GPL
39821 +#ifndef __OS_FILE_H__
39822 +#define __OS_FILE_H__
39824 +#define DEV_NULL "/dev/null"
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
39833 + * ---------------------------------------------------------------------------
39834 + * Local variables:
39835 + * c-file-style: "linux"
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
39844 +# Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com)
39845 +# Licensed under the GPL
39848 +O_TARGET = built-in.o
39850 +obj-y = aio.o file.o process.o time.o tty.o
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)
39858 +include $(TOPDIR)/Rules.make
39860 +$(obj-y) : %.o: %.c
39861 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
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
39872 + * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
39873 + * Licensed under the GPL
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>
39884 +#include "user_util.h"
39886 +#define ARBITRARY_ADDR -1
39887 +#define FAILURE_PID -1
39889 +#define STAT_PATH_LEN sizeof("/proc/#######/stat\0")
39890 +#define COMM_SCANF "%*[^)])"
39892 +unsigned long os_process_pc(int pid)
39894 + char proc_stat[STAT_PATH_LEN], buf[256];
39895 + unsigned long pc;
39898 + sprintf(proc_stat, "/proc/%d/stat", pid);
39899 + fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
39901 + printk("os_process_pc - couldn't open '%s', err = %d\n",
39903 + return(ARBITRARY_ADDR);
39905 + err = os_read_file(fd, buf, sizeof(buf));
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);
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);
39922 +int os_process_parent(int pid)
39924 + char stat[STAT_PATH_LEN];
39926 + int parent, n, fd;
39928 + if(pid == -1) return(-1);
39930 + snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
39931 + fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
39933 + printk("Couldn't open '%s', err = %d\n", stat, -fd);
39934 + return(FAILURE_PID);
39937 + n = os_read_file(fd, data, sizeof(data));
39938 + os_close_file(fd);
39941 + printk("Couldn't read '%s', err = %d\n", stat, -n);
39942 + return(FAILURE_PID);
39945 + parent = FAILURE_PID;
39946 + n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent);
39948 + printk("Failed to scan '%s'\n", data);
39953 +void os_stop_process(int pid)
39955 + kill(pid, SIGSTOP);
39958 +void os_kill_process(int pid, int reap_child)
39960 + kill(pid, SIGKILL);
39962 + CATCH_EINTR(waitpid(pid, NULL, 0));
39966 +void os_usr1_process(int pid)
39968 + kill(pid, SIGUSR1);
39971 +int os_getpid(void)
39973 + return(getpid());
39976 +int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
39977 + int r, int w, int x)
39982 + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
39983 + (x ? PROT_EXEC : 0);
39985 + loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
39987 + if(loc == MAP_FAILED)
39992 +int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
39994 + int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
39995 + (x ? PROT_EXEC : 0));
39997 + if(mprotect(addr, len, prot) < 0)
40002 +int os_unmap_memory(void *addr, int len)
40006 + err = munmap(addr, len);
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
40017 + * ---------------------------------------------------------------------------
40018 + * Local variables:
40019 + * c-file-style: "linux"
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
40027 +#include <stdlib.h>
40028 +#include <sys/time.h>
40030 +unsigned long long os_usecs(void)
40032 + struct timeval tv;
40034 + gettimeofday(&tv, NULL);
40035 + return((unsigned long long) tv.tv_sec * 1000000 + tv.tv_usec);
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
40043 + * ---------------------------------------------------------------------------
40044 + * Local variables:
40045 + * c-file-style: "linux"
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
40054 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40055 + * Licensed under the GPL
40058 +#include <stdlib.h>
40059 +#include <errno.h>
40062 +#include "kern_util.h"
40064 +struct grantpt_info {
40070 +static void grantpt_cb(void *arg)
40072 + struct grantpt_info *info = arg;
40074 + info->res = grantpt(info->fd);
40075 + info->err = errno;
40080 + struct grantpt_info info;
40083 + fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0);
40085 + printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd);
40090 + initial_thread_cb(grantpt_cb, &info);
40092 + if(info.res < 0){
40093 + printk("get_pty : Couldn't grant pty - errno = %d\n",
40097 + if(unlockpt(fd) < 0){
40098 + printk("get_pty : Couldn't unlock pty - errno = %d\n", errno);
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
40109 + * ---------------------------------------------------------------------------
40110 + * Local variables:
40111 + * c-file-style: "linux"
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
40120 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40121 + * Licensed under the GPL
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"
40131 +#include "sysdep/ptrace.h"
40135 +#define MAXTOKEN 64
40137 +/* Set during early boot */
40138 +int host_has_cmov = 1;
40139 +int host_has_xmm = 0;
40141 +static char token(int fd, char *buf, int len, char stop)
40144 + char *ptr, *end, c;
40149 + n = os_read_file(fd, ptr, sizeof(*ptr));
40151 + if(n != sizeof(*ptr)){
40152 + if(n == 0) return(0);
40153 + printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
40159 + } while((c != '\n') && (c != stop) && (ptr < end));
40162 + printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
40165 + *(ptr - 1) = '\0';
40169 +static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
40174 + scratch[len - 1] = '\0';
40176 + c = token(fd, scratch, len - 1, ':');
40179 + else if(c != ':'){
40180 + printk("Failed to find ':' in /proc/cpuinfo\n");
40184 + if(!strncmp(scratch, key, strlen(key)))
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);
40194 + } while(c != '\n');
40199 +int cpu_feature(char *what, char *buf, int len)
40203 + fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
40205 + printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
40209 + if(!find_cpuinfo_line(fd, what, buf, len)){
40210 + printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
40214 + token(fd, buf, len, '\n');
40218 + os_close_file(fd);
40222 +static int check_cpu_flag(char *feature, int *have_it)
40224 + char buf[MAXTOKEN], c;
40225 + int fd, len = sizeof(buf)/sizeof(buf[0]);
40227 + printk("Checking for host processor %s support...", feature);
40228 + fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
40230 + printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
40235 + if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0])))
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");
40246 + c = token(fd, buf, len - 1, ' ');
40247 + if(c < 0) goto out;
40248 + else if(c == '\n') break;
40250 + if(!strcmp(buf, feature)){
40256 + if(*have_it == 0) printk("No\n");
40257 + else if(*have_it == 1) printk("Yes\n");
40258 + os_close_file(fd);
40262 +#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems
40263 + * for some people.
40265 +static void disable_lcall(void)
40267 + struct modify_ldt_ldt_s ldt;
40270 + bzero(&ldt, sizeof(ldt));
40271 + ldt.entry_number = 7;
40272 + ldt.base_addr = 0;
40274 + err = modify_ldt(1, &ldt, sizeof(ldt));
40276 + printk("Failed to disable lcall7 - errno = %d\n", errno);
40280 +void arch_init_thread(void)
40287 +void arch_check_bugs(void)
40291 + if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){
40292 + printk("/proc/cpuinfo not available - skipping CPU capability "
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;
40302 +int arch_handle_signal(int sig, union uml_pt_regs *regs)
40304 + unsigned char tmp[2];
40306 + /* This is testing for a cmov (0x0f 0x4x) instruction causing a
40307 + * SIGILL in init.
40309 + if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0);
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))
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 "
40320 + else if(host_has_cmov == 1)
40321 + panic("SIGILL caused by cmov, which this processor claims to "
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 "
40327 + else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
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
40336 + * ---------------------------------------------------------------------------
40337 + * Local variables:
40338 + * c-file-style: "linux"
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
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.
40351 + * IP/TCP/UDP checksumming routines
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.
40362 + * Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception
40364 + * Andi Kleen, add zeroing on error
40365 + * converted to pure assembler
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.
40373 +#include <linux/config.h>
40374 +#include <asm/errno.h>
40377 + * computes a partial checksum, e.g. for TCP/UDP fragments
40381 +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
40386 +.globl arch_csum_partial
40388 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
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.
40397 +arch_csum_partial:
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.
40409 +1: movw (%esi), %bx
40418 +1: movl (%esi), %ebx
40420 + movl 4(%esi), %ebx
40422 + movl 8(%esi), %ebx
40424 + movl 12(%esi), %ebx
40426 + movl 16(%esi), %ebx
40428 + movl 20(%esi), %ebx
40430 + movl 24(%esi), %ebx
40432 + movl 28(%esi), %ebx
40434 + lea 32(%esi), %esi
40438 +2: movl %edx, %ecx
40441 + shrl $2, %edx # This clears CF
40442 +3: adcl (%esi), %eax
40443 + lea 4(%esi), %esi
40452 + leal 2(%esi),%esi
40455 +5: movb (%esi),%cl
40465 +/* Version for PentiumII/PPro */
40467 +arch_csum_partial:
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
40484 + lea 45f(%ebx,%ebx,2), %ebx
40488 + # Handle 2-byte-aligned regions
40489 +20: addw (%esi), %ax
40490 + lea 2(%esi), %esi
40497 + movzbl (%esi),%ebx # csumming 1 byte, 2-aligned
40502 + addw (%esi), %ax # csumming 2 bytes, 2-aligned
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
40540 + lea 128(%esi), %esi
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
40553 + andl -128(%esi),%ebx # esi is 4-aligned so should be ok
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)
40569 + * Copy from ds while checksumming, otherwise like csum_partial
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.
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.
40579 +#define SRC(y...) \
40581 + .section __ex_table, "a"; \
40582 + .long 9999b, 6001f ; \
40585 +#define DST(y...) \
40587 + .section __ex_table, "a"; \
40588 + .long 9999b, 6002f ; \
40592 +.globl csum_partial_copy_generic_i386
40594 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
40596 +#define ARGBASE 16
40599 +csum_partial_copy_generic_i386:
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
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.
40615 +SRC(1: movw (%esi), %bx )
40617 +DST( movw %bx, (%edi) )
40622 + movl %ecx, FP(%esp)
40626 +SRC(1: movl (%esi), %ebx )
40627 +SRC( movl 4(%esi), %edx )
40629 +DST( movl %ebx, (%edi) )
40631 +DST( movl %edx, 4(%edi) )
40633 +SRC( movl 8(%esi), %ebx )
40634 +SRC( movl 12(%esi), %edx )
40636 +DST( movl %ebx, 8(%edi) )
40638 +DST( movl %edx, 12(%edi) )
40640 +SRC( movl 16(%esi), %ebx )
40641 +SRC( movl 20(%esi), %edx )
40643 +DST( movl %ebx, 16(%edi) )
40645 +DST( movl %edx, 20(%edi) )
40647 +SRC( movl 24(%esi), %ebx )
40648 +SRC( movl 28(%esi), %edx )
40650 +DST( movl %ebx, 24(%edi) )
40652 +DST( movl %edx, 28(%edi) )
40654 + lea 32(%esi), %esi
40655 + lea 32(%edi), %edi
40659 +2: movl FP(%esp), %edx
40663 + shrl $2, %edx # This clears CF
40664 +SRC(3: movl (%esi), %ebx )
40666 +DST( movl %ebx, (%edi) )
40667 + lea 4(%esi), %esi
40668 + lea 4(%edi), %edi
40676 +SRC( movw (%esi), %cx )
40677 + leal 2(%esi), %esi
40678 +DST( movw %cx, (%edi) )
40679 + leal 2(%edi), %edi
40682 +SRC(5: movb (%esi), %cl )
40683 +DST( movb %cl, (%edi) )
40684 +6: addl %ecx, %eax
40689 +# Exception handler:
40690 +.section .fixup, "ax"
40693 + movl ARGBASE+20(%esp), %ebx # src_err_ptr
40694 + movl $-EFAULT, (%ebx)
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
40706 + movl ARGBASE+24(%esp), %ebx # dst_err_ptr
40707 + movl $-EFAULT,(%ebx)
40715 + popl %ecx # equivalent to addl $4,%esp
40720 +/* Version for PentiumII/PPro */
40722 +#define ROUND1(x) \
40723 + SRC(movl x(%esi), %ebx ) ; \
40724 + addl %ebx, %eax ; \
40725 + DST(movl %ebx, x(%edi) ) ;
40727 +#define ROUND(x) \
40728 + SRC(movl x(%esi), %ebx ) ; \
40729 + adcl %ebx, %eax ; \
40730 + DST(movl %ebx, x(%edi) ) ;
40732 +#define ARGBASE 12
40734 +csum_partial_copy_generic_i386:
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
40750 + lea -1(%esi),%edx
40752 + lea 3f(%ebx,%ebx), %ebx
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)
40766 +4: movl ARGBASE+12(%esp),%edx #len
40771 +SRC( movw (%esi), %dx )
40772 + leal 2(%esi), %esi
40773 +DST( movw %dx, (%edi) )
40774 + leal 2(%edi), %edi
40778 +SRC( movb (%esi), %dl )
40779 +DST( movb %dl, (%edi) )
40780 +6: addl %edx, %eax
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
40792 +6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
40793 + movl $-EFAULT, (%ebx)
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
40812 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40813 + * Licensed under the GPL
40816 +#include <signal.h>
40817 +#include "sysdep/ptrace.h"
40818 +#include "sysdep/sigcontext.h"
40820 +extern unsigned long search_exception_table(unsigned long addr);
40822 +int arch_fixup(unsigned long address, void *sc_ptr)
40824 + struct sigcontext *sc = sc_ptr;
40825 + unsigned long fixup;
40827 + fixup = search_exception_table(address);
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
40840 + * ---------------------------------------------------------------------------
40841 + * Local variables:
40842 + * c-file-style: "linux"
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
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"
40859 +EXPORT_SYMBOL(__down_failed);
40860 +EXPORT_SYMBOL(__down_failed_interruptible);
40861 +EXPORT_SYMBOL(__down_failed_trylock);
40862 +EXPORT_SYMBOL(__up_wakeup);
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
40873 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
40874 + * Licensed under the GPL
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"
40884 +#ifdef CONFIG_MODE_TT
40885 +extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
40887 +/* XXX this needs copy_to_user and copy_from_user */
40889 +int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
40891 + if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT);
40892 + return(modify_ldt(func, ptr, bytecount));
40896 +#ifdef CONFIG_MODE_SKAS
40897 +extern int userspace_pid;
40899 +int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
40901 + struct ptrace_ldt ldt;
40905 + buf = kmalloc(bytecount, GFP_KERNEL);
40914 + res = copy_from_user(buf, ptr, bytecount);
40923 + ldt = ((struct ptrace_ldt) { .func = func,
40925 + .bytecount = bytecount });
40926 + res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt);
40934 + res = copy_to_user(ptr, buf, n);
40948 +int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
40950 + return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
40951 + ptr, bytecount));
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
40961 + * ---------------------------------------------------------------------------
40962 + * Local variables:
40963 + * c-file-style: "linux"
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
40972 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40973 +# Licensed under the GPL
40976 +O_TARGET = built-in.o
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
40982 +USER_OBJS = bugs.o ptrace_user.o sigcontext.o fault.o
40984 +SYMLINKS = semaphore.c extable.c
40986 +semaphore.c-dir = kernel
40987 +extable.c-dir = mm
40989 +include $(TOPDIR)/Rules.make
40991 +$(USER_OBJS) : %.o: %.c
40992 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
40996 + ln -sf $(TOPDIR)/arch/i386/$($1-dir)/$1 $1
41000 + $(call make_link,$@)
41003 + $(MAKE) -C util clean
41004 + rm -f $(SYMLINKS)
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
41023 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
41024 + * Licensed under the GPL
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"
41036 +void arch_switch(void)
41038 + update_debugregs(current->thread.arch.debugregs_seq);
41041 +int is_syscall(unsigned long addr)
41043 + unsigned short instr;
41046 + n = copy_from_user(&instr, (void *) addr, sizeof(instr));
41048 + printk("is_syscall : failed to read instruction from 0x%lx\n",
41052 + /* int 0x80 or sysenter */
41053 + return((instr == 0x80cd) || (instr == 0x340f));
41056 +/* determines which flags the user has access to. */
41057 +/* 1 = access 0 = no access */
41058 +#define FLAG_MASK 0x00044dd5
41060 +int putreg(struct task_struct *child, int regno, unsigned long value)
41065 + if (value && (value & 3) != 3)
41067 + PT_REGS_FS(&child->thread.regs) = value;
41070 + if (value && (value & 3) != 3)
41072 + PT_REGS_GS(&child->thread.regs) = value;
41076 + if (value && (value & 3) != 3)
41082 + if ((value & 3) != 3)
41087 + value &= FLAG_MASK;
41088 + value |= PT_REGS_EFLAGS(&child->thread.regs);
41091 + PT_REGS_SET(&child->thread.regs, regno, value);
41095 +unsigned long getreg(struct task_struct *child, int regno)
41097 + unsigned long retval = ~0UL;
41108 + /* fall through */
41110 + retval &= PT_REG(&child->thread.regs, regno);
41115 +struct i387_fxsave_struct {
41116 + unsigned short cwd;
41117 + unsigned short swd;
41118 + unsigned short twd;
41119 + unsigned short fop;
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];
41132 + * FPU tag word conversions.
41135 +static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
41137 + unsigned int tmp; /* to avoid 16 bit prefixes in the code */
41139 + /* Transform each pair of bits into 01 (valid) or 00 (empty) */
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 */
41149 +static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
41151 + struct _fpxreg *st = NULL;
41152 + unsigned long twd = (unsigned long) fxsave->twd;
41153 + unsigned long tag;
41154 + unsigned long ret = 0xffff0000;
41157 +#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
41159 + for ( i = 0 ; i < 8 ; i++ ) {
41160 + if ( twd & 0x1 ) {
41161 + st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
41163 + switch ( st->exponent & 0x7fff ) {
41165 + tag = 2; /* Special */
41168 + if ( !st->significand[0] &&
41169 + !st->significand[1] &&
41170 + !st->significand[2] &&
41171 + !st->significand[3] ) {
41172 + tag = 1; /* Zero */
41174 + tag = 2; /* Special */
41178 + if ( st->significand[3] & 0x8000 ) {
41179 + tag = 0; /* Valid */
41181 + tag = 2; /* Special */
41186 + tag = 3; /* Empty */
41188 + ret |= (tag << (2 * i));
41195 + * FXSR floating point environment conversions.
41198 +#ifdef CONFIG_MODE_TT
41199 +static inline int convert_fxsr_to_user_tt(struct _fpstate *buf,
41200 + struct pt_regs *regs)
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;
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;
41216 + if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
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) ) )
41229 +static inline int convert_fxsr_to_user(struct _fpstate *buf,
41230 + struct pt_regs *regs)
41232 + return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0));
41235 +#ifdef CONFIG_MODE_TT
41236 +static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
41237 + struct _fpstate *buf)
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;
41245 + if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
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];
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) ) )
41267 +static inline int convert_fxsr_from_user(struct pt_regs *regs,
41268 + struct _fpstate *buf)
41270 + return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0));
41273 +int get_fpregs(unsigned long buf, struct task_struct *child)
41277 + err = convert_fxsr_to_user((struct _fpstate *) buf,
41278 + &child->thread.regs);
41279 + if(err) return(-EFAULT);
41283 +int set_fpregs(unsigned long buf, struct task_struct *child)
41287 + err = convert_fxsr_from_user(&child->thread.regs,
41288 + (struct _fpstate *) buf);
41289 + if(err) return(-EFAULT);
41293 +#ifdef CONFIG_MODE_TT
41294 +int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
41296 + struct pt_regs *regs = &tsk->thread.regs;
41297 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
41300 + err = __copy_to_user((void *) buf, fxsave,
41301 + sizeof(struct user_fxsr_struct));
41302 + if(err) return -EFAULT;
41307 +int get_fpxregs(unsigned long buf, struct task_struct *tsk)
41309 + return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0));
41312 +#ifdef CONFIG_MODE_TT
41313 +int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
41315 + struct pt_regs *regs = &tsk->thread.regs;
41316 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
41319 + err = __copy_from_user(fxsave, (void *) buf,
41320 + sizeof(struct user_fxsr_struct) );
41321 + if(err) return -EFAULT;
41326 +int set_fpxregs(unsigned long buf, struct task_struct *tsk)
41328 + return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0));
41332 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
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));
41342 + memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)),
41343 + sizeof(fpu->st_space));
41348 +#ifdef CONFIG_MODE_TT
41349 +static inline void copy_fpu_fxsave_tt(struct pt_regs *regs,
41350 + struct user_i387_struct *buf)
41352 + struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs));
41353 + unsigned short *to;
41354 + unsigned short *from;
41357 + memcpy( buf, fpu, 7 * sizeof(long) );
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) );
41367 +static inline void copy_fpu_fxsave(struct pt_regs *regs,
41368 + struct user_i387_struct *buf)
41370 + (void) CHOOSE_MODE(copy_fpu_fxsave_tt(regs, buf), 0);
41373 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
41375 + copy_fpu_fxsave(regs, (struct user_i387_struct *) fpu);
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
41384 + * ---------------------------------------------------------------------------
41385 + * Local variables:
41386 + * c-file-style: "linux"
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
41395 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
41396 + * Licensed under the GPL
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"
41411 +int ptrace_getregs(long pid, unsigned long *regs_out)
41413 + return(ptrace(PTRACE_GETREGS, pid, 0, regs_out));
41416 +int ptrace_setregs(long pid, unsigned long *regs)
41418 + return(ptrace(PTRACE_SETREGS, pid, 0, regs));
41421 +int ptrace_getfpregs(long pid, unsigned long *regs)
41423 + return(ptrace(PTRACE_GETFPREGS, pid, 0, regs));
41426 +static void write_debugregs(int pid, unsigned long *regs)
41428 + struct user *dummy;
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],
41437 + printk("write_debugregs - ptrace failed on "
41438 + "register %d, value = 0x%x, errno = %d\n", i,
41443 +static void read_debugregs(int pid, unsigned long *regs)
41445 + struct user *dummy;
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);
41456 +/* Accessed only by the tracing thread */
41457 +static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
41458 +static int debugregs_seq = 0;
41460 +void arch_enter_kernel(void *task, int pid)
41462 + read_debugregs(pid, TASK_DEBUGREGS(task));
41463 + write_debugregs(pid, kernel_debugregs);
41466 +void arch_leave_kernel(void *task, int pid)
41468 + read_debugregs(pid, kernel_debugregs);
41469 + write_debugregs(pid, TASK_DEBUGREGS(task));
41472 +void ptrace_pokeuser(unsigned long addr, unsigned long data)
41474 + if((addr < offsetof(struct user, u_debugreg[0])) ||
41475 + (addr > offsetof(struct user, u_debugreg[7])))
41477 + addr -= offsetof(struct user, u_debugreg[0]);
41478 + addr = addr >> 2;
41479 + if(kernel_debugregs[addr] == data) return;
41481 + kernel_debugregs[addr] = data;
41485 +static void update_debugregs_cb(void *arg)
41487 + int pid = *((int *) arg);
41489 + write_debugregs(pid, kernel_debugregs);
41492 +void update_debugregs(int seq)
41496 + if(seq == debugregs_seq) return;
41498 + me = os_getpid();
41499 + initial_thread_cb(update_debugregs_cb, &me);
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
41507 + * ---------------------------------------------------------------------------
41508 + * Local variables:
41509 + * c-file-style: "linux"
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
41518 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
41519 + * Licensed under the GPL
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"
41530 +int sc_size(void *data)
41532 + struct arch_frame_data *arch = data;
41534 + return(sizeof(struct sigcontext) + arch->fpstate_size);
41537 +void sc_to_sc(void *to_ptr, void *from_ptr)
41539 + struct sigcontext *to = to_ptr, *from = from_ptr;
41540 + int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size;
41542 + memcpy(to, from, size);
41543 + if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1);
41546 +unsigned long *sc_sigmask(void *sc_ptr)
41548 + struct sigcontext *sc = sc_ptr;
41550 + return(&sc->oldmask);
41553 +int sc_get_fpregs(unsigned long buf, void *sc_ptr)
41555 + struct sigcontext *sc = sc_ptr;
41556 + struct _fpstate *from = sc->fpstate, *to = (struct _fpstate *) buf;
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));
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));
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
41592 + * ---------------------------------------------------------------------------
41593 + * Local variables:
41594 + * c-file-style: "linux"
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
41603 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
41604 + * Licensed under the GPL
41607 +#include "asm/mman.h"
41608 +#include "asm/uaccess.h"
41609 +#include "asm/unistd.h"
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..
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;
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);
41631 +int old_mmap_i386(struct mmap_arg_struct *arg)
41633 + struct mmap_arg_struct a;
41634 + int err = -EFAULT;
41636 + if (copy_from_user(&a, arg, sizeof(a)))
41639 + err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
41644 +struct sel_arg_struct {
41646 + fd_set *inp, *outp, *exp;
41647 + struct timeval *tvp;
41650 +int old_select(struct sel_arg_struct *arg)
41652 + struct sel_arg_struct a;
41654 + if (copy_from_user(&a, arg, sizeof(a)))
41656 + /* sys_select() does the appropriate kernel locking */
41657 + return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
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
41665 + * ---------------------------------------------------------------------------
41666 + * Local variables:
41667 + * c-file-style: "linux"
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
41675 +#include "linux/kernel.h"
41676 +#include "linux/smp.h"
41677 +#include "linux/sched.h"
41678 +#include "asm/ptrace.h"
41679 +#include "sysrq.h"
41681 +void show_regs(struct pt_regs *regs)
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));
41703 + show_trace((unsigned long *) ®s);
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
41710 +EXE = mk_sc mk_thread
41712 +include $(TOPDIR)/Rules.make
41717 + $(HOSTCC) -o mk_sc mk_sc.o
41722 +mk_thread : mk_thread_user.o mk_thread_kern.o
41723 + $(HOSTCC) -o mk_thread mk_thread_user.o mk_thread_kern.o
41725 +mk_thread_user.o : mk_thread_user.c
41728 +mk_thread_kern.o : mk_thread_kern.c
41729 + $(HOSTCC) $(CFLAGS) -c $<
41734 +archmrproper : clean
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
41743 +#include <stdio.h>
41744 +#include <signal.h>
41745 +#include <linux/stddef.h>
41747 +#define SC_OFFSET(name, field) \
41748 + printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
41749 + offsetof(struct sigcontext, field))
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))
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))
41761 +int main(int argc, char **argv)
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");
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
41800 +#include "linux/config.h"
41801 +#include "linux/stddef.h"
41802 +#include "linux/sched.h"
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);
41809 +#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
41811 +int main(int argc, char **argv)
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));
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
41827 +#include <stdio.h>
41829 +void print_head(void)
41832 + printf(" * Generated by mk_thread\n");
41835 + printf("#ifndef __UM_THREAD_H\n");
41836 + printf("#define __UM_THREAD_H\n");
41840 +void print_constant_ptr(char *name, int value)
41842 + printf("#define %s(task) ((unsigned long *) "
41843 + "&(((char *) (task))[%d]))\n", name, value);
41846 +void print_constant(char *name, char *type, int value)
41848 + printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
41852 +void print_tail(void)
41855 + printf("#endif\n");
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
41870 + $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
41880 + @$(MAKEBOOT) clean
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
41896 + $(CC) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
41898 +OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \
41899 + ptrace_user.o sysrq.o
41901 +EXTRA_AFLAGS := -DCONFIG_ALL_PPC -I. -I$(TOPDIR)/arch/ppc/kernel
41907 + $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
41909 +ptrace_user.o: ptrace_user.c
41910 + $(CC) -D__KERNEL__ $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
41912 +sigcontext.o: sigcontext.c
41913 + $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
41917 + ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
41921 + ln -s $(TOPDIR)/arch/ppc/lib/$@ $@
41925 + ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
41929 + ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
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
41946 +# the asm link is horrible, and breaks the other targets. This is also
41947 +# not going to work with parallel makes.
41949 +checksum.o: checksum.S
41951 + ln -s $(TOPDIR)/include/asm-ppc asm
41952 + $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
41955 +misc.o: misc.S ppc_defs.h
41957 + ln -s $(TOPDIR)/include/asm-ppc asm
41958 + $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
41964 + rm -f checksum.S semaphore.c mk_defs.c
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
41979 + * This file contains miscellaneous low-level functions.
41980 + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
41982 + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
41983 + * and Paul Mackerras.
41985 + * A couple of functions stolen from arch/ppc/kernel/misc.S for UML
41986 + * by Chris Emerson.
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.
41995 +#include <linux/config.h>
41996 +#include <asm/processor.h>
41997 +#include "ppc_asm.h"
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
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 */
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.
42020 +_GLOBAL(clear_page)
42021 + li r0,4096/CACHE_LINE_SIZE
42032 + addi r3,r3,CACHE_LINE_SIZE
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
42042 +#define COPY_16_BYTES \
42046 + lwzu r9,16(r4); \
42052 +_GLOBAL(copy_page)
42057 +#ifndef CONFIG_8xx
42058 +#if MAX_COPY_PREFETCH > 1
42059 + li r0,MAX_COPY_PREFETCH
42063 + addi r11,r11,CACHE_LINE_SIZE
42065 +#else /* MAX_COPY_PREFETCH == 1 */
42067 + li r11,CACHE_LINE_SIZE+4
42068 +#endif /* MAX_COPY_PREFETCH */
42069 +#endif /* CONFIG_8xx */
42071 + li r0,4096/CACHE_LINE_SIZE
42074 +#ifndef CONFIG_8xx
42079 +#if CACHE_LINE_SIZE >= 32
42081 +#if CACHE_LINE_SIZE >= 64
42084 +#if CACHE_LINE_SIZE >= 128
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
42099 +#include "linux/threads.h"
42100 +#include "linux/stddef.h" // for NULL
42101 +#include "linux/elf.h" // for AT_NULL
42103 +/* The following function nicked from arch/ppc/kernel/process.c and
42104 + * adapted slightly */
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. :-(
42110 +void shove_aux_table(unsigned long sp)
42115 + unsigned long aux_start, offset;
42117 + argc = *(int *)sp;
42118 + sp += sizeof(int) + (argc + 1) * sizeof(char *);
42119 + /* skip over the environment pointers */
42121 + p = *(char **)sp;
42122 + sp += sizeof(char *);
42123 + } while (p != NULL);
42125 + /* skip to the end of the auxiliary table */
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) {
42133 + sp -= sizeof(unsigned long);
42134 + e = *(unsigned long *)sp;
42135 + *(unsigned long *)(sp + offset) = e;
42136 + } while (sp > aux_start);
42139 +/* END stuff taken from arch/ppc/kernel/process.c */
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
42147 + * ---------------------------------------------------------------------------
42148 + * Local variables:
42149 + * c-file-style: "linux"
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
42157 +#include "linux/sched.h"
42158 +#include "asm/ptrace.h"
42160 +int putreg(struct task_struct *child, unsigned long regno,
42161 + unsigned long value)
42163 + child->thread.process_regs.regs[regno >> 2] = value;
42167 +unsigned long getreg(struct task_struct *child, unsigned long regno)
42169 + unsigned long retval = ~0UL;
42171 + retval &= child->thread.process_regs.regs[regno >> 2];
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
42180 + * ---------------------------------------------------------------------------
42181 + * Local variables:
42182 + * c-file-style: "linux"
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
42190 +#include <sys/ptrace.h>
42191 +#include <errno.h>
42192 +#include <asm/ptrace.h>
42193 +#include "sysdep/ptrace.h"
42195 +int ptrace_getregs(long pid, unsigned long *regs_out)
42198 + for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
42200 + regs_out->regs[i] = ptrace(PTRACE_PEEKUSER, pid, i*4, 0);
42208 +int ptrace_setregs(long pid, unsigned long *regs_in)
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) {
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
42225 + * ---------------------------------------------------------------------------
42226 + * Local variables:
42227 + * c-file-style: "linux"
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
42235 +#include "asm/ptrace.h"
42236 +#include "asm/sigcontext.h"
42237 +#include "sysdep/ptrace.h"
42238 +#include "user_util.h"
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
42245 + * ---------------------------------------------------------------------------
42246 + * Local variables:
42247 + * c-file-style: "linux"
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
42256 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
42257 + * Licensed under the GPL
42260 +#include "linux/kernel.h"
42261 +#include "linux/smp.h"
42262 +#include "asm/ptrace.h"
42263 +#include "sysrq.h"
42265 +void show_regs(struct pt_regs_subarch *regs)
42268 + printk("show_regs(): insert regs here.\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);
42284 + show_trace(®s->gpr[1]);
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
42293 + * ---------------------------------------------------------------------------
42294 + * Local variables:
42295 + * c-file-style: "linux"
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
42303 +ALL = mk_task mk_constants
42307 +mk_task : mk_task_user.o mk_task_kern.o
42308 + $(HOSTCC) -o mk_task mk_task_user.o mk_task_kern.o
42310 +mk_task_user.o : mk_task_user.c
42313 +mk_task_kern.o : mk_task_kern.c
42314 + $(HOSTCC) $(CFLAGS) -c $<
42316 +mk_constants : mk_constants_user.o mk_constants_kern.o
42317 + $(HOSTCC) -o mk_constants mk_constants_user.o mk_constants_kern.o
42319 +mk_constants_user.o : mk_constants_user.c
42322 +mk_constants_kern.o : mk_constants_kern.c
42323 + $(HOSTCC) $(CFLAGS) -c $<
42326 + $(RM) $(ALL) *.o *~
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
42334 +#include "linux/kernel.h"
42335 +#include "linux/stringify.h"
42336 +#include "asm/page.h"
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);
42343 +int main(int argc, char **argv)
42346 + print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
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);
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
42364 +#include <stdio.h>
42366 +void print_head(void)
42369 + printf(" * Generated by mk_constants\n");
42372 + printf("#ifndef __UM_CONSTANTS_H\n");
42373 + printf("#define __UM_CONSTANTS_H\n");
42377 +void print_constant_str(char *name, char *value)
42379 + printf("#define %s \"%s\"\n", name, value);
42382 +void print_constant_int(char *name, int value)
42384 + printf("#define %s %d\n", name, value);
42387 +void print_tail(void)
42390 + printf("#endif\n");
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
42397 +#include "linux/sched.h"
42398 +#include "linux/stddef.h"
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);
42405 +int main(int argc, char **argv)
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));
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
42419 +#include <stdio.h>
42421 +void print(char *name, char *type, int offset)
42423 + printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
42427 +void print_ptr(char *name, char *type, int offset)
42429 + printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
42433 +void print_head(void)
42436 + printf(" * Generated by mk_task\n");
42439 + printf("#ifndef __TASK_H\n");
42440 + printf("#define __TASK_H\n");
42444 +void print_tail(void)
42447 + printf("#endif\n");
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 @@
42455 W: http://lars.nocrew.org/
42456 D: dsp56k device driver
42457 +D: ptrace proxy in user mode kernel port
42461 @@ -727,7 +728,7 @@
42462 E: jdike@karaya.com
42463 W: http://user-mode-linux.sourceforge.net
42464 D: User mode kernel port
42466 +S: 375 Tubbs Hill Rd
42467 S: Deering NH 03244
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>.
42478 +Support for /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.
42485 + If you don't know what this does just say Y.
42487 +Separate Kernel Address Space support
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.
42496 +Tracing thread support
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.
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
42512 +2G/2G host address space split
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.
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.
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.
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
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 @@
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
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.
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 @@
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.
42569 @@ -16357,6 +16413,9 @@
42570 See <http://user-mode-linux.sourceforge.net/gprof.html> for more
42573 + This option requires that CONFIG_MODE_TT be disabled, as UML will
42574 + not build with both enabled.
42576 If you're involved in UML kernel development and want to use gprof,
42577 say Y. If you're unsure, say N.
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.
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.
42591 + See <http://user-mode-linux.sf.net/hppfs.html> for more information.
42593 + You only need this if you are setting up a UML honeypot. Otherwise,
42594 + it is safe to say 'N' here.
42596 Example IO Memory driver
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.
42603 +Anonymous Memory support
42605 + Don't ask. Just say Y.
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.
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.
42618 Virtual Serial Line
42620 The User-Mode Linux environment allows you to create virtual serial
42621 @@ -16505,26 +16592,197 @@
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.
42632 - To use this, your host must support Slip devices.
42633 + To use this, your host must support slip devices.
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.
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.
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).
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.
42674 + Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
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.
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.
42687 + If you intend to use UML as a network monitor for the host, say
42688 + Y here. Otherwise, say N.
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.
42698 +Default console channel initialization
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.
42708 +Default serial line channel initialization
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.
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.
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.
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.
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.
42756 +file descriptor channel support
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.
42764 +null device channel support
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.
42770 +port channel support
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.
42779 +pty channel support
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.
42788 +tty channel support
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.
42796 +xterm channel support
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
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.
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.
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.
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 @@
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 @@
42849 char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
42852 if (p < (unsigned long) high_memory) {
42854 if (count > (unsigned long) high_memory - p)
42855 @@ -292,6 +292,8 @@
42856 wrote = (unsigned long) high_memory - p;
42858 wrote = do_write_mem(file, (void*)p, p, buf, wrote, ppos);
42864 @@ -664,6 +666,8 @@
42868 +extern struct file_operations anon_file_operations;
42870 static int memory_open(struct inode * inode, struct file * filp)
42872 switch (MINOR(inode->i_rdev)) {
42873 @@ -693,6 +697,9 @@
42875 filp->f_op = &urandom_fops;
42878 + filp->f_op = &anon_file_operations;
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},
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
42898 * who actually finally proved there really was a race.
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
42904 + * waiting writing processes-Sapan Bhatia <sapan@corewars.org>
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>
42911 #include <linux/types.h>
42912 @@ -1393,9 +1395,9 @@
42913 if (O_OPOST(tty) && !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
42915 ssize_t num = opost_block(tty, b, nr);
42917 - if (num == -EAGAIN)
42920 + if(num == -EAGAIN)
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 @@
42933 +#ifdef CONFIG_TTY_LOG
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;
42939 +void register_tty_logger(int (*opener)(void *, void *),
42940 + int (*writer)(int, const char *, int, void *, int),
42941 + void (*closer)(int, void *))
42943 + open_log = opener;
42944 + write_log = writer;
42945 + close_log = closer;
42950 static ssize_t tty_read(struct file * file, char * buf, size_t count,
42953 @@ -1012,8 +1029,13 @@
42955 tty_ldisc_deref(ld);
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);
42968 @@ -1067,6 +1089,10 @@
42970 file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
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);
42977 up(&tty->atomic_write);
42979 @@ -1662,6 +1688,11 @@
42980 tty_set_termios_ldisc(o_tty,N_TTY);
42983 +#ifdef CONFIG_TTY_LOG
42984 + if((tty->log_fd >= 0) && (close_log != NULL))
42985 + (*close_log)(tty->log_fd, tty);
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 @@
42996 +#ifdef CONFIG_TTY_LOG
42997 + if((tty->log_fd < 0) && (open_log != NULL))
42998 + tty->log_fd = (*open_log)(tty, current->tty);
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;
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
43018 extern int lmc_setup(void);
43020 extern int madgemc_probe(void);
43021 -extern int uml_net_probe(void);
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},
43029 -#ifdef CONFIG_UML_NET
43030 - {uml_net_probe, 0},
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
43041 void make_bad_inode(struct inode * inode)
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
43052 #include <linux/config.h>
43053 #include <linux/threads.h>
43054 #include <linux/irq.h>
43055 +#include <asm/processor.h> /* for cpu_relax */
43057 /* assembly code in softirq.h is sensitive to the offsets of these fields */
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
43064 +#ifndef __UM_A_OUT_H
43065 +#define __UM_A_OUT_H
43067 +#include "linux/config.h"
43068 +#include "asm/arch/a.out.h"
43069 +#include "choose-mode.h"
43073 +extern unsigned long stacksizelim;
43075 +extern unsigned long host_task_size;
43077 +#define STACK_ROOM (stacksizelim)
43079 +extern int honeypot;
43080 +#define STACK_TOP \
43081 + CHOOSE_MODE((honeypot ? host_task_size : task_size), task_size)
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
43090 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
43091 + * Licensed under the GPL
43094 +#ifndef __UM_ARCHPARAM_I386_H
43095 +#define __UM_ARCHPARAM_I386_H
43097 +/********* Bits for asm-um/elf.h ************/
43101 +#define ELF_PLATFORM "i586"
43103 +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
43105 +typedef struct user_i387_struct elf_fpregset_t;
43106 +typedef unsigned long elf_greg_t;
43108 +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
43109 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
43111 +#define ELF_DATA ELFDATA2LSB
43112 +#define ELF_ARCH EM_386
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; \
43124 +/* Shamelessly stolen from include/asm-i386/elf.h */
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); \
43147 +/********* Bits for asm-um/delay.h **********/
43149 +typedef unsigned long um_udelay_t;
43151 +/********* Nothing for asm-um/hardirq.h **********/
43153 +/********* Nothing for asm-um/hw_irq.h **********/
43155 +/********* Nothing for asm-um/string.h **********/
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
43164 + * ---------------------------------------------------------------------------
43165 + * Local variables:
43166 + * c-file-style: "linux"
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
43174 +#ifndef __UM_ARCHPARAM_PPC_H
43175 +#define __UM_ARCHPARAM_PPC_H
43177 +/********* Bits for asm-um/elf.h ************/
43179 +#define ELF_PLATFORM (0)
43181 +#define ELF_ET_DYN_BASE (0x08000000)
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];
43190 +/* Floating point registers */
43191 +typedef double elf_fpreg_t;
43192 +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
43194 +#define ELF_DATA ELFDATA2MSB
43195 +#define ELF_ARCH EM_PPC
43197 +/********* Bits for asm-um/delay.h **********/
43199 +typedef unsigned int um_udelay_t;
43201 +/********* Bits for asm-um/hw_irq.h **********/
43203 +struct hw_interrupt_type;
43205 +/********* Bits for asm-um/hardirq.h **********/
43207 +#define irq_enter(cpu, irq) hardirq_enter(cpu)
43208 +#define irq_exit(cpu, irq) hardirq_exit(cpu)
43210 +/********* Bits for asm-um/string.h **********/
43212 +#define __HAVE_ARCH_STRRCHR
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
43221 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
43222 + * Licensed under the GPL
43225 +#ifndef __UM_ARCH_SIGNAL_I386_H
43226 +#define __UM_ARCH_SIGNAL_I386_H
43228 +struct arch_signal_context {
43229 + unsigned long extrasigs[_NSIG_WORDS];
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
43239 + * ---------------------------------------------------------------------------
43240 + * Local variables:
43241 + * c-file-style: "linux"
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
43249 +#ifndef __UM_ATOMIC_H
43250 +#define __UM_ATOMIC_H
43252 +#include "asm/arch/atomic.h"
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
43260 +#ifndef __UM_BITOPS_H
43261 +#define __UM_BITOPS_H
43263 +#include "asm/arch/bitops.h"
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
43271 +#ifndef __UM_BOOT_H
43272 +#define __UM_BOOT_H
43274 +#include "asm/arch/boot.h"
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
43282 +#ifndef __UM_BUGS_H
43283 +#define __UM_BUGS_H
43285 +void check_bugs(void);
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
43293 +#ifndef __UM_BYTEORDER_H
43294 +#define __UM_BYTEORDER_H
43296 +#include "asm/arch/byteorder.h"
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
43304 +#ifndef __UM_CACHE_H
43305 +#define __UM_CACHE_H
43307 +#define L1_CACHE_BYTES 32
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
43315 +#ifndef __UM_CHECKSUM_H
43316 +#define __UM_CHECKSUM_H
43318 +#include "sysdep/checksum.h"
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
43326 +#ifndef __UM_COBALT_H
43327 +#define __UM_COBALT_H
43329 +#include "asm/arch/cobalt.h"
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
43338 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
43339 + * Licensed under the GPL
43342 +#ifndef __UM_CURRENT_H
43343 +#define __UM_CURRENT_H
43345 +#ifndef __ASSEMBLY__
43347 +#include "linux/config.h"
43348 +#include "asm/page.h"
43350 +struct task_struct;
43352 +#define CURRENT_TASK(dummy) (((unsigned long) &dummy) & \
43353 + (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
43355 +#define current ({ int dummy; (struct task_struct *) CURRENT_TASK(dummy); })
43357 +#endif /* __ASSEMBLY__ */
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
43366 + * ---------------------------------------------------------------------------
43367 + * Local variables:
43368 + * c-file-style: "linux"
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
43376 +#ifndef __UM_DELAY_H
43377 +#define __UM_DELAY_H
43379 +#include "asm/arch/delay.h"
43380 +#include "asm/archparam.h"
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
43388 +#ifndef __UM_DESC_H
43389 +#define __UM_DESC_H
43391 +#include "asm/arch/desc.h"
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
43399 +#ifndef _UM_DIV64_H
43400 +#define _UM_DIV64_H
43402 +#include "asm/arch/div64.h"
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
43410 +#ifndef __UM_DMA_H
43411 +#define __UM_DMA_H
43413 +#include "asm/io.h"
43415 +extern unsigned long uml_physmem;
43417 +#define MAX_DMA_ADDRESS (uml_physmem)
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
43425 +#ifndef __UM_ELF_H
43426 +#define __UM_ELF_H
43428 +#include "asm/archparam.h"
43430 +#define ELF_HWCAP (0)
43432 +#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
43434 +#define ELF_EXEC_PAGESIZE 4096
43436 +#define elf_check_arch(x) (1)
43438 +#define ELF_CLASS ELFCLASS32
43440 +#define USE_ELF_CORE_DUMP
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
43448 +#ifndef __UM_ERRNO_H
43449 +#define __UM_ERRNO_H
43451 +#include "asm/arch/errno.h"
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
43459 +#ifndef __UM_FCNTL_H
43460 +#define __UM_FCNTL_H
43462 +#include "asm/arch/fcntl.h"
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
43470 +#ifndef __UM_FIXMAP_H
43471 +#define __UM_FIXMAP_H
43473 +#include <linux/config.h>
43474 +#include <asm/kmap_types.h>
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.
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.
43491 + * TLB entries of such buffers will not be flushed across
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
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,
43506 + __end_of_fixed_addresses
43509 +extern void __set_fixmap (enum fixed_addresses idx,
43510 + unsigned long phys, pgprot_t flags);
43512 +#define set_fixmap(idx, phys) \
43513 + __set_fixmap(idx, phys, PAGE_KERNEL)
43515 + * Some hardware wants to get fixmapped without caching.
43517 +#define set_fixmap_nocache(idx, phys) \
43518 + __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
43520 + * used by vmalloc.c.
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..
43526 +extern unsigned long get_kmem_end(void);
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)
43532 +#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
43534 +extern void __this_fixmap_does_not_exist(void);
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.
43541 +static inline unsigned long fix_to_virt(const unsigned int idx)
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).
43549 + * If it doesn't get removed, the linker will complain
43550 + * loudly with a reasonably clear error message..
43552 + if (idx >= __end_of_fixed_addresses)
43553 + __this_fixmap_does_not_exist();
43555 + return __fix_to_virt(idx);
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
43564 +#ifndef __UM_FLOPPY_H
43565 +#define __UM_FLOPPY_H
43567 +#include "asm/arch/floppy.h"
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
43575 +#ifndef __UM_HARDIRQ_H
43576 +#define __UM_HARDIRQ_H
43578 +#include "asm/arch/hardirq.h"
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
43586 +#ifndef __UM_HDREG_H
43587 +#define __UM_HDREG_H
43589 +#include "asm/arch/hdreg.h"
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
43597 +#ifndef __UM_HIGHMEM_H
43598 +#define __UM_HIGHMEM_H
43600 +#include "asm/page.h"
43601 +#include "asm/fixmap.h"
43602 +#include "asm/arch/highmem.h"
43606 +#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK)
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
43614 +#ifndef _ASM_UM_HW_IRQ_H
43615 +#define _ASM_UM_HW_IRQ_H
43617 +#include "asm/irq.h"
43618 +#include "asm/archparam.h"
43620 +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
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
43629 +#ifndef __UM_IDE_H
43630 +#define __UM_IDE_H
43632 +#include "asm/arch/ide.h"
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
43640 +#ifndef _UM_INIT_H
43641 +#define _UM_INIT_H
43645 +#define __initdata
43646 +#define __initfunc(__arginit) __arginit
43647 +#define __cacheline_aligned
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
43656 +#ifndef __UM_IOCTL_H
43657 +#define __UM_IOCTL_H
43659 +#include "asm/arch/ioctl.h"
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
43667 +#ifndef __UM_IOCTLS_H
43668 +#define __UM_IOCTLS_H
43670 +#include "asm/arch/ioctls.h"
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
43681 +#include "asm/page.h"
43683 +#define IO_SPACE_LIMIT 0xdeadbeef /* Sure hope nothing uses this */
43685 +static inline int inb(unsigned long i) { return(0); }
43686 +static inline void outb(char c, unsigned long i) { }
43689 + * Change virtual addresses to physical addresses and vv.
43690 + * These are pretty trivial
43692 +static inline unsigned long virt_to_phys(volatile void * address)
43694 + return __pa((void *) address);
43697 +static inline void * phys_to_virt(unsigned long address)
43699 + return __va(address);
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
43708 +#ifndef __UM_IPCBUF_H
43709 +#define __UM_IPCBUF_H
43711 +#include "asm/arch/ipcbuf.h"
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
43719 +#ifndef __UM_IPC_H
43720 +#define __UM_IPC_H
43722 +#include "asm/arch/ipc.h"
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
43730 +#ifndef __UM_IRQ_H
43731 +#define __UM_IRQ_H
43733 +#define TIMER_IRQ 0
43735 +#define CONSOLE_IRQ 2
43736 +#define CONSOLE_WRITE_IRQ 3
43738 +#define UM_ETH_IRQ 5
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
43749 +#define LAST_IRQ HUMFS_IRQ
43750 +#define NR_IRQS (LAST_IRQ + 1)
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
43758 +#ifndef __UM_KEYBOARD_H
43759 +#define __UM_KEYBOARD_H
43761 +#include "asm/arch/keyboard.h"
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
43770 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
43771 + * Licensed under the GPL
43774 +#ifndef __UM_KMAP_TYPES_H
43775 +#define __UM_KMAP_TYPES_H
43777 +#include "asm/arch/kmap_types.h"
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
43785 +#ifndef __UM_LINUX_LOGO_H
43786 +#define __UM_LINUX_LOGO_H
43788 +#include "asm/arch/linux_logo.h"
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
43796 +#ifndef __UM_LOCKS_H
43797 +#define __UM_LOCKS_H
43799 +#include "asm/arch/locks.h"
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
43807 +#ifndef mca___UM_DMA_H
43808 +#define mca___UM_DMA_H
43810 +#include "asm/arch/mca_dma.h"
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
43818 +#ifndef __UM_MMAN_H
43819 +#define __UM_MMAN_H
43821 +#include "asm/arch/mman.h"
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
43830 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
43831 + * Licensed under the GPL
43834 +#ifndef __UM_MMU_CONTEXT_H
43835 +#define __UM_MMU_CONTEXT_H
43837 +#include "linux/sched.h"
43838 +#include "choose-mode.h"
43840 +#define get_mmu_context(task) do ; while(0)
43841 +#define activate_context(tsk) do ; while(0)
43843 +static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
43847 +extern void switch_mm_skas(int mm_fd);
43849 +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
43850 + struct task_struct *tsk, unsigned cpu)
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));
43861 +static inline void enter_lazy_tlb(struct mm_struct *mm,
43862 + struct task_struct *tsk, unsigned cpu)
43866 +extern int init_new_context_skas(struct task_struct *task,
43867 + struct mm_struct *mm);
43869 +static inline int init_new_context_tt(struct task_struct *task,
43870 + struct mm_struct *mm)
43875 +static inline int init_new_context(struct task_struct *task,
43876 + struct mm_struct *mm)
43878 + return(CHOOSE_MODE_PROC(init_new_context_tt, init_new_context_skas,
43882 +extern void destroy_context_skas(struct mm_struct *mm);
43884 +static inline void destroy_context(struct mm_struct *mm)
43886 + CHOOSE_MODE((void) 0, destroy_context_skas(mm));
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
43896 + * ---------------------------------------------------------------------------
43897 + * Local variables:
43898 + * c-file-style: "linux"
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
43907 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
43908 + * Licensed under the GPL
43914 +#include "um_mmu.h"
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
43923 + * ---------------------------------------------------------------------------
43924 + * Local variables:
43925 + * c-file-style: "linux"
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
43933 +#ifndef __UM_MODULE_H
43934 +#define __UM_MODULE_H
43936 +#include "asm/arch/module.h"
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
43944 +#ifndef __UM_MSGBUF_H
43945 +#define __UM_MSGBUF_H
43947 +#include "asm/arch/msgbuf.h"
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
43955 +#ifndef __UM_MTRR_H
43956 +#define __UM_MTRR_H
43958 +#include "asm/arch/mtrr.h"
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
43966 +#ifndef __UM_NAMEI_H
43967 +#define __UM_NAMEI_H
43969 +#include "asm/arch/namei.h"
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
43978 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
43979 + * Licensed under the GPL
43982 +#ifndef __UM_PAGE_H
43983 +#define __UM_PAGE_H
43987 +#include "asm/arch/page.h"
43993 +#undef virt_to_page
43995 +#undef PAGE_OFFSET
43998 +extern unsigned long uml_physmem;
44000 +#define PAGE_OFFSET (uml_physmem)
44001 +#define KERNELBASE PAGE_OFFSET
44003 +#ifndef __ASSEMBLY__
44005 +extern void stop(void);
44007 +#define BUG() do { \
44008 + panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
44011 +#define PAGE_BUG(page) do { \
44015 +#endif /* __ASSEMBLY__ */
44017 +#define __va_space (8*1024*1024)
44019 +extern unsigned long to_phys(void *virt);
44020 +extern void *to_virt(unsigned long phys);
44022 +#define __pa(virt) to_phys((void *) virt)
44023 +#define __va(phys) to_virt((unsigned long) phys)
44025 +#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
44027 +extern struct page *arch_validate(struct page *page, int mask, int order);
44028 +#define HAVE_ARCH_VALIDATE
44030 +extern void arch_free_page(struct page *page, int order);
44031 +#define HAVE_ARCH_FREE_PAGE
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
44040 + * ---------------------------------------------------------------------------
44041 + * Local variables:
44042 + * c-file-style: "linux"
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
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
44056 +#ifndef _UM_PARAM_H
44057 +#define _UM_PARAM_H
44061 +#define EXEC_PAGESIZE 4096
44064 +#define NGROUPS 32
44068 +#define NOGROUP (-1)
44071 +#define MAXHOSTNAMELEN 64 /* max length of hostname */
44074 +# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */
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
44083 +#ifndef __UM_PCI_H
44084 +#define __UM_PCI_H
44086 +#define PCI_DMA_BUS_IS_PHYS (1)
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
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
44100 +#ifndef __UM_PGALLOC_H
44101 +#define __UM_PGALLOC_H
44103 +#include "linux/config.h"
44104 +#include "linux/mm.h"
44105 +#include "asm/fixmap.h"
44106 +#include "choose-mode.h"
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)
44113 +#define pmd_populate(mm, pmd, pte) set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
44116 + * Allocate and free page tables.
44119 +static inline pgd_t *get_pgd_slow_tt(void)
44121 + pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
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));
44132 +static inline pgd_t *get_pgd_slow_skas(void)
44134 + pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
44137 + memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
44141 +static inline pgd_t *get_pgd_slow(void)
44143 + return(CHOOSE_MODE(get_pgd_slow_tt(), get_pgd_slow_skas()));
44146 +static inline pgd_t *get_pgd_fast(void)
44148 + unsigned long *ret;
44150 + ret = pgd_quicklist;
44151 + if (ret != NULL) {
44152 + pgd_quicklist = (unsigned long *)(*ret);
44154 + pgtable_cache_size--;
44156 + ret = (unsigned long *)get_pgd_slow();
44157 + return (pgd_t *)ret;
44160 +static inline void free_pgd_fast(pgd_t *pgd)
44162 + *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
44163 + pgd_quicklist = (unsigned long *) pgd;
44164 + pgtable_cache_size++;
44167 +static inline void free_pgd_slow(pgd_t *pgd)
44169 + free_page((unsigned long)pgd);
44172 +static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
44176 + pte = (pte_t *) __get_free_page(GFP_KERNEL);
44182 +static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
44184 + unsigned long *ret;
44186 + ret = (unsigned long *)pte_quicklist;
44187 + if (ret != NULL) {
44188 + pte_quicklist = (unsigned long *)(*ret);
44190 + pgtable_cache_size--;
44192 + return (pte_t *)ret;
44195 +static inline void pte_free_fast(pte_t *pte)
44197 + *(unsigned long *)pte = (unsigned long) pte_quicklist;
44198 + pte_quicklist = (unsigned long *) pte;
44199 + pgtable_cache_size++;
44202 +static inline void pte_free_slow(pte_t *pte)
44204 + free_page((unsigned long)pte);
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()
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.
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()
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
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);
44242 +static inline void flush_tlb_pgtables(struct mm_struct *mm,
44243 + unsigned long start, unsigned long end)
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
44253 + * ---------------------------------------------------------------------------
44254 + * Local variables:
44255 + * c-file-style: "linux"
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
44264 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
44265 + * Derived from include/asm-i386/pgtable.h
44266 + * Licensed under the GPL
44269 +#ifndef __UM_PGTABLE_H
44270 +#define __UM_PGTABLE_H
44272 +#include "linux/sched.h"
44273 +#include "asm/processor.h"
44274 +#include "asm/page.h"
44276 +extern pgd_t swapper_pg_dir[1024];
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)
44288 +extern void __flush_tlb_one(unsigned long addr);
44290 +extern void pte_free(pte_t *pte);
44292 +extern void pgd_free(pgd_t *pgd);
44294 +extern int do_check_pgt_cache(int, int);
44296 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
44299 +/* zero page used for uninitialized stuff */
44300 +extern unsigned long *empty_zero_page;
44302 +#define pgtable_cache_init() do ; while (0)
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))
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))
44315 + * entries per page directory level: the i386 is two-level, so
44316 + * we don't really have any PMD directory physically.
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
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))
44332 + * pgd entries used up by user/kernel:
44335 +#define USER_PGD_PTRS (TASK_SIZE >> PGDIR_SHIFT)
44336 +#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
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. ;)
44347 +extern unsigned long end_iomem;
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))
44353 +#if CONFIG_HIGHMEM
44354 +# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
44356 +# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
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
44368 +#define REGION_MASK 0xf0000000
44369 +#define REGION_SHIFT 28
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)
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)
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..
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
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
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,..)'
44409 +#undef TEST_VERIFY_AREA
44411 +/* page table for 0-4MB for everybody */
44412 +extern unsigned long pg0[1024];
44415 + * BAD_PAGETABLE is used when we need a bogus page-table, while
44416 + * BAD_PAGE is used for a bogus page.
44418 + * ZERO_PAGE is a global shared page that is always zero: used
44419 + * for zero-mapped memory areas etc..
44421 +extern pte_t __bad_page(void);
44422 +extern pte_t * __bad_pagetable(void);
44424 +#define BAD_PAGETABLE __bad_pagetable()
44425 +#define BAD_PAGE __bad_page()
44427 +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
44429 +/* number of bits that fit into a memory pointer */
44430 +#define BITS_PER_PTR (8*sizeof(unsigned long))
44432 +/* to align the pointer to a pointer address */
44433 +#define PTR_MASK (~(sizeof(void*)-1))
44435 +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
44436 +/* 64-bit machines, beware! SRB. */
44437 +#define SIZEOF_PTR_LOG2 2
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)
44443 +#define pte_none(x) !(pte_val(x) & ~_PAGE_NEWPAGE)
44444 +#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
44446 +#define pte_clear(xp) do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
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)
44453 +#define pmd_newpage(x) (pmd_val(x) & _PAGE_NEWPAGE)
44454 +#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE)
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)
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) { }
44466 +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
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))
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)
44475 +static inline pte_t pte_mknewprot(pte_t pte)
44477 + pte_val(pte) |= _PAGE_NEWPROT;
44481 +static inline pte_t pte_mknewpage(pte_t pte)
44483 + pte_val(pte) |= _PAGE_NEWPAGE;
44487 +static inline void set_pte(pte_t *pteptr, pte_t pteval)
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
44493 + *pteptr = pte_mknewpage(pteval);
44494 + if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr);
44498 + * (pmds are folded into pgds so this doesnt get actually called,
44499 + * but the define is needed for a generic inline function.)
44501 +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
44502 +#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
44505 + * The following only work if pte_present() is true.
44506 + * Undefined behaviour if not..
44508 +static inline int pte_read(pte_t pte)
44510 + return((pte_val(pte) & _PAGE_USER) &&
44511 + !(pte_val(pte) & _PAGE_PROTNONE));
44514 +static inline int pte_exec(pte_t pte){
44515 + return((pte_val(pte) & _PAGE_USER) &&
44516 + !(pte_val(pte) & _PAGE_PROTNONE));
44519 +static inline int pte_write(pte_t pte)
44521 + return((pte_val(pte) & _PAGE_RW) &&
44522 + !(pte_val(pte) & _PAGE_PROTNONE));
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)
44530 + return(pte_present(pte) && (pte_val(pte) & _PAGE_NEWPROT));
44533 +static inline pte_t pte_rdprotect(pte_t pte)
44535 + pte_val(pte) &= ~_PAGE_USER;
44536 + return(pte_mknewprot(pte));
44539 +static inline pte_t pte_exprotect(pte_t pte)
44541 + pte_val(pte) &= ~_PAGE_USER;
44542 + return(pte_mknewprot(pte));
44545 +static inline pte_t pte_mkclean(pte_t pte)
44547 + pte_val(pte) &= ~_PAGE_DIRTY;
44551 +static inline pte_t pte_mkold(pte_t pte)
44553 + pte_val(pte) &= ~_PAGE_ACCESSED;
44557 +static inline pte_t pte_wrprotect(pte_t pte)
44559 + pte_val(pte) &= ~_PAGE_RW;
44560 + return(pte_mknewprot(pte));
44563 +static inline pte_t pte_mkread(pte_t pte)
44565 + pte_val(pte) |= _PAGE_USER;
44566 + return(pte_mknewprot(pte));
44569 +static inline pte_t pte_mkexec(pte_t pte)
44571 + pte_val(pte) |= _PAGE_USER;
44572 + return(pte_mknewprot(pte));
44575 +static inline pte_t pte_mkdirty(pte_t pte)
44577 + pte_val(pte) |= _PAGE_DIRTY;
44581 +static inline pte_t pte_mkyoung(pte_t pte)
44583 + pte_val(pte) |= _PAGE_ACCESSED;
44587 +static inline pte_t pte_mkwrite(pte_t pte)
44589 + pte_val(pte) |= _PAGE_RW;
44590 + return(pte_mknewprot(pte));
44593 +static inline pte_t pte_mkuptodate(pte_t pte)
44595 + pte_val(pte) &= ~_PAGE_NEWPAGE;
44596 + if(pte_present(pte)) pte_val(pte) &= ~_PAGE_NEWPROT;
44600 +extern unsigned long page_to_phys(struct page *page);
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.
44607 +extern pte_t mk_pte(struct page *page, pgprot_t pgprot);
44609 +/* This takes a physical page address that is used by the remapping
44612 +#define mk_pte_phys(phys, pgprot) \
44613 + (pte_mknewpage(mk_pte(virt_to_page(__va(phys)), pgprot)))
44615 +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
44617 + pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
44618 + if(pte_present(pte)) pte = pte_mknewpage(pte_mknewprot(pte));
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)
44626 +/* to find an entry in a page-table-directory */
44627 +#define pgd_offset(mm, address) \
44628 +((mm)->pgd + ((address) >> PGDIR_SHIFT))
44630 +/* to find an entry in a kernel page-table-directory */
44631 +#define pgd_offset_k(address) pgd_offset(&init_mm, address)
44633 +#define __pmd_offset(address) \
44634 + (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
44636 +/* Find an entry in the second-level page table.. */
44637 +static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
44639 + return (pmd_t *) dir;
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))))
44646 +#define update_mmu_cache(vma,address,pte) do ; while (0)
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)
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 })
44658 +#define PageSkip(x) (0)
44659 +#define kern_addr_valid(addr) (1)
44661 +#include <asm-generic/pgtable.h>
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
44671 + * ---------------------------------------------------------------------------
44672 + * Local variables:
44673 + * c-file-style: "linux"
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
44681 +#ifndef __UM_POLL_H
44682 +#define __UM_POLL_H
44684 +#include "asm/arch/poll.h"
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
44692 +#ifndef __UM_POSIX_TYPES_H
44693 +#define __UM_POSIX_TYPES_H
44695 +#include "asm/arch/posix_types.h"
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
44704 + * Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com)
44705 + * Licensed under the GPL
44708 +#ifndef __UM_PROCESSOR_GENERIC_H
44709 +#define __UM_PROCESSOR_GENERIC_H
44713 +struct task_struct;
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"
44723 +#define current_text_addr() ((void *) 0)
44725 +#define cpu_relax() do ; while (0)
44727 +struct thread_struct {
44730 + struct pt_regs regs;
44731 + unsigned long cr2;
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;
44740 + struct arch_thread arch;
44742 +#ifdef CONFIG_MODE_TT
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.
44753 + void *switch_pipe;
44754 + int singlestep_syscall;
44758 +#ifdef CONFIG_MODE_SKAS
44760 + void *switch_buf;
44773 + int (*proc)(void *);
44777 + void (*proc)(void *);
44784 +#define INIT_THREAD \
44787 + .nsyscalls = 0, \
44788 + .regs = EMPTY_REGS, \
44791 + .fault_addr = NULL, \
44792 + .prev_sched = NULL, \
44793 + .temp_stack = 0, \
44794 + .exec_buf = NULL, \
44795 + .arch = INIT_ARCH_THREAD, \
44796 + .request = { 0 } \
44799 +#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
44802 + unsigned long seg;
44805 +extern struct task_struct *alloc_task_struct(void);
44806 +extern void free_task_struct(struct task_struct *task);
44808 +#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count)
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);
44815 +extern unsigned long thread_saved_pc(struct thread_struct *t);
44817 +static inline void mm_copy_segments(struct mm_struct *from_mm,
44818 + struct mm_struct *new_mm)
44822 +static inline void copy_segments(struct task_struct *p,
44823 + struct mm_struct *new_mm)
44827 +static inline void release_segments(struct mm_struct *mm)
44831 +#define init_task (init_task_union.task)
44832 +#define init_stack (init_task_union.stack)
44835 + * User space process size: 3GB (default).
44837 +extern unsigned long task_size;
44839 +#define TASK_SIZE (task_size)
44841 +/* This decides where the kernel will search for a free chunk of vm
44842 + * space during mmap's.
44844 +#define TASK_UNMAPPED_BASE (0x40000000)
44846 +extern void start_thread(struct pt_regs *regs, unsigned long entry,
44847 + unsigned long stack);
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;
44858 +extern struct cpuinfo_um boot_cpu_data;
44860 +#define my_cpu_data cpu_data[smp_processor_id()]
44863 +extern struct cpuinfo_um cpu_data[];
44864 +#define current_cpu_data cpu_data[smp_processor_id()]
44866 +#define cpu_data (&boot_cpu_data)
44867 +#define current_cpu_data boot_cpu_data
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)
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
44881 + * ---------------------------------------------------------------------------
44882 + * Local variables:
44883 + * c-file-style: "linux"
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
44892 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
44893 + * Licensed under the GPL
44896 +#ifndef __UM_PROCESSOR_I386_H
44897 +#define __UM_PROCESSOR_I386_H
44899 +extern int cpu_has_xmm;
44900 +extern int cpu_has_cmov;
44902 +struct arch_thread {
44903 + unsigned long debugregs[8];
44904 + int debugregs_seq;
44907 +#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \
44908 + .debugregs_seq = 0 }
44910 +#include "asm/arch/user.h"
44912 +#include "asm/processor-generic.h"
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
44921 + * ---------------------------------------------------------------------------
44922 + * Local variables:
44923 + * c-file-style: "linux"
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
44931 +#ifndef __UM_PROCESSOR_PPC_H
44932 +#define __UM_PROCESSOR_PPC_H
44934 +#if defined(__ASSEMBLY__)
44936 +#define CONFIG_ALL_PPC
44937 +#include "arch/processor.h"
44941 +#include "asm/processor-generic.h"
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
44952 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
44953 + * Licensed under the GPL
44956 +#ifndef __UM_PTRACE_GENERIC_H
44957 +#define __UM_PTRACE_GENERIC_H
44959 +#ifndef __ASSEMBLY__
44961 +#include "linux/config.h"
44963 +#include "asm/current.h"
44965 +#define pt_regs pt_regs_subarch
44966 +#define show_regs show_regs_subarch
44968 +#include "asm/arch/ptrace.h"
44973 +#undef instruction_pointer
44975 +#include "sysdep/ptrace.h"
44976 +#include "skas_ptrace.h"
44979 + union uml_pt_regs regs;
44982 +#define EMPTY_REGS { regs : EMPTY_UML_PT_REGS }
44984 +#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
44985 +#define PT_REGS_SP(r) UPT_SP(&(r)->regs)
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)
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)
44994 +#define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs)
44996 +#define PT_REGS_SC(r) UPT_SC(&(r)->regs)
44998 +struct task_struct;
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);
45007 +extern void show_regs(struct pt_regs *regs);
45009 +#define INIT_TASK_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
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
45020 + * ---------------------------------------------------------------------------
45021 + * Local variables:
45022 + * c-file-style: "linux"
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
45031 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
45032 + * Licensed under the GPL
45035 +#ifndef __UM_PTRACE_I386_H
45036 +#define __UM_PTRACE_I386_H
45038 +#include "sysdep/ptrace.h"
45039 +#include "asm/ptrace-generic.h"
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)
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)
45056 +#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs)
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)
45062 +#define user_mode(r) UPT_IS_USER(&(r)->regs)
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
45071 + * ---------------------------------------------------------------------------
45072 + * Local variables:
45073 + * c-file-style: "linux"
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
45081 +#ifndef __UM_RESOURCE_H
45082 +#define __UM_RESOURCE_H
45084 +#include "asm/arch/resource.h"
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
45092 +#ifndef __UM_RWLOCK_H
45093 +#define __UM_RWLOCK_H
45095 +#include "asm/arch/rwlock.h"
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
45103 +#ifndef __UM_RWSEM_H__
45104 +#define __UM_RWSEM_H__
45106 +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
45107 +#define __builtin_expect(exp,c) (exp)
45110 +#include "asm/arch/rwsem.h"
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
45118 +#ifndef __UM_SCATTERLIST_H
45119 +#define __UM_SCATTERLIST_H
45121 +#include "asm/arch/scatterlist.h"
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
45129 +#ifndef __UM_SEGMENT_H
45130 +#define __UM_SEGMENT_H
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
45138 +#ifndef __UM_SEMAPHORE_H
45139 +#define __UM_SEMAPHORE_H
45141 +#include "asm/arch/semaphore.h"
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
45149 +#ifndef __UM_SEMBUF_H
45150 +#define __UM_SEMBUF_H
45152 +#include "asm/arch/sembuf.h"
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
45160 +#ifndef __UM_SERIAL_H
45161 +#define __UM_SERIAL_H
45163 +#include "asm/arch/serial.h"
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
45171 +#ifndef __UM_SHMBUF_H
45172 +#define __UM_SHMBUF_H
45174 +#include "asm/arch/shmbuf.h"
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
45182 +#ifndef __UM_SHMPARAM_H
45183 +#define __UM_SHMPARAM_H
45185 +#include "asm/arch/shmparam.h"
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
45193 +#ifndef __UM_SIGCONTEXT_GENERIC_H
45194 +#define __UM_SIGCONTEXT_GENERIC_H
45196 +#include "asm/arch/sigcontext.h"
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
45204 +#ifndef __UM_SIGCONTEXT_I386_H
45205 +#define __UM_SIGCONTEXT_I386_H
45207 +#include "asm/sigcontext-generic.h"
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
45215 +#ifndef __UM_SIGCONTEXT_PPC_H
45216 +#define __UM_SIGCONTEXT_PPC_H
45218 +#define pt_regs sys_pt_regs
45220 +#include "asm/sigcontext-generic.h"
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
45230 +#ifndef __UM_SIGINFO_H
45231 +#define __UM_SIGINFO_H
45233 +#include "asm/arch/siginfo.h"
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
45242 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
45243 + * Licensed under the GPL
45246 +#ifndef __UM_SIGNAL_H
45247 +#define __UM_SIGNAL_H
45249 +#include "asm/arch/signal.h"
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
45258 + * ---------------------------------------------------------------------------
45259 + * Local variables:
45260 + * c-file-style: "linux"
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
45268 +#ifndef __UM_SMP_H
45269 +#define __UM_SMP_H
45273 +#include "linux/config.h"
45274 +#include "asm/current.h"
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
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
45292 +#ifndef __UM_SMPLOCK_H
45293 +#define __UM_SMPLOCK_H
45295 +#include "asm/arch/smplock.h"
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
45303 +#ifndef __UM_SOCKET_H
45304 +#define __UM_SOCKET_H
45306 +#include "asm/arch/socket.h"
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
45314 +#ifndef __UM_SOCKIOS_H
45315 +#define __UM_SOCKIOS_H
45317 +#include "asm/arch/sockios.h"
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
45325 +#ifndef __UM_SOFTIRQ_H
45326 +#define __UM_SOFTIRQ_H
45328 +#include "linux/smp.h"
45329 +#include "asm/system.h"
45330 +#include "asm/processor.h"
45332 +/* A gratuitous name change */
45333 +#define i386_bh_lock um_bh_lock
45334 +#include "asm/arch/softirq.h"
45335 +#undef i386_bh_lock
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
45343 +#ifndef __UM_SPINLOCK_H
45344 +#define __UM_SPINLOCK_H
45346 +#include "linux/config.h"
45349 +#include "asm/arch/spinlock.h"
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
45358 +#ifndef _UM_STATFS_H
45359 +#define _UM_STATFS_H
45361 +#include "asm/arch/statfs.h"
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
45369 +#ifndef __UM_STAT_H
45370 +#define __UM_STAT_H
45372 +#include "asm/arch/stat.h"
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
45380 +#ifndef __UM_STRING_H
45381 +#define __UM_STRING_H
45383 +#include "asm/arch/string.h"
45384 +#include "asm/archparam.h"
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
45392 +#ifndef __UM_SYSTEM_GENERIC_H
45393 +#define __UM_SYSTEM_GENERIC_H
45395 +#include "asm/arch/system.h"
45397 +#undef prepare_to_switch
45399 +#undef __save_flags
45401 +#undef __restore_flags
45402 +#undef restore_flags
45407 +#undef local_irq_save
45408 +#undef local_irq_restore
45409 +#undef local_irq_disable
45410 +#undef local_irq_enable
45412 +#define prepare_to_switch() do ; while(0)
45414 +void *_switch_to(void *prev, void *next);
45416 +#define switch_to(prev, next, last) prev = _switch_to(prev, next)
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);
45423 +#define local_irq_save(flags) do { (flags) = set_signals(0); } while(0)
45425 +#define local_irq_restore(flags) do { set_signals(flags); } while(0)
45427 +#define local_irq_enable() unblock_signals()
45428 +#define local_irq_disable() block_signals()
45430 +#define __sti() unblock_signals()
45431 +#define sti() unblock_signals()
45432 +#define __cli() block_signals()
45433 +#define cli() block_signals()
45435 +#define __save_flags(x) do { (x) = get_signals(); } while(0)
45436 +#define save_flags(x) __save_flags(x)
45438 +#define __restore_flags(x) local_irq_restore(x)
45439 +#define restore_flags(x) __restore_flags(x)
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
45447 +#ifndef __UM_SYSTEM_I386_H
45448 +#define __UM_SYSTEM_I386_H
45450 +#include "asm/system-generic.h"
45452 +#define __HAVE_ARCH_CMPXCHG 1
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
45460 +#ifndef __UM_SYSTEM_PPC_H
45461 +#define __UM_SYSTEM_PPC_H
45463 +#define _switch_to _ppc_switch_to
45465 +#include "asm/arch/system.h"
45469 +#include "asm/system-generic.h"
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
45477 +#ifndef __UM_TERMBITS_H
45478 +#define __UM_TERMBITS_H
45480 +#include "asm/arch/termbits.h"
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
45488 +#ifndef __UM_TERMIOS_H
45489 +#define __UM_TERMIOS_H
45491 +#include "asm/arch/termios.h"
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
45499 +#ifndef __UM_TIMEX_H
45500 +#define __UM_TIMEX_H
45502 +#include "linux/time.h"
45504 +typedef unsigned long cycles_t;
45506 +#define cacheflush_time (0)
45508 +static inline cycles_t get_cycles (void)
45513 +#define vxtime_lock() do ; while (0)
45514 +#define vxtime_unlock() do ; while (0)
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
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
45528 +#ifndef __UM_TYPES_H
45529 +#define __UM_TYPES_H
45531 +#include "asm/arch/types.h"
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
45540 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
45541 + * Licensed under the GPL
45544 +#ifndef __UM_UACCESS_H
45545 +#define __UM_UACCESS_H
45547 +#include "linux/sched.h"
45549 +#define VERIFY_READ 0
45550 +#define VERIFY_WRITE 1
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.
45557 + * For historical reasons, these macros are grossly misnamed.
45560 +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
45562 +#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
45563 +#define USER_DS MAKE_MM_SEG(TASK_SIZE)
45565 +#define get_ds() (KERNEL_DS)
45566 +#define get_fs() (current->addr_limit)
45567 +#define set_fs(x) (current->addr_limit = (x))
45569 +#define segment_eq(a, b) ((a).seg == (b).seg)
45571 +#include "um_uaccess.h"
45573 +#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
45575 +#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
45577 +#define __get_user(x, ptr) \
45579 + const __typeof__(ptr) __private_ptr = ptr; \
45580 + __typeof__(*(__private_ptr)) __private_val; \
45581 + int __private_ret = -EFAULT; \
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; \
45591 +#define get_user(x, ptr) \
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)); \
45598 +#define __put_user(x, ptr) \
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; \
45611 +#define put_user(x, ptr) \
45613 + __typeof__(*(ptr)) *private_ptr = (ptr); \
45614 + (access_ok(VERIFY_WRITE, private_ptr, sizeof(*private_ptr)) ? \
45615 + __put_user(x, private_ptr) : -EFAULT); \
45618 +#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
45620 +struct exception_table_entry
45622 + unsigned long insn;
45623 + unsigned long fixup;
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
45633 + * ---------------------------------------------------------------------------
45634 + * Local variables:
45635 + * c-file-style: "linux"
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
45643 +#ifndef _ASM_UM_UCONTEXT_H
45644 +#define _ASM_UM_UCONTEXT_H
45646 +#include "asm/arch/ucontext.h"
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
45654 +#ifndef __UM_UNALIGNED_H
45655 +#define __UM_UNALIGNED_H
45657 +#include "asm/arch/unaligned.h"
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
45666 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
45667 + * Licensed under the GPL
45670 +#ifndef _UM_UNISTD_H_
45671 +#define _UM_UNISTD_H_
45673 +#include "linux/resource.h"
45674 +#include "asm/uaccess.h"
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);
45692 +#ifdef __KERNEL_SYSCALLS__
45694 +#define KERNEL_CALL(ret_t, sys, args...) \
45695 + mm_segment_t fs = get_fs(); \
45697 + set_fs(KERNEL_DS); \
45698 + ret = sys(args); \
45702 + errno = -(long)ret; \
45705 +static inline long open(const char *pathname, int flags, int mode)
45707 + KERNEL_CALL(int, sys_open, pathname, flags, mode)
45710 +static inline long dup(unsigned int fd)
45712 + KERNEL_CALL(int, sys_dup, fd);
45715 +static inline long close(unsigned int fd)
45717 + KERNEL_CALL(int, sys_close, fd);
45720 +static inline int execve(const char *filename, char *const argv[],
45721 + char *const envp[])
45723 + KERNEL_CALL(int, um_execve, filename, argv, envp);
45726 +static inline long waitpid(pid_t pid, unsigned int *status, int options)
45728 + KERNEL_CALL(pid_t, sys_wait4, pid, status, options, NULL)
45731 +static inline pid_t wait(int *status)
45733 + KERNEL_CALL(pid_t, sys_wait4, -1, status, 0, NULL)
45736 +static inline pid_t setsid(void)
45738 + KERNEL_CALL(pid_t, sys_setsid)
45741 +static inline long lseek(unsigned int fd, off_t offset, unsigned int whence)
45743 + KERNEL_CALL(long, sys_lseek, fd, offset, whence)
45746 +static inline int read(unsigned int fd, char * buf, int len)
45748 + KERNEL_CALL(int, sys_read, fd, buf, len)
45751 +static inline int write(unsigned int fd, char * buf, int len)
45753 + KERNEL_CALL(int, sys_write, fd, buf, len)
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__.
45763 +#ifdef __KERNEL_SYSCALLS__
45764 +#define __SAVE_KERNEL_SYSCALLS__ __KERNEL_SYSCALLS__
45767 +#undef __KERNEL_SYSCALLS__
45768 +#include "asm/arch/unistd.h"
45770 +#ifdef __KERNEL_SYSCALLS__
45771 +#define __KERNEL_SYSCALLS__ __SAVE_KERNEL_SYSCALLS__
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
45781 + * ---------------------------------------------------------------------------
45782 + * Local variables:
45783 + * c-file-style: "linux"
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
45791 +#ifndef __UM_USER_H
45792 +#define __UM_USER_H
45794 +#include "asm/arch/user.h"
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
45802 +#ifndef __UM_VGA_H
45803 +#define __UM_VGA_H
45805 +#include "asm/arch/vga.h"
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
45813 +#ifndef __UM_XOR_H
45814 +#define __UM_XOR_H
45816 +#include "asm-generic/xor.h"
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)
45827 +#elif (MAJOR_NR == UBD_MAJOR)
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)
45836 +#elif (MAJOR_NR == COW_MAJOR)
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)
45845 #endif /* MAJOR_NR == whatever */
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>
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;
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 @@
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
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
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
45909 #define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
45911 struct NAME##_table {\
45912 @@ -165,7 +185,7 @@
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)\
45919 LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
45921 @@ -206,12 +226,10 @@
45923 LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
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))\
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
45940 +#ifndef _HOSTFS_FS_I
45941 +#define _HOSTFS_FS_I
45943 +#include "filehandle.h"
45945 +struct externfs_file_ops;
45947 +struct hostfs_inode_info {
45948 + struct externfs_file_ops *ops;
45949 + struct file_handle *fh;
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
45960 + * ---------------------------------------------------------------------------
45961 + * Local variables:
45962 + * c-file-style: "linux"
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
45970 +#ifndef _HPPFS_FS_I
45971 +#define _HPPFS_FS_I
45973 +struct hppfs_inode_info {
45974 + struct dentry *proc_dentry;
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
45984 + * ---------------------------------------------------------------------------
45985 + * Local variables:
45986 + * c-file-style: "linux"
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
45994 # define ATTRIB_NORET __attribute__((noreturn))
45995 # define NORET_AND noreturn,
45998 +#if defined(__i386__) || defined(UM_FASTCALL)
45999 #define FASTCALL(x) x __attribute__((regparm(3)))
46000 #define fastcall __attribute__((regparm(3)))
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
46007 * used by rstatd/perfmeter
46010 -#define DK_MAX_MAJOR 16
46011 +#define DK_MAX_MAJOR 99
46012 #define DK_MAX_DISK 16
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);
46023 +#ifndef HAVE_ARCH_VALIDATE
46024 +static inline struct page *arch_validate(struct page *page,
46025 + unsigned int gfp_mask, int order)
46031 +#ifndef HAVE_ARCH_FREE_PAGE
46032 +static inline void arch_free_page(struct page *page, int order) { }
46035 static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
46038 @@ -448,7 +460,7 @@
46040 if (order >= MAX_ORDER)
46042 - return _alloc_pages(gfp_mask, order);
46043 + return arch_validate(_alloc_pages(gfp_mask, order), gfp_mask, order);
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);
46051 +extern long do_mprotect(struct mm_struct *mm, unsigned long start,
46052 + size_t len, unsigned long prot);
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 @@
46059 extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
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);
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)
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);
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
46087 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
46088 + * Licensed under the GPL
46091 +#ifndef __PROC_MM_H
46092 +#define __PROC_MM_H
46094 +#include "linux/sched.h"
46096 +#define MM_MMAP 54
46097 +#define MM_MUNMAP 55
46098 +#define MM_MPROTECT 56
46099 +#define MM_COPY_SEGMENTS 57
46102 + unsigned long addr;
46103 + unsigned long len;
46104 + unsigned long prot;
46105 + unsigned long flags;
46106 + unsigned long fd;
46107 + unsigned long offset;
46110 +struct mm_munmap {
46111 + unsigned long addr;
46112 + unsigned long len;
46115 +struct mm_mprotect {
46116 + unsigned long addr;
46117 + unsigned long len;
46118 + unsigned int prot;
46121 +struct proc_mm_op {
46124 + struct mm_mmap mmap;
46125 + struct mm_munmap munmap;
46126 + struct mm_mprotect mprotect;
46127 + int copy_segments;
46131 +extern struct mm_struct *proc_mm_get_mm(int fd);
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
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
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);
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);
46173 +extern void stdio_console_init(void);
46175 #endif /* __KERNEL__ */
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 @@
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
46212 - notifier_call_chain(&panic_notifier_list, 0, NULL);
46213 + notifier_call_chain(&panic_notifier_list, 0, buf);
46215 if (panic_timeout > 0)
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
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
46234 USB "USBNET" DRIVER
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
46242 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
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.
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)
46254 KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
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
46264 obj-$(CONFIG_HIGHMEM) += highmem.o
46265 +obj-$(CONFIG_PROC_MM) += proc_mm.o
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 @@
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)
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);
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,
46296 zap_page_range(mm, st, size);
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 @@
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)
46311 unsigned long nstart, end, tmp;
46312 struct vm_area_struct * vma, * next, * prev;
46313 @@ -281,9 +282,9 @@
46317 - down_write(¤t->mm->mmap_sem);
46318 + down_write(&mm->mmap_sem);
46320 - vma = find_vma_prev(current->mm, start, &prev);
46321 + vma = find_vma_prev(mm, start, &prev);
46323 if (!vma || vma->vm_start > start)
46325 @@ -332,6 +333,11 @@
46326 prev->vm_mm->map_count--;
46329 - up_write(¤t->mm->mmap_sem);
46330 + up_write(&mm->mmap_sem);
46334 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
46336 + return(do_mprotect(current->mm, start, len, prot));
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 @@
46346 + arch_free_page(page, order);
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
46356 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
46357 + * Licensed under the GPL
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"
46367 +static struct file_operations proc_mm_fops;
46369 +struct mm_struct *proc_mm_get_mm(int fd)
46371 + struct mm_struct *ret = ERR_PTR(-EBADF);
46372 + struct file *file;
46378 + ret = ERR_PTR(-EINVAL);
46379 + if(file->f_op != &proc_mm_fops)
46382 + ret = file->private_data;
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);
46394 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
46395 + size_t count, loff_t *ppos)
46397 + struct mm_struct *mm = file->private_data;
46398 + struct proc_mm_op req;
46401 + if(count > sizeof(req))
46404 + n = copy_from_user(&req, buffer, count);
46411 + struct mm_mmap *map = &req.u.mmap;
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)
46420 + case MM_MUNMAP: {
46421 + struct mm_munmap *unmap = &req.u.munmap;
46423 + down_write(&mm->mmap_sem);
46424 + ret = do_munmap(mm, unmap->addr, unmap->len);
46425 + up_write(&mm->mmap_sem);
46431 + case MM_MPROTECT: {
46432 + struct mm_mprotect *protect = &req.u.mprotect;
46434 + ret = do_mprotect(mm, protect->addr, protect->len,
46441 + case MM_COPY_SEGMENTS: {
46442 + struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
46444 + if(IS_ERR(from)){
46445 + ret = PTR_ERR(from);
46449 + mm_copy_segments(from, mm);
46460 +static int open_proc_mm(struct inode *inode, struct file *file)
46462 + struct mm_struct *mm = mm_alloc();
46469 + ret = init_new_context(current, mm);
46473 + spin_lock(&mmlist_lock);
46474 + list_add(&mm->mmlist, ¤t->mm->mmlist);
46476 + spin_unlock(&mmlist_lock);
46478 + file->private_data = mm;
46488 +static int release_proc_mm(struct inode *inode, struct file *file)
46490 + struct mm_struct *mm = file->private_data;
46496 +static struct file_operations proc_mm_fops = {
46497 + .open = open_proc_mm,
46498 + .release = release_proc_mm,
46499 + .write = write_proc_mm,
46502 +static int make_proc_mm(void)
46504 + struct proc_dir_entry *ent;
46506 + ent = create_proc_entry("mm", 0222, &proc_root);
46508 + printk("make_proc_mm : Failed to register /proc/mm\n");
46511 + ent->proc_fops = &proc_mm_fops;
46516 +__initcall(make_proc_mm);
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
46523 + * ---------------------------------------------------------------------------
46524 + * Local variables:
46525 + * c-file-style: "linux"
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 @@
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)
46540 unsigned long offset;
46543 if (index < SHMEM_NR_DIRECT)
46544 - return info->i_direct+index;
46545 - if (!info->i_indirect) {
46546 + return direct+index;
46547 + if (!*indirect) {
46549 - info->i_indirect = (void **) *page;
46550 + *indirect = (void **) *page;
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;
46561 if (index >= ENTRIES_PER_PAGE/2) {
46562 index -= ENTRIES_PER_PAGE/2;
46563 @@ -169,7 +170,21 @@
46564 *dir = (void *) *page;
46567 - return (swp_entry_t *) *dir + offset;
46568 + return (unsigned long **) *dir + offset;
46571 +static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, unsigned long *page)
46573 + return((swp_entry_t *) shmem_block(index, page,
46574 + (unsigned long *) info->i_direct,
46575 + &info->i_indirect));
46578 +static unsigned long *shmem_map_count(struct shmem_inode_info *info,
46579 + unsigned long index, unsigned long *page)
46581 + return((unsigned long *) shmem_block(index, page, info->map_direct,
46582 + &info->map_indirect));
46586 @@ -847,6 +862,7 @@
46587 ops = &shmem_vm_ops;
46588 if (!S_ISREG(inode->i_mode))
46591 UPDATE_ATIME(inode);
46594 @@ -1750,4 +1766,125 @@
46598 +static int adjust_map_counts(struct shmem_inode_info *info,
46599 + unsigned long offset, unsigned long len,
46602 + unsigned long idx, i, *count, page = 0;
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);
46610 + while((count = shmem_map_count(info, idx, &page)) == NULL){
46611 + spin_unlock(&info->lock);
46612 + page = get_zeroed_page(GFP_KERNEL);
46615 + spin_lock(&info->lock);
46621 + *count += adjust;
46623 + spin_unlock(&info->lock);
46627 EXPORT_SYMBOL(shmem_file_setup);
46629 +struct file_operations anon_file_operations;
46631 +static int anon_mmap(struct file *file, struct vm_area_struct *vma)
46633 + struct file *new;
46634 + struct inode *inode;
46635 + loff_t size = vma->vm_end - vma->vm_start;
46638 + if(file->private_data == NULL){
46639 + new = shmem_file_setup("dev/anon", size);
46641 + return(PTR_ERR(new));
46643 + new->f_op = &anon_file_operations;
46644 + file->private_data = new;
46647 + if (vma->vm_file)
46648 + fput(vma->vm_file);
46649 + vma->vm_file = file->private_data;
46650 + get_file(vma->vm_file);
46652 + inode = vma->vm_file->f_dentry->d_inode;
46653 + err = adjust_map_counts(SHMEM_I(inode), vma->vm_pgoff, size, 1);
46657 + vma->vm_ops = &shmem_vm_ops;
46661 +static void anon_munmap(struct file *file, struct vm_area_struct *vma,
46662 + unsigned long start, unsigned long len)
46664 + struct inode *inode = file->f_dentry->d_inode;
46665 + struct shmem_inode_info *info = SHMEM_I(inode);
46669 + struct page *page;
46670 + unsigned long addr, idx, *count;
46672 + for(addr = start; addr < start + len; addr += PAGE_SIZE){
46673 + idx = (addr - vma->vm_start + vma->vm_pgoff);
46674 + idx >>= PAGE_CACHE_SHIFT;
46676 + count = shmem_map_count(info, idx, NULL);
46677 + BUG_ON(count == NULL);
46683 + pgd = pgd_offset(vma->vm_mm, addr);
46684 + if(pgd_none(*pgd))
46687 + pmd = pmd_offset(pgd, addr);
46688 + if(pmd_none(*pmd))
46691 + pte = pte_offset(pmd, addr);
46692 + if(!pte_present(*pte)) /* XXX need to handle swapped pages */
46695 + *pte = pte_mkclean(*pte);
46697 + page = pte_page(*pte);
46699 + lru_cache_del(page);
46700 + ClearPageDirty(page);
46701 + remove_inode_page(page);
46702 + UnlockPage(page);
46704 + page_cache_release(page);
46708 +int anon_release(struct inode *inode, struct file *file)
46710 + if(file->private_data != NULL)
46711 + fput(file->private_data);
46715 +struct file_operations anon_file_operations = {
46716 + .mmap = anon_mmap,
46717 + .munmap = anon_munmap,
46718 + .release = anon_release,