1 diff -Naur -X ../exclude-files orig/arch/um/common.ld.in um/arch/um/common.ld.in
2 --- orig/arch/um/common.ld.in 1969-12-31 19:00:00.000000000 -0500
3 +++ um/arch/um/common.ld.in 2003-10-21 03:26:06.000000000 -0400
5 + .kstrtab : { *(.kstrtab) }
7 + . = ALIGN(16); /* Exception table */
8 + __start___ex_table = .;
9 + __ex_table : { *(__ex_table) }
10 + __stop___ex_table = .;
12 + __start___ksymtab = .; /* Kernel symbol table */
13 + __ksymtab : { *(__ksymtab) }
14 + __stop___ksymtab = .;
16 + .unprotected : { *(.unprotected) }
18 + PROVIDE (_unprotected_end = .);
21 + __uml_setup_start = .;
22 + .uml.setup.init : { *(.uml.setup.init) }
23 + __uml_setup_end = .;
24 + __uml_help_start = .;
25 + .uml.help.init : { *(.uml.help.init) }
27 + __uml_postsetup_start = .;
28 + .uml.postsetup.init : { *(.uml.postsetup.init) }
29 + __uml_postsetup_end = .;
31 + .setup.init : { *(.setup.init) }
33 + __initcall_start = .;
34 + .initcall.init : { *(.initcall.init) }
36 + __uml_initcall_start = .;
37 + .uml.initcall.init : { *(.uml.initcall.init) }
38 + __uml_initcall_end = .;
40 + __exitcall_begin = .;
41 + .exitcall : { *(.exitcall.exit) }
43 + __uml_exitcall_begin = .;
44 + .uml.exitcall : { *(.uml.exitcall.exit) }
45 + __uml_exitcall_end = .;
47 + __preinit_array_start = .;
48 + .preinit_array : { *(.preinit_array) }
49 + __preinit_array_end = .;
50 + __init_array_start = .;
51 + .init_array : { *(.init_array) }
52 + __init_array_end = .;
53 + __fini_array_start = .;
54 + .fini_array : { *(.fini_array) }
55 + __fini_array_end = .;
57 + .data.init : { *(.data.init) }
58 diff -Naur -X ../exclude-files orig/arch/um/config_block.in um/arch/um/config_block.in
59 --- orig/arch/um/config_block.in 1969-12-31 19:00:00.000000000 -0500
60 +++ um/arch/um/config_block.in 2003-10-21 03:26:06.000000000 -0400
62 +mainmenu_option next_comment
63 +comment 'Block Devices'
65 +bool 'Virtual block device' CONFIG_BLK_DEV_UBD
66 +dep_bool ' Always do synchronous disk IO for UBD' CONFIG_BLK_DEV_UBD_SYNC $CONFIG_BLK_DEV_UBD
67 +bool 'COW device' CONFIG_COW
69 +if [ "$CONFIG_BLK_DEV_UBD" = "y" -o "$CONFIG_COW" = "y" ] ; then
70 + define_bool CONFIG_COW_COMMON y
73 +tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
74 +dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
75 +tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
76 +if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
77 + int ' Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
79 +dep_bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM
81 +tristate 'Example IO memory driver' CONFIG_MMAPPER
84 diff -Naur -X ../exclude-files orig/arch/um/config_char.in um/arch/um/config_char.in
85 --- orig/arch/um/config_char.in 1969-12-31 19:00:00.000000000 -0500
86 +++ um/arch/um/config_char.in 2003-10-21 03:26:06.000000000 -0400
88 +mainmenu_option next_comment
89 +comment 'Character Devices'
91 +define_bool CONFIG_STDIO_CONSOLE y
93 +bool 'Virtual serial line' CONFIG_SSL
95 +bool 'file descriptor channel support' CONFIG_FD_CHAN
96 +bool 'null channel support' CONFIG_NULL_CHAN
97 +bool 'port channel support' CONFIG_PORT_CHAN
98 +bool 'pty channel support' CONFIG_PTY_CHAN
99 +bool 'tty channel support' CONFIG_TTY_CHAN
100 +bool 'xterm channel support' CONFIG_XTERM_CHAN
101 +string 'Default main console channel initialization' CONFIG_CON_ZERO_CHAN \
103 +string 'Default console channel initialization' CONFIG_CON_CHAN "xterm"
104 +string 'Default serial line channel initialization' CONFIG_SSL_CHAN "pty"
107 +bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
108 +if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
109 + int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
112 +bool 'Watchdog Timer Support' CONFIG_WATCHDOG
113 +dep_bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT \
115 +dep_tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG $CONFIG_WATCHDOG
116 +dep_tristate ' UML watchdog' CONFIG_UML_WATCHDOG $CONFIG_WATCHDOG
118 +tristate 'Sound support' CONFIG_UML_SOUND
119 +define_tristate CONFIG_SOUND $CONFIG_UML_SOUND
120 +define_tristate CONFIG_HOSTAUDIO $CONFIG_UML_SOUND
122 +bool 'Enable tty logging' CONFIG_TTY_LOG
125 diff -Naur -X ../exclude-files orig/arch/um/config.in um/arch/um/config.in
126 --- orig/arch/um/config.in 1969-12-31 19:00:00.000000000 -0500
127 +++ um/arch/um/config.in 2003-12-14 11:34:02.000000000 -0500
129 +define_bool CONFIG_USERMODE y
131 +mainmenu_name "Linux/Usermode Kernel Configuration"
133 +define_bool CONFIG_ISA n
134 +define_bool CONFIG_SBUS n
135 +define_bool CONFIG_PCI n
137 +define_bool CONFIG_UID16 y
139 +define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
141 +mainmenu_option next_comment
142 +comment 'Code maturity level options'
143 +bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
146 +mainmenu_option next_comment
147 +comment 'General Setup'
149 +bool 'Separate kernel address space support' CONFIG_MODE_SKAS
151 +# This is to ensure that at least one of the modes is enabled. When neither
152 +# is present in defconfig, they default to N, which is bad.
153 +if [ "$CONFIG_MODE_SKAS" != "y" ]; then
154 + define_bool CONFIG_MODE_TT y
157 +bool 'Tracing thread support' CONFIG_MODE_TT
158 +if [ "$CONFIG_MODE_TT" != "y" ]; then
159 + bool 'Statically linked binary when CONFIG_MODE_TT is disabled' CONFIG_STATIC_LINK
161 +bool 'Networking support' CONFIG_NET
162 +bool 'System V IPC' CONFIG_SYSVIPC
163 +bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
164 +bool 'Sysctl support' CONFIG_SYSCTL
165 +tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
166 +tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
167 +tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
168 +tristate 'Host filesystem' CONFIG_HOSTFS
169 +tristate 'Honeypot proc filesystem' CONFIG_HPPFS
170 +bool 'Management console' CONFIG_MCONSOLE
171 +dep_bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ $CONFIG_MCONSOLE
172 +bool '2G/2G host address space split' CONFIG_HOST_2G_2G
173 +bool 'Symmetric multi-processing support' CONFIG_UML_SMP
174 +define_bool CONFIG_SMP $CONFIG_UML_SMP
175 +int 'Nesting level' CONFIG_NEST_LEVEL 0
176 +int 'Kernel address space size (in .5G units)' CONFIG_KERNEL_HALF_GIGS 1
177 +bool 'Highmem support' CONFIG_HIGHMEM
178 +bool '/proc/mm' CONFIG_PROC_MM
179 +int 'Kernel stack size order' CONFIG_KERNEL_STACK_ORDER 2
180 +bool 'Real-time Clock' CONFIG_UML_REAL_TIME_CLOCK
183 +mainmenu_option next_comment
184 +comment 'Loadable module support'
185 +bool 'Enable loadable module support' CONFIG_MODULES
186 +if [ "$CONFIG_MODULES" = "y" ]; then
187 +# MODVERSIONS does not yet work in this architecture
188 +# bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
189 + bool ' Kernel module loader' CONFIG_KMOD
193 +source arch/um/config_char.in
195 +source arch/um/config_block.in
197 +define_bool CONFIG_NETDEVICES $CONFIG_NET
199 +if [ "$CONFIG_NET" = "y" ]; then
200 + source arch/um/config_net.in
201 + source net/Config.in
206 +mainmenu_option next_comment
207 +comment 'SCSI support'
209 +tristate 'SCSI support' CONFIG_SCSI
211 +if [ "$CONFIG_SCSI" != "n" ]; then
212 + source arch/um/config_scsi.in
216 +source drivers/md/Config.in
218 +source drivers/mtd/Config.in
220 +source lib/Config.in
222 +mainmenu_option next_comment
223 +comment 'Kernel hacking'
224 +bool 'Debug memory allocations' CONFIG_DEBUG_SLAB
225 +bool 'Enable kernel debugging symbols' CONFIG_DEBUGSYM
226 +if [ "$CONFIG_XTERM_CHAN" = "y" ]; then
227 + dep_bool 'Enable ptrace proxy' CONFIG_PT_PROXY $CONFIG_DEBUGSYM
229 + define_bool CONFIG_PT_PROXY n
231 +dep_bool 'Enable gprof support' CONFIG_GPROF $CONFIG_DEBUGSYM
232 +dep_bool 'Enable gcov support' CONFIG_GCOV $CONFIG_DEBUGSYM
234 diff -Naur -X ../exclude-files orig/arch/um/config_net.in um/arch/um/config_net.in
235 --- orig/arch/um/config_net.in 1969-12-31 19:00:00.000000000 -0500
236 +++ um/arch/um/config_net.in 2003-10-21 03:26:06.000000000 -0400
238 +mainmenu_option next_comment
239 +comment 'Network Devices'
241 +# UML virtual driver
242 +bool 'Virtual network device' CONFIG_UML_NET
244 +dep_bool ' Ethertap transport' CONFIG_UML_NET_ETHERTAP $CONFIG_UML_NET
245 +dep_bool ' TUN/TAP transport' CONFIG_UML_NET_TUNTAP $CONFIG_UML_NET
246 +dep_bool ' SLIP transport' CONFIG_UML_NET_SLIP $CONFIG_UML_NET
247 +dep_bool ' SLiRP transport' CONFIG_UML_NET_SLIRP $CONFIG_UML_NET
248 +dep_bool ' Daemon transport' CONFIG_UML_NET_DAEMON $CONFIG_UML_NET
249 +dep_bool ' Multicast transport' CONFIG_UML_NET_MCAST $CONFIG_UML_NET
250 +dep_bool ' pcap transport' CONFIG_UML_NET_PCAP $CONFIG_UML_NET
252 +# Below are hardware-independent drivers mirrored from
253 +# drivers/net/Config.in. It would be nice if Linux
254 +# had HW independent drivers separated from the other
255 +# but it does not. Until then each non-ISA/PCI arch
256 +# needs to provide it's own menu of network drivers
258 +tristate 'Dummy net driver support' CONFIG_DUMMY
259 +tristate 'Bonding driver support' CONFIG_BONDING
260 +tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
261 +tristate 'Universal TUN/TAP device driver support' CONFIG_TUN
262 +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
263 + if [ "$CONFIG_NETLINK" = "y" ]; then
264 + tristate 'Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP
268 +tristate 'PPP (point-to-point protocol) support' CONFIG_PPP
269 +if [ ! "$CONFIG_PPP" = "n" ]; then
270 + dep_bool ' PPP multilink support (EXPERIMENTAL)' CONFIG_PPP_MULTILINK $CONFIG_EXPERIMENTAL
271 + dep_bool ' PPP filtering' CONFIG_PPP_FILTER $CONFIG_FILTER
272 + dep_tristate ' PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP
273 + dep_tristate ' PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
274 + dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
275 + dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP
276 + dep_tristate ' PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP $CONFIG_EXPERIMENTAL
279 +tristate 'SLIP (serial line) support' CONFIG_SLIP
280 +dep_bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED $CONFIG_SLIP
281 +dep_bool ' Keepalive and linefill' CONFIG_SLIP_SMART $CONFIG_SLIP
282 +dep_bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 $CONFIG_SLIP
285 diff -Naur -X ../exclude-files orig/arch/um/config.release um/arch/um/config.release
286 --- orig/arch/um/config.release 1969-12-31 19:00:00.000000000 -0500
287 +++ um/arch/um/config.release 2003-10-21 03:26:06.000000000 -0400
290 +# Automatically generated make config: don't edit
293 +# CONFIG_ISA is not set
294 +# CONFIG_SBUS is not set
295 +# CONFIG_PCI is not set
297 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
300 +# Code maturity level options
302 +CONFIG_EXPERIMENTAL=y
309 +CONFIG_BSD_PROCESS_ACCT=y
311 +CONFIG_BINFMT_AOUT=y
313 +CONFIG_BINFMT_MISC=y
315 +# CONFIG_HPPFS is not set
317 +CONFIG_MAGIC_SYSRQ=y
318 +# CONFIG_HOST_2G_2G is not set
319 +# CONFIG_UML_SMP is not set
320 +# CONFIG_SMP is not set
322 +CONFIG_KERNEL_HALF_GIGS=1
325 +# Loadable module support
333 +CONFIG_STDIO_CONSOLE=y
336 +# CONFIG_NULL_CHAN is not set
341 +CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
342 +CONFIG_CON_CHAN="xterm"
343 +CONFIG_SSL_CHAN="pty"
344 +CONFIG_UNIX98_PTYS=y
345 +CONFIG_UNIX98_PTY_COUNT=256
346 +# CONFIG_WATCHDOG is not set
350 +# CONFIG_TTY_LOG is not set
355 +CONFIG_BLK_DEV_UBD=y
356 +# CONFIG_BLK_DEV_UBD_SYNC is not set
357 +CONFIG_BLK_DEV_LOOP=y
358 +CONFIG_BLK_DEV_NBD=y
359 +CONFIG_BLK_DEV_RAM=y
360 +CONFIG_BLK_DEV_RAM_SIZE=4096
361 +CONFIG_BLK_DEV_INITRD=y
362 +# CONFIG_MMAPPER is not set
369 +CONFIG_UML_NET_ETHERTAP=y
370 +CONFIG_UML_NET_TUNTAP=y
371 +CONFIG_UML_NET_SLIP=y
372 +CONFIG_UML_NET_DAEMON=y
373 +CONFIG_UML_NET_MCAST=y
379 +CONFIG_PPP_MULTILINK=y
380 +# CONFIG_PPP_ASYNC is not set
381 +CONFIG_PPP_SYNC_TTY=m
382 +CONFIG_PPP_DEFLATE=m
383 +CONFIG_PPP_BSDCOMP=m
388 +# Networking options
391 +CONFIG_PACKET_MMAP=y
392 +# CONFIG_NETLINK_DEV is not set
393 +# CONFIG_NETFILTER is not set
394 +# CONFIG_FILTER is not set
397 +# CONFIG_IP_MULTICAST is not set
398 +# CONFIG_IP_ADVANCED_ROUTER is not set
399 +# CONFIG_IP_PNP is not set
400 +# CONFIG_NET_IPIP is not set
401 +# CONFIG_NET_IPGRE is not set
402 +# CONFIG_ARPD is not set
403 +# CONFIG_INET_ECN is not set
404 +# CONFIG_SYN_COOKIES is not set
405 +# CONFIG_IPV6 is not set
406 +# CONFIG_KHTTPD is not set
407 +# CONFIG_ATM is not set
408 +# CONFIG_VLAN_8021Q is not set
413 +# CONFIG_IPX is not set
414 +# CONFIG_ATALK is not set
419 +# CONFIG_DECNET is not set
420 +# CONFIG_BRIDGE is not set
421 +# CONFIG_X25 is not set
422 +# CONFIG_LAPB is not set
423 +# CONFIG_LLC is not set
424 +# CONFIG_NET_DIVERT is not set
425 +# CONFIG_ECONET is not set
426 +# CONFIG_WAN_ROUTER is not set
427 +# CONFIG_NET_FASTROUTE is not set
428 +# CONFIG_NET_HW_FLOWCONTROL is not set
431 +# QoS and/or fair queueing
433 +# CONFIG_NET_SCHED is not set
438 +# CONFIG_NET_PKTGEN is not set
446 +CONFIG_REISERFS_FS=m
447 +# CONFIG_REISERFS_CHECK is not set
448 +# CONFIG_REISERFS_PROC_INFO is not set
450 +# CONFIG_ADFS_FS_RW is not set
456 +# CONFIG_JBD_DEBUG is not set
466 +# CONFIG_JOLIET is not set
467 +# CONFIG_ZISOFS is not set
470 +# CONFIG_NTFS_FS is not set
474 +CONFIG_DEVFS_MOUNT=y
475 +# CONFIG_DEVFS_DEBUG is not set
478 +# CONFIG_QNX4FS_RW is not set
483 +# CONFIG_UDF_RW is not set
485 +# CONFIG_UFS_FS_WRITE is not set
488 +# Network File Systems
490 +# CONFIG_CODA_FS is not set
491 +# CONFIG_INTERMEZZO_FS is not set
499 +# CONFIG_SMB_FS is not set
500 +# CONFIG_NCP_FS is not set
501 +# CONFIG_ZISOFS_FS is not set
502 +CONFIG_ZLIB_FS_INFLATE=m
507 +# CONFIG_PARTITION_ADVANCED is not set
508 +CONFIG_MSDOS_PARTITION=y
509 +# CONFIG_SMB_NLS is not set
513 +# Native Language Support
515 +CONFIG_NLS_DEFAULT="iso8859-1"
516 +# CONFIG_NLS_CODEPAGE_437 is not set
517 +# CONFIG_NLS_CODEPAGE_737 is not set
518 +# CONFIG_NLS_CODEPAGE_775 is not set
519 +# CONFIG_NLS_CODEPAGE_850 is not set
520 +# CONFIG_NLS_CODEPAGE_852 is not set
521 +# CONFIG_NLS_CODEPAGE_855 is not set
522 +# CONFIG_NLS_CODEPAGE_857 is not set
523 +# CONFIG_NLS_CODEPAGE_860 is not set
524 +# CONFIG_NLS_CODEPAGE_861 is not set
525 +# CONFIG_NLS_CODEPAGE_862 is not set
526 +# CONFIG_NLS_CODEPAGE_863 is not set
527 +# CONFIG_NLS_CODEPAGE_864 is not set
528 +# CONFIG_NLS_CODEPAGE_865 is not set
529 +# CONFIG_NLS_CODEPAGE_866 is not set
530 +# CONFIG_NLS_CODEPAGE_869 is not set
531 +# CONFIG_NLS_CODEPAGE_936 is not set
532 +# CONFIG_NLS_CODEPAGE_950 is not set
533 +# CONFIG_NLS_CODEPAGE_932 is not set
534 +# CONFIG_NLS_CODEPAGE_949 is not set
535 +# CONFIG_NLS_CODEPAGE_874 is not set
536 +# CONFIG_NLS_ISO8859_8 is not set
537 +# CONFIG_NLS_CODEPAGE_1250 is not set
538 +# CONFIG_NLS_CODEPAGE_1251 is not set
539 +# CONFIG_NLS_ISO8859_1 is not set
540 +# CONFIG_NLS_ISO8859_2 is not set
541 +# CONFIG_NLS_ISO8859_3 is not set
542 +# CONFIG_NLS_ISO8859_4 is not set
543 +# CONFIG_NLS_ISO8859_5 is not set
544 +# CONFIG_NLS_ISO8859_6 is not set
545 +# CONFIG_NLS_ISO8859_7 is not set
546 +# CONFIG_NLS_ISO8859_9 is not set
547 +# CONFIG_NLS_ISO8859_13 is not set
548 +# CONFIG_NLS_ISO8859_14 is not set
549 +# CONFIG_NLS_ISO8859_15 is not set
550 +# CONFIG_NLS_KOI8_R is not set
551 +# CONFIG_NLS_KOI8_U is not set
552 +# CONFIG_NLS_UTF8 is not set
560 +# SCSI support type (disk, tape, CD-ROM)
562 +# CONFIG_BLK_DEV_SD is not set
563 +# CONFIG_CHR_DEV_ST is not set
564 +# CONFIG_BLK_DEV_SR is not set
565 +# CONFIG_CHR_DEV_SG is not set
568 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
570 +# CONFIG_SCSI_DEBUG_QUEUES is not set
571 +# CONFIG_SCSI_MULTI_LUN is not set
572 +# CONFIG_SCSI_CONSTANTS is not set
573 +# CONFIG_SCSI_LOGGING is not set
577 +# Multi-device support (RAID and LVM)
579 +# CONFIG_MD is not set
582 +# Memory Technology Devices (MTD)
584 +# CONFIG_MTD is not set
589 +# CONFIG_DEBUG_SLAB is not set
590 +# CONFIG_DEBUGSYM is not set
591 diff -Naur -X ../exclude-files orig/arch/um/config_scsi.in um/arch/um/config_scsi.in
592 --- orig/arch/um/config_scsi.in 1969-12-31 19:00:00.000000000 -0500
593 +++ um/arch/um/config_scsi.in 2003-10-21 03:26:06.000000000 -0400
595 +comment 'SCSI support type (disk, tape, CD-ROM)'
597 +dep_tristate ' SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
599 +if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then
600 + int 'Maximum number of SCSI disks that can be loaded as modules' CONFIG_SD_EXTRA_DEVS 40
603 +dep_tristate ' SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
605 +dep_tristate ' SCSI CD-ROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
607 +if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
608 + bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
609 + int 'Maximum number of CDROM devices that can be loaded as modules' CONFIG_SR_EXTRA_DEVS 2
611 +dep_tristate ' SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
613 +comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
615 +#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
616 + bool ' Enable extra checks in new queueing code' CONFIG_SCSI_DEBUG_QUEUES
619 +bool ' Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
621 +bool ' Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
622 +bool ' SCSI logging facility' CONFIG_SCSI_LOGGING
624 +dep_tristate 'SCSI debugging host simulator (EXPERIMENTAL)' CONFIG_SCSI_DEBUG $CONFIG_SCSI
625 diff -Naur -X ../exclude-files orig/arch/um/defconfig um/arch/um/defconfig
626 --- orig/arch/um/defconfig 1969-12-31 19:00:00.000000000 -0500
627 +++ um/arch/um/defconfig 2003-12-17 02:15:39.000000000 -0500
630 +# Automatically generated make config: don't edit
633 +# CONFIG_ISA is not set
634 +# CONFIG_SBUS is not set
635 +# CONFIG_PCI is not set
637 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
640 +# Code maturity level options
642 +CONFIG_EXPERIMENTAL=y
651 +CONFIG_BSD_PROCESS_ACCT=y
653 +CONFIG_BINFMT_AOUT=y
655 +CONFIG_BINFMT_MISC=y
659 +CONFIG_MAGIC_SYSRQ=y
660 +# CONFIG_HOST_2G_2G is not set
661 +# CONFIG_UML_SMP is not set
662 +# CONFIG_SMP is not set
664 +CONFIG_KERNEL_HALF_GIGS=1
665 +# CONFIG_HIGHMEM is not set
667 +CONFIG_KERNEL_STACK_ORDER=2
668 +CONFIG_UML_REAL_TIME_CLOCK=y
671 +# Loadable module support
674 +# CONFIG_KMOD is not set
679 +CONFIG_STDIO_CONSOLE=y
687 +CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
688 +CONFIG_CON_CHAN="xterm"
689 +CONFIG_SSL_CHAN="pty"
690 +CONFIG_UNIX98_PTYS=y
691 +CONFIG_UNIX98_PTY_COUNT=256
692 +# CONFIG_WATCHDOG is not set
693 +# CONFIG_WATCHDOG_NOWAYOUT is not set
694 +# CONFIG_SOFT_WATCHDOG is not set
695 +# CONFIG_UML_WATCHDOG is not set
699 +# CONFIG_TTY_LOG is not set
704 +CONFIG_BLK_DEV_UBD=y
705 +# CONFIG_BLK_DEV_UBD_SYNC is not set
706 +# CONFIG_COW is not set
708 +CONFIG_BLK_DEV_LOOP=y
709 +CONFIG_BLK_DEV_NBD=y
710 +CONFIG_BLK_DEV_RAM=y
711 +CONFIG_BLK_DEV_RAM_SIZE=4096
712 +CONFIG_BLK_DEV_INITRD=y
713 +# CONFIG_MMAPPER is not set
720 +CONFIG_UML_NET_ETHERTAP=y
721 +CONFIG_UML_NET_TUNTAP=y
722 +CONFIG_UML_NET_SLIP=y
723 +CONFIG_UML_NET_SLIRP=y
724 +CONFIG_UML_NET_DAEMON=y
725 +CONFIG_UML_NET_MCAST=y
726 +# CONFIG_UML_NET_PCAP is not set
728 +# CONFIG_BONDING is not set
729 +# CONFIG_EQUALIZER is not set
732 +# CONFIG_PPP_MULTILINK is not set
733 +# CONFIG_PPP_FILTER is not set
734 +# CONFIG_PPP_ASYNC is not set
735 +# CONFIG_PPP_SYNC_TTY is not set
736 +# CONFIG_PPP_DEFLATE is not set
737 +# CONFIG_PPP_BSDCOMP is not set
738 +# CONFIG_PPPOE is not set
740 +# CONFIG_SLIP_COMPRESSED is not set
741 +# CONFIG_SLIP_SMART is not set
742 +# CONFIG_SLIP_MODE_SLIP6 is not set
745 +# Networking options
748 +CONFIG_PACKET_MMAP=y
749 +# CONFIG_NETLINK_DEV is not set
750 +# CONFIG_NETFILTER is not set
751 +# CONFIG_FILTER is not set
754 +# CONFIG_IP_MULTICAST is not set
755 +# CONFIG_IP_ADVANCED_ROUTER is not set
756 +# CONFIG_IP_PNP is not set
757 +# CONFIG_NET_IPIP is not set
758 +# CONFIG_NET_IPGRE is not set
759 +# CONFIG_ARPD is not set
760 +# CONFIG_INET_ECN is not set
761 +# CONFIG_SYN_COOKIES is not set
762 +# CONFIG_IPV6 is not set
763 +# CONFIG_KHTTPD is not set
766 +# SCTP Configuration (EXPERIMENTAL)
768 +CONFIG_IPV6_SCTP__=y
769 +# CONFIG_IP_SCTP is not set
770 +# CONFIG_ATM is not set
771 +# CONFIG_VLAN_8021Q is not set
776 +# CONFIG_IPX is not set
777 +# CONFIG_ATALK is not set
782 +# CONFIG_DEV_APPLETALK is not set
783 +# CONFIG_DECNET is not set
784 +# CONFIG_BRIDGE is not set
785 +# CONFIG_X25 is not set
786 +# CONFIG_LAPB is not set
787 +# CONFIG_LLC is not set
788 +# CONFIG_NET_DIVERT is not set
789 +# CONFIG_ECONET is not set
790 +# CONFIG_WAN_ROUTER is not set
791 +# CONFIG_NET_FASTROUTE is not set
792 +# CONFIG_NET_HW_FLOWCONTROL is not set
795 +# QoS and/or fair queueing
797 +# CONFIG_NET_SCHED is not set
802 +# CONFIG_NET_PKTGEN is not set
808 +# CONFIG_QFMT_V2 is not set
811 +CONFIG_REISERFS_FS=y
812 +# CONFIG_REISERFS_CHECK is not set
813 +# CONFIG_REISERFS_PROC_INFO is not set
814 +# CONFIG_ADFS_FS is not set
815 +# CONFIG_ADFS_FS_RW is not set
816 +# CONFIG_AFFS_FS is not set
817 +# CONFIG_HFS_FS is not set
818 +# CONFIG_HFSPLUS_FS is not set
819 +# CONFIG_BEFS_FS is not set
820 +# CONFIG_BEFS_DEBUG is not set
821 +# CONFIG_BFS_FS is not set
822 +# CONFIG_EXT3_FS is not set
823 +# CONFIG_JBD is not set
824 +# CONFIG_JBD_DEBUG is not set
829 +# CONFIG_EFS_FS is not set
831 +CONFIG_JFFS_FS_VERBOSE=0
832 +CONFIG_JFFS_PROC_FS=y
834 +CONFIG_JFFS2_FS_DEBUG=0
835 +# CONFIG_CRAMFS is not set
836 +# CONFIG_TMPFS is not set
839 +# CONFIG_JOLIET is not set
840 +# CONFIG_ZISOFS is not set
841 +# CONFIG_JFS_FS is not set
842 +# CONFIG_JFS_DEBUG is not set
843 +# CONFIG_JFS_STATISTICS is not set
845 +# CONFIG_VXFS_FS is not set
846 +# CONFIG_NTFS_FS is not set
847 +# CONFIG_NTFS_RW is not set
848 +# CONFIG_HPFS_FS is not set
851 +CONFIG_DEVFS_MOUNT=y
852 +# CONFIG_DEVFS_DEBUG is not set
854 +# CONFIG_QNX4FS_FS is not set
855 +# CONFIG_QNX4FS_RW is not set
856 +# CONFIG_ROMFS_FS is not set
858 +# CONFIG_SYSV_FS is not set
859 +# CONFIG_UDF_FS is not set
860 +# CONFIG_UDF_RW is not set
861 +# CONFIG_UFS_FS is not set
862 +# CONFIG_UFS_FS_WRITE is not set
865 +# Network File Systems
867 +# CONFIG_CODA_FS is not set
868 +# CONFIG_INTERMEZZO_FS is not set
869 +# CONFIG_NFS_FS is not set
870 +# CONFIG_NFS_V3 is not set
871 +# CONFIG_NFS_DIRECTIO is not set
872 +# CONFIG_ROOT_NFS is not set
873 +# CONFIG_NFSD is not set
874 +# CONFIG_NFSD_V3 is not set
875 +# CONFIG_NFSD_TCP is not set
876 +# CONFIG_SUNRPC is not set
877 +# CONFIG_LOCKD is not set
878 +# CONFIG_SMB_FS is not set
879 +# CONFIG_NCP_FS is not set
880 +# CONFIG_NCPFS_PACKET_SIGNING is not set
881 +# CONFIG_NCPFS_IOCTL_LOCKING is not set
882 +# CONFIG_NCPFS_STRONG is not set
883 +# CONFIG_NCPFS_NFS_NS is not set
884 +# CONFIG_NCPFS_OS2_NS is not set
885 +# CONFIG_NCPFS_SMALLDOS is not set
886 +# CONFIG_NCPFS_NLS is not set
887 +# CONFIG_NCPFS_EXTRAS is not set
888 +# CONFIG_ZISOFS_FS is not set
893 +# CONFIG_PARTITION_ADVANCED is not set
894 +CONFIG_MSDOS_PARTITION=y
895 +# CONFIG_SMB_NLS is not set
899 +# Native Language Support
901 +CONFIG_NLS_DEFAULT="iso8859-1"
902 +# CONFIG_NLS_CODEPAGE_437 is not set
903 +# CONFIG_NLS_CODEPAGE_737 is not set
904 +# CONFIG_NLS_CODEPAGE_775 is not set
905 +# CONFIG_NLS_CODEPAGE_850 is not set
906 +# CONFIG_NLS_CODEPAGE_852 is not set
907 +# CONFIG_NLS_CODEPAGE_855 is not set
908 +# CONFIG_NLS_CODEPAGE_857 is not set
909 +# CONFIG_NLS_CODEPAGE_860 is not set
910 +# CONFIG_NLS_CODEPAGE_861 is not set
911 +# CONFIG_NLS_CODEPAGE_862 is not set
912 +# CONFIG_NLS_CODEPAGE_863 is not set
913 +# CONFIG_NLS_CODEPAGE_864 is not set
914 +# CONFIG_NLS_CODEPAGE_865 is not set
915 +# CONFIG_NLS_CODEPAGE_866 is not set
916 +# CONFIG_NLS_CODEPAGE_869 is not set
917 +# CONFIG_NLS_CODEPAGE_936 is not set
918 +# CONFIG_NLS_CODEPAGE_950 is not set
919 +# CONFIG_NLS_CODEPAGE_932 is not set
920 +# CONFIG_NLS_CODEPAGE_949 is not set
921 +# CONFIG_NLS_CODEPAGE_874 is not set
922 +# CONFIG_NLS_ISO8859_8 is not set
923 +# CONFIG_NLS_CODEPAGE_1250 is not set
924 +# CONFIG_NLS_CODEPAGE_1251 is not set
925 +# CONFIG_NLS_ISO8859_1 is not set
926 +# CONFIG_NLS_ISO8859_2 is not set
927 +# CONFIG_NLS_ISO8859_3 is not set
928 +# CONFIG_NLS_ISO8859_4 is not set
929 +# CONFIG_NLS_ISO8859_5 is not set
930 +# CONFIG_NLS_ISO8859_6 is not set
931 +# CONFIG_NLS_ISO8859_7 is not set
932 +# CONFIG_NLS_ISO8859_9 is not set
933 +# CONFIG_NLS_ISO8859_13 is not set
934 +# CONFIG_NLS_ISO8859_14 is not set
935 +# CONFIG_NLS_ISO8859_15 is not set
936 +# CONFIG_NLS_KOI8_R is not set
937 +# CONFIG_NLS_KOI8_U is not set
938 +# CONFIG_NLS_UTF8 is not set
946 +# SCSI support type (disk, tape, CD-ROM)
948 +# CONFIG_BLK_DEV_SD is not set
949 +# CONFIG_CHR_DEV_ST is not set
950 +# CONFIG_BLK_DEV_SR is not set
951 +# CONFIG_CHR_DEV_SG is not set
954 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
956 +# CONFIG_SCSI_DEBUG_QUEUES is not set
957 +# CONFIG_SCSI_MULTI_LUN is not set
958 +# CONFIG_SCSI_CONSTANTS is not set
959 +# CONFIG_SCSI_LOGGING is not set
963 +# Multi-device support (RAID and LVM)
965 +# CONFIG_MD is not set
966 +# CONFIG_BLK_DEV_MD is not set
967 +# CONFIG_MD_LINEAR is not set
968 +# CONFIG_MD_RAID0 is not set
969 +# CONFIG_MD_RAID1 is not set
970 +# CONFIG_MD_RAID5 is not set
971 +# CONFIG_MD_MULTIPATH is not set
972 +# CONFIG_BLK_DEV_LVM is not set
975 +# Memory Technology Devices (MTD)
978 +# CONFIG_MTD_DEBUG is not set
979 +# CONFIG_MTD_PARTITIONS is not set
980 +# CONFIG_MTD_CONCAT is not set
981 +# CONFIG_MTD_REDBOOT_PARTS is not set
982 +# CONFIG_MTD_CMDLINE_PARTS is not set
985 +# User Modules And Translation Layers
989 +# CONFIG_FTL is not set
990 +# CONFIG_NFTL is not set
993 +# RAM/ROM/Flash chip drivers
995 +# CONFIG_MTD_CFI is not set
996 +# CONFIG_MTD_JEDECPROBE is not set
997 +# CONFIG_MTD_GEN_PROBE is not set
998 +# CONFIG_MTD_CFI_INTELEXT is not set
999 +# CONFIG_MTD_CFI_AMDSTD is not set
1000 +# CONFIG_MTD_CFI_STAA is not set
1001 +# CONFIG_MTD_RAM is not set
1002 +# CONFIG_MTD_ROM is not set
1003 +# CONFIG_MTD_ABSENT is not set
1004 +# CONFIG_MTD_OBSOLETE_CHIPS is not set
1005 +# CONFIG_MTD_AMDSTD is not set
1006 +# CONFIG_MTD_SHARP is not set
1007 +# CONFIG_MTD_JEDEC is not set
1010 +# Mapping drivers for chip access
1012 +# CONFIG_MTD_PHYSMAP is not set
1013 +# CONFIG_MTD_PCI is not set
1014 +# CONFIG_MTD_PCMCIA is not set
1017 +# Self-contained MTD device drivers
1019 +# CONFIG_MTD_PMC551 is not set
1020 +# CONFIG_MTD_SLRAM is not set
1021 +# CONFIG_MTD_MTDRAM is not set
1022 +CONFIG_MTD_BLKMTD=y
1025 +# Disk-On-Chip Device Drivers
1027 +# CONFIG_MTD_DOC1000 is not set
1028 +# CONFIG_MTD_DOC2000 is not set
1029 +# CONFIG_MTD_DOC2001 is not set
1030 +# CONFIG_MTD_DOCPROBE is not set
1033 +# NAND Flash Device Drivers
1035 +# CONFIG_MTD_NAND is not set
1040 +# CONFIG_CRC32 is not set
1041 +CONFIG_ZLIB_INFLATE=y
1042 +CONFIG_ZLIB_DEFLATE=y
1047 +# CONFIG_DEBUG_SLAB is not set
1050 +# CONFIG_GPROF is not set
1051 +# CONFIG_GCOV is not set
1052 diff -Naur -X ../exclude-files orig/arch/um/drivers/chan_kern.c um/arch/um/drivers/chan_kern.c
1053 --- orig/arch/um/drivers/chan_kern.c 1969-12-31 19:00:00.000000000 -0500
1054 +++ um/arch/um/drivers/chan_kern.c 2003-11-07 07:25:34.000000000 -0500
1057 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
1058 + * Licensed under the GPL
1061 +#include <linux/stddef.h>
1062 +#include <linux/kernel.h>
1063 +#include <linux/list.h>
1064 +#include <linux/slab.h>
1065 +#include <linux/tty.h>
1066 +#include <linux/string.h>
1067 +#include <linux/tty_flip.h>
1068 +#include <asm/irq.h>
1069 +#include "chan_kern.h"
1070 +#include "user_util.h"
1072 +#include "irq_user.h"
1076 +static void *not_configged_init(char *str, int device, struct chan_opts *opts)
1078 + printk(KERN_ERR "Using a channel type which is configured out of "
1083 +static int not_configged_open(int input, int output, int primary, void *data,
1086 + printk(KERN_ERR "Using a channel type which is configured out of "
1091 +static void not_configged_close(int fd, void *data)
1093 + printk(KERN_ERR "Using a channel type which is configured out of "
1097 +static int not_configged_read(int fd, char *c_out, void *data)
1099 + printk(KERN_ERR "Using a channel type which is configured out of "
1104 +static int not_configged_write(int fd, const char *buf, int len, void *data)
1106 + printk(KERN_ERR "Using a channel type which is configured out of "
1111 +static int not_configged_console_write(int fd, const char *buf, int len,
1114 + printk(KERN_ERR "Using a channel type which is configured out of "
1119 +static int not_configged_window_size(int fd, void *data, unsigned short *rows,
1120 + unsigned short *cols)
1122 + printk(KERN_ERR "Using a channel type which is configured out of "
1127 +static void not_configged_free(void *data)
1129 + printk(KERN_ERR "Using a channel type which is configured out of "
1133 +static struct chan_ops not_configged_ops = {
1134 + .init = not_configged_init,
1135 + .open = not_configged_open,
1136 + .close = not_configged_close,
1137 + .read = not_configged_read,
1138 + .write = not_configged_write,
1139 + .console_write = not_configged_console_write,
1140 + .window_size = not_configged_window_size,
1141 + .free = not_configged_free,
1145 +static void tty_receive_char(struct tty_struct *tty, char ch)
1147 + if(tty == NULL) return;
1149 + if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
1150 + if(ch == STOP_CHAR(tty)){
1154 + else if(ch == START_CHAR(tty)){
1160 + if((tty->flip.flag_buf_ptr == NULL) ||
1161 + (tty->flip.char_buf_ptr == NULL))
1163 + tty_insert_flip_char(tty, ch, TTY_NORMAL);
1166 +static int open_one_chan(struct chan *chan, int input, int output, int primary)
1170 + if(chan->opened) return(0);
1171 + if(chan->ops->open == NULL) fd = 0;
1172 + else fd = (*chan->ops->open)(input, output, primary, chan->data,
1174 + if(fd < 0) return(fd);
1181 +int open_chan(struct list_head *chans)
1183 + struct list_head *ele;
1184 + struct chan *chan;
1187 + list_for_each(ele, chans){
1188 + chan = list_entry(ele, struct chan, list);
1189 + ret = open_one_chan(chan, chan->input, chan->output,
1191 + if(chan->primary) err = ret;
1196 +void chan_enable_winch(struct list_head *chans, void *line)
1198 + struct list_head *ele;
1199 + struct chan *chan;
1201 + list_for_each(ele, chans){
1202 + chan = list_entry(ele, struct chan, list);
1203 + if(chan->primary && chan->output && chan->ops->winch){
1204 + register_winch(chan->fd, line);
1210 +void enable_chan(struct list_head *chans, void *data)
1212 + struct list_head *ele;
1213 + struct chan *chan;
1215 + list_for_each(ele, chans){
1216 + chan = list_entry(ele, struct chan, list);
1217 + if(!chan->opened) continue;
1219 + line_setup_irq(chan->fd, chan->input, chan->output, data);
1223 +void close_chan(struct list_head *chans)
1225 + struct list_head *ele;
1226 + struct chan *chan;
1228 + /* Close in reverse order as open in case more than one of them
1229 + * refers to the same device and they save and restore that device's
1230 + * state. Then, the first one opened will have the original state,
1231 + * so it must be the last closed.
1233 + for(ele = chans->prev; ele != chans; ele = ele->prev){
1234 + chan = list_entry(ele, struct chan, list);
1235 + if(!chan->opened) continue;
1236 + if(chan->ops->close != NULL)
1237 + (*chan->ops->close)(chan->fd, chan->data);
1243 +int write_chan(struct list_head *chans, const char *buf, int len,
1246 + struct list_head *ele;
1247 + struct chan *chan;
1250 + list_for_each(ele, chans){
1251 + chan = list_entry(ele, struct chan, list);
1252 + if(!chan->output || (chan->ops->write == NULL)) continue;
1253 + n = chan->ops->write(chan->fd, buf, len, chan->data);
1254 + if(chan->primary){
1256 + if((ret == -EAGAIN) || ((ret >= 0) && (ret < len))){
1257 + reactivate_fd(chan->fd, write_irq);
1258 + if(ret == -EAGAIN) ret = 0;
1265 +int console_write_chan(struct list_head *chans, const char *buf, int len)
1267 + struct list_head *ele;
1268 + struct chan *chan;
1271 + list_for_each(ele, chans){
1272 + chan = list_entry(ele, struct chan, list);
1273 + if(!chan->output || (chan->ops->console_write == NULL))
1275 + n = chan->ops->console_write(chan->fd, buf, len, chan->data);
1276 + if(chan->primary) ret = n;
1281 +int chan_window_size(struct list_head *chans, unsigned short *rows_out,
1282 + unsigned short *cols_out)
1284 + struct list_head *ele;
1285 + struct chan *chan;
1287 + list_for_each(ele, chans){
1288 + chan = list_entry(ele, struct chan, list);
1289 + if(chan->primary){
1290 + if(chan->ops->window_size == NULL) return(0);
1291 + return(chan->ops->window_size(chan->fd, chan->data,
1292 + rows_out, cols_out));
1298 +void free_one_chan(struct chan *chan)
1300 + list_del(&chan->list);
1301 + if(chan->ops->free != NULL)
1302 + (*chan->ops->free)(chan->data);
1303 + free_irq_by_fd(chan->fd);
1304 + if(chan->primary && chan->output) ignore_sigio_fd(chan->fd);
1308 +void free_chan(struct list_head *chans)
1310 + struct list_head *ele, *next;
1311 + struct chan *chan;
1313 + list_for_each_safe(ele, next, chans){
1314 + chan = list_entry(ele, struct chan, list);
1315 + free_one_chan(chan);
1319 +static int one_chan_config_string(struct chan *chan, char *str, int size,
1325 + CONFIG_CHUNK(str, size, n, "none", 1);
1329 + CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
1331 + if(chan->dev == NULL){
1332 + CONFIG_CHUNK(str, size, n, "", 1);
1336 + CONFIG_CHUNK(str, size, n, ":", 0);
1337 + CONFIG_CHUNK(str, size, n, chan->dev, 0);
1342 +static int chan_pair_config_string(struct chan *in, struct chan *out,
1343 + char *str, int size, char **error_out)
1347 + n = one_chan_config_string(in, str, size, error_out);
1352 + CONFIG_CHUNK(str, size, n, "", 1);
1356 + CONFIG_CHUNK(str, size, n, ",", 1);
1357 + n = one_chan_config_string(out, str, size, error_out);
1360 + CONFIG_CHUNK(str, size, n, "", 1);
1365 +int chan_config_string(struct list_head *chans, char *str, int size,
1368 + struct list_head *ele;
1369 + struct chan *chan, *in = NULL, *out = NULL;
1371 + list_for_each(ele, chans){
1372 + chan = list_entry(ele, struct chan, list);
1373 + if(!chan->primary)
1381 + return(chan_pair_config_string(in, out, str, size, error_out));
1386 + struct chan_ops *ops;
1389 +struct chan_type chan_table[] = {
1390 +#ifdef CONFIG_FD_CHAN
1391 + { "fd", &fd_ops },
1393 + { "fd", ¬_configged_ops },
1396 +#ifdef CONFIG_NULL_CHAN
1397 + { "null", &null_ops },
1399 + { "null", ¬_configged_ops },
1402 +#ifdef CONFIG_PORT_CHAN
1403 + { "port", &port_ops },
1405 + { "port", ¬_configged_ops },
1408 +#ifdef CONFIG_PTY_CHAN
1409 + { "pty", &pty_ops },
1410 + { "pts", &pts_ops },
1412 + { "pty", ¬_configged_ops },
1413 + { "pts", ¬_configged_ops },
1416 +#ifdef CONFIG_TTY_CHAN
1417 + { "tty", &tty_ops },
1419 + { "tty", ¬_configged_ops },
1422 +#ifdef CONFIG_XTERM_CHAN
1423 + { "xterm", &xterm_ops },
1425 + { "xterm", ¬_configged_ops },
1429 +static struct chan *parse_chan(char *str, int pri, int device,
1430 + struct chan_opts *opts)
1432 + struct chan_type *entry;
1433 + struct chan_ops *ops;
1434 + struct chan *chan;
1440 + for(i = 0; i < sizeof(chan_table)/sizeof(chan_table[0]); i++){
1441 + entry = &chan_table[i];
1442 + if(!strncmp(str, entry->key, strlen(entry->key))){
1444 + str += strlen(entry->key);
1449 + printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n",
1453 + if(ops->init == NULL) return(NULL);
1454 + data = (*ops->init)(str, device, opts);
1455 + if(data == NULL) return(NULL);
1457 + chan = kmalloc(sizeof(*chan), GFP_KERNEL);
1458 + if(chan == NULL) return(NULL);
1459 + *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list),
1471 +int parse_chan_pair(char *str, struct list_head *chans, int pri, int device,
1472 + struct chan_opts *opts)
1474 + struct chan *new, *chan;
1477 + if(!list_empty(chans)){
1478 + chan = list_entry(chans->next, struct chan, list);
1479 + if(chan->pri >= pri) return(0);
1481 + INIT_LIST_HEAD(chans);
1484 + out = strchr(str, ',');
1489 + new = parse_chan(in, pri, device, opts);
1490 + if(new == NULL) return(-1);
1492 + list_add(&new->list, chans);
1494 + new = parse_chan(out, pri, device, opts);
1495 + if(new == NULL) return(-1);
1496 + list_add(&new->list, chans);
1500 + new = parse_chan(str, pri, device, opts);
1501 + if(new == NULL) return(-1);
1502 + list_add(&new->list, chans);
1509 +int chan_out_fd(struct list_head *chans)
1511 + struct list_head *ele;
1512 + struct chan *chan;
1514 + list_for_each(ele, chans){
1515 + chan = list_entry(ele, struct chan, list);
1516 + if(chan->primary && chan->output)
1522 +void chan_interrupt(struct list_head *chans, struct tq_struct *task,
1523 + struct tty_struct *tty, int irq, void *dev)
1525 + struct list_head *ele, *next;
1526 + struct chan *chan;
1530 + list_for_each_safe(ele, next, chans){
1531 + chan = list_entry(ele, struct chan, list);
1532 + if(!chan->input || (chan->ops->read == NULL)) continue;
1534 + if((tty != NULL) &&
1535 + (tty->flip.count >= TTY_FLIPBUF_SIZE)){
1536 + queue_task(task, &tq_timer);
1539 + err = chan->ops->read(chan->fd, &c, chan->data);
1541 + tty_receive_char(tty, c);
1544 + if(err == 0) reactivate_fd(chan->fd, irq);
1546 + if(chan->primary){
1549 + line_disable(dev, irq);
1550 + close_chan(chans);
1555 + if(chan->ops->close != NULL)
1556 + chan->ops->close(chan->fd, chan->data);
1557 + free_one_chan(chan);
1562 + if(tty) tty_flip_buffer_push(tty);
1566 + * Overrides for Emacs so that we follow Linus's tabbing style.
1567 + * Emacs will notice this stuff at the end of the file and automatically
1568 + * adjust the settings for this buffer only. This must remain at the end
1570 + * ---------------------------------------------------------------------------
1571 + * Local variables:
1572 + * c-file-style: "linux"
1575 diff -Naur -X ../exclude-files orig/arch/um/drivers/chan_user.c um/arch/um/drivers/chan_user.c
1576 --- orig/arch/um/drivers/chan_user.c 1969-12-31 19:00:00.000000000 -0500
1577 +++ um/arch/um/drivers/chan_user.c 2003-11-07 07:23:45.000000000 -0500
1580 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
1581 + * Licensed under the GPL
1584 +#include <unistd.h>
1585 +#include <stdlib.h>
1587 +#include <termios.h>
1588 +#include <string.h>
1589 +#include <signal.h>
1590 +#include <sys/stat.h>
1591 +#include <sys/ioctl.h>
1592 +#include <sys/socket.h>
1593 +#include "kern_util.h"
1594 +#include "user_util.h"
1595 +#include "chan_user.h"
1597 +#include "helper.h"
1599 +#include "choose-mode.h"
1602 +void generic_close(int fd, void *unused)
1604 + os_close_file(fd);
1607 +int generic_read(int fd, char *c_out, void *unused)
1611 + n = os_read_file(fd, c_out, sizeof(*c_out));
1620 +/* XXX Trivial wrapper around os_write_file */
1622 +int generic_write(int fd, const char *buf, int n, void *unused)
1624 + return(os_write_file(fd, buf, n));
1627 +int generic_console_write(int fd, const char *buf, int n, void *unused)
1629 + struct termios save, new;
1633 + tcgetattr(fd, &save);
1635 + new.c_oflag |= OPOST;
1636 + tcsetattr(fd, TCSAFLUSH, &new);
1638 + err = generic_write(fd, buf, n, NULL);
1639 + if(isatty(fd)) tcsetattr(fd, TCSAFLUSH, &save);
1643 +int generic_window_size(int fd, void *unused, unsigned short *rows_out,
1644 + unsigned short *cols_out)
1649 + ret = os_window_size(fd, &rows, &cols);
1653 + ret = ((*rows_out != rows) || (*cols_out != cols));
1661 +void generic_free(void *data)
1666 +static void winch_handler(int sig)
1670 +struct winch_data {
1676 +static int winch_thread(void *arg)
1678 + struct winch_data *data = arg;
1680 + int pty_fd, pipe_fd;
1684 + os_close_file(data->close_me);
1685 + pty_fd = data->pty_fd;
1686 + pipe_fd = data->pipe_fd;
1687 + count = os_write_file(pipe_fd, &c, sizeof(c));
1688 + if(count != sizeof(c))
1689 + printk("winch_thread : failed to write synchronization "
1690 + "byte, err = %d\n", -count);
1692 + signal(SIGWINCH, winch_handler);
1693 + sigfillset(&sigs);
1694 + sigdelset(&sigs, SIGWINCH);
1695 + if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
1696 + printk("winch_thread : sigprocmask failed, errno = %d\n",
1702 + printk("winch_thread : setsid failed, errno = %d\n", errno);
1706 + err = os_new_tty_pgrp(pty_fd, os_getpid());
1708 + printk("winch_thread : new_tty_pgrp failed, err = %d\n", -err);
1712 + count = os_read_file(pipe_fd, &c, sizeof(c));
1713 + if(count != sizeof(c))
1714 + printk("winch_thread : failed to read synchronization byte, "
1715 + "err = %d\n", -count);
1720 + count = os_write_file(pipe_fd, &c, sizeof(c));
1721 + if(count != sizeof(c))
1722 + printk("winch_thread : write failed, err = %d\n",
1727 +static int winch_tramp(int fd, void *device_data, int *fd_out)
1729 + struct winch_data data;
1730 + unsigned long stack;
1731 + int fds[2], pid, n, err;
1734 + err = os_pipe(fds, 1, 1);
1736 + printk("winch_tramp : os_pipe failed, err = %d\n", -err);
1740 + data = ((struct winch_data) { .pty_fd = fd,
1741 + .pipe_fd = fds[1],
1742 + .close_me = fds[0] } );
1743 + pid = run_helper_thread(winch_thread, &data, 0, &stack, 0);
1745 + printk("fork of winch_thread failed - errno = %d\n", errno);
1749 + os_close_file(fds[1]);
1751 + n = os_read_file(fds[0], &c, sizeof(c));
1752 + if(n != sizeof(c)){
1753 + printk("winch_tramp : failed to read synchronization byte\n");
1754 + printk("read failed, err = %d\n", -n);
1755 + printk("fd %d will not support SIGWINCH\n", fd);
1761 +void register_winch(int fd, void *device_data)
1763 + int pid, thread, thread_fd;
1770 + pid = tcgetpgrp(fd);
1771 + if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd,
1772 + device_data) && (pid == -1)){
1773 + thread = winch_tramp(fd, device_data, &thread_fd);
1775 + register_winch_irq(thread_fd, fd, thread, device_data);
1777 + count = os_write_file(thread_fd, &c, sizeof(c));
1778 + if(count != sizeof(c))
1779 + printk("register_winch : failed to write "
1780 + "synchronization byte, err = %d\n",
1787 + * Overrides for Emacs so that we follow Linus's tabbing style.
1788 + * Emacs will notice this stuff at the end of the file and automatically
1789 + * adjust the settings for this buffer only. This must remain at the end
1791 + * ---------------------------------------------------------------------------
1792 + * Local variables:
1793 + * c-file-style: "linux"
1796 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow.h um/arch/um/drivers/cow.h
1797 --- orig/arch/um/drivers/cow.h 1969-12-31 19:00:00.000000000 -0500
1798 +++ um/arch/um/drivers/cow.h 2003-12-15 00:32:23.000000000 -0500
1803 +#include <asm/types.h>
1805 +#if __BYTE_ORDER == __BIG_ENDIAN
1806 +# define ntohll(x) (x)
1807 +# define htonll(x) (x)
1808 +#elif __BYTE_ORDER == __LITTLE_ENDIAN
1809 +# define ntohll(x) bswap_64(x)
1810 +# define htonll(x) bswap_64(x)
1812 +#error "__BYTE_ORDER not defined"
1815 +extern int init_cow_file(int fd, char *cow_file, char *backing_file,
1816 + int sectorsize, int alignment, int *bitmap_offset_out,
1817 + unsigned long *bitmap_len_out, int *data_offset_out);
1819 +extern int file_reader(__u64 offset, char *buf, int len, void *arg);
1820 +extern int read_cow_header(int (*reader)(__u64, char *, int, void *),
1821 + void *arg, __u32 *version_out,
1822 + char **backing_file_out, time_t *mtime_out,
1823 + __u64 *size_out, int *sectorsize_out,
1824 + __u32 *align_out, int *bitmap_offset_out);
1826 +extern int write_cow_header(char *cow_file, int fd, char *backing_file,
1827 + int sectorsize, int alignment, long long *size);
1829 +extern void cow_sizes(int version, __u64 size, int sectorsize, int align,
1830 + int bitmap_offset, unsigned long *bitmap_len_out,
1831 + int *data_offset_out);
1836 + * ---------------------------------------------------------------------------
1837 + * Local variables:
1838 + * c-file-style: "linux"
1841 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow_kern.c um/arch/um/drivers/cow_kern.c
1842 --- orig/arch/um/drivers/cow_kern.c 1969-12-31 19:00:00.000000000 -0500
1843 +++ um/arch/um/drivers/cow_kern.c 2003-10-21 03:26:06.000000000 -0400
1845 +#define COW_MAJOR 60
1846 +#define MAJOR_NR COW_MAJOR
1848 +#include <linux/stddef.h>
1849 +#include <linux/kernel.h>
1850 +#include <linux/ctype.h>
1851 +#include <linux/stat.h>
1852 +#include <linux/vmalloc.h>
1853 +#include <linux/blkdev.h>
1854 +#include <linux/blk.h>
1855 +#include <linux/fs.h>
1856 +#include <linux/genhd.h>
1857 +#include <linux/devfs_fs.h>
1858 +#include <asm/uaccess.h>
1859 +#include "2_5compat.h"
1861 +#include "ubd_user.h"
1863 +#define COW_SHIFT 4
1869 + struct block_device *cow_bdev;
1870 + char *backing_path;
1871 + dev_t backing_dev;
1872 + struct block_device *backing_bdev;
1874 + unsigned long *bitmap;
1875 + unsigned long bitmap_len;
1876 + int bitmap_offset;
1878 + devfs_handle_t devfs;
1879 + struct semaphore sem;
1880 + struct semaphore io_sem;
1882 + spinlock_t io_lock;
1883 + struct buffer_head *bh;
1884 + struct buffer_head *bhtail;
1888 +#define DEFAULT_COW { \
1890 + .cow_path = NULL, \
1892 + .backing_path = NULL, \
1893 + .backing_dev = 0, \
1895 + .bitmap_len = 0, \
1896 + .bitmap_offset = 0, \
1897 + .data_offset = 0, \
1899 + .working = ATOMIC_INIT(0), \
1900 + .io_lock = SPIN_LOCK_UNLOCKED, \
1903 +#define MAX_DEV (8)
1904 +#define MAX_MINOR (MAX_DEV << COW_SHIFT)
1906 +struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
1908 +/* Not modified by this driver */
1909 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
1910 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
1912 +/* Protected by cow_lock */
1913 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
1915 +static struct hd_struct cow_part[MAX_MINOR] =
1916 + { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
1918 +/* Protected by io_request_lock */
1919 +static request_queue_t *cow_queue;
1921 +static int cow_open(struct inode *inode, struct file *filp);
1922 +static int cow_release(struct inode * inode, struct file * file);
1923 +static int cow_ioctl(struct inode * inode, struct file * file,
1924 + unsigned int cmd, unsigned long arg);
1925 +static int cow_revalidate(kdev_t rdev);
1927 +static struct block_device_operations cow_blops = {
1929 + .release = cow_release,
1930 + .ioctl = cow_ioctl,
1931 + .revalidate = cow_revalidate,
1934 +/* Initialized in an initcall, and unchanged thereafter */
1935 +devfs_handle_t cow_dir_handle;
1937 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
1940 + .major_name = name, \
1941 + .minor_shift = shift, \
1942 + .max_p = 1 << shift, \
1944 + .sizes = bsizes, \
1946 + .real_devices = NULL, \
1953 +static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
1955 +static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
1956 + COW_SHIFT, sizes, MAX_DEV,
1959 +static int cow_add(int n)
1961 + struct cow *dev = &cow_dev[n];
1962 + char name[sizeof("nnnnnn\0")];
1963 + int err = -ENODEV;
1965 + if(dev->cow_path == NULL)
1968 + sprintf(name, "%d", n);
1969 + dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE,
1970 + MAJOR_NR, n << COW_SHIFT, S_IFBLK |
1971 + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
1972 + &cow_blops, NULL);
1974 + init_MUTEX_LOCKED(&dev->sem);
1975 + init_MUTEX(&dev->io_sem);
1984 + * Add buffer_head to back of pending list
1986 +static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
1988 + unsigned long flags;
1990 + spin_lock_irqsave(&cow->io_lock, flags);
1991 + if(cow->bhtail != NULL){
1992 + cow->bhtail->b_reqnext = bh;
1999 + spin_unlock_irqrestore(&cow->io_lock, flags);
2003 + * Grab first pending buffer
2005 +static struct buffer_head *cow_get_bh(struct cow *cow)
2007 + struct buffer_head *bh;
2009 + spin_lock_irq(&cow->io_lock);
2012 + if(bh == cow->bhtail)
2013 + cow->bhtail = NULL;
2014 + cow->bh = bh->b_reqnext;
2015 + bh->b_reqnext = NULL;
2017 + spin_unlock_irq(&cow->io_lock);
2022 +static void cow_handle_bh(struct cow *cow, struct buffer_head *bh,
2023 + struct buffer_head **cow_bh, int ncow_bh)
2028 + ll_rw_block(WRITE, ncow_bh, cow_bh);
2030 + for(i = 0; i < ncow_bh ; i++){
2031 + wait_on_buffer(cow_bh[i]);
2032 + brelse(cow_bh[i]);
2035 + ll_rw_block(WRITE, 1, &bh);
2039 +static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
2041 + struct buffer_head *bh;
2043 + sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize;
2044 + bh = getblk(dev->cow_dev, sector, dev->sectorsize);
2045 + memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])),
2050 +/* Copied from loop.c, needed to avoid deadlocking in make_request. */
2052 +static int cow_thread(void *data)
2054 + struct cow *dev = data;
2055 + struct buffer_head *bh;
2058 + exit_files(current);
2060 + sprintf(current->comm, "cow%d", dev - cow_dev);
2062 + spin_lock_irq(¤t->sigmask_lock);
2063 + sigfillset(¤t->blocked);
2064 + flush_signals(current);
2065 + spin_unlock_irq(¤t->sigmask_lock);
2067 + atomic_inc(&dev->working);
2069 + current->policy = SCHED_OTHER;
2070 + current->nice = -20;
2072 + current->flags |= PF_NOIO;
2075 + * up sem, we are running
2080 + int start, len, nbh, i, update_bitmap = 0;
2081 + struct buffer_head *cow_bh[2];
2083 + down_interruptible(&dev->io_sem);
2085 + * could be upped because of tear-down, not because of
2088 + if(!atomic_read(&dev->working))
2091 + bh = cow_get_bh(dev);
2093 + printk(KERN_ERR "cow: missing bh\n");
2097 + start = bh->b_blocknr * bh->b_size / dev->sectorsize;
2098 + len = bh->b_size / dev->sectorsize;
2099 + for(i = 0; i < len ; i++){
2100 + if(ubd_test_bit(start + i,
2101 + (unsigned char *) dev->bitmap))
2104 + update_bitmap = 1;
2105 + ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
2111 + if(update_bitmap){
2112 + cow_bh[0] = cow_new_bh(dev, start);
2114 + if(start / dev->sectorsize !=
2115 + (start + len) / dev->sectorsize){
2116 + cow_bh[1] = cow_new_bh(dev, start + len);
2121 + bh->b_dev = dev->cow_dev;
2122 + bh->b_blocknr += dev->data_offset / dev->sectorsize;
2124 + cow_handle_bh(dev, bh, cow_bh, nbh);
2127 + * upped both for pending work and tear-down, lo_pending
2128 + * will hit zero then
2130 + if(atomic_dec_and_test(&dev->working))
2138 +static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
2143 + minor = MINOR(bh->b_rdev);
2144 + n = minor >> COW_SHIFT;
2145 + dev = &cow_dev[n];
2147 + dev->end_io = NULL;
2148 + if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){
2149 + bh->b_rdev = dev->cow_dev;
2150 + bh->b_rsector += dev->data_offset / dev->sectorsize;
2152 + else if(rw == WRITE){
2153 + bh->b_dev = dev->cow_dev;
2154 + bh->b_blocknr += dev->data_offset / dev->sectorsize;
2156 + cow_add_bh(dev, bh);
2161 + bh->b_rdev = dev->backing_dev;
2171 + cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL);
2172 + if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) {
2173 + printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR);
2176 + read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */
2177 + blksize_size[MAJOR_NR] = blk_sizes;
2178 + blk_size[MAJOR_NR] = sizes;
2179 + INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
2181 + cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
2182 + blk_init_queue(cow_queue, NULL);
2183 + INIT_ELV(cow_queue, &cow_queue->elevator);
2184 + blk_queue_make_request(cow_queue, cow_make_request);
2186 + add_gendisk(&cow_gendisk);
2188 + for(i=0;i<MAX_DEV;i++)
2194 +__initcall(cow_init);
2196 +static int reader(__u64 start, char *buf, int count, void *arg)
2198 + dev_t dev = *((dev_t *) arg);
2199 + struct buffer_head *bh;
2201 + int cur, offset, left, n, blocksize = get_hardsect_size(dev);
2203 + if(blocksize == 0)
2204 + panic("Zero blocksize");
2206 + block = start / blocksize;
2207 + offset = start % blocksize;
2211 + n = (left > blocksize) ? blocksize : left;
2213 + bh = bread(dev, block, (n < 512) ? 512 : n);
2218 + memcpy(&buf[cur], bh->b_data + offset, n);
2229 +static int cow_open(struct inode *inode, struct file *filp)
2231 + int (*dev_ioctl)(struct inode *, struct file *, unsigned int,
2236 + __u32 version, align;
2238 + char *backing_file;
2239 + int n, offset, err = 0;
2241 + n = DEVICE_NR(inode->i_rdev);
2244 + dev = &cow_dev[n];
2245 + offset = n << COW_SHIFT;
2247 + spin_lock(&cow_lock);
2249 + if(dev->count == 0){
2250 + dev->cow_dev = name_to_kdev_t(dev->cow_path);
2251 + if(dev->cow_dev == 0){
2252 + printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
2253 + "failed\n", dev->cow_path);
2257 + dev->backing_dev = name_to_kdev_t(dev->backing_path);
2258 + if(dev->backing_dev == 0){
2259 + printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
2260 + "failed\n", dev->backing_path);
2267 + dev->cow_bdev = bdget(dev->cow_dev);
2268 + if(dev->cow_bdev == NULL){
2269 + printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n",
2273 + dev->backing_bdev = bdget(dev->backing_dev);
2274 + if(dev->backing_bdev == NULL){
2275 + printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n",
2276 + dev->backing_path);
2283 + err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0,
2286 + printk("cow_open - blkdev_get of COW device failed, "
2287 + "error = %d\n", err);
2291 + err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
2293 + printk("cow_open - blkdev_get of backing device "
2294 + "failed, error = %d\n", err);
2298 + err = read_cow_header(reader, &dev->cow_dev, &version,
2299 + &backing_file, &mtime, &size,
2300 + &dev->sectorsize, &align,
2301 + &dev->bitmap_offset);
2303 + printk(KERN_ERR "cow_open - read_cow_header failed, "
2304 + "err = %d\n", err);
2308 + cow_sizes(version, size, dev->sectorsize, align,
2309 + dev->bitmap_offset, &dev->bitmap_len,
2310 + &dev->data_offset);
2311 + dev->bitmap = (void *) vmalloc(dev->bitmap_len);
2312 + if(dev->bitmap == NULL){
2314 + printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
2317 + flush_tlb_kernel_vm();
2319 + err = reader(dev->bitmap_offset, (char *) dev->bitmap,
2320 + dev->bitmap_len, &dev->cow_dev);
2322 + printk(KERN_ERR "Failed to read COW bitmap\n");
2323 + vfree(dev->bitmap);
2327 + dev_ioctl = dev->backing_bdev->bd_op->ioctl;
2329 + set_fs(KERNEL_DS);
2330 + err = (*dev_ioctl)(inode, filp, BLKGETSIZE,
2331 + (unsigned long) &sizes[offset]);
2334 + printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
2335 + "error = %d\n", err);
2339 + kernel_thread(cow_thread, dev,
2340 + CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
2345 + spin_unlock(&cow_lock);
2349 +static int cow_release(struct inode * inode, struct file * file)
2354 + n = DEVICE_NR(inode->i_rdev);
2357 + dev = &cow_dev[n];
2359 + spin_lock(&cow_lock);
2361 + if(--dev->count > 0)
2364 + err = blkdev_put(dev->cow_bdev, BDEV_RAW);
2366 + printk("cow_release - blkdev_put of cow device failed, "
2367 + "error = %d\n", err);
2368 + bdput(dev->cow_bdev);
2369 + dev->cow_bdev = 0;
2371 + err = blkdev_put(dev->backing_bdev, BDEV_RAW);
2373 + printk("cow_release - blkdev_put of backing device failed, "
2374 + "error = %d\n", err);
2375 + bdput(dev->backing_bdev);
2376 + dev->backing_bdev = 0;
2379 + spin_unlock(&cow_lock);
2383 +static int cow_ioctl(struct inode * inode, struct file * file,
2384 + unsigned int cmd, unsigned long arg)
2387 + int (*dev_ioctl)(struct inode *, struct file *, unsigned int,
2391 + n = DEVICE_NR(inode->i_rdev);
2394 + dev = &cow_dev[n];
2396 + dev_ioctl = dev->backing_bdev->bd_op->ioctl;
2397 + return((*dev_ioctl)(inode, file, cmd, arg));
2400 +static int cow_revalidate(kdev_t rdev)
2402 + printk(KERN_ERR "Need to implement cow_revalidate\n");
2406 +static int parse_unit(char **ptr)
2408 + char *str = *ptr, *end;
2411 + if(isdigit(*str)) {
2412 + n = simple_strtoul(str, &end, 0);
2417 + else if (('a' <= *str) && (*str <= 'h')) {
2425 +static int cow_setup(char *str)
2428 + char *cow_name, *backing_name;
2431 + unit = parse_unit(&str);
2433 + printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
2438 + printk(KERN_ERR "cow_setup - Missing '=' after unit "
2445 + backing_name = strchr(str, ',');
2446 + if(backing_name == NULL){
2447 + printk(KERN_ERR "cow_setup - missing backing device name\n");
2450 + *backing_name = '\0';
2453 + spin_lock(&cow_lock);
2455 + dev = &cow_dev[unit];
2456 + dev->cow_path = cow_name;
2457 + dev->backing_path = backing_name;
2459 + spin_unlock(&cow_lock);
2463 +__setup("cow", cow_setup);
2466 + * Overrides for Emacs so that we follow Linus's tabbing style.
2467 + * Emacs will notice this stuff at the end of the file and automatically
2468 + * adjust the settings for this buffer only. This must remain at the end
2470 + * ---------------------------------------------------------------------------
2471 + * Local variables:
2472 + * c-file-style: "linux"
2475 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow_sys.h um/arch/um/drivers/cow_sys.h
2476 --- orig/arch/um/drivers/cow_sys.h 1969-12-31 19:00:00.000000000 -0500
2477 +++ um/arch/um/drivers/cow_sys.h 2003-12-17 10:53:03.000000000 -0500
2479 +#ifndef __COW_SYS_H__
2480 +#define __COW_SYS_H__
2482 +#include "kern_util.h"
2483 +#include "user_util.h"
2487 +static inline void *cow_malloc(int size)
2489 + return(um_kmalloc(size));
2492 +static inline void cow_free(void *ptr)
2497 +#define cow_printf printk
2499 +static inline char *cow_strdup(char *str)
2501 + return(uml_strdup(str));
2504 +static inline int cow_seek_file(int fd, __u64 offset)
2506 + return(os_seek_file(fd, offset));
2509 +static inline int cow_file_size(char *file, __u64 *size_out)
2511 + return(os_file_size(file, size_out));
2514 +static inline int cow_write_file(int fd, char *buf, int size)
2516 + return(os_write_file(fd, buf, size));
2522 + * ---------------------------------------------------------------------------
2523 + * Local variables:
2524 + * c-file-style: "linux"
2527 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow_user.c um/arch/um/drivers/cow_user.c
2528 --- orig/arch/um/drivers/cow_user.c 1969-12-31 19:00:00.000000000 -0500
2529 +++ um/arch/um/drivers/cow_user.c 2003-11-08 06:29:47.000000000 -0500
2531 +#include <stddef.h>
2532 +#include <string.h>
2534 +#include <unistd.h>
2535 +#include <byteswap.h>
2536 +#include <sys/time.h>
2537 +#include <sys/param.h>
2538 +#include <sys/user.h>
2539 +#include <netinet/in.h>
2544 +#include "cow_sys.h"
2546 +#define PATH_LEN_V1 256
2548 +struct cow_header_v1 {
2551 + char backing_file[PATH_LEN_V1];
2557 +#define PATH_LEN_V2 MAXPATHLEN
2559 +struct cow_header_v2 {
2560 + unsigned long magic;
2561 + unsigned long version;
2562 + char backing_file[PATH_LEN_V2];
2568 +/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in
2569 + * case other systems have different values for MAXPATHLEN
2571 +#define PATH_LEN_V3 4096
2573 +/* Changes from V2 -
2574 + * PATH_LEN_V3 as described above
2575 + * Explicitly specify field bit lengths for systems with different
2576 + * lengths for the usual C types. Not sure whether char or
2577 + * time_t should be changed, this can be changed later without
2578 + * breaking compatibility
2579 + * Add alignment field so that different alignments can be used for the
2581 + * Add cow_format field to allow for the possibility of different ways
2582 + * of specifying the COW blocks. For now, the only value is 0,
2583 + * for the traditional COW bitmap.
2584 + * Move the backing_file field to the end of the header. This allows
2585 + * for the possibility of expanding it into the padding required
2586 + * by the bitmap alignment.
2587 + * The bitmap and data portions of the file will be aligned as specified
2588 + * by the alignment field. This is to allow COW files to be
2589 + * put on devices with restrictions on access alignments, such as
2590 + * /dev/raw, with a 512 byte alignment restriction. This also
2591 + * allows the data to be more aligned more strictly than on
2592 + * sector boundaries. This is needed for ubd-mmap, which needs
2593 + * the data to be page aligned.
2594 + * Fixed (finally!) the rounding bug
2597 +struct cow_header_v3 {
2605 + char backing_file[PATH_LEN_V3];
2608 +/* COW format definitions - for now, we have only the usual COW bitmap */
2609 +#define COW_BITMAP 0
2612 + struct cow_header_v1 v1;
2613 + struct cow_header_v2 v2;
2614 + struct cow_header_v3 v3;
2617 +#define COW_MAGIC 0x4f4f4f4d /* MOOO */
2618 +#define COW_VERSION 3
2620 +#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len))
2621 +#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align)
2623 +void cow_sizes(int version, __u64 size, int sectorsize, int align,
2624 + int bitmap_offset, unsigned long *bitmap_len_out,
2625 + int *data_offset_out)
2628 + *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
2630 + *data_offset_out = bitmap_offset + *bitmap_len_out;
2631 + *data_offset_out = (*data_offset_out + sectorsize - 1) /
2633 + *data_offset_out *= sectorsize;
2636 + *bitmap_len_out = DIV_ROUND(size, sectorsize);
2637 + *bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8);
2639 + *data_offset_out = bitmap_offset + *bitmap_len_out;
2640 + *data_offset_out = ROUND_UP(*data_offset_out, align);
2644 +static int absolutize(char *to, int size, char *from)
2646 + char save_cwd[256], *slash;
2649 + if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
2650 + cow_printf("absolutize : unable to get cwd - errno = %d\n",
2654 + slash = strrchr(from, '/');
2655 + if(slash != NULL){
2659 + cow_printf("absolutize : Can't cd to '%s' - "
2660 + "errno = %d\n", from, errno);
2664 + if(getcwd(to, size) == NULL){
2665 + cow_printf("absolutize : unable to get cwd of '%s' - "
2666 + "errno = %d\n", from, errno);
2669 + remaining = size - strlen(to);
2670 + if(strlen(slash) + 1 > remaining){
2671 + cow_printf("absolutize : unable to fit '%s' into %d "
2672 + "chars\n", from, size);
2675 + strcat(to, slash);
2678 + if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
2679 + cow_printf("absolutize : unable to fit '%s' into %d "
2680 + "chars\n", from, size);
2683 + strcpy(to, save_cwd);
2691 +int write_cow_header(char *cow_file, int fd, char *backing_file,
2692 + int sectorsize, int alignment, long long *size)
2694 + struct cow_header_v3 *header;
2695 + unsigned long modtime;
2698 + err = cow_seek_file(fd, 0);
2700 + cow_printf("write_cow_header - lseek failed, err = %d\n", -err);
2705 + header = cow_malloc(sizeof(*header));
2706 + if(header == NULL){
2707 + cow_printf("Failed to allocate COW V3 header\n");
2710 + header->magic = htonl(COW_MAGIC);
2711 + header->version = htonl(COW_VERSION);
2714 + if(strlen(backing_file) > sizeof(header->backing_file) - 1){
2715 + cow_printf("Backing file name \"%s\" is too long - names are "
2716 + "limited to %d characters\n", backing_file,
2717 + sizeof(header->backing_file) - 1);
2721 + if(absolutize(header->backing_file, sizeof(header->backing_file),
2725 + err = os_file_modtime(header->backing_file, &modtime);
2727 + cow_printf("Backing file '%s' mtime request failed, "
2728 + "err = %d\n", header->backing_file, -err);
2732 + err = cow_file_size(header->backing_file, size);
2734 + cow_printf("Couldn't get size of backing file '%s', "
2735 + "err = %d\n", header->backing_file, -err);
2739 + header->mtime = htonl(modtime);
2740 + header->size = htonll(*size);
2741 + header->sectorsize = htonl(sectorsize);
2742 + header->alignment = htonl(alignment);
2743 + header->cow_format = COW_BITMAP;
2745 + err = os_write_file(fd, header, sizeof(*header));
2746 + if(err != sizeof(*header)){
2747 + cow_printf("Write of header to new COW file '%s' failed, "
2748 + "err = %d\n", cow_file, -err);
2758 +int file_reader(__u64 offset, char *buf, int len, void *arg)
2760 + int fd = *((int *) arg);
2762 + return(pread(fd, buf, len, offset));
2765 +/* XXX Need to sanity-check the values read from the header */
2767 +int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
2768 + __u32 *version_out, char **backing_file_out,
2769 + time_t *mtime_out, __u64 *size_out,
2770 + int *sectorsize_out, __u32 *align_out,
2771 + int *bitmap_offset_out)
2773 + union cow_header *header;
2776 + unsigned long version, magic;
2778 + header = cow_malloc(sizeof(*header));
2779 + if(header == NULL){
2780 + cow_printf("read_cow_header - Failed to allocate header\n");
2784 + n = (*reader)(0, (char *) header, sizeof(*header), arg);
2785 + if(n < offsetof(typeof(header->v1), backing_file)){
2786 + cow_printf("read_cow_header - short header\n");
2790 + magic = header->v1.magic;
2791 + if(magic == COW_MAGIC) {
2792 + version = header->v1.version;
2794 + else if(magic == ntohl(COW_MAGIC)){
2795 + version = ntohl(header->v1.version);
2797 + /* No error printed because the non-COW case comes through here */
2800 + *version_out = version;
2803 + if(n < sizeof(header->v1)){
2804 + cow_printf("read_cow_header - failed to read V1 "
2808 + *mtime_out = header->v1.mtime;
2809 + *size_out = header->v1.size;
2810 + *sectorsize_out = header->v1.sectorsize;
2811 + *bitmap_offset_out = sizeof(header->v1);
2812 + *align_out = *sectorsize_out;
2813 + file = header->v1.backing_file;
2815 + else if(version == 2){
2816 + if(n < sizeof(header->v2)){
2817 + cow_printf("read_cow_header - failed to read V2 "
2821 + *mtime_out = ntohl(header->v2.mtime);
2822 + *size_out = ntohll(header->v2.size);
2823 + *sectorsize_out = ntohl(header->v2.sectorsize);
2824 + *bitmap_offset_out = sizeof(header->v2);
2825 + *align_out = *sectorsize_out;
2826 + file = header->v2.backing_file;
2828 + else if(version == 3){
2829 + if(n < sizeof(header->v3)){
2830 + cow_printf("read_cow_header - failed to read V2 "
2834 + *mtime_out = ntohl(header->v3.mtime);
2835 + *size_out = ntohll(header->v3.size);
2836 + *sectorsize_out = ntohl(header->v3.sectorsize);
2837 + *align_out = ntohl(header->v3.alignment);
2838 + *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out);
2839 + file = header->v3.backing_file;
2842 + cow_printf("read_cow_header - invalid COW version\n");
2846 + *backing_file_out = cow_strdup(file);
2847 + if(*backing_file_out == NULL){
2848 + cow_printf("read_cow_header - failed to allocate backing "
2858 +int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
2859 + int alignment, int *bitmap_offset_out,
2860 + unsigned long *bitmap_len_out, int *data_offset_out)
2862 + __u64 size, offset;
2866 + err = write_cow_header(cow_file, fd, backing_file, sectorsize,
2867 + alignment, &size);
2871 + *bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment);
2872 + cow_sizes(COW_VERSION, size, sectorsize, alignment, *bitmap_offset_out,
2873 + bitmap_len_out, data_offset_out);
2875 + offset = *data_offset_out + size - sizeof(zero);
2876 + err = cow_seek_file(fd, offset);
2878 + cow_printf("cow bitmap lseek failed : err = %d\n", -err);
2882 + /* does not really matter how much we write it is just to set EOF
2883 + * this also sets the entire COW bitmap
2884 + * to zero without having to allocate it
2886 + err = cow_write_file(fd, &zero, sizeof(zero));
2887 + if(err != sizeof(zero)){
2888 + cow_printf("Write of bitmap to new COW file '%s' failed, "
2889 + "err = %d\n", cow_file, -err);
2901 + * ---------------------------------------------------------------------------
2902 + * Local variables:
2903 + * c-file-style: "linux"
2906 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon.h um/arch/um/drivers/daemon.h
2907 --- orig/arch/um/drivers/daemon.h 1969-12-31 19:00:00.000000000 -0500
2908 +++ um/arch/um/drivers/daemon.h 2003-10-21 03:26:06.000000000 -0400
2911 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
2912 + * Licensed under the GPL
2915 +#include "net_user.h"
2917 +#define SWITCH_VERSION 3
2919 +struct daemon_data {
2930 +extern struct net_user_info daemon_user_info;
2932 +extern int daemon_user_write(int fd, void *buf, int len,
2933 + struct daemon_data *pri);
2936 + * Overrides for Emacs so that we follow Linus's tabbing style.
2937 + * Emacs will notice this stuff at the end of the file and automatically
2938 + * adjust the settings for this buffer only. This must remain at the end
2940 + * ---------------------------------------------------------------------------
2941 + * Local variables:
2942 + * c-file-style: "linux"
2945 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon_kern.c um/arch/um/drivers/daemon_kern.c
2946 --- orig/arch/um/drivers/daemon_kern.c 1969-12-31 19:00:00.000000000 -0500
2947 +++ um/arch/um/drivers/daemon_kern.c 2003-10-21 03:26:06.000000000 -0400
2950 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
2951 + * James Leu (jleu@mindspring.net).
2952 + * Copyright (C) 2001 by various other people who didn't put their name here.
2953 + * Licensed under the GPL.
2956 +#include "linux/kernel.h"
2957 +#include "linux/init.h"
2958 +#include "linux/netdevice.h"
2959 +#include "linux/etherdevice.h"
2960 +#include "net_kern.h"
2961 +#include "net_user.h"
2962 +#include "daemon.h"
2964 +struct daemon_init {
2969 +void daemon_init(struct net_device *dev, void *data)
2971 + struct uml_net_private *pri;
2972 + struct daemon_data *dpri;
2973 + struct daemon_init *init = data;
2975 + init_etherdev(dev, 0);
2977 + dpri = (struct daemon_data *) pri->user;
2978 + *dpri = ((struct daemon_data)
2979 + { .sock_type = init->sock_type,
2980 + .ctl_sock = init->ctl_sock,
2982 + .data_addr = NULL,
2983 + .local_addr = NULL,
2988 + printk("daemon backend (uml_switch version %d) - %s:%s",
2989 + SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
2993 +static int daemon_read(int fd, struct sk_buff **skb,
2994 + struct uml_net_private *lp)
2996 + *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
2997 + if(*skb == NULL) return(-ENOMEM);
2998 + return(net_recvfrom(fd, (*skb)->mac.raw,
2999 + (*skb)->dev->mtu + ETH_HEADER_OTHER));
3002 +static int daemon_write(int fd, struct sk_buff **skb,
3003 + struct uml_net_private *lp)
3005 + return(daemon_user_write(fd, (*skb)->data, (*skb)->len,
3006 + (struct daemon_data *) &lp->user));
3009 +static struct net_kern_info daemon_kern_info = {
3010 + .init = daemon_init,
3011 + .protocol = eth_protocol,
3012 + .read = daemon_read,
3013 + .write = daemon_write,
3016 +int daemon_setup(char *str, char **mac_out, void *data)
3018 + struct daemon_init *init = data;
3021 + *init = ((struct daemon_init)
3022 + { .sock_type = "unix",
3023 + .ctl_sock = "/tmp/uml.ctl" });
3025 + remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
3027 + if(remain != NULL)
3028 + printk(KERN_WARNING "daemon_setup : Ignoring data socket "
3029 + "specification\n");
3034 +static struct transport daemon_transport = {
3035 + .list = LIST_HEAD_INIT(daemon_transport.list),
3037 + .setup = daemon_setup,
3038 + .user = &daemon_user_info,
3039 + .kern = &daemon_kern_info,
3040 + .private_size = sizeof(struct daemon_data),
3041 + .setup_size = sizeof(struct daemon_init),
3044 +static int register_daemon(void)
3046 + register_transport(&daemon_transport);
3050 +__initcall(register_daemon);
3053 + * Overrides for Emacs so that we follow Linus's tabbing style.
3054 + * Emacs will notice this stuff at the end of the file and automatically
3055 + * adjust the settings for this buffer only. This must remain at the end
3057 + * ---------------------------------------------------------------------------
3058 + * Local variables:
3059 + * c-file-style: "linux"
3062 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon_user.c um/arch/um/drivers/daemon_user.c
3063 --- orig/arch/um/drivers/daemon_user.c 1969-12-31 19:00:00.000000000 -0500
3064 +++ um/arch/um/drivers/daemon_user.c 2003-10-21 03:26:06.000000000 -0400
3067 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
3068 + * James Leu (jleu@mindspring.net).
3069 + * Copyright (C) 2001 by various other people who didn't put their name here.
3070 + * Licensed under the GPL.
3074 +#include <unistd.h>
3075 +#include <stdint.h>
3076 +#include <sys/socket.h>
3077 +#include <sys/un.h>
3078 +#include <sys/time.h>
3079 +#include "net_user.h"
3080 +#include "daemon.h"
3081 +#include "kern_util.h"
3082 +#include "user_util.h"
3086 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
3088 +enum request_type { REQ_NEW_CONTROL };
3090 +#define SWITCH_MAGIC 0xfeedface
3092 +struct request_v3 {
3095 + enum request_type type;
3096 + struct sockaddr_un sock;
3099 +static struct sockaddr_un *new_addr(void *name, int len)
3101 + struct sockaddr_un *sun;
3103 + sun = um_kmalloc(sizeof(struct sockaddr_un));
3105 + printk("new_addr: allocation of sockaddr_un failed\n");
3108 + sun->sun_family = AF_UNIX;
3109 + memcpy(sun->sun_path, name, len);
3113 +static int connect_to_switch(struct daemon_data *pri)
3115 + struct sockaddr_un *ctl_addr = pri->ctl_addr;
3116 + struct sockaddr_un *local_addr = pri->local_addr;
3117 + struct sockaddr_un *sun;
3118 + struct request_v3 req;
3121 + pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
3122 + if(pri->control < 0){
3123 + printk("daemon_open : control socket failed, errno = %d\n",
3128 + if(connect(pri->control, (struct sockaddr *) ctl_addr,
3129 + sizeof(*ctl_addr)) < 0){
3130 + printk("daemon_open : control connect failed, errno = %d\n",
3136 + fd = socket(AF_UNIX, SOCK_DGRAM, 0);
3138 + printk("daemon_open : data socket failed, errno = %d\n",
3143 + if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){
3144 + printk("daemon_open : data bind failed, errno = %d\n",
3150 + sun = um_kmalloc(sizeof(struct sockaddr_un));
3152 + printk("new_addr: allocation of sockaddr_un failed\n");
3157 + req.magic = SWITCH_MAGIC;
3158 + req.version = SWITCH_VERSION;
3159 + req.type = REQ_NEW_CONTROL;
3160 + req.sock = *local_addr;
3161 + n = os_write_file(pri->control, &req, sizeof(req));
3162 + if(n != sizeof(req)){
3163 + printk("daemon_open : control setup request failed, err = %d\n",
3169 + n = os_read_file(pri->control, sun, sizeof(*sun));
3170 + if(n != sizeof(*sun)){
3171 + printk("daemon_open : read of data socket failed, err = %d\n",
3177 + pri->data_addr = sun;
3181 + os_close_file(fd);
3183 + os_close_file(pri->control);
3187 +static void daemon_user_init(void *data, void *dev)
3189 + struct daemon_data *pri = data;
3190 + struct timeval tv;
3197 + if(!strcmp(pri->sock_type, "unix"))
3198 + pri->ctl_addr = new_addr(pri->ctl_sock,
3199 + strlen(pri->ctl_sock) + 1);
3201 + name.pid = os_getpid();
3202 + gettimeofday(&tv, NULL);
3203 + name.usecs = tv.tv_usec;
3204 + pri->local_addr = new_addr(&name, sizeof(name));
3206 + pri->fd = connect_to_switch(pri);
3208 + kfree(pri->local_addr);
3209 + pri->local_addr = NULL;
3213 +static int daemon_open(void *data)
3215 + struct daemon_data *pri = data;
3219 +static void daemon_remove(void *data)
3221 + struct daemon_data *pri = data;
3223 + os_close_file(pri->fd);
3224 + os_close_file(pri->control);
3225 + if(pri->data_addr != NULL) kfree(pri->data_addr);
3226 + if(pri->ctl_addr != NULL) kfree(pri->ctl_addr);
3227 + if(pri->local_addr != NULL) kfree(pri->local_addr);
3230 +int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
3232 + struct sockaddr_un *data_addr = pri->data_addr;
3234 + return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
3237 +static int daemon_set_mtu(int mtu, void *data)
3242 +struct net_user_info daemon_user_info = {
3243 + .init = daemon_user_init,
3244 + .open = daemon_open,
3246 + .remove = daemon_remove,
3247 + .set_mtu = daemon_set_mtu,
3248 + .add_address = NULL,
3249 + .delete_address = NULL,
3250 + .max_packet = MAX_PACKET - ETH_HEADER_OTHER
3254 + * Overrides for Emacs so that we follow Linus's tabbing style.
3255 + * Emacs will notice this stuff at the end of the file and automatically
3256 + * adjust the settings for this buffer only. This must remain at the end
3258 + * ---------------------------------------------------------------------------
3259 + * Local variables:
3260 + * c-file-style: "linux"
3263 diff -Naur -X ../exclude-files orig/arch/um/drivers/fd.c um/arch/um/drivers/fd.c
3264 --- orig/arch/um/drivers/fd.c 1969-12-31 19:00:00.000000000 -0500
3265 +++ um/arch/um/drivers/fd.c 2003-10-21 03:26:06.000000000 -0400
3268 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
3269 + * Licensed under the GPL
3273 +#include <stdlib.h>
3274 +#include <unistd.h>
3275 +#include <termios.h>
3277 +#include "user_util.h"
3278 +#include "chan_user.h"
3283 + struct termios tt;
3284 + char str[sizeof("1234567890\0")];
3287 +void *fd_init(char *str, int device, struct chan_opts *opts)
3289 + struct fd_chan *data;
3294 + printk("fd_init : channel type 'fd' must specify a file "
3299 + n = strtoul(str, &end, 0);
3300 + if((*end != '\0') || (end == str)){
3301 + printk("fd_init : couldn't parse file descriptor '%s'\n", str);
3304 + data = um_kmalloc(sizeof(*data));
3305 + if(data == NULL) return(NULL);
3306 + *data = ((struct fd_chan) { .fd = n,
3307 + .raw = opts->raw });
3311 +int fd_open(int input, int output, int primary, void *d, char **dev_out)
3313 + struct fd_chan *data = d;
3315 + if(data->raw && isatty(data->fd)){
3316 + tcgetattr(data->fd, &data->tt);
3319 + sprintf(data->str, "%d", data->fd);
3320 + *dev_out = data->str;
3324 +void fd_close(int fd, void *d)
3326 + struct fd_chan *data = d;
3328 + if(data->raw && isatty(fd)){
3329 + tcsetattr(fd, TCSAFLUSH, &data->tt);
3334 +int fd_console_write(int fd, const char *buf, int n, void *d)
3336 + struct fd_chan *data = d;
3338 + return(generic_console_write(fd, buf, n, &data->tt));
3341 +struct chan_ops fd_ops = {
3345 + .close = fd_close,
3346 + .read = generic_read,
3347 + .write = generic_write,
3348 + .console_write = fd_console_write,
3349 + .window_size = generic_window_size,
3350 + .free = generic_free,
3355 + * Overrides for Emacs so that we follow Linus's tabbing style.
3356 + * Emacs will notice this stuff at the end of the file and automatically
3357 + * adjust the settings for this buffer only. This must remain at the end
3359 + * ---------------------------------------------------------------------------
3360 + * Local variables:
3361 + * c-file-style: "linux"
3364 diff -Naur -X ../exclude-files orig/arch/um/drivers/harddog_kern.c um/arch/um/drivers/harddog_kern.c
3365 --- orig/arch/um/drivers/harddog_kern.c 1969-12-31 19:00:00.000000000 -0500
3366 +++ um/arch/um/drivers/harddog_kern.c 2003-10-21 03:26:06.000000000 -0400
3368 +/* UML hardware watchdog, shamelessly stolen from:
3370 + * SoftDog 0.05: A Software Watchdog Device
3372 + * (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
3373 + * http://www.redhat.com
3375 + * This program is free software; you can redistribute it and/or
3376 + * modify it under the terms of the GNU General Public License
3377 + * as published by the Free Software Foundation; either version
3378 + * 2 of the License, or (at your option) any later version.
3380 + * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
3381 + * warranty for any of this software. This material is provided
3382 + * "AS-IS" and at no charge.
3384 + * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
3386 + * Software only watchdog driver. Unlike its big brother the WDT501P
3387 + * driver this won't always recover a failed machine.
3389 + * 03/96: Angelo Haritsis <ah@doc.ic.ac.uk> :
3391 + * Added soft_margin; use upon insmod to change the timer delay.
3392 + * NB: uses same minor as wdt (WATCHDOG_MINOR); we could use separate
3395 + * 19980911 Alan Cox
3396 + * Made SMP safe for 2.3.x
3398 + * 20011127 Joel Becker (jlbec@evilplan.org>
3399 + * Added soft_noboot; Allows testing the softdog trigger without
3400 + * requiring a recompile.
3401 + * Added WDIOC_GETTIMEOUT and WDIOC_SETTIMOUT.
3404 +#include <linux/module.h>
3405 +#include <linux/config.h>
3406 +#include <linux/types.h>
3407 +#include <linux/kernel.h>
3408 +#include <linux/fs.h>
3409 +#include <linux/mm.h>
3410 +#include <linux/miscdevice.h>
3411 +#include <linux/watchdog.h>
3412 +#include <linux/reboot.h>
3413 +#include <linux/smp_lock.h>
3414 +#include <linux/init.h>
3415 +#include <asm/uaccess.h>
3416 +#include "helper.h"
3417 +#include "mconsole.h"
3419 +MODULE_LICENSE("GPL");
3421 +/* Locked by the BKL in harddog_open and harddog_release */
3422 +static int timer_alive;
3423 +static int harddog_in_fd = -1;
3424 +static int harddog_out_fd = -1;
3427 + * Allow only one person to hold it open
3430 +extern int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock);
3432 +static int harddog_open(struct inode *inode, struct file *file)
3435 + char *sock = NULL;
3440 +#ifdef CONFIG_HARDDOG_NOWAYOUT
3441 + MOD_INC_USE_COUNT;
3444 +#ifdef CONFIG_MCONSOLE
3445 + sock = mconsole_notify_socket();
3447 + err = start_watchdog(&harddog_in_fd, &harddog_out_fd, sock);
3448 + if(err) return(err);
3455 +extern void stop_watchdog(int in_fd, int out_fd);
3457 +static int harddog_release(struct inode *inode, struct file *file)
3460 + * Shut off the timer.
3464 + stop_watchdog(harddog_in_fd, harddog_out_fd);
3465 + harddog_in_fd = -1;
3466 + harddog_out_fd = -1;
3473 +extern int ping_watchdog(int fd);
3475 +static ssize_t harddog_write(struct file *file, const char *data, size_t len,
3478 + /* Can't seek (pwrite) on this device */
3479 + if (ppos != &file->f_pos)
3483 + * Refresh the timer.
3486 + return(ping_watchdog(harddog_out_fd));
3490 +static int harddog_ioctl(struct inode *inode, struct file *file,
3491 + unsigned int cmd, unsigned long arg)
3493 + static struct watchdog_info ident = {
3496 + "UML Hardware Watchdog"
3501 + case WDIOC_GETSUPPORT:
3502 + if(copy_to_user((struct harddog_info *)arg, &ident,
3506 + case WDIOC_GETSTATUS:
3507 + case WDIOC_GETBOOTSTATUS:
3508 + return put_user(0,(int *)arg);
3509 + case WDIOC_KEEPALIVE:
3510 + return(ping_watchdog(harddog_out_fd));
3514 +static struct file_operations harddog_fops = {
3515 + .owner = THIS_MODULE,
3516 + .write = harddog_write,
3517 + .ioctl = harddog_ioctl,
3518 + .open = harddog_open,
3519 + .release = harddog_release,
3522 +static struct miscdevice harddog_miscdev = {
3523 + .minor = WATCHDOG_MINOR,
3524 + .name = "watchdog",
3525 + .fops = &harddog_fops,
3528 +static char banner[] __initdata = KERN_INFO "UML Watchdog Timer\n";
3530 +static int __init harddog_init(void)
3534 + ret = misc_register(&harddog_miscdev);
3544 +static void __exit harddog_exit(void)
3546 + misc_deregister(&harddog_miscdev);
3549 +module_init(harddog_init);
3550 +module_exit(harddog_exit);
3553 + * Overrides for Emacs so that we follow Linus's tabbing style.
3554 + * Emacs will notice this stuff at the end of the file and automatically
3555 + * adjust the settings for this buffer only. This must remain at the end
3557 + * ---------------------------------------------------------------------------
3558 + * Local variables:
3559 + * c-file-style: "linux"
3562 diff -Naur -X ../exclude-files orig/arch/um/drivers/harddog_user.c um/arch/um/drivers/harddog_user.c
3563 --- orig/arch/um/drivers/harddog_user.c 1969-12-31 19:00:00.000000000 -0500
3564 +++ um/arch/um/drivers/harddog_user.c 2003-10-21 03:26:06.000000000 -0400
3567 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3568 + * Licensed under the GPL
3572 +#include <unistd.h>
3574 +#include "user_util.h"
3576 +#include "helper.h"
3577 +#include "mconsole.h"
3579 +#include "choose-mode.h"
3588 +static void pre_exec(void *d)
3590 + struct dog_data *data = d;
3592 + dup2(data->stdin, 0);
3593 + dup2(data->stdout, 1);
3594 + dup2(data->stdout, 2);
3595 + os_close_file(data->stdin);
3596 + os_close_file(data->stdout);
3597 + os_close_file(data->close_me[0]);
3598 + os_close_file(data->close_me[1]);
3601 +int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
3603 + struct dog_data data;
3604 + int in_fds[2], out_fds[2], pid, n, err;
3605 + char pid_buf[sizeof("nnnnn\0")], c;
3606 + char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL };
3607 + char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL,
3609 + char **args = NULL;
3611 + err = os_pipe(in_fds, 1, 0);
3613 + printk("harddog_open - os_pipe failed, err = %d\n", -err);
3617 + err = os_pipe(out_fds, 1, 0);
3619 + printk("harddog_open - os_pipe failed, err = %d\n", -err);
3620 + goto out_close_in;
3623 + data.stdin = out_fds[0];
3624 + data.stdout = in_fds[1];
3625 + data.close_me[0] = out_fds[1];
3626 + data.close_me[1] = in_fds[0];
3629 + mconsole_args[2] = sock;
3630 + args = mconsole_args;
3633 + /* XXX The os_getpid() is not SMP correct */
3634 + sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid()));
3638 + pid = run_helper(pre_exec, &data, args, NULL);
3640 + os_close_file(out_fds[0]);
3641 + os_close_file(in_fds[1]);
3645 + printk("harddog_open - run_helper failed, errno = %d\n", -err);
3646 + goto out_close_out;
3649 + n = os_read_file(in_fds[0], &c, sizeof(c));
3651 + printk("harddog_open - EOF on watchdog pipe\n");
3654 + goto out_close_out;
3657 + printk("harddog_open - read of watchdog pipe failed, "
3658 + "err = %d\n", -n);
3661 + goto out_close_out;
3663 + *in_fd_ret = in_fds[0];
3664 + *out_fd_ret = out_fds[1];
3668 + os_close_file(in_fds[0]);
3669 + os_close_file(in_fds[1]);
3671 + os_close_file(out_fds[0]);
3672 + os_close_file(out_fds[1]);
3677 +void stop_watchdog(int in_fd, int out_fd)
3679 + os_close_file(in_fd);
3680 + os_close_file(out_fd);
3683 +int ping_watchdog(int fd)
3688 + n = os_write_file(fd, &c, sizeof(c));
3689 + if(n != sizeof(c)){
3690 + printk("ping_watchdog - write failed, err = %d\n", -n);
3700 + * Overrides for Emacs so that we follow Linus's tabbing style.
3701 + * Emacs will notice this stuff at the end of the file and automatically
3702 + * adjust the settings for this buffer only. This must remain at the end
3704 + * ---------------------------------------------------------------------------
3705 + * Local variables:
3706 + * c-file-style: "linux"
3709 diff -Naur -X ../exclude-files orig/arch/um/drivers/hostaudio_kern.c um/arch/um/drivers/hostaudio_kern.c
3710 --- orig/arch/um/drivers/hostaudio_kern.c 1969-12-31 19:00:00.000000000 -0500
3711 +++ um/arch/um/drivers/hostaudio_kern.c 2003-11-10 00:04:23.000000000 -0500
3714 + * Copyright (C) 2002 Steve Schmidtke
3715 + * Licensed under the GPL
3718 +#include "linux/config.h"
3719 +#include "linux/module.h"
3720 +#include "linux/version.h"
3721 +#include "linux/init.h"
3722 +#include "linux/slab.h"
3723 +#include "linux/fs.h"
3724 +#include "linux/sound.h"
3725 +#include "linux/soundcard.h"
3726 +#include "asm/uaccess.h"
3727 +#include "kern_util.h"
3729 +#include "hostaudio.h"
3731 +/* Only changed from linux_main at boot time */
3732 +char *dsp = HOSTAUDIO_DEV_DSP;
3733 +char *mixer = HOSTAUDIO_DEV_MIXER;
3736 +" This is used to specify the host dsp device to the hostaudio driver.\n" \
3737 +" The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
3739 +#define MIXER_HELP \
3740 +" This is used to specify the host mixer device to the hostaudio driver.\n" \
3741 +" The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
3744 +static int set_dsp(char *name, int *add)
3750 +__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
3752 +static int set_mixer(char *name, int *add)
3758 +__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
3762 +MODULE_PARM(dsp, "s");
3763 +MODULE_PARM_DESC(dsp, DSP_HELP);
3765 +MODULE_PARM(mixer, "s");
3766 +MODULE_PARM_DESC(mixer, MIXER_HELP);
3770 +/* /dev/dsp file operations */
3772 +static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count,
3775 + struct hostaudio_state *state = file->private_data;
3780 + printk("hostaudio: read called, count = %d\n", count);
3783 + kbuf = kmalloc(count, GFP_KERNEL);
3787 + err = hostaudio_read_user(state, kbuf, count, ppos);
3791 + if(copy_to_user(buffer, kbuf, err))
3799 +static ssize_t hostaudio_write(struct file *file, const char *buffer,
3800 + size_t count, loff_t *ppos)
3802 + struct hostaudio_state *state = file->private_data;
3807 + printk("hostaudio: write called, count = %d\n", count);
3810 + kbuf = kmalloc(count, GFP_KERNEL);
3815 + if(copy_from_user(kbuf, buffer, count))
3818 + err = hostaudio_write_user(state, kbuf, count, ppos);
3827 +static unsigned int hostaudio_poll(struct file *file,
3828 + struct poll_table_struct *wait)
3830 + unsigned int mask = 0;
3833 + printk("hostaudio: poll called (unimplemented)\n");
3839 +static int hostaudio_ioctl(struct inode *inode, struct file *file,
3840 + unsigned int cmd, unsigned long arg)
3842 + struct hostaudio_state *state = file->private_data;
3843 + unsigned long data = 0;
3847 + printk("hostaudio: ioctl called, cmd = %u\n", cmd);
3850 + case SNDCTL_DSP_SPEED:
3851 + case SNDCTL_DSP_STEREO:
3852 + case SNDCTL_DSP_GETBLKSIZE:
3853 + case SNDCTL_DSP_CHANNELS:
3854 + case SNDCTL_DSP_SUBDIVIDE:
3855 + case SNDCTL_DSP_SETFRAGMENT:
3856 + if(get_user(data, (int *) arg))
3863 + err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
3866 + case SNDCTL_DSP_SPEED:
3867 + case SNDCTL_DSP_STEREO:
3868 + case SNDCTL_DSP_GETBLKSIZE:
3869 + case SNDCTL_DSP_CHANNELS:
3870 + case SNDCTL_DSP_SUBDIVIDE:
3871 + case SNDCTL_DSP_SETFRAGMENT:
3872 + if(put_user(data, (int *) arg))
3882 +static int hostaudio_open(struct inode *inode, struct file *file)
3884 + struct hostaudio_state *state;
3889 + printk("hostaudio: open called (host: %s)\n", dsp);
3892 + state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
3893 + if(state == NULL) return(-ENOMEM);
3895 + if(file->f_mode & FMODE_READ) r = 1;
3896 + if(file->f_mode & FMODE_WRITE) w = 1;
3898 + ret = hostaudio_open_user(state, r, w, dsp);
3904 + file->private_data = state;
3908 +static int hostaudio_release(struct inode *inode, struct file *file)
3910 + struct hostaudio_state *state = file->private_data;
3914 + printk("hostaudio: release called\n");
3917 + ret = hostaudio_release_user(state);
3923 +/* /dev/mixer file operations */
3925 +static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file,
3926 + unsigned int cmd, unsigned long arg)
3928 + struct hostmixer_state *state = file->private_data;
3931 + printk("hostmixer: ioctl called\n");
3934 + return(hostmixer_ioctl_mixdev_user(state, cmd, arg));
3937 +static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
3939 + struct hostmixer_state *state;
3944 + printk("hostmixer: open called (host: %s)\n", mixer);
3947 + state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL);
3948 + if(state == NULL) return(-ENOMEM);
3950 + if(file->f_mode & FMODE_READ) r = 1;
3951 + if(file->f_mode & FMODE_WRITE) w = 1;
3953 + ret = hostmixer_open_mixdev_user(state, r, w, mixer);
3960 + file->private_data = state;
3964 +static int hostmixer_release(struct inode *inode, struct file *file)
3966 + struct hostmixer_state *state = file->private_data;
3970 + printk("hostmixer: release called\n");
3973 + ret = hostmixer_release_mixdev_user(state);
3980 +/* kernel module operations */
3982 +static struct file_operations hostaudio_fops = {
3983 + .owner = THIS_MODULE,
3984 + .llseek = no_llseek,
3985 + .read = hostaudio_read,
3986 + .write = hostaudio_write,
3987 + .poll = hostaudio_poll,
3988 + .ioctl = hostaudio_ioctl,
3990 + .open = hostaudio_open,
3991 + .release = hostaudio_release,
3994 +static struct file_operations hostmixer_fops = {
3995 + .owner = THIS_MODULE,
3996 + .llseek = no_llseek,
3997 + .ioctl = hostmixer_ioctl_mixdev,
3998 + .open = hostmixer_open_mixdev,
3999 + .release = hostmixer_release,
4007 +MODULE_AUTHOR("Steve Schmidtke");
4008 +MODULE_DESCRIPTION("UML Audio Relay");
4009 +MODULE_LICENSE("GPL");
4011 +static int __init hostaudio_init_module(void)
4013 + printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
4016 + module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
4017 + if(module_data.dev_audio < 0){
4018 + printk(KERN_ERR "hostaudio: couldn't register DSP device!\n");
4022 + module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1);
4023 + if(module_data.dev_mixer < 0){
4024 + printk(KERN_ERR "hostmixer: couldn't register mixer "
4026 + unregister_sound_dsp(module_data.dev_audio);
4033 +static void __exit hostaudio_cleanup_module (void)
4035 + unregister_sound_mixer(module_data.dev_mixer);
4036 + unregister_sound_dsp(module_data.dev_audio);
4039 +module_init(hostaudio_init_module);
4040 +module_exit(hostaudio_cleanup_module);
4043 + * Overrides for Emacs so that we follow Linus's tabbing style.
4044 + * Emacs will notice this stuff at the end of the file and automatically
4045 + * adjust the settings for this buffer only. This must remain at the end
4047 + * ---------------------------------------------------------------------------
4048 + * Local variables:
4049 + * c-file-style: "linux"
4052 diff -Naur -X ../exclude-files orig/arch/um/drivers/hostaudio_user.c um/arch/um/drivers/hostaudio_user.c
4053 --- orig/arch/um/drivers/hostaudio_user.c 1969-12-31 19:00:00.000000000 -0500
4054 +++ um/arch/um/drivers/hostaudio_user.c 2003-10-21 03:26:06.000000000 -0400
4057 + * Copyright (C) 2002 Steve Schmidtke
4058 + * Licensed under the GPL
4061 +#include <sys/types.h>
4062 +#include <unistd.h>
4064 +#include "hostaudio.h"
4065 +#include "user_util.h"
4066 +#include "kern_util.h"
4070 +/* /dev/dsp file operations */
4072 +ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer,
4073 + size_t count, loff_t *ppos)
4076 + printk("hostaudio: read_user called, count = %d\n", count);
4079 + return(os_read_file(state->fd, buffer, count));
4082 +ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer,
4083 + size_t count, loff_t *ppos)
4088 + printk("hostaudio: write_user called, count = %d\n", count);
4091 + return(os_write_file(state->fd, buffer, count));
4096 +int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd,
4097 + unsigned long arg)
4100 + printk("hostaudio: ioctl_user called, cmd = %u\n", cmd);
4103 + return(os_ioctl_generic(state->fd, cmd, arg));
4106 +int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp)
4109 + printk("hostaudio: open_user called\n");
4112 + state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
4114 + if(state->fd < 0) {
4115 + printk("hostaudio_open_user failed to open '%s', err = %d\n",
4117 + return(state->fd);
4123 +int hostaudio_release_user(struct hostaudio_state *state)
4126 + printk("hostaudio: release called\n");
4128 + if(state->fd >= 0){
4129 + os_close_file(state->fd);
4136 +/* /dev/mixer file operations */
4138 +int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state,
4139 + unsigned int cmd, unsigned long arg)
4142 + printk("hostmixer: ioctl_user called cmd = %u\n",cmd);
4145 + return(os_ioctl_generic(state->fd, cmd, arg));
4148 +int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w,
4152 + printk("hostmixer: open_user called\n");
4155 + state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
4157 + if(state->fd < 0) {
4158 + printk("hostaudio_open_mixdev_user failed to open '%s', "
4159 + "err = %d\n", mixer, state->fd);
4160 + return(state->fd);
4166 +int hostmixer_release_mixdev_user(struct hostmixer_state *state)
4169 + printk("hostmixer: release_user called\n");
4172 + if(state->fd >= 0){
4173 + os_close_file(state->fd);
4181 + * Overrides for Emacs so that we follow Linus's tabbing style.
4182 + * Emacs will notice this stuff at the end of the file and automatically
4183 + * adjust the settings for this buffer only. This must remain at the end
4185 + * ---------------------------------------------------------------------------
4186 + * Local variables:
4187 + * c-file-style: "linux"
4190 diff -Naur -X ../exclude-files orig/arch/um/drivers/line.c um/arch/um/drivers/line.c
4191 --- orig/arch/um/drivers/line.c 1969-12-31 19:00:00.000000000 -0500
4192 +++ um/arch/um/drivers/line.c 2003-11-07 03:03:57.000000000 -0500
4195 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4196 + * Licensed under the GPL
4199 +#include "linux/sched.h"
4200 +#include "linux/slab.h"
4201 +#include "linux/list.h"
4202 +#include "linux/devfs_fs_kernel.h"
4203 +#include "asm/irq.h"
4204 +#include "asm/uaccess.h"
4205 +#include "chan_kern.h"
4206 +#include "irq_user.h"
4209 +#include "user_util.h"
4210 +#include "kern_util.h"
4212 +#include "irq_kern.h"
4214 +#define LINE_BUFSIZE 4096
4216 +static void line_interrupt(int irq, void *data, struct pt_regs *unused)
4218 + struct line *dev = data;
4220 + if(dev->count > 0)
4221 + chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq,
4225 +static void line_timer_cb(void *arg)
4227 + struct line *dev = arg;
4229 + line_interrupt(dev->driver->read_irq, dev, NULL);
4232 +static int write_room(struct line *dev)
4236 + if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
4238 + n = dev->head - dev->tail;
4239 + if(n <= 0) n = LINE_BUFSIZE + n;
4243 +static int buffer_data(struct line *line, const char *buf, int len)
4247 + if(line->buffer == NULL){
4248 + line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
4249 + if(line->buffer == NULL){
4250 + printk("buffer_data - atomic allocation failed\n");
4253 + line->head = line->buffer;
4254 + line->tail = line->buffer;
4257 + room = write_room(line);
4258 + len = (len > room) ? room : len;
4260 + end = line->buffer + LINE_BUFSIZE - line->tail;
4262 + memcpy(line->tail, buf, len);
4263 + line->tail += len;
4266 + memcpy(line->tail, buf, end);
4269 + memcpy(line->buffer, buf, len);
4270 + line->tail = line->buffer + len;
4276 +static int flush_buffer(struct line *line)
4280 + if((line->buffer == NULL) || (line->head == line->tail)) return(1);
4282 + if(line->tail < line->head){
4283 + count = line->buffer + LINE_BUFSIZE - line->head;
4284 + n = write_chan(&line->chan_list, line->head, count,
4285 + line->driver->write_irq);
4286 + if(n < 0) return(n);
4287 + if(n == count) line->head = line->buffer;
4294 + count = line->tail - line->head;
4295 + n = write_chan(&line->chan_list, line->head, count,
4296 + line->driver->write_irq);
4297 + if(n < 0) return(n);
4300 + return(line->head == line->tail);
4303 +int line_write(struct line *lines, struct tty_struct *tty, int from_user,
4304 + const char *buf, int len)
4306 + struct line *line;
4308 + unsigned long flags;
4309 + int n, err, i, ret = 0;
4311 + if(tty->stopped) return 0;
4314 + new = kmalloc(len, GFP_KERNEL);
4317 + n = copy_from_user(new, buf, len);
4327 + i = minor(tty->device) - tty->driver.minor_start;
4331 + if(line->head != line->tail){
4332 + local_irq_save(flags);
4333 + ret += buffer_data(line, buf, len);
4334 + err = flush_buffer(line);
4335 + local_irq_restore(flags);
4340 + n = write_chan(&line->chan_list, buf, len,
4341 + line->driver->write_irq);
4350 + ret += buffer_data(line, buf + n, len);
4361 +static void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
4363 + struct line *dev = data;
4364 + struct tty_struct *tty = dev->tty;
4367 + err = flush_buffer(dev);
4368 + if(err == 0) return;
4370 + dev->head = dev->buffer;
4371 + dev->tail = dev->buffer;
4374 + if(tty == NULL) return;
4376 + if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
4377 + (tty->ldisc.write_wakeup != NULL))
4378 + (tty->ldisc.write_wakeup)(tty);
4381 + * In blocking mode, everything sleeps on tty->write_wait.
4382 + * Sleeping in the console driver would break non-blocking
4386 + if (waitqueue_active(&tty->write_wait))
4387 + wake_up_interruptible(&tty->write_wait);
4391 +int line_setup_irq(int fd, int input, int output, void *data)
4393 + struct line *line = data;
4394 + struct line_driver *driver = line->driver;
4395 + int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
4397 + if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ,
4398 + line_interrupt, flags,
4399 + driver->read_irq_name, line);
4400 + if(err) return(err);
4401 + if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
4402 + line_write_interrupt, flags,
4403 + driver->write_irq_name, line);
4404 + line->have_irq = 1;
4408 +void line_disable(struct line *line, int current_irq)
4410 + if(!line->have_irq) return;
4412 + if(line->driver->read_irq == current_irq)
4413 + free_irq_later(line->driver->read_irq, line);
4415 + free_irq(line->driver->read_irq, line);
4417 + if(line->driver->write_irq == current_irq)
4418 + free_irq_later(line->driver->write_irq, line);
4420 + free_irq(line->driver->write_irq, line);
4422 + line->have_irq = 0;
4425 +int line_open(struct line *lines, struct tty_struct *tty,
4426 + struct chan_opts *opts)
4428 + struct line *line;
4431 + if(tty == NULL) n = 0;
4432 + else n = minor(tty->device) - tty->driver.minor_start;
4436 + if(line->count == 0){
4441 + if(list_empty(&line->chan_list)){
4442 + err = parse_chan_pair(line->init_str, &line->chan_list,
4443 + line->init_pri, n, opts);
4445 + err = open_chan(&line->chan_list);
4448 + enable_chan(&line->chan_list, line);
4449 + INIT_TQUEUE(&line->task, line_timer_cb, line);
4453 + chan_enable_winch(&line->chan_list, line);
4457 + /* This is outside the if because the initial console is opened
4458 + * with tty == NULL
4463 + tty->driver_data = line;
4464 + chan_window_size(&line->chan_list, &tty->winsize.ws_row,
4465 + &tty->winsize.ws_col);
4474 +void line_close(struct line *lines, struct tty_struct *tty)
4476 + struct line *line;
4479 + if(tty == NULL) n = 0;
4480 + else n = minor(tty->device) - tty->driver.minor_start;
4486 + /* I don't like this, but I can't think of anything better. What's
4487 + * going on is that the tty is in the process of being closed for
4488 + * the last time. Its count hasn't been dropped yet, so it's still
4489 + * at 1. This may happen when line->count != 0 because of the initial
4490 + * console open (without a tty) bumping it up to 1.
4492 + if((line->tty != NULL) && (line->tty->count == 1))
4494 + if(line->count == 0)
4495 + line_disable(line, -1);
4499 +void close_lines(struct line *lines, int nlines)
4503 + for(i = 0; i < nlines; i++)
4504 + close_chan(&lines[i].chan_list);
4507 +int line_setup(struct line *lines, int num, char *init, int all_allowed)
4512 + if(*init == '=') n = -1;
4514 + n = simple_strtoul(init, &end, 0);
4516 + printk(KERN_ERR "line_setup failed to parse \"%s\"\n",
4523 + if((n >= 0) && (n >= num)){
4524 + printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
4529 + if(lines[n].count > 0){
4530 + printk("line_setup - device %d is open\n", n);
4533 + if(lines[n].init_pri <= INIT_ONE){
4534 + lines[n].init_pri = INIT_ONE;
4535 + if(!strcmp(init, "none")) lines[n].valid = 0;
4537 + lines[n].init_str = init;
4538 + lines[n].valid = 1;
4542 + else if(!all_allowed){
4543 + printk("line_setup - can't configure all devices from "
4548 + for(i = 0; i < num; i++){
4549 + if(lines[i].init_pri <= INIT_ALL){
4550 + lines[i].init_pri = INIT_ALL;
4551 + if(!strcmp(init, "none")) lines[i].valid = 0;
4553 + lines[i].init_str = init;
4554 + lines[i].valid = 1;
4562 +int line_config(struct line *lines, int num, char *str)
4564 + char *new = uml_strdup(str);
4567 + printk("line_config - uml_strdup failed\n");
4570 + return(!line_setup(lines, num, new, 0));
4573 +int line_get_config(char *name, struct line *lines, int num, char *str,
4574 + int size, char **error_out)
4576 + struct line *line;
4580 + dev = simple_strtoul(name, &end, 0);
4581 + if((*end != '\0') || (end == name)){
4582 + *error_out = "line_get_config failed to parse device number";
4586 + if((dev < 0) || (dev >= num)){
4587 + *error_out = "device number of of range";
4591 + line = &lines[dev];
4595 + CONFIG_CHUNK(str, size, n, "none", 1);
4596 + else if(line->count == 0)
4597 + CONFIG_CHUNK(str, size, n, line->init_str, 1);
4598 + else n = chan_config_string(&line->chan_list, str, size, error_out);
4604 +int line_remove(struct line *lines, int num, char *str)
4606 + char config[sizeof("conxxxx=none\0")];
4608 + sprintf(config, "%s=none", str);
4609 + return(!line_setup(lines, num, config, 0));
4612 +static int line_write_room(struct tty_struct *tty)
4614 + struct line *dev = tty->driver_data;
4616 + return(write_room(dev));
4619 +void line_register_devfs(struct lines *set, struct line_driver *line_driver,
4620 + struct tty_driver *driver, struct line *lines,
4626 + driver->driver_name = line_driver->name;
4627 + driver->name = line_driver->devfs_name;
4628 + driver->major = line_driver->major;
4629 + driver->minor_start = line_driver->minor_start;
4630 + driver->type = line_driver->type;
4631 + driver->subtype = line_driver->subtype;
4632 + driver->magic = TTY_DRIVER_MAGIC;
4633 + driver->flags = TTY_DRIVER_REAL_RAW;
4637 + driver->table = kmalloc(n * sizeof(driver->table[0]), GFP_KERNEL);
4638 + driver->termios = kmalloc(n * sizeof(driver->termios[0]), GFP_KERNEL);
4639 + driver->termios_locked = kmalloc(n * sizeof(driver->termios_locked[0]),
4641 + if((driver->table == NULL) || (driver->termios == NULL) ||
4642 + (driver->termios_locked == NULL))
4643 + panic("Failed to allocate driver table");
4645 + memset(driver->table, 0, n * sizeof(driver->table[0]));
4646 + memset(driver->termios, 0, n * sizeof(driver->termios[0]));
4647 + memset(driver->termios_locked, 0,
4648 + n * sizeof(driver->termios_locked[0]));
4650 + driver->write_room = line_write_room;
4651 + driver->init_termios = tty_std_termios;
4653 + if (tty_register_driver(driver))
4654 + panic("line_register_devfs : Couldn't register driver\n");
4656 + from = line_driver->symlink_from;
4657 + to = line_driver->symlink_to;
4658 + err = devfs_mk_symlink(NULL, from, 0, to, NULL, NULL);
4659 + if(err) printk("Symlink creation from /dev/%s to /dev/%s "
4660 + "returned %d\n", from, to, err);
4662 + for(i = 0; i < nlines; i++){
4663 + if(!lines[i].valid)
4664 + tty_unregister_devfs(driver, driver->minor_start + i);
4667 + mconsole_register_dev(&line_driver->mc);
4670 +void lines_init(struct line *lines, int nlines)
4672 + struct line *line;
4675 + for(i = 0; i < nlines; i++){
4677 + INIT_LIST_HEAD(&line->chan_list);
4678 + sema_init(&line->sem, 1);
4679 + if(line->init_str != NULL){
4680 + line->init_str = uml_strdup(line->init_str);
4681 + if(line->init_str == NULL)
4682 + printk("lines_init - uml_strdup returned "
4689 + struct list_head list;
4693 + struct line *line;
4696 +void winch_interrupt(int irq, void *data, struct pt_regs *unused)
4698 + struct winch *winch = data;
4699 + struct tty_struct *tty;
4703 + if(winch->fd != -1){
4704 + err = generic_read(winch->fd, &c, NULL);
4706 + if(err != -EAGAIN){
4707 + printk("winch_interrupt : read failed, "
4708 + "errno = %d\n", -err);
4709 + printk("fd %d is losing SIGWINCH support\n",
4716 + tty = winch->line->tty;
4718 + chan_window_size(&winch->line->chan_list,
4719 + &tty->winsize.ws_row,
4720 + &tty->winsize.ws_col);
4721 + kill_pg(tty->pgrp, SIGWINCH, 1);
4724 + if(winch->fd != -1)
4725 + reactivate_fd(winch->fd, WINCH_IRQ);
4728 +DECLARE_MUTEX(winch_handler_sem);
4729 +LIST_HEAD(winch_handlers);
4731 +void register_winch_irq(int fd, int tty_fd, int pid, void *line)
4733 + struct winch *winch;
4735 + down(&winch_handler_sem);
4736 + winch = kmalloc(sizeof(*winch), GFP_KERNEL);
4737 + if(winch == NULL){
4738 + printk("register_winch_irq - kmalloc failed\n");
4741 + *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list),
4746 + list_add(&winch->list, &winch_handlers);
4747 + if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
4748 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
4749 + "winch", winch) < 0)
4750 + printk("register_winch_irq - failed to register IRQ\n");
4752 + up(&winch_handler_sem);
4755 +static void winch_cleanup(void)
4757 + struct list_head *ele;
4758 + struct winch *winch;
4760 + list_for_each(ele, &winch_handlers){
4761 + winch = list_entry(ele, struct winch, list);
4762 + if(winch->fd != -1){
4763 + deactivate_fd(winch->fd, WINCH_IRQ);
4764 + os_close_file(winch->fd);
4766 + if(winch->pid != -1)
4767 + os_kill_process(winch->pid, 1);
4771 +__uml_exitcall(winch_cleanup);
4773 +char *add_xterm_umid(char *base)
4775 + char *umid, *title;
4778 + umid = get_umid(1);
4779 + if(umid == NULL) return(base);
4781 + len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
4782 + title = kmalloc(len, GFP_KERNEL);
4783 + if(title == NULL){
4784 + printk("Failed to allocate buffer for xterm title\n");
4788 + strncpy(title, base, len);
4789 + len -= strlen(title);
4790 + snprintf(&title[strlen(title)], len, " (%s)", umid);
4795 + * Overrides for Emacs so that we follow Linus's tabbing style.
4796 + * Emacs will notice this stuff at the end of the file and automatically
4797 + * adjust the settings for this buffer only. This must remain at the end
4799 + * ---------------------------------------------------------------------------
4800 + * Local variables:
4801 + * c-file-style: "linux"
4804 diff -Naur -X ../exclude-files orig/arch/um/drivers/Makefile um/arch/um/drivers/Makefile
4805 --- orig/arch/um/drivers/Makefile 1969-12-31 19:00:00.000000000 -0500
4806 +++ um/arch/um/drivers/Makefile 2003-11-08 09:58:54.000000000 -0500
4809 +# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
4810 +# Licensed under the GPL
4813 +O_TARGET := built-in.o
4815 +CHAN_OBJS := chan_kern.o chan_user.o line.o
4817 +list-multi := slip.o slirp.o daemon.o mcast.o mconsole.o net.o ubd.o \
4818 + hostaudio.o pcap.o port.o harddog.o
4820 +slip-objs := slip_kern.o slip_user.o
4821 +slirp-objs := slirp_kern.o slirp_user.o
4822 +daemon-objs := daemon_kern.o daemon_user.o
4823 +mcast-objs := mcast_kern.o mcast_user.o
4824 +pcap-objs := pcap_kern.o pcap_user.o
4825 +pcap-libs := -lpcap -L/usr/lib
4826 +net-objs := net_kern.o net_user.o
4827 +mconsole-objs := mconsole_kern.o mconsole_user.o
4828 +hostaudio-objs := hostaudio_kern.o hostaudio_user.o
4829 +ubd-objs := ubd_kern.o ubd_user.o
4830 +port-objs := port_kern.o port_user.o
4831 +harddog-objs := harddog_kern.o harddog_user.o
4833 +export-objs := mconsole_kern.o
4836 +obj-$(CONFIG_SSL) += ssl.o
4837 +obj-$(CONFIG_UML_NET_SLIP) += slip.o
4838 +obj-$(CONFIG_UML_NET_SLIRP) += slirp.o
4839 +obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
4840 +obj-$(CONFIG_UML_NET_MCAST) += mcast.o
4841 +obj-$(CONFIG_UML_NET_PCAP) += pcap.o
4842 +obj-$(CONFIG_UML_NET) += net.o
4843 +obj-$(CONFIG_MCONSOLE) += mconsole.o
4844 +obj-$(CONFIG_MMAPPER) += mmapper_kern.o
4845 +obj-$(CONFIG_BLK_DEV_UBD) += ubd.o
4846 +obj-$(CONFIG_HOSTAUDIO) += hostaudio.o
4847 +obj-$(CONFIG_FD_CHAN) += fd.o
4848 +obj-$(CONFIG_NULL_CHAN) += null.o
4849 +obj-$(CONFIG_PORT_CHAN) += port.o
4850 +obj-$(CONFIG_PTY_CHAN) += pty.o
4851 +obj-$(CONFIG_TTY_CHAN) += tty.o
4852 +obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
4853 +obj-$(CONFIG_UML_WATCHDOG) += harddog.o
4854 +obj-$(CONFIG_COW) += cow_kern.o
4855 +obj-$(CONFIG_COW_COMMON) += cow_user.o
4857 +CFLAGS_pcap_user.o = -I/usr/include/pcap
4859 +obj-y += stdio_console.o $(CHAN_OBJS)
4861 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
4863 +USER_OBJS = $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
4864 + null.o pty.o tty.o xterm.o
4866 +include $(TOPDIR)/Rules.make
4868 +$(USER_OBJS) : %.o: %.c
4869 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
4881 +daemon.o : $(daemon-objs)
4883 +slip.o : $(slip-objs)
4885 +slirp.o : $(slirp-objs)
4887 +mcast.o : $(mcast-objs)
4889 +pcap.o : $(pcap-objs)
4891 +mconsole.o : $(mconsole-objs)
4893 +net.o : $(net-objs)
4895 +hostaudio.o : $(hostaudio-objs)
4897 +ubd.o : $(ubd-objs)
4899 +port.o : $(port-objs)
4901 +harddog.o : $(harddog-objs)
4903 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
4904 + $(LD) -r -o $@ $($(patsubst %.o,%,$@)-objs) $($(patsubst %.o,%,$@)-libs)
4905 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast.h um/arch/um/drivers/mcast.h
4906 --- orig/arch/um/drivers/mcast.h 1969-12-31 19:00:00.000000000 -0500
4907 +++ um/arch/um/drivers/mcast.h 2003-10-21 03:26:06.000000000 -0400
4910 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
4911 + * Licensed under the GPL
4914 +#include "net_user.h"
4916 +struct mcast_data {
4918 + unsigned short port;
4924 +extern struct net_user_info mcast_user_info;
4926 +extern int mcast_user_write(int fd, void *buf, int len,
4927 + struct mcast_data *pri);
4930 + * Overrides for Emacs so that we follow Linus's tabbing style.
4931 + * Emacs will notice this stuff at the end of the file and automatically
4932 + * adjust the settings for this buffer only. This must remain at the end
4934 + * ---------------------------------------------------------------------------
4935 + * Local variables:
4936 + * c-file-style: "linux"
4939 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_kern.c um/arch/um/drivers/mcast_kern.c
4940 --- orig/arch/um/drivers/mcast_kern.c 1969-12-31 19:00:00.000000000 -0500
4941 +++ um/arch/um/drivers/mcast_kern.c 2003-10-21 03:26:06.000000000 -0400
4944 + * user-mode-linux networking multicast transport
4945 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4947 + * based on the existing uml-networking code, which is
4948 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
4949 + * James Leu (jleu@mindspring.net).
4950 + * Copyright (C) 2001 by various other people who didn't put their name here.
4952 + * Licensed under the GPL.
4955 +#include "linux/kernel.h"
4956 +#include "linux/init.h"
4957 +#include "linux/netdevice.h"
4958 +#include "linux/etherdevice.h"
4959 +#include "linux/in.h"
4960 +#include "linux/inet.h"
4961 +#include "net_kern.h"
4962 +#include "net_user.h"
4965 +struct mcast_init {
4971 +void mcast_init(struct net_device *dev, void *data)
4973 + struct uml_net_private *pri;
4974 + struct mcast_data *dpri;
4975 + struct mcast_init *init = data;
4977 + init_etherdev(dev, 0);
4979 + dpri = (struct mcast_data *) pri->user;
4980 + *dpri = ((struct mcast_data)
4981 + { .addr = init->addr,
4982 + .port = init->port,
4984 + .mcast_addr = NULL,
4986 + printk("mcast backend ");
4987 + printk("multicast adddress: %s:%u, TTL:%u ",
4988 + dpri->addr, dpri->port, dpri->ttl);
4993 +static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
4995 + *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
4996 + if(*skb == NULL) return(-ENOMEM);
4997 + return(net_recvfrom(fd, (*skb)->mac.raw,
4998 + (*skb)->dev->mtu + ETH_HEADER_OTHER));
5001 +static int mcast_write(int fd, struct sk_buff **skb,
5002 + struct uml_net_private *lp)
5004 + return mcast_user_write(fd, (*skb)->data, (*skb)->len,
5005 + (struct mcast_data *) &lp->user);
5008 +static struct net_kern_info mcast_kern_info = {
5009 + .init = mcast_init,
5010 + .protocol = eth_protocol,
5011 + .read = mcast_read,
5012 + .write = mcast_write,
5015 +int mcast_setup(char *str, char **mac_out, void *data)
5017 + struct mcast_init *init = data;
5018 + char *port_str = NULL, *ttl_str = NULL, *remain;
5022 + *init = ((struct mcast_init)
5023 + { .addr = "239.192.168.1",
5027 + remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
5029 + if(remain != NULL){
5030 + printk(KERN_ERR "mcast_setup - Extra garbage on "
5031 + "specification : '%s'\n", remain);
5035 + if(port_str != NULL){
5036 + n = simple_strtoul(port_str, &last, 10);
5037 + if((*last != '\0') || (last == port_str)){
5038 + printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
5042 + init->port = htons(n);
5045 + if(ttl_str != NULL){
5046 + init->ttl = simple_strtoul(ttl_str, &last, 10);
5047 + if((*last != '\0') || (last == ttl_str)){
5048 + printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
5054 + printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
5055 + init->port, init->ttl);
5060 +static struct transport mcast_transport = {
5061 + .list = LIST_HEAD_INIT(mcast_transport.list),
5063 + .setup = mcast_setup,
5064 + .user = &mcast_user_info,
5065 + .kern = &mcast_kern_info,
5066 + .private_size = sizeof(struct mcast_data),
5067 + .setup_size = sizeof(struct mcast_init),
5070 +static int register_mcast(void)
5072 + register_transport(&mcast_transport);
5076 +__initcall(register_mcast);
5079 + * Overrides for Emacs so that we follow Linus's tabbing style.
5080 + * Emacs will notice this stuff at the end of the file and automatically
5081 + * adjust the settings for this buffer only. This must remain at the end
5083 + * ---------------------------------------------------------------------------
5084 + * Local variables:
5085 + * c-file-style: "linux"
5088 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_user.c um/arch/um/drivers/mcast_user.c
5089 --- orig/arch/um/drivers/mcast_user.c 1969-12-31 19:00:00.000000000 -0500
5090 +++ um/arch/um/drivers/mcast_user.c 2003-10-21 03:26:06.000000000 -0400
5093 + * user-mode-linux networking multicast transport
5094 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
5096 + * based on the existing uml-networking code, which is
5097 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
5098 + * James Leu (jleu@mindspring.net).
5099 + * Copyright (C) 2001 by various other people who didn't put their name here.
5101 + * Licensed under the GPL.
5106 +#include <unistd.h>
5107 +#include <linux/inet.h>
5108 +#include <sys/socket.h>
5109 +#include <sys/un.h>
5110 +#include <sys/time.h>
5111 +#include <netinet/in.h>
5112 +#include "net_user.h"
5114 +#include "kern_util.h"
5115 +#include "user_util.h"
5119 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
5121 +static struct sockaddr_in *new_addr(char *addr, unsigned short port)
5123 + struct sockaddr_in *sin;
5125 + sin = um_kmalloc(sizeof(struct sockaddr_in));
5127 + printk("new_addr: allocation of sockaddr_in failed\n");
5130 + sin->sin_family = AF_INET;
5131 + sin->sin_addr.s_addr = in_aton(addr);
5132 + sin->sin_port = port;
5136 +static void mcast_user_init(void *data, void *dev)
5138 + struct mcast_data *pri = data;
5140 + pri->mcast_addr = new_addr(pri->addr, pri->port);
5144 +static int mcast_open(void *data)
5146 + struct mcast_data *pri = data;
5147 + struct sockaddr_in *sin = pri->mcast_addr;
5148 + struct ip_mreq mreq;
5152 + if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) {
5157 + fd = socket(AF_INET, SOCK_DGRAM, 0);
5159 + printk("mcast_open : data socket failed, errno = %d\n",
5165 + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
5166 + printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
5168 + os_close_file(fd);
5173 + /* set ttl according to config */
5174 + if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
5175 + sizeof(pri->ttl)) < 0) {
5176 + printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
5178 + os_close_file(fd);
5183 + /* set LOOP, so data does get fed back to local sockets */
5184 + if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
5185 + printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
5187 + os_close_file(fd);
5192 + /* bind socket to mcast address */
5193 + if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
5194 + printk("mcast_open : data bind failed, errno = %d\n", errno);
5195 + os_close_file(fd);
5200 + /* subscribe to the multicast group */
5201 + mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
5202 + mreq.imr_interface.s_addr = 0;
5203 + if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
5204 + &mreq, sizeof(mreq)) < 0) {
5205 + printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n",
5207 + printk("There appears not to be a multicast-capable network "
5208 + "interface on the host.\n");
5209 + printk("eth0 should be configured in order to use the "
5210 + "multicast transport.\n");
5211 + os_close_file(fd);
5219 +static void mcast_close(int fd, void *data)
5221 + struct ip_mreq mreq;
5222 + struct mcast_data *pri = data;
5223 + struct sockaddr_in *sin = pri->mcast_addr;
5225 + mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
5226 + mreq.imr_interface.s_addr = 0;
5227 + if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
5228 + &mreq, sizeof(mreq)) < 0) {
5229 + printk("mcast_open: IP_DROP_MEMBERSHIP failed, error = %d\n",
5233 + os_close_file(fd);
5236 +int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
5238 + struct sockaddr_in *data_addr = pri->mcast_addr;
5240 + return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
5243 +static int mcast_set_mtu(int mtu, void *data)
5248 +struct net_user_info mcast_user_info = {
5249 + .init = mcast_user_init,
5250 + .open = mcast_open,
5251 + .close = mcast_close,
5253 + .set_mtu = mcast_set_mtu,
5254 + .add_address = NULL,
5255 + .delete_address = NULL,
5256 + .max_packet = MAX_PACKET - ETH_HEADER_OTHER
5260 + * Overrides for Emacs so that we follow Linus's tabbing style.
5261 + * Emacs will notice this stuff at the end of the file and automatically
5262 + * adjust the settings for this buffer only. This must remain at the end
5264 + * ---------------------------------------------------------------------------
5265 + * Local variables:
5266 + * c-file-style: "linux"
5269 diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_kern.c um/arch/um/drivers/mconsole_kern.c
5270 --- orig/arch/um/drivers/mconsole_kern.c 1969-12-31 19:00:00.000000000 -0500
5271 +++ um/arch/um/drivers/mconsole_kern.c 2003-10-21 03:26:06.000000000 -0400
5274 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
5275 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
5276 + * Licensed under the GPL
5279 +#include "linux/kernel.h"
5280 +#include "linux/slab.h"
5281 +#include "linux/init.h"
5282 +#include "linux/notifier.h"
5283 +#include "linux/reboot.h"
5284 +#include "linux/utsname.h"
5285 +#include "linux/ctype.h"
5286 +#include "linux/interrupt.h"
5287 +#include "linux/sysrq.h"
5288 +#include "linux/tqueue.h"
5289 +#include "linux/module.h"
5290 +#include "linux/file.h"
5291 +#include "linux/fs.h"
5292 +#include "linux/proc_fs.h"
5293 +#include "asm/irq.h"
5294 +#include "asm/uaccess.h"
5295 +#include "user_util.h"
5296 +#include "kern_util.h"
5298 +#include "mconsole.h"
5299 +#include "mconsole_kern.h"
5300 +#include "irq_user.h"
5304 +#include "irq_kern.h"
5306 +static int do_unlink_socket(struct notifier_block *notifier,
5307 + unsigned long what, void *data)
5309 + return(mconsole_unlink_socket());
5313 +static struct notifier_block reboot_notifier = {
5314 + .notifier_call = do_unlink_socket,
5318 +/* Safe without explicit locking for now. Tasklets provide their own
5319 + * locking, and the interrupt handler is safe because it can't interrupt
5320 + * itself and it can only happen on CPU 0.
5323 +LIST_HEAD(mc_requests);
5325 +void mc_task_proc(void *unused)
5327 + struct mconsole_entry *req;
5328 + unsigned long flags;
5332 + save_flags(flags);
5333 + req = list_entry(mc_requests.next, struct mconsole_entry,
5335 + list_del(&req->list);
5336 + done = list_empty(&mc_requests);
5337 + restore_flags(flags);
5338 + req->request.cmd->handler(&req->request);
5343 +struct tq_struct mconsole_task = {
5344 + .routine = mc_task_proc,
5348 +void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
5351 + struct mconsole_entry *new;
5352 + struct mc_request req;
5354 + fd = (int) dev_id;
5355 + while (mconsole_get_request(fd, &req)){
5356 + if(req.cmd->context == MCONSOLE_INTR)
5357 + (*req.cmd->handler)(&req);
5359 + new = kmalloc(sizeof(*new), GFP_ATOMIC);
5361 + mconsole_reply(&req, "Out of memory", 1, 0);
5363 + new->request = req;
5364 + list_add(&new->list, &mc_requests);
5368 + if(!list_empty(&mc_requests)) schedule_task(&mconsole_task);
5369 + reactivate_fd(fd, MCONSOLE_IRQ);
5372 +void mconsole_version(struct mc_request *req)
5374 + char version[256];
5376 + sprintf(version, "%s %s %s %s %s", system_utsname.sysname,
5377 + system_utsname.nodename, system_utsname.release,
5378 + system_utsname.version, system_utsname.machine);
5379 + mconsole_reply(req, version, 0, 0);
5382 +void mconsole_log(struct mc_request *req)
5385 + char *ptr = req->request.data;
5387 + ptr += strlen("log");
5388 + while(isspace(*ptr)) ptr++;
5390 + len = req->len - (ptr - req->request.data);
5391 + printk("%.*s", len, ptr);
5392 + mconsole_reply(req, "", 0, 0);
5395 +void mconsole_proc(struct mc_request *req)
5397 + struct nameidata nd;
5398 + struct file_system_type *proc;
5399 + struct super_block *super;
5400 + struct file *file;
5402 + char *ptr = req->request.data, *buf;
5404 + ptr += strlen("proc");
5405 + while(isspace(*ptr)) ptr++;
5407 + proc = get_fs_type("proc");
5409 + mconsole_reply(req, "procfs not registered", 1, 0);
5413 + super = get_anon_super(proc, NULL, NULL);
5414 + if(super == NULL){
5415 + mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
5419 + if(super->s_root == NULL){
5420 + super = (*proc->read_super)(super, NULL, 0);
5421 + if(super == NULL){
5422 + mconsole_reply(req, "Failed to read superblock", 1, 0);
5426 + up_write(&super->s_umount);
5428 + nd.dentry = super->s_root;
5430 + nd.flags = O_RDONLY + 1;
5431 + nd.last_type = LAST_ROOT;
5433 + err = link_path_walk(ptr, &nd);
5435 + mconsole_reply(req, "Failed to look up file", 1, 0);
5439 + file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
5441 + mconsole_reply(req, "Failed to open file", 1, 0);
5445 + buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
5447 + mconsole_reply(req, "Failed to allocate buffer", 1, 0);
5451 + if((file->f_op != NULL) && (file->f_op->read != NULL)){
5453 + n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1,
5457 + mconsole_reply(req, buf, 0, (n > 0));
5460 + mconsole_reply(req, "Read of file failed",
5466 + else mconsole_reply(req, "", 0, 0);
5473 + kill_super(super);
5475 + /* put_filesystem(proc); */
5479 +#define UML_MCONSOLE_HELPTEXT \
5481 + version - Get kernel version \n\
5482 + help - Print this message \n\
5483 + halt - Halt UML \n\
5484 + reboot - Reboot UML \n\
5485 + config <dev>=<config> - Add a new device to UML; \n\
5486 + same syntax as command line \n\
5487 + config <dev> - Query the configuration of a device \n\
5488 + remove <dev> - Remove a device from UML \n\
5489 + sysrq <letter> - Performs the SysRq action controlled by the letter \n\
5490 + cad - invoke the Ctl-Alt-Del handler \n\
5491 + stop - pause the UML; it will do nothing until it receives a 'go' \n\
5492 + go - continue the UML after a 'stop' \n\
5493 + log <string> - make UML enter <string> into the kernel log\n\
5494 + proc <file> - returns the contents of the UML's /proc/<file>\n\
5497 +void mconsole_help(struct mc_request *req)
5499 + mconsole_reply(req, UML_MCONSOLE_HELPTEXT, 0, 0);
5502 +void mconsole_halt(struct mc_request *req)
5504 + mconsole_reply(req, "", 0, 0);
5508 +void mconsole_reboot(struct mc_request *req)
5510 + mconsole_reply(req, "", 0, 0);
5511 + machine_restart(NULL);
5514 +extern void ctrl_alt_del(void);
5516 +void mconsole_cad(struct mc_request *req)
5518 + mconsole_reply(req, "", 0, 0);
5522 +void mconsole_go(struct mc_request *req)
5524 + mconsole_reply(req, "Not stopped", 1, 0);
5527 +void mconsole_stop(struct mc_request *req)
5529 + deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
5530 + os_set_fd_block(req->originating_fd, 1);
5531 + mconsole_reply(req, "", 0, 0);
5532 + while(mconsole_get_request(req->originating_fd, req)){
5533 + if(req->cmd->handler == mconsole_go) break;
5534 + (*req->cmd->handler)(req);
5536 + os_set_fd_block(req->originating_fd, 0);
5537 + reactivate_fd(req->originating_fd, MCONSOLE_IRQ);
5538 + mconsole_reply(req, "", 0, 0);
5541 +/* This list is populated by __initcall routines. */
5543 +LIST_HEAD(mconsole_devices);
5545 +void mconsole_register_dev(struct mc_device *new)
5547 + list_add(&new->list, &mconsole_devices);
5550 +static struct mc_device *mconsole_find_dev(char *name)
5552 + struct list_head *ele;
5553 + struct mc_device *dev;
5555 + list_for_each(ele, &mconsole_devices){
5556 + dev = list_entry(ele, struct mc_device, list);
5557 + if(!strncmp(name, dev->name, strlen(dev->name)))
5563 +#define CONFIG_BUF_SIZE 64
5565 +static void mconsole_get_config(int (*get_config)(char *, char *, int,
5567 + struct mc_request *req, char *name)
5569 + char default_buf[CONFIG_BUF_SIZE], *error, *buf;
5572 + if(get_config == NULL){
5573 + mconsole_reply(req, "No get_config routine defined", 1, 0);
5578 + size = sizeof(default_buf)/sizeof(default_buf[0]);
5579 + buf = default_buf;
5582 + n = (*get_config)(name, buf, size, &error);
5583 + if(error != NULL){
5584 + mconsole_reply(req, error, 1, 0);
5589 + mconsole_reply(req, buf, 0, 0);
5593 + if(buf != default_buf)
5597 + buf = kmalloc(size, GFP_KERNEL);
5599 + mconsole_reply(req, "Failed to allocate buffer", 1, 0);
5604 + if(buf != default_buf)
5609 +void mconsole_config(struct mc_request *req)
5611 + struct mc_device *dev;
5612 + char *ptr = req->request.data, *name;
5615 + ptr += strlen("config");
5616 + while(isspace(*ptr)) ptr++;
5617 + dev = mconsole_find_dev(ptr);
5619 + mconsole_reply(req, "Bad configuration option", 1, 0);
5623 + name = &ptr[strlen(dev->name)];
5625 + while((*ptr != '=') && (*ptr != '\0'))
5629 + err = (*dev->config)(name);
5630 + mconsole_reply(req, "", err, 0);
5632 + else mconsole_get_config(dev->get_config, req, name);
5635 +void mconsole_remove(struct mc_request *req)
5637 + struct mc_device *dev;
5638 + char *ptr = req->request.data;
5641 + ptr += strlen("remove");
5642 + while(isspace(*ptr)) ptr++;
5643 + dev = mconsole_find_dev(ptr);
5645 + mconsole_reply(req, "Bad remove option", 1, 0);
5648 + err = (*dev->remove)(&ptr[strlen(dev->name)]);
5649 + mconsole_reply(req, "", err, 0);
5652 +#ifdef CONFIG_MAGIC_SYSRQ
5653 +void mconsole_sysrq(struct mc_request *req)
5655 + char *ptr = req->request.data;
5657 + ptr += strlen("sysrq");
5658 + while(isspace(*ptr)) ptr++;
5660 + handle_sysrq(*ptr, ¤t->thread.regs, NULL, NULL);
5661 + mconsole_reply(req, "", 0, 0);
5664 +void mconsole_sysrq(struct mc_request *req)
5666 + mconsole_reply(req, "Sysrq not compiled in", 1, 0);
5670 +/* Changed by mconsole_setup, which is __setup, and called before SMP is
5673 +static char *notify_socket = NULL;
5675 +int mconsole_init(void)
5680 + if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
5681 + snprintf(mconsole_socket_name, sizeof(file), "%s", file);
5683 + sock = os_create_unix_socket(file, sizeof(file), 1);
5685 + printk("Failed to initialize management console\n");
5689 + register_reboot_notifier(&reboot_notifier);
5691 + err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
5692 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
5693 + "mconsole", (void *)sock);
5695 + printk("Failed to get IRQ for management console\n");
5699 + if(notify_socket != NULL){
5700 + notify_socket = uml_strdup(notify_socket);
5701 + if(notify_socket != NULL)
5702 + mconsole_notify(notify_socket, MCONSOLE_SOCKET,
5703 + mconsole_socket_name,
5704 + strlen(mconsole_socket_name) + 1);
5705 + else printk(KERN_ERR "mconsole_setup failed to strdup "
5709 + printk("mconsole (version %d) initialized on %s\n",
5710 + MCONSOLE_VERSION, mconsole_socket_name);
5714 +__initcall(mconsole_init);
5716 +static int write_proc_mconsole(struct file *file, const char *buffer,
5717 + unsigned long count, void *data)
5721 + buf = kmalloc(count + 1, GFP_KERNEL);
5725 + if(copy_from_user(buf, buffer, count)){
5730 + buf[count] = '\0';
5732 + mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
5738 +static int create_proc_mconsole(void)
5740 + struct proc_dir_entry *ent;
5742 + if(notify_socket == NULL) return(0);
5744 + ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
5746 + printk("create_proc_mconsole : create_proc_entry failed\n");
5750 + ent->read_proc = NULL;
5751 + ent->write_proc = write_proc_mconsole;
5755 +static spinlock_t notify_spinlock = SPIN_LOCK_UNLOCKED;
5757 +void lock_notify(void)
5759 + spin_lock(¬ify_spinlock);
5762 +void unlock_notify(void)
5764 + spin_unlock(¬ify_spinlock);
5767 +__initcall(create_proc_mconsole);
5769 +#define NOTIFY "=notify:"
5771 +static int mconsole_setup(char *str)
5773 + if(!strncmp(str, NOTIFY, strlen(NOTIFY))){
5774 + str += strlen(NOTIFY);
5775 + notify_socket = str;
5777 + else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str);
5781 +__setup("mconsole", mconsole_setup);
5783 +__uml_help(mconsole_setup,
5784 +"mconsole=notify:<socket>\n"
5785 +" Requests that the mconsole driver send a message to the named Unix\n"
5786 +" socket containing the name of the mconsole socket. This also serves\n"
5787 +" to notify outside processes when UML has booted far enough to respond\n"
5788 +" to mconsole requests.\n\n"
5791 +static int notify_panic(struct notifier_block *self, unsigned long unused1,
5794 + char *message = ptr;
5796 + if(notify_socket == NULL) return(0);
5798 + mconsole_notify(notify_socket, MCONSOLE_PANIC, message,
5799 + strlen(message) + 1);
5803 +static struct notifier_block panic_exit_notifier = {
5804 + .notifier_call = notify_panic,
5809 +static int add_notifier(void)
5811 + notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
5815 +__initcall(add_notifier);
5817 +char *mconsole_notify_socket(void)
5819 + return(notify_socket);
5822 +EXPORT_SYMBOL(mconsole_notify_socket);
5825 + * Overrides for Emacs so that we follow Linus's tabbing style.
5826 + * Emacs will notice this stuff at the end of the file and automatically
5827 + * adjust the settings for this buffer only. This must remain at the end
5829 + * ---------------------------------------------------------------------------
5830 + * Local variables:
5831 + * c-file-style: "linux"
5834 diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_user.c um/arch/um/drivers/mconsole_user.c
5835 --- orig/arch/um/drivers/mconsole_user.c 1969-12-31 19:00:00.000000000 -0500
5836 +++ um/arch/um/drivers/mconsole_user.c 2003-10-21 03:26:06.000000000 -0400
5839 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
5840 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
5841 + * Licensed under the GPL
5845 +#include <stdlib.h>
5847 +#include <signal.h>
5848 +#include <sys/socket.h>
5849 +#include <sys/types.h>
5850 +#include <sys/uio.h>
5851 +#include <sys/un.h>
5852 +#include <unistd.h>
5854 +#include "mconsole.h"
5857 +static struct mconsole_command commands[] = {
5858 + { "version", mconsole_version, MCONSOLE_INTR },
5859 + { "halt", mconsole_halt, MCONSOLE_PROC },
5860 + { "reboot", mconsole_reboot, MCONSOLE_PROC },
5861 + { "config", mconsole_config, MCONSOLE_PROC },
5862 + { "remove", mconsole_remove, MCONSOLE_PROC },
5863 + { "sysrq", mconsole_sysrq, MCONSOLE_INTR },
5864 + { "help", mconsole_help, MCONSOLE_INTR },
5865 + { "cad", mconsole_cad, MCONSOLE_INTR },
5866 + { "stop", mconsole_stop, MCONSOLE_PROC },
5867 + { "go", mconsole_go, MCONSOLE_INTR },
5868 + { "log", mconsole_log, MCONSOLE_INTR },
5869 + { "proc", mconsole_proc, MCONSOLE_PROC },
5872 +/* Initialized in mconsole_init, which is an initcall */
5873 +char mconsole_socket_name[256];
5875 +int mconsole_reply_v0(struct mc_request *req, char *reply)
5878 + struct msghdr msg;
5880 + iov.iov_base = reply;
5881 + iov.iov_len = strlen(reply);
5883 + msg.msg_name = &(req->origin);
5884 + msg.msg_namelen = req->originlen;
5885 + msg.msg_iov = &iov;
5886 + msg.msg_iovlen = 1;
5887 + msg.msg_control = NULL;
5888 + msg.msg_controllen = 0;
5889 + msg.msg_flags = 0;
5891 + return sendmsg(req->originating_fd, &msg, 0);
5894 +static struct mconsole_command *mconsole_parse(struct mc_request *req)
5896 + struct mconsole_command *cmd;
5899 + for(i=0;i<sizeof(commands)/sizeof(commands[0]);i++){
5900 + cmd = &commands[i];
5901 + if(!strncmp(req->request.data, cmd->command,
5902 + strlen(cmd->command))){
5909 +#define MIN(a,b) ((a)<(b) ? (a):(b))
5911 +#define STRINGX(x) #x
5912 +#define STRING(x) STRINGX(x)
5914 +int mconsole_get_request(int fd, struct mc_request *req)
5918 + req->originlen = sizeof(req->origin);
5919 + req->len = recvfrom(fd, &req->request, sizeof(req->request), 0,
5920 + (struct sockaddr *) req->origin, &req->originlen);
5924 + req->originating_fd = fd;
5926 + if(req->request.magic != MCONSOLE_MAGIC){
5927 + /* Unversioned request */
5928 + len = MIN(sizeof(req->request.data) - 1,
5929 + strlen((char *) &req->request));
5930 + memmove(req->request.data, &req->request, len);
5931 + req->request.data[len] = '\0';
5933 + req->request.magic = MCONSOLE_MAGIC;
5934 + req->request.version = 0;
5935 + req->request.len = len;
5937 + mconsole_reply_v0(req, "ERR Version 0 mconsole clients are "
5938 + "not supported by this driver");
5942 + if(req->request.len >= MCONSOLE_MAX_DATA){
5943 + mconsole_reply(req, "Request too large", 1, 0);
5946 + if(req->request.version != MCONSOLE_VERSION){
5947 + mconsole_reply(req, "This driver only supports version "
5948 + STRING(MCONSOLE_VERSION) " clients", 1, 0);
5951 + req->request.data[req->request.len] = '\0';
5952 + req->cmd = mconsole_parse(req);
5953 + if(req->cmd == NULL){
5954 + mconsole_reply(req, "Unknown command", 1, 0);
5961 +int mconsole_reply(struct mc_request *req, char *str, int err, int more)
5963 + struct mconsole_reply reply;
5964 + int total, len, n;
5966 + total = strlen(str);
5970 + /* err can only be true on the first packet */
5973 + len = MIN(total, MCONSOLE_MAX_DATA - 1);
5975 + if(len == total) reply.more = more;
5976 + else reply.more = 1;
5978 + memcpy(reply.data, str, len);
5979 + reply.data[len] = '\0';
5982 + reply.len = len + 1;
5984 + len = sizeof(reply) + reply.len - sizeof(reply.data);
5986 + n = sendto(req->originating_fd, &reply, len, 0,
5987 + (struct sockaddr *) req->origin, req->originlen);
5989 + if(n < 0) return(-errno);
5990 + } while(total > 0);
5994 +int mconsole_unlink_socket(void)
5996 + unlink(mconsole_socket_name);
6000 +static int notify_sock = -1;
6002 +int mconsole_notify(char *sock_name, int type, const void *data, int len)
6004 + struct sockaddr_un target;
6005 + struct mconsole_notify packet;
6009 + if(notify_sock < 0){
6010 + notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0);
6011 + if(notify_sock < 0){
6012 + printk("mconsole_notify - socket failed, errno = %d\n",
6022 + target.sun_family = AF_UNIX;
6023 + strcpy(target.sun_path, sock_name);
6025 + packet.magic = MCONSOLE_MAGIC;
6026 + packet.version = MCONSOLE_VERSION;
6027 + packet.type = type;
6028 + len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len;
6030 + memcpy(packet.data, data, len);
6033 + len = sizeof(packet) + packet.len - sizeof(packet.data);
6034 + n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target,
6037 + printk("mconsole_notify - sendto failed, errno = %d\n", errno);
6044 + * Overrides for Emacs so that we follow Linus's tabbing style.
6045 + * Emacs will notice this stuff at the end of the file and automatically
6046 + * adjust the settings for this buffer only. This must remain at the end
6048 + * ---------------------------------------------------------------------------
6049 + * Local variables:
6050 + * c-file-style: "linux"
6053 diff -Naur -X ../exclude-files orig/arch/um/drivers/mmapper_kern.c um/arch/um/drivers/mmapper_kern.c
6054 --- orig/arch/um/drivers/mmapper_kern.c 1969-12-31 19:00:00.000000000 -0500
6055 +++ um/arch/um/drivers/mmapper_kern.c 2003-10-21 03:26:06.000000000 -0400
6058 + * arch/um/drivers/mmapper_kern.c
6060 + * BRIEF MODULE DESCRIPTION
6062 + * Copyright (C) 2000 RidgeRun, Inc.
6063 + * Author: RidgeRun, Inc.
6064 + * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
6067 +#include <linux/kdev_t.h>
6068 +#include <linux/time.h>
6069 +#include <linux/devfs_fs_kernel.h>
6070 +#include <linux/module.h>
6071 +#include <linux/mm.h>
6072 +#include <linux/slab.h>
6073 +#include <linux/init.h>
6074 +#include <asm/uaccess.h>
6075 +#include <asm/irq.h>
6076 +#include <asm/smplock.h>
6077 +#include <asm/pgtable.h>
6078 +#include "mem_user.h"
6079 +#include "user_util.h"
6081 +/* These are set in mmapper_init, which is called at boot time */
6082 +static unsigned long mmapper_size;
6083 +static unsigned long p_buf = 0;
6084 +static char *v_buf = NULL;
6087 +mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos)
6089 + if(*ppos > mmapper_size)
6092 + if(count + *ppos > mmapper_size)
6093 + count = count + *ppos - mmapper_size;
6098 + copy_to_user(buf,&v_buf[*ppos],count);
6104 +mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
6106 + if(*ppos > mmapper_size)
6109 + if(count + *ppos > mmapper_size)
6110 + count = count + *ppos - mmapper_size;
6115 + copy_from_user(&v_buf[*ppos],buf,count);
6121 +mmapper_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
6122 + unsigned long arg)
6124 + return(-ENOIOCTLCMD);
6128 +mmapper_mmap(struct file *file, struct vm_area_struct * vma)
6130 + int ret = -EINVAL;
6134 + if (vma->vm_pgoff != 0)
6137 + size = vma->vm_end - vma->vm_start;
6138 + if(size > mmapper_size) return(-EFAULT);
6140 + /* XXX A comment above remap_page_range says it should only be
6141 + * called when the mm semaphore is held
6143 + if (remap_page_range(vma->vm_start, p_buf, size, vma->vm_page_prot))
6152 +mmapper_open(struct inode *inode, struct file *file)
6158 +mmapper_release(struct inode *inode, struct file *file)
6163 +static struct file_operations mmapper_fops = {
6164 + .owner = THIS_MODULE,
6165 + .read = mmapper_read,
6166 + .write = mmapper_write,
6167 + .ioctl = mmapper_ioctl,
6168 + .mmap = mmapper_mmap,
6169 + .open = mmapper_open,
6170 + .release = mmapper_release,
6173 +static int __init mmapper_init(void)
6175 + printk(KERN_INFO "Mapper v0.1\n");
6177 + v_buf = (char *) find_iomem("mmapper", &mmapper_size);
6178 + if(mmapper_size == 0){
6179 + printk(KERN_ERR "mmapper_init - find_iomem failed\n");
6183 + p_buf = __pa(v_buf);
6185 + devfs_register (NULL, "mmapper", DEVFS_FL_DEFAULT,
6186 + 30, 0, S_IFCHR | S_IRUGO | S_IWUGO,
6187 + &mmapper_fops, NULL);
6188 + devfs_mk_symlink(NULL, "mmapper0", DEVFS_FL_DEFAULT, "mmapper",
6193 +static void mmapper_exit(void)
6197 +module_init(mmapper_init);
6198 +module_exit(mmapper_exit);
6200 +MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>");
6201 +MODULE_DESCRIPTION("DSPLinux simulator mmapper driver");
6203 + * ---------------------------------------------------------------------------
6204 + * Local variables:
6205 + * c-file-style: "linux"
6208 diff -Naur -X ../exclude-files orig/arch/um/drivers/net_kern.c um/arch/um/drivers/net_kern.c
6209 --- orig/arch/um/drivers/net_kern.c 1969-12-31 19:00:00.000000000 -0500
6210 +++ um/arch/um/drivers/net_kern.c 2003-10-21 03:26:06.000000000 -0400
6213 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
6214 + * James Leu (jleu@mindspring.net).
6215 + * Copyright (C) 2001 by various other people who didn't put their name here.
6216 + * Licensed under the GPL.
6219 +#include "linux/config.h"
6220 +#include "linux/kernel.h"
6221 +#include "linux/netdevice.h"
6222 +#include "linux/rtnetlink.h"
6223 +#include "linux/skbuff.h"
6224 +#include "linux/socket.h"
6225 +#include "linux/spinlock.h"
6226 +#include "linux/module.h"
6227 +#include "linux/init.h"
6228 +#include "linux/etherdevice.h"
6229 +#include "linux/list.h"
6230 +#include "linux/inetdevice.h"
6231 +#include "linux/ctype.h"
6232 +#include "linux/bootmem.h"
6233 +#include "user_util.h"
6234 +#include "kern_util.h"
6235 +#include "net_kern.h"
6236 +#include "net_user.h"
6237 +#include "mconsole_kern.h"
6239 +#include "irq_user.h"
6240 +#include "irq_kern.h"
6242 +static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
6245 +static int uml_net_rx(struct net_device *dev)
6247 + struct uml_net_private *lp = dev->priv;
6249 + struct sk_buff *skb;
6251 + /* If we can't allocate memory, try again next round. */
6252 + skb = dev_alloc_skb(dev->mtu);
6253 + if (skb == NULL) {
6254 + lp->stats.rx_dropped++;
6259 + skb_put(skb, dev->mtu);
6260 + skb->mac.raw = skb->data;
6261 + pkt_len = (*lp->read)(lp->fd, &skb, lp);
6263 + if (pkt_len > 0) {
6264 + skb_trim(skb, pkt_len);
6265 + skb->protocol = (*lp->protocol)(skb);
6268 + lp->stats.rx_bytes += skb->len;
6269 + lp->stats.rx_packets++;
6277 +void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6279 + struct net_device *dev = dev_id;
6280 + struct uml_net_private *lp = dev->priv;
6283 + if(!netif_running(dev))
6286 + spin_lock(&lp->lock);
6287 + while((err = uml_net_rx(dev)) > 0) ;
6290 + "Device '%s' read returned %d, shutting it down\n",
6295 + reactivate_fd(lp->fd, UM_ETH_IRQ);
6298 + spin_unlock(&lp->lock);
6301 +static int uml_net_open(struct net_device *dev)
6303 + struct uml_net_private *lp = dev->priv;
6304 + char addr[sizeof("255.255.255.255\0")];
6307 + spin_lock(&lp->lock);
6314 + if(!lp->have_mac){
6315 + dev_ip_addr(dev, addr, &lp->mac[2]);
6316 + set_ether_mac(dev, lp->mac);
6319 + lp->fd = (*lp->open)(&lp->user);
6325 + err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
6326 + SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
6328 + printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
6329 + if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6331 + err = -ENETUNREACH;
6334 + lp->tl.data = (unsigned long) &lp->user;
6335 + netif_start_queue(dev);
6337 + spin_lock(&opened_lock);
6338 + list_add(&lp->list, &opened);
6339 + spin_unlock(&opened_lock);
6340 + MOD_INC_USE_COUNT;
6342 + spin_unlock(&lp->lock);
6346 +static int uml_net_close(struct net_device *dev)
6348 + struct uml_net_private *lp = dev->priv;
6350 + netif_stop_queue(dev);
6351 + spin_lock(&lp->lock);
6353 + free_irq(dev->irq, dev);
6354 + if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6356 + spin_lock(&opened_lock);
6357 + list_del(&lp->list);
6358 + spin_unlock(&opened_lock);
6360 + MOD_DEC_USE_COUNT;
6361 + spin_unlock(&lp->lock);
6365 +static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
6367 + struct uml_net_private *lp = dev->priv;
6368 + unsigned long flags;
6371 + netif_stop_queue(dev);
6373 + spin_lock_irqsave(&lp->lock, flags);
6375 + len = (*lp->write)(lp->fd, &skb, lp);
6377 + if(len == skb->len) {
6378 + lp->stats.tx_packets++;
6379 + lp->stats.tx_bytes += skb->len;
6380 + dev->trans_start = jiffies;
6381 + netif_start_queue(dev);
6383 + /* this is normally done in the interrupt when tx finishes */
6384 + netif_wake_queue(dev);
6386 + else if(len == 0){
6387 + netif_start_queue(dev);
6388 + lp->stats.tx_dropped++;
6391 + netif_start_queue(dev);
6392 + printk(KERN_ERR "uml_net_start_xmit: failed(%d)\n", len);
6395 + spin_unlock_irqrestore(&lp->lock, flags);
6397 + dev_kfree_skb(skb);
6402 +static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
6404 + struct uml_net_private *lp = dev->priv;
6405 + return &lp->stats;
6408 +static void uml_net_set_multicast_list(struct net_device *dev)
6410 + if (dev->flags & IFF_PROMISC) return;
6411 + else if (dev->mc_count) dev->flags |= IFF_ALLMULTI;
6412 + else dev->flags &= ~IFF_ALLMULTI;
6415 +static void uml_net_tx_timeout(struct net_device *dev)
6417 + dev->trans_start = jiffies;
6418 + netif_wake_queue(dev);
6421 +static int uml_net_set_mac(struct net_device *dev, void *addr)
6423 + struct uml_net_private *lp = dev->priv;
6424 + struct sockaddr *hwaddr = addr;
6426 + spin_lock(&lp->lock);
6427 + memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
6428 + spin_unlock(&lp->lock);
6433 +static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
6435 + struct uml_net_private *lp = dev->priv;
6438 + spin_lock(&lp->lock);
6440 + new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
6446 + dev->mtu = new_mtu;
6449 + spin_unlock(&lp->lock);
6453 +static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6458 +void uml_net_user_timer_expire(unsigned long _conn)
6461 + struct connection *conn = (struct connection *)_conn;
6463 + dprintk(KERN_INFO "uml_net_user_timer_expire [%p]\n", conn);
6469 + * default do nothing hard header packet routines for struct net_device init.
6470 + * real ethernet transports will overwrite with real routines.
6472 +static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
6473 + unsigned short type, void *daddr, void *saddr, unsigned len)
6475 + return(0); /* no change */
6478 +static int uml_net_rebuild_header(struct sk_buff *skb)
6480 + return(0); /* ignore */
6483 +static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
6485 + return(-1); /* fail */
6488 +static void uml_net_header_cache_update(struct hh_cache *hh,
6489 + struct net_device *dev, unsigned char * haddr)
6494 +static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
6496 + return(0); /* nothing */
6499 +static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
6500 +static struct list_head devices = LIST_HEAD_INIT(devices);
6502 +static int eth_configure(int n, void *init, char *mac,
6503 + struct transport *transport)
6505 + struct uml_net *device;
6506 + struct net_device *dev;
6507 + struct uml_net_private *lp;
6508 + int save, err, size;
6510 + size = transport->private_size + sizeof(struct uml_net_private) +
6511 + sizeof(((struct uml_net_private *) 0)->user);
6513 + device = kmalloc(sizeof(*device), GFP_KERNEL);
6514 + if(device == NULL){
6515 + printk(KERN_ERR "eth_configure failed to allocate uml_net\n");
6519 + *device = ((struct uml_net) { .list = LIST_HEAD_INIT(device->list),
6522 + .mac = { [ 0 ... 5 ] = 0 },
6525 + spin_lock(&devices_lock);
6526 + list_add(&device->list, &devices);
6527 + spin_unlock(&devices_lock);
6529 + if(setup_etheraddr(mac, device->mac))
6530 + device->have_mac = 1;
6532 + printk(KERN_INFO "Netdevice %d ", n);
6533 + if(device->have_mac) printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
6534 + device->mac[0], device->mac[1],
6535 + device->mac[2], device->mac[3],
6536 + device->mac[4], device->mac[5]);
6538 + dev = kmalloc(sizeof(*dev) + size, GFP_KERNEL);
6540 + printk(KERN_ERR "eth_configure: failed to allocate device\n");
6543 + memset(dev, 0, sizeof(*dev) + size);
6545 + snprintf(dev->name, sizeof(dev->name), "eth%d", n);
6546 + dev->priv = (void *) &dev[1];
6547 + device->dev = dev;
6549 + dev->hard_header = uml_net_hard_header;
6550 + dev->rebuild_header = uml_net_rebuild_header;
6551 + dev->hard_header_cache = uml_net_header_cache;
6552 + dev->header_cache_update= uml_net_header_cache_update;
6553 + dev->hard_header_parse = uml_net_header_parse;
6555 + (*transport->kern->init)(dev, init);
6557 + dev->mtu = transport->user->max_packet;
6558 + dev->open = uml_net_open;
6559 + dev->hard_start_xmit = uml_net_start_xmit;
6560 + dev->stop = uml_net_close;
6561 + dev->get_stats = uml_net_get_stats;
6562 + dev->set_multicast_list = uml_net_set_multicast_list;
6563 + dev->tx_timeout = uml_net_tx_timeout;
6564 + dev->set_mac_address = uml_net_set_mac;
6565 + dev->change_mtu = uml_net_change_mtu;
6566 + dev->do_ioctl = uml_net_ioctl;
6567 + dev->watchdog_timeo = (HZ >> 1);
6568 + dev->irq = UM_ETH_IRQ;
6571 + err = register_netdevice(dev);
6577 + /* lp.user is the first four bytes of the transport data, which
6578 + * has already been initialized. This structure assignment will
6579 + * overwrite that, so we make sure that .user gets overwritten with
6580 + * what it already has.
6582 + save = lp->user[0];
6583 + *lp = ((struct uml_net_private)
6584 + { .list = LIST_HEAD_INIT(lp->list),
6585 + .lock = SPIN_LOCK_UNLOCKED,
6588 + .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
6589 + .have_mac = device->have_mac,
6590 + .protocol = transport->kern->protocol,
6591 + .open = transport->user->open,
6592 + .close = transport->user->close,
6593 + .remove = transport->user->remove,
6594 + .read = transport->kern->read,
6595 + .write = transport->kern->write,
6596 + .add_address = transport->user->add_address,
6597 + .delete_address = transport->user->delete_address,
6598 + .set_mtu = transport->user->set_mtu,
6599 + .user = { save } });
6600 + init_timer(&lp->tl);
6601 + lp->tl.function = uml_net_user_timer_expire;
6602 + memset(&lp->stats, 0, sizeof(lp->stats));
6603 + if(lp->have_mac) memcpy(lp->mac, device->mac, sizeof(lp->mac));
6605 + if(transport->user->init)
6606 + (*transport->user->init)(&lp->user, dev);
6608 + if(device->have_mac)
6609 + set_ether_mac(dev, device->mac);
6613 +static struct uml_net *find_device(int n)
6615 + struct uml_net *device;
6616 + struct list_head *ele;
6618 + spin_lock(&devices_lock);
6619 + list_for_each(ele, &devices){
6620 + device = list_entry(ele, struct uml_net, list);
6621 + if(device->index == n)
6626 + spin_unlock(&devices_lock);
6630 +static int eth_parse(char *str, int *index_out, char **str_out)
6635 + n = simple_strtoul(str, &end, 0);
6637 + printk(KERN_ERR "eth_setup: Failed to parse '%s'\n", str);
6641 + printk(KERN_ERR "eth_setup: device %d is negative\n", n);
6647 + "eth_setup: expected '=' after device number\n");
6651 + if(find_device(n)){
6652 + printk(KERN_ERR "eth_setup: Device %d already configured\n",
6656 + if(index_out) *index_out = n;
6662 + struct list_head list;
6667 +/* Filled in at boot time. Will need locking if the transports become
6670 +struct list_head transports = LIST_HEAD_INIT(transports);
6672 +/* Filled in during early boot */
6673 +struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
6675 +static int check_transport(struct transport *transport, char *eth, int n,
6676 + void **init_out, char **mac_out)
6680 + len = strlen(transport->name);
6681 + if(strncmp(eth, transport->name, len))
6687 + else if(*eth != '\0')
6690 + *init_out = kmalloc(transport->setup_size, GFP_KERNEL);
6691 + if(*init_out == NULL)
6694 + if(!transport->setup(eth, mac_out, *init_out)){
6701 +void register_transport(struct transport *new)
6703 + struct list_head *ele, *next;
6704 + struct eth_init *eth;
6709 + list_add(&new->list, &transports);
6711 + list_for_each_safe(ele, next, ð_cmd_line){
6712 + eth = list_entry(ele, struct eth_init, list);
6713 + match = check_transport(new, eth->init, eth->index, &init,
6717 + else if(init != NULL){
6718 + eth_configure(eth->index, init, mac, new);
6721 + list_del(ð->list);
6725 +static int eth_setup_common(char *str, int index)
6727 + struct list_head *ele;
6728 + struct transport *transport;
6732 + list_for_each(ele, &transports){
6733 + transport = list_entry(ele, struct transport, list);
6734 + if(!check_transport(transport, str, index, &init, &mac))
6737 + eth_configure(index, init, mac, transport);
6745 +static int eth_setup(char *str)
6747 + struct eth_init *new;
6750 + err = eth_parse(str, &n, &str);
6751 + if(err) return(1);
6753 + new = alloc_bootmem(sizeof(new));
6755 + printk("eth_init : alloc_bootmem failed\n");
6758 + *new = ((struct eth_init) { .list = LIST_HEAD_INIT(new->list),
6761 + list_add_tail(&new->list, ð_cmd_line);
6765 +__setup("eth", eth_setup);
6766 +__uml_help(eth_setup,
6767 +"eth[0-9]+=<transport>,<options>\n"
6768 +" Configure a network device.\n\n"
6771 +static int eth_init(void)
6773 + struct list_head *ele, *next;
6774 + struct eth_init *eth;
6776 + list_for_each_safe(ele, next, ð_cmd_line){
6777 + eth = list_entry(ele, struct eth_init, list);
6779 + if(eth_setup_common(eth->init, eth->index))
6780 + list_del(ð->list);
6786 +__initcall(eth_init);
6788 +static int net_config(char *str)
6792 + err = eth_parse(str, &n, &str);
6793 + if(err) return(err);
6795 + str = uml_strdup(str);
6797 + printk(KERN_ERR "net_config failed to strdup string\n");
6800 + err = !eth_setup_common(str, n);
6806 +static int net_remove(char *str)
6808 + struct uml_net *device;
6809 + struct net_device *dev;
6810 + struct uml_net_private *lp;
6814 + n = simple_strtoul(str, &end, 0);
6815 + if((*end != '\0') || (end == str))
6818 + device = find_device(n);
6819 + if(device == NULL)
6822 + dev = device->dev;
6824 + if(lp->fd > 0) return(-1);
6825 + if(lp->remove != NULL) (*lp->remove)(&lp->user);
6826 + unregister_netdev(dev);
6828 + list_del(&device->list);
6833 +static struct mc_device net_mc = {
6835 + .config = net_config,
6836 + .get_config = NULL,
6837 + .remove = net_remove,
6840 +static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
6843 + struct in_ifaddr *ifa = ptr;
6844 + u32 addr = ifa->ifa_address;
6845 + u32 netmask = ifa->ifa_mask;
6846 + struct net_device *dev = ifa->ifa_dev->dev;
6847 + struct uml_net_private *lp;
6848 + void (*proc)(unsigned char *, unsigned char *, void *);
6849 + unsigned char addr_buf[4], netmask_buf[4];
6851 + if(dev->open != uml_net_open) return(NOTIFY_DONE);
6858 + proc = lp->add_address;
6861 + proc = lp->delete_address;
6865 + addr_buf[0] = addr & 0xff;
6866 + addr_buf[1] = (addr >> 8) & 0xff;
6867 + addr_buf[2] = (addr >> 16) & 0xff;
6868 + addr_buf[3] = addr >> 24;
6869 + netmask_buf[0] = netmask & 0xff;
6870 + netmask_buf[1] = (netmask >> 8) & 0xff;
6871 + netmask_buf[2] = (netmask >> 16) & 0xff;
6872 + netmask_buf[3] = netmask >> 24;
6873 + (*proc)(addr_buf, netmask_buf, &lp->user);
6875 + return(NOTIFY_DONE);
6878 +struct notifier_block uml_inetaddr_notifier = {
6879 + .notifier_call = uml_inetaddr_event,
6882 +static int uml_net_init(void)
6884 + struct list_head *ele;
6885 + struct uml_net_private *lp;
6886 + struct in_device *ip;
6887 + struct in_ifaddr *in;
6889 + mconsole_register_dev(&net_mc);
6890 + register_inetaddr_notifier(¨_inetaddr_notifier);
6892 + /* Devices may have been opened already, so the uml_inetaddr_notifier
6893 + * didn't get a chance to run for them. This fakes it so that
6894 + * addresses which have already been set up get handled properly.
6896 + list_for_each(ele, &opened){
6897 + lp = list_entry(ele, struct uml_net_private, list);
6898 + ip = lp->dev->ip_ptr;
6899 + if(ip == NULL) continue;
6900 + in = ip->ifa_list;
6901 + while(in != NULL){
6902 + uml_inetaddr_event(NULL, NETDEV_UP, in);
6903 + in = in->ifa_next;
6910 +__initcall(uml_net_init);
6912 +static void close_devices(void)
6914 + struct list_head *ele;
6915 + struct uml_net_private *lp;
6917 + list_for_each(ele, &opened){
6918 + lp = list_entry(ele, struct uml_net_private, list);
6919 + if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6920 + if(lp->remove != NULL) (*lp->remove)(&lp->user);
6924 +__uml_exitcall(close_devices);
6926 +int setup_etheraddr(char *str, unsigned char *addr)
6934 + addr[i] = simple_strtoul(str, &end, 16);
6935 + if((end == str) ||
6936 + ((*end != ':') && (*end != ',') && (*end != '\0'))){
6938 + "setup_etheraddr: failed to parse '%s' "
6939 + "as an ethernet address\n", str);
6946 + "Attempt to assign a broadcast ethernet address to a "
6947 + "device disallowed\n");
6953 +void dev_ip_addr(void *d, char *buf, char *bin_buf)
6955 + struct net_device *dev = d;
6956 + struct in_device *ip = dev->ip_ptr;
6957 + struct in_ifaddr *in;
6960 + if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
6961 + printk(KERN_WARNING "dev_ip_addr - device not assigned an "
6965 + addr = in->ifa_address;
6966 + sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff,
6967 + (addr >> 16) & 0xff, addr >> 24);
6969 + bin_buf[0] = addr & 0xff;
6970 + bin_buf[1] = (addr >> 8) & 0xff;
6971 + bin_buf[2] = (addr >> 16) & 0xff;
6972 + bin_buf[3] = addr >> 24;
6976 +void set_ether_mac(void *d, unsigned char *addr)
6978 + struct net_device *dev = d;
6980 + memcpy(dev->dev_addr, addr, ETH_ALEN);
6983 +struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
6985 + if((skb != NULL) && (skb_tailroom(skb) < extra)){
6986 + struct sk_buff *skb2;
6988 + skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
6989 + dev_kfree_skb(skb);
6992 + if(skb != NULL) skb_put(skb, extra);
6996 +void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
7000 + struct net_device *dev = d;
7001 + struct in_device *ip = dev->ip_ptr;
7002 + struct in_ifaddr *in;
7003 + unsigned char address[4], netmask[4];
7005 + if(ip == NULL) return;
7006 + in = ip->ifa_list;
7007 + while(in != NULL){
7008 + address[0] = in->ifa_address & 0xff;
7009 + address[1] = (in->ifa_address >> 8) & 0xff;
7010 + address[2] = (in->ifa_address >> 16) & 0xff;
7011 + address[3] = in->ifa_address >> 24;
7012 + netmask[0] = in->ifa_mask & 0xff;
7013 + netmask[1] = (in->ifa_mask >> 8) & 0xff;
7014 + netmask[2] = (in->ifa_mask >> 16) & 0xff;
7015 + netmask[3] = in->ifa_mask >> 24;
7016 + (*cb)(address, netmask, arg);
7017 + in = in->ifa_next;
7021 +int dev_netmask(void *d, void *m)
7023 + struct net_device *dev = d;
7024 + struct in_device *ip = dev->ip_ptr;
7025 + struct in_ifaddr *in;
7026 + __u32 *mask_out = m;
7031 + in = ip->ifa_list;
7035 + *mask_out = in->ifa_mask;
7039 +void *get_output_buffer(int *len_out)
7043 + ret = (void *) __get_free_pages(GFP_KERNEL, 0);
7044 + if(ret) *len_out = PAGE_SIZE;
7045 + else *len_out = 0;
7049 +void free_output_buffer(void *buffer)
7051 + free_pages((unsigned long) buffer, 0);
7054 +int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out,
7059 + remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL);
7060 + if(remain != NULL){
7061 + printk("tap_setup_common - Extra garbage on specification : "
7062 + "'%s'\n", remain);
7069 +unsigned short eth_protocol(struct sk_buff *skb)
7071 + return(eth_type_trans(skb, skb->dev));
7075 + * Overrides for Emacs so that we follow Linus's tabbing style.
7076 + * Emacs will notice this stuff at the end of the file and automatically
7077 + * adjust the settings for this buffer only. This must remain at the end
7079 + * ---------------------------------------------------------------------------
7080 + * Local variables:
7081 + * c-file-style: "linux"
7084 diff -Naur -X ../exclude-files orig/arch/um/drivers/net_user.c um/arch/um/drivers/net_user.c
7085 --- orig/arch/um/drivers/net_user.c 1969-12-31 19:00:00.000000000 -0500
7086 +++ um/arch/um/drivers/net_user.c 2003-10-21 03:26:06.000000000 -0400
7089 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7090 + * Licensed under the GPL
7093 +#include <stddef.h>
7094 +#include <stdarg.h>
7095 +#include <unistd.h>
7098 +#include <stdlib.h>
7099 +#include <string.h>
7100 +#include <sys/socket.h>
7101 +#include <sys/wait.h>
7103 +#include "user_util.h"
7104 +#include "kern_util.h"
7105 +#include "net_user.h"
7106 +#include "helper.h"
7109 +int tap_open_common(void *dev, char *gate_addr)
7113 + if(gate_addr == NULL) return(0);
7114 + if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
7115 + &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
7116 + printk("Invalid tap IP address - '%s'\n", gate_addr);
7122 +void tap_check_ips(char *gate_addr, char *eth_addr)
7126 + if((gate_addr != NULL) &&
7127 + (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
7128 + &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
7129 + (eth_addr[0] == tap_addr[0]) &&
7130 + (eth_addr[1] == tap_addr[1]) &&
7131 + (eth_addr[2] == tap_addr[2]) &&
7132 + (eth_addr[3] == tap_addr[3])){
7133 + printk("The tap IP address and the UML eth IP address"
7134 + " must be different\n");
7138 +void read_output(int fd, char *output, int len)
7140 + int remain, n, actual;
7143 + if(output == NULL){
7149 + n = os_read_file(fd, &remain, sizeof(remain));
7150 + if(n != sizeof(remain)){
7151 + printk("read_output - read of length failed, err = %d\n", -n);
7155 + while(remain != 0){
7156 + n = (remain < len) ? remain : len;
7157 + actual = os_read_file(fd, output, n);
7159 + printk("read_output - read of data failed, "
7160 + "err = %d\n", -actual);
7168 +int net_read(int fd, void *buf, int len)
7172 + n = os_read_file(fd, buf, len);
7177 + return(-ENOTCONN);
7181 +int net_recvfrom(int fd, void *buf, int len)
7185 + while(((n = recvfrom(fd, buf, len, 0, NULL, NULL)) < 0) &&
7186 + (errno == EINTR)) ;
7189 + if(errno == EAGAIN) return(0);
7192 + else if(n == 0) return(-ENOTCONN);
7196 +int net_write(int fd, void *buf, int len)
7200 + n = os_write_file(fd, buf, len);
7205 + return(-ENOTCONN);
7209 +int net_send(int fd, void *buf, int len)
7213 + while(((n = send(fd, buf, len, 0)) < 0) && (errno == EINTR)) ;
7215 + if(errno == EAGAIN) return(0);
7218 + else if(n == 0) return(-ENOTCONN);
7222 +int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
7226 + while(((n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
7227 + sock_len)) < 0) && (errno == EINTR)) ;
7229 + if(errno == EAGAIN) return(0);
7232 + else if(n == 0) return(-ENOTCONN);
7236 +struct change_pre_exec_data {
7241 +static void change_pre_exec(void *arg)
7243 + struct change_pre_exec_data *data = arg;
7245 + os_close_file(data->close_me);
7246 + dup2(data->stdout, 1);
7249 +static int change_tramp(char **argv, char *output, int output_len)
7251 + int pid, fds[2], err;
7252 + struct change_pre_exec_data pe_data;
7254 + err = os_pipe(fds, 1, 0);
7256 + printk("change_tramp - pipe failed, err = %d\n", -err);
7259 + pe_data.close_me = fds[0];
7260 + pe_data.stdout = fds[1];
7261 + pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
7263 + os_close_file(fds[1]);
7264 + read_output(fds[0], output, output_len);
7265 + waitpid(pid, NULL, 0);
7269 +static void change(char *dev, char *what, unsigned char *addr,
7270 + unsigned char *netmask)
7272 + char addr_buf[sizeof("255.255.255.255\0")];
7273 + char netmask_buf[sizeof("255.255.255.255\0")];
7274 + char version[sizeof("nnnnn\0")];
7275 + char *argv[] = { "uml_net", version, what, dev, addr_buf,
7276 + netmask_buf, NULL };
7278 + int output_len, pid;
7280 + sprintf(version, "%d", UML_NET_VERSION);
7281 + sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
7282 + sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1],
7283 + netmask[2], netmask[3]);
7285 + output_len = page_size();
7286 + output = um_kmalloc(output_len);
7287 + if(output == NULL)
7288 + printk("change : failed to allocate output buffer\n");
7290 + pid = change_tramp(argv, output, output_len);
7291 + if(pid < 0) return;
7293 + if(output != NULL){
7294 + printk("%s", output);
7299 +void open_addr(unsigned char *addr, unsigned char *netmask, void *arg)
7301 + change(arg, "add", addr, netmask);
7304 +void close_addr(unsigned char *addr, unsigned char *netmask, void *arg)
7306 + change(arg, "del", addr, netmask);
7309 +char *split_if_spec(char *str, ...)
7314 + va_start(ap, str);
7315 + while((arg = va_arg(ap, char **)) != NULL){
7318 + end = strchr(str, ',');
7331 + * Overrides for Emacs so that we follow Linus's tabbing style.
7332 + * Emacs will notice this stuff at the end of the file and automatically
7333 + * adjust the settings for this buffer only. This must remain at the end
7335 + * ---------------------------------------------------------------------------
7336 + * Local variables:
7337 + * c-file-style: "linux"
7340 diff -Naur -X ../exclude-files orig/arch/um/drivers/null.c um/arch/um/drivers/null.c
7341 --- orig/arch/um/drivers/null.c 1969-12-31 19:00:00.000000000 -0500
7342 +++ um/arch/um/drivers/null.c 2003-10-21 03:26:06.000000000 -0400
7345 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7346 + * Licensed under the GPL
7349 +#include <stdlib.h>
7351 +#include "chan_user.h"
7354 +static int null_chan;
7356 +void *null_init(char *str, int device, struct chan_opts *opts)
7358 + return(&null_chan);
7361 +int null_open(int input, int output, int primary, void *d, char **dev_out)
7364 + return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0));
7367 +int null_read(int fd, char *c_out, void *unused)
7372 +void null_free(void *data)
7376 +struct chan_ops null_ops = {
7378 + .init = null_init,
7379 + .open = null_open,
7380 + .close = generic_close,
7381 + .read = null_read,
7382 + .write = generic_write,
7383 + .console_write = generic_console_write,
7384 + .window_size = generic_window_size,
7385 + .free = null_free,
7390 + * Overrides for Emacs so that we follow Linus's tabbing style.
7391 + * Emacs will notice this stuff at the end of the file and automatically
7392 + * adjust the settings for this buffer only. This must remain at the end
7394 + * ---------------------------------------------------------------------------
7395 + * Local variables:
7396 + * c-file-style: "linux"
7399 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_kern.c um/arch/um/drivers/pcap_kern.c
7400 --- orig/arch/um/drivers/pcap_kern.c 1969-12-31 19:00:00.000000000 -0500
7401 +++ um/arch/um/drivers/pcap_kern.c 2003-10-21 03:26:06.000000000 -0400
7404 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
7405 + * Licensed under the GPL.
7408 +#include "linux/init.h"
7409 +#include "linux/netdevice.h"
7410 +#include "linux/etherdevice.h"
7411 +#include "net_kern.h"
7412 +#include "net_user.h"
7413 +#include "pcap_user.h"
7422 +void pcap_init(struct net_device *dev, void *data)
7424 + struct uml_net_private *pri;
7425 + struct pcap_data *ppri;
7426 + struct pcap_init *init = data;
7428 + init_etherdev(dev, 0);
7430 + ppri = (struct pcap_data *) pri->user;
7431 + *ppri = ((struct pcap_data)
7432 + { .host_if = init->host_if,
7433 + .promisc = init->promisc,
7434 + .optimize = init->optimize,
7435 + .filter = init->filter,
7440 +static int pcap_read(int fd, struct sk_buff **skb,
7441 + struct uml_net_private *lp)
7443 + *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
7444 + if(*skb == NULL) return(-ENOMEM);
7445 + return(pcap_user_read(fd, (*skb)->mac.raw,
7446 + (*skb)->dev->mtu + ETH_HEADER_OTHER,
7447 + (struct pcap_data *) &lp->user));
7450 +static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
7455 +static struct net_kern_info pcap_kern_info = {
7456 + .init = pcap_init,
7457 + .protocol = eth_protocol,
7458 + .read = pcap_read,
7459 + .write = pcap_write,
7462 +int pcap_setup(char *str, char **mac_out, void *data)
7464 + struct pcap_init *init = data;
7465 + char *remain, *host_if = NULL, *options[2] = { NULL, NULL };
7468 + *init = ((struct pcap_init)
7469 + { .host_if = "eth0",
7472 + .filter = NULL });
7474 + remain = split_if_spec(str, &host_if, &init->filter,
7475 + &options[0], &options[1], NULL);
7476 + if(remain != NULL){
7477 + printk(KERN_ERR "pcap_setup - Extra garbage on "
7478 + "specification : '%s'\n", remain);
7482 + if(host_if != NULL)
7483 + init->host_if = host_if;
7485 + for(i = 0; i < sizeof(options)/sizeof(options[0]); i++){
7486 + if(options[i] == NULL)
7488 + if(!strcmp(options[i], "promisc"))
7489 + init->promisc = 1;
7490 + else if(!strcmp(options[i], "nopromisc"))
7491 + init->promisc = 0;
7492 + else if(!strcmp(options[i], "optimize"))
7493 + init->optimize = 1;
7494 + else if(!strcmp(options[i], "nooptimize"))
7495 + init->optimize = 0;
7496 + else printk("pcap_setup : bad option - '%s'\n", options[i]);
7502 +static struct transport pcap_transport = {
7503 + .list = LIST_HEAD_INIT(pcap_transport.list),
7505 + .setup = pcap_setup,
7506 + .user = &pcap_user_info,
7507 + .kern = &pcap_kern_info,
7508 + .private_size = sizeof(struct pcap_data),
7509 + .setup_size = sizeof(struct pcap_init),
7512 +static int register_pcap(void)
7514 + register_transport(&pcap_transport);
7518 +__initcall(register_pcap);
7521 + * Overrides for Emacs so that we follow Linus's tabbing style.
7522 + * Emacs will notice this stuff at the end of the file and automatically
7523 + * adjust the settings for this buffer only. This must remain at the end
7525 + * ---------------------------------------------------------------------------
7526 + * Local variables:
7527 + * c-file-style: "linux"
7530 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.c um/arch/um/drivers/pcap_user.c
7531 --- orig/arch/um/drivers/pcap_user.c 1969-12-31 19:00:00.000000000 -0500
7532 +++ um/arch/um/drivers/pcap_user.c 2003-10-21 03:26:06.000000000 -0400
7535 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
7536 + * Licensed under the GPL.
7539 +#include <unistd.h>
7540 +#include <stdlib.h>
7541 +#include <string.h>
7544 +#include <asm/types.h>
7545 +#include "net_user.h"
7546 +#include "pcap_user.h"
7549 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
7551 +#define PCAP_FD(p) (*(int *)(p))
7553 +static void pcap_user_init(void *data, void *dev)
7555 + struct pcap_data *pri = data;
7557 + char errors[PCAP_ERRBUF_SIZE];
7559 + p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors);
7561 + printk("pcap_user_init : pcap_open_live failed - '%s'\n",
7570 +static int pcap_open(void *data)
7572 + struct pcap_data *pri = data;
7576 + if(pri->pcap == NULL)
7579 + if(pri->filter != NULL){
7580 + err = dev_netmask(pri->dev, &netmask);
7582 + printk("pcap_open : dev_netmask failed\n");
7586 + pri->compiled = um_kmalloc(sizeof(struct bpf_program));
7587 + if(pri->compiled == NULL){
7588 + printk("pcap_open : kmalloc failed\n");
7592 + err = pcap_compile(pri->pcap,
7593 + (struct bpf_program *) pri->compiled,
7594 + pri->filter, pri->optimize, netmask);
7596 + printk("pcap_open : pcap_compile failed - '%s'\n",
7597 + pcap_geterr(pri->pcap));
7601 + err = pcap_setfilter(pri->pcap, pri->compiled);
7603 + printk("pcap_open : pcap_setfilter failed - '%s'\n",
7604 + pcap_geterr(pri->pcap));
7609 + return(PCAP_FD(pri->pcap));
7612 +static void pcap_remove(void *data)
7614 + struct pcap_data *pri = data;
7616 + if(pri->compiled != NULL)
7617 + pcap_freecode(pri->compiled);
7619 + pcap_close(pri->pcap);
7622 +struct pcap_handler_data {
7627 +static void handler(u_char *data, const struct pcap_pkthdr *header,
7628 + const u_char *packet)
7632 + struct pcap_handler_data *hdata = (struct pcap_handler_data *) data;
7634 + len = hdata->len < header->caplen ? hdata->len : header->caplen;
7635 + memcpy(hdata->buffer, packet, len);
7639 +int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
7641 + struct pcap_handler_data hdata = ((struct pcap_handler_data)
7642 + { .buffer = buffer,
7646 + n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
7648 + printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap));
7653 + return(hdata.len);
7656 +struct net_user_info pcap_user_info = {
7657 + .init = pcap_user_init,
7658 + .open = pcap_open,
7660 + .remove = pcap_remove,
7662 + .add_address = NULL,
7663 + .delete_address = NULL,
7664 + .max_packet = MAX_PACKET - ETH_HEADER_OTHER
7668 + * Overrides for Emacs so that we follow Linus's tabbing style.
7669 + * Emacs will notice this stuff at the end of the file and automatically
7670 + * adjust the settings for this buffer only. This must remain at the end
7672 + * ---------------------------------------------------------------------------
7673 + * Local variables:
7674 + * c-file-style: "linux"
7677 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.h um/arch/um/drivers/pcap_user.h
7678 --- orig/arch/um/drivers/pcap_user.h 1969-12-31 19:00:00.000000000 -0500
7679 +++ um/arch/um/drivers/pcap_user.h 2003-10-21 03:26:06.000000000 -0400
7682 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7683 + * Licensed under the GPL
7686 +#include "net_user.h"
7698 +extern struct net_user_info pcap_user_info;
7700 +extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
7703 + * Overrides for Emacs so that we follow Linus's tabbing style.
7704 + * Emacs will notice this stuff at the end of the file and automatically
7705 + * adjust the settings for this buffer only. This must remain at the end
7707 + * ---------------------------------------------------------------------------
7708 + * Local variables:
7709 + * c-file-style: "linux"
7712 diff -Naur -X ../exclude-files orig/arch/um/drivers/port.h um/arch/um/drivers/port.h
7713 --- orig/arch/um/drivers/port.h 1969-12-31 19:00:00.000000000 -0500
7714 +++ um/arch/um/drivers/port.h 2003-10-21 03:26:06.000000000 -0400
7717 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
7718 + * Licensed under the GPL
7724 +extern void *port_data(int port);
7725 +extern int port_wait(void *data);
7726 +extern void port_kern_close(void *d);
7727 +extern int port_connection(int fd, int *socket_out, int *pid_out);
7728 +extern int port_listen_fd(int port);
7729 +extern void port_read(int fd, void *data);
7730 +extern void port_kern_free(void *d);
7731 +extern int port_rcv_fd(int fd);
7732 +extern void port_remove_dev(void *d);
7737 + * Overrides for Emacs so that we follow Linus's tabbing style.
7738 + * Emacs will notice this stuff at the end of the file and automatically
7739 + * adjust the settings for this buffer only. This must remain at the end
7741 + * ---------------------------------------------------------------------------
7742 + * Local variables:
7743 + * c-file-style: "linux"
7746 diff -Naur -X ../exclude-files orig/arch/um/drivers/port_kern.c um/arch/um/drivers/port_kern.c
7747 --- orig/arch/um/drivers/port_kern.c 1969-12-31 19:00:00.000000000 -0500
7748 +++ um/arch/um/drivers/port_kern.c 2003-10-21 03:26:06.000000000 -0400
7751 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7752 + * Licensed under the GPL
7755 +#include "linux/list.h"
7756 +#include "linux/sched.h"
7757 +#include "linux/slab.h"
7758 +#include "linux/irq.h"
7759 +#include "linux/spinlock.h"
7760 +#include "linux/errno.h"
7761 +#include "asm/semaphore.h"
7762 +#include "asm/errno.h"
7763 +#include "kern_util.h"
7765 +#include "irq_user.h"
7766 +#include "irq_kern.h"
7772 + struct list_head list;
7773 + int has_connection;
7774 + struct semaphore sem;
7778 + struct list_head pending;
7779 + struct list_head connections;
7783 + struct port_list *port;
7788 +struct connection {
7789 + struct list_head list;
7794 + struct port_list *port;
7797 +static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
7799 + struct connection *conn = data;
7802 + fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
7807 + printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
7809 + os_close_file(conn->fd);
7812 + list_del(&conn->list);
7815 + list_add(&conn->list, &conn->port->connections);
7817 + up(&conn->port->sem);
7820 +static int port_accept(struct port_list *port)
7822 + struct connection *conn;
7823 + int fd, socket[2], pid, ret = 0;
7825 + fd = port_connection(port->fd, socket, &pid);
7828 + printk(KERN_ERR "port_accept : port_connection "
7829 + "returned %d\n", -fd);
7833 + conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
7835 + printk(KERN_ERR "port_accept : failed to allocate "
7839 + *conn = ((struct connection)
7840 + { .list = LIST_HEAD_INIT(conn->list),
7842 + .socket = { socket[0], socket[1] },
7843 + .telnetd_pid = pid,
7846 + if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
7847 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
7848 + "telnetd", conn)){
7849 + printk(KERN_ERR "port_accept : failed to get IRQ for "
7854 + list_add(&conn->list, &port->pending);
7860 + os_close_file(fd);
7862 + os_kill_process(pid, 1);
7867 +DECLARE_MUTEX(ports_sem);
7868 +struct list_head ports = LIST_HEAD_INIT(ports);
7870 +void port_task_proc(void *unused)
7872 + struct port_list *port;
7873 + struct list_head *ele;
7874 + unsigned long flags;
7876 + save_flags(flags);
7877 + list_for_each(ele, &ports){
7878 + port = list_entry(ele, struct port_list, list);
7879 + if(!port->has_connection)
7881 + reactivate_fd(port->fd, ACCEPT_IRQ);
7882 + while(port_accept(port)) ;
7883 + port->has_connection = 0;
7885 + restore_flags(flags);
7888 +struct tq_struct port_task = {
7889 + .routine = port_task_proc,
7893 +static void port_interrupt(int irq, void *data, struct pt_regs *regs)
7895 + struct port_list *port = data;
7897 + port->has_connection = 1;
7898 + schedule_task(&port_task);
7901 +void *port_data(int port_num)
7903 + struct list_head *ele;
7904 + struct port_list *port;
7905 + struct port_dev *dev = NULL;
7909 + list_for_each(ele, &ports){
7910 + port = list_entry(ele, struct port_list, list);
7911 + if(port->port == port_num) goto found;
7913 + port = kmalloc(sizeof(struct port_list), GFP_KERNEL);
7915 + printk(KERN_ERR "Allocation of port list failed\n");
7919 + fd = port_listen_fd(port_num);
7921 + printk(KERN_ERR "binding to port %d failed, errno = %d\n",
7925 + if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
7926 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "port",
7928 + printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
7932 + *port = ((struct port_list)
7933 + { .list = LIST_HEAD_INIT(port->list),
7934 + .has_connection = 0,
7935 + .sem = __SEMAPHORE_INITIALIZER(port->sem,
7937 + .lock = SPIN_LOCK_UNLOCKED,
7940 + .pending = LIST_HEAD_INIT(port->pending),
7941 + .connections = LIST_HEAD_INIT(port->connections) });
7942 + list_add(&port->list, &ports);
7945 + dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL);
7947 + printk(KERN_ERR "Allocation of port device entry failed\n");
7951 + *dev = ((struct port_dev) { .port = port,
7953 + .telnetd_pid = -1 });
7959 + os_close_file(fd);
7965 +int port_wait(void *data)
7967 + struct port_dev *dev = data;
7968 + struct connection *conn;
7969 + struct port_list *port = dev->port;
7973 + if(down_interruptible(&port->sem))
7974 + return(-ERESTARTSYS);
7976 + spin_lock(&port->lock);
7978 + conn = list_entry(port->connections.next, struct connection,
7980 + list_del(&conn->list);
7981 + spin_unlock(&port->lock);
7983 + os_shutdown_socket(conn->socket[0], 1, 1);
7984 + os_close_file(conn->socket[0]);
7985 + os_shutdown_socket(conn->socket[1], 1, 1);
7986 + os_close_file(conn->socket[1]);
7988 + /* This is done here because freeing an IRQ can't be done
7989 + * within the IRQ handler. So, pipe_interrupt always ups
7990 + * the semaphore regardless of whether it got a successful
7991 + * connection. Then we loop here throwing out failed
7992 + * connections until a good one is found.
7994 + free_irq(TELNETD_IRQ, conn);
7996 + if(conn->fd >= 0) break;
7997 + os_close_file(conn->fd);
8002 + dev->helper_pid = conn->helper_pid;
8003 + dev->telnetd_pid = conn->telnetd_pid;
8009 +void port_remove_dev(void *d)
8011 + struct port_dev *dev = d;
8013 + if(dev->helper_pid != -1)
8014 + os_kill_process(dev->helper_pid, 0);
8015 + if(dev->telnetd_pid != -1)
8016 + os_kill_process(dev->telnetd_pid, 1);
8017 + dev->helper_pid = -1;
8018 + dev->telnetd_pid = -1;
8021 +void port_kern_free(void *d)
8023 + struct port_dev *dev = d;
8025 + port_remove_dev(dev);
8029 +static void free_port(void)
8031 + struct list_head *ele;
8032 + struct port_list *port;
8034 + list_for_each(ele, &ports){
8035 + port = list_entry(ele, struct port_list, list);
8036 + free_irq_by_fd(port->fd);
8037 + os_close_file(port->fd);
8041 +__uml_exitcall(free_port);
8044 + * Overrides for Emacs so that we follow Linus's tabbing style.
8045 + * Emacs will notice this stuff at the end of the file and automatically
8046 + * adjust the settings for this buffer only. This must remain at the end
8048 + * ---------------------------------------------------------------------------
8049 + * Local variables:
8050 + * c-file-style: "linux"
8053 diff -Naur -X ../exclude-files orig/arch/um/drivers/port_user.c um/arch/um/drivers/port_user.c
8054 --- orig/arch/um/drivers/port_user.c 1969-12-31 19:00:00.000000000 -0500
8055 +++ um/arch/um/drivers/port_user.c 2003-10-21 03:26:06.000000000 -0400
8058 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
8059 + * Licensed under the GPL
8063 +#include <stddef.h>
8064 +#include <stdlib.h>
8065 +#include <string.h>
8067 +#include <unistd.h>
8068 +#include <termios.h>
8069 +#include <sys/socket.h>
8070 +#include <sys/un.h>
8071 +#include <netinet/in.h>
8072 +#include "user_util.h"
8073 +#include "kern_util.h"
8075 +#include "chan_user.h"
8077 +#include "helper.h"
8082 + struct termios tt;
8083 + void *kernel_data;
8084 + char dev[sizeof("32768\0")];
8087 +void *port_init(char *str, int device, struct chan_opts *opts)
8089 + struct port_chan *data;
8095 + printk("port_init : channel type 'port' must specify a "
8100 + port = strtoul(str, &end, 0);
8101 + if((*end != '\0') || (end == str)){
8102 + printk("port_init : couldn't parse port '%s'\n", str);
8106 + kern_data = port_data(port);
8107 + if(kern_data == NULL)
8110 + data = um_kmalloc(sizeof(*data));
8114 + *data = ((struct port_chan) { .raw = opts->raw,
8115 + .kernel_data = kern_data });
8116 + sprintf(data->dev, "%d", port);
8120 + port_kern_free(kern_data);
8124 +void port_free(void *d)
8126 + struct port_chan *data = d;
8128 + port_kern_free(data->kernel_data);
8132 +int port_open(int input, int output, int primary, void *d, char **dev_out)
8134 + struct port_chan *data = d;
8137 + fd = port_wait(data->kernel_data);
8138 + if((fd >= 0) && data->raw){
8139 + tcgetattr(fd, &data->tt);
8142 + *dev_out = data->dev;
8146 +void port_close(int fd, void *d)
8148 + struct port_chan *data = d;
8150 + port_remove_dev(data->kernel_data);
8151 + os_close_file(fd);
8154 +int port_console_write(int fd, const char *buf, int n, void *d)
8156 + struct port_chan *data = d;
8158 + return(generic_console_write(fd, buf, n, &data->tt));
8161 +struct chan_ops port_ops = {
8163 + .init = port_init,
8164 + .open = port_open,
8165 + .close = port_close,
8166 + .read = generic_read,
8167 + .write = generic_write,
8168 + .console_write = port_console_write,
8169 + .window_size = generic_window_size,
8170 + .free = port_free,
8174 +int port_listen_fd(int port)
8176 + struct sockaddr_in addr;
8179 + fd = socket(PF_INET, SOCK_STREAM, 0);
8183 + addr.sin_family = AF_INET;
8184 + addr.sin_port = htons(port);
8185 + addr.sin_addr.s_addr = htonl(INADDR_ANY);
8186 + if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){
8191 + if(listen(fd, 1) < 0){
8196 + err = os_set_fd_block(fd, 0);
8202 + os_close_file(fd);
8206 +struct port_pre_exec_data {
8211 +void port_pre_exec(void *arg)
8213 + struct port_pre_exec_data *data = arg;
8215 + dup2(data->sock_fd, 0);
8216 + dup2(data->sock_fd, 1);
8217 + dup2(data->sock_fd, 2);
8218 + os_close_file(data->sock_fd);
8219 + dup2(data->pipe_fd, 3);
8220 + os_shutdown_socket(3, 1, 0);
8221 + os_close_file(data->pipe_fd);
8224 +int port_connection(int fd, int *socket, int *pid_out)
8227 + char *argv[] = { "/usr/sbin/in.telnetd", "-L",
8228 + "/usr/lib/uml/port-helper", NULL };
8229 + struct port_pre_exec_data data;
8231 + new = os_accept_connection(fd);
8235 + err = os_pipe(socket, 0, 0);
8239 + data = ((struct port_pre_exec_data)
8241 + .pipe_fd = socket[1] });
8243 + err = run_helper(port_pre_exec, &data, argv, NULL);
8245 + goto out_shutdown;
8251 + os_shutdown_socket(socket[0], 1, 1);
8252 + os_close_file(socket[0]);
8253 + os_shutdown_socket(socket[1], 1, 1);
8254 + os_close_file(socket[1]);
8256 + os_close_file(new);
8261 + * Overrides for Emacs so that we follow Linus's tabbing style.
8262 + * Emacs will notice this stuff at the end of the file and automatically
8263 + * adjust the settings for this buffer only. This must remain at the end
8265 + * ---------------------------------------------------------------------------
8266 + * Local variables:
8267 + * c-file-style: "linux"
8270 diff -Naur -X ../exclude-files orig/arch/um/drivers/pty.c um/arch/um/drivers/pty.c
8271 --- orig/arch/um/drivers/pty.c 1969-12-31 19:00:00.000000000 -0500
8272 +++ um/arch/um/drivers/pty.c 2003-10-21 03:26:06.000000000 -0400
8275 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
8276 + * Licensed under the GPL
8280 +#include <unistd.h>
8281 +#include <string.h>
8283 +#include <termios.h>
8284 +#include "chan_user.h"
8286 +#include "user_util.h"
8287 +#include "kern_util.h"
8291 + void (*announce)(char *dev_name, int dev);
8294 + struct termios tt;
8295 + char dev_name[sizeof("/dev/pts/0123456\0")];
8298 +void *pty_chan_init(char *str, int device, struct chan_opts *opts)
8300 + struct pty_chan *data;
8302 + data = um_kmalloc(sizeof(*data));
8303 + if(data == NULL) return(NULL);
8304 + *data = ((struct pty_chan) { .announce = opts->announce,
8306 + .raw = opts->raw });
8310 +int pts_open(int input, int output, int primary, void *d, char **dev_out)
8312 + struct pty_chan *data = d;
8318 + printk("open_pts : Failed to open pts\n");
8322 + tcgetattr(fd, &data->tt);
8326 + dev = ptsname(fd);
8327 + sprintf(data->dev_name, "%s", dev);
8328 + *dev_out = data->dev_name;
8329 + if(data->announce) (*data->announce)(dev, data->dev);
8333 +int getmaster(char *line)
8335 + char *pty, *bank, *cp;
8338 + pty = &line[strlen("/dev/ptyp")];
8339 + for (bank = "pqrs"; *bank; bank++) {
8340 + line[strlen("/dev/pty")] = *bank;
8342 + if (os_stat_file(line, NULL) < 0)
8344 + for (cp = "0123456789abcdef"; *cp; cp++) {
8346 + master = os_open_file(line, of_rdwr(OPENFLAGS()), 0);
8347 + if (master >= 0) {
8348 + char *tp = &line[strlen("/dev/")];
8350 + /* verify slave side is usable */
8352 + err = os_access(line, OS_ACC_RW_OK);
8354 + if(err == 0) return(master);
8355 + (void) os_close_file(master);
8362 +int pty_open(int input, int output, int primary, void *d, char **dev_out)
8364 + struct pty_chan *data = d;
8366 + char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
8368 + fd = getmaster(dev);
8369 + if(fd < 0) return(-errno);
8371 + if(data->raw) raw(fd, 0);
8372 + if(data->announce) (*data->announce)(dev, data->dev);
8374 + sprintf(data->dev_name, "%s", dev);
8375 + *dev_out = data->dev_name;
8379 +int pty_console_write(int fd, const char *buf, int n, void *d)
8381 + struct pty_chan *data = d;
8383 + return(generic_console_write(fd, buf, n, &data->tt));
8386 +struct chan_ops pty_ops = {
8388 + .init = pty_chan_init,
8390 + .close = generic_close,
8391 + .read = generic_read,
8392 + .write = generic_write,
8393 + .console_write = pty_console_write,
8394 + .window_size = generic_window_size,
8395 + .free = generic_free,
8399 +struct chan_ops pts_ops = {
8401 + .init = pty_chan_init,
8403 + .close = generic_close,
8404 + .read = generic_read,
8405 + .write = generic_write,
8406 + .console_write = pty_console_write,
8407 + .window_size = generic_window_size,
8408 + .free = generic_free,
8413 + * Overrides for Emacs so that we follow Linus's tabbing style.
8414 + * Emacs will notice this stuff at the end of the file and automatically
8415 + * adjust the settings for this buffer only. This must remain at the end
8417 + * ---------------------------------------------------------------------------
8418 + * Local variables:
8419 + * c-file-style: "linux"
8422 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip.h um/arch/um/drivers/slip.h
8423 --- orig/arch/um/drivers/slip.h 1969-12-31 19:00:00.000000000 -0500
8424 +++ um/arch/um/drivers/slip.h 2003-10-21 03:26:06.000000000 -0400
8426 +#ifndef __UM_SLIP_H
8427 +#define __UM_SLIP_H
8429 +#define BUF_SIZE 1500
8430 + /* two bytes each for a (pathological) max packet of escaped chars + *
8431 + * terminating END char + initial END char */
8432 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8436 + char name[sizeof("slnnnnn\0")];
8440 + char ibuf[ENC_BUF_SIZE];
8441 + char obuf[ENC_BUF_SIZE];
8442 + int more; /* more data: do not read fd until ibuf has been drained */
8447 +extern struct net_user_info slip_user_info;
8449 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
8450 +extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri);
8451 +extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri);
8456 + * Overrides for Emacs so that we follow Linus's tabbing style.
8457 + * Emacs will notice this stuff at the end of the file and automatically
8458 + * adjust the settings for this buffer only. This must remain at the end
8460 + * ---------------------------------------------------------------------------
8461 + * Local variables:
8462 + * c-file-style: "linux"
8465 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_kern.c um/arch/um/drivers/slip_kern.c
8466 --- orig/arch/um/drivers/slip_kern.c 1969-12-31 19:00:00.000000000 -0500
8467 +++ um/arch/um/drivers/slip_kern.c 2003-10-21 03:26:06.000000000 -0400
8469 +#include "linux/config.h"
8470 +#include "linux/kernel.h"
8471 +#include "linux/stddef.h"
8472 +#include "linux/init.h"
8473 +#include "linux/netdevice.h"
8474 +#include "linux/if_arp.h"
8475 +#include "net_kern.h"
8476 +#include "net_user.h"
8484 +void slip_init(struct net_device *dev, void *data)
8486 + struct uml_net_private *private;
8487 + struct slip_data *spri;
8488 + struct slip_init *init = data;
8490 + private = dev->priv;
8491 + spri = (struct slip_data *) private->user;
8492 + *spri = ((struct slip_data)
8493 + { .name = { '\0' },
8495 + .gate_addr = init->gate_addr,
8504 + dev->hard_header_len = 0;
8505 + dev->addr_len = 4;
8506 + dev->type = ARPHRD_ETHER;
8507 + dev->tx_queue_len = 256;
8508 + dev->flags = IFF_NOARP;
8509 + printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr);
8512 +static unsigned short slip_protocol(struct sk_buff *skbuff)
8514 + return(htons(ETH_P_IP));
8517 +static int slip_read(int fd, struct sk_buff **skb,
8518 + struct uml_net_private *lp)
8520 + return(slip_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu,
8521 + (struct slip_data *) &lp->user));
8524 +static int slip_write(int fd, struct sk_buff **skb,
8525 + struct uml_net_private *lp)
8527 + return(slip_user_write(fd, (*skb)->data, (*skb)->len,
8528 + (struct slip_data *) &lp->user));
8531 +struct net_kern_info slip_kern_info = {
8532 + .init = slip_init,
8533 + .protocol = slip_protocol,
8534 + .read = slip_read,
8535 + .write = slip_write,
8538 +static int slip_setup(char *str, char **mac_out, void *data)
8540 + struct slip_init *init = data;
8542 + *init = ((struct slip_init)
8543 + { .gate_addr = NULL });
8545 + if(str[0] != '\0')
8546 + init->gate_addr = str;
8550 +static struct transport slip_transport = {
8551 + .list = LIST_HEAD_INIT(slip_transport.list),
8553 + .setup = slip_setup,
8554 + .user = &slip_user_info,
8555 + .kern = &slip_kern_info,
8556 + .private_size = sizeof(struct slip_data),
8557 + .setup_size = sizeof(struct slip_init),
8560 +static int register_slip(void)
8562 + register_transport(&slip_transport);
8566 +__initcall(register_slip);
8569 + * Overrides for Emacs so that we follow Linus's tabbing style.
8570 + * Emacs will notice this stuff at the end of the file and automatically
8571 + * adjust the settings for this buffer only. This must remain at the end
8573 + * ---------------------------------------------------------------------------
8574 + * Local variables:
8575 + * c-file-style: "linux"
8578 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_proto.h um/arch/um/drivers/slip_proto.h
8579 --- orig/arch/um/drivers/slip_proto.h 1969-12-31 19:00:00.000000000 -0500
8580 +++ um/arch/um/drivers/slip_proto.h 2003-10-21 03:26:06.000000000 -0400
8583 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
8584 + * Licensed under the GPL
8587 +#ifndef __UM_SLIP_PROTO_H__
8588 +#define __UM_SLIP_PROTO_H__
8590 +/* SLIP protocol characters. */
8591 +#define SLIP_END 0300 /* indicates end of frame */
8592 +#define SLIP_ESC 0333 /* indicates byte stuffing */
8593 +#define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */
8594 +#define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
8596 +static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc)
8609 + case SLIP_ESC_ESC:
8615 + case SLIP_ESC_END:
8622 + buf[(*pos)++] = c;
8626 +static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
8628 + unsigned char *ptr = d;
8632 + * Send an initial END character to flush out any
8633 + * data that may have accumulated in the receiver
8634 + * due to line noise.
8637 + *ptr++ = SLIP_END;
8640 + * For each byte in the packet, send the appropriate
8641 + * character sequence, according to the SLIP protocol.
8644 + while (len-- > 0) {
8645 + switch(c = *s++) {
8647 + *ptr++ = SLIP_ESC;
8648 + *ptr++ = SLIP_ESC_END;
8651 + *ptr++ = SLIP_ESC;
8652 + *ptr++ = SLIP_ESC_ESC;
8659 + *ptr++ = SLIP_END;
8666 + * Overrides for Emacs so that we follow Linus's tabbing style.
8667 + * Emacs will notice this stuff at the end of the file and automatically
8668 + * adjust the settings for this buffer only. This must remain at the end
8670 + * ---------------------------------------------------------------------------
8671 + * Local variables:
8672 + * c-file-style: "linux"
8675 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_user.c um/arch/um/drivers/slip_user.c
8676 --- orig/arch/um/drivers/slip_user.c 1969-12-31 19:00:00.000000000 -0500
8677 +++ um/arch/um/drivers/slip_user.c 2003-10-21 03:26:06.000000000 -0400
8680 +#include <stdlib.h>
8681 +#include <unistd.h>
8682 +#include <stddef.h>
8684 +#include <string.h>
8685 +#include <sys/errno.h>
8686 +#include <sys/termios.h>
8687 +#include <sys/wait.h>
8688 +#include <sys/signal.h>
8689 +#include "user_util.h"
8690 +#include "kern_util.h"
8692 +#include "net_user.h"
8694 +#include "slip_proto.h"
8695 +#include "helper.h"
8698 +void slip_user_init(void *data, void *dev)
8700 + struct slip_data *pri = data;
8705 +static int set_up_tty(int fd)
8708 + struct termios tios;
8710 + if (tcgetattr(fd, &tios) < 0) {
8711 + printk("could not get initial terminal attributes\n");
8715 + tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
8716 + tios.c_iflag = IGNBRK | IGNPAR;
8719 + for (i = 0; i < NCCS; i++)
8721 + tios.c_cc[VMIN] = 1;
8722 + tios.c_cc[VTIME] = 0;
8724 + cfsetospeed(&tios, B38400);
8725 + cfsetispeed(&tios, B38400);
8727 + if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
8728 + printk("failed to set terminal attributes\n");
8734 +struct slip_pre_exec_data {
8740 +static void slip_pre_exec(void *arg)
8742 + struct slip_pre_exec_data *data = arg;
8744 + if(data->stdin >= 0) dup2(data->stdin, 0);
8745 + dup2(data->stdout, 1);
8746 + if(data->close_me >= 0) os_close_file(data->close_me);
8749 +static int slip_tramp(char **argv, int fd)
8751 + struct slip_pre_exec_data pe_data;
8753 + int status, pid, fds[2], err, output_len;
8755 + err = os_pipe(fds, 1, 0);
8757 + printk("slip_tramp : pipe failed, err = %d\n", -err);
8762 + pe_data.stdin = fd;
8763 + pe_data.stdout = fds[1];
8764 + pe_data.close_me = fds[0];
8765 + pid = run_helper(slip_pre_exec, &pe_data, argv, NULL);
8767 + if(pid < 0) err = pid;
8769 + output_len = page_size();
8770 + output = um_kmalloc(output_len);
8771 + if(output == NULL)
8772 + printk("slip_tramp : failed to allocate output "
8775 + os_close_file(fds[1]);
8776 + read_output(fds[0], output, output_len);
8777 + if(output != NULL){
8778 + printk("%s", output);
8781 + if(waitpid(pid, &status, 0) < 0) err = errno;
8782 + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
8783 + printk("'%s' didn't exit with status 0\n", argv[0]);
8790 +static int slip_open(void *data)
8792 + struct slip_data *pri = data;
8793 + char version_buf[sizeof("nnnnn\0")];
8794 + char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
8795 + char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf,
8797 + int sfd, mfd, err;
8801 + printk("umn : Failed to open pty, err = %d\n", -mfd);
8804 + sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
8806 + printk("Couldn't open tty for slip line, err = %d\n", -sfd);
8809 + if(set_up_tty(sfd)) return(-1);
8813 + if(pri->gate_addr != NULL){
8814 + sprintf(version_buf, "%d", UML_NET_VERSION);
8815 + strcpy(gate_buf, pri->gate_addr);
8817 + err = slip_tramp(argv, sfd);
8820 + printk("slip_tramp failed - err = %d\n", -err);
8823 + err = os_get_ifname(pri->slave, pri->name);
8825 + printk("get_ifname failed, err = %d\n", -err);
8828 + iter_addresses(pri->dev, open_addr, pri->name);
8831 + err = os_set_slip(sfd);
8833 + printk("Failed to set slip discipline encapsulation - "
8834 + "err = %d\n", -err);
8841 +static void slip_close(int fd, void *data)
8843 + struct slip_data *pri = data;
8844 + char version_buf[sizeof("nnnnn\0")];
8845 + char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
8849 + if(pri->gate_addr != NULL)
8850 + iter_addresses(pri->dev, close_addr, pri->name);
8852 + sprintf(version_buf, "%d", UML_NET_VERSION);
8854 + err = slip_tramp(argv, -1);
8857 + printk("slip_tramp failed - errno = %d\n", -err);
8858 + os_close_file(fd);
8859 + os_close_file(pri->slave);
8863 +int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
8865 + int i, n, size, start;
8869 + while(i < pri->more) {
8870 + size = slip_unesc(pri->ibuf[i++],
8871 + pri->ibuf, &pri->pos, &pri->esc);
8873 + memcpy(buf, pri->ibuf, size);
8874 + memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
8875 + pri->more=pri->more-i;
8882 + n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
8883 + if(n <= 0) return(n);
8886 + for(i = 0; i < n; i++){
8887 + size = slip_unesc(pri->ibuf[start + i],
8888 + pri->ibuf, &pri->pos, &pri->esc);
8890 + memcpy(buf, pri->ibuf, size);
8891 + memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
8892 + pri->more=n-(i+1);
8899 +int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
8903 + actual = slip_esc(buf, pri->obuf, len);
8904 + n = net_write(fd, pri->obuf, actual);
8905 + if(n < 0) return(n);
8909 +static int slip_set_mtu(int mtu, void *data)
8914 +static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
8917 + struct slip_data *pri = data;
8919 + if(pri->slave < 0) return;
8920 + open_addr(addr, netmask, pri->name);
8923 +static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
8926 + struct slip_data *pri = data;
8928 + if(pri->slave < 0) return;
8929 + close_addr(addr, netmask, pri->name);
8932 +struct net_user_info slip_user_info = {
8933 + .init = slip_user_init,
8934 + .open = slip_open,
8935 + .close = slip_close,
8937 + .set_mtu = slip_set_mtu,
8938 + .add_address = slip_add_addr,
8939 + .delete_address = slip_del_addr,
8940 + .max_packet = BUF_SIZE
8944 + * Overrides for Emacs so that we follow Linus's tabbing style.
8945 + * Emacs will notice this stuff at the end of the file and automatically
8946 + * adjust the settings for this buffer only. This must remain at the end
8948 + * ---------------------------------------------------------------------------
8949 + * Local variables:
8950 + * c-file-style: "linux"
8953 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp.h um/arch/um/drivers/slirp.h
8954 --- orig/arch/um/drivers/slirp.h 1969-12-31 19:00:00.000000000 -0500
8955 +++ um/arch/um/drivers/slirp.h 2003-10-21 03:26:06.000000000 -0400
8957 +#ifndef __UM_SLIRP_H
8958 +#define __UM_SLIRP_H
8960 +#define BUF_SIZE 1500
8961 + /* two bytes each for a (pathological) max packet of escaped chars + *
8962 + * terminating END char + initial END char */
8963 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8965 +#define SLIRP_MAX_ARGS 100
8967 + * XXX this next definition is here because I don't understand why this
8968 + * initializer doesn't work in slirp_kern.c:
8970 + * argv : { init->argv[ 0 ... SLIRP_MAX_ARGS-1 ] },
8972 + * or why I can't typecast like this:
8974 + * argv : (char* [SLIRP_MAX_ARGS])(init->argv),
8976 +struct arg_list_dummy_wrapper { char *argv[SLIRP_MAX_ARGS]; };
8978 +struct slirp_data {
8980 + struct arg_list_dummy_wrapper argw;
8983 + char ibuf[ENC_BUF_SIZE];
8984 + char obuf[ENC_BUF_SIZE];
8985 + int more; /* more data: do not read fd until ibuf has been drained */
8990 +extern struct net_user_info slirp_user_info;
8992 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
8993 +extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri);
8994 +extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri);
8999 + * Overrides for Emacs so that we follow Linus's tabbing style.
9000 + * Emacs will notice this stuff at the end of the file and automatically
9001 + * adjust the settings for this buffer only. This must remain at the end
9003 + * ---------------------------------------------------------------------------
9004 + * Local variables:
9005 + * c-file-style: "linux"
9008 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_kern.c um/arch/um/drivers/slirp_kern.c
9009 --- orig/arch/um/drivers/slirp_kern.c 1969-12-31 19:00:00.000000000 -0500
9010 +++ um/arch/um/drivers/slirp_kern.c 2003-10-21 03:26:06.000000000 -0400
9012 +#include "linux/kernel.h"
9013 +#include "linux/stddef.h"
9014 +#include "linux/init.h"
9015 +#include "linux/netdevice.h"
9016 +#include "linux/if_arp.h"
9017 +#include "net_kern.h"
9018 +#include "net_user.h"
9022 +struct slirp_init {
9023 + struct arg_list_dummy_wrapper argw; /* XXX should be simpler... */
9026 +void slirp_init(struct net_device *dev, void *data)
9028 + struct uml_net_private *private;
9029 + struct slirp_data *spri;
9030 + struct slirp_init *init = data;
9033 + private = dev->priv;
9034 + spri = (struct slirp_data *) private->user;
9035 + *spri = ((struct slirp_data)
9036 + { .argw = init->argw,
9046 + dev->hard_header_len = 0;
9047 + dev->addr_len = 4;
9048 + dev->type = ARPHRD_ETHER;
9049 + dev->tx_queue_len = 256;
9050 + dev->flags = IFF_NOARP;
9051 + printk("SLIRP backend - command line:");
9052 + for(i=0;spri->argw.argv[i]!=NULL;i++) {
9053 + printk(" '%s'",spri->argw.argv[i]);
9058 +static unsigned short slirp_protocol(struct sk_buff *skbuff)
9060 + return(htons(ETH_P_IP));
9063 +static int slirp_read(int fd, struct sk_buff **skb,
9064 + struct uml_net_private *lp)
9066 + return(slirp_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu,
9067 + (struct slirp_data *) &lp->user));
9070 +static int slirp_write(int fd, struct sk_buff **skb,
9071 + struct uml_net_private *lp)
9073 + return(slirp_user_write(fd, (*skb)->data, (*skb)->len,
9074 + (struct slirp_data *) &lp->user));
9077 +struct net_kern_info slirp_kern_info = {
9078 + .init = slirp_init,
9079 + .protocol = slirp_protocol,
9080 + .read = slirp_read,
9081 + .write = slirp_write,
9084 +static int slirp_setup(char *str, char **mac_out, void *data)
9086 + struct slirp_init *init = data;
9089 + *init = ((struct slirp_init)
9090 + { argw : { { "slirp", NULL } } });
9092 + str = split_if_spec(str, mac_out, NULL);
9094 + if(str == NULL) { /* no command line given after MAC addr */
9099 + if(i>=SLIRP_MAX_ARGS-1) {
9100 + printk("slirp_setup: truncating slirp arguments\n");
9103 + init->argw.argv[i++] = str;
9104 + while(*str && *str!=',') {
9105 + if(*str=='_') *str=' ';
9112 + init->argw.argv[i]=NULL;
9116 +static struct transport slirp_transport = {
9117 + .list = LIST_HEAD_INIT(slirp_transport.list),
9119 + .setup = slirp_setup,
9120 + .user = &slirp_user_info,
9121 + .kern = &slirp_kern_info,
9122 + .private_size = sizeof(struct slirp_data),
9123 + .setup_size = sizeof(struct slirp_init),
9126 +static int register_slirp(void)
9128 + register_transport(&slirp_transport);
9132 +__initcall(register_slirp);
9135 + * Overrides for Emacs so that we follow Linus's tabbing style.
9136 + * Emacs will notice this stuff at the end of the file and automatically
9137 + * adjust the settings for this buffer only. This must remain at the end
9139 + * ---------------------------------------------------------------------------
9140 + * Local variables:
9141 + * c-file-style: "linux"
9144 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_user.c um/arch/um/drivers/slirp_user.c
9145 --- orig/arch/um/drivers/slirp_user.c 1969-12-31 19:00:00.000000000 -0500
9146 +++ um/arch/um/drivers/slirp_user.c 2003-10-21 03:26:06.000000000 -0400
9149 +#include <stdlib.h>
9150 +#include <unistd.h>
9151 +#include <stddef.h>
9153 +#include <string.h>
9154 +#include <sys/errno.h>
9155 +#include <sys/wait.h>
9156 +#include <sys/signal.h>
9157 +#include "user_util.h"
9158 +#include "kern_util.h"
9160 +#include "net_user.h"
9162 +#include "slip_proto.h"
9163 +#include "helper.h"
9166 +void slirp_user_init(void *data, void *dev)
9168 + struct slirp_data *pri = data;
9173 +struct slirp_pre_exec_data {
9178 +static void slirp_pre_exec(void *arg)
9180 + struct slirp_pre_exec_data *data = arg;
9182 + if(data->stdin != -1) dup2(data->stdin, 0);
9183 + if(data->stdout != -1) dup2(data->stdout, 1);
9186 +static int slirp_tramp(char **argv, int fd)
9188 + struct slirp_pre_exec_data pe_data;
9191 + pe_data.stdin = fd;
9192 + pe_data.stdout = fd;
9193 + pid = run_helper(slirp_pre_exec, &pe_data, argv, NULL);
9198 +/* XXX This is just a trivial wrapper around os_pipe */
9199 +static int slirp_datachan(int *mfd, int *sfd)
9203 + err = os_pipe(fds, 1, 1);
9205 + printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
9214 +static int slirp_open(void *data)
9216 + struct slirp_data *pri = data;
9217 + int sfd, mfd, pid, err;
9219 + err = slirp_datachan(&mfd, &sfd);
9223 + pid = slirp_tramp(pri->argw.argv, sfd);
9226 + printk("slirp_tramp failed - errno = %d\n", -pid);
9227 + os_close_file(sfd);
9228 + os_close_file(mfd);
9241 +static void slirp_close(int fd, void *data)
9243 + struct slirp_data *pri = data;
9246 + os_close_file(fd);
9247 + os_close_file(pri->slave);
9252 + printk("slirp_close: no child process to shut down\n");
9257 + if(kill(pri->pid, SIGHUP)<0) {
9258 + printk("slirp_close: sending hangup to %d failed (%d)\n",
9263 + err = waitpid(pri->pid, &status, WNOHANG);
9265 + printk("slirp_close: waitpid returned %d\n", errno);
9270 + printk("slirp_close: process %d has not exited\n");
9277 +int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
9279 + int i, n, size, start;
9283 + while(i < pri->more) {
9284 + size = slip_unesc(pri->ibuf[i++],
9285 + pri->ibuf,&pri->pos,&pri->esc);
9287 + memcpy(buf, pri->ibuf, size);
9288 + memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
9289 + pri->more=pri->more-i;
9296 + n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
9297 + if(n <= 0) return(n);
9300 + for(i = 0; i < n; i++){
9301 + size = slip_unesc(pri->ibuf[start + i],
9302 + pri->ibuf,&pri->pos,&pri->esc);
9304 + memcpy(buf, pri->ibuf, size);
9305 + memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
9306 + pri->more=n-(i+1);
9313 +int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
9317 + actual = slip_esc(buf, pri->obuf, len);
9318 + n = net_write(fd, pri->obuf, actual);
9319 + if(n < 0) return(n);
9323 +static int slirp_set_mtu(int mtu, void *data)
9328 +struct net_user_info slirp_user_info = {
9329 + .init = slirp_user_init,
9330 + .open = slirp_open,
9331 + .close = slirp_close,
9333 + .set_mtu = slirp_set_mtu,
9334 + .add_address = NULL,
9335 + .delete_address = NULL,
9336 + .max_packet = BUF_SIZE
9340 + * Overrides for Emacs so that we follow Linus's tabbing style.
9341 + * Emacs will notice this stuff at the end of the file and automatically
9342 + * adjust the settings for this buffer only. This must remain at the end
9344 + * ---------------------------------------------------------------------------
9345 + * Local variables:
9346 + * c-file-style: "linux"
9349 diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.c um/arch/um/drivers/ssl.c
9350 --- orig/arch/um/drivers/ssl.c 1969-12-31 19:00:00.000000000 -0500
9351 +++ um/arch/um/drivers/ssl.c 2003-11-08 02:57:02.000000000 -0500
9354 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
9355 + * Licensed under the GPL
9358 +#include "linux/config.h"
9359 +#include "linux/fs.h"
9360 +#include "linux/tty.h"
9361 +#include "linux/tty_driver.h"
9362 +#include "linux/major.h"
9363 +#include "linux/mm.h"
9364 +#include "linux/init.h"
9365 +#include "linux/console.h"
9366 +#include "asm/termbits.h"
9367 +#include "asm/irq.h"
9370 +#include "chan_kern.h"
9371 +#include "user_util.h"
9372 +#include "kern_util.h"
9375 +#include "irq_user.h"
9376 +#include "mconsole_kern.h"
9377 +#include "2_5compat.h"
9379 +static int ssl_version = 1;
9381 +/* Referenced only by tty_driver below - presumably it's locked correctly
9382 + * by the tty driver.
9384 +static int ssl_refcount = 0;
9386 +static struct tty_driver ssl_driver;
9388 +#define NR_PORTS 64
9390 +void ssl_announce(char *dev_name, int dev)
9392 + printk(KERN_INFO "Serial line %d assigned device '%s'\n", dev,
9396 +static struct chan_opts opts = {
9397 + .announce = ssl_announce,
9398 + .xterm_title = "Serial Line #%d",
9404 +static int ssl_config(char *str);
9405 +static int ssl_get_config(char *dev, char *str, int size, char **error_out);
9406 +static int ssl_remove(char *str);
9408 +static struct line_driver driver = {
9409 + .name = "UML serial line",
9410 + .devfs_name = "tts/%d",
9411 + .major = TTY_MAJOR,
9412 + .minor_start = 64,
9413 + .type = TTY_DRIVER_TYPE_SERIAL,
9415 + .read_irq = SSL_IRQ,
9416 + .read_irq_name = "ssl",
9417 + .write_irq = SSL_WRITE_IRQ,
9418 + .write_irq_name = "ssl-write",
9419 + .symlink_from = "serial",
9420 + .symlink_to = "tts",
9423 + .config = ssl_config,
9424 + .get_config = ssl_get_config,
9425 + .remove = ssl_remove,
9429 +/* The array is initialized by line_init, which is an initcall. The
9430 + * individual elements are protected by individual semaphores.
9432 +static struct line serial_lines[NR_PORTS] =
9433 + { [0 ... NR_PORTS - 1] = LINE_INIT(CONFIG_SSL_CHAN, &driver) };
9435 +static struct lines lines = LINES_INIT(NR_PORTS);
9437 +static int ssl_config(char *str)
9439 + return(line_config(serial_lines,
9440 + sizeof(serial_lines)/sizeof(serial_lines[0]), str));
9443 +static int ssl_get_config(char *dev, char *str, int size, char **error_out)
9445 + return(line_get_config(dev, serial_lines,
9446 + sizeof(serial_lines)/sizeof(serial_lines[0]),
9447 + str, size, error_out));
9450 +static int ssl_remove(char *str)
9452 + return(line_remove(serial_lines,
9453 + sizeof(serial_lines)/sizeof(serial_lines[0]), str));
9456 +int ssl_open(struct tty_struct *tty, struct file *filp)
9458 + return(line_open(serial_lines, tty, &opts));
9461 +static void ssl_close(struct tty_struct *tty, struct file * filp)
9463 + line_close(serial_lines, tty);
9466 +static int ssl_write(struct tty_struct * tty, int from_user,
9467 + const unsigned char *buf, int count)
9469 + return(line_write(serial_lines, tty, from_user, buf, count));
9472 +static void ssl_put_char(struct tty_struct *tty, unsigned char ch)
9474 + line_write(serial_lines, tty, 0, &ch, sizeof(ch));
9477 +static void ssl_flush_chars(struct tty_struct *tty)
9482 +static int ssl_chars_in_buffer(struct tty_struct *tty)
9487 +static void ssl_flush_buffer(struct tty_struct *tty)
9492 +static int ssl_ioctl(struct tty_struct *tty, struct file * file,
9493 + unsigned int cmd, unsigned long arg)
9509 + ret = -ENOIOCTLCMD;
9513 + "Unimplemented ioctl in ssl_ioctl : 0x%x\n", cmd);
9514 + ret = -ENOIOCTLCMD;
9520 +static void ssl_throttle(struct tty_struct * tty)
9522 + printk(KERN_ERR "Someone should implement ssl_throttle\n");
9525 +static void ssl_unthrottle(struct tty_struct * tty)
9527 + printk(KERN_ERR "Someone should implement ssl_unthrottle\n");
9530 +static void ssl_set_termios(struct tty_struct *tty,
9531 + struct termios *old_termios)
9535 +static void ssl_stop(struct tty_struct *tty)
9537 + printk(KERN_ERR "Someone should implement ssl_stop\n");
9540 +static void ssl_start(struct tty_struct *tty)
9542 + printk(KERN_ERR "Someone should implement ssl_start\n");
9545 +void ssl_hangup(struct tty_struct *tty)
9549 +static struct tty_driver ssl_driver = {
9550 + .refcount = &ssl_refcount,
9552 + .close = ssl_close,
9553 + .write = ssl_write,
9554 + .put_char = ssl_put_char,
9555 + .flush_chars = ssl_flush_chars,
9556 + .chars_in_buffer = ssl_chars_in_buffer,
9557 + .flush_buffer = ssl_flush_buffer,
9558 + .ioctl = ssl_ioctl,
9559 + .throttle = ssl_throttle,
9560 + .unthrottle = ssl_unthrottle,
9561 + .set_termios = ssl_set_termios,
9563 + .start = ssl_start,
9564 + .hangup = ssl_hangup
9567 +/* Changed by ssl_init and referenced by ssl_exit, which are both serialized
9568 + * by being an initcall and exitcall, respectively.
9570 +static int ssl_init_done = 0;
9572 +static void ssl_console_write(struct console *c, const char *string,
9575 + struct line *line = &serial_lines[c->index];
9578 + console_write_chan(&line->chan_list, string, len);
9583 +static kdev_t ssl_console_device(struct console *c)
9585 +#if 0 /* This is the 2.5 implementation */
9586 +static struct tty_driver *ssl_console_device(struct console *c, int *index)
9587 + *index = c->index;
9588 + return ssl_driver;
9591 + return mk_kdev(TTY_MAJOR, c->index);
9594 +static int ssl_console_setup(struct console *co, char *options)
9599 +static struct console ssl_cons = {
9601 + write: ssl_console_write,
9602 + device: ssl_console_device,
9603 + setup: ssl_console_setup,
9604 + flags: CON_PRINTBUFFER,
9612 + printk(KERN_INFO "Initializing software serial port version %d\n",
9615 + line_register_devfs(&lines, &driver, &ssl_driver, serial_lines,
9616 + sizeof(serial_lines)/sizeof(serial_lines[0]));
9618 + lines_init(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]));
9620 + new_title = add_xterm_umid(opts.xterm_title);
9621 + if(new_title != NULL) opts.xterm_title = new_title;
9623 + register_console(&ssl_cons);
9624 + ssl_init_done = 1;
9628 +__initcall(ssl_init);
9630 +static int ssl_chan_setup(char *str)
9632 + return(line_setup(serial_lines,
9633 + sizeof(serial_lines)/sizeof(serial_lines[0]),
9637 +__setup("ssl", ssl_chan_setup);
9638 +__channel_help(ssl_chan_setup, "ssl");
9640 +static void ssl_exit(void)
9642 + if(!ssl_init_done) return;
9643 + close_lines(serial_lines,
9644 + sizeof(serial_lines)/sizeof(serial_lines[0]));
9647 +__uml_exitcall(ssl_exit);
9650 + * Overrides for Emacs so that we follow Linus's tabbing style.
9651 + * Emacs will notice this stuff at the end of the file and automatically
9652 + * adjust the settings for this buffer only. This must remain at the end
9654 + * ---------------------------------------------------------------------------
9655 + * Local variables:
9656 + * c-file-style: "linux"
9659 diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.h um/arch/um/drivers/ssl.h
9660 --- orig/arch/um/drivers/ssl.h 1969-12-31 19:00:00.000000000 -0500
9661 +++ um/arch/um/drivers/ssl.h 2003-10-21 03:26:06.000000000 -0400
9664 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9665 + * Licensed under the GPL
9671 +extern int ssl_read(int fd, int line);
9672 +extern void ssl_receive_char(int line, char ch);
9677 + * Overrides for Emacs so that we follow Linus's tabbing style.
9678 + * Emacs will notice this stuff at the end of the file and automatically
9679 + * adjust the settings for this buffer only. This must remain at the end
9681 + * ---------------------------------------------------------------------------
9682 + * Local variables:
9683 + * c-file-style: "linux"
9686 diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.c um/arch/um/drivers/stdio_console.c
9687 --- orig/arch/um/drivers/stdio_console.c 1969-12-31 19:00:00.000000000 -0500
9688 +++ um/arch/um/drivers/stdio_console.c 2003-11-07 03:03:03.000000000 -0500
9691 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
9692 + * Licensed under the GPL
9695 +#include "linux/config.h"
9696 +#include "linux/posix_types.h"
9697 +#include "linux/tty.h"
9698 +#include "linux/tty_flip.h"
9699 +#include "linux/types.h"
9700 +#include "linux/major.h"
9701 +#include "linux/kdev_t.h"
9702 +#include "linux/console.h"
9703 +#include "linux/string.h"
9704 +#include "linux/sched.h"
9705 +#include "linux/list.h"
9706 +#include "linux/init.h"
9707 +#include "linux/interrupt.h"
9708 +#include "linux/slab.h"
9709 +#include "asm/current.h"
9710 +#include "asm/softirq.h"
9711 +#include "asm/hardirq.h"
9712 +#include "asm/irq.h"
9713 +#include "stdio_console.h"
9715 +#include "chan_kern.h"
9716 +#include "user_util.h"
9717 +#include "kern_util.h"
9718 +#include "irq_user.h"
9719 +#include "mconsole_kern.h"
9721 +#include "2_5compat.h"
9723 +#define MAX_TTYS (8)
9725 +/* Referenced only by tty_driver below - presumably it's locked correctly
9726 + * by the tty driver.
9729 +static struct tty_driver console_driver;
9731 +static int console_refcount = 0;
9733 +static struct chan_ops init_console_ops = {
9734 + .type = "you shouldn't see this",
9740 + .console_write = generic_write,
9741 + .window_size = NULL,
9746 +static struct chan init_console_chan = {
9753 + .pri = INIT_STATIC,
9754 + .ops = &init_console_ops,
9758 +void stdio_announce(char *dev_name, int dev)
9760 + printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
9764 +static struct chan_opts opts = {
9765 + .announce = stdio_announce,
9766 + .xterm_title = "Virtual Console #%d",
9772 +static int con_config(char *str);
9773 +static int con_get_config(char *dev, char *str, int size, char **error_out);
9774 +static int con_remove(char *str);
9776 +static struct line_driver driver = {
9777 + .name = "UML console",
9778 + .devfs_name = "vc/%d",
9779 + .major = TTY_MAJOR,
9781 + .type = TTY_DRIVER_TYPE_CONSOLE,
9782 + .subtype = SYSTEM_TYPE_CONSOLE,
9783 + .read_irq = CONSOLE_IRQ,
9784 + .read_irq_name = "console",
9785 + .write_irq = CONSOLE_WRITE_IRQ,
9786 + .write_irq_name = "console-write",
9787 + .symlink_from = "ttys",
9788 + .symlink_to = "vc",
9791 + .config = con_config,
9792 + .get_config = con_get_config,
9793 + .remove = con_remove,
9797 +static struct lines console_lines = LINES_INIT(MAX_TTYS);
9799 +/* The array is initialized by line_init, which is an initcall. The
9800 + * individual elements are protected by individual semaphores.
9802 +struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
9803 + [ 1 ... MAX_TTYS - 1 ] =
9804 + LINE_INIT(CONFIG_CON_CHAN, &driver) };
9806 +static int con_config(char *str)
9808 + return(line_config(vts, sizeof(vts)/sizeof(vts[0]), str));
9811 +static int con_get_config(char *dev, char *str, int size, char **error_out)
9813 + return(line_get_config(dev, vts, sizeof(vts)/sizeof(vts[0]), str,
9814 + size, error_out));
9817 +static int con_remove(char *str)
9819 + return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str));
9822 +static int open_console(struct tty_struct *tty)
9824 + return(line_open(vts, tty, &opts));
9827 +static int con_open(struct tty_struct *tty, struct file *filp)
9829 + return(open_console(tty));
9832 +static void con_close(struct tty_struct *tty, struct file *filp)
9834 + line_close(vts, tty);
9837 +static int con_write(struct tty_struct *tty, int from_user,
9838 + const unsigned char *buf, int count)
9840 + return(line_write(vts, tty, from_user, buf, count));
9843 +static void set_termios(struct tty_struct *tty, struct termios * old)
9847 +static int chars_in_buffer(struct tty_struct *tty)
9852 +static int con_init_done = 0;
9854 +int stdio_init(void)
9858 + printk(KERN_INFO "Initializing stdio console driver\n");
9860 + line_register_devfs(&console_lines, &driver, &console_driver, vts,
9861 + sizeof(vts)/sizeof(vts[0]));
9863 + lines_init(vts, sizeof(vts)/sizeof(vts[0]));
9865 + new_title = add_xterm_umid(opts.xterm_title);
9866 + if(new_title != NULL) opts.xterm_title = new_title;
9868 + open_console(NULL);
9869 + con_init_done = 1;
9873 +__initcall(stdio_init);
9875 +static void console_write(struct console *console, const char *string,
9878 + struct line *line = &vts[console->index];
9882 + console_write_chan(&line->chan_list, string, len);
9887 +static struct tty_driver console_driver = {
9888 + .refcount = &console_refcount,
9890 + .close = con_close,
9891 + .write = con_write,
9892 + .chars_in_buffer = chars_in_buffer,
9893 + .set_termios = set_termios
9896 +static kdev_t console_device(struct console *c)
9898 + return mk_kdev(TTY_MAJOR, c->index);
9901 +static int console_setup(struct console *co, char *options)
9906 +static struct console stdiocons = {
9908 + write: console_write,
9909 + device: console_device,
9910 + setup: console_setup,
9911 + flags: CON_PRINTBUFFER,
9915 +void stdio_console_init(void)
9917 + INIT_LIST_HEAD(&vts[0].chan_list);
9918 + list_add(&init_console_chan.list, &vts[0].chan_list);
9919 + register_console(&stdiocons);
9922 +static int console_chan_setup(char *str)
9924 + return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
9927 +__setup("con", console_chan_setup);
9928 +__channel_help(console_chan_setup, "con");
9930 +static void console_exit(void)
9932 + if(!con_init_done) return;
9933 + close_lines(vts, sizeof(vts)/sizeof(vts[0]));
9936 +__uml_exitcall(console_exit);
9939 + * Overrides for Emacs so that we follow Linus's tabbing style.
9940 + * Emacs will notice this stuff at the end of the file and automatically
9941 + * adjust the settings for this buffer only. This must remain at the end
9943 + * ---------------------------------------------------------------------------
9944 + * Local variables:
9945 + * c-file-style: "linux"
9948 diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.h um/arch/um/drivers/stdio_console.h
9949 --- orig/arch/um/drivers/stdio_console.h 1969-12-31 19:00:00.000000000 -0500
9950 +++ um/arch/um/drivers/stdio_console.h 2003-10-21 03:26:06.000000000 -0400
9953 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9954 + * Licensed under the GPL
9957 +#ifndef __STDIO_CONSOLE_H
9958 +#define __STDIO_CONSOLE_H
9960 +extern void save_console_flags(void);
9964 + * Overrides for Emacs so that we follow Linus's tabbing style.
9965 + * Emacs will notice this stuff at the end of the file and automatically
9966 + * adjust the settings for this buffer only. This must remain at the end
9968 + * ---------------------------------------------------------------------------
9969 + * Local variables:
9970 + * c-file-style: "linux"
9973 diff -Naur -X ../exclude-files orig/arch/um/drivers/tty.c um/arch/um/drivers/tty.c
9974 --- orig/arch/um/drivers/tty.c 1969-12-31 19:00:00.000000000 -0500
9975 +++ um/arch/um/drivers/tty.c 2003-10-21 03:26:06.000000000 -0400
9978 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
9979 + * Licensed under the GPL
9983 +#include <termios.h>
9985 +#include <unistd.h>
9986 +#include "chan_user.h"
9987 +#include "user_util.h"
9994 + struct termios tt;
9997 +void *tty_chan_init(char *str, int device, struct chan_opts *opts)
9999 + struct tty_chan *data;
10002 + printk("tty_init : channel type 'tty' must specify "
10008 + data = um_kmalloc(sizeof(*data));
10011 + *data = ((struct tty_chan) { .dev = str,
10012 + .raw = opts->raw });
10017 +int tty_open(int input, int output, int primary, void *d, char **dev_out)
10019 + struct tty_chan *data = d;
10022 + fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0);
10023 + if(fd < 0) return(fd);
10025 + tcgetattr(fd, &data->tt);
10029 + *dev_out = data->dev;
10033 +int tty_console_write(int fd, const char *buf, int n, void *d)
10035 + struct tty_chan *data = d;
10037 + return(generic_console_write(fd, buf, n, &data->tt));
10040 +struct chan_ops tty_ops = {
10042 + .init = tty_chan_init,
10043 + .open = tty_open,
10044 + .close = generic_close,
10045 + .read = generic_read,
10046 + .write = generic_write,
10047 + .console_write = tty_console_write,
10048 + .window_size = generic_window_size,
10049 + .free = generic_free,
10054 + * Overrides for Emacs so that we follow Linus's tabbing style.
10055 + * Emacs will notice this stuff at the end of the file and automatically
10056 + * adjust the settings for this buffer only. This must remain at the end
10058 + * ---------------------------------------------------------------------------
10059 + * Local variables:
10060 + * c-file-style: "linux"
10063 diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_kern.c um/arch/um/drivers/ubd_kern.c
10064 --- orig/arch/um/drivers/ubd_kern.c 1969-12-31 19:00:00.000000000 -0500
10065 +++ um/arch/um/drivers/ubd_kern.c 2003-12-17 10:48:17.000000000 -0500
10068 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
10069 + * Licensed under the GPL
10072 +/* 2001-09-28...2002-04-17
10073 + * Partition stuff by James_McMechan@hotmail.com
10074 + * old style ubd by setting UBD_SHIFT to 0
10077 +#define MAJOR_NR UBD_MAJOR
10078 +#define UBD_SHIFT 4
10080 +#include "linux/config.h"
10081 +#include "linux/blk.h"
10082 +#include "linux/blkdev.h"
10083 +#include "linux/hdreg.h"
10084 +#include "linux/init.h"
10085 +#include "linux/devfs_fs_kernel.h"
10086 +#include "linux/cdrom.h"
10087 +#include "linux/proc_fs.h"
10088 +#include "linux/ctype.h"
10089 +#include "linux/capability.h"
10090 +#include "linux/mm.h"
10091 +#include "linux/vmalloc.h"
10092 +#include "linux/blkpg.h"
10093 +#include "linux/genhd.h"
10094 +#include "linux/spinlock.h"
10095 +#include "asm/segment.h"
10096 +#include "asm/uaccess.h"
10097 +#include "asm/irq.h"
10098 +#include "asm/types.h"
10099 +#include "user_util.h"
10100 +#include "mem_user.h"
10101 +#include "kern_util.h"
10103 +#include "mconsole_kern.h"
10105 +#include "irq_user.h"
10106 +#include "irq_kern.h"
10107 +#include "ubd_user.h"
10108 +#include "2_5compat.h"
10111 +#include "mem_kern.h"
10113 +static int ubd_open(struct inode * inode, struct file * filp);
10114 +static int ubd_release(struct inode * inode, struct file * file);
10115 +static int ubd_ioctl(struct inode * inode, struct file * file,
10116 + unsigned int cmd, unsigned long arg);
10117 +static int ubd_revalidate(kdev_t rdev);
10118 +static int ubd_revalidate1(kdev_t rdev);
10120 +#define MAX_DEV (8)
10121 +#define MAX_MINOR (MAX_DEV << UBD_SHIFT)
10123 +/* Changed in early boot */
10124 +static int ubd_do_mmap = 0;
10125 +#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
10127 +/* Not modified by this driver */
10128 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
10129 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
10131 +/* Protected by ubd_lock */
10132 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
10134 +static struct block_device_operations ubd_blops = {
10135 + .open = ubd_open,
10136 + .release = ubd_release,
10137 + .ioctl = ubd_ioctl,
10138 + .revalidate = ubd_revalidate,
10141 +/* Protected by ubd_lock, except in prepare_request and ubd_ioctl because
10142 + * the block layer should ensure that the device is idle before closing it.
10144 +static struct hd_struct ubd_part[MAX_MINOR] =
10145 + { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
10147 +/* Protected by io_request_lock */
10148 +static request_queue_t *ubd_queue;
10150 +/* Protected by ubd_lock */
10151 +static int fake_major = MAJOR_NR;
10153 +static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
10155 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
10158 + .major_name = name, \
10159 + .minor_shift = shift, \
10160 + .max_p = 1 << shift, \
10162 + .sizes = bsizes, \
10163 + .nr_real = max, \
10164 + .real_devices = NULL, \
10167 + .de_arr = NULL, \
10171 +static struct gendisk ubd_gendisk = INIT_GENDISK(MAJOR_NR, "ubd", ubd_part,
10172 + UBD_SHIFT, sizes, MAX_DEV,
10174 +static struct gendisk fake_gendisk = INIT_GENDISK(0, "ubd", ubd_part,
10175 + UBD_SHIFT, sizes, MAX_DEV,
10178 +#ifdef CONFIG_BLK_DEV_UBD_SYNC
10179 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
10182 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \
10186 +/* Not protected - changed only in ubd_setup_common and then only to
10187 + * to enable O_SYNC.
10189 +static struct openflags global_openflags = OPEN_FLAGS;
10194 + unsigned long *bitmap;
10195 + unsigned long bitmap_len;
10196 + int bitmap_offset;
10205 + struct openflags boot_openflags;
10206 + struct openflags openflags;
10207 + devfs_handle_t devfs;
10213 + int nomap_writes;
10218 +#define DEFAULT_COW { \
10221 + .bitmap = NULL, \
10222 + .bitmap_offset = 0, \
10223 + .data_offset = 0, \
10226 +#define DEFAULT_UBD { \
10231 + .boot_openflags = OPEN_FLAGS, \
10232 + .openflags = OPEN_FLAGS, \
10235 + .cow = DEFAULT_COW, \
10236 + .map_writes = 0, \
10237 + .map_reads = 0, \
10238 + .nomap_writes = 0, \
10239 + .nomap_reads = 0, \
10240 + .write_maps = 0, \
10243 +struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
10245 +static int ubd0_init(void)
10247 + struct ubd *dev = &ubd_dev[0];
10249 + if(dev->file == NULL)
10250 + dev->file = "root_fs";
10254 +__initcall(ubd0_init);
10256 +/* Only changed by fake_ide_setup which is a setup */
10257 +static int fake_ide = 0;
10258 +static struct proc_dir_entry *proc_ide_root = NULL;
10259 +static struct proc_dir_entry *proc_ide = NULL;
10261 +static void make_proc_ide(void)
10263 + proc_ide_root = proc_mkdir("ide", 0);
10264 + proc_ide = proc_mkdir("ide0", proc_ide_root);
10267 +static int proc_ide_read_media(char *page, char **start, off_t off, int count,
10268 + int *eof, void *data)
10272 + strcpy(page, "disk\n");
10273 + len = strlen("disk\n");
10275 + if (len < count){
10277 + if (len <= 0) return 0;
10279 + else len = count;
10280 + *start = page + off;
10284 +static void make_ide_entries(char *dev_name)
10286 + struct proc_dir_entry *dir, *ent;
10289 + if(!fake_ide) return;
10291 + /* Without locking this could race if a UML was booted with no
10292 + * disks and then two mconsole requests which add disks came in
10293 + * at the same time.
10295 + spin_lock(&ubd_lock);
10296 + if(proc_ide_root == NULL) make_proc_ide();
10297 + spin_unlock(&ubd_lock);
10299 + dir = proc_mkdir(dev_name, proc_ide);
10302 + ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir);
10305 + ent->data = NULL;
10306 + ent->read_proc = proc_ide_read_media;
10307 + ent->write_proc = NULL;
10308 + sprintf(name,"ide0/%s", dev_name);
10309 + proc_symlink(dev_name, proc_ide_root, name);
10312 +static int fake_ide_setup(char *str)
10318 +__setup("fake_ide", fake_ide_setup);
10320 +__uml_help(fake_ide_setup,
10322 +" Create ide0 entries that map onto ubd devices.\n\n"
10325 +static int parse_unit(char **ptr)
10327 + char *str = *ptr, *end;
10330 + if(isdigit(*str)) {
10331 + n = simple_strtoul(str, &end, 0);
10336 + else if (('a' <= *str) && (*str <= 'h')) {
10344 +static int ubd_setup_common(char *str, int *index_out)
10346 + struct openflags flags = global_openflags;
10348 + char *backing_file;
10351 + if(index_out) *index_out = -1;
10358 + if(!strcmp(str, "mmap")){
10359 + CHOOSE_MODE(printk("mmap not supported by the ubd "
10360 + "driver in tt mode\n"),
10361 + ubd_do_mmap = 1);
10365 + if(!strcmp(str, "sync")){
10366 + global_openflags.s = 1;
10369 + major = simple_strtoul(str, &end, 0);
10370 + if((*end != '\0') || (end == str)){
10372 + "ubd_setup : didn't parse major number\n");
10377 + spin_lock(&ubd_lock);
10378 + if(fake_major != MAJOR_NR){
10379 + printk(KERN_ERR "Can't assign a fake major twice\n");
10383 + fake_gendisk.major = major;
10384 + fake_major = major;
10386 + printk(KERN_INFO "Setting extra ubd major number to %d\n",
10390 + spin_unlock(&ubd_lock);
10394 + n = parse_unit(&str);
10396 + printk(KERN_ERR "ubd_setup : couldn't parse unit number "
10401 + if(n >= MAX_DEV){
10402 + printk(KERN_ERR "ubd_setup : index %d out of range "
10403 + "(%d devices)\n", n, MAX_DEV);
10408 + spin_lock(&ubd_lock);
10410 + dev = &ubd_dev[n];
10411 + if(dev->file != NULL){
10412 + printk(KERN_ERR "ubd_setup : device already configured\n");
10416 + if(index_out) *index_out = n;
10431 + if(*str++ != '='){
10432 + printk(KERN_ERR "ubd_setup : Expected '='\n");
10437 + backing_file = strchr(str, ',');
10438 + if(backing_file){
10440 + printk(KERN_ERR "Can't specify both 'd' and a "
10443 + *backing_file = '\0';
10448 + dev->cow.file = backing_file;
10449 + dev->boot_openflags = flags;
10451 + spin_unlock(&ubd_lock);
10455 +static int ubd_setup(char *str)
10457 + ubd_setup_common(str, NULL);
10461 +__setup("ubd", ubd_setup);
10462 +__uml_help(ubd_setup,
10463 +"ubd<n>=<filename>\n"
10464 +" This is used to associate a device with a file in the underlying\n"
10465 +" filesystem. Usually, there is a filesystem in the file, but \n"
10466 +" that's not required. Swap devices containing swap files can be\n"
10467 +" specified like this. Also, a file which doesn't contain a\n"
10468 +" filesystem can have its contents read in the virtual \n"
10469 +" machine by running dd on the device. n must be in the range\n"
10470 +" 0 to 7. Appending an 'r' to the number will cause that device\n"
10471 +" to be mounted read-only. For example ubd1r=./ext_fs. Appending\n"
10472 +" an 's' (has to be _after_ 'r', if there is one) will cause data\n"
10473 +" to be written to disk on the host immediately.\n\n"
10476 +static int fakehd(char *str)
10479 + "fakehd : Changing ubd_gendisk.major_name to \"hd\".\n");
10480 + ubd_gendisk.major_name = "hd";
10484 +__setup("fakehd", fakehd);
10485 +__uml_help(fakehd,
10487 +" Change the ubd device name to \"hd\".\n\n"
10490 +static void do_ubd_request(request_queue_t * q);
10492 +/* Only changed by ubd_init, which is an initcall. */
10493 +int thread_fd = -1;
10495 +/* Changed by ubd_handler, which is serialized because interrupts only
10496 + * happen on CPU 0.
10498 +int intr_count = 0;
10500 +static void ubd_finish(int error)
10508 + nsect = CURRENT->current_nr_sectors;
10509 + CURRENT->sector += nsect;
10510 + CURRENT->buffer += nsect << 9;
10511 + CURRENT->errors = 0;
10512 + CURRENT->nr_sectors -= nsect;
10513 + CURRENT->current_nr_sectors = 0;
10517 +static void ubd_handler(void)
10519 + struct io_thread_req req;
10522 + DEVICE_INTR = NULL;
10524 + n = read_ubd_fs(thread_fd, &req, sizeof(req));
10525 + if(n != sizeof(req)){
10526 + printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
10527 + "err = %d\n", os_getpid(), -n);
10528 + spin_lock(&io_request_lock);
10530 + spin_unlock(&io_request_lock);
10534 + if((req.op != UBD_MMAP) &&
10535 + ((req.offset != ((__u64) (CURRENT->sector)) << 9) ||
10536 + (req.length != (CURRENT->current_nr_sectors) << 9)))
10537 + panic("I/O op mismatch");
10539 + if(req.map_fd != -1){
10540 + err = physmem_subst_mapping(req.buffer, req.map_fd,
10541 + req.map_offset, 1);
10543 + printk("ubd_handler - physmem_subst_mapping failed, "
10544 + "err = %d\n", -err);
10547 + spin_lock(&io_request_lock);
10548 + ubd_finish(req.error);
10549 + reactivate_fd(thread_fd, UBD_IRQ);
10550 + do_ubd_request(ubd_queue);
10551 + spin_unlock(&io_request_lock);
10554 +static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
10559 +/* Only changed by ubd_init, which is an initcall. */
10560 +static int io_pid = -1;
10562 +void kill_io_thread(void)
10565 + os_kill_process(io_pid, 1);
10568 +__uml_exitcall(kill_io_thread);
10570 +/* Initialized in an initcall, and unchanged thereafter */
10571 +devfs_handle_t ubd_dir_handle;
10573 +static int ubd_add(int n)
10575 + struct ubd *dev = &ubd_dev[n];
10576 + char name[sizeof("nnnnnn\0")], dev_name[sizeof("ubd0x")];
10577 + int err = -EISDIR;
10579 + if(dev->file == NULL)
10582 + err = ubd_revalidate1(MKDEV(MAJOR_NR, n << UBD_SHIFT));
10586 + if(dev->cow.file == NULL)
10587 + blk_sizes[n] = UBD_MMAP_BLOCK_SIZE;
10589 + sprintf(name, "%d", n);
10590 + dev->devfs = devfs_register(ubd_dir_handle, name, DEVFS_FL_REMOVABLE,
10591 + MAJOR_NR, n << UBD_SHIFT, S_IFBLK |
10592 + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
10593 + &ubd_blops, NULL);
10595 +#if 0 /* 2.5 ... */
10596 + sprintf(disk->disk_name, "ubd%c", 'a' + unit);
10599 + sprintf(dev_name, "%s%c", ubd_gendisk.major_name,
10602 + make_ide_entries(dev_name);
10609 +static int ubd_config(char *str)
10613 + str = uml_strdup(str);
10615 + printk(KERN_ERR "ubd_config failed to strdup string\n");
10618 + err = ubd_setup_common(str, &n);
10623 + if(n == -1) return(0);
10625 + spin_lock(&ubd_lock);
10626 + err = ubd_add(n);
10628 + ubd_dev[n].file = NULL;
10629 + spin_unlock(&ubd_lock);
10634 +static int ubd_get_config(char *name, char *str, int size, char **error_out)
10640 + n = simple_strtoul(name, &end, 0);
10641 + if((*end != '\0') || (end == name)){
10642 + *error_out = "ubd_get_config : didn't parse device number";
10646 + if((n >= MAX_DEV) || (n < 0)){
10647 + *error_out = "ubd_get_config : device number out of range";
10651 + dev = &ubd_dev[n];
10652 + spin_lock(&ubd_lock);
10654 + if(dev->file == NULL){
10655 + CONFIG_CHUNK(str, size, len, "", 1);
10659 + CONFIG_CHUNK(str, size, len, dev->file, 0);
10661 + if(dev->cow.file != NULL){
10662 + CONFIG_CHUNK(str, size, len, ",", 0);
10663 + CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
10665 + else CONFIG_CHUNK(str, size, len, "", 1);
10668 + spin_unlock(&ubd_lock);
10672 +static int ubd_remove(char *str)
10675 + int n, err = -ENODEV;
10677 + if(isdigit(*str)){
10679 + n = simple_strtoul(str, &end, 0);
10680 + if ((*end != '\0') || (end == str))
10683 + else if (('a' <= *str) && (*str <= 'h'))
10686 + return(err); /* it should be a number 0-7/a-h */
10688 + if((n < 0) || (n >= MAX_DEV))
10691 + dev = &ubd_dev[n];
10693 + spin_lock(&ubd_lock);
10695 + if(dev->file == NULL)
10698 + if(dev->count > 0)
10700 + if(dev->devfs != NULL)
10701 + devfs_unregister(dev->devfs);
10703 + *dev = ((struct ubd) DEFAULT_UBD);
10706 + spin_unlock(&ubd_lock);
10710 +static struct mc_device ubd_mc = {
10712 + .config = ubd_config,
10713 + .get_config = ubd_get_config,
10714 + .remove = ubd_remove,
10717 +static int ubd_mc_init(void)
10719 + mconsole_register_dev(&ubd_mc);
10723 +__initcall(ubd_mc_init);
10725 +static request_queue_t *ubd_get_queue(kdev_t device)
10727 + return(ubd_queue);
10730 +int ubd_init(void)
10732 + unsigned long stack;
10735 + ubd_dir_handle = devfs_mk_dir (NULL, "ubd", NULL);
10736 + if (devfs_register_blkdev(MAJOR_NR, "ubd", &ubd_blops)) {
10737 + printk(KERN_ERR "ubd: unable to get major %d\n", MAJOR_NR);
10740 + read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */
10741 + blksize_size[MAJOR_NR] = blk_sizes;
10742 + blk_size[MAJOR_NR] = sizes;
10743 + INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
10745 + ubd_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
10746 + blk_init_queue(ubd_queue, DEVICE_REQUEST);
10747 + INIT_ELV(ubd_queue, &ubd_queue->elevator);
10749 + add_gendisk(&ubd_gendisk);
10750 + if (fake_major != MAJOR_NR){
10751 + /* major number 0 is used to auto select */
10752 + err = devfs_register_blkdev(fake_major, "fake", &ubd_blops);
10753 + if(fake_major == 0){
10754 + /* auto device number case */
10755 + fake_major = err;
10760 + /* not auto so normal error */
10761 + printk(KERN_ERR "ubd: error %d getting major %d\n",
10762 + -err, fake_major);
10766 + blk_dev[fake_major].queue = ubd_get_queue;
10767 + read_ahead[fake_major] = 8; /* 8 sector (4kB) read-ahead */
10768 + blksize_size[fake_major] = blk_sizes;
10769 + blk_size[fake_major] = sizes;
10770 + INIT_HARDSECT(hardsect_size, fake_major, hardsect_sizes);
10771 + add_gendisk(&fake_gendisk);
10774 + for(i=0;i<MAX_DEV;i++)
10777 + if(global_openflags.s){
10778 + printk(KERN_INFO "ubd : Synchronous mode\n");
10781 + stack = alloc_stack(0, 0);
10782 + io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
10787 + "ubd : Failed to start I/O thread (errno = %d) - "
10788 + "falling back to synchronous I/O\n", -io_pid);
10791 + err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
10792 + SA_INTERRUPT, "ubd", ubd_dev);
10794 + printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
10798 +__initcall(ubd_init);
10800 +static void ubd_close(struct ubd *dev)
10802 + os_close_file(dev->fd);
10803 + if(dev->cow.file != NULL) {
10804 + os_close_file(dev->cow.fd);
10805 + vfree(dev->cow.bitmap);
10806 + dev->cow.bitmap = NULL;
10810 +static int ubd_open_dev(struct ubd *dev)
10812 + struct openflags flags;
10814 + int err, create_cow, *create_ptr;
10816 + dev->openflags = dev->boot_openflags;
10818 + create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
10819 + back_ptr = dev->no_cow ? NULL : &dev->cow.file;
10820 + dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
10821 + &dev->cow.bitmap_offset, &dev->cow.bitmap_len,
10822 + &dev->cow.data_offset, create_ptr);
10824 + if((dev->fd == -ENOENT) && create_cow){
10825 + dev->fd = create_cow_file(dev->file, dev->cow.file,
10826 + dev->openflags, 1 << 9, PAGE_SIZE,
10827 + &dev->cow.bitmap_offset,
10828 + &dev->cow.bitmap_len,
10829 + &dev->cow.data_offset);
10830 + if(dev->fd >= 0){
10831 + printk(KERN_INFO "Creating \"%s\" as COW file for "
10832 + "\"%s\"\n", dev->file, dev->cow.file);
10836 + if(dev->fd < 0) return(dev->fd);
10838 + if(dev->cow.file != NULL){
10840 + dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
10841 + if(dev->cow.bitmap == NULL){
10842 + printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
10845 + flush_tlb_kernel_vm();
10847 + err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
10848 + dev->cow.bitmap_offset,
10849 + dev->cow.bitmap_len);
10850 + if(err < 0) goto error;
10852 + flags = dev->openflags;
10854 + err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL,
10856 + if(err < 0) goto error;
10857 + dev->cow.fd = err;
10861 + os_close_file(dev->fd);
10865 +static int ubd_file_size(struct ubd *dev, __u64 *size_out)
10869 + file = dev->cow.file ? dev->cow.file : dev->file;
10870 + return(os_file_size(file, size_out));
10873 +static int ubd_open(struct inode *inode, struct file *filp)
10876 + int n, offset, err = 0;
10878 + n = DEVICE_NR(inode->i_rdev);
10879 + dev = &ubd_dev[n];
10883 + spin_lock(&ubd_lock);
10884 + offset = n << UBD_SHIFT;
10886 + if(dev->count == 0){
10887 + err = ubd_open_dev(dev);
10889 + printk(KERN_ERR "ubd%d: Can't open \"%s\": "
10890 + "errno = %d\n", n, dev->file, -err);
10893 + err = ubd_file_size(dev, &dev->size);
10896 + sizes[offset] = dev->size / BLOCK_SIZE;
10897 + ubd_part[offset].nr_sects = dev->size / hardsect_sizes[offset];
10900 + if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
10901 + if(--dev->count == 0) ubd_close(dev);
10905 + spin_unlock(&ubd_lock);
10909 +static int ubd_release(struct inode * inode, struct file * file)
10913 + n = DEVICE_NR(inode->i_rdev);
10914 + offset = n << UBD_SHIFT;
10918 + spin_lock(&ubd_lock);
10919 + if(--ubd_dev[n].count == 0)
10920 + ubd_close(&ubd_dev[n]);
10921 + spin_unlock(&ubd_lock);
10926 +static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
10927 + __u64 *cow_offset, unsigned long *bitmap,
10928 + __u64 bitmap_offset, unsigned long *bitmap_words,
10929 + __u64 bitmap_len)
10931 + __u64 sector = io_offset >> 9;
10932 + int i, update_bitmap = 0;
10934 + for(i = 0; i < length >> 9; i++){
10935 + if(cow_mask != NULL)
10936 + ubd_set_bit(i, (unsigned char *) cow_mask);
10937 + if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
10940 + update_bitmap = 1;
10941 + ubd_set_bit(sector + i, (unsigned char *) bitmap);
10944 + if(!update_bitmap)
10947 + *cow_offset = sector / (sizeof(unsigned long) * 8);
10949 + /* This takes care of the case where we're exactly at the end of the
10950 + * device, and *cow_offset + 1 is off the end. So, just back it up
10951 + * by one word. Thanks to Lynn Kerby for the fix and James McMechan
10952 + * for the original diagnosis.
10954 + if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
10955 + sizeof(unsigned long) - 1))
10958 + bitmap_words[0] = bitmap[*cow_offset];
10959 + bitmap_words[1] = bitmap[*cow_offset + 1];
10961 + *cow_offset *= sizeof(unsigned long);
10962 + *cow_offset += bitmap_offset;
10965 +static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
10966 + __u64 bitmap_offset, __u64 bitmap_len)
10968 + __u64 sector = req->offset >> 9;
10971 + if(req->length > (sizeof(req->sector_mask) * 8) << 9)
10972 + panic("Operation too long");
10974 + if(req->op == UBD_READ) {
10975 + for(i = 0; i < req->length >> 9; i++){
10976 + if(ubd_test_bit(sector + i, (unsigned char *) bitmap)){
10977 + ubd_set_bit(i, (unsigned char *)
10978 + &req->sector_mask);
10982 + else cowify_bitmap(req->offset, req->length, &req->sector_mask,
10983 + &req->cow_offset, bitmap, bitmap_offset,
10984 + req->bitmap_words, bitmap_len);
10987 +static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
10990 + unsigned char *bitmap;
10993 + /* mmap must have been requested on the command line */
10997 + /* The buffer must be page aligned */
10998 + if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
11001 + /* The request must be a page long */
11002 + if((req->current_nr_sectors << 9) != PAGE_SIZE)
11005 + if(dev->cow.file == NULL)
11008 + sector = offset >> 9;
11009 + bitmap = (unsigned char *) dev->cow.bitmap;
11010 + bit = ubd_test_bit(sector, bitmap);
11012 + for(i = 1; i < req->current_nr_sectors; i++){
11013 + if(ubd_test_bit(sector + i, bitmap) != bit)
11017 + if(bit || (req->cmd == WRITE))
11018 + offset += dev->cow.data_offset;
11020 + /* The data on disk must be page aligned */
11021 + if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
11024 + return(bit ? dev->fd : dev->cow.fd);
11027 +static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset,
11028 + struct request *req,
11029 + struct io_thread_req *io_req)
11033 + if(req->cmd == WRITE){
11034 + /* Writes are almost no-ops since the new data is already in the
11035 + * host page cache
11037 + dev->map_writes++;
11038 + if(dev->cow.file != NULL)
11039 + cowify_bitmap(io_req->offset, io_req->length,
11040 + &io_req->sector_mask, &io_req->cow_offset,
11041 + dev->cow.bitmap, dev->cow.bitmap_offset,
11042 + io_req->bitmap_words,
11043 + dev->cow.bitmap_len);
11048 + if((dev->cow.file != NULL) && (fd == dev->cow.fd))
11050 + else w = dev->openflags.w;
11052 + if((dev->cow.file != NULL) && (fd == dev->fd))
11053 + offset += dev->cow.data_offset;
11055 + err = physmem_subst_mapping(req->buffer, fd, offset, w);
11057 + printk("physmem_subst_mapping failed, err = %d\n",
11061 + dev->map_reads++;
11063 + io_req->op = UBD_MMAP;
11064 + io_req->buffer = req->buffer;
11068 +static int prepare_request(struct request *req, struct io_thread_req *io_req)
11072 + int minor, n, len, fd;
11074 + if(req->rq_status == RQ_INACTIVE) return(1);
11076 + minor = MINOR(req->rq_dev);
11077 + n = minor >> UBD_SHIFT;
11078 + dev = &ubd_dev[n];
11080 + if(IS_WRITE(req) && !dev->openflags.w){
11081 + printk("Write attempted on readonly ubd device %d\n", n);
11086 + req->sector += ubd_part[minor].start_sect;
11087 + offset = ((__u64) req->sector) << 9;
11088 + len = req->current_nr_sectors << 9;
11090 + io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
11091 + io_req->fds[1] = dev->fd;
11092 + io_req->map_fd = -1;
11093 + io_req->cow_offset = -1;
11094 + io_req->offset = offset;
11095 + io_req->length = len;
11096 + io_req->error = 0;
11097 + io_req->sector_mask = 0;
11099 + fd = mmap_fd(req, dev, io_req->offset);
11101 + /* If mmapping is otherwise OK, but the first access to the
11102 + * page is a write, then it's not mapped in yet. So we have
11103 + * to write the data to disk first, then we can map the disk
11104 + * page in and continue normally from there.
11106 + if((req->cmd == WRITE) && !is_remapped(req->buffer)){
11107 + io_req->map_fd = dev->fd;
11108 + io_req->map_offset = io_req->offset +
11109 + dev->cow.data_offset;
11110 + dev->write_maps++;
11112 + else return(prepare_mmap_request(dev, fd, io_req->offset, req,
11116 + if(req->cmd == READ)
11117 + dev->nomap_reads++;
11118 + else dev->nomap_writes++;
11120 + io_req->op = (req->cmd == READ) ? UBD_READ : UBD_WRITE;
11121 + io_req->offsets[0] = 0;
11122 + io_req->offsets[1] = dev->cow.data_offset;
11123 + io_req->buffer = req->buffer;
11124 + io_req->sectorsize = 1 << 9;
11126 + if(dev->cow.file != NULL)
11127 + cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
11128 + dev->cow.bitmap_len);
11132 +static void do_ubd_request(request_queue_t *q)
11134 + struct io_thread_req io_req;
11135 + struct request *req;
11138 + if(thread_fd == -1){
11139 + while(!list_empty(&q->queue_head)){
11140 + req = blkdev_entry_next_request(&q->queue_head);
11141 + err = prepare_request(req, &io_req);
11144 + ubd_finish(io_req.error);
11149 + if(DEVICE_INTR || list_empty(&q->queue_head)) return;
11150 + req = blkdev_entry_next_request(&q->queue_head);
11151 + err = prepare_request(req, &io_req);
11153 + SET_INTR(ubd_handler);
11154 + n = write_ubd_fs(thread_fd, (char *) &io_req,
11156 + if(n != sizeof(io_req))
11157 + printk("write to io thread failed, "
11158 + "errno = %d\n", -n);
11163 +static int ubd_ioctl(struct inode * inode, struct file * file,
11164 + unsigned int cmd, unsigned long arg)
11166 + struct hd_geometry *loc = (struct hd_geometry *) arg;
11168 + int n, minor, err;
11169 + struct hd_driveid ubd_id = {
11175 + if(!inode) return(-EINVAL);
11176 + minor = MINOR(inode->i_rdev);
11177 + n = minor >> UBD_SHIFT;
11180 + dev = &ubd_dev[n];
11182 + struct hd_geometry g;
11183 + struct cdrom_volctrl volume;
11184 + case HDIO_GETGEO:
11185 + if(!loc) return(-EINVAL);
11188 + g.cylinders = dev->size / (128 * 32 * hardsect_sizes[minor]);
11189 + g.start = ubd_part[minor].start_sect;
11190 + return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
11191 + case BLKGETSIZE: /* Return device size */
11192 + if(!arg) return(-EINVAL);
11193 + err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
11196 + put_user(ubd_part[minor].nr_sects, (long *) arg);
11198 + case BLKRRPART: /* Re-read partition tables */
11199 + return(ubd_revalidate(inode->i_rdev));
11201 + case HDIO_SET_UNMASKINTR:
11202 + if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
11203 + if((arg > 1) || (minor & 0x3F)) return(-EINVAL);
11206 + case HDIO_GET_UNMASKINTR:
11207 + if(!arg) return(-EINVAL);
11208 + err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
11213 + case HDIO_GET_MULTCOUNT:
11214 + if(!arg) return(-EINVAL);
11215 + err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
11220 + case HDIO_SET_MULTCOUNT:
11221 + if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
11222 + if(MINOR(inode->i_rdev) & 0x3F) return(-EINVAL);
11225 + case HDIO_GET_IDENTITY:
11226 + ubd_id.cyls = dev->size / (128 * 32 * hardsect_sizes[minor]);
11227 + if(copy_to_user((char *) arg, (char *) &ubd_id,
11232 + case CDROMVOLREAD:
11233 + if(copy_from_user(&volume, (char *) arg, sizeof(volume)))
11235 + volume.channel0 = 255;
11236 + volume.channel1 = 255;
11237 + volume.channel2 = 255;
11238 + volume.channel3 = 255;
11239 + if(copy_to_user((char *) arg, &volume, sizeof(volume)))
11244 + return blk_ioctl(inode->i_rdev, cmd, arg);
11248 +static int ubd_revalidate1(kdev_t rdev)
11250 + int i, n, offset, err = 0, pcount = 1 << UBD_SHIFT;
11252 + struct hd_struct *part;
11254 + n = DEVICE_NR(rdev);
11255 + offset = n << UBD_SHIFT;
11256 + dev = &ubd_dev[n];
11258 + part = &ubd_part[offset];
11260 + /* clear all old partition counts */
11261 + for(i = 1; i < pcount; i++) {
11262 + part[i].start_sect = 0;
11263 + part[i].nr_sects = 0;
11266 + /* If it already has been opened we can check the partitions
11270 + part->start_sect = 0;
11271 + register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount,
11272 + &ubd_blops, part->nr_sects);
11274 + else if(dev->file){
11275 + err = ubd_open_dev(dev);
11277 + printk(KERN_ERR "unable to open %s for validation\n",
11282 + /* have to recompute sizes since we opened it */
11283 + err = ubd_file_size(dev, &dev->size);
11288 + part->start_sect = 0;
11289 + part->nr_sects = dev->size / hardsect_sizes[offset];
11290 + register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount,
11291 + &ubd_blops, part->nr_sects);
11293 + /* we are done so close it */
11296 + else err = -ENODEV;
11301 +static int ubd_revalidate(kdev_t rdev)
11305 + spin_lock(&ubd_lock);
11306 + err = ubd_revalidate1(rdev);
11307 + spin_unlock(&ubd_lock);
11311 +static int ubd_check_remapped(int fd, unsigned long address, int is_write,
11314 + __u64 bitmap_offset;
11315 + unsigned long new_bitmap[2];
11318 + /* If it's not a write access, we can't do anything about it */
11322 + /* We have a write */
11323 + for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
11324 + struct ubd *dev = &ubd_dev[i];
11326 + if((dev->fd != fd) && (dev->cow.fd != fd))
11329 + /* It's a write to a ubd device */
11331 + if(!dev->openflags.w){
11332 + /* It's a write access on a read-only device - probably
11333 + * shouldn't happen. If the kernel is trying to change
11334 + * something with no intention of writing it back out,
11335 + * then this message will clue us in that this needs
11338 + printk("Write access to mapped page from readonly ubd "
11339 + "device %d\n", i);
11343 + /* It's a write to a writeable ubd device - it must be COWed
11344 + * because, otherwise, the page would have been mapped in
11348 + if(!dev->cow.file)
11349 + panic("Write fault on writeable non-COW ubd device %d",
11352 + /* It should also be an access to the backing file since the
11353 + * COW pages should be mapped in read-write
11356 + if(fd == dev->fd)
11357 + panic("Write fault on a backing page of ubd "
11358 + "device %d\n", i);
11360 + /* So, we do the write, copying the backing data to the COW
11364 + err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
11366 + panic("Couldn't seek to %lld in COW file of ubd "
11367 + "device %d, err = %d",
11368 + offset + dev->cow.data_offset, i, -err);
11370 + n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
11371 + if(n != PAGE_SIZE)
11372 + panic("Couldn't copy data to COW file of ubd "
11373 + "device %d, err = %d", i, -n);
11375 + /* ... updating the COW bitmap... */
11377 + cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset,
11378 + dev->cow.bitmap, dev->cow.bitmap_offset,
11379 + new_bitmap, dev->cow.bitmap_len);
11381 + err = os_seek_file(dev->fd, bitmap_offset);
11383 + panic("Couldn't seek to %lld in COW file of ubd "
11384 + "device %d, err = %d", bitmap_offset, i, -err);
11386 + n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
11387 + if(n != sizeof(new_bitmap))
11388 + panic("Couldn't update bitmap of ubd device %d, "
11389 + "err = %d", i, -n);
11391 + /* Maybe we can map the COW page in, and maybe we can't. If
11392 + * it is a pre-V3 COW file, we can't, since the alignment will
11393 + * be wrong. If it is a V3 or later COW file which has been
11394 + * moved to a system with a larger page size, then maybe we
11395 + * can't, depending on the exact location of the page.
11398 + offset += dev->cow.data_offset;
11400 + /* Remove the remapping, putting the original anonymous page
11401 + * back. If the COW file can be mapped in, that is done.
11402 + * Otherwise, the COW page is read in.
11405 + if(!physmem_remove_mapping((void *) address))
11406 + panic("Address 0x%lx not remapped by ubd device %d",
11408 + if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
11409 + physmem_subst_mapping((void *) address, dev->fd,
11412 + err = os_seek_file(dev->fd, offset);
11414 + panic("Couldn't seek to %lld in COW file of "
11415 + "ubd device %d, err = %d", offset, i,
11418 + n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
11419 + if(n != PAGE_SIZE)
11420 + panic("Failed to read page from offset %llx of "
11421 + "COW file of ubd device %d, err = %d",
11428 + /* It's not a write on a ubd device */
11432 +static struct remapper ubd_remapper = {
11433 + .list = LIST_HEAD_INIT(ubd_remapper.list),
11434 + .proc = ubd_check_remapped,
11437 +static int ubd_remapper_setup(void)
11440 + register_remapper(&ubd_remapper);
11445 +__initcall(ubd_remapper_setup);
11448 + * Overrides for Emacs so that we follow Linus's tabbing style.
11449 + * Emacs will notice this stuff at the end of the file and automatically
11450 + * adjust the settings for this buffer only. This must remain at the end
11452 + * ---------------------------------------------------------------------------
11453 + * Local variables:
11454 + * c-file-style: "linux"
11457 diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_user.c um/arch/um/drivers/ubd_user.c
11458 --- orig/arch/um/drivers/ubd_user.c 1969-12-31 19:00:00.000000000 -0500
11459 +++ um/arch/um/drivers/ubd_user.c 2003-11-08 07:57:49.000000000 -0500
11462 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
11463 + * Copyright (C) 2001 Ridgerun,Inc (glonnon@ridgerun.com)
11464 + * Licensed under the GPL
11467 +#include <stddef.h>
11468 +#include <unistd.h>
11469 +#include <errno.h>
11470 +#include <sched.h>
11471 +#include <signal.h>
11472 +#include <string.h>
11473 +#include <netinet/in.h>
11474 +#include <sys/time.h>
11475 +#include <sys/socket.h>
11476 +#include <string.h>
11477 +#include <sys/mman.h>
11478 +#include <sys/param.h>
11479 +#include "asm/types.h"
11480 +#include "user_util.h"
11481 +#include "kern_util.h"
11483 +#include "ubd_user.h"
11487 +#include <endian.h>
11488 +#include <byteswap.h>
11490 +static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
11492 + struct uml_stat buf1, buf2;
11495 + if(from_cmdline == NULL) return(1);
11496 + if(!strcmp(from_cmdline, from_cow)) return(1);
11498 + err = os_stat_file(from_cmdline, &buf1);
11500 + printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
11503 + err = os_stat_file(from_cow, &buf2);
11505 + printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
11508 + if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
11511 + printk("Backing file mismatch - \"%s\" requested,\n"
11512 + "\"%s\" specified in COW header of \"%s\"\n",
11513 + from_cmdline, from_cow, cow);
11517 +static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
11519 + unsigned long modtime;
11520 + long long actual;
11523 + err = os_file_modtime(file, &modtime);
11525 + printk("Failed to get modification time of backing file "
11526 + "\"%s\", err = %d\n", file, -err);
11530 + err = os_file_size(file, &actual);
11532 + printk("Failed to get size of backing file \"%s\", "
11533 + "err = %d\n", file, -err);
11537 + if(actual != size){
11538 + printk("Size mismatch (%ld vs %ld) of COW header vs backing "
11539 + "file\n", size, actual);
11542 + if(modtime != mtime){
11543 + printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
11544 + "file\n", mtime, modtime);
11550 +int read_cow_bitmap(int fd, void *buf, int offset, int len)
11554 + err = os_seek_file(fd, offset);
11558 + err = os_read_file(fd, buf, len);
11565 +int open_ubd_file(char *file, struct openflags *openflags,
11566 + char **backing_file_out, int *bitmap_offset_out,
11567 + unsigned long *bitmap_len_out, int *data_offset_out,
11568 + int *create_cow_out)
11572 + __u32 version, align;
11573 + char *backing_file;
11574 + int fd, err, sectorsize, same, mode = 0644;
11576 + fd = os_open_file(file, *openflags, mode);
11578 + if((fd == -ENOENT) && (create_cow_out != NULL))
11579 + *create_cow_out = 1;
11580 + if(!openflags->w ||
11581 + ((errno != EROFS) && (errno != EACCES))) return(-errno);
11582 + openflags->w = 0;
11583 + fd = os_open_file(file, *openflags, mode);
11588 + err = os_lock_file(fd, openflags->w);
11590 + printk("Failed to lock '%s', err = %d\n", file, -err);
11594 + if(backing_file_out == NULL) return(fd);
11596 + err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
11597 + &size, §orsize, &align, bitmap_offset_out);
11598 + if(err && (*backing_file_out != NULL)){
11599 + printk("Failed to read COW header from COW file \"%s\", "
11600 + "errno = %d\n", file, -err);
11603 + if(err) return(fd);
11605 + if(backing_file_out == NULL) return(fd);
11607 + same = same_backing_files(*backing_file_out, backing_file, file);
11609 + if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
11610 + printk("Switching backing file to '%s'\n", *backing_file_out);
11611 + err = write_cow_header(file, fd, *backing_file_out,
11612 + sectorsize, align, &size);
11614 + printk("Switch failed, errno = %d\n", -err);
11619 + *backing_file_out = backing_file;
11620 + err = backing_file_mismatch(*backing_file_out, size, mtime);
11621 + if(err) goto out_close;
11624 + cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
11625 + bitmap_len_out, data_offset_out);
11629 + os_close_file(fd);
11633 +int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
11634 + int sectorsize, int alignment, int *bitmap_offset_out,
11635 + unsigned long *bitmap_len_out, int *data_offset_out)
11640 + fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
11643 + printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
11648 + err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
11649 + bitmap_offset_out, bitmap_len_out,
11650 + data_offset_out);
11654 + os_close_file(fd);
11659 +/* XXX Just trivial wrappers around os_read_file and os_write_file */
11660 +int read_ubd_fs(int fd, void *buffer, int len)
11662 + return(os_read_file(fd, buffer, len));
11665 +int write_ubd_fs(int fd, char *buffer, int len)
11667 + return(os_write_file(fd, buffer, len));
11670 +static int update_bitmap(struct io_thread_req *req)
11674 + if(req->cow_offset == -1)
11677 + n = os_seek_file(req->fds[1], req->cow_offset);
11679 + printk("do_io - bitmap lseek failed : err = %d\n", -n);
11683 + n = os_write_file(req->fds[1], &req->bitmap_words,
11684 + sizeof(req->bitmap_words));
11685 + if(n != sizeof(req->bitmap_words)){
11686 + printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
11694 +void do_io(struct io_thread_req *req)
11697 + unsigned long len;
11698 + int n, nsectors, start, end, bit;
11702 + if(req->op == UBD_MMAP){
11703 + /* Touch the page to force the host to do any necessary IO to
11704 + * get it into memory
11706 + n = *((volatile int *) req->buffer);
11707 + req->error = update_bitmap(req);
11711 + nsectors = req->length / req->sectorsize;
11714 + bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
11716 + while((end < nsectors) &&
11717 + (ubd_test_bit(end, (unsigned char *)
11718 + &req->sector_mask) == bit))
11721 + off = req->offset + req->offsets[bit] +
11722 + start * req->sectorsize;
11723 + len = (end - start) * req->sectorsize;
11724 + buf = &req->buffer[start * req->sectorsize];
11726 + err = os_seek_file(req->fds[bit], off);
11728 + printk("do_io - lseek failed : err = %d\n", -err);
11732 + if(req->op == UBD_READ){
11737 + n = os_read_file(req->fds[bit], buf, len);
11739 + printk("do_io - read failed, err = %d "
11740 + "fd = %d\n", -n, req->fds[bit]);
11744 + } while((n < len) && (n != 0));
11745 + if (n < len) memset(&buf[n], 0, len - n);
11748 + n = os_write_file(req->fds[bit], buf, len);
11750 + printk("do_io - write failed err = %d "
11751 + "fd = %d\n", -n, req->fds[bit]);
11758 + } while(start < nsectors);
11760 + req->error = update_bitmap(req);
11763 +/* Changed in start_io_thread, which is serialized by being called only
11764 + * from ubd_init, which is an initcall.
11766 +int kernel_fd = -1;
11768 +/* Only changed by the io thread */
11771 +int io_thread(void *arg)
11773 + struct io_thread_req req;
11776 + signal(SIGWINCH, SIG_IGN);
11778 + n = os_read_file(kernel_fd, &req, sizeof(req));
11779 + if(n != sizeof(req)){
11781 + printk("io_thread - read failed, fd = %d, "
11782 + "err = %d\n", kernel_fd, -n);
11784 + printk("io_thread - short read, fd = %d, "
11785 + "length = %d\n", kernel_fd, n);
11791 + n = os_write_file(kernel_fd, &req, sizeof(req));
11792 + if(n != sizeof(req))
11793 + printk("io_thread - write failed, fd = %d, err = %d\n",
11798 +int start_io_thread(unsigned long sp, int *fd_out)
11800 + int pid, fds[2], err;
11802 + err = os_pipe(fds, 1, 1);
11804 + printk("start_io_thread - os_pipe failed, err = %d\n", -err);
11808 + kernel_fd = fds[0];
11809 + *fd_out = fds[1];
11811 + pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
11814 + printk("start_io_thread - clone failed : errno = %d\n", errno);
11821 + os_close_file(fds[0]);
11822 + os_close_file(fds[1]);
11830 + * Overrides for Emacs so that we follow Linus's tabbing style.
11831 + * Emacs will notice this stuff at the end of the file and automatically
11832 + * adjust the settings for this buffer only. This must remain at the end
11834 + * ---------------------------------------------------------------------------
11835 + * Local variables:
11836 + * c-file-style: "linux"
11839 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.c um/arch/um/drivers/xterm.c
11840 --- orig/arch/um/drivers/xterm.c 1969-12-31 19:00:00.000000000 -0500
11841 +++ um/arch/um/drivers/xterm.c 2003-10-21 03:26:06.000000000 -0400
11844 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
11845 + * Licensed under the GPL
11848 +#include <stdio.h>
11849 +#include <stdlib.h>
11850 +#include <unistd.h>
11851 +#include <string.h>
11852 +#include <errno.h>
11853 +#include <termios.h>
11854 +#include <signal.h>
11855 +#include <sched.h>
11856 +#include <sys/socket.h>
11857 +#include "kern_util.h"
11858 +#include "chan_user.h"
11859 +#include "helper.h"
11860 +#include "user_util.h"
11863 +#include "xterm.h"
11865 +struct xterm_chan {
11871 + struct termios tt;
11872 + unsigned long stack;
11876 +void *xterm_init(char *str, int device, struct chan_opts *opts)
11878 + struct xterm_chan *data;
11880 + data = malloc(sizeof(*data));
11881 + if(data == NULL) return(NULL);
11882 + *data = ((struct xterm_chan) { .pid = -1,
11883 + .helper_pid = -1,
11884 + .device = device,
11885 + .title = opts->xterm_title,
11886 + .raw = opts->raw,
11887 + .stack = opts->tramp_stack,
11888 + .direct_rcv = !opts->in_kernel } );
11892 +/* Only changed by xterm_setup, which is a setup */
11893 +static char *terminal_emulator = "xterm";
11894 +static char *title_switch = "-T";
11895 +static char *exec_switch = "-e";
11897 +static int __init xterm_setup(char *line, int *add)
11900 + terminal_emulator = line;
11902 + line = strchr(line, ',');
11903 + if(line == NULL) return(0);
11905 + if(*line) title_switch = line;
11907 + line = strchr(line, ',');
11908 + if(line == NULL) return(0);
11910 + if(*line) exec_switch = line;
11915 +__uml_setup("xterm=", xterm_setup,
11916 +"xterm=<terminal emulator>,<title switch>,<exec switch>\n"
11917 +" Specifies an alternate terminal emulator to use for the debugger,\n"
11918 +" consoles, and serial lines when they are attached to the xterm channel.\n"
11919 +" The values are the terminal emulator binary, the switch it uses to set\n"
11920 +" its title, and the switch it uses to execute a subprocess,\n"
11921 +" respectively. The title switch must have the form '<switch> title',\n"
11922 +" not '<switch>=title'. Similarly, the exec switch must have the form\n"
11923 +" '<switch> command arg1 arg2 ...'.\n"
11924 +" The default values are 'xterm=xterm,-T,-e'. Values for gnome-terminal\n"
11925 +" are 'xterm=gnome-terminal,-t,-x'.\n\n"
11928 +int xterm_open(int input, int output, int primary, void *d, char **dev_out)
11930 + struct xterm_chan *data = d;
11931 + unsigned long stack;
11932 + int pid, fd, new, err;
11933 + char title[256], file[] = "/tmp/xterm-pipeXXXXXX";
11934 + char *argv[] = { terminal_emulator, title_switch, title, exec_switch,
11935 + "/usr/lib/uml/port-helper", "-uml-socket",
11938 + if(os_access(argv[4], OS_ACC_X_OK) < 0)
11939 + argv[4] = "port-helper";
11941 + fd = mkstemp(file);
11943 + printk("xterm_open : mkstemp failed, errno = %d\n", errno);
11947 + if(unlink(file)){
11948 + printk("xterm_open : unlink failed, errno = %d\n", errno);
11951 + os_close_file(fd);
11953 + fd = os_create_unix_socket(file, sizeof(file), 1);
11955 + printk("xterm_open : create_unix_socket failed, errno = %d\n",
11960 + sprintf(title, data->title, data->device);
11961 + stack = data->stack;
11962 + pid = run_helper(NULL, NULL, argv, &stack);
11964 + printk("xterm_open : run_helper failed, errno = %d\n", -pid);
11968 + if(data->stack == 0) free_stack(stack, 0);
11970 + if(data->direct_rcv)
11971 + new = os_rcv_fd(fd, &data->helper_pid);
11973 + err = os_set_fd_block(fd, 0);
11975 + printk("xterm_open : failed to set descriptor "
11976 + "non-blocking, err = %d\n", -err);
11979 + new = xterm_fd(fd, &data->helper_pid);
11982 + printk("xterm_open : os_rcv_fd failed, err = %d\n", -new);
11986 + tcgetattr(new, &data->tt);
11987 + if(data->raw) raw(new, 0);
11996 +void xterm_close(int fd, void *d)
11998 + struct xterm_chan *data = d;
12000 + if(data->pid != -1)
12001 + os_kill_process(data->pid, 1);
12003 + if(data->helper_pid != -1)
12004 + os_kill_process(data->helper_pid, 0);
12005 + data->helper_pid = -1;
12006 + os_close_file(fd);
12009 +void xterm_free(void *d)
12014 +int xterm_console_write(int fd, const char *buf, int n, void *d)
12016 + struct xterm_chan *data = d;
12018 + return(generic_console_write(fd, buf, n, &data->tt));
12021 +struct chan_ops xterm_ops = {
12023 + .init = xterm_init,
12024 + .open = xterm_open,
12025 + .close = xterm_close,
12026 + .read = generic_read,
12027 + .write = generic_write,
12028 + .console_write = xterm_console_write,
12029 + .window_size = generic_window_size,
12030 + .free = xterm_free,
12035 + * Overrides for Emacs so that we follow Linus's tabbing style.
12036 + * Emacs will notice this stuff at the end of the file and automatically
12037 + * adjust the settings for this buffer only. This must remain at the end
12039 + * ---------------------------------------------------------------------------
12040 + * Local variables:
12041 + * c-file-style: "linux"
12044 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.h um/arch/um/drivers/xterm.h
12045 --- orig/arch/um/drivers/xterm.h 1969-12-31 19:00:00.000000000 -0500
12046 +++ um/arch/um/drivers/xterm.h 2003-10-21 03:26:06.000000000 -0400
12049 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
12050 + * Licensed under the GPL
12053 +#ifndef __XTERM_H__
12054 +#define __XTERM_H__
12056 +extern int xterm_fd(int socket, int *pid_out);
12061 + * Overrides for Emacs so that we follow Linus's tabbing style.
12062 + * Emacs will notice this stuff at the end of the file and automatically
12063 + * adjust the settings for this buffer only. This must remain at the end
12065 + * ---------------------------------------------------------------------------
12066 + * Local variables:
12067 + * c-file-style: "linux"
12070 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm_kern.c um/arch/um/drivers/xterm_kern.c
12071 --- orig/arch/um/drivers/xterm_kern.c 1969-12-31 19:00:00.000000000 -0500
12072 +++ um/arch/um/drivers/xterm_kern.c 2003-10-21 03:26:06.000000000 -0400
12075 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
12076 + * Licensed under the GPL
12079 +#include "linux/errno.h"
12080 +#include "linux/slab.h"
12081 +#include "asm/semaphore.h"
12082 +#include "asm/irq.h"
12083 +#include "irq_user.h"
12084 +#include "irq_kern.h"
12085 +#include "kern_util.h"
12087 +#include "xterm.h"
12089 +struct xterm_wait {
12090 + struct semaphore sem;
12096 +static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
12098 + struct xterm_wait *xterm = data;
12101 + fd = os_rcv_fd(xterm->fd, &xterm->pid);
12102 + if(fd == -EAGAIN)
12105 + xterm->new_fd = fd;
12109 +int xterm_fd(int socket, int *pid_out)
12111 + struct xterm_wait *data;
12114 + data = kmalloc(sizeof(*data), GFP_KERNEL);
12115 + if(data == NULL){
12116 + printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
12119 + *data = ((struct xterm_wait)
12120 + { .sem = __SEMAPHORE_INITIALIZER(data->sem, 0),
12125 + err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt,
12126 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
12129 + printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
12130 + "err = %d\n", err);
12134 + down(&data->sem);
12136 + free_irq(XTERM_IRQ, data);
12138 + ret = data->new_fd;
12139 + *pid_out = data->pid;
12147 + * Overrides for Emacs so that we follow Linus's tabbing style.
12148 + * Emacs will notice this stuff at the end of the file and automatically
12149 + * adjust the settings for this buffer only. This must remain at the end
12151 + * ---------------------------------------------------------------------------
12152 + * Local variables:
12153 + * c-file-style: "linux"
12156 diff -Naur -X ../exclude-files orig/arch/um/dyn_link.ld.in um/arch/um/dyn_link.ld.in
12157 --- orig/arch/um/dyn_link.ld.in 1969-12-31 19:00:00.000000000 -0500
12158 +++ um/arch/um/dyn_link.ld.in 2003-10-21 03:26:06.000000000 -0400
12160 +OUTPUT_FORMAT("ELF_FORMAT")
12161 +OUTPUT_ARCH(ELF_ARCH)
12163 +SEARCH_DIR("/usr/local/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
12164 +/* Do we need any of these for elf?
12165 + __DYNAMIC = 0; */
12168 + . = START() + SIZEOF_HEADERS;
12169 + .interp : { *(.interp) }
12171 + __binary_start = .;
12172 + . = ALIGN(4096); /* Init code and data */
12174 + __init_begin = .;
12175 + .text.init : { *(.text.init) }
12179 + /* Read-only sections, merged into text segment: */
12180 + .hash : { *(.hash) }
12181 + .dynsym : { *(.dynsym) }
12182 + .dynstr : { *(.dynstr) }
12183 + .gnu.version : { *(.gnu.version) }
12184 + .gnu.version_d : { *(.gnu.version_d) }
12185 + .gnu.version_r : { *(.gnu.version_r) }
12186 + .rel.init : { *(.rel.init) }
12187 + .rela.init : { *(.rela.init) }
12188 + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
12189 + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
12190 + .rel.fini : { *(.rel.fini) }
12191 + .rela.fini : { *(.rela.fini) }
12192 + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
12193 + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
12194 + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
12195 + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
12196 + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
12197 + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
12198 + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
12199 + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
12200 + .rel.ctors : { *(.rel.ctors) }
12201 + .rela.ctors : { *(.rela.ctors) }
12202 + .rel.dtors : { *(.rel.dtors) }
12203 + .rela.dtors : { *(.rela.dtors) }
12204 + .rel.got : { *(.rel.got) }
12205 + .rela.got : { *(.rela.got) }
12206 + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
12207 + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
12208 + .rel.plt : { *(.rel.plt) }
12209 + .rela.plt : { *(.rela.plt) }
12213 + .plt : { *(.plt) }
12215 + *(.text .stub .text.* .gnu.linkonce.t.*)
12216 + /* .gnu.warning sections are handled specially by elf32.em. */
12223 + PROVIDE (__etext = .);
12224 + PROVIDE (_etext = .);
12225 + PROVIDE (etext = .);
12226 + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
12227 + .rodata1 : { *(.rodata1) }
12228 + .eh_frame_hdr : { *(.eh_frame_hdr) }
12232 + PROVIDE (_sdata = .);
12234 +include(`arch/um/common.ld.in')
12236 + /* Ensure the __preinit_array_start label is properly aligned. We
12237 + could instead move the label definition inside the section, but
12238 + the linker would then create the section even if it turns out to
12239 + be empty, which isn't pretty. */
12240 + . = ALIGN(32 / 8);
12241 + .preinit_array : { *(.preinit_array) }
12242 + .init_array : { *(.init_array) }
12243 + .fini_array : { *(.fini_array) }
12245 + . = ALIGN(KERNEL_STACK_SIZE); /* init_task */
12246 + *(.data.init_task)
12247 + *(.data .data.* .gnu.linkonce.d.*)
12248 + SORT(CONSTRUCTORS)
12250 + .data1 : { *(.data1) }
12251 + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
12252 + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
12253 + .eh_frame : { KEEP (*(.eh_frame)) }
12254 + .gcc_except_table : { *(.gcc_except_table) }
12255 + .dynamic : { *(.dynamic) }
12257 + /* gcc uses crtbegin.o to find the start of
12258 + the constructors, so we make sure it is
12259 + first. Because this is a wildcard, it
12260 + doesn't matter if the user does not
12261 + actually link against crtbegin.o; the
12262 + linker won't look for a file to match a
12263 + wildcard. The wildcard also means that it
12264 + doesn't matter which directory crtbegin.o
12266 + KEEP (*crtbegin.o(.ctors))
12267 + /* We don't want to include the .ctor section from
12268 + from the crtend.o file until after the sorted ctors.
12269 + The .ctor section from the crtend file contains the
12270 + end of ctors marker and it must be last */
12271 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
12272 + KEEP (*(SORT(.ctors.*)))
12276 + KEEP (*crtbegin.o(.dtors))
12277 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
12278 + KEEP (*(SORT(.dtors.*)))
12281 + .jcr : { KEEP (*(.jcr)) }
12282 + .got : { *(.got.plt) *(.got) }
12284 + PROVIDE (edata = .);
12288 + *(.bss .bss.* .gnu.linkonce.b.*)
12290 + /* Align here to ensure that the .bss section occupies space up to
12291 + _end. Align after .bss to ensure correct alignment even if the
12292 + .bss section disappears because there are no input sections. */
12293 + . = ALIGN(32 / 8);
12294 + . = ALIGN(32 / 8);
12297 + PROVIDE (end = .);
12298 + /* Stabs debugging sections. */
12299 + .stab 0 : { *(.stab) }
12300 + .stabstr 0 : { *(.stabstr) }
12301 + .stab.excl 0 : { *(.stab.excl) }
12302 + .stab.exclstr 0 : { *(.stab.exclstr) }
12303 + .stab.index 0 : { *(.stab.index) }
12304 + .stab.indexstr 0 : { *(.stab.indexstr) }
12305 + .comment 0 : { *(.comment) }
12306 + /* DWARF debug sections.
12307 + Symbols in the DWARF debugging sections are relative to the beginning
12308 + of the section so we begin them at 0. */
12310 + .debug 0 : { *(.debug) }
12311 + .line 0 : { *(.line) }
12312 + /* GNU DWARF 1 extensions */
12313 + .debug_srcinfo 0 : { *(.debug_srcinfo) }
12314 + .debug_sfnames 0 : { *(.debug_sfnames) }
12315 + /* DWARF 1.1 and DWARF 2 */
12316 + .debug_aranges 0 : { *(.debug_aranges) }
12317 + .debug_pubnames 0 : { *(.debug_pubnames) }
12319 + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
12320 + .debug_abbrev 0 : { *(.debug_abbrev) }
12321 + .debug_line 0 : { *(.debug_line) }
12322 + .debug_frame 0 : { *(.debug_frame) }
12323 + .debug_str 0 : { *(.debug_str) }
12324 + .debug_loc 0 : { *(.debug_loc) }
12325 + .debug_macinfo 0 : { *(.debug_macinfo) }
12326 + /* SGI/MIPS DWARF 2 extensions */
12327 + .debug_weaknames 0 : { *(.debug_weaknames) }
12328 + .debug_funcnames 0 : { *(.debug_funcnames) }
12329 + .debug_typenames 0 : { *(.debug_typenames) }
12330 + .debug_varnames 0 : { *(.debug_varnames) }
12332 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs.h um/arch/um/fs/hostfs/hostfs.h
12333 --- orig/arch/um/fs/hostfs/hostfs.h 1969-12-31 19:00:00.000000000 -0500
12334 +++ um/arch/um/fs/hostfs/hostfs.h 2003-12-17 10:52:50.000000000 -0500
12336 +#ifndef __UM_FS_HOSTFS
12337 +#define __UM_FS_HOSTFS
12341 +/* These are exactly the same definitions as in fs.h, but the names are
12342 + * changed so that this file can be included in both kernel and user files.
12345 +#define HOSTFS_ATTR_MODE 1
12346 +#define HOSTFS_ATTR_UID 2
12347 +#define HOSTFS_ATTR_GID 4
12348 +#define HOSTFS_ATTR_SIZE 8
12349 +#define HOSTFS_ATTR_ATIME 16
12350 +#define HOSTFS_ATTR_MTIME 32
12351 +#define HOSTFS_ATTR_CTIME 64
12352 +#define HOSTFS_ATTR_ATIME_SET 128
12353 +#define HOSTFS_ATTR_MTIME_SET 256
12354 +#define HOSTFS_ATTR_FORCE 512 /* Not a change, but a change it */
12355 +#define HOSTFS_ATTR_ATTR_FLAG 1024
12357 +struct hostfs_iattr {
12358 + unsigned int ia_valid;
12366 + unsigned int ia_attr_flags;
12369 +extern int stat_file(const char *path, int *dev_out,
12370 + unsigned long long *inode_out, int *mode_out,
12371 + int *nlink_out, int *uid_out, int *gid_out,
12372 + unsigned long long *size_out, unsigned long *atime_out,
12373 + unsigned long *mtime_out, unsigned long *ctime_out,
12374 + int *blksize_out, unsigned long long *blocks_out);
12375 +extern int access_file(char *path, int r, int w, int x);
12376 +extern int open_file(char *path, int r, int w, int append);
12377 +extern int file_type(const char *path, int *rdev);
12378 +extern void *open_dir(char *path, int *err_out);
12379 +extern char *read_dir(void *stream, unsigned long long *pos,
12380 + unsigned long long *ino_out, int *len_out);
12381 +extern void close_file(void *stream);
12382 +extern void close_dir(void *stream);
12383 +extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
12384 +extern int write_file(int fd, unsigned long long *offset, const char *buf,
12386 +extern int lseek_file(int fd, long long offset, int whence);
12387 +extern int file_create(char *name, int ur, int uw, int ux, int gr,
12388 + int gw, int gx, int or, int ow, int ox);
12389 +extern int set_attr(const char *file, struct hostfs_iattr *attrs);
12390 +extern int make_symlink(const char *from, const char *to);
12391 +extern int unlink_file(const char *file);
12392 +extern int do_mkdir(const char *file, int mode);
12393 +extern int do_rmdir(const char *file);
12394 +extern int do_mknod(const char *file, int mode, int dev);
12395 +extern int link_file(const char *from, const char *to);
12396 +extern int do_readlink(char *file, char *buf, int size);
12397 +extern int rename_file(char *from, char *to);
12398 +extern int do_statfs(char *root, long *bsize_out, long long *blocks_out,
12399 + long long *bfree_out, long long *bavail_out,
12400 + long long *files_out, long long *ffree_out,
12401 + void *fsid_out, int fsid_size, long *namelen_out,
12402 + long *spare_out);
12405 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_kern.c um/arch/um/fs/hostfs/hostfs_kern.c
12406 --- orig/arch/um/fs/hostfs/hostfs_kern.c 1969-12-31 19:00:00.000000000 -0500
12407 +++ um/arch/um/fs/hostfs/hostfs_kern.c 2003-10-21 03:26:06.000000000 -0400
12410 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
12411 + * Licensed under the GPL
12414 +#include <linux/stddef.h>
12415 +#include <linux/fs.h>
12416 +#include <linux/version.h>
12417 +#include <linux/module.h>
12418 +#include <linux/init.h>
12419 +#include <linux/slab.h>
12420 +#include <linux/pagemap.h>
12421 +#include <linux/blkdev.h>
12422 +#include <asm/uaccess.h>
12423 +#include "hostfs.h"
12424 +#include "kern_util.h"
12426 +#include "user_util.h"
12427 +#include "2_5compat.h"
12430 +#define file_hostfs_i(file) (&(file)->f_dentry->d_inode->u.hostfs_i)
12432 +int hostfs_d_delete(struct dentry *dentry)
12437 +struct dentry_operations hostfs_dentry_ops = {
12438 + .d_delete = hostfs_d_delete,
12441 +#define DEFAULT_ROOT "/"
12443 +/* Changed in hostfs_args before the kernel starts running */
12444 +static char *jail_dir = NULL;
12445 +static int append = 0;
12447 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
12449 +static struct inode_operations hostfs_iops;
12450 +static struct inode_operations hostfs_dir_iops;
12451 +static struct address_space_operations hostfs_link_aops;
12453 +static int __init hostfs_args(char *options, int *add)
12457 + ptr = strchr(options, ',');
12460 + if(*options != '\0')
12461 + jail_dir = options;
12465 + ptr = strchr(options, ',');
12468 + if(*options != '\0'){
12469 + if(!strcmp(options, "append"))
12471 + else printf("hostfs_args - unsupported option - %s\n",
12479 +__uml_setup("hostfs=", hostfs_args,
12480 +"hostfs=<root dir>,<flags>,...\n"
12481 +" This is used to set hostfs parameters. The root directory argument\n"
12482 +" is used to confine all hostfs mounts to within the specified directory\n"
12483 +" tree on the host. If this isn't specified, then a user inside UML can\n"
12484 +" mount anything on the host that's accessible to the user that's running\n"
12486 +" The only flag currently supported is 'append', which specifies that all\n"
12487 +" files opened by hostfs will be opened in append mode.\n\n"
12490 +static char *dentry_name(struct dentry *dentry, int extra)
12492 + struct dentry *parent;
12493 + char *root, *name;
12498 + while(parent->d_parent != parent){
12499 + len += parent->d_name.len + 1;
12500 + parent = parent->d_parent;
12503 + root = parent->d_inode->u.hostfs_i.host_filename;
12504 + len += strlen(root);
12505 + name = kmalloc(len + extra + 1, GFP_KERNEL);
12506 + if(name == NULL) return(NULL);
12508 + name[len] = '\0';
12510 + while(parent->d_parent != parent){
12511 + len -= parent->d_name.len + 1;
12513 + strncpy(&name[len + 1], parent->d_name.name,
12514 + parent->d_name.len);
12515 + parent = parent->d_parent;
12517 + strncpy(name, root, strlen(root));
12521 +static char *inode_name(struct inode *ino, int extra)
12523 + struct dentry *dentry;
12525 + dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
12526 + return(dentry_name(dentry, extra));
12529 +static int read_name(struct inode *ino, char *name)
12531 + /* The non-int inode fields are copied into ints by stat_file and
12532 + * then copied into the inode because passing the actual pointers
12533 + * in and having them treated as int * breaks on big-endian machines
12536 + int i_dev, i_mode, i_nlink, i_blksize;
12537 + unsigned long long i_size;
12538 + unsigned long long i_ino;
12539 + unsigned long long i_blocks;
12540 + err = stat_file(name, &i_dev, &i_ino, &i_mode, &i_nlink,
12541 + &ino->i_uid, &ino->i_gid, &i_size, &ino->i_atime,
12542 + &ino->i_mtime, &ino->i_ctime, &i_blksize, &i_blocks);
12543 + if(err) return(err);
12544 + ino->i_ino = i_ino;
12545 + ino->i_dev = i_dev;
12546 + ino->i_mode = i_mode;
12547 + ino->i_nlink = i_nlink;
12548 + ino->i_size = i_size;
12549 + ino->i_blksize = i_blksize;
12550 + ino->i_blocks = i_blocks;
12551 + if(kdev_same(ino->i_sb->s_dev, ROOT_DEV) && (ino->i_uid == getuid()))
12556 +static char *follow_link(char *link)
12559 + char *name, *resolved, *end;
12564 + name = kmalloc(len, GFP_KERNEL);
12568 + n = do_readlink(link, name, len);
12580 + end = strrchr(link, '/');
12584 + *(end + 1) = '\0';
12585 + len = strlen(link) + strlen(name) + 1;
12587 + resolved = kmalloc(len, GFP_KERNEL);
12588 + if(resolved == NULL){
12593 + sprintf(resolved, "%s%s", link, name);
12596 + return(resolved);
12601 + return(ERR_PTR(n));
12604 +static int read_inode(struct inode *ino)
12610 + name = inode_name(ino, 0);
12614 + if(file_type(name, NULL) == OS_TYPE_SYMLINK){
12615 + name = follow_link(name);
12616 + if(IS_ERR(name)){
12617 + err = PTR_ERR(name);
12622 + err = read_name(ino, name);
12628 +void hostfs_delete_inode(struct inode *ino)
12630 + if(ino->u.hostfs_i.host_filename)
12631 + kfree(ino->u.hostfs_i.host_filename);
12632 + ino->u.hostfs_i.host_filename = NULL;
12634 + if(ino->u.hostfs_i.fd != -1)
12635 + close_file(&ino->u.hostfs_i.fd);
12637 + ino->u.hostfs_i.mode = 0;
12638 + clear_inode(ino);
12641 +int hostfs_statfs(struct super_block *sb, struct statfs *sf)
12643 + /* do_statfs uses struct statfs64 internally, but the linux kernel
12644 + * struct statfs still has 32-bit versions for most of these fields,
12645 + * so we convert them here
12648 + long long f_blocks;
12649 + long long f_bfree;
12650 + long long f_bavail;
12651 + long long f_files;
12652 + long long f_ffree;
12654 + err = do_statfs(sb->s_root->d_inode->u.hostfs_i.host_filename,
12655 + &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
12656 + &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
12657 + &sf->f_namelen, sf->f_spare);
12658 + if(err) return(err);
12659 + sf->f_blocks = f_blocks;
12660 + sf->f_bfree = f_bfree;
12661 + sf->f_bavail = f_bavail;
12662 + sf->f_files = f_files;
12663 + sf->f_ffree = f_ffree;
12664 + sf->f_type = HOSTFS_SUPER_MAGIC;
12668 +static struct super_operations hostfs_sbops = {
12669 + .put_inode = force_delete,
12670 + .delete_inode = hostfs_delete_inode,
12671 + .statfs = hostfs_statfs,
12674 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
12678 + unsigned long long next, ino;
12681 + name = dentry_name(file->f_dentry, 0);
12682 + if(name == NULL) return(-ENOMEM);
12683 + dir = open_dir(name, &error);
12685 + if(dir == NULL) return(-error);
12686 + next = file->f_pos;
12687 + while((name = read_dir(dir, &next, &ino, &len)) != NULL){
12688 + error = (*filldir)(ent, name, len, file->f_pos,
12689 + ino, DT_UNKNOWN);
12691 + file->f_pos = next;
12697 +int hostfs_file_open(struct inode *ino, struct file *file)
12700 + int mode = 0, r = 0, w = 0, fd;
12702 + mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
12703 + if((mode & ino->u.hostfs_i.mode) == mode)
12706 + /* The file may already have been opened, but with the wrong access,
12707 + * so this resets things and reopens the file with the new access.
12709 + if(ino->u.hostfs_i.fd != -1){
12710 + close_file(&ino->u.hostfs_i.fd);
12711 + ino->u.hostfs_i.fd = -1;
12714 + ino->u.hostfs_i.mode |= mode;
12715 + if(ino->u.hostfs_i.mode & FMODE_READ)
12717 + if(ino->u.hostfs_i.mode & FMODE_WRITE)
12722 + name = dentry_name(file->f_dentry, 0);
12726 + fd = open_file(name, r, w, append);
12728 + if(fd < 0) return(fd);
12729 + file_hostfs_i(file)->fd = fd;
12734 +int hostfs_dir_open(struct inode *ino, struct file *file)
12739 +int hostfs_dir_release(struct inode *ino, struct file *file)
12744 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
12749 +static struct file_operations hostfs_file_fops = {
12751 + .read = generic_file_read,
12752 + .write = generic_file_write,
12753 + .mmap = generic_file_mmap,
12754 + .open = hostfs_file_open,
12756 + .fsync = hostfs_fsync,
12759 +static struct file_operations hostfs_dir_fops = {
12761 + .readdir = hostfs_readdir,
12762 + .open = hostfs_dir_open,
12763 + .release = hostfs_dir_release,
12764 + .fsync = hostfs_fsync,
12767 +int hostfs_writepage(struct page *page)
12769 + struct address_space *mapping = page->mapping;
12770 + struct inode *inode = mapping->host;
12772 + unsigned long long base;
12773 + int count = PAGE_CACHE_SIZE;
12774 + int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
12777 + if (page->index >= end_index)
12778 + count = inode->i_size & (PAGE_CACHE_SIZE-1);
12780 + buffer = kmap(page);
12781 + base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
12783 + err = write_file(inode->u.hostfs_i.fd, &base, buffer, count);
12784 + if(err != count){
12785 + ClearPageUptodate(page);
12789 + if (base > inode->i_size)
12790 + inode->i_size = base;
12792 + if (PageError(page))
12793 + ClearPageError(page);
12799 + UnlockPage(page);
12803 +int hostfs_readpage(struct file *file, struct page *page)
12809 + start = (long long) page->index << PAGE_CACHE_SHIFT;
12810 + buffer = kmap(page);
12811 + err = read_file(file_hostfs_i(file)->fd, &start, buffer,
12812 + PAGE_CACHE_SIZE);
12813 + if(err < 0) goto out;
12815 + memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
12817 + flush_dcache_page(page);
12818 + SetPageUptodate(page);
12819 + if (PageError(page)) ClearPageError(page);
12823 + UnlockPage(page);
12827 +int hostfs_prepare_write(struct file *file, struct page *page,
12828 + unsigned int from, unsigned int to)
12831 + long long start, tmp;
12834 + start = (long long) page->index << PAGE_CACHE_SHIFT;
12835 + buffer = kmap(page);
12838 + err = read_file(file_hostfs_i(file)->fd, &tmp, buffer,
12840 + if(err < 0) goto out;
12842 + if(to != PAGE_CACHE_SIZE){
12844 + err = read_file(file_hostfs_i(file)->fd, &start, buffer + to,
12845 + PAGE_CACHE_SIZE - to);
12846 + if(err < 0) goto out;
12854 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
12857 + struct address_space *mapping = page->mapping;
12858 + struct inode *inode = mapping->host;
12863 + start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
12864 + buffer = kmap(page);
12865 + err = write_file(file_hostfs_i(file)->fd, &start, buffer + from,
12867 + if(err > 0) err = 0;
12868 + if(!err && (start > inode->i_size))
12869 + inode->i_size = start;
12875 +static struct address_space_operations hostfs_aops = {
12876 + .writepage = hostfs_writepage,
12877 + .readpage = hostfs_readpage,
12878 +/* .set_page_dirty = __set_page_dirty_nobuffers, */
12879 + .prepare_write = hostfs_prepare_write,
12880 + .commit_write = hostfs_commit_write
12883 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
12886 + struct inode *inode;
12888 + int type, err = -ENOMEM, rdev;
12890 + inode = new_inode(sb);
12891 + if(inode == NULL)
12894 + inode->u.hostfs_i.host_filename = NULL;
12895 + inode->u.hostfs_i.fd = -1;
12896 + inode->u.hostfs_i.mode = 0;
12897 + insert_inode_hash(inode);
12899 + name = dentry_name(dentry, 0);
12900 + if(name == NULL){
12904 + type = file_type(name, &rdev);
12907 + else type = OS_TYPE_DIR;
12908 + inode->i_sb = sb;
12911 + if(type == OS_TYPE_SYMLINK)
12912 + inode->i_op = &page_symlink_inode_operations;
12913 + else if(type == OS_TYPE_DIR)
12914 + inode->i_op = &hostfs_dir_iops;
12915 + else inode->i_op = &hostfs_iops;
12917 + if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
12918 + else inode->i_fop = &hostfs_file_fops;
12920 + if(type == OS_TYPE_SYMLINK)
12921 + inode->i_mapping->a_ops = &hostfs_link_aops;
12922 + else inode->i_mapping->a_ops = &hostfs_aops;
12925 + case OS_TYPE_CHARDEV:
12926 + init_special_inode(inode, S_IFCHR, rdev);
12928 + case OS_TYPE_BLOCKDEV:
12929 + init_special_inode(inode, S_IFBLK, rdev);
12931 + case OS_TYPE_FIFO:
12932 + init_special_inode(inode, S_IFIFO, 0);
12934 + case OS_TYPE_SOCK:
12935 + init_special_inode(inode, S_IFSOCK, 0);
12939 + if(error) *error = err;
12942 + make_bad_inode(inode);
12945 + if(error) *error = err;
12949 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode)
12951 + struct inode *inode;
12955 + inode = get_inode(dir->i_sb, dentry, &error);
12956 + if(error) return(error);
12957 + name = dentry_name(dentry, 0);
12958 + if(name == NULL){
12962 + fd = file_create(name,
12963 + mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
12964 + mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
12965 + mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
12968 + else error = read_name(inode, name);
12975 + inode->u.hostfs_i.fd = fd;
12976 + inode->u.hostfs_i.mode = FMODE_READ | FMODE_WRITE;
12977 + d_instantiate(dentry, inode);
12981 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry)
12983 + struct inode *inode;
12987 + inode = get_inode(ino->i_sb, dentry, &error);
12988 + if(error != 0) return(ERR_PTR(error));
12989 + name = dentry_name(dentry, 0);
12990 + if(name == NULL) return(ERR_PTR(-ENOMEM));
12991 + error = read_name(inode, name);
12995 + if(error == -ENOENT) inode = NULL;
12996 + else return(ERR_PTR(error));
12998 + d_add(dentry, inode);
12999 + dentry->d_op = &hostfs_dentry_ops;
13003 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
13008 + file = inode_name(ino, dentry->d_name.len + 1);
13009 + if(file == NULL) return(NULL);
13010 + strcat(file, "/");
13011 + len = strlen(file);
13012 + strncat(file, dentry->d_name.name, dentry->d_name.len);
13013 + file[len + dentry->d_name.len] = '\0';
13017 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
13019 + char *from_name, *to_name;
13022 + from_name = inode_dentry_name(ino, from);
13023 + if(from_name == NULL)
13025 + to_name = dentry_name(to, 0);
13026 + if(to_name == NULL){
13027 + kfree(from_name);
13030 + err = link_file(to_name, from_name);
13031 + kfree(from_name);
13036 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
13041 + file = inode_dentry_name(ino, dentry);
13042 + if(file == NULL) return(-ENOMEM);
13046 + err = unlink_file(file);
13051 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
13056 + file = inode_dentry_name(ino, dentry);
13057 + if(file == NULL) return(-ENOMEM);
13058 + err = make_symlink(file, to);
13063 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
13068 + file = inode_dentry_name(ino, dentry);
13069 + if(file == NULL) return(-ENOMEM);
13070 + err = do_mkdir(file, mode);
13075 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
13080 + file = inode_dentry_name(ino, dentry);
13081 + if(file == NULL) return(-ENOMEM);
13082 + err = do_rmdir(file);
13087 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
13089 + struct inode *inode;
13093 + inode = get_inode(dir->i_sb, dentry, &error);
13094 + if(error) return(error);
13095 + name = dentry_name(dentry, 0);
13096 + if(name == NULL){
13100 + init_special_inode(inode, mode, dev);
13101 + error = do_mknod(name, mode, dev);
13102 + if(!error) error = read_name(inode, name);
13108 + d_instantiate(dentry, inode);
13112 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
13113 + struct inode *to_ino, struct dentry *to)
13115 + char *from_name, *to_name;
13118 + from_name = inode_dentry_name(from_ino, from);
13119 + if(from_name == NULL)
13121 + to_name = inode_dentry_name(to_ino, to);
13122 + if(to_name == NULL){
13123 + kfree(from_name);
13126 + err = rename_file(from_name, to_name);
13127 + kfree(from_name);
13132 +void hostfs_truncate(struct inode *ino)
13134 + not_implemented();
13137 +int hostfs_permission(struct inode *ino, int desired)
13140 + int r = 0, w = 0, x = 0, err;
13142 + if(desired & MAY_READ) r = 1;
13143 + if(desired & MAY_WRITE) w = 1;
13144 + if(desired & MAY_EXEC) x = 1;
13145 + name = inode_name(ino, 0);
13146 + if(name == NULL) return(-ENOMEM);
13147 + err = access_file(name, r, w, x);
13149 + if(!err) err = vfs_permission(ino, desired);
13153 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
13155 + struct hostfs_iattr attrs;
13160 + attr->ia_valid &= ~ATTR_SIZE;
13162 + attrs.ia_valid = 0;
13163 + if(attr->ia_valid & ATTR_MODE){
13164 + attrs.ia_valid |= HOSTFS_ATTR_MODE;
13165 + attrs.ia_mode = attr->ia_mode;
13167 + if(attr->ia_valid & ATTR_UID){
13168 + if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) &&
13169 + (attr->ia_uid == 0))
13170 + attr->ia_uid = getuid();
13171 + attrs.ia_valid |= HOSTFS_ATTR_UID;
13172 + attrs.ia_uid = attr->ia_uid;
13174 + if(attr->ia_valid & ATTR_GID){
13175 + if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) &&
13176 + (attr->ia_gid == 0))
13177 + attr->ia_gid = getuid();
13178 + attrs.ia_valid |= HOSTFS_ATTR_GID;
13179 + attrs.ia_gid = attr->ia_gid;
13181 + if(attr->ia_valid & ATTR_SIZE){
13182 + attrs.ia_valid |= HOSTFS_ATTR_SIZE;
13183 + attrs.ia_size = attr->ia_size;
13185 + if(attr->ia_valid & ATTR_ATIME){
13186 + attrs.ia_valid |= HOSTFS_ATTR_ATIME;
13187 + attrs.ia_atime = attr->ia_atime;
13189 + if(attr->ia_valid & ATTR_MTIME){
13190 + attrs.ia_valid |= HOSTFS_ATTR_MTIME;
13191 + attrs.ia_mtime = attr->ia_mtime;
13193 + if(attr->ia_valid & ATTR_CTIME){
13194 + attrs.ia_valid |= HOSTFS_ATTR_CTIME;
13195 + attrs.ia_ctime = attr->ia_ctime;
13197 + if(attr->ia_valid & ATTR_ATIME_SET){
13198 + attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
13200 + if(attr->ia_valid & ATTR_MTIME_SET){
13201 + attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
13203 + name = dentry_name(dentry, 0);
13204 + if(name == NULL) return(-ENOMEM);
13205 + err = set_attr(name, &attrs);
13210 + return(inode_setattr(dentry->d_inode, attr));
13213 +int hostfs_getattr(struct dentry *dentry, struct iattr *attr)
13215 + not_implemented();
13219 +static struct inode_operations hostfs_iops = {
13220 + .create = hostfs_create,
13221 + .link = hostfs_link,
13222 + .unlink = hostfs_unlink,
13223 + .symlink = hostfs_symlink,
13224 + .mkdir = hostfs_mkdir,
13225 + .rmdir = hostfs_rmdir,
13226 + .mknod = hostfs_mknod,
13227 + .rename = hostfs_rename,
13228 + .truncate = hostfs_truncate,
13229 + .permission = hostfs_permission,
13230 + .setattr = hostfs_setattr,
13231 + .getattr = hostfs_getattr,
13234 +static struct inode_operations hostfs_dir_iops = {
13235 + .create = hostfs_create,
13236 + .lookup = hostfs_lookup,
13237 + .link = hostfs_link,
13238 + .unlink = hostfs_unlink,
13239 + .symlink = hostfs_symlink,
13240 + .mkdir = hostfs_mkdir,
13241 + .rmdir = hostfs_rmdir,
13242 + .mknod = hostfs_mknod,
13243 + .rename = hostfs_rename,
13244 + .truncate = hostfs_truncate,
13245 + .permission = hostfs_permission,
13246 + .setattr = hostfs_setattr,
13247 + .getattr = hostfs_getattr,
13250 +int hostfs_link_readpage(struct file *file, struct page *page)
13252 + char *buffer, *name;
13256 + start = page->index << PAGE_CACHE_SHIFT;
13257 + buffer = kmap(page);
13258 + name = inode_name(page->mapping->host, 0);
13259 + if(name == NULL) return(-ENOMEM);
13260 + err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
13262 + if(err == PAGE_CACHE_SIZE)
13264 + else if(err > 0){
13265 + flush_dcache_page(page);
13266 + SetPageUptodate(page);
13267 + if (PageError(page)) ClearPageError(page);
13271 + UnlockPage(page);
13275 +static struct address_space_operations hostfs_link_aops = {
13276 + .readpage = hostfs_link_readpage,
13279 +static char *get_root(char *mount_arg)
13281 + char *root, *slash = "";
13284 + if(jail_dir != NULL){
13285 + len += strlen(jail_dir);
13286 + if((*jail_dir == '\0') ||
13287 + (jail_dir[strlen(jail_dir) - 1] != '/'))
13289 + len += strlen(slash);
13292 + if((mount_arg == NULL) || (*mount_arg == '\0'))
13293 + mount_arg = DEFAULT_ROOT;
13295 + len += strlen(mount_arg) + 1;
13297 + root = kmalloc(len, GFP_KERNEL);
13301 + if(jail_dir != NULL)
13302 + sprintf(root, "%s%s%s", jail_dir, slash, mount_arg);
13304 + strcpy(root, mount_arg);
13309 +struct super_block *hostfs_read_super(struct super_block *sb, void *data,
13312 + struct inode *root_inode;
13315 + sb->s_blocksize = 1024;
13316 + sb->s_blocksize_bits = 10;
13317 + sb->s_magic = HOSTFS_SUPER_MAGIC;
13318 + sb->s_op = &hostfs_sbops;
13320 + root_inode = get_inode(sb, NULL, NULL);
13321 + if(root_inode == NULL)
13324 + root_dir = get_root(data);
13325 + if(root_dir == NULL)
13328 + root_inode->u.hostfs_i.host_filename = root_dir;
13329 + sb->s_root = d_alloc_root(root_inode);
13330 + if(sb->s_root == NULL)
13333 + if(read_inode(root_inode))
13338 + dput(sb->s_root);
13342 + make_bad_inode(root_inode);
13343 + iput(root_inode);
13348 +DECLARE_FSTYPE(hostfs_type, "hostfs", hostfs_read_super, 0);
13350 +static int __init init_hostfs(void)
13352 + return(register_filesystem(&hostfs_type));
13355 +static void __exit exit_hostfs(void)
13357 + unregister_filesystem(&hostfs_type);
13360 +module_init(init_hostfs)
13361 +module_exit(exit_hostfs)
13362 +MODULE_LICENSE("GPL");
13365 + * Overrides for Emacs so that we follow Linus's tabbing style.
13366 + * Emacs will notice this stuff at the end of the file and automatically
13367 + * adjust the settings for this buffer only. This must remain at the end
13369 + * ---------------------------------------------------------------------------
13370 + * Local variables:
13371 + * c-file-style: "linux"
13374 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_user.c um/arch/um/fs/hostfs/hostfs_user.c
13375 --- orig/arch/um/fs/hostfs/hostfs_user.c 1969-12-31 19:00:00.000000000 -0500
13376 +++ um/arch/um/fs/hostfs/hostfs_user.c 2003-11-14 08:51:20.000000000 -0500
13379 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13380 + * Licensed under the GPL
13383 +#include <unistd.h>
13384 +#include <stdio.h>
13385 +#include <fcntl.h>
13386 +#include <dirent.h>
13387 +#include <errno.h>
13388 +#include <utime.h>
13389 +#include <string.h>
13390 +#include <sys/stat.h>
13391 +#include <sys/time.h>
13392 +#include <sys/vfs.h>
13393 +#include "hostfs.h"
13394 +#include "kern_util.h"
13397 +int stat_file(const char *path, int *dev_out, unsigned long long *inode_out,
13398 + int *mode_out, int *nlink_out, int *uid_out, int *gid_out,
13399 + unsigned long long *size_out, unsigned long *atime_out,
13400 + unsigned long *mtime_out, unsigned long *ctime_out,
13401 + int *blksize_out, unsigned long long *blocks_out)
13403 + struct stat64 buf;
13405 + if(lstat64(path, &buf) < 0)
13407 + if(dev_out != NULL) *dev_out = buf.st_dev;
13409 + /* See the Makefile for why STAT64_INO_FIELD is passed in
13412 + if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
13413 + if(mode_out != NULL) *mode_out = buf.st_mode;
13414 + if(nlink_out != NULL) *nlink_out = buf.st_nlink;
13415 + if(uid_out != NULL) *uid_out = buf.st_uid;
13416 + if(gid_out != NULL) *gid_out = buf.st_gid;
13417 + if(size_out != NULL) *size_out = buf.st_size;
13418 + if(atime_out != NULL) *atime_out = buf.st_atime;
13419 + if(mtime_out != NULL) *mtime_out = buf.st_mtime;
13420 + if(ctime_out != NULL) *ctime_out = buf.st_ctime;
13421 + if(blksize_out != NULL) *blksize_out = buf.st_blksize;
13422 + if(blocks_out != NULL) *blocks_out = buf.st_blocks;
13426 +int file_type(const char *path, int *rdev)
13428 + struct stat64 buf;
13430 + if(lstat64(path, &buf) < 0)
13433 + *rdev = buf.st_rdev;
13435 + if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
13436 + else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
13437 + else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
13438 + else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
13439 + else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
13440 + else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
13441 + else return(OS_TYPE_FILE);
13444 +int access_file(char *path, int r, int w, int x)
13448 + if(r) mode = R_OK;
13449 + if(w) mode |= W_OK;
13450 + if(x) mode |= X_OK;
13451 + if(access(path, mode) != 0) return(-errno);
13455 +int open_file(char *path, int r, int w, int append)
13457 + int mode = 0, fd;
13465 + else panic("Impossible mode in open_file");
13468 + mode |= O_APPEND;
13469 + fd = open64(path, mode);
13470 + if(fd < 0) return(-errno);
13474 +void *open_dir(char *path, int *err_out)
13478 + dir = opendir(path);
13479 + *err_out = errno;
13480 + if(dir == NULL) return(NULL);
13484 +char *read_dir(void *stream, unsigned long long *pos,
13485 + unsigned long long *ino_out, int *len_out)
13487 + DIR *dir = stream;
13488 + struct dirent *ent;
13490 + seekdir(dir, *pos);
13491 + ent = readdir(dir);
13492 + if(ent == NULL) return(NULL);
13493 + *len_out = strlen(ent->d_name);
13494 + *ino_out = ent->d_ino;
13495 + *pos = telldir(dir);
13496 + return(ent->d_name);
13499 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
13503 + err = os_seek_file(fd, *offset);
13507 + n = os_read_file(fd, buf, len);
13515 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
13519 + err = os_seek_file(fd, *offset);
13523 + n = os_write_file(fd, buf, len);
13531 +int lseek_file(int fd, long long offset, int whence)
13535 + ret = lseek64(fd, offset, whence);
13536 + if(ret < 0) return(-errno);
13540 +void close_file(void *stream)
13542 + close(*((int *) stream));
13545 +void close_dir(void *stream)
13547 + closedir(stream);
13550 +int file_create(char *name, int ur, int uw, int ux, int gr,
13551 + int gw, int gx, int or, int ow, int ox)
13556 + mode |= ur ? S_IRUSR : 0;
13557 + mode |= uw ? S_IWUSR : 0;
13558 + mode |= ux ? S_IXUSR : 0;
13559 + mode |= gr ? S_IRGRP : 0;
13560 + mode |= gw ? S_IWGRP : 0;
13561 + mode |= gx ? S_IXGRP : 0;
13562 + mode |= or ? S_IROTH : 0;
13563 + mode |= ow ? S_IWOTH : 0;
13564 + mode |= ox ? S_IXOTH : 0;
13565 + fd = open64(name, O_CREAT | O_RDWR, mode);
13571 +int set_attr(const char *file, struct hostfs_iattr *attrs)
13573 + struct utimbuf buf;
13576 + if(attrs->ia_valid & HOSTFS_ATTR_MODE){
13577 + if(chmod(file, attrs->ia_mode) != 0) return(-errno);
13579 + if(attrs->ia_valid & HOSTFS_ATTR_UID){
13580 + if(chown(file, attrs->ia_uid, -1)) return(-errno);
13582 + if(attrs->ia_valid & HOSTFS_ATTR_GID){
13583 + if(chown(file, -1, attrs->ia_gid)) return(-errno);
13585 + if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
13586 + if(truncate(file, attrs->ia_size)) return(-errno);
13588 + ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
13589 + if((attrs->ia_valid & ma) == ma){
13590 + buf.actime = attrs->ia_atime;
13591 + buf.modtime = attrs->ia_mtime;
13592 + if(utime(file, &buf) != 0) return(-errno);
13595 + if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
13596 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
13597 + NULL, NULL, NULL, &buf.modtime, NULL,
13599 + if(err != 0) return(err);
13600 + buf.actime = attrs->ia_atime;
13601 + if(utime(file, &buf) != 0) return(-errno);
13603 + if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
13604 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
13605 + NULL, NULL, &buf.actime, NULL, NULL,
13607 + if(err != 0) return(err);
13608 + buf.modtime = attrs->ia_mtime;
13609 + if(utime(file, &buf) != 0) return(-errno);
13612 + if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
13613 + if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
13614 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
13615 + NULL, NULL, &attrs->ia_atime, &attrs->ia_mtime,
13616 + NULL, NULL, NULL);
13617 + if(err != 0) return(err);
13622 +int make_symlink(const char *from, const char *to)
13626 + err = symlink(to, from);
13627 + if(err) return(-errno);
13631 +int unlink_file(const char *file)
13635 + err = unlink(file);
13636 + if(err) return(-errno);
13640 +int do_mkdir(const char *file, int mode)
13644 + err = mkdir(file, mode);
13645 + if(err) return(-errno);
13649 +int do_rmdir(const char *file)
13653 + err = rmdir(file);
13654 + if(err) return(-errno);
13658 +int do_mknod(const char *file, int mode, int dev)
13662 + err = mknod(file, mode, dev);
13663 + if(err) return(-errno);
13667 +int link_file(const char *to, const char *from)
13671 + err = link(to, from);
13672 + if(err) return(-errno);
13676 +int do_readlink(char *file, char *buf, int size)
13680 + n = readlink(file, buf, size);
13688 +int rename_file(char *from, char *to)
13692 + err = rename(from, to);
13693 + if(err < 0) return(-errno);
13697 +int do_statfs(char *root, long *bsize_out, long long *blocks_out,
13698 + long long *bfree_out, long long *bavail_out,
13699 + long long *files_out, long long *ffree_out,
13700 + void *fsid_out, int fsid_size, long *namelen_out,
13703 + struct statfs64 buf;
13706 + err = statfs64(root, &buf);
13707 + if(err < 0) return(-errno);
13708 + *bsize_out = buf.f_bsize;
13709 + *blocks_out = buf.f_blocks;
13710 + *bfree_out = buf.f_bfree;
13711 + *bavail_out = buf.f_bavail;
13712 + *files_out = buf.f_files;
13713 + *ffree_out = buf.f_ffree;
13714 + memcpy(fsid_out, &buf.f_fsid,
13715 + sizeof(buf.f_fsid) > fsid_size ? fsid_size :
13716 + sizeof(buf.f_fsid));
13717 + *namelen_out = buf.f_namelen;
13718 + spare_out[0] = buf.f_spare[0];
13719 + spare_out[1] = buf.f_spare[1];
13720 + spare_out[2] = buf.f_spare[2];
13721 + spare_out[3] = buf.f_spare[3];
13722 + spare_out[4] = buf.f_spare[4];
13723 + spare_out[5] = buf.f_spare[5];
13728 + * Overrides for Emacs so that we follow Linus's tabbing style.
13729 + * Emacs will notice this stuff at the end of the file and automatically
13730 + * adjust the settings for this buffer only. This must remain at the end
13732 + * ---------------------------------------------------------------------------
13733 + * Local variables:
13734 + * c-file-style: "linux"
13737 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/Makefile um/arch/um/fs/hostfs/Makefile
13738 --- orig/arch/um/fs/hostfs/Makefile 1969-12-31 19:00:00.000000000 -0500
13739 +++ um/arch/um/fs/hostfs/Makefile 2003-10-21 03:26:06.000000000 -0400
13742 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13743 +# Licensed under the GPL
13746 +# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino
13747 +# to __st_ino. It stayed in the same place, so as long as the correct name
13748 +# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa.
13750 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
13753 +USER_CFLAGS := $(USER_CFLAGS) -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
13755 +O_TARGET := hostfs.o
13756 +obj-y = hostfs_kern.o hostfs_user.o
13757 +obj-m = $(O_TARGET)
13759 +USER_OBJS = $(filter %_user.o,$(obj-y))
13761 +include $(TOPDIR)/Rules.make
13763 +$(USER_OBJS) : %.o: %.c
13764 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
13765 diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/hppfs_kern.c um/arch/um/fs/hppfs/hppfs_kern.c
13766 --- orig/arch/um/fs/hppfs/hppfs_kern.c 1969-12-31 19:00:00.000000000 -0500
13767 +++ um/arch/um/fs/hppfs/hppfs_kern.c 2003-11-08 09:42:49.000000000 -0500
13770 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13771 + * Licensed under the GPL
13774 +#include <linux/fs.h>
13775 +#include <linux/module.h>
13776 +#include <linux/slab.h>
13777 +#include <linux/list.h>
13778 +#include <linux/kernel.h>
13779 +#include <linux/ctype.h>
13780 +#include <asm/uaccess.h>
13783 +struct hppfs_data {
13784 + struct list_head list;
13785 + char contents[PAGE_SIZE - sizeof(struct list_head)];
13788 +struct hppfs_private {
13789 + struct file proc_file;
13792 + struct hppfs_data *contents;
13795 +#define HPPFS_SUPER_MAGIC 0xb00000ee
13797 +static struct super_operations hppfs_sbops;
13799 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
13802 +static int is_pid(struct dentry *dentry)
13804 + struct super_block *sb;
13807 + sb = dentry->d_sb;
13808 + if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
13811 + for(i = 0; i < dentry->d_name.len; i++){
13812 + if(!isdigit(dentry->d_name.name[i]))
13818 +static char *dentry_name(struct dentry *dentry, int extra)
13820 + struct dentry *parent;
13821 + char *root, *name;
13822 + const char *seg_name;
13823 + int len, seg_len;
13827 + while(parent->d_parent != parent){
13828 + if(is_pid(parent))
13829 + len += strlen("pid") + 1;
13830 + else len += parent->d_name.len + 1;
13831 + parent = parent->d_parent;
13835 + len += strlen(root);
13836 + name = kmalloc(len + extra + 1, GFP_KERNEL);
13837 + if(name == NULL) return(NULL);
13839 + name[len] = '\0';
13841 + while(parent->d_parent != parent){
13842 + if(is_pid(parent)){
13843 + seg_name = "pid";
13844 + seg_len = strlen("pid");
13847 + seg_name = parent->d_name.name;
13848 + seg_len = parent->d_name.len;
13851 + len -= seg_len + 1;
13853 + strncpy(&name[len + 1], seg_name, seg_len);
13854 + parent = parent->d_parent;
13856 + strncpy(name, root, strlen(root));
13860 +struct dentry_operations hppfs_dentry_ops = {
13863 +static int file_removed(struct dentry *dentry, const char *file)
13869 + if(file != NULL) extra += strlen(file) + 1;
13871 + host_file = dentry_name(dentry, extra + strlen("/remove"));
13872 + if(host_file == NULL){
13873 + printk("file_removed : allocation failed\n");
13877 + if(file != NULL){
13878 + strcat(host_file, "/");
13879 + strcat(host_file, file);
13881 + strcat(host_file, "/remove");
13883 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
13884 + kfree(host_file);
13886 + os_close_file(fd);
13892 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry)
13894 + struct dentry *proc_dentry;
13895 + struct inode *inode;
13896 + int err, deleted;
13898 + deleted = file_removed(dentry, NULL);
13900 + return(ERR_PTR(deleted));
13902 + return(ERR_PTR(-ENOENT));
13904 + proc_dentry = lookup_hash(&dentry->d_name, ino->u.hppfs_i.proc_dentry);
13905 + if(IS_ERR(proc_dentry))
13906 + return(proc_dentry);
13908 + inode = get_inode(ino->i_sb, proc_dentry, &err);
13910 + return(ERR_PTR(err));
13912 + d_add(dentry, inode);
13913 + dentry->d_op = &hppfs_dentry_ops;
13917 +static struct inode_operations hppfs_file_iops = {
13920 +static struct inode_operations hppfs_dir_iops = {
13921 + .lookup = hppfs_lookup,
13924 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count,
13925 + loff_t *ppos, int is_user)
13927 + ssize_t (*read)(struct file *, char *, size_t, loff_t *);
13930 + read = file->f_dentry->d_inode->i_fop->read;
13933 + set_fs(KERNEL_DS);
13935 + n = (*read)(file, buf, count, &file->f_pos);
13940 + if(ppos) *ppos = file->f_pos;
13944 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
13951 + new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
13952 + if(new_buf == NULL){
13953 + printk("hppfs_read_file : kmalloc failed\n");
13957 + while(count > 0){
13958 + cur = min_t(ssize_t, count, PAGE_SIZE);
13959 + err = os_read_file(fd, new_buf, cur);
13961 + printk("hppfs_read : read failed, err = %d\n", -err);
13965 + else if(err == 0)
13968 + if(copy_to_user(buf, new_buf, err)){
13981 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
13984 + struct hppfs_private *hppfs = file->private_data;
13985 + struct hppfs_data *data;
13989 + if(hppfs->contents != NULL){
13990 + if(*ppos >= hppfs->len) return(0);
13992 + data = hppfs->contents;
13994 + while(off >= sizeof(data->contents)){
13995 + data = list_entry(data->list.next, struct hppfs_data,
13997 + off -= sizeof(data->contents);
14000 + if(off + count > hppfs->len)
14001 + count = hppfs->len - off;
14002 + copy_to_user(buf, &data->contents[off], count);
14005 + else if(hppfs->host_fd != -1){
14006 + err = os_seek_file(hppfs->host_fd, *ppos);
14008 + printk("hppfs_read : seek failed, err = %d\n", -err);
14011 + count = hppfs_read_file(hppfs->host_fd, buf, count);
14015 + else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
14020 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len,
14023 + struct hppfs_private *data = file->private_data;
14024 + struct file *proc_file = &data->proc_file;
14025 + ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
14028 + write = proc_file->f_dentry->d_inode->i_fop->write;
14030 + proc_file->f_pos = file->f_pos;
14031 + err = (*write)(proc_file, buf, len, &proc_file->f_pos);
14032 + file->f_pos = proc_file->f_pos;
14037 +static int open_host_sock(char *host_file, int *filter_out)
14042 + end = &host_file[strlen(host_file)];
14043 + strcpy(end, "/rw");
14045 + fd = os_connect_socket(host_file);
14049 + strcpy(end, "/r");
14051 + fd = os_connect_socket(host_file);
14055 +static void free_contents(struct hppfs_data *head)
14057 + struct hppfs_data *data;
14058 + struct list_head *ele, *next;
14060 + if(head == NULL) return;
14062 + list_for_each_safe(ele, next, &head->list){
14063 + data = list_entry(ele, struct hppfs_data, list);
14069 +static struct hppfs_data *hppfs_get_data(int fd, int filter,
14070 + struct file *proc_file,
14071 + struct file *hppfs_file,
14072 + loff_t *size_out)
14074 + struct hppfs_data *data, *new, *head;
14078 + data = kmalloc(sizeof(*data), GFP_KERNEL);
14079 + if(data == NULL){
14080 + printk("hppfs_get_data : head allocation failed\n");
14084 + INIT_LIST_HEAD(&data->list);
14090 + while((n = read_proc(proc_file, data->contents,
14091 + sizeof(data->contents), NULL, 0)) > 0) {
14092 + err = os_write_file(fd, data->contents, n);
14094 + printk("hppfs_get_data : failed to write out "
14095 + "%d bytes, err = %d\n", n, -err);
14097 + err = os_shutdown_socket(fd, 0, 1);
14099 + printk("hppfs_get_data : failed to shut down "
14101 + goto failed_free;
14105 + n = os_read_file(fd, data->contents, sizeof(data->contents));
14108 + printk("hppfs_get_data : read failed, err = %d\n", -n);
14109 + goto failed_free;
14116 + if(n < sizeof(data->contents))
14119 + new = kmalloc(sizeof(*data), GFP_KERNEL);
14121 + printk("hppfs_get_data : data allocation failed\n");
14123 + goto failed_free;
14126 + INIT_LIST_HEAD(&new->list);
14127 + list_add(&new->list, &data->list);
14133 + free_contents(head);
14135 + return(ERR_PTR(err));
14138 +static struct hppfs_private *hppfs_data(void)
14140 + struct hppfs_private *data;
14142 + data = kmalloc(sizeof(*data), GFP_KERNEL);
14146 + *data = ((struct hppfs_private ) { .host_fd = -1,
14148 + .contents = NULL } );
14152 +static int hppfs_open(struct inode *inode, struct file *file)
14154 + struct hppfs_private *data;
14155 + struct dentry *proc_dentry;
14157 + int err, fd, type, filter;
14160 + data = hppfs_data();
14164 + host_file = dentry_name(file->f_dentry, strlen("/rw"));
14165 + if(host_file == NULL)
14168 + proc_dentry = inode->u.hppfs_i.proc_dentry;
14169 + err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
14173 + type = os_file_type(host_file);
14174 + if(type == OS_TYPE_FILE){
14175 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
14177 + data->host_fd = fd;
14178 + else printk("hppfs_open : failed to open '%s', err = %d\n",
14181 + data->contents = NULL;
14183 + else if(type == OS_TYPE_DIR){
14184 + fd = open_host_sock(host_file, &filter);
14186 + data->contents = hppfs_get_data(fd, filter,
14187 + &data->proc_file,
14188 + file, &data->len);
14189 + if(!IS_ERR(data->contents))
14190 + data->host_fd = fd;
14192 + else printk("hppfs_open : failed to open a socket in "
14193 + "'%s', err = %d\n", host_file, -fd);
14195 + kfree(host_file);
14197 + file->private_data = data;
14201 + kfree(host_file);
14203 + free_contents(data->contents);
14209 +static int hppfs_dir_open(struct inode *inode, struct file *file)
14211 + struct hppfs_private *data;
14212 + struct dentry *proc_dentry;
14216 + data = hppfs_data();
14220 + proc_dentry = inode->u.hppfs_i.proc_dentry;
14221 + err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
14225 + file->private_data = data;
14234 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
14236 + struct hppfs_private *data = file->private_data;
14237 + struct file *proc_file = &data->proc_file;
14238 + loff_t (*llseek)(struct file *, loff_t, int);
14241 + llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
14242 + if(llseek != NULL){
14243 + ret = (*llseek)(proc_file, off, where);
14248 + return(default_llseek(file, off, where));
14251 +struct hppfs_dirent {
14252 + void *vfs_dirent;
14253 + filldir_t filldir;
14254 + struct dentry *dentry;
14257 +static int hppfs_filldir(void *d, const char *name, int size,
14258 + loff_t offset, ino_t inode, unsigned int type)
14260 + struct hppfs_dirent *dirent = d;
14262 + if(file_removed(dirent->dentry, name))
14265 + return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
14269 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
14271 + struct hppfs_private *data = file->private_data;
14272 + struct file *proc_file = &data->proc_file;
14273 + int (*readdir)(struct file *, void *, filldir_t);
14274 + struct hppfs_dirent dirent = ((struct hppfs_dirent)
14275 + { .vfs_dirent = ent,
14276 + .filldir = filldir,
14277 + .dentry = file->f_dentry } );
14280 + readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
14282 + proc_file->f_pos = file->f_pos;
14283 + err = (*readdir)(proc_file, &dirent, hppfs_filldir);
14284 + file->f_pos = proc_file->f_pos;
14289 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
14294 +static struct file_operations hppfs_file_fops = {
14296 + .llseek = hppfs_llseek,
14297 + .read = hppfs_read,
14298 + .write = hppfs_write,
14299 + .open = hppfs_open,
14302 +static struct file_operations hppfs_dir_fops = {
14304 + .readdir = hppfs_readdir,
14305 + .open = hppfs_dir_open,
14306 + .fsync = hppfs_fsync,
14309 +static int hppfs_statfs(struct super_block *sb, struct statfs *sf)
14311 + sf->f_blocks = 0;
14313 + sf->f_bavail = 0;
14316 + sf->f_type = HPPFS_SUPER_MAGIC;
14320 +static struct super_operations hppfs_sbops = {
14321 + .put_inode = force_delete,
14322 + .delete_inode = NULL,
14323 + .statfs = hppfs_statfs,
14326 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
14328 + struct file proc_file;
14329 + struct dentry *proc_dentry;
14330 + int (*readlink)(struct dentry *, char *, int);
14333 + proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
14334 + err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
14338 + readlink = proc_dentry->d_inode->i_op->readlink;
14339 + n = (*readlink)(proc_dentry, buffer, buflen);
14341 + if(proc_file.f_op->release)
14342 + (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
14347 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
14349 + struct file proc_file;
14350 + struct dentry *proc_dentry;
14351 + int (*follow_link)(struct dentry *, struct nameidata *);
14354 + proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
14355 + err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
14359 + follow_link = proc_dentry->d_inode->i_op->follow_link;
14360 + n = (*follow_link)(proc_dentry, nd);
14362 + if(proc_file.f_op->release)
14363 + (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
14368 +static struct inode_operations hppfs_link_iops = {
14369 + .readlink = hppfs_readlink,
14370 + .follow_link = hppfs_follow_link,
14373 +static void read_inode(struct inode *ino)
14375 + struct inode *proc_ino;
14377 + proc_ino = ino->u.hppfs_i.proc_dentry->d_inode;
14378 + ino->i_uid = proc_ino->i_uid;
14379 + ino->i_gid = proc_ino->i_gid;
14380 + ino->i_atime = proc_ino->i_atime;
14381 + ino->i_mtime = proc_ino->i_mtime;
14382 + ino->i_ctime = proc_ino->i_ctime;
14383 + ino->i_ino = proc_ino->i_ino;
14384 + ino->i_dev = proc_ino->i_dev;
14385 + ino->i_mode = proc_ino->i_mode;
14386 + ino->i_nlink = proc_ino->i_nlink;
14387 + ino->i_size = proc_ino->i_size;
14388 + ino->i_blksize = proc_ino->i_blksize;
14389 + ino->i_blocks = proc_ino->i_blocks;
14392 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
14395 + struct inode *inode;
14396 + int err = -ENOMEM;
14398 + inode = new_inode(sb);
14399 + if(inode == NULL)
14402 + insert_inode_hash(inode);
14403 + if(S_ISDIR(dentry->d_inode->i_mode)){
14404 + inode->i_op = &hppfs_dir_iops;
14405 + inode->i_fop = &hppfs_dir_fops;
14407 + else if(S_ISLNK(dentry->d_inode->i_mode)){
14408 + inode->i_op = &hppfs_link_iops;
14409 + inode->i_fop = &hppfs_file_fops;
14412 + inode->i_op = &hppfs_file_iops;
14413 + inode->i_fop = &hppfs_file_fops;
14416 + inode->i_sb = sb;
14417 + inode->u.hppfs_i.proc_dentry = dentry;
14419 + read_inode(inode);
14422 + if(error) *error = err;
14425 + if(error) *error = err;
14429 +static struct super_block *hppfs_read_super(struct super_block *sb, void *d,
14432 + struct inode *root_inode;
14433 + struct file_system_type *procfs;
14434 + struct super_block *proc_sb;
14436 + procfs = get_fs_type("proc");
14437 + if(procfs == NULL)
14440 + if(list_empty(&procfs->fs_supers))
14443 + proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
14446 + sb->s_blocksize = 1024;
14447 + sb->s_blocksize_bits = 10;
14448 + sb->s_magic = HPPFS_SUPER_MAGIC;
14449 + sb->s_op = &hppfs_sbops;
14451 + dget(proc_sb->s_root);
14452 + root_inode = get_inode(sb, proc_sb->s_root, NULL);
14453 + if(root_inode == NULL)
14456 + sb->s_root = d_alloc_root(root_inode);
14457 + if(sb->s_root == NULL)
14463 + iput(root_inode);
14465 + dput(proc_sb->s_root);
14470 +DECLARE_FSTYPE(hppfs_type, "hppfs", hppfs_read_super, 0);
14472 +static int __init init_hppfs(void)
14474 + return(register_filesystem(&hppfs_type));
14477 +static void __exit exit_hppfs(void)
14479 + unregister_filesystem(&hppfs_type);
14482 +module_init(init_hppfs)
14483 +module_exit(exit_hppfs)
14484 +MODULE_LICENSE("GPL");
14487 + * Overrides for Emacs so that we follow Linus's tabbing style.
14488 + * Emacs will notice this stuff at the end of the file and automatically
14489 + * adjust the settings for this buffer only. This must remain at the end
14491 + * ---------------------------------------------------------------------------
14492 + * Local variables:
14493 + * c-file-style: "linux"
14496 diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/Makefile um/arch/um/fs/hppfs/Makefile
14497 --- orig/arch/um/fs/hppfs/Makefile 1969-12-31 19:00:00.000000000 -0500
14498 +++ um/arch/um/fs/hppfs/Makefile 2003-10-21 03:26:06.000000000 -0400
14500 +O_TARGET := hppfs.o
14501 +obj-y = hppfs_kern.o #hppfs_user.o
14502 +obj-m = $(O_TARGET)
14504 +CFLAGS_hppfs_kern.o := $(CFLAGS)
14505 +#CFLAGS_hppfs_user.o := $(USER_CFLAGS)
14509 +include $(TOPDIR)/Rules.make
14510 diff -Naur -X ../exclude-files orig/arch/um/fs/Makefile um/arch/um/fs/Makefile
14511 --- orig/arch/um/fs/Makefile 1969-12-31 19:00:00.000000000 -0500
14512 +++ um/arch/um/fs/Makefile 2003-10-21 03:26:06.000000000 -0400
14515 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
14516 +# Licensed under the GPL
14519 +O_TARGET := built-in.o
14524 +subdir-$(CONFIG_HOSTFS) += hostfs
14525 +subdir-$(CONFIG_HPPFS) += hppfs
14527 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
14528 +obj-m += $(join $(subdir-m),$(subdir-m:%=/%.o))
14530 +include $(TOPDIR)/Rules.make
14537 diff -Naur -X ../exclude-files orig/arch/um/include/2_5compat.h um/arch/um/include/2_5compat.h
14538 --- orig/arch/um/include/2_5compat.h 1969-12-31 19:00:00.000000000 -0500
14539 +++ um/arch/um/include/2_5compat.h 2003-11-07 02:49:26.000000000 -0500
14542 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
14543 + * Licensed under the GPL
14546 +#ifndef __2_5_COMPAT_H__
14547 +#define __2_5_COMPAT_H__
14549 +#include "linux/version.h"
14551 +#define INIT_ELV(queue, elv) elevator_init(elv, ELV_NOOP)
14553 +#define ELV_NOOP ELEVATOR_NOOP
14555 +#define INIT_HARDSECT(arr, maj, sizes) arr[maj] = sizes
14557 +#define IS_WRITE(req) ((req)->cmd == WRITE)
14559 +#define SET_PRI(task) \
14560 + do { (task)->nice = 20; (task)->counter = -100; } while(0);
14565 + * Overrides for Emacs so that we follow Linus's tabbing style.
14566 + * Emacs will notice this stuff at the end of the file and automatically
14567 + * adjust the settings for this buffer only. This must remain at the end
14569 + * ---------------------------------------------------------------------------
14570 + * Local variables:
14571 + * c-file-style: "linux"
14574 diff -Naur -X ../exclude-files orig/arch/um/include/chan_kern.h um/arch/um/include/chan_kern.h
14575 --- orig/arch/um/include/chan_kern.h 1969-12-31 19:00:00.000000000 -0500
14576 +++ um/arch/um/include/chan_kern.h 2003-10-21 03:26:06.000000000 -0400
14579 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
14580 + * Licensed under the GPL
14583 +#ifndef __CHAN_KERN_H__
14584 +#define __CHAN_KERN_H__
14586 +#include "linux/tty.h"
14587 +#include "linux/list.h"
14588 +#include "chan_user.h"
14591 + struct list_head list;
14593 + unsigned int primary:1;
14594 + unsigned int input:1;
14595 + unsigned int output:1;
14596 + unsigned int opened:1;
14598 + enum chan_init_pri pri;
14599 + struct chan_ops *ops;
14603 +extern void chan_interrupt(struct list_head *chans, struct tq_struct *task,
14604 + struct tty_struct *tty, int irq, void *dev);
14605 +extern int parse_chan_pair(char *str, struct list_head *chans, int pri,
14606 + int device, struct chan_opts *opts);
14607 +extern int open_chan(struct list_head *chans);
14608 +extern int write_chan(struct list_head *chans, const char *buf, int len,
14610 +extern int console_write_chan(struct list_head *chans, const char *buf,
14612 +extern void close_chan(struct list_head *chans);
14613 +extern void chan_enable_winch(struct list_head *chans, void *line);
14614 +extern void enable_chan(struct list_head *chans, void *data);
14615 +extern int chan_window_size(struct list_head *chans,
14616 + unsigned short *rows_out,
14617 + unsigned short *cols_out);
14618 +extern int chan_out_fd(struct list_head *chans);
14619 +extern int chan_config_string(struct list_head *chans, char *str, int size,
14620 + char **error_out);
14625 + * Overrides for Emacs so that we follow Linus's tabbing style.
14626 + * Emacs will notice this stuff at the end of the file and automatically
14627 + * adjust the settings for this buffer only. This must remain at the end
14629 + * ---------------------------------------------------------------------------
14630 + * Local variables:
14631 + * c-file-style: "linux"
14634 diff -Naur -X ../exclude-files orig/arch/um/include/chan_user.h um/arch/um/include/chan_user.h
14635 --- orig/arch/um/include/chan_user.h 1969-12-31 19:00:00.000000000 -0500
14636 +++ um/arch/um/include/chan_user.h 2003-10-21 03:26:06.000000000 -0400
14639 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
14640 + * Licensed under the GPL
14643 +#ifndef __CHAN_USER_H__
14644 +#define __CHAN_USER_H__
14648 +struct chan_opts {
14649 + void (*announce)(char *dev_name, int dev);
14650 + char *xterm_title;
14652 + unsigned long tramp_stack;
14656 +enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE };
14660 + void *(*init)(char *, int, struct chan_opts *);
14661 + int (*open)(int, int, int, void *, char **);
14662 + void (*close)(int, void *);
14663 + int (*read)(int, char *, void *);
14664 + int (*write)(int, const char *, int, void *);
14665 + int (*console_write)(int, const char *, int, void *);
14666 + int (*window_size)(int, void *, unsigned short *, unsigned short *);
14667 + void (*free)(void *);
14671 +extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops,
14674 +extern void generic_close(int fd, void *unused);
14675 +extern int generic_read(int fd, char *c_out, void *unused);
14676 +extern int generic_write(int fd, const char *buf, int n, void *unused);
14677 +extern int generic_console_write(int fd, const char *buf, int n, void *state);
14678 +extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
14679 + unsigned short *cols_out);
14680 +extern void generic_free(void *data);
14682 +extern void register_winch(int fd, void *device_data);
14683 +extern void register_winch_irq(int fd, int tty_fd, int pid, void *line);
14685 +#define __channel_help(fn, prefix) \
14686 +__uml_help(fn, prefix "[0-9]*=<channel description>\n" \
14687 +" Attach a console or serial line to a host channel. See\n" \
14688 +" http://user-mode-linux.sourceforge.net/input.html for a complete\n" \
14689 +" description of this switch.\n\n" \
14695 + * Overrides for Emacs so that we follow Linus's tabbing style.
14696 + * Emacs will notice this stuff at the end of the file and automatically
14697 + * adjust the settings for this buffer only. This must remain at the end
14699 + * ---------------------------------------------------------------------------
14700 + * Local variables:
14701 + * c-file-style: "linux"
14704 diff -Naur -X ../exclude-files orig/arch/um/include/choose-mode.h um/arch/um/include/choose-mode.h
14705 --- orig/arch/um/include/choose-mode.h 1969-12-31 19:00:00.000000000 -0500
14706 +++ um/arch/um/include/choose-mode.h 2003-10-21 03:26:06.000000000 -0400
14709 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14710 + * Licensed under the GPL
14713 +#ifndef __CHOOSE_MODE_H__
14714 +#define __CHOOSE_MODE_H__
14716 +#include "uml-config.h"
14718 +#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS)
14719 +#define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas))
14721 +#elif defined(UML_CONFIG_MODE_SKAS)
14722 +#define CHOOSE_MODE(tt, skas) (skas)
14724 +#elif defined(UML_CONFIG_MODE_TT)
14725 +#define CHOOSE_MODE(tt, skas) (tt)
14728 +#define CHOOSE_MODE_PROC(tt, skas, args...) \
14729 + CHOOSE_MODE(tt(args), skas(args))
14734 + * Overrides for Emacs so that we follow Linus's tabbing style.
14735 + * Emacs will notice this stuff at the end of the file and automatically
14736 + * adjust the settings for this buffer only. This must remain at the end
14738 + * ---------------------------------------------------------------------------
14739 + * Local variables:
14740 + * c-file-style: "linux"
14743 diff -Naur -X ../exclude-files orig/arch/um/include/frame.h um/arch/um/include/frame.h
14744 --- orig/arch/um/include/frame.h 1969-12-31 19:00:00.000000000 -0500
14745 +++ um/arch/um/include/frame.h 2003-10-21 03:26:06.000000000 -0400
14748 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14749 + * Licensed under the GPL
14752 +#ifndef __FRAME_H_
14753 +#define __FRAME_H_
14755 +#include "sysdep/frame.h"
14757 +struct frame_common {
14764 + struct arch_frame_data arch;
14768 + struct frame_common common;
14772 +extern struct sc_frame signal_frame_sc;
14774 +extern struct sc_frame signal_frame_sc_sr;
14777 + struct frame_common common;
14784 +extern struct si_frame signal_frame_si;
14786 +extern void capture_signal_stack(void);
14791 + * Overrides for Emacs so that we follow Linus's tabbing style.
14792 + * Emacs will notice this stuff at the end of the file and automatically
14793 + * adjust the settings for this buffer only. This must remain at the end
14795 + * ---------------------------------------------------------------------------
14796 + * Local variables:
14797 + * c-file-style: "linux"
14800 diff -Naur -X ../exclude-files orig/arch/um/include/frame_kern.h um/arch/um/include/frame_kern.h
14801 --- orig/arch/um/include/frame_kern.h 1969-12-31 19:00:00.000000000 -0500
14802 +++ um/arch/um/include/frame_kern.h 2003-10-21 03:26:06.000000000 -0400
14805 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14806 + * Licensed under the GPL
14809 +#ifndef __FRAME_KERN_H_
14810 +#define __FRAME_KERN_H_
14812 +#include "frame.h"
14813 +#include "sysdep/frame_kern.h"
14815 +extern int setup_signal_stack_sc(unsigned long stack_top, int sig,
14816 + unsigned long handler,
14817 + void (*restorer)(void),
14818 + struct pt_regs *regs,
14820 +extern int setup_signal_stack_si(unsigned long stack_top, int sig,
14821 + unsigned long handler,
14822 + void (*restorer)(void),
14823 + struct pt_regs *regs, siginfo_t *info,
14829 + * Overrides for Emacs so that we follow Linus's tabbing style.
14830 + * Emacs will notice this stuff at the end of the file and automatically
14831 + * adjust the settings for this buffer only. This must remain at the end
14833 + * ---------------------------------------------------------------------------
14834 + * Local variables:
14835 + * c-file-style: "linux"
14838 diff -Naur -X ../exclude-files orig/arch/um/include/frame_user.h um/arch/um/include/frame_user.h
14839 --- orig/arch/um/include/frame_user.h 1969-12-31 19:00:00.000000000 -0500
14840 +++ um/arch/um/include/frame_user.h 2003-10-21 03:26:06.000000000 -0400
14843 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14844 + * Licensed under the GPL
14847 +#ifndef __FRAME_USER_H_
14848 +#define __FRAME_USER_H_
14850 +#include "sysdep/frame_user.h"
14851 +#include "frame.h"
14856 + * Overrides for Emacs so that we follow Linus's tabbing style.
14857 + * Emacs will notice this stuff at the end of the file and automatically
14858 + * adjust the settings for this buffer only. This must remain at the end
14860 + * ---------------------------------------------------------------------------
14861 + * Local variables:
14862 + * c-file-style: "linux"
14865 diff -Naur -X ../exclude-files orig/arch/um/include/helper.h um/arch/um/include/helper.h
14866 --- orig/arch/um/include/helper.h 1969-12-31 19:00:00.000000000 -0500
14867 +++ um/arch/um/include/helper.h 2003-10-21 03:26:06.000000000 -0400
14870 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14871 + * Licensed under the GPL
14874 +#ifndef __HELPER_H__
14875 +#define __HELPER_H__
14877 +extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
14878 + unsigned long *stack_out);
14879 +extern int run_helper_thread(int (*proc)(void *), void *arg,
14880 + unsigned int flags, unsigned long *stack_out,
14881 + int stack_order);
14882 +extern int helper_wait(int pid);
14887 + * Overrides for Emacs so that we follow Linus's tabbing style.
14888 + * Emacs will notice this stuff at the end of the file and automatically
14889 + * adjust the settings for this buffer only. This must remain at the end
14891 + * ---------------------------------------------------------------------------
14892 + * Local variables:
14893 + * c-file-style: "linux"
14896 diff -Naur -X ../exclude-files orig/arch/um/include/hostaudio.h um/arch/um/include/hostaudio.h
14897 --- orig/arch/um/include/hostaudio.h 1969-12-31 19:00:00.000000000 -0500
14898 +++ um/arch/um/include/hostaudio.h 2003-10-21 03:26:06.000000000 -0400
14901 + * Copyright (C) 2002 Steve Schmidtke
14902 + * Licensed under the GPL
14905 +#ifndef HOSTAUDIO_H
14906 +#define HOSTAUDIO_H
14908 +#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
14909 +#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
14911 +struct hostaudio_state {
14915 +struct hostmixer_state {
14919 +/* UML user-side protoypes */
14920 +extern ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer,
14921 + size_t count, loff_t *ppos);
14922 +extern ssize_t hostaudio_write_user(struct hostaudio_state *state,
14923 + const char *buffer, size_t count,
14925 +extern int hostaudio_ioctl_user(struct hostaudio_state *state,
14926 + unsigned int cmd, unsigned long arg);
14927 +extern int hostaudio_open_user(struct hostaudio_state *state, int r, int w,
14929 +extern int hostaudio_release_user(struct hostaudio_state *state);
14930 +extern int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state,
14931 + unsigned int cmd, unsigned long arg);
14932 +extern int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r,
14933 + int w, char *mixer);
14934 +extern int hostmixer_release_mixdev_user(struct hostmixer_state *state);
14936 +#endif /* HOSTAUDIO_H */
14939 + * Overrides for Emacs so that we follow Linus's tabbing style.
14940 + * Emacs will notice this stuff at the end of the file and automatically
14941 + * adjust the settings for this buffer only. This must remain at the end
14943 + * ---------------------------------------------------------------------------
14944 + * Local variables:
14945 + * c-file-style: "linux"
14948 diff -Naur -X ../exclude-files orig/arch/um/include/init.h um/arch/um/include/init.h
14949 --- orig/arch/um/include/init.h 1969-12-31 19:00:00.000000000 -0500
14950 +++ um/arch/um/include/init.h 2003-10-21 03:26:06.000000000 -0400
14952 +#ifndef _LINUX_UML_INIT_H
14953 +#define _LINUX_UML_INIT_H
14955 +/* These macros are used to mark some functions or
14956 + * initialized data (doesn't apply to uninitialized data)
14957 + * as `initialization' functions. The kernel can take this
14958 + * as hint that the function is used only during the initialization
14959 + * phase and free up used memory resources after
14964 + * You should add __init immediately before the function name, like:
14966 + * static void __init initme(int x, int y)
14968 + * extern int z; z = x * y;
14971 + * If the function has a prototype somewhere, you can also add
14972 + * __init between closing brace of the prototype and semicolon:
14974 + * extern int initialize_foobar_device(int, int, int) __init;
14976 + * For initialized data:
14977 + * You should insert __initdata between the variable name and equal
14978 + * sign followed by value, e.g.:
14980 + * static int init_variable __initdata = 0;
14981 + * static char linux_logo[] __initdata = { 0x32, 0x36, ... };
14983 + * Don't forget to initialize data not at file scope, i.e. within a function,
14984 + * as gcc otherwise puts the data into the bss section and not into the init
14987 + * Also note, that this data cannot be "const".
14990 +#ifndef _LINUX_INIT_H
14991 +typedef int (*initcall_t)(void);
14992 +typedef void (*exitcall_t)(void);
14994 +#define __init __attribute__ ((__section__ (".text.init")))
14995 +#define __exit __attribute__ ((unused, __section__(".text.exit")))
14996 +#define __initdata __attribute__ ((__section__ (".data.init")))
15001 +struct uml_param {
15003 + int (*setup_func)(char *, int *);
15006 +extern initcall_t __uml_initcall_start, __uml_initcall_end;
15007 +extern initcall_t __uml_postsetup_start, __uml_postsetup_end;
15008 +extern const char *__uml_help_start, *__uml_help_end;
15011 +#define __uml_initcall(fn) \
15012 + static initcall_t __uml_initcall_##fn __uml_init_call = fn
15014 +#define __uml_exitcall(fn) \
15015 + static exitcall_t __uml_exitcall_##fn __uml_exit_call = fn
15017 +extern struct uml_param __uml_setup_start, __uml_setup_end;
15019 +#define __uml_postsetup(fn) \
15020 + static initcall_t __uml_postsetup_##fn __uml_postsetup_call = fn
15022 +#define __non_empty_string(dummyname,string) \
15023 + struct __uml_non_empty_string_struct_##dummyname \
15025 + char _string[sizeof(string)-2]; \
15029 +#define __uml_setup(str, fn, help...) \
15030 + __non_empty_string(fn ##_setup, str); \
15031 + __uml_help(fn, help); \
15032 + static char __uml_setup_str_##fn[] __initdata = str; \
15033 + static struct uml_param __uml_setup_##fn __uml_init_setup = { __uml_setup_str_##fn, fn }
15035 +#define __uml_setup(str, fn, help...) \
15039 +#define __uml_help(fn, help...) \
15040 + __non_empty_string(fn ##__help, help); \
15041 + static char __uml_help_str_##fn[] __initdata = help; \
15042 + static const char *__uml_help_##fn __uml_setup_help = __uml_help_str_##fn
15045 + * Mark functions and data as being only used at initialization
15048 +#define __uml_init_setup __attribute__ ((unused,__section__ (".uml.setup.init")))
15049 +#define __uml_setup_help __attribute__ ((unused,__section__ (".uml.help.init")))
15050 +#define __uml_init_call __attribute__ ((unused,__section__ (".uml.initcall.init")))
15051 +#define __uml_postsetup_call __attribute__ ((unused,__section__ (".uml.postsetup.init")))
15052 +#define __uml_exit_call __attribute__ ((unused,__section__ (".uml.exitcall.exit")))
15054 +#endif /* _LINUX_UML_INIT_H */
15057 + * Overrides for Emacs so that we follow Linus's tabbing style.
15058 + * Emacs will notice this stuff at the end of the file and automatically
15059 + * adjust the settings for this buffer only. This must remain at the end
15061 + * ---------------------------------------------------------------------------
15062 + * Local variables:
15063 + * c-file-style: "linux"
15066 diff -Naur -X ../exclude-files orig/arch/um/include/initrd.h um/arch/um/include/initrd.h
15067 --- orig/arch/um/include/initrd.h 1969-12-31 19:00:00.000000000 -0500
15068 +++ um/arch/um/include/initrd.h 2003-10-21 03:26:06.000000000 -0400
15071 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15072 + * Licensed under the GPL
15075 +#ifndef __INITRD_USER_H__
15076 +#define __INITRD_USER_H__
15078 +extern int load_initrd(char *filename, void *buf, int size);
15083 + * Overrides for Emacs so that we follow Linus's tabbing style.
15084 + * Emacs will notice this stuff at the end of the file and automatically
15085 + * adjust the settings for this buffer only. This must remain at the end
15087 + * ---------------------------------------------------------------------------
15088 + * Local variables:
15089 + * c-file-style: "linux"
15092 diff -Naur -X ../exclude-files orig/arch/um/include/irq_kern.h um/arch/um/include/irq_kern.h
15093 --- orig/arch/um/include/irq_kern.h 1969-12-31 19:00:00.000000000 -0500
15094 +++ um/arch/um/include/irq_kern.h 2003-10-21 03:26:06.000000000 -0400
15097 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15098 + * Licensed under the GPL
15101 +#ifndef __IRQ_KERN_H__
15102 +#define __IRQ_KERN_H__
15104 +#include "linux/interrupt.h"
15106 +extern int um_request_irq(unsigned int irq, int fd, int type,
15107 + void (*handler)(int, void *, struct pt_regs *),
15108 + unsigned long irqflags, const char * devname,
15114 + * Overrides for Emacs so that we follow Linus's tabbing style.
15115 + * Emacs will notice this stuff at the end of the file and automatically
15116 + * adjust the settings for this buffer only. This must remain at the end
15118 + * ---------------------------------------------------------------------------
15119 + * Local variables:
15120 + * c-file-style: "linux"
15123 diff -Naur -X ../exclude-files orig/arch/um/include/irq_user.h um/arch/um/include/irq_user.h
15124 --- orig/arch/um/include/irq_user.h 1969-12-31 19:00:00.000000000 -0500
15125 +++ um/arch/um/include/irq_user.h 2003-10-21 03:26:06.000000000 -0400
15128 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15129 + * Licensed under the GPL
15132 +#ifndef __IRQ_USER_H__
15133 +#define __IRQ_USER_H__
15135 +enum { IRQ_READ, IRQ_WRITE };
15137 +extern void sigio_handler(int sig, union uml_pt_regs *regs);
15138 +extern int activate_fd(int irq, int fd, int type, void *dev_id);
15139 +extern void free_irq_by_irq_and_dev(int irq, void *dev_id);
15140 +extern void free_irq_by_fd(int fd);
15141 +extern void reactivate_fd(int fd, int irqnum);
15142 +extern void deactivate_fd(int fd, int irqnum);
15143 +extern void forward_interrupts(int pid);
15144 +extern void init_irq_signals(int on_sigstack);
15145 +extern void forward_ipi(int fd, int pid);
15146 +extern void free_irq_later(int irq, void *dev_id);
15147 +extern int activate_ipi(int fd, int pid);
15148 +extern unsigned long irq_lock(void);
15149 +extern void irq_unlock(unsigned long flags);
15153 + * Overrides for Emacs so that we follow Linus's tabbing style.
15154 + * Emacs will notice this stuff at the end of the file and automatically
15155 + * adjust the settings for this buffer only. This must remain at the end
15157 + * ---------------------------------------------------------------------------
15158 + * Local variables:
15159 + * c-file-style: "linux"
15162 diff -Naur -X ../exclude-files orig/arch/um/include/kern.h um/arch/um/include/kern.h
15163 --- orig/arch/um/include/kern.h 1969-12-31 19:00:00.000000000 -0500
15164 +++ um/arch/um/include/kern.h 2003-10-21 03:26:06.000000000 -0400
15167 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15168 + * Licensed under the GPL
15171 +#ifndef __KERN_H__
15172 +#define __KERN_H__
15174 +/* These are all user-mode things which are convenient to call directly
15175 + * from kernel code and for which writing a wrapper is too much of a pain.
15176 + * The regular include files can't be included because this file is included
15177 + * only into kernel code, and user-space includes conflict with kernel
15183 +extern int clone(int (*proc)(void *), void *sp, int flags, void *data);
15184 +extern int sleep(int);
15185 +extern int printf(char *fmt, ...);
15186 +extern char *strerror(int errnum);
15187 +extern char *ptsname(int __fd);
15188 +extern int munmap(void *, int);
15189 +extern void *sbrk(int increment);
15190 +extern void *malloc(int size);
15191 +extern void perror(char *err);
15192 +extern int kill(int pid, int sig);
15193 +extern int getuid(void);
15194 +extern int pause(void);
15195 +extern int write(int, const void *, int);
15196 +extern int exit(int);
15197 +extern int close(int);
15198 +extern int read(unsigned int, char *, int);
15199 +extern int pipe(int *);
15200 +extern int sched_yield(void);
15201 +extern int ptrace(int op, int pid, long addr, long data);
15205 + * Overrides for Emacs so that we follow Linus's tabbing style.
15206 + * Emacs will notice this stuff at the end of the file and automatically
15207 + * adjust the settings for this buffer only. This must remain at the end
15209 + * ---------------------------------------------------------------------------
15210 + * Local variables:
15211 + * c-file-style: "linux"
15214 diff -Naur -X ../exclude-files orig/arch/um/include/kern_util.h um/arch/um/include/kern_util.h
15215 --- orig/arch/um/include/kern_util.h 1969-12-31 19:00:00.000000000 -0500
15216 +++ um/arch/um/include/kern_util.h 2003-11-10 00:58:10.000000000 -0500
15219 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
15220 + * Licensed under the GPL
15223 +#ifndef __KERN_UTIL_H__
15224 +#define __KERN_UTIL_H__
15226 +#include "sysdep/ptrace.h"
15229 +extern char *linux_prog;
15230 +extern char *gdb_init;
15231 +extern int kmalloc_ok;
15232 +extern int timer_irq_inited;
15234 +extern int nsyscalls;
15236 +#define UML_ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK))
15237 +#define UML_ROUND_UP(addr) \
15238 + UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
15240 +extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg);
15241 +extern unsigned long stack_sp(unsigned long page);
15242 +extern int kernel_thread_proc(void *data);
15243 +extern void syscall_segv(int sig);
15244 +extern int current_pid(void);
15245 +extern unsigned long alloc_stack(int order, int atomic);
15246 +extern int do_signal(int error);
15247 +extern int is_stack_fault(unsigned long sp);
15248 +extern unsigned long segv(unsigned long address, unsigned long ip,
15249 + int is_write, int is_user, void *sc);
15250 +extern unsigned long handle_page_fault(unsigned long address, unsigned long ip,
15251 + int is_write, int is_user,
15253 +extern void syscall_ready(void);
15254 +extern int segv_syscall(void);
15255 +extern void kern_finish_exec(void *task, int new_pid, unsigned long stack);
15256 +extern int page_size(void);
15257 +extern int page_mask(void);
15258 +extern int need_finish_fork(void);
15259 +extern void free_stack(unsigned long stack, int order);
15260 +extern void add_input_request(int op, void (*proc)(int), void *arg);
15261 +extern int sys_execve(char *file, char **argv, char **env);
15262 +extern char *current_cmd(void);
15263 +extern void timer_handler(int sig, union uml_pt_regs *regs);
15264 +extern int set_signals(int enable);
15265 +extern void force_sigbus(void);
15266 +extern int pid_to_processor_id(int pid);
15267 +extern void block_signals(void);
15268 +extern void unblock_signals(void);
15269 +extern void deliver_signals(void *t);
15270 +extern int next_syscall_index(int max);
15271 +extern int next_trap_index(int max);
15272 +extern void cpu_idle(void);
15273 +extern void finish_fork(void);
15274 +extern void paging_init(void);
15275 +extern void init_flush_vm(void);
15276 +extern void *syscall_sp(void *t);
15277 +extern void syscall_trace(void);
15278 +extern int hz(void);
15279 +extern void idle_timer(void);
15280 +extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
15281 +extern int external_pid(void *t);
15282 +extern void boot_timer_handler(int sig);
15283 +extern void interrupt_end(void);
15284 +extern void initial_thread_cb(void (*proc)(void *), void *arg);
15285 +extern int debugger_signal(int status, int pid);
15286 +extern void debugger_parent_signal(int status, int pid);
15287 +extern void child_signal(int pid, int status);
15288 +extern int init_ptrace_proxy(int idle_pid, int startup, int stop);
15289 +extern int init_parent_proxy(int pid);
15290 +extern void check_stack_overflow(void *ptr);
15291 +extern void relay_signal(int sig, union uml_pt_regs *regs);
15292 +extern void not_implemented(void);
15293 +extern int user_context(unsigned long sp);
15294 +extern void timer_irq(union uml_pt_regs *regs);
15295 +extern void unprotect_stack(unsigned long stack);
15296 +extern void do_uml_exitcalls(void);
15297 +extern int attach_debugger(int idle_pid, int pid, int stop);
15298 +extern void bad_segv(unsigned long address, unsigned long ip, int is_write);
15299 +extern int config_gdb(char *str);
15300 +extern int remove_gdb(void);
15301 +extern char *uml_strdup(char *string);
15302 +extern void unprotect_kernel_mem(void);
15303 +extern void protect_kernel_mem(void);
15304 +extern void set_kmem_end(unsigned long);
15305 +extern void uml_cleanup(void);
15306 +extern void set_current(void *t);
15307 +extern void lock_signalled_task(void *t);
15308 +extern void IPI_handler(int cpu);
15309 +extern int jail_setup(char *line, int *add);
15310 +extern void *get_init_task(void);
15311 +extern int clear_user_proc(void *buf, int size);
15312 +extern int copy_to_user_proc(void *to, void *from, int size);
15313 +extern int copy_from_user_proc(void *to, void *from, int size);
15314 +extern int strlen_user_proc(char *str);
15315 +extern void bus_handler(int sig, union uml_pt_regs *regs);
15316 +extern void winch(int sig, union uml_pt_regs *regs);
15317 +extern long execute_syscall(void *r);
15318 +extern int smp_sigio_handler(void);
15319 +extern void *get_current(void);
15320 +extern struct task_struct *get_task(int pid, int require);
15321 +extern void machine_halt(void);
15322 +extern int is_syscall(unsigned long addr);
15323 +extern void arch_switch(void);
15324 +extern void free_irq(unsigned int, void *);
15325 +extern int um_in_interrupt(void);
15326 +extern int cpu(void);
15327 +extern unsigned long long time_stamp(void);
15332 + * Overrides for Emacs so that we follow Linus's tabbing style.
15333 + * Emacs will notice this stuff at the end of the file and automatically
15334 + * adjust the settings for this buffer only. This must remain at the end
15336 + * ---------------------------------------------------------------------------
15337 + * Local variables:
15338 + * c-file-style: "linux"
15341 diff -Naur -X ../exclude-files orig/arch/um/include/line.h um/arch/um/include/line.h
15342 --- orig/arch/um/include/line.h 1969-12-31 19:00:00.000000000 -0500
15343 +++ um/arch/um/include/line.h 2003-11-07 02:25:37.000000000 -0500
15346 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15347 + * Licensed under the GPL
15350 +#ifndef __LINE_H__
15351 +#define __LINE_H__
15353 +#include "linux/list.h"
15354 +#include "linux/tqueue.h"
15355 +#include "linux/tty.h"
15356 +#include "asm/semaphore.h"
15357 +#include "chan_user.h"
15358 +#include "mconsole_kern.h"
15360 +struct line_driver {
15362 + char *devfs_name;
15364 + short minor_start;
15368 + char *read_irq_name;
15370 + char *write_irq_name;
15371 + char *symlink_from;
15372 + char *symlink_to;
15373 + struct mc_device mc;
15379 + struct list_head chan_list;
15382 + struct tty_struct *tty;
15383 + struct semaphore sem;
15388 + struct tq_struct task;
15389 + struct line_driver *driver;
15393 +#define LINE_INIT(str, d) \
15394 + { init_str : str, \
15395 + init_pri : INIT_STATIC, \
15396 + chan_list : { }, \
15412 +#define LINES_INIT(n) { num : n }
15414 +extern void line_close(struct line *lines, struct tty_struct *tty);
15415 +extern int line_open(struct line *lines, struct tty_struct *tty,
15416 + struct chan_opts *opts);
15417 +extern int line_setup(struct line *lines, int num, char *init,
15418 + int all_allowed);
15419 +extern int line_write(struct line *line, struct tty_struct *tty, int from_user,
15420 + const char *buf, int len);
15421 +extern char *add_xterm_umid(char *base);
15422 +extern int line_setup_irq(int fd, int input, int output, void *data);
15423 +extern void line_close_chan(struct line *line);
15424 +extern void line_disable(struct line *line, int current_irq);
15425 +extern void line_register_devfs(struct lines *set,
15426 + struct line_driver *line_driver,
15427 + struct tty_driver *driver, struct line *lines,
15429 +extern void lines_init(struct line *lines, int nlines);
15430 +extern void close_lines(struct line *lines, int nlines);
15431 +extern int line_config(struct line *lines, int num, char *str);
15432 +extern int line_remove(struct line *lines, int num, char *str);
15433 +extern int line_get_config(char *dev, struct line *lines, int num, char *str,
15434 + int size, char **error_out);
15439 + * Overrides for Emacs so that we follow Linus's tabbing style.
15440 + * Emacs will notice this stuff at the end of the file and automatically
15441 + * adjust the settings for this buffer only. This must remain at the end
15443 + * ---------------------------------------------------------------------------
15444 + * Local variables:
15445 + * c-file-style: "linux"
15448 diff -Naur -X ../exclude-files orig/arch/um/include/Makefile um/arch/um/include/Makefile
15449 --- orig/arch/um/include/Makefile 1969-12-31 19:00:00.000000000 -0500
15450 +++ um/arch/um/include/Makefile 2003-10-21 03:26:06.000000000 -0400
15454 +sc.h : ../util/mk_sc
15455 + ../util/mk_sc > $@
15458 + $(MAKE) -C ../util mk_sc
15459 diff -Naur -X ../exclude-files orig/arch/um/include/mconsole.h um/arch/um/include/mconsole.h
15460 --- orig/arch/um/include/mconsole.h 1969-12-31 19:00:00.000000000 -0500
15461 +++ um/arch/um/include/mconsole.h 2003-10-21 03:26:06.000000000 -0400
15464 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
15465 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15466 + * Licensed under the GPL
15469 +#ifndef __MCONSOLE_H__
15470 +#define __MCONSOLE_H__
15472 +#ifndef __KERNEL__
15473 +#include <stdint.h>
15474 +#define u32 uint32_t
15477 +#define MCONSOLE_MAGIC (0xcafebabe)
15478 +#define MCONSOLE_MAX_DATA (512)
15479 +#define MCONSOLE_VERSION 2
15481 +struct mconsole_request {
15485 + char data[MCONSOLE_MAX_DATA];
15488 +struct mconsole_reply {
15492 + char data[MCONSOLE_MAX_DATA];
15495 +struct mconsole_notify {
15498 + enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
15499 + MCONSOLE_USER_NOTIFY } type;
15501 + char data[MCONSOLE_MAX_DATA];
15504 +struct mc_request;
15506 +enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
15508 +struct mconsole_command
15511 + void (*handler)(struct mc_request *req);
15512 + enum mc_context context;
15518 + int as_interrupt;
15520 + int originating_fd;
15522 + unsigned char origin[128]; /* sockaddr_un */
15524 + struct mconsole_request request;
15525 + struct mconsole_command *cmd;
15528 +extern char mconsole_socket_name[];
15530 +extern int mconsole_unlink_socket(void);
15531 +extern int mconsole_reply(struct mc_request *req, char *reply, int err,
15534 +extern void mconsole_version(struct mc_request *req);
15535 +extern void mconsole_help(struct mc_request *req);
15536 +extern void mconsole_halt(struct mc_request *req);
15537 +extern void mconsole_reboot(struct mc_request *req);
15538 +extern void mconsole_config(struct mc_request *req);
15539 +extern void mconsole_remove(struct mc_request *req);
15540 +extern void mconsole_sysrq(struct mc_request *req);
15541 +extern void mconsole_cad(struct mc_request *req);
15542 +extern void mconsole_stop(struct mc_request *req);
15543 +extern void mconsole_go(struct mc_request *req);
15544 +extern void mconsole_log(struct mc_request *req);
15545 +extern void mconsole_proc(struct mc_request *req);
15547 +extern int mconsole_get_request(int fd, struct mc_request *req);
15548 +extern int mconsole_notify(char *sock_name, int type, const void *data,
15550 +extern char *mconsole_notify_socket(void);
15551 +extern void lock_notify(void);
15552 +extern void unlock_notify(void);
15557 + * Overrides for Emacs so that we follow Linus's tabbing style.
15558 + * Emacs will notice this stuff at the end of the file and automatically
15559 + * adjust the settings for this buffer only. This must remain at the end
15561 + * ---------------------------------------------------------------------------
15562 + * Local variables:
15563 + * c-file-style: "linux"
15566 diff -Naur -X ../exclude-files orig/arch/um/include/mconsole_kern.h um/arch/um/include/mconsole_kern.h
15567 --- orig/arch/um/include/mconsole_kern.h 1969-12-31 19:00:00.000000000 -0500
15568 +++ um/arch/um/include/mconsole_kern.h 2003-10-21 03:26:06.000000000 -0400
15571 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15572 + * Licensed under the GPL
15575 +#ifndef __MCONSOLE_KERN_H__
15576 +#define __MCONSOLE_KERN_H__
15578 +#include "linux/config.h"
15579 +#include "linux/list.h"
15580 +#include "mconsole.h"
15582 +struct mconsole_entry {
15583 + struct list_head list;
15584 + struct mc_request request;
15587 +struct mc_device {
15588 + struct list_head list;
15590 + int (*config)(char *);
15591 + int (*get_config)(char *, char *, int, char **);
15592 + int (*remove)(char *);
15595 +#define CONFIG_CHUNK(str, size, current, chunk, end) \
15597 + current += strlen(chunk); \
15598 + if(current >= size) \
15600 + if(str != NULL){ \
15601 + strcpy(str, chunk); \
15602 + str += strlen(chunk); \
15608 +#ifdef CONFIG_MCONSOLE
15610 +extern void mconsole_register_dev(struct mc_device *new);
15614 +static inline void mconsole_register_dev(struct mc_device *new)
15623 + * Overrides for Emacs so that we follow Linus's tabbing style.
15624 + * Emacs will notice this stuff at the end of the file and automatically
15625 + * adjust the settings for this buffer only. This must remain at the end
15627 + * ---------------------------------------------------------------------------
15628 + * Local variables:
15629 + * c-file-style: "linux"
15632 diff -Naur -X ../exclude-files orig/arch/um/include/mem.h um/arch/um/include/mem.h
15633 --- orig/arch/um/include/mem.h 1969-12-31 19:00:00.000000000 -0500
15634 +++ um/arch/um/include/mem.h 2003-10-21 03:26:06.000000000 -0400
15637 + * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com)
15638 + * Licensed under the GPL
15644 +#include "linux/types.h"
15646 +extern void set_kmem_end(unsigned long new);
15647 +extern int phys_mapping(unsigned long phys, __u64 *offset_out);
15648 +extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
15649 +extern int is_remapped(void *virt);
15650 +extern int physmem_remove_mapping(void *virt);
15655 + * Overrides for Emacs so that we follow Linus's tabbing style.
15656 + * Emacs will notice this stuff at the end of the file and automatically
15657 + * adjust the settings for this buffer only. This must remain at the end
15659 + * ---------------------------------------------------------------------------
15660 + * Local variables:
15661 + * c-file-style: "linux"
15664 diff -Naur -X ../exclude-files orig/arch/um/include/mem_kern.h um/arch/um/include/mem_kern.h
15665 --- orig/arch/um/include/mem_kern.h 1969-12-31 19:00:00.000000000 -0500
15666 +++ um/arch/um/include/mem_kern.h 2003-10-21 03:26:06.000000000 -0400
15669 + * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com)
15670 + * Licensed under the GPL
15673 +#ifndef __MEM_KERN_H__
15674 +#define __MEM_KERN_H__
15676 +#include "linux/list.h"
15677 +#include "linux/types.h"
15680 + struct list_head list;
15681 + int (*proc)(int, unsigned long, int, __u64);
15684 +extern void register_remapper(struct remapper *info);
15689 + * Overrides for Emacs so that we follow Linus's tabbing style.
15690 + * Emacs will notice this stuff at the end of the file and automatically
15691 + * adjust the settings for this buffer only. This must remain at the end
15693 + * ---------------------------------------------------------------------------
15694 + * Local variables:
15695 + * c-file-style: "linux"
15698 diff -Naur -X ../exclude-files orig/arch/um/include/mem_user.h um/arch/um/include/mem_user.h
15699 --- orig/arch/um/include/mem_user.h 1969-12-31 19:00:00.000000000 -0500
15700 +++ um/arch/um/include/mem_user.h 2003-12-14 11:16:03.000000000 -0500
15703 + * arch/um/include/mem_user.h
15705 + * BRIEF MODULE DESCRIPTION
15706 + * user side memory interface for support IO memory inside user mode linux
15708 + * Copyright (C) 2001 RidgeRun, Inc.
15709 + * Author: RidgeRun, Inc.
15710 + * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
15712 + * This program is free software; you can redistribute it and/or modify it
15713 + * under the terms of the GNU General Public License as published by the
15714 + * Free Software Foundation; either version 2 of the License, or (at your
15715 + * option) any later version.
15717 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15718 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15719 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
15720 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15721 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15722 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
15723 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
15724 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15725 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
15726 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15728 + * You should have received a copy of the GNU General Public License along
15729 + * with this program; if not, write to the Free Software Foundation, Inc.,
15730 + * 675 Mass Ave, Cambridge, MA 02139, USA.
15733 +#ifndef _MEM_USER_H
15734 +#define _MEM_USER_H
15736 +struct iomem_region {
15737 + struct iomem_region *next;
15741 + unsigned long phys;
15742 + unsigned long virt;
15745 +extern struct iomem_region *iomem_regions;
15746 +extern int iomem_size;
15748 +#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
15750 +extern unsigned long host_task_size;
15751 +extern unsigned long task_size;
15753 +extern void check_devanon(void);
15754 +extern int init_mem_user(void);
15755 +extern int create_mem_file(unsigned long len);
15756 +extern void setup_memory(void *entry);
15757 +extern unsigned long find_iomem(char *driver, unsigned long *len_out);
15758 +extern int init_maps(unsigned long physmem, unsigned long iomem,
15759 + unsigned long highmem);
15760 +extern unsigned long get_vm(unsigned long len);
15761 +extern void setup_physmem(unsigned long start, unsigned long usable,
15762 + unsigned long len, unsigned long highmem);
15763 +extern void add_iomem(char *name, int fd, unsigned long size);
15764 +extern unsigned long phys_offset(unsigned long phys);
15765 +extern void unmap_physmem(void);
15766 +extern void map_memory(unsigned long virt, unsigned long phys,
15767 + unsigned long len, int r, int w, int x);
15768 +extern int protect_memory(unsigned long addr, unsigned long len,
15769 + int r, int w, int x, int must_succeed);
15770 +extern unsigned long get_kmem_end(void);
15775 + * Overrides for Emacs so that we follow Linus's tabbing style.
15776 + * Emacs will notice this stuff at the end of the file and automatically
15777 + * adjust the settings for this buffer only. This must remain at the end
15779 + * ---------------------------------------------------------------------------
15780 + * Local variables:
15781 + * c-file-style: "linux"
15784 diff -Naur -X ../exclude-files orig/arch/um/include/mode.h um/arch/um/include/mode.h
15785 --- orig/arch/um/include/mode.h 1969-12-31 19:00:00.000000000 -0500
15786 +++ um/arch/um/include/mode.h 2003-10-21 03:26:06.000000000 -0400
15789 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15790 + * Licensed under the GPL
15793 +#ifndef __MODE_H__
15794 +#define __MODE_H__
15796 +#include "uml-config.h"
15798 +#ifdef UML_CONFIG_MODE_TT
15799 +#include "../kernel/tt/include/mode.h"
15802 +#ifdef UML_CONFIG_MODE_SKAS
15803 +#include "../kernel/skas/include/mode.h"
15809 + * Overrides for Emacs so that we follow Linus's tabbing style.
15810 + * Emacs will notice this stuff at the end of the file and automatically
15811 + * adjust the settings for this buffer only. This must remain at the end
15813 + * ---------------------------------------------------------------------------
15814 + * Local variables:
15815 + * c-file-style: "linux"
15818 diff -Naur -X ../exclude-files orig/arch/um/include/mode_kern.h um/arch/um/include/mode_kern.h
15819 --- orig/arch/um/include/mode_kern.h 1969-12-31 19:00:00.000000000 -0500
15820 +++ um/arch/um/include/mode_kern.h 2003-10-21 03:26:06.000000000 -0400
15823 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15824 + * Licensed under the GPL
15827 +#ifndef __MODE_KERN_H__
15828 +#define __MODE_KERN_H__
15830 +#include "linux/config.h"
15832 +#ifdef CONFIG_MODE_TT
15833 +#include "../kernel/tt/include/mode_kern.h"
15836 +#ifdef CONFIG_MODE_SKAS
15837 +#include "../kernel/skas/include/mode_kern.h"
15843 + * Overrides for Emacs so that we follow Linus's tabbing style.
15844 + * Emacs will notice this stuff at the end of the file and automatically
15845 + * adjust the settings for this buffer only. This must remain at the end
15847 + * ---------------------------------------------------------------------------
15848 + * Local variables:
15849 + * c-file-style: "linux"
15852 diff -Naur -X ../exclude-files orig/arch/um/include/net_kern.h um/arch/um/include/net_kern.h
15853 --- orig/arch/um/include/net_kern.h 1969-12-31 19:00:00.000000000 -0500
15854 +++ um/arch/um/include/net_kern.h 2003-10-21 03:26:06.000000000 -0400
15857 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15858 + * Licensed under the GPL
15861 +#ifndef __UM_NET_KERN_H
15862 +#define __UM_NET_KERN_H
15864 +#include "linux/netdevice.h"
15865 +#include "linux/skbuff.h"
15866 +#include "linux/socket.h"
15867 +#include "linux/list.h"
15870 + struct list_head list;
15871 + struct net_device *dev;
15873 + unsigned char mac[ETH_ALEN];
15877 +struct uml_net_private {
15878 + struct list_head list;
15880 + struct net_device *dev;
15881 + struct timer_list tl;
15882 + struct net_device_stats stats;
15884 + unsigned char mac[ETH_ALEN];
15886 + unsigned short (*protocol)(struct sk_buff *);
15887 + int (*open)(void *);
15888 + void (*close)(int, void *);
15889 + void (*remove)(void *);
15890 + int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
15891 + int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
15893 + void (*add_address)(unsigned char *, unsigned char *, void *);
15894 + void (*delete_address)(unsigned char *, unsigned char *, void *);
15895 + int (*set_mtu)(int mtu, void *);
15899 +struct net_kern_info {
15900 + void (*init)(struct net_device *, void *);
15901 + unsigned short (*protocol)(struct sk_buff *);
15902 + int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
15903 + int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
15906 +struct transport {
15907 + struct list_head list;
15909 + int (*setup)(char *, char **, void *);
15910 + struct net_user_info *user;
15911 + struct net_kern_info *kern;
15912 + int private_size;
15916 +extern struct net_device *ether_init(int);
15917 +extern unsigned short ether_protocol(struct sk_buff *);
15918 +extern int setup_etheraddr(char *str, unsigned char *addr);
15919 +extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
15920 +extern int tap_setup_common(char *str, char *type, char **dev_name,
15921 + char **mac_out, char **gate_addr);
15922 +extern void register_transport(struct transport *new);
15923 +extern unsigned short eth_protocol(struct sk_buff *skb);
15928 + * Overrides for Emacs so that we follow Linus's tabbing style.
15929 + * Emacs will notice this stuff at the end of the file and automatically
15930 + * adjust the settings for this buffer only. This must remain at the end
15932 + * ---------------------------------------------------------------------------
15933 + * Local variables:
15934 + * c-file-style: "linux"
15937 diff -Naur -X ../exclude-files orig/arch/um/include/net_user.h um/arch/um/include/net_user.h
15938 --- orig/arch/um/include/net_user.h 1969-12-31 19:00:00.000000000 -0500
15939 +++ um/arch/um/include/net_user.h 2003-10-21 03:26:06.000000000 -0400
15942 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15943 + * Licensed under the GPL
15946 +#ifndef __UM_NET_USER_H__
15947 +#define __UM_NET_USER_H__
15949 +#define ETH_ADDR_LEN (6)
15950 +#define ETH_HEADER_ETHERTAP (16)
15951 +#define ETH_HEADER_OTHER (14)
15952 +#define ETH_MAX_PACKET (1500)
15954 +#define UML_NET_VERSION (4)
15956 +struct net_user_info {
15957 + void (*init)(void *, void *);
15958 + int (*open)(void *);
15959 + void (*close)(int, void *);
15960 + void (*remove)(void *);
15961 + int (*set_mtu)(int mtu, void *);
15962 + void (*add_address)(unsigned char *, unsigned char *, void *);
15963 + void (*delete_address)(unsigned char *, unsigned char *, void *);
15967 +extern void ether_user_init(void *data, void *dev);
15968 +extern void dev_ip_addr(void *d, char *buf, char *bin_buf);
15969 +extern void set_ether_mac(void *d, unsigned char *addr);
15970 +extern void iter_addresses(void *d, void (*cb)(unsigned char *,
15971 + unsigned char *, void *),
15974 +extern void *get_output_buffer(int *len_out);
15975 +extern void free_output_buffer(void *buffer);
15977 +extern int tap_open_common(void *dev, char *gate_addr);
15978 +extern void tap_check_ips(char *gate_addr, char *eth_addr);
15980 +extern void read_output(int fd, char *output_out, int len);
15982 +extern int net_read(int fd, void *buf, int len);
15983 +extern int net_recvfrom(int fd, void *buf, int len);
15984 +extern int net_write(int fd, void *buf, int len);
15985 +extern int net_send(int fd, void *buf, int len);
15986 +extern int net_sendto(int fd, void *buf, int len, void *to, int sock_len);
15988 +extern void open_addr(unsigned char *addr, unsigned char *netmask, void *arg);
15989 +extern void close_addr(unsigned char *addr, unsigned char *netmask, void *arg);
15991 +extern char *split_if_spec(char *str, ...);
15993 +extern int dev_netmask(void *d, void *m);
15998 + * Overrides for Emacs so that we follow Linus's tabbing style.
15999 + * Emacs will notice this stuff at the end of the file and automatically
16000 + * adjust the settings for this buffer only. This must remain at the end
16002 + * ---------------------------------------------------------------------------
16003 + * Local variables:
16004 + * c-file-style: "linux"
16007 diff -Naur -X ../exclude-files orig/arch/um/include/os.h um/arch/um/include/os.h
16008 --- orig/arch/um/include/os.h 1969-12-31 19:00:00.000000000 -0500
16009 +++ um/arch/um/include/os.h 2003-12-17 10:48:12.000000000 -0500
16012 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16013 + * Licensed under the GPL
16019 +#include "asm/types.h"
16020 +#include "../os/include/file.h"
16022 +#define OS_TYPE_FILE 1
16023 +#define OS_TYPE_DIR 2
16024 +#define OS_TYPE_SYMLINK 3
16025 +#define OS_TYPE_CHARDEV 4
16026 +#define OS_TYPE_BLOCKDEV 5
16027 +#define OS_TYPE_FIFO 6
16028 +#define OS_TYPE_SOCK 7
16030 +/* os_access() flags */
16031 +#define OS_ACC_F_OK 0 /* Test for existence. */
16032 +#define OS_ACC_X_OK 1 /* Test for execute permission. */
16033 +#define OS_ACC_W_OK 2 /* Test for write permission. */
16034 +#define OS_ACC_R_OK 4 /* Test for read permission. */
16035 +#define OS_ACC_RW_OK (OS_ACC_W_OK | OS_ACC_R_OK) /* Test for RW permission */
16038 + * types taken from stat_file() in hostfs_user.c
16039 + * (if they are wrong here, they are wrong there...).
16042 + int ust_dev; /* device */
16043 + unsigned long long ust_ino; /* inode */
16044 + int ust_mode; /* protection */
16045 + int ust_nlink; /* number of hard links */
16046 + int ust_uid; /* user ID of owner */
16047 + int ust_gid; /* group ID of owner */
16048 + unsigned long long ust_size; /* total size, in bytes */
16049 + int ust_blksize; /* blocksize for filesystem I/O */
16050 + unsigned long long ust_blocks; /* number of blocks allocated */
16051 + unsigned long ust_atime; /* time of last access */
16052 + unsigned long ust_mtime; /* time of last modification */
16053 + unsigned long ust_ctime; /* time of last change */
16056 +struct openflags {
16057 + unsigned int r : 1;
16058 + unsigned int w : 1;
16059 + unsigned int s : 1; /* O_SYNC */
16060 + unsigned int c : 1; /* O_CREAT */
16061 + unsigned int t : 1; /* O_TRUNC */
16062 + unsigned int a : 1; /* O_APPEND */
16063 + unsigned int e : 1; /* O_EXCL */
16064 + unsigned int cl : 1; /* FD_CLOEXEC */
16067 +#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
16068 + .t = 0, .a = 0, .e = 0, .cl = 0 })
16070 +static inline struct openflags of_read(struct openflags flags)
16076 +static inline struct openflags of_write(struct openflags flags)
16082 +static inline struct openflags of_rdwr(struct openflags flags)
16084 + return(of_read(of_write(flags)));
16087 +static inline struct openflags of_set_rw(struct openflags flags, int r, int w)
16094 +static inline struct openflags of_sync(struct openflags flags)
16100 +static inline struct openflags of_create(struct openflags flags)
16106 +static inline struct openflags of_trunc(struct openflags flags)
16112 +static inline struct openflags of_append(struct openflags flags)
16118 +static inline struct openflags of_excl(struct openflags flags)
16124 +static inline struct openflags of_cloexec(struct openflags flags)
16130 +extern int os_stat_file(const char *file_name, struct uml_stat *buf);
16131 +extern int os_stat_fd(const int fd, struct uml_stat *buf);
16132 +extern int os_access(const char *file, int mode);
16133 +extern void os_print_error(int error, const char* str);
16134 +extern int os_get_exec_close(int fd, int *close_on_exec);
16135 +extern int os_set_exec_close(int fd, int close_on_exec);
16136 +extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
16137 +extern int os_window_size(int fd, int *rows, int *cols);
16138 +extern int os_new_tty_pgrp(int fd, int pid);
16139 +extern int os_get_ifname(int fd, char *namebuf);
16140 +extern int os_set_slip(int fd);
16141 +extern int os_set_owner(int fd, int pid);
16142 +extern int os_sigio_async(int master, int slave);
16143 +extern int os_mode_fd(int fd, int mode);
16145 +extern int os_seek_file(int fd, __u64 offset);
16146 +extern int os_open_file(char *file, struct openflags flags, int mode);
16147 +extern int os_read_file(int fd, void *buf, int len);
16148 +extern int os_write_file(int fd, const void *buf, int count);
16149 +extern int os_file_size(char *file, long long *size_out);
16150 +extern int os_file_modtime(char *file, unsigned long *modtime);
16151 +extern int os_pipe(int *fd, int stream, int close_on_exec);
16152 +extern int os_set_fd_async(int fd, int owner);
16153 +extern int os_set_fd_block(int fd, int blocking);
16154 +extern int os_accept_connection(int fd);
16155 +extern int os_create_unix_socket(char *file, int len, int close_on_exec);
16156 +extern int os_shutdown_socket(int fd, int r, int w);
16157 +extern void os_close_file(int fd);
16158 +extern int os_rcv_fd(int fd, int *helper_pid_out);
16159 +extern int create_unix_socket(char *file, int len, int close_on_exec);
16160 +extern int os_connect_socket(char *name);
16161 +extern int os_file_type(char *file);
16162 +extern int os_file_mode(char *file, struct openflags *mode_out);
16163 +extern int os_lock_file(int fd, int excl);
16165 +extern unsigned long os_process_pc(int pid);
16166 +extern int os_process_parent(int pid);
16167 +extern void os_stop_process(int pid);
16168 +extern void os_kill_process(int pid, int reap_child);
16169 +extern void os_usr1_process(int pid);
16170 +extern int os_getpid(void);
16172 +extern int os_map_memory(void *virt, int fd, unsigned long long off,
16173 + unsigned long len, int r, int w, int x);
16174 +extern int os_protect_memory(void *addr, unsigned long len,
16175 + int r, int w, int x);
16176 +extern int os_unmap_memory(void *addr, int len);
16177 +extern void os_flush_stdout(void);
16182 + * Overrides for Emacs so that we follow Linus's tabbing style.
16183 + * Emacs will notice this stuff at the end of the file and automatically
16184 + * adjust the settings for this buffer only. This must remain at the end
16186 + * ---------------------------------------------------------------------------
16187 + * Local variables:
16188 + * c-file-style: "linux"
16191 diff -Naur -X ../exclude-files orig/arch/um/include/process.h um/arch/um/include/process.h
16192 --- orig/arch/um/include/process.h 1969-12-31 19:00:00.000000000 -0500
16193 +++ um/arch/um/include/process.h 2003-10-21 03:26:06.000000000 -0400
16196 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16197 + * Licensed under the GPL
16200 +#ifndef __PROCESS_H__
16201 +#define __PROCESS_H__
16203 +#include <asm/sigcontext.h>
16205 +extern void sig_handler(int sig, struct sigcontext sc);
16206 +extern void alarm_handler(int sig, struct sigcontext sc);
16211 + * Overrides for Emacs so that we follow Linus's tabbing style.
16212 + * Emacs will notice this stuff at the end of the file and automatically
16213 + * adjust the settings for this buffer only. This must remain at the end
16215 + * ---------------------------------------------------------------------------
16216 + * Local variables:
16217 + * c-file-style: "linux"
16220 diff -Naur -X ../exclude-files orig/arch/um/include/ptrace_user.h um/arch/um/include/ptrace_user.h
16221 --- orig/arch/um/include/ptrace_user.h 1969-12-31 19:00:00.000000000 -0500
16222 +++ um/arch/um/include/ptrace_user.h 2003-10-21 03:26:06.000000000 -0400
16225 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16226 + * Licensed under the GPL
16229 +#ifndef __PTRACE_USER_H__
16230 +#define __PTRACE_USER_H__
16232 +#include "sysdep/ptrace_user.h"
16234 +extern int ptrace_getregs(long pid, unsigned long *regs_out);
16235 +extern int ptrace_setregs(long pid, unsigned long *regs_in);
16236 +extern int ptrace_getfpregs(long pid, unsigned long *regs_out);
16237 +extern void arch_enter_kernel(void *task, int pid);
16238 +extern void arch_leave_kernel(void *task, int pid);
16239 +extern void ptrace_pokeuser(unsigned long addr, unsigned long data);
16242 diff -Naur -X ../exclude-files orig/arch/um/include/sigcontext.h um/arch/um/include/sigcontext.h
16243 --- orig/arch/um/include/sigcontext.h 1969-12-31 19:00:00.000000000 -0500
16244 +++ um/arch/um/include/sigcontext.h 2003-10-21 03:26:06.000000000 -0400
16247 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
16248 + * Licensed under the GPL
16251 +#ifndef __UML_SIGCONTEXT_H__
16252 +#define __UML_SIGCONTEXT_H__
16254 +#include "sysdep/sigcontext.h"
16256 +extern int sc_size(void *data);
16257 +extern void sc_to_sc(void *to_ptr, void *from_ptr);
16262 + * Overrides for Emacs so that we follow Linus's tabbing style.
16263 + * Emacs will notice this stuff at the end of the file and automatically
16264 + * adjust the settings for this buffer only. This must remain at the end
16266 + * ---------------------------------------------------------------------------
16267 + * Local variables:
16268 + * c-file-style: "linux"
16271 diff -Naur -X ../exclude-files orig/arch/um/include/sigio.h um/arch/um/include/sigio.h
16272 --- orig/arch/um/include/sigio.h 1969-12-31 19:00:00.000000000 -0500
16273 +++ um/arch/um/include/sigio.h 2003-10-21 03:26:06.000000000 -0400
16276 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16277 + * Licensed under the GPL
16280 +#ifndef __SIGIO_H__
16281 +#define __SIGIO_H__
16283 +extern int write_sigio_irq(int fd);
16284 +extern int register_sigio_fd(int fd);
16285 +extern int read_sigio_fd(int fd);
16286 +extern int add_sigio_fd(int fd, int read);
16287 +extern int ignore_sigio_fd(int fd);
16288 +extern void sigio_lock(void);
16289 +extern void sigio_unlock(void);
16294 + * Overrides for Emacs so that we follow Linus's tabbing style.
16295 + * Emacs will notice this stuff at the end of the file and automatically
16296 + * adjust the settings for this buffer only. This must remain at the end
16298 + * ---------------------------------------------------------------------------
16299 + * Local variables:
16300 + * c-file-style: "linux"
16303 diff -Naur -X ../exclude-files orig/arch/um/include/signal_kern.h um/arch/um/include/signal_kern.h
16304 --- orig/arch/um/include/signal_kern.h 1969-12-31 19:00:00.000000000 -0500
16305 +++ um/arch/um/include/signal_kern.h 2003-10-21 03:26:06.000000000 -0400
16308 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
16309 + * Licensed under the GPL
16312 +#ifndef __SIGNAL_KERN_H__
16313 +#define __SIGNAL_KERN_H__
16315 +extern int have_signals(void *t);
16320 + * Overrides for Emacs so that we follow Linus's tabbing style.
16321 + * Emacs will notice this stuff at the end of the file and automatically
16322 + * adjust the settings for this buffer only. This must remain at the end
16324 + * ---------------------------------------------------------------------------
16325 + * Local variables:
16326 + * c-file-style: "linux"
16329 diff -Naur -X ../exclude-files orig/arch/um/include/signal_user.h um/arch/um/include/signal_user.h
16330 --- orig/arch/um/include/signal_user.h 1969-12-31 19:00:00.000000000 -0500
16331 +++ um/arch/um/include/signal_user.h 2003-10-21 03:26:06.000000000 -0400
16334 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
16335 + * Licensed under the GPL
16338 +#ifndef __SIGNAL_USER_H__
16339 +#define __SIGNAL_USER_H__
16341 +extern int signal_stack_size;
16343 +extern int change_sig(int signal, int on);
16344 +extern void set_sigstack(void *stack, int size);
16345 +extern void set_handler(int sig, void (*handler)(int), int flags, ...);
16350 + * Overrides for Emacs so that we follow Linus's tabbing style.
16351 + * Emacs will notice this stuff at the end of the file and automatically
16352 + * adjust the settings for this buffer only. This must remain at the end
16354 + * ---------------------------------------------------------------------------
16355 + * Local variables:
16356 + * c-file-style: "linux"
16359 diff -Naur -X ../exclude-files orig/arch/um/include/skas_ptrace.h um/arch/um/include/skas_ptrace.h
16360 --- orig/arch/um/include/skas_ptrace.h 1969-12-31 19:00:00.000000000 -0500
16361 +++ um/arch/um/include/skas_ptrace.h 2003-10-21 03:26:06.000000000 -0400
16364 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16365 + * Licensed under the GPL
16368 +#ifndef __SKAS_PTRACE_H
16369 +#define __SKAS_PTRACE_H
16371 +struct ptrace_faultinfo {
16373 + unsigned long addr;
16376 +struct ptrace_ldt {
16379 + unsigned long bytecount;
16382 +#define PTRACE_FAULTINFO 52
16383 +#define PTRACE_SIGPENDING 53
16384 +#define PTRACE_LDT 54
16385 +#define PTRACE_SWITCH_MM 55
16390 + * Overrides for Emacs so that we follow Linus's tabbing style.
16391 + * Emacs will notice this stuff at the end of the file and automatically
16392 + * adjust the settings for this buffer only. This must remain at the end
16394 + * ---------------------------------------------------------------------------
16395 + * Local variables:
16396 + * c-file-style: "linux"
16399 diff -Naur -X ../exclude-files orig/arch/um/include/syscall_user.h um/arch/um/include/syscall_user.h
16400 --- orig/arch/um/include/syscall_user.h 1969-12-31 19:00:00.000000000 -0500
16401 +++ um/arch/um/include/syscall_user.h 2003-10-21 03:26:06.000000000 -0400
16404 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16405 + * Licensed under the GPL
16408 +#ifndef __SYSCALL_USER_H
16409 +#define __SYSCALL_USER_H
16411 +extern int record_syscall_start(int syscall);
16412 +extern void record_syscall_end(int index, int result);
16417 + * Overrides for Emacs so that we follow Linus's tabbing style.
16418 + * Emacs will notice this stuff at the end of the file and automatically
16419 + * adjust the settings for this buffer only. This must remain at the end
16421 + * ---------------------------------------------------------------------------
16422 + * Local variables:
16423 + * c-file-style: "linux"
16426 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/checksum.h um/arch/um/include/sysdep-i386/checksum.h
16427 --- orig/arch/um/include/sysdep-i386/checksum.h 1969-12-31 19:00:00.000000000 -0500
16428 +++ um/arch/um/include/sysdep-i386/checksum.h 2003-10-21 03:26:06.000000000 -0400
16431 + * Licensed under the GPL
16434 +#ifndef __UM_SYSDEP_CHECKSUM_H
16435 +#define __UM_SYSDEP_CHECKSUM_H
16437 +#include "linux/string.h"
16440 + * computes the checksum of a memory block at buff, length len,
16441 + * and adds in "sum" (32-bit)
16443 + * returns a 32-bit number suitable for feeding into itself
16444 + * or csum_tcpudp_magic
16446 + * this function must be called with even lengths, except
16447 + * for the last fragment, which may be odd
16449 + * it's best to have buff aligned on a 32-bit boundary
16451 +unsigned int csum_partial(const unsigned char * buff, int len,
16452 + unsigned int sum);
16455 + * the same as csum_partial, but copies from src while it
16456 + * checksums, and handles user-space pointer exceptions correctly, when needed.
16458 + * here even more important to align src and dst on a 32-bit (or even
16459 + * better 64-bit) boundary
16462 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len,
16463 + int sum, int *err_ptr);
16464 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len,
16465 + int sum, int *err_ptr);
16468 + * Note: when you get a NULL pointer exception here this means someone
16469 + * passed in an incorrect kernel address to one of these functions.
16471 + * If you use these functions directly please don't forget the
16476 +unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
16477 + int len, int sum)
16479 + memcpy(dst, src, len);
16480 + return(csum_partial(dst, len, sum));
16484 +unsigned int csum_partial_copy_from_user(const char *src, char *dst,
16485 + int len, int sum, int *err_ptr)
16487 + return csum_partial_copy_from(src, dst, len, sum, err_ptr);
16491 + * These are the old (and unsafe) way of doing checksums, a warning message
16492 + * will be printed if they are used and an exeption occurs.
16494 + * these functions should go away after some time.
16497 +#define csum_partial_copy_fromuser csum_partial_copy_from_user
16498 +unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
16501 + * This is a version of ip_compute_csum() optimized for IP headers,
16502 + * which always checksum on 4 octet boundaries.
16504 + * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
16505 + * Arnt Gulbrandsen.
16507 +static inline unsigned short ip_fast_csum(unsigned char * iph,
16508 + unsigned int ihl)
16510 + unsigned int sum;
16512 + __asm__ __volatile__(
16513 + "movl (%1), %0 ;\n"
16514 + "subl $4, %2 ;\n"
16516 + "addl 4(%1), %0 ;\n"
16517 + "adcl 8(%1), %0 ;\n"
16518 + "adcl 12(%1), %0 ;\n"
16519 +"1: adcl 16(%1), %0 ;\n"
16520 + "lea 4(%1), %1 ;\n"
16523 + "adcl $0, %0 ;\n"
16524 + "movl %0, %2 ;\n"
16525 + "shrl $16, %0 ;\n"
16526 + "addw %w2, %w0 ;\n"
16527 + "adcl $0, %0 ;\n"
16530 + /* Since the input registers which are loaded with iph and ipl
16531 + are modified, we must also specify them as outputs, or gcc
16532 + will assume they contain their original values. */
16533 + : "=r" (sum), "=r" (iph), "=r" (ihl)
16534 + : "1" (iph), "2" (ihl));
16539 + * Fold a partial checksum
16542 +static inline unsigned int csum_fold(unsigned int sum)
16545 + "addl %1, %0 ;\n"
16546 + "adcl $0xffff, %0 ;\n"
16548 + : "r" (sum << 16), "0" (sum & 0xffff0000)
16550 + return (~sum) >> 16;
16553 +static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
16554 + unsigned long daddr,
16555 + unsigned short len,
16556 + unsigned short proto,
16557 + unsigned int sum)
16560 + "addl %1, %0 ;\n"
16561 + "adcl %2, %0 ;\n"
16562 + "adcl %3, %0 ;\n"
16563 + "adcl $0, %0 ;\n"
16565 + : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum));
16570 + * computes the checksum of the TCP/UDP pseudo-header
16571 + * returns a 16-bit checksum, already complemented
16573 +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
16574 + unsigned long daddr,
16575 + unsigned short len,
16576 + unsigned short proto,
16577 + unsigned int sum)
16579 + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
16583 + * this routine is used for miscellaneous IP-like checksums, mainly
16587 +static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
16589 + return csum_fold (csum_partial(buff, len, 0));
16592 +#define _HAVE_ARCH_IPV6_CSUM
16593 +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
16594 + struct in6_addr *daddr,
16596 + unsigned short proto,
16597 + unsigned int sum)
16600 + "addl 0(%1), %0 ;\n"
16601 + "adcl 4(%1), %0 ;\n"
16602 + "adcl 8(%1), %0 ;\n"
16603 + "adcl 12(%1), %0 ;\n"
16604 + "adcl 0(%2), %0 ;\n"
16605 + "adcl 4(%2), %0 ;\n"
16606 + "adcl 8(%2), %0 ;\n"
16607 + "adcl 12(%2), %0 ;\n"
16608 + "adcl %3, %0 ;\n"
16609 + "adcl %4, %0 ;\n"
16610 + "adcl $0, %0 ;\n"
16612 + : "r" (saddr), "r" (daddr),
16613 + "r"(htonl(len)), "r"(htonl(proto)), "0"(sum));
16615 + return csum_fold(sum);
16619 + * Copy and checksum to user
16621 +#define HAVE_CSUM_COPY_USER
16622 +static __inline__ unsigned int csum_and_copy_to_user(const char *src,
16623 + char *dst, int len,
16624 + int sum, int *err_ptr)
16626 + if (access_ok(VERIFY_WRITE, dst, len))
16627 + return(csum_partial_copy_to(src, dst, len, sum, err_ptr));
16630 + *err_ptr = -EFAULT;
16632 + return -1; /* invalid checksum */
16638 + * Overrides for Emacs so that we follow Linus's tabbing style.
16639 + * Emacs will notice this stuff at the end of the file and automatically
16640 + * adjust the settings for this buffer only. This must remain at the end
16642 + * ---------------------------------------------------------------------------
16643 + * Local variables:
16644 + * c-file-style: "linux"
16647 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame.h um/arch/um/include/sysdep-i386/frame.h
16648 --- orig/arch/um/include/sysdep-i386/frame.h 1969-12-31 19:00:00.000000000 -0500
16649 +++ um/arch/um/include/sysdep-i386/frame.h 2003-10-21 03:26:06.000000000 -0400
16652 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16653 + * Licensed under the GPL
16656 +#ifndef __FRAME_I386_H
16657 +#define __FRAME_I386_H
16659 +struct arch_frame_data_raw {
16660 + unsigned long fp_start;
16661 + unsigned long sr;
16664 +struct arch_frame_data {
16665 + int fpstate_size;
16671 + * Overrides for Emacs so that we follow Linus's tabbing style.
16672 + * Emacs will notice this stuff at the end of the file and automatically
16673 + * adjust the settings for this buffer only. This must remain at the end
16675 + * ---------------------------------------------------------------------------
16676 + * Local variables:
16677 + * c-file-style: "linux"
16680 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_kern.h um/arch/um/include/sysdep-i386/frame_kern.h
16681 --- orig/arch/um/include/sysdep-i386/frame_kern.h 1969-12-31 19:00:00.000000000 -0500
16682 +++ um/arch/um/include/sysdep-i386/frame_kern.h 2003-10-21 03:26:06.000000000 -0400
16685 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16686 + * Licensed under the GPL
16689 +#ifndef __FRAME_KERN_I386_H
16690 +#define __FRAME_KERN_I386_H
16692 +/* This is called from sys_sigreturn. It takes the sp at the point of the
16693 + * sigreturn system call and returns the address of the sigcontext struct
16697 +static inline void *sp_to_sc(unsigned long sp)
16699 + return((void *) sp);
16702 +static inline void *sp_to_uc(unsigned long sp)
16704 + unsigned long uc;
16706 + uc = sp + signal_frame_si.uc_index -
16707 + signal_frame_si.common.sp_index - 4;
16708 + return((void *) uc);
16711 +static inline void *sp_to_rt_sc(unsigned long sp)
16713 + unsigned long sc;
16715 + sc = sp - signal_frame_si.common.sp_index +
16716 + signal_frame_si.common.len - 4;
16717 + return((void *) sc);
16720 +static inline void *sp_to_mask(unsigned long sp)
16722 + unsigned long mask;
16724 + mask = sp - signal_frame_sc.common.sp_index +
16725 + signal_frame_sc.common.len - 8;
16726 + return((void *) mask);
16729 +extern int sc_size(void *data);
16731 +static inline void *sp_to_rt_mask(unsigned long sp)
16733 + unsigned long mask;
16735 + mask = sp - signal_frame_si.common.sp_index +
16736 + signal_frame_si.common.len +
16737 + sc_size(&signal_frame_si.common.arch) - 4;
16738 + return((void *) mask);
16744 + * Overrides for Emacs so that we follow Linus's tabbing style.
16745 + * Emacs will notice this stuff at the end of the file and automatically
16746 + * adjust the settings for this buffer only. This must remain at the end
16748 + * ---------------------------------------------------------------------------
16749 + * Local variables:
16750 + * c-file-style: "linux"
16753 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_user.h um/arch/um/include/sysdep-i386/frame_user.h
16754 --- orig/arch/um/include/sysdep-i386/frame_user.h 1969-12-31 19:00:00.000000000 -0500
16755 +++ um/arch/um/include/sysdep-i386/frame_user.h 2003-10-21 03:26:06.000000000 -0400
16758 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16759 + * Licensed under the GPL
16762 +#ifndef __FRAME_USER_I386_H
16763 +#define __FRAME_USER_I386_H
16765 +#include <asm/page.h>
16766 +#include "sysdep/frame.h"
16768 +/* This stuff is to calculate the size of the fp state struct at runtime
16769 + * because it has changed between 2.2 and 2.4 and it would be good for a
16770 + * UML compiled on one to work on the other.
16771 + * So, setup_arch_frame_raw fills in the arch struct with the raw data, which
16772 + * just contains the address of the end of the sigcontext. This is invoked
16773 + * from the signal handler.
16774 + * setup_arch_frame uses that data to figure out what
16775 + * arch_frame_data.fpstate_size should be. It really has no idea, since it's
16776 + * not allowed to do sizeof(struct fpstate) but it's safe to consider that it's
16777 + * everything from the end of the sigcontext up to the top of the stack. So,
16778 + * it masks off the page number to get the offset within the page and subtracts
16779 + * that from the page size, and that's how big the fpstate struct will be
16780 + * considered to be.
16783 +static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data,
16784 + void *end, unsigned long srp)
16786 + unsigned long sr = *((unsigned long *) srp);
16788 + data->fp_start = (unsigned long) end;
16789 + if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK))
16791 + else data->sr = 0;
16794 +static inline void setup_arch_frame(struct arch_frame_data_raw *in,
16795 + struct arch_frame_data *out)
16797 + unsigned long fpstate_start = in->fp_start;
16800 + fpstate_start &= ~PAGE_MASK;
16801 + out->fpstate_size = PAGE_SIZE - fpstate_start;
16804 + out->fpstate_size = in->sr - fpstate_start;
16808 +/* This figures out where on the stack the SA_RESTORER function address
16809 + * is stored. For i386, it's the signal handler return address, so it's
16810 + * located next to the frame pointer.
16811 + * This is inlined, so __builtin_frame_address(0) is correct. Otherwise,
16812 + * it would have to be __builtin_frame_address(1).
16815 +static inline unsigned long frame_restorer(void)
16817 + unsigned long *fp;
16819 + fp = __builtin_frame_address(0);
16820 + return((unsigned long) (fp + 1));
16823 +/* Similarly, this returns the value of sp when the handler was first
16824 + * entered. This is used to calculate the proper sp when delivering
16828 +static inline unsigned long frame_sp(void)
16830 + unsigned long *fp;
16832 + fp = __builtin_frame_address(0);
16833 + return((unsigned long) (fp + 1));
16839 + * Overrides for Emacs so that we follow Linus's tabbing style.
16840 + * Emacs will notice this stuff at the end of the file and automatically
16841 + * adjust the settings for this buffer only. This must remain at the end
16843 + * ---------------------------------------------------------------------------
16844 + * Local variables:
16845 + * c-file-style: "linux"
16848 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace.h um/arch/um/include/sysdep-i386/ptrace.h
16849 --- orig/arch/um/include/sysdep-i386/ptrace.h 1969-12-31 19:00:00.000000000 -0500
16850 +++ um/arch/um/include/sysdep-i386/ptrace.h 2003-10-21 03:26:06.000000000 -0400
16853 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16854 + * Licensed under the GPL
16857 +#ifndef __SYSDEP_I386_PTRACE_H
16858 +#define __SYSDEP_I386_PTRACE_H
16860 +#include "uml-config.h"
16862 +#ifdef UML_CONFIG_MODE_TT
16863 +#include "ptrace-tt.h"
16866 +#ifdef UML_CONFIG_MODE_SKAS
16867 +#include "ptrace-skas.h"
16870 +#include "choose-mode.h"
16872 +union uml_pt_regs {
16873 +#ifdef UML_CONFIG_MODE_TT
16879 +#ifdef UML_CONFIG_MODE_SKAS
16880 + struct skas_regs {
16881 + unsigned long regs[HOST_FRAME_SIZE];
16882 + unsigned long fp[HOST_FP_SIZE];
16883 + unsigned long xfp[HOST_XFP_SIZE];
16884 + unsigned long fault_addr;
16885 + unsigned long fault_type;
16886 + unsigned long trap_type;
16893 +#define EMPTY_UML_PT_REGS { }
16895 +extern int mode_tt;
16897 +#define UPT_SC(r) ((r)->tt.sc)
16898 +#define UPT_IP(r) \
16899 + CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
16900 +#define UPT_SP(r) \
16901 + CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
16902 +#define UPT_EFLAGS(r) \
16903 + CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
16904 +#define UPT_EAX(r) \
16905 + CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs))
16906 +#define UPT_EBX(r) \
16907 + CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs))
16908 +#define UPT_ECX(r) \
16909 + CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs))
16910 +#define UPT_EDX(r) \
16911 + CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs))
16912 +#define UPT_ESI(r) \
16913 + CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs))
16914 +#define UPT_EDI(r) \
16915 + CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs))
16916 +#define UPT_EBP(r) \
16917 + CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs))
16918 +#define UPT_ORIG_EAX(r) \
16919 + CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
16920 +#define UPT_CS(r) \
16921 + CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
16922 +#define UPT_SS(r) \
16923 + CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs))
16924 +#define UPT_DS(r) \
16925 + CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
16926 +#define UPT_ES(r) \
16927 + CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
16928 +#define UPT_FS(r) \
16929 + CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
16930 +#define UPT_GS(r) \
16931 + CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
16933 +#define UPT_SYSCALL_ARG1(r) UPT_EBX(r)
16934 +#define UPT_SYSCALL_ARG2(r) UPT_ECX(r)
16935 +#define UPT_SYSCALL_ARG3(r) UPT_EDX(r)
16936 +#define UPT_SYSCALL_ARG4(r) UPT_ESI(r)
16937 +#define UPT_SYSCALL_ARG5(r) UPT_EDI(r)
16938 +#define UPT_SYSCALL_ARG6(r) UPT_EBP(r)
16940 +extern int user_context(unsigned long sp);
16942 +#define UPT_IS_USER(r) \
16943 + CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
16945 +struct syscall_args {
16946 + unsigned long args[6];
16949 +#define SYSCALL_ARGS(r) ((struct syscall_args) \
16950 + { .args = { UPT_SYSCALL_ARG1(r), \
16951 + UPT_SYSCALL_ARG2(r), \
16952 + UPT_SYSCALL_ARG3(r), \
16953 + UPT_SYSCALL_ARG4(r), \
16954 + UPT_SYSCALL_ARG5(r), \
16955 + UPT_SYSCALL_ARG6(r) } } )
16957 +#define UPT_REG(regs, reg) \
16958 + ({ unsigned long val; \
16960 + case EIP: val = UPT_IP(regs); break; \
16961 + case UESP: val = UPT_SP(regs); break; \
16962 + case EAX: val = UPT_EAX(regs); break; \
16963 + case EBX: val = UPT_EBX(regs); break; \
16964 + case ECX: val = UPT_ECX(regs); break; \
16965 + case EDX: val = UPT_EDX(regs); break; \
16966 + case ESI: val = UPT_ESI(regs); break; \
16967 + case EDI: val = UPT_EDI(regs); break; \
16968 + case EBP: val = UPT_EBP(regs); break; \
16969 + case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \
16970 + case CS: val = UPT_CS(regs); break; \
16971 + case SS: val = UPT_SS(regs); break; \
16972 + case DS: val = UPT_DS(regs); break; \
16973 + case ES: val = UPT_ES(regs); break; \
16974 + case FS: val = UPT_FS(regs); break; \
16975 + case GS: val = UPT_GS(regs); break; \
16976 + case EFL: val = UPT_EFLAGS(regs); break; \
16978 + panic("Bad register in UPT_REG : %d\n", reg); \
16985 +#define UPT_SET(regs, reg, val) \
16988 + case EIP: UPT_IP(regs) = val; break; \
16989 + case UESP: UPT_SP(regs) = val; break; \
16990 + case EAX: UPT_EAX(regs) = val; break; \
16991 + case EBX: UPT_EBX(regs) = val; break; \
16992 + case ECX: UPT_ECX(regs) = val; break; \
16993 + case EDX: UPT_EDX(regs) = val; break; \
16994 + case ESI: UPT_ESI(regs) = val; break; \
16995 + case EDI: UPT_EDI(regs) = val; break; \
16996 + case EBP: UPT_EBP(regs) = val; break; \
16997 + case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \
16998 + case CS: UPT_CS(regs) = val; break; \
16999 + case SS: UPT_SS(regs) = val; break; \
17000 + case DS: UPT_DS(regs) = val; break; \
17001 + case ES: UPT_ES(regs) = val; break; \
17002 + case FS: UPT_FS(regs) = val; break; \
17003 + case GS: UPT_GS(regs) = val; break; \
17004 + case EFL: UPT_EFLAGS(regs) = val; break; \
17006 + panic("Bad register in UPT_SET : %d\n", reg); \
17011 +#define UPT_SET_SYSCALL_RETURN(r, res) \
17012 + CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \
17013 + REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
17015 +#define UPT_RESTART_SYSCALL(r) \
17016 + CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
17017 + REGS_RESTART_SYSCALL((r)->skas.regs))
17019 +#define UPT_ORIG_SYSCALL(r) UPT_EAX(r)
17020 +#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
17021 +#define UPT_SYSCALL_RET(r) UPT_EAX(r)
17023 +#define UPT_SEGV_IS_FIXABLE(r) \
17024 + CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
17025 + REGS_SEGV_IS_FIXABLE(&r->skas))
17027 +#define UPT_FAULT_ADDR(r) \
17028 + CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
17030 +#define UPT_FAULT_WRITE(r) \
17031 + CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
17036 + * Overrides for Emacs so that we follow Linus's tabbing style.
17037 + * Emacs will notice this stuff at the end of the file and automatically
17038 + * adjust the settings for this buffer only. This must remain at the end
17040 + * ---------------------------------------------------------------------------
17041 + * Local variables:
17042 + * c-file-style: "linux"
17045 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace_user.h um/arch/um/include/sysdep-i386/ptrace_user.h
17046 --- orig/arch/um/include/sysdep-i386/ptrace_user.h 1969-12-31 19:00:00.000000000 -0500
17047 +++ um/arch/um/include/sysdep-i386/ptrace_user.h 2003-10-21 03:26:06.000000000 -0400
17050 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17051 + * Licensed under the GPL
17054 +#ifndef __SYSDEP_I386_PTRACE_USER_H__
17055 +#define __SYSDEP_I386_PTRACE_USER_H__
17057 +#include <asm/ptrace.h>
17059 +#define PT_OFFSET(r) ((r) * sizeof(long))
17061 +#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX])
17062 +#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX)
17064 +#define PT_SYSCALL_ARG1_OFFSET PT_OFFSET(EBX)
17065 +#define PT_SYSCALL_ARG2_OFFSET PT_OFFSET(ECX)
17066 +#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX)
17067 +#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI)
17068 +#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI)
17070 +#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX)
17072 +#define PT_IP_OFFSET PT_OFFSET(EIP)
17073 +#define PT_IP(regs) ((regs)[EIP])
17074 +#define PT_SP(regs) ((regs)[UESP])
17076 +#ifndef FRAME_SIZE
17077 +#define FRAME_SIZE (17)
17079 +#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long))
17081 +#define FP_FRAME_SIZE (27)
17082 +#define FPX_FRAME_SIZE (128)
17084 +#ifdef PTRACE_GETREGS
17085 +#define UM_HAVE_GETREGS
17088 +#ifdef PTRACE_SETREGS
17089 +#define UM_HAVE_SETREGS
17092 +#ifdef PTRACE_GETFPREGS
17093 +#define UM_HAVE_GETFPREGS
17096 +#ifdef PTRACE_SETFPREGS
17097 +#define UM_HAVE_SETFPREGS
17100 +#ifdef PTRACE_GETFPXREGS
17101 +#define UM_HAVE_GETFPXREGS
17104 +#ifdef PTRACE_SETFPXREGS
17105 +#define UM_HAVE_SETFPXREGS
17108 +extern void update_debugregs(int seq);
17111 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/sigcontext.h um/arch/um/include/sysdep-i386/sigcontext.h
17112 --- orig/arch/um/include/sysdep-i386/sigcontext.h 1969-12-31 19:00:00.000000000 -0500
17113 +++ um/arch/um/include/sysdep-i386/sigcontext.h 2003-10-21 03:26:06.000000000 -0400
17116 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
17117 + * Licensed under the GPL
17120 +#ifndef __SYS_SIGCONTEXT_I386_H
17121 +#define __SYS_SIGCONTEXT_I386_H
17125 +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
17127 +#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
17128 +#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
17130 +#define SC_FAULT_ADDR(sc) SC_CR2(sc)
17131 +#define SC_FAULT_TYPE(sc) SC_ERR(sc)
17133 +#define FAULT_WRITE(err) (err & 2)
17134 +#define TO_SC_ERR(is_write) ((is_write) ? 2 : 0)
17136 +#define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc)))
17138 +#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
17140 +/* ptrace expects that, at the start of a system call, %eax contains
17141 + * -ENOSYS, so this makes it so.
17143 +#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
17145 +/* This is Page Fault */
17146 +#define SEGV_IS_FIXABLE(trap) (trap == 14)
17148 +#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
17150 +extern unsigned long *sc_sigmask(void *sc_ptr);
17151 +extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
17155 + * Overrides for Emacs so that we follow Linus's tabbing style.
17156 + * Emacs will notice this stuff at the end of the file and automatically
17157 + * adjust the settings for this buffer only. This must remain at the end
17159 + * ---------------------------------------------------------------------------
17160 + * Local variables:
17161 + * c-file-style: "linux"
17164 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/syscalls.h um/arch/um/include/sysdep-i386/syscalls.h
17165 --- orig/arch/um/include/sysdep-i386/syscalls.h 1969-12-31 19:00:00.000000000 -0500
17166 +++ um/arch/um/include/sysdep-i386/syscalls.h 2003-10-21 03:26:06.000000000 -0400
17169 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17170 + * Licensed under the GPL
17173 +#include "asm/unistd.h"
17174 +#include "sysdep/ptrace.h"
17176 +typedef long syscall_handler_t(struct pt_regs);
17178 +#define EXECUTE_SYSCALL(syscall, regs) \
17179 + ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs))
17181 +extern syscall_handler_t sys_modify_ldt;
17182 +extern syscall_handler_t old_mmap_i386;
17183 +extern syscall_handler_t old_select;
17184 +extern syscall_handler_t sys_ni_syscall;
17186 +#define ARCH_SYSCALLS \
17187 + [ __NR_mmap ] = old_mmap_i386, \
17188 + [ __NR_select ] = old_select, \
17189 + [ __NR_vm86old ] = sys_ni_syscall, \
17190 + [ __NR_modify_ldt ] = sys_modify_ldt, \
17191 + [ __NR_lchown32 ] = sys_lchown, \
17192 + [ __NR_getuid32 ] = sys_getuid, \
17193 + [ __NR_getgid32 ] = sys_getgid, \
17194 + [ __NR_geteuid32 ] = sys_geteuid, \
17195 + [ __NR_getegid32 ] = sys_getegid, \
17196 + [ __NR_setreuid32 ] = sys_setreuid, \
17197 + [ __NR_setregid32 ] = sys_setregid, \
17198 + [ __NR_getgroups32 ] = sys_getgroups, \
17199 + [ __NR_setgroups32 ] = sys_setgroups, \
17200 + [ __NR_fchown32 ] = sys_fchown, \
17201 + [ __NR_setresuid32 ] = sys_setresuid, \
17202 + [ __NR_getresuid32 ] = sys_getresuid, \
17203 + [ __NR_setresgid32 ] = sys_setresgid, \
17204 + [ __NR_getresgid32 ] = sys_getresgid, \
17205 + [ __NR_chown32 ] = sys_chown, \
17206 + [ __NR_setuid32 ] = sys_setuid, \
17207 + [ __NR_setgid32 ] = sys_setgid, \
17208 + [ __NR_setfsuid32 ] = sys_setfsuid, \
17209 + [ __NR_setfsgid32 ] = sys_setfsgid, \
17210 + [ __NR_pivot_root ] = sys_pivot_root, \
17211 + [ __NR_mincore ] = sys_mincore, \
17212 + [ __NR_madvise ] = sys_madvise, \
17213 + [ 222 ] = sys_ni_syscall,
17215 +/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
17217 +#define LAST_ARCH_SYSCALL 222
17220 + * Overrides for Emacs so that we follow Linus's tabbing style.
17221 + * Emacs will notice this stuff at the end of the file and automatically
17222 + * adjust the settings for this buffer only. This must remain at the end
17224 + * ---------------------------------------------------------------------------
17225 + * Local variables:
17226 + * c-file-style: "linux"
17229 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/ptrace.h um/arch/um/include/sysdep-ia64/ptrace.h
17230 --- orig/arch/um/include/sysdep-ia64/ptrace.h 1969-12-31 19:00:00.000000000 -0500
17231 +++ um/arch/um/include/sysdep-ia64/ptrace.h 2003-10-21 03:26:06.000000000 -0400
17234 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17235 + * Licensed under the GPL
17238 +#ifndef __SYSDEP_IA64_PTRACE_H
17239 +#define __SYSDEP_IA64_PTRACE_H
17241 +struct sys_pt_regs {
17245 +#define EMPTY_REGS { 0 }
17250 + * Overrides for Emacs so that we follow Linus's tabbing style.
17251 + * Emacs will notice this stuff at the end of the file and automatically
17252 + * adjust the settings for this buffer only. This must remain at the end
17254 + * ---------------------------------------------------------------------------
17255 + * Local variables:
17256 + * c-file-style: "linux"
17259 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/sigcontext.h um/arch/um/include/sysdep-ia64/sigcontext.h
17260 --- orig/arch/um/include/sysdep-ia64/sigcontext.h 1969-12-31 19:00:00.000000000 -0500
17261 +++ um/arch/um/include/sysdep-ia64/sigcontext.h 2003-10-21 03:26:06.000000000 -0400
17264 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17265 + * Licensed under the GPL
17268 +#ifndef __SYSDEP_IA64_SIGCONTEXT_H
17269 +#define __SYSDEP_IA64_SIGCONTEXT_H
17274 + * Overrides for Emacs so that we follow Linus's tabbing style.
17275 + * Emacs will notice this stuff at the end of the file and automatically
17276 + * adjust the settings for this buffer only. This must remain at the end
17278 + * ---------------------------------------------------------------------------
17279 + * Local variables:
17280 + * c-file-style: "linux"
17283 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/syscalls.h um/arch/um/include/sysdep-ia64/syscalls.h
17284 --- orig/arch/um/include/sysdep-ia64/syscalls.h 1969-12-31 19:00:00.000000000 -0500
17285 +++ um/arch/um/include/sysdep-ia64/syscalls.h 2003-10-21 03:26:06.000000000 -0400
17288 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17289 + * Licensed under the GPL
17292 +#ifndef __SYSDEP_IA64_SYSCALLS_H
17293 +#define __SYSDEP_IA64_SYSCALLS_H
17298 + * Overrides for Emacs so that we follow Linus's tabbing style.
17299 + * Emacs will notice this stuff at the end of the file and automatically
17300 + * adjust the settings for this buffer only. This must remain at the end
17302 + * ---------------------------------------------------------------------------
17303 + * Local variables:
17304 + * c-file-style: "linux"
17307 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/ptrace.h um/arch/um/include/sysdep-ppc/ptrace.h
17308 --- orig/arch/um/include/sysdep-ppc/ptrace.h 1969-12-31 19:00:00.000000000 -0500
17309 +++ um/arch/um/include/sysdep-ppc/ptrace.h 2003-10-21 03:26:06.000000000 -0400
17312 + * Licensed under the GPL
17315 +#ifndef __SYS_PTRACE_PPC_H
17316 +#define __SYS_PTRACE_PPC_H
17318 +#include "linux/config.h"
17319 +#include "linux/types.h"
17321 +/* the following taken from <asm-ppc/ptrace.h> */
17323 +#ifdef CONFIG_PPC64
17324 +#define PPC_REG unsigned long /*long*/
17326 +#define PPC_REG unsigned long
17328 +struct sys_pt_regs_s {
17332 + PPC_REG orig_gpr3; /* Used for restarting system calls */
17337 + PPC_REG mq; /* 601 only (not used at present) */
17338 + /* Used on APUS to hold IPL value. */
17339 + PPC_REG trap; /* Reason for being here */
17340 + PPC_REG dar; /* Fault registers */
17342 + PPC_REG result; /* Result of a system call */
17345 +#define NUM_REGS (sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG))
17347 +struct sys_pt_regs {
17348 + PPC_REG regs[sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG)];
17351 +#define UM_MAX_REG (PT_FPR0)
17352 +#define UM_MAX_REG_OFFSET (UM_MAX_REG * sizeof(PPC_REG))
17354 +#define EMPTY_REGS { { [ 0 ... NUM_REGS - 1] = 0 } }
17356 +#define UM_REG(r, n) ((r)->regs[n])
17358 +#define UM_SYSCALL_RET(r) UM_REG(r, PT_R3)
17359 +#define UM_SP(r) UM_REG(r, PT_R1)
17360 +#define UM_IP(r) UM_REG(r, PT_NIP)
17361 +#define UM_ELF_ZERO(r) UM_REG(r, PT_FPSCR)
17362 +#define UM_SYSCALL_NR(r) UM_REG(r, PT_R0)
17363 +#define UM_SYSCALL_ARG1(r) UM_REG(r, PT_ORIG_R3)
17364 +#define UM_SYSCALL_ARG2(r) UM_REG(r, PT_R4)
17365 +#define UM_SYSCALL_ARG3(r) UM_REG(r, PT_R5)
17366 +#define UM_SYSCALL_ARG4(r) UM_REG(r, PT_R6)
17367 +#define UM_SYSCALL_ARG5(r) UM_REG(r, PT_R7)
17368 +#define UM_SYSCALL_ARG6(r) UM_REG(r, PT_R8)
17370 +#define UM_SYSCALL_NR_OFFSET (PT_R0 * sizeof(PPC_REG))
17371 +#define UM_SYSCALL_RET_OFFSET (PT_R3 * sizeof(PPC_REG))
17372 +#define UM_SYSCALL_ARG1_OFFSET (PT_R3 * sizeof(PPC_REG))
17373 +#define UM_SYSCALL_ARG2_OFFSET (PT_R4 * sizeof(PPC_REG))
17374 +#define UM_SYSCALL_ARG3_OFFSET (PT_R5 * sizeof(PPC_REG))
17375 +#define UM_SYSCALL_ARG4_OFFSET (PT_R6 * sizeof(PPC_REG))
17376 +#define UM_SYSCALL_ARG5_OFFSET (PT_R7 * sizeof(PPC_REG))
17377 +#define UM_SYSCALL_ARG6_OFFSET (PT_R8 * sizeof(PPC_REG))
17378 +#define UM_SP_OFFSET (PT_R1 * sizeof(PPC_REG))
17379 +#define UM_IP_OFFSET (PT_NIP * sizeof(PPC_REG))
17380 +#define UM_ELF_ZERO_OFFSET (PT_R3 * sizeof(PPC_REG))
17382 +#define UM_SET_SYSCALL_RETURN(_regs, result) \
17384 + if (result < 0) { \
17385 + (_regs)->regs[PT_CCR] |= 0x10000000; \
17386 + UM_SYSCALL_RET((_regs)) = -result; \
17388 + UM_SYSCALL_RET((_regs)) = result; \
17392 +extern void shove_aux_table(unsigned long sp);
17393 +#define UM_FIX_EXEC_STACK(sp) shove_aux_table(sp);
17395 +/* These aren't actually defined. The undefs are just to make sure
17396 + * everyone's clear on the concept.
17398 +#undef UML_HAVE_GETREGS
17399 +#undef UML_HAVE_GETFPREGS
17400 +#undef UML_HAVE_SETREGS
17401 +#undef UML_HAVE_SETFPREGS
17406 + * Overrides for Emacs so that we follow Linus's tabbing style.
17407 + * Emacs will notice this stuff at the end of the file and automatically
17408 + * adjust the settings for this buffer only. This must remain at the end
17410 + * ---------------------------------------------------------------------------
17411 + * Local variables:
17412 + * c-file-style: "linux"
17415 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/sigcontext.h um/arch/um/include/sysdep-ppc/sigcontext.h
17416 --- orig/arch/um/include/sysdep-ppc/sigcontext.h 1969-12-31 19:00:00.000000000 -0500
17417 +++ um/arch/um/include/sysdep-ppc/sigcontext.h 2003-10-21 03:26:06.000000000 -0400
17420 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17421 + * Licensed under the GPL
17424 +#ifndef __SYS_SIGCONTEXT_PPC_H
17425 +#define __SYS_SIGCONTEXT_PPC_H
17427 +#define DSISR_WRITE 0x02000000
17429 +#define SC_FAULT_ADDR(sc) ({ \
17430 + struct sigcontext *_sc = (sc); \
17431 + long retval = -1; \
17432 + switch (_sc->regs->trap) { \
17434 + /* data exception */ \
17435 + retval = _sc->regs->dar; \
17438 + /* instruction exception */ \
17439 + retval = _sc->regs->nip; \
17442 + panic("SC_FAULT_ADDR: unhandled trap type\n"); \
17447 +#define SC_FAULT_WRITE(sc) ({ \
17448 + struct sigcontext *_sc = (sc); \
17449 + long retval = -1; \
17450 + switch (_sc->regs->trap) { \
17452 + /* data exception */ \
17453 + retval = !!(_sc->regs->dsisr & DSISR_WRITE); \
17456 + /* instruction exception: not a write */ \
17460 + panic("SC_FAULT_ADDR: unhandled trap type\n"); \
17465 +#define SC_IP(sc) ((sc)->regs->nip)
17466 +#define SC_SP(sc) ((sc)->regs->gpr[1])
17467 +#define SEGV_IS_FIXABLE(sc) (1)
17472 + * Overrides for Emacs so that we follow Linus's tabbing style.
17473 + * Emacs will notice this stuff at the end of the file and automatically
17474 + * adjust the settings for this buffer only. This must remain at the end
17476 + * ---------------------------------------------------------------------------
17477 + * Local variables:
17478 + * c-file-style: "linux"
17481 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/syscalls.h um/arch/um/include/sysdep-ppc/syscalls.h
17482 --- orig/arch/um/include/sysdep-ppc/syscalls.h 1969-12-31 19:00:00.000000000 -0500
17483 +++ um/arch/um/include/sysdep-ppc/syscalls.h 2003-10-21 03:26:06.000000000 -0400
17486 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17487 + * Licensed under the GPL
17490 +typedef long syscall_handler_t(unsigned long arg1, unsigned long arg2,
17491 + unsigned long arg3, unsigned long arg4,
17492 + unsigned long arg5, unsigned long arg6);
17494 +#define EXECUTE_SYSCALL(syscall, regs) \
17495 + (*sys_call_table[syscall])(UM_SYSCALL_ARG1(®s), \
17496 + UM_SYSCALL_ARG2(®s), \
17497 + UM_SYSCALL_ARG3(®s), \
17498 + UM_SYSCALL_ARG4(®s), \
17499 + UM_SYSCALL_ARG5(®s), \
17500 + UM_SYSCALL_ARG6(®s))
17502 +extern syscall_handler_t sys_mincore;
17503 +extern syscall_handler_t sys_madvise;
17505 +/* old_mmap needs the correct prototype since syscall_kern.c includes
17508 +int old_mmap(unsigned long addr, unsigned long len,
17509 + unsigned long prot, unsigned long flags,
17510 + unsigned long fd, unsigned long offset);
17512 +#define ARCH_SYSCALLS \
17513 + [ __NR_modify_ldt ] = sys_ni_syscall, \
17514 + [ __NR_pciconfig_read ] = sys_ni_syscall, \
17515 + [ __NR_pciconfig_write ] = sys_ni_syscall, \
17516 + [ __NR_pciconfig_iobase ] = sys_ni_syscall, \
17517 + [ __NR_pivot_root ] = sys_ni_syscall, \
17518 + [ __NR_multiplexer ] = sys_ni_syscall, \
17519 + [ __NR_mmap ] = old_mmap, \
17520 + [ __NR_madvise ] = sys_madvise, \
17521 + [ __NR_mincore ] = sys_mincore,
17523 +#define LAST_ARCH_SYSCALL __NR_mincore
17526 + * Overrides for Emacs so that we follow Linus's tabbing style.
17527 + * Emacs will notice this stuff at the end of the file and automatically
17528 + * adjust the settings for this buffer only. This must remain at the end
17530 + * ---------------------------------------------------------------------------
17531 + * Local variables:
17532 + * c-file-style: "linux"
17535 diff -Naur -X ../exclude-files orig/arch/um/include/sysrq.h um/arch/um/include/sysrq.h
17536 --- orig/arch/um/include/sysrq.h 1969-12-31 19:00:00.000000000 -0500
17537 +++ um/arch/um/include/sysrq.h 2003-10-21 03:26:06.000000000 -0400
17539 +#ifndef __UM_SYSRQ_H
17540 +#define __UM_SYSRQ_H
17542 +extern void show_trace(unsigned long *stack);
17545 diff -Naur -X ../exclude-files orig/arch/um/include/tempfile.h um/arch/um/include/tempfile.h
17546 --- orig/arch/um/include/tempfile.h 1969-12-31 19:00:00.000000000 -0500
17547 +++ um/arch/um/include/tempfile.h 2003-10-21 03:26:06.000000000 -0400
17550 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
17551 + * Licensed under the GPL
17554 +#ifndef __TEMPFILE_H__
17555 +#define __TEMPFILE_H__
17557 +extern int make_tempfile(const char *template, char **tempname, int do_unlink);
17561 + * Overrides for Emacs so that we follow Linus's tabbing style.
17562 + * Emacs will notice this stuff at the end of the file and automatically
17563 + * adjust the settings for this buffer only. This must remain at the end
17565 + * ---------------------------------------------------------------------------
17566 + * Local variables:
17567 + * c-file-style: "linux"
17570 diff -Naur -X ../exclude-files orig/arch/um/include/time_user.h um/arch/um/include/time_user.h
17571 --- orig/arch/um/include/time_user.h 1969-12-31 19:00:00.000000000 -0500
17572 +++ um/arch/um/include/time_user.h 2003-10-21 03:26:06.000000000 -0400
17575 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17576 + * Licensed under the GPL
17579 +#ifndef __TIME_USER_H__
17580 +#define __TIME_USER_H__
17582 +extern void timer(void);
17583 +extern void switch_timers(int to_real);
17584 +extern void set_interval(int timer_type);
17585 +extern void idle_sleep(int secs);
17586 +extern void enable_timer(void);
17587 +extern unsigned long time_lock(void);
17588 +extern void time_unlock(unsigned long);
17591 diff -Naur -X ../exclude-files orig/arch/um/include/tlb.h um/arch/um/include/tlb.h
17592 --- orig/arch/um/include/tlb.h 1969-12-31 19:00:00.000000000 -0500
17593 +++ um/arch/um/include/tlb.h 2003-10-21 03:26:06.000000000 -0400
17596 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17597 + * Licensed under the GPL
17603 +extern void mprotect_kernel_vm(int w);
17604 +extern void force_flush_all(void);
17609 + * Overrides for Emacs so that we follow Linus's tabbing style.
17610 + * Emacs will notice this stuff at the end of the file and automatically
17611 + * adjust the settings for this buffer only. This must remain at the end
17613 + * ---------------------------------------------------------------------------
17614 + * Local variables:
17615 + * c-file-style: "linux"
17618 diff -Naur -X ../exclude-files orig/arch/um/include/ubd_user.h um/arch/um/include/ubd_user.h
17619 --- orig/arch/um/include/ubd_user.h 1969-12-31 19:00:00.000000000 -0500
17620 +++ um/arch/um/include/ubd_user.h 2003-10-21 03:26:06.000000000 -0400
17623 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17624 + * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com)
17625 + * Licensed under the GPL
17628 +#ifndef __UM_UBD_USER_H
17629 +#define __UM_UBD_USER_H
17633 +enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
17635 +struct io_thread_req {
17638 + unsigned long offsets[2];
17639 + unsigned long long offset;
17640 + unsigned long length;
17643 + unsigned long sector_mask;
17644 + unsigned long long cow_offset;
17645 + unsigned long bitmap_words[2];
17647 + unsigned long long map_offset;
17651 +extern int open_ubd_file(char *file, struct openflags *openflags,
17652 + char **backing_file_out, int *bitmap_offset_out,
17653 + unsigned long *bitmap_len_out, int *data_offset_out,
17654 + int *create_cow_out);
17655 +extern int create_cow_file(char *cow_file, char *backing_file,
17656 + struct openflags flags, int sectorsize,
17657 + int alignment, int *bitmap_offset_out,
17658 + unsigned long *bitmap_len_out,
17659 + int *data_offset_out);
17660 +extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
17661 +extern int read_ubd_fs(int fd, void *buffer, int len);
17662 +extern int write_ubd_fs(int fd, char *buffer, int len);
17663 +extern int start_io_thread(unsigned long sp, int *fds_out);
17664 +extern void do_io(struct io_thread_req *req);
17666 +static inline int ubd_test_bit(__u64 bit, unsigned char *data)
17671 + bits = sizeof(data[0]) * 8;
17673 + off = bit % bits;
17674 + return((data[n] & (1 << off)) != 0);
17677 +static inline void ubd_set_bit(__u64 bit, unsigned char *data)
17682 + bits = sizeof(data[0]) * 8;
17684 + off = bit % bits;
17685 + data[n] |= (1 << off);
17692 + * Overrides for Emacs so that we follow Linus's tabbing style.
17693 + * Emacs will notice this stuff at the end of the file and automatically
17694 + * adjust the settings for this buffer only. This must remain at the end
17696 + * ---------------------------------------------------------------------------
17697 + * Local variables:
17698 + * c-file-style: "linux"
17701 diff -Naur -X ../exclude-files orig/arch/um/include/umid.h um/arch/um/include/umid.h
17702 --- orig/arch/um/include/umid.h 1969-12-31 19:00:00.000000000 -0500
17703 +++ um/arch/um/include/umid.h 2003-10-21 03:26:06.000000000 -0400
17706 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
17707 + * Licensed under the GPL
17710 +#ifndef __UMID_H__
17711 +#define __UMID_H__
17713 +extern int umid_file_name(char *name, char *buf, int len);
17718 + * Overrides for Emacs so that we follow Linus's tabbing style.
17719 + * Emacs will notice this stuff at the end of the file and automatically
17720 + * adjust the settings for this buffer only. This must remain at the end
17722 + * ---------------------------------------------------------------------------
17723 + * Local variables:
17724 + * c-file-style: "linux"
17727 diff -Naur -X ../exclude-files orig/arch/um/include/uml_uaccess.h um/arch/um/include/uml_uaccess.h
17728 --- orig/arch/um/include/uml_uaccess.h 1969-12-31 19:00:00.000000000 -0500
17729 +++ um/arch/um/include/uml_uaccess.h 2003-10-21 03:26:06.000000000 -0400
17732 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
17733 + * Licensed under the GPL
17736 +#ifndef __UML_UACCESS_H__
17737 +#define __UML_UACCESS_H__
17739 +extern int __do_copy_to_user(void *to, const void *from, int n,
17740 + void **fault_addr, void **fault_catcher);
17741 +extern unsigned long __do_user_copy(void *to, const void *from, int n,
17742 + void **fault_addr, void **fault_catcher,
17743 + void (*op)(void *to, const void *from,
17744 + int n), int *faulted_out);
17745 +void __do_copy(void *to, const void *from, int n);
17750 + * Overrides for Emacs so that we follow Linus's tabbing style.
17751 + * Emacs will notice this stuff at the end of the file and automatically
17752 + * adjust the settings for this buffer only. This must remain at the end
17754 + * ---------------------------------------------------------------------------
17755 + * Local variables:
17756 + * c-file-style: "linux"
17759 diff -Naur -X ../exclude-files orig/arch/um/include/um_mmu.h um/arch/um/include/um_mmu.h
17760 --- orig/arch/um/include/um_mmu.h 1969-12-31 19:00:00.000000000 -0500
17761 +++ um/arch/um/include/um_mmu.h 2003-10-21 03:26:06.000000000 -0400
17764 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17765 + * Licensed under the GPL
17768 +#ifndef __ARCH_UM_MMU_H
17769 +#define __ARCH_UM_MMU_H
17771 +#include "linux/config.h"
17772 +#include "choose-mode.h"
17774 +#ifdef CONFIG_MODE_TT
17775 +#include "../kernel/tt/include/mmu.h"
17778 +#ifdef CONFIG_MODE_SKAS
17779 +#include "../kernel/skas/include/mmu.h"
17783 +#ifdef CONFIG_MODE_TT
17784 + struct mmu_context_tt tt;
17786 +#ifdef CONFIG_MODE_SKAS
17787 + struct mmu_context_skas skas;
17794 + * Overrides for Emacs so that we follow Linus's tabbing style.
17795 + * Emacs will notice this stuff at the end of the file and automatically
17796 + * adjust the settings for this buffer only. This must remain at the end
17798 + * ---------------------------------------------------------------------------
17799 + * Local variables:
17800 + * c-file-style: "linux"
17803 diff -Naur -X ../exclude-files orig/arch/um/include/umn.h um/arch/um/include/umn.h
17804 --- orig/arch/um/include/umn.h 1969-12-31 19:00:00.000000000 -0500
17805 +++ um/arch/um/include/umn.h 2003-10-21 03:26:06.000000000 -0400
17808 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17809 + * Licensed under the GPL
17815 +extern int open_umn_tty(int *slave_out, int *slipno_out);
17816 +extern void close_umn_tty(int master, int slave);
17817 +extern int umn_send_packet(int fd, void *data, int len);
17818 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
17819 +extern void slip_unesc(unsigned char s);
17820 +extern void umn_read(int fd);
17825 + * Overrides for Emacs so that we follow Linus's tabbing style.
17826 + * Emacs will notice this stuff at the end of the file and automatically
17827 + * adjust the settings for this buffer only. This must remain at the end
17829 + * ---------------------------------------------------------------------------
17830 + * Local variables:
17831 + * c-file-style: "linux"
17834 diff -Naur -X ../exclude-files orig/arch/um/include/um_uaccess.h um/arch/um/include/um_uaccess.h
17835 --- orig/arch/um/include/um_uaccess.h 1969-12-31 19:00:00.000000000 -0500
17836 +++ um/arch/um/include/um_uaccess.h 2003-10-21 03:26:06.000000000 -0400
17839 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17840 + * Licensed under the GPL
17843 +#ifndef __ARCH_UM_UACCESS_H
17844 +#define __ARCH_UM_UACCESS_H
17846 +#include "linux/config.h"
17847 +#include "choose-mode.h"
17849 +#ifdef CONFIG_MODE_TT
17850 +#include "../kernel/tt/include/uaccess.h"
17853 +#ifdef CONFIG_MODE_SKAS
17854 +#include "../kernel/skas/include/uaccess.h"
17857 +#define access_ok(type, addr, size) \
17858 + CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
17860 +static inline int verify_area(int type, const void * addr, unsigned long size)
17862 + return(CHOOSE_MODE_PROC(verify_area_tt, verify_area_skas, type, addr,
17866 +static inline int copy_from_user(void *to, const void *from, int n)
17868 + return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to,
17872 +static inline int copy_to_user(void *to, const void *from, int n)
17874 + return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to,
17879 + * strncpy_from_user: - Copy a NUL terminated string from userspace.
17880 + * @dst: Destination address, in kernel space. This buffer must be at
17881 + * least @count bytes long.
17882 + * @src: Source address, in user space.
17883 + * @count: Maximum number of bytes to copy, including the trailing NUL.
17885 + * Copies a NUL-terminated string from userspace to kernel space.
17887 + * On success, returns the length of the string (not including the trailing
17890 + * If access to userspace fails, returns -EFAULT (some data may have been
17893 + * If @count is smaller than the length of the string, copies @count bytes
17894 + * and returns @count.
17897 +static inline int strncpy_from_user(char *dst, const char *src, int count)
17899 + return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
17900 + dst, src, count));
17904 + * __clear_user: - Zero a block of memory in user space, with less checking.
17905 + * @to: Destination address, in user space.
17906 + * @n: Number of bytes to zero.
17908 + * Zero a block of memory in user space. Caller must check
17909 + * the specified block with access_ok() before calling this function.
17911 + * Returns number of bytes that could not be cleared.
17912 + * On success, this will be zero.
17914 +static inline int __clear_user(void *mem, int len)
17916 + return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
17920 + * clear_user: - Zero a block of memory in user space.
17921 + * @to: Destination address, in user space.
17922 + * @n: Number of bytes to zero.
17924 + * Zero a block of memory in user space.
17926 + * Returns number of bytes that could not be cleared.
17927 + * On success, this will be zero.
17929 +static inline int clear_user(void *mem, int len)
17931 + return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
17935 + * strlen_user: - Get the size of a string in user space.
17936 + * @str: The string to measure.
17937 + * @n: The maximum valid length
17939 + * Get the size of a NUL-terminated string in user space.
17941 + * Returns the size of the string INCLUDING the terminating NUL.
17942 + * On exception, returns 0.
17943 + * If the string is too long, returns a value greater than @n.
17945 +static inline int strnlen_user(const void *str, int len)
17947 + return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
17953 + * Overrides for Emacs so that we follow Linus's tabbing style.
17954 + * Emacs will notice this stuff at the end of the file and automatically
17955 + * adjust the settings for this buffer only. This must remain at the end
17957 + * ---------------------------------------------------------------------------
17958 + * Local variables:
17959 + * c-file-style: "linux"
17962 diff -Naur -X ../exclude-files orig/arch/um/include/user.h um/arch/um/include/user.h
17963 --- orig/arch/um/include/user.h 1969-12-31 19:00:00.000000000 -0500
17964 +++ um/arch/um/include/user.h 2003-10-21 03:26:06.000000000 -0400
17967 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17968 + * Licensed under the GPL
17971 +#ifndef __USER_H__
17972 +#define __USER_H__
17974 +extern void panic(const char *fmt, ...);
17975 +extern int printk(const char *fmt, ...);
17976 +extern void schedule(void);
17977 +extern void *um_kmalloc(int size);
17978 +extern void *um_kmalloc_atomic(int size);
17979 +extern void kfree(void *ptr);
17980 +extern int in_aton(char *str);
17981 +extern int open_gdb_chan(void);
17986 + * Overrides for Emacs so that we follow Linus's tabbing style.
17987 + * Emacs will notice this stuff at the end of the file and automatically
17988 + * adjust the settings for this buffer only. This must remain at the end
17990 + * ---------------------------------------------------------------------------
17991 + * Local variables:
17992 + * c-file-style: "linux"
17995 diff -Naur -X ../exclude-files orig/arch/um/include/user_util.h um/arch/um/include/user_util.h
17996 --- orig/arch/um/include/user_util.h 1969-12-31 19:00:00.000000000 -0500
17997 +++ um/arch/um/include/user_util.h 2003-11-09 11:36:31.000000000 -0500
18000 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
18001 + * Licensed under the GPL
18004 +#ifndef __USER_UTIL_H__
18005 +#define __USER_UTIL_H__
18007 +#include "sysdep/ptrace.h"
18009 +extern int mode_tt;
18011 +extern int grantpt(int __fd);
18012 +extern int unlockpt(int __fd);
18013 +extern char *ptsname(int __fd);
18020 +extern struct cpu_task cpu_tasks[];
18022 +struct signal_info {
18023 + void (*handler)(int, union uml_pt_regs *);
18027 +extern struct signal_info sig_info[];
18029 +extern unsigned long low_physmem;
18030 +extern unsigned long high_physmem;
18031 +extern unsigned long uml_physmem;
18032 +extern unsigned long uml_reserved;
18033 +extern unsigned long end_vm;
18034 +extern unsigned long start_vm;
18035 +extern unsigned long highmem;
18037 +extern char host_info[];
18039 +extern char saved_command_line[];
18040 +extern char command_line[];
18042 +extern char *tempdir;
18044 +extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
18045 +extern unsigned long _unprotected_end;
18046 +extern unsigned long brk_start;
18048 +extern int pty_output_sigio;
18049 +extern int pty_close_sigio;
18051 +extern void stop(void);
18052 +extern void stack_protections(unsigned long address);
18053 +extern void task_protections(unsigned long address);
18054 +extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
18055 +extern void *add_signal_handler(int sig, void (*handler)(int));
18056 +extern int start_fork_tramp(void *arg, unsigned long temp_stack,
18057 + int clone_flags, int (*tramp)(void *));
18058 +extern int linux_main(int argc, char **argv);
18059 +extern void set_cmdline(char *cmd);
18060 +extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
18061 +extern int get_pty(void);
18062 +extern void *um_kmalloc(int size);
18063 +extern int raw(int fd, int complain);
18064 +extern int switcheroo(int fd, int prot, void *from, void *to, int size);
18065 +extern void setup_machinename(char *machine_out);
18066 +extern void setup_hostinfo(void);
18067 +extern void add_arg(char *cmd_line, char *arg);
18068 +extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
18069 +extern void init_new_thread_signals(int altstack);
18070 +extern void do_exec(int old_pid, int new_pid);
18071 +extern void tracer_panic(char *msg, ...);
18072 +extern char *get_umid(int only_if_set);
18073 +extern void do_longjmp(void *p, int val);
18074 +extern void suspend_new_thread(int fd);
18075 +extern int detach(int pid, int sig);
18076 +extern int attach(int pid);
18077 +extern void kill_child_dead(int pid);
18078 +extern int cont(int pid);
18079 +extern void check_ptrace(void);
18080 +extern void check_sigio(void);
18081 +extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
18082 +extern void write_sigio_workaround(void);
18083 +extern void arch_check_bugs(void);
18084 +extern int cpu_feature(char *what, char *buf, int len);
18085 +extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
18086 +extern int arch_fixup(unsigned long address, void *sc_ptr);
18087 +extern int can_do_skas(void);
18088 +extern void arch_init_thread(void);
18093 + * Overrides for Emacs so that we follow Linus's tabbing style.
18094 + * Emacs will notice this stuff at the end of the file and automatically
18095 + * adjust the settings for this buffer only. This must remain at the end
18097 + * ---------------------------------------------------------------------------
18098 + * Local variables:
18099 + * c-file-style: "linux"
18102 diff -Naur -X ../exclude-files orig/arch/um/kernel/checksum.c um/arch/um/kernel/checksum.c
18103 --- orig/arch/um/kernel/checksum.c 1969-12-31 19:00:00.000000000 -0500
18104 +++ um/arch/um/kernel/checksum.c 2003-10-21 03:26:06.000000000 -0400
18106 +#include "asm/uaccess.h"
18107 +#include "linux/errno.h"
18109 +extern unsigned int arch_csum_partial(const char *buff, int len, int sum);
18111 +extern unsigned int csum_partial(char *buff, int len, int sum)
18113 + return(arch_csum_partial(buff, len, sum));
18116 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len,
18117 + int sum, int *err_ptr)
18119 + if(copy_to_user(dst, src, len)){
18120 + *err_ptr = -EFAULT;
18124 + return(arch_csum_partial(src, len, sum));
18127 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len,
18128 + int sum, int *err_ptr)
18130 + if(copy_from_user(dst, src, len)){
18131 + *err_ptr = -EFAULT;
18135 + return(arch_csum_partial(dst, len, sum));
18139 + * Overrides for Emacs so that we follow Linus's tabbing style.
18140 + * Emacs will notice this stuff at the end of the file and automatically
18141 + * adjust the settings for this buffer only. This must remain at the end
18143 + * ---------------------------------------------------------------------------
18144 + * Local variables:
18145 + * c-file-style: "linux"
18148 diff -Naur -X ../exclude-files orig/arch/um/kernel/config.c.in um/arch/um/kernel/config.c.in
18149 --- orig/arch/um/kernel/config.c.in 1969-12-31 19:00:00.000000000 -0500
18150 +++ um/arch/um/kernel/config.c.in 2003-10-21 03:26:06.000000000 -0400
18153 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18154 + * Licensed under the GPL
18157 +#include <stdio.h>
18158 +#include <stdlib.h>
18161 +static __initdata char *config = "CONFIG";
18163 +static int __init print_config(char *line, int *add)
18165 + printf("%s", config);
18169 +__uml_setup("--showconfig", print_config,
18171 +" Prints the config file that this UML binary was generated from.\n\n"
18175 + * Overrides for Emacs so that we follow Linus's tabbing style.
18176 + * Emacs will notice this stuff at the end of the file and automatically
18177 + * adjust the settings for this buffer only. This must remain at the end
18179 + * ---------------------------------------------------------------------------
18180 + * Local variables:
18181 + * c-file-style: "linux"
18184 diff -Naur -X ../exclude-files orig/arch/um/kernel/exec_kern.c um/arch/um/kernel/exec_kern.c
18185 --- orig/arch/um/kernel/exec_kern.c 1969-12-31 19:00:00.000000000 -0500
18186 +++ um/arch/um/kernel/exec_kern.c 2003-10-21 03:26:06.000000000 -0400
18189 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
18190 + * Licensed under the GPL
18193 +#include "linux/slab.h"
18194 +#include "linux/smp_lock.h"
18195 +#include "asm/ptrace.h"
18196 +#include "asm/pgtable.h"
18197 +#include "asm/pgalloc.h"
18198 +#include "asm/uaccess.h"
18199 +#include "user_util.h"
18200 +#include "kern_util.h"
18201 +#include "mem_user.h"
18203 +#include "irq_user.h"
18205 +#include "2_5compat.h"
18207 +#include "time_user.h"
18208 +#include "choose-mode.h"
18209 +#include "mode_kern.h"
18211 +void flush_thread(void)
18213 + CHOOSE_MODE(flush_thread_tt(), flush_thread_skas());
18216 +void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
18218 + CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
18221 +extern void log_exec(char **argv, void *tty);
18223 +static int execve1(char *file, char **argv, char **env)
18227 +#ifdef CONFIG_TTY_LOG
18228 + log_exec(argv, current->tty);
18230 + error = do_execve(file, argv, env, ¤t->thread.regs);
18232 + current->ptrace &= ~PT_DTRACE;
18233 + set_cmdline(current_cmd());
18238 +int um_execve(char *file, char **argv, char **env)
18242 + err = execve1(file, argv, env);
18244 + do_longjmp(current->thread.exec_buf, 1);
18248 +int sys_execve(char *file, char **argv, char **env)
18254 + filename = getname((char *) file);
18255 + error = PTR_ERR(filename);
18256 + if (IS_ERR(filename)) goto out;
18257 + error = execve1(filename, argv, env);
18258 + putname(filename);
18265 + * Overrides for Emacs so that we follow Linus's tabbing style.
18266 + * Emacs will notice this stuff at the end of the file and automatically
18267 + * adjust the settings for this buffer only. This must remain at the end
18269 + * ---------------------------------------------------------------------------
18270 + * Local variables:
18271 + * c-file-style: "linux"
18274 diff -Naur -X ../exclude-files orig/arch/um/kernel/exitcode.c um/arch/um/kernel/exitcode.c
18275 --- orig/arch/um/kernel/exitcode.c 1969-12-31 19:00:00.000000000 -0500
18276 +++ um/arch/um/kernel/exitcode.c 2003-10-21 03:26:06.000000000 -0400
18279 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18280 + * Licensed under the GPL
18283 +#include "linux/init.h"
18284 +#include "linux/ctype.h"
18285 +#include "linux/proc_fs.h"
18286 +#include "asm/uaccess.h"
18288 +/* If read and write race, the read will still atomically read a valid
18291 +int uml_exitcode = 0;
18293 +static int read_proc_exitcode(char *page, char **start, off_t off,
18294 + int count, int *eof, void *data)
18298 + len = sprintf(page, "%d\n", uml_exitcode);
18300 + if(len <= off+count) *eof = 1;
18301 + *start = page + off;
18302 + if(len > count) len = count;
18303 + if(len < 0) len = 0;
18307 +static int write_proc_exitcode(struct file *file, const char *buffer,
18308 + unsigned long count, void *data)
18310 + char *end, buf[sizeof("nnnnn\0")];
18313 + if(copy_from_user(buf, buffer, count))
18315 + tmp = simple_strtol(buf, &end, 0);
18316 + if((*end != '\0') && !isspace(*end))
18318 + uml_exitcode = tmp;
18322 +static int make_proc_exitcode(void)
18324 + struct proc_dir_entry *ent;
18326 + ent = create_proc_entry("exitcode", 0600, &proc_root);
18328 + printk("make_proc_exitcode : Failed to register "
18329 + "/proc/exitcode\n");
18333 + ent->read_proc = read_proc_exitcode;
18334 + ent->write_proc = write_proc_exitcode;
18339 +__initcall(make_proc_exitcode);
18342 + * Overrides for Emacs so that we follow Linus's tabbing style.
18343 + * Emacs will notice this stuff at the end of the file and automatically
18344 + * adjust the settings for this buffer only. This must remain at the end
18346 + * ---------------------------------------------------------------------------
18347 + * Local variables:
18348 + * c-file-style: "linux"
18351 diff -Naur -X ../exclude-files orig/arch/um/kernel/frame.c um/arch/um/kernel/frame.c
18352 --- orig/arch/um/kernel/frame.c 1969-12-31 19:00:00.000000000 -0500
18353 +++ um/arch/um/kernel/frame.c 2003-10-21 03:26:06.000000000 -0400
18356 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18357 + * Licensed under the GPL
18360 +#include <stdio.h>
18361 +#include <stdlib.h>
18362 +#include <unistd.h>
18363 +#include <string.h>
18364 +#include <signal.h>
18366 +#include <sched.h>
18367 +#include <errno.h>
18368 +#include <sys/ptrace.h>
18369 +#include <sys/syscall.h>
18370 +#include <sys/mman.h>
18371 +#include <asm/page.h>
18372 +#include <asm/ptrace.h>
18373 +#include <asm/sigcontext.h>
18374 +#include "sysdep/ptrace.h"
18375 +#include "sysdep/sigcontext.h"
18376 +#include "frame_user.h"
18377 +#include "kern_util.h"
18378 +#include "ptrace_user.h"
18381 +static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
18382 + unsigned long top, void **data_out)
18384 + unsigned long regs[FRAME_SIZE];
18385 + int pid, status, n, len;
18387 + /* Start the child as a thread */
18388 + pid = clone(child, sp, CLONE_VM | SIGCHLD, arg);
18390 + printf("capture_stack : clone failed - errno = %d\n", errno);
18394 + /* Wait for it to stop itself and continue it with a SIGUSR1 to force
18395 + * it into the signal handler.
18397 + n = waitpid(pid, &status, WUNTRACED);
18399 + printf("capture_stack : waitpid failed - errno = %d\n", errno);
18402 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
18403 + fprintf(stderr, "capture_stack : Expected SIGSTOP, "
18404 + "got status = 0x%x\n", status);
18407 + if(ptrace(PTRACE_CONT, pid, 0, SIGUSR1) < 0){
18408 + printf("capture_stack : PTRACE_CONT failed - errno = %d\n",
18413 + /* Wait for it to stop itself again and grab its registers again.
18414 + * At this point, the handler has stuffed the addresses of
18415 + * sig, sc, and SA_RESTORER in raw.
18417 + n = waitpid(pid, &status, WUNTRACED);
18419 + printf("capture_stack : waitpid failed - errno = %d\n", errno);
18422 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
18423 + fprintf(stderr, "capture_stack : Expected SIGSTOP, "
18424 + "got status = 0x%x\n", status);
18427 + if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0){
18428 + printf("capture_stack : PTRACE_GETREGS failed - errno = %d\n",
18433 + /* It has outlived its usefulness, so continue it so it can exit */
18434 + if(ptrace(PTRACE_CONT, pid, 0, 0) < 0){
18435 + printf("capture_stack : PTRACE_CONT failed - errno = %d\n",
18439 + if(waitpid(pid, &status, 0) < 0){
18440 + printf("capture_stack : waitpid failed - errno = %d\n", errno);
18443 + if(!WIFSIGNALED(status) || (WTERMSIG(status) != 9)){
18444 + printf("capture_stack : Expected exit signal 9, "
18445 + "got status = 0x%x\n", status);
18449 + /* The frame that we want is the top of the signal stack */
18451 + len = top - PT_SP(regs);
18452 + *data_out = malloc(len);
18453 + if(*data_out == NULL){
18454 + printf("capture_stack : malloc failed - errno = %d\n", errno);
18457 + memcpy(*data_out, (void *) PT_SP(regs), len);
18462 +struct common_raw {
18465 + unsigned long sig;
18466 + unsigned long sr;
18467 + unsigned long sp;
18468 + struct arch_frame_data_raw arch;
18471 +#define SA_RESTORER (0x04000000)
18473 +typedef unsigned long old_sigset_t;
18475 +struct old_sigaction {
18476 + __sighandler_t handler;
18477 + old_sigset_t sa_mask;
18478 + unsigned long sa_flags;
18479 + void (*sa_restorer)(void);
18482 +static void child_common(struct common_raw *common, sighandler_t handler,
18483 + int restorer, int flags)
18485 + stack_t ss = ((stack_t) { .ss_sp = common->stack,
18487 + .ss_size = common->size });
18490 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
18491 + printf("PTRACE_TRACEME failed, errno = %d\n", errno);
18493 + if(sigaltstack(&ss, NULL) < 0){
18494 + printf("sigaltstack failed - errno = %d\n", errno);
18495 + kill(getpid(), SIGKILL);
18499 + struct sigaction sa;
18501 + sa.sa_handler = handler;
18502 + sigemptyset(&sa.sa_mask);
18503 + sa.sa_flags = SA_ONSTACK | flags;
18504 + err = sigaction(SIGUSR1, &sa, NULL);
18507 + struct old_sigaction sa;
18509 + sa.handler = handler;
18511 + sa.sa_flags = (SA_ONSTACK | flags) & ~SA_RESTORER;
18512 + err = syscall(__NR_sigaction, SIGUSR1, &sa, NULL);
18516 + printf("sigaction failed - errno = %d\n", errno);
18517 + kill(getpid(), SIGKILL);
18520 + os_stop_process(os_getpid());
18523 +/* Changed only during early boot */
18524 +struct sc_frame signal_frame_sc;
18526 +struct sc_frame signal_frame_sc_sr;
18528 +struct sc_frame_raw {
18529 + struct common_raw common;
18530 + unsigned long sc;
18534 +/* Changed only during early boot */
18535 +static struct sc_frame_raw *raw_sc = NULL;
18537 +static void sc_handler(int sig, struct sigcontext sc)
18539 + raw_sc->common.sig = (unsigned long) &sig;
18540 + raw_sc->common.sr = frame_restorer();
18541 + raw_sc->common.sp = frame_sp();
18542 + raw_sc->sc = (unsigned long) ≻
18543 + setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr);
18545 + os_stop_process(os_getpid());
18546 + kill(getpid(), SIGKILL);
18549 +static int sc_child(void *arg)
18552 + child_common(&raw_sc->common, (sighandler_t) sc_handler,
18553 + raw_sc->restorer, 0);
18557 +/* Changed only during early boot */
18558 +struct si_frame signal_frame_si;
18560 +struct si_frame_raw {
18561 + struct common_raw common;
18562 + unsigned long sip;
18563 + unsigned long si;
18564 + unsigned long ucp;
18565 + unsigned long uc;
18568 +/* Changed only during early boot */
18569 +static struct si_frame_raw *raw_si = NULL;
18571 +static void si_handler(int sig, siginfo_t *si, struct ucontext *ucontext)
18573 + raw_si->common.sig = (unsigned long) &sig;
18574 + raw_si->common.sr = frame_restorer();
18575 + raw_si->common.sp = frame_sp();
18576 + raw_si->sip = (unsigned long) &si;
18577 + raw_si->si = (unsigned long) si;
18578 + raw_si->ucp = (unsigned long) &ucontext;
18579 + raw_si->uc = (unsigned long) ucontext;
18580 + setup_arch_frame_raw(&raw_si->common.arch,
18581 + ucontext->uc_mcontext.fpregs, raw_si->common.sr);
18583 + os_stop_process(os_getpid());
18584 + kill(getpid(), SIGKILL);
18587 +static int si_child(void *arg)
18590 + child_common(&raw_si->common, (sighandler_t) si_handler, 1,
18595 +static int relative_sr(unsigned long sr, int sr_index, void *stack,
18598 + unsigned long *srp = (unsigned long *) sr;
18599 + unsigned long frame = (unsigned long) framep;
18601 + if((*srp & PAGE_MASK) == (unsigned long) stack){
18603 + *((unsigned long *) (frame + sr_index)) = *srp;
18609 +static unsigned long capture_stack_common(int (*proc)(void *), void *arg,
18610 + struct common_raw *common_in,
18611 + void *top, void *sigstack,
18613 + struct frame_common *common_out)
18615 + unsigned long sig_top = (unsigned long) sigstack + stack_len, base;
18617 + common_in->stack = (void *) sigstack;
18618 + common_in->size = stack_len;
18619 + common_out->len = capture_stack(proc, arg, top, sig_top,
18620 + &common_out->data);
18621 + base = sig_top - common_out->len;
18622 + common_out->sig_index = common_in->sig - base;
18623 + common_out->sp_index = common_in->sp - base;
18624 + common_out->sr_index = common_in->sr - base;
18625 + common_out->sr_relative = relative_sr(common_in->sr,
18626 + common_out->sr_index, sigstack,
18627 + common_out->data);
18631 +void capture_signal_stack(void)
18633 + struct sc_frame_raw raw_sc;
18634 + struct si_frame_raw raw_si;
18635 + void *stack, *sigstack;
18636 + unsigned long top, base;
18638 + stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
18639 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
18640 + sigstack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
18641 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
18642 + if((stack == MAP_FAILED) || (sigstack == MAP_FAILED)){
18643 + printf("capture_signal_stack : mmap failed - errno = %d\n",
18648 + top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
18650 + /* Get the sigcontext, no sigrestorer layout */
18651 + raw_sc.restorer = 0;
18652 + base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common,
18653 + (void *) top, sigstack, PAGE_SIZE,
18654 + &signal_frame_sc.common);
18656 + signal_frame_sc.sc_index = raw_sc.sc - base;
18657 + setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc.common.arch);
18659 + /* Ditto for the sigcontext, sigrestorer layout */
18660 + raw_sc.restorer = 1;
18661 + base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common,
18662 + (void *) top, sigstack, PAGE_SIZE,
18663 + &signal_frame_sc_sr.common);
18664 + signal_frame_sc_sr.sc_index = raw_sc.sc - base;
18665 + setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc_sr.common.arch);
18667 + /* And the siginfo layout */
18669 + base = capture_stack_common(si_child, &raw_si, &raw_si.common,
18670 + (void *) top, sigstack, PAGE_SIZE,
18671 + &signal_frame_si.common);
18672 + signal_frame_si.sip_index = raw_si.sip - base;
18673 + signal_frame_si.si_index = raw_si.si - base;
18674 + signal_frame_si.ucp_index = raw_si.ucp - base;
18675 + signal_frame_si.uc_index = raw_si.uc - base;
18676 + setup_arch_frame(&raw_si.common.arch, &signal_frame_si.common.arch);
18678 + if((munmap(stack, PAGE_SIZE) < 0) ||
18679 + (munmap(sigstack, PAGE_SIZE) < 0)){
18680 + printf("capture_signal_stack : munmap failed - errno = %d\n",
18687 + * Overrides for Emacs so that we follow Linus's tabbing style.
18688 + * Emacs will notice this stuff at the end of the file and automatically
18689 + * adjust the settings for this buffer only. This must remain at the end
18691 + * ---------------------------------------------------------------------------
18692 + * Local variables:
18693 + * c-file-style: "linux"
18696 diff -Naur -X ../exclude-files orig/arch/um/kernel/frame_kern.c um/arch/um/kernel/frame_kern.c
18697 --- orig/arch/um/kernel/frame_kern.c 1969-12-31 19:00:00.000000000 -0500
18698 +++ um/arch/um/kernel/frame_kern.c 2003-11-19 03:32:43.000000000 -0500
18701 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18702 + * Licensed under the GPL
18705 +#include "asm/ptrace.h"
18706 +#include "asm/uaccess.h"
18707 +#include "asm/signal.h"
18708 +#include "asm/uaccess.h"
18709 +#include "asm/ucontext.h"
18710 +#include "frame_kern.h"
18711 +#include "sigcontext.h"
18712 +#include "sysdep/ptrace.h"
18713 +#include "choose-mode.h"
18716 +int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
18718 + if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
18720 + if (from->si_code < 0)
18721 + return __copy_to_user(to, from, sizeof(siginfo_t));
18725 + /* If you change siginfo_t structure, please be sure
18726 + this code is fixed accordingly.
18727 + It should never copy any pad contained in the structure
18728 + to avoid security leaks, but must copy the generic
18729 + 3 ints plus the relevant union member. */
18730 + err = __put_user(from->si_signo, &to->si_signo);
18731 + err |= __put_user(from->si_errno, &to->si_errno);
18732 + err |= __put_user((short)from->si_code, &to->si_code);
18733 + /* First 32bits of unions are always present. */
18734 + err |= __put_user(from->si_pid, &to->si_pid);
18735 + switch (from->si_code >> 16) {
18736 + case __SI_FAULT >> 16:
18738 + case __SI_CHLD >> 16:
18739 + err |= __put_user(from->si_utime, &to->si_utime);
18740 + err |= __put_user(from->si_stime, &to->si_stime);
18741 + err |= __put_user(from->si_status, &to->si_status);
18743 + err |= __put_user(from->si_uid, &to->si_uid);
18750 +static int copy_restorer(void (*restorer)(void), unsigned long start,
18751 + unsigned long sr_index, int sr_relative)
18753 + unsigned long sr;
18756 + sr = (unsigned long) restorer;
18757 + sr += start + sr_index;
18758 + restorer = (void (*)(void)) sr;
18761 + return(copy_to_user((void *) (start + sr_index), &restorer,
18762 + sizeof(restorer)));
18765 +extern int userspace_pid[];
18767 +static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from,
18768 + struct arch_frame_data *arch)
18770 + return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
18772 + copy_sc_to_user_skas(userspace_pid[0], to, fp,
18774 + current->thread.cr2,
18775 + current->thread.err)));
18778 +static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set,
18779 + unsigned long sp)
18783 + err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
18784 + err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
18785 + err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
18786 + err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs,
18787 + &signal_frame_si.common.arch);
18788 + err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
18792 +int setup_signal_stack_si(unsigned long stack_top, int sig,
18793 + unsigned long handler, void (*restorer)(void),
18794 + struct pt_regs *regs, siginfo_t *info,
18797 + unsigned long start;
18798 + void *sip, *ucp, *fp;
18800 + start = stack_top - signal_frame_si.common.len;
18801 + sip = (void *) (start + signal_frame_si.si_index);
18802 + ucp = (void *) (start + signal_frame_si.uc_index);
18803 + fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext));
18805 + if(restorer == NULL)
18806 + panic("setup_signal_stack_si - no restorer");
18808 + if(copy_to_user((void *) start, signal_frame_si.common.data,
18809 + signal_frame_si.common.len) ||
18810 + copy_to_user((void *) (start + signal_frame_si.common.sig_index),
18811 + &sig, sizeof(sig)) ||
18812 + copy_siginfo_to_user(sip, info) ||
18813 + copy_to_user((void *) (start + signal_frame_si.sip_index), &sip,
18815 + copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) ||
18816 + copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp,
18818 + copy_restorer(restorer, start, signal_frame_si.common.sr_index,
18819 + signal_frame_si.common.sr_relative))
18822 + PT_REGS_IP(regs) = handler;
18823 + PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
18827 +int setup_signal_stack_sc(unsigned long stack_top, int sig,
18828 + unsigned long handler, void (*restorer)(void),
18829 + struct pt_regs *regs, sigset_t *mask)
18831 + struct frame_common *frame = &signal_frame_sc_sr.common;
18833 + int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
18834 + unsigned long sigs, sr;
18835 + unsigned long start = stack_top - frame->len - sig_size;
18837 + user_sc = (void *) (start + signal_frame_sc_sr.sc_index);
18838 + if(restorer == NULL){
18839 + frame = &signal_frame_sc.common;
18840 + user_sc = (void *) (start + signal_frame_sc.sc_index);
18841 + sr = (unsigned long) frame->data;
18842 + sr += frame->sr_index;
18843 + sr = *((unsigned long *) sr);
18844 + restorer = ((void (*)(void)) sr);
18847 + sigs = start + frame->len;
18848 + if(copy_to_user((void *) start, frame->data, frame->len) ||
18849 + copy_to_user((void *) (start + frame->sig_index), &sig,
18851 + copy_sc_to_user(user_sc, NULL, regs,
18852 + &signal_frame_sc.common.arch) ||
18853 + copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) ||
18854 + copy_to_user((void *) sigs, &mask->sig[1], sig_size) ||
18855 + copy_restorer(restorer, start, frame->sr_index, frame->sr_relative))
18858 + PT_REGS_IP(regs) = handler;
18859 + PT_REGS_SP(regs) = start + frame->sp_index;
18865 + * Overrides for Emacs so that we follow Linus's tabbing style.
18866 + * Emacs will notice this stuff at the end of the file and automatically
18867 + * adjust the settings for this buffer only. This must remain at the end
18869 + * ---------------------------------------------------------------------------
18870 + * Local variables:
18871 + * c-file-style: "linux"
18874 diff -Naur -X ../exclude-files orig/arch/um/kernel/gmon_syms.c um/arch/um/kernel/gmon_syms.c
18875 --- orig/arch/um/kernel/gmon_syms.c 1969-12-31 19:00:00.000000000 -0500
18876 +++ um/arch/um/kernel/gmon_syms.c 2003-10-21 03:26:06.000000000 -0400
18879 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
18880 + * Licensed under the GPL
18883 +#include "linux/module.h"
18885 +extern void __bb_init_func(void *);
18886 +EXPORT_SYMBOL(__bb_init_func);
18889 + * Overrides for Emacs so that we follow Linus's tabbing style.
18890 + * Emacs will notice this stuff at the end of the file and automatically
18891 + * adjust the settings for this buffer only. This must remain at the end
18893 + * ---------------------------------------------------------------------------
18894 + * Local variables:
18895 + * c-file-style: "linux"
18898 diff -Naur -X ../exclude-files orig/arch/um/kernel/gprof_syms.c um/arch/um/kernel/gprof_syms.c
18899 --- orig/arch/um/kernel/gprof_syms.c 1969-12-31 19:00:00.000000000 -0500
18900 +++ um/arch/um/kernel/gprof_syms.c 2003-10-21 03:26:06.000000000 -0400
18903 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
18904 + * Licensed under the GPL
18907 +#include "linux/module.h"
18909 +extern void mcount(void);
18910 +EXPORT_SYMBOL(mcount);
18913 + * Overrides for Emacs so that we follow Linus's tabbing style.
18914 + * Emacs will notice this stuff at the end of the file and automatically
18915 + * adjust the settings for this buffer only. This must remain at the end
18917 + * ---------------------------------------------------------------------------
18918 + * Local variables:
18919 + * c-file-style: "linux"
18922 diff -Naur -X ../exclude-files orig/arch/um/kernel/helper.c um/arch/um/kernel/helper.c
18923 --- orig/arch/um/kernel/helper.c 1969-12-31 19:00:00.000000000 -0500
18924 +++ um/arch/um/kernel/helper.c 2003-11-08 07:41:30.000000000 -0500
18927 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18928 + * Licensed under the GPL
18931 +#include <stdio.h>
18932 +#include <stdlib.h>
18933 +#include <unistd.h>
18934 +#include <errno.h>
18935 +#include <sched.h>
18936 +#include <sys/signal.h>
18937 +#include <sys/wait.h>
18939 +#include "kern_util.h"
18942 +struct helper_data {
18943 + void (*pre_exec)(void*);
18949 +/* Debugging aid, changed only from gdb */
18950 +int helper_pause = 0;
18952 +static void helper_hup(int sig)
18956 +static int helper_child(void *arg)
18958 + struct helper_data *data = arg;
18959 + char **argv = data->argv;
18962 + if(helper_pause){
18963 + signal(SIGHUP, helper_hup);
18966 + if(data->pre_exec != NULL)
18967 + (*data->pre_exec)(data->pre_data);
18968 + execvp(argv[0], argv);
18970 + printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
18971 + os_write_file(data->fd, &errval, sizeof(errval));
18972 + os_kill_process(os_getpid(), 0);
18976 +/* XXX The alloc_stack here breaks if this is called in the tracing thread */
18978 +int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
18979 + unsigned long *stack_out)
18981 + struct helper_data data;
18982 + unsigned long stack, sp;
18983 + int pid, fds[2], err, n;
18985 + if((stack_out != NULL) && (*stack_out != 0))
18986 + stack = *stack_out;
18987 + else stack = alloc_stack(0, um_in_interrupt());
18991 + err = os_pipe(fds, 1, 0);
18993 + printk("run_helper : pipe failed, err = %d\n", -err);
18997 + err = os_set_exec_close(fds[1], 1);
18999 + printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
19004 + sp = stack + page_size() - sizeof(void *);
19005 + data.pre_exec = pre_exec;
19006 + data.pre_data = pre_data;
19007 + data.argv = argv;
19008 + data.fd = fds[1];
19009 + pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
19011 + printk("run_helper : clone failed, errno = %d\n", errno);
19016 + os_close_file(fds[1]);
19017 + n = os_read_file(fds[0], &err, sizeof(err));
19019 + printk("run_helper : read on pipe failed, err = %d\n", -n);
19024 + waitpid(pid, NULL, 0);
19028 + if(stack_out == NULL) free_stack(stack, 0);
19029 + else *stack_out = stack;
19033 + os_kill_process(pid, 1);
19035 + os_close_file(fds[0]);
19036 + os_close_file(fds[1]);
19038 + free_stack(stack, 0);
19042 +int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
19043 + unsigned long *stack_out, int stack_order)
19045 + unsigned long stack, sp;
19048 + stack = alloc_stack(stack_order, um_in_interrupt());
19049 + if(stack == 0) return(-ENOMEM);
19051 + sp = stack + (page_size() << stack_order) - sizeof(void *);
19052 + pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
19054 + printk("run_helper_thread : clone failed, errno = %d\n",
19058 + if(stack_out == NULL){
19059 + pid = waitpid(pid, &status, 0);
19061 + printk("run_helper_thread - wait failed, errno = %d\n",
19065 + if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
19066 + printk("run_helper_thread - thread returned status "
19067 + "0x%x\n", status);
19068 + free_stack(stack, stack_order);
19070 + else *stack_out = stack;
19074 +int helper_wait(int pid, int block)
19078 + ret = waitpid(pid, NULL, WNOHANG);
19080 + printk("helper_wait : waitpid failed, errno = %d\n", errno);
19087 + * Overrides for Emacs so that we follow Linus's tabbing style.
19088 + * Emacs will notice this stuff at the end of the file and automatically
19089 + * adjust the settings for this buffer only. This must remain at the end
19091 + * ---------------------------------------------------------------------------
19092 + * Local variables:
19093 + * c-file-style: "linux"
19096 diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_kern.c um/arch/um/kernel/initrd_kern.c
19097 --- orig/arch/um/kernel/initrd_kern.c 1969-12-31 19:00:00.000000000 -0500
19098 +++ um/arch/um/kernel/initrd_kern.c 2003-10-21 03:26:06.000000000 -0400
19101 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
19102 + * Licensed under the GPL
19105 +#include "linux/init.h"
19106 +#include "linux/bootmem.h"
19107 +#include "linux/blk.h"
19108 +#include "asm/types.h"
19109 +#include "user_util.h"
19110 +#include "kern_util.h"
19111 +#include "initrd.h"
19115 +/* Changed by uml_initrd_setup, which is a setup */
19116 +static char *initrd __initdata = NULL;
19118 +static int __init read_initrd(void)
19124 + if(initrd == NULL) return 0;
19125 + err = os_file_size(initrd, &size);
19126 + if(err) return 0;
19127 + area = alloc_bootmem(size);
19128 + if(area == NULL) return 0;
19129 + if(load_initrd(initrd, area, size) == -1) return 0;
19130 + initrd_start = (unsigned long) area;
19131 + initrd_end = initrd_start + size;
19135 +__uml_postsetup(read_initrd);
19137 +static int __init uml_initrd_setup(char *line, int *add)
19143 +__uml_setup("initrd=", uml_initrd_setup,
19144 +"initrd=<initrd image>\n"
19145 +" This is used to boot UML from an initrd image. The argument is the\n"
19146 +" name of the file containing the image.\n\n"
19150 + * Overrides for Emacs so that we follow Linus's tabbing style.
19151 + * Emacs will notice this stuff at the end of the file and automatically
19152 + * adjust the settings for this buffer only. This must remain at the end
19154 + * ---------------------------------------------------------------------------
19155 + * Local variables:
19156 + * c-file-style: "linux"
19159 diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_user.c um/arch/um/kernel/initrd_user.c
19160 --- orig/arch/um/kernel/initrd_user.c 1969-12-31 19:00:00.000000000 -0500
19161 +++ um/arch/um/kernel/initrd_user.c 2003-10-21 03:26:06.000000000 -0400
19164 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
19165 + * Licensed under the GPL
19168 +#include <unistd.h>
19169 +#include <sys/types.h>
19170 +#include <sys/stat.h>
19171 +#include <errno.h>
19173 +#include "user_util.h"
19174 +#include "kern_util.h"
19176 +#include "initrd.h"
19179 +int load_initrd(char *filename, void *buf, int size)
19183 + fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
19185 + printk("Opening '%s' failed - err = %d\n", filename, -fd);
19188 + n = os_read_file(fd, buf, size);
19190 + printk("Read of %d bytes from '%s' failed, err = %d\n", size,
19198 + * Overrides for Emacs so that we follow Linus's tabbing style.
19199 + * Emacs will notice this stuff at the end of the file and automatically
19200 + * adjust the settings for this buffer only. This must remain at the end
19202 + * ---------------------------------------------------------------------------
19203 + * Local variables:
19204 + * c-file-style: "linux"
19207 diff -Naur -X ../exclude-files orig/arch/um/kernel/init_task.c um/arch/um/kernel/init_task.c
19208 --- orig/arch/um/kernel/init_task.c 1969-12-31 19:00:00.000000000 -0500
19209 +++ um/arch/um/kernel/init_task.c 2003-10-21 03:26:06.000000000 -0400
19212 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19213 + * Licensed under the GPL
19216 +#include "linux/config.h"
19217 +#include "linux/mm.h"
19218 +#include "linux/sched.h"
19219 +#include "linux/version.h"
19220 +#include "asm/uaccess.h"
19221 +#include "asm/pgtable.h"
19222 +#include "user_util.h"
19223 +#include "mem_user.h"
19225 +static struct fs_struct init_fs = INIT_FS;
19226 +static struct files_struct init_files = INIT_FILES;
19227 +static struct signal_struct init_signals = INIT_SIGNALS;
19228 +struct mm_struct init_mm = INIT_MM(init_mm);
19231 + * Initial task structure.
19233 + * We need to make sure that this is 16384-byte aligned due to the
19234 + * way process stacks are handled. This is done by having a special
19235 + * "init_task" linker map entry..
19238 +union task_union init_task_union
19239 +__attribute__((__section__(".data.init_task"))) =
19240 +{ INIT_TASK(init_task_union.task) };
19242 +struct task_struct *alloc_task_struct(void)
19244 + return((struct task_struct *)
19245 + __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
19248 +void unprotect_stack(unsigned long stack)
19250 + protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
19254 +void free_task_struct(struct task_struct *task)
19256 + /* free_pages decrements the page counter and only actually frees
19257 + * the pages if they are now not accessed by anything.
19259 + free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
19263 + * Overrides for Emacs so that we follow Linus's tabbing style.
19264 + * Emacs will notice this stuff at the end of the file and automatically
19265 + * adjust the settings for this buffer only. This must remain at the end
19267 + * ---------------------------------------------------------------------------
19268 + * Local variables:
19269 + * c-file-style: "linux"
19272 diff -Naur -X ../exclude-files orig/arch/um/kernel/irq.c um/arch/um/kernel/irq.c
19273 --- orig/arch/um/kernel/irq.c 1969-12-31 19:00:00.000000000 -0500
19274 +++ um/arch/um/kernel/irq.c 2003-12-16 22:45:27.000000000 -0500
19277 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19278 + * Licensed under the GPL
19279 + * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
19280 + * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
19283 +#include "linux/config.h"
19284 +#include "linux/kernel.h"
19285 +#include "linux/smp.h"
19286 +#include "linux/irq.h"
19287 +#include "linux/kernel_stat.h"
19288 +#include "linux/interrupt.h"
19289 +#include "linux/random.h"
19290 +#include "linux/slab.h"
19291 +#include "linux/file.h"
19292 +#include "linux/proc_fs.h"
19293 +#include "linux/init.h"
19294 +#include "linux/seq_file.h"
19295 +#include "asm/irq.h"
19296 +#include "asm/hw_irq.h"
19297 +#include "asm/hardirq.h"
19298 +#include "asm/atomic.h"
19299 +#include "asm/signal.h"
19300 +#include "asm/system.h"
19301 +#include "asm/errno.h"
19302 +#include "asm/uaccess.h"
19303 +#include "user_util.h"
19304 +#include "kern_util.h"
19305 +#include "irq_user.h"
19306 +#include "irq_kern.h"
19308 +static void register_irq_proc (unsigned int irq);
19310 +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
19311 + { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
19314 + * Generic no controller code
19317 +static void enable_none(unsigned int irq) { }
19318 +static unsigned int startup_none(unsigned int irq) { return 0; }
19319 +static void disable_none(unsigned int irq) { }
19320 +static void ack_none(unsigned int irq)
19323 + * 'what should we do if we get a hw irq event on an illegal vector'.
19324 + * each architecture has to answer this themselves, it doesnt deserve
19325 + * a generic callback i think.
19328 + printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
19329 +#ifdef CONFIG_X86_LOCAL_APIC
19331 + * Currently unexpected vectors happen only on SMP and APIC.
19332 + * We _must_ ack these because every local APIC has only N
19333 + * irq slots per priority level, and a 'hanging, unacked' IRQ
19334 + * holds up an irq slot - in excessive cases (when multiple
19335 + * unexpected vectors occur) that might lock up the APIC
19343 +/* startup is the same as "enable", shutdown is same as "disable" */
19344 +#define shutdown_none disable_none
19345 +#define end_none enable_none
19347 +struct hw_interrupt_type no_irq_type = {
19358 + * Generic, controller-independent functions:
19361 +int get_irq_list(char *buf)
19364 + unsigned long flags;
19365 + struct irqaction * action;
19368 + p += sprintf(p, " ");
19369 + for (j=0; j<smp_num_cpus; j++)
19370 + p += sprintf(p, "CPU%d ",j);
19373 + for (i = 0 ; i < NR_IRQS ; i++) {
19374 + spin_lock_irqsave(&irq_desc[i].lock, flags);
19375 + action = irq_desc[i].action;
19378 + p += sprintf(p, "%3d: ",i);
19379 +#ifndef CONFIG_SMP
19380 + p += sprintf(p, "%10u ", kstat_irqs(i));
19382 + for (j = 0; j < smp_num_cpus; j++)
19383 + p += sprintf(p, "%10u ",
19384 + kstat.irqs[cpu_logical_map(j)][i]);
19386 + p += sprintf(p, " %14s", irq_desc[i].handler->typename);
19387 + p += sprintf(p, " %s", action->name);
19389 + for (action=action->next; action; action = action->next)
19390 + p += sprintf(p, ", %s", action->name);
19393 + spin_unlock_irqrestore(&irq_desc[i].lock, flags);
19395 + p += sprintf(p, "\n");
19398 + p += sprintf(p, "LOC: ");
19399 + for (j = 0; j < smp_num_cpus; j++)
19400 + p += sprintf(p, "%10u ",
19401 + apic_timer_irqs[cpu_logical_map(j)]);
19402 + p += sprintf(p, "\n");
19405 + p += sprintf(p, "ERR: %10lu\n", 0L);
19410 + * This should really return information about whether
19411 + * we should do bottom half handling etc. Right now we
19412 + * end up _always_ checking the bottom half, which is a
19413 + * waste of time and is not what some drivers would
19416 +int handle_IRQ_event(unsigned int irq, struct pt_regs * regs,
19417 + struct irqaction * action)
19420 + int cpu = smp_processor_id();
19422 + irq_enter(cpu, irq);
19424 + status = 1; /* Force the "do bottom halves" bit */
19426 + if (!(action->flags & SA_INTERRUPT))
19430 + status |= action->flags;
19431 + action->handler(irq, action->dev_id, regs);
19432 + action = action->next;
19433 + } while (action);
19434 + if (status & SA_SAMPLE_RANDOM)
19435 + add_interrupt_randomness(irq);
19438 + irq_exit(cpu, irq);
19444 + * Generic enable/disable code: this just calls
19445 + * down into the PIC-specific version for the actual
19446 + * hardware disable after having gotten the irq
19447 + * controller lock.
19451 + * disable_irq_nosync - disable an irq without waiting
19452 + * @irq: Interrupt to disable
19454 + * Disable the selected interrupt line. Disables of an interrupt
19455 + * stack. Unlike disable_irq(), this function does not ensure existing
19456 + * instances of the IRQ handler have completed before returning.
19458 + * This function may be called from IRQ context.
19461 +void inline disable_irq_nosync(unsigned int irq)
19463 + irq_desc_t *desc = irq_desc + irq;
19464 + unsigned long flags;
19466 + spin_lock_irqsave(&desc->lock, flags);
19467 + if (!desc->depth++) {
19468 + desc->status |= IRQ_DISABLED;
19469 + desc->handler->disable(irq);
19471 + spin_unlock_irqrestore(&desc->lock, flags);
19475 + * disable_irq - disable an irq and wait for completion
19476 + * @irq: Interrupt to disable
19478 + * Disable the selected interrupt line. Disables of an interrupt
19479 + * stack. That is for two disables you need two enables. This
19480 + * function waits for any pending IRQ handlers for this interrupt
19481 + * to complete before returning. If you use this function while
19482 + * holding a resource the IRQ handler may need you will deadlock.
19484 + * This function may be called - with care - from IRQ context.
19487 +void disable_irq(unsigned int irq)
19489 + disable_irq_nosync(irq);
19491 + if (!local_irq_count(smp_processor_id())) {
19494 + } while (irq_desc[irq].status & IRQ_INPROGRESS);
19499 + * enable_irq - enable interrupt handling on an irq
19500 + * @irq: Interrupt to enable
19502 + * Re-enables the processing of interrupts on this IRQ line
19503 + * providing no disable_irq calls are now in effect.
19505 + * This function may be called from IRQ context.
19508 +void enable_irq(unsigned int irq)
19510 + irq_desc_t *desc = irq_desc + irq;
19511 + unsigned long flags;
19513 + spin_lock_irqsave(&desc->lock, flags);
19514 + switch (desc->depth) {
19516 + unsigned int status = desc->status & ~IRQ_DISABLED;
19517 + desc->status = status;
19518 + if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
19519 + desc->status = status | IRQ_REPLAY;
19520 + hw_resend_irq(desc->handler,irq);
19522 + desc->handler->enable(irq);
19523 + /* fall-through */
19529 + printk(KERN_ERR "enable_irq() unbalanced from %p\n",
19530 + __builtin_return_address(0));
19532 + spin_unlock_irqrestore(&desc->lock, flags);
19536 + * do_IRQ handles all normal device IRQ's (the special
19537 + * SMP cross-CPU interrupts have their own specific
19540 +unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
19543 + * 0 return value means that this irq is already being
19544 + * handled by some other CPU. (or is disabled)
19546 + int cpu = smp_processor_id();
19547 + irq_desc_t *desc = irq_desc + irq;
19548 + struct irqaction * action;
19549 + unsigned int status;
19551 + kstat.irqs[cpu][irq]++;
19552 + spin_lock(&desc->lock);
19553 + desc->handler->ack(irq);
19555 + REPLAY is when Linux resends an IRQ that was dropped earlier
19556 + WAITING is used by probe to mark irqs that are being tested
19558 + status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
19559 + status |= IRQ_PENDING; /* we _want_ to handle it */
19562 + * If the IRQ is disabled for whatever reason, we cannot
19563 + * use the action we have.
19566 + if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
19567 + action = desc->action;
19568 + status &= ~IRQ_PENDING; /* we commit to handling */
19569 + status |= IRQ_INPROGRESS; /* we are handling it */
19571 + desc->status = status;
19574 + * If there is no IRQ handler or it was disabled, exit early.
19575 + Since we set PENDING, if another processor is handling
19576 + a different instance of this same irq, the other processor
19577 + will take care of it.
19583 + * Edge triggered interrupts need to remember
19584 + * pending events.
19585 + * This applies to any hw interrupts that allow a second
19586 + * instance of the same irq to arrive while we are in do_IRQ
19587 + * or in the handler. But the code here only handles the _second_
19588 + * instance of the irq, not the third or fourth. So it is mostly
19589 + * useful for irq hardware that does not mask cleanly in an
19590 + * SMP environment.
19593 + spin_unlock(&desc->lock);
19594 + handle_IRQ_event(irq, (struct pt_regs *) regs, action);
19595 + spin_lock(&desc->lock);
19597 + if (!(desc->status & IRQ_PENDING))
19599 + desc->status &= ~IRQ_PENDING;
19601 + desc->status &= ~IRQ_INPROGRESS;
19604 + * The ->end() handler has to deal with interrupts which got
19605 + * disabled while the handler was running.
19607 + desc->handler->end(irq);
19608 + spin_unlock(&desc->lock);
19610 + if (softirq_pending(cpu))
19616 + * request_irq - allocate an interrupt line
19617 + * @irq: Interrupt line to allocate
19618 + * @handler: Function to be called when the IRQ occurs
19619 + * @irqflags: Interrupt type flags
19620 + * @devname: An ascii name for the claiming device
19621 + * @dev_id: A cookie passed back to the handler function
19623 + * This call allocates interrupt resources and enables the
19624 + * interrupt line and IRQ handling. From the point this
19625 + * call is made your handler function may be invoked. Since
19626 + * your handler function must clear any interrupt the board
19627 + * raises, you must take care both to initialise your hardware
19628 + * and to set up the interrupt handler in the right order.
19630 + * Dev_id must be globally unique. Normally the address of the
19631 + * device data structure is used as the cookie. Since the handler
19632 + * receives this value it makes sense to use it.
19634 + * If your interrupt is shared you must pass a non NULL dev_id
19635 + * as this is required when freeing the interrupt.
19639 + * SA_SHIRQ Interrupt is shared
19641 + * SA_INTERRUPT Disable local interrupts while processing
19643 + * SA_SAMPLE_RANDOM The interrupt can be used for entropy
19647 +int request_irq(unsigned int irq,
19648 + void (*handler)(int, void *, struct pt_regs *),
19649 + unsigned long irqflags,
19650 + const char * devname,
19654 + struct irqaction * action;
19658 + * Sanity-check: shared interrupts should REALLY pass in
19659 + * a real dev-ID, otherwise we'll have trouble later trying
19660 + * to figure out which interrupt is which (messes up the
19661 + * interrupt freeing logic etc).
19663 + if (irqflags & SA_SHIRQ) {
19665 + printk(KERN_ERR "Bad boy: %s (at 0x%x) called us "
19666 + "without a dev_id!\n", devname, (&irq)[-1]);
19670 + if (irq >= NR_IRQS)
19675 + action = (struct irqaction *)
19676 + kmalloc(sizeof(struct irqaction), GFP_KERNEL);
19680 + action->handler = handler;
19681 + action->flags = irqflags;
19682 + action->mask = 0;
19683 + action->name = devname;
19684 + action->next = NULL;
19685 + action->dev_id = dev_id;
19687 + retval = setup_irq(irq, action);
19693 +int um_request_irq(unsigned int irq, int fd, int type,
19694 + void (*handler)(int, void *, struct pt_regs *),
19695 + unsigned long irqflags, const char * devname,
19700 + err = request_irq(irq, handler, irqflags, devname, dev_id);
19705 + err = activate_fd(irq, fd, type, dev_id);
19709 +/* this was setup_x86_irq but it seems pretty generic */
19710 +int setup_irq(unsigned int irq, struct irqaction * new)
19713 + unsigned long flags;
19714 + struct irqaction *old, **p;
19715 + irq_desc_t *desc = irq_desc + irq;
19718 + * Some drivers like serial.c use request_irq() heavily,
19719 + * so we have to be careful not to interfere with a
19720 + * running system.
19722 + if (new->flags & SA_SAMPLE_RANDOM) {
19724 + * This function might sleep, we want to call it first,
19725 + * outside of the atomic block.
19726 + * Yes, this might clear the entropy pool if the wrong
19727 + * driver is attempted to be loaded, without actually
19728 + * installing a new handler, but is this really a problem,
19729 + * only the sysadmin is able to do this.
19731 + rand_initialize_irq(irq);
19735 + * The following block of code has to be executed atomically
19737 + spin_lock_irqsave(&desc->lock,flags);
19738 + p = &desc->action;
19740 + if (old != NULL) {
19741 + /* Can't share interrupts unless both agree to */
19742 + if (!(old->flags & new->flags & SA_SHIRQ)) {
19743 + spin_unlock_irqrestore(&desc->lock,flags);
19747 + /* add new interrupt at end of irq queue */
19759 + desc->status &= ~IRQ_DISABLED;
19760 + desc->handler->startup(irq);
19762 + spin_unlock_irqrestore(&desc->lock,flags);
19764 + register_irq_proc(irq);
19769 + * free_irq - free an interrupt
19770 + * @irq: Interrupt line to free
19771 + * @dev_id: Device identity to free
19773 + * Remove an interrupt handler. The handler is removed and if the
19774 + * interrupt line is no longer in use by any driver it is disabled.
19775 + * On a shared IRQ the caller must ensure the interrupt is disabled
19776 + * on the card it drives before calling this function. The function
19777 + * does not return until any executing interrupts for this IRQ
19778 + * have completed.
19780 + * This function may be called from interrupt context.
19782 + * Bugs: Attempting to free an irq in a handler for the same irq hangs
19786 +void free_irq(unsigned int irq, void *dev_id)
19788 + irq_desc_t *desc;
19789 + struct irqaction **p;
19790 + unsigned long flags;
19792 + if (irq >= NR_IRQS)
19795 + desc = irq_desc + irq;
19796 + spin_lock_irqsave(&desc->lock,flags);
19797 + p = &desc->action;
19799 + struct irqaction * action = *p;
19801 + struct irqaction **pp = p;
19802 + p = &action->next;
19803 + if (action->dev_id != dev_id)
19806 + /* Found it - now remove it from the list of entries */
19807 + *pp = action->next;
19808 + if (!desc->action) {
19809 + desc->status |= IRQ_DISABLED;
19810 + desc->handler->shutdown(irq);
19812 + free_irq_by_irq_and_dev(irq, dev_id);
19813 + spin_unlock_irqrestore(&desc->lock,flags);
19816 + /* Wait to make sure it's not being used on another CPU */
19817 + while (desc->status & IRQ_INPROGRESS)
19823 + printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
19824 + spin_unlock_irqrestore(&desc->lock,flags);
19829 +/* These are initialized by sysctl_init, which is called from init/main.c */
19830 +static struct proc_dir_entry * root_irq_dir;
19831 +static struct proc_dir_entry * irq_dir [NR_IRQS];
19832 +static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
19834 +/* These are read and written as longs, so a read won't see a partial write
19835 + * even during a race.
19837 +static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
19839 +#define HEX_DIGITS 8
19841 +static int irq_affinity_read_proc (char *page, char **start, off_t off,
19842 + int count, int *eof, void *data)
19844 + if (count < HEX_DIGITS+1)
19846 + return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
19849 +static unsigned int parse_hex_value (const char *buffer,
19850 + unsigned long count, unsigned long *ret)
19852 + unsigned char hexnum [HEX_DIGITS];
19853 + unsigned long value;
19858 + if (count > HEX_DIGITS)
19859 + count = HEX_DIGITS;
19860 + if (copy_from_user(hexnum, buffer, count))
19864 + * Parse the first HEX_DIGITS characters as a hex string, any non-hex
19865 + * char is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
19869 + for (i = 0; i < count; i++) {
19870 + unsigned int c = hexnum[i];
19873 + case '0' ... '9': c -= '0'; break;
19874 + case 'a' ... 'f': c -= 'a'-10; break;
19875 + case 'A' ... 'F': c -= 'A'-10; break;
19879 + value = (value << 4) | c;
19886 +static int irq_affinity_write_proc (struct file *file, const char *buffer,
19887 + unsigned long count, void *data)
19889 + int irq = (long) data, full_count = count, err;
19890 + unsigned long new_value;
19892 + if (!irq_desc[irq].handler->set_affinity)
19895 + err = parse_hex_value(buffer, count, &new_value);
19899 + * Do not allow disabling IRQs completely - it's a too easy
19900 + * way to make the system unusable accidentally :-) At least
19901 + * one online CPU still has to be targeted.
19903 + if (!(new_value & cpu_online_map))
19907 + irq_affinity[irq] = new_value;
19908 + irq_desc[irq].handler->set_affinity(irq, new_value);
19910 + return full_count;
19913 +static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
19914 + int count, int *eof, void *data)
19916 + unsigned long *mask = (unsigned long *) data;
19917 + if (count < HEX_DIGITS+1)
19919 + return sprintf (page, "%08lx\n", *mask);
19922 +static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
19923 + unsigned long count, void *data)
19925 + unsigned long *mask = (unsigned long *) data, full_count = count, err;
19926 + unsigned long new_value;
19928 + err = parse_hex_value(buffer, count, &new_value);
19932 + *mask = new_value;
19933 + return full_count;
19936 +#define MAX_NAMELEN 10
19938 +static void register_irq_proc (unsigned int irq)
19940 + struct proc_dir_entry *entry;
19941 + char name [MAX_NAMELEN];
19943 + if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
19947 + memset(name, 0, MAX_NAMELEN);
19948 + sprintf(name, "%d", irq);
19950 + /* create /proc/irq/1234 */
19951 + irq_dir[irq] = proc_mkdir(name, root_irq_dir);
19953 + /* create /proc/irq/1234/smp_affinity */
19954 + entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
19956 + entry->nlink = 1;
19957 + entry->data = (void *)(long)irq;
19958 + entry->read_proc = irq_affinity_read_proc;
19959 + entry->write_proc = irq_affinity_write_proc;
19961 + smp_affinity_entry[irq] = entry;
19964 +/* Read and written as a long */
19965 +unsigned long prof_cpu_mask = -1;
19967 +void __init init_irq_proc (void)
19969 + struct proc_dir_entry *entry;
19972 + /* create /proc/irq */
19973 + root_irq_dir = proc_mkdir("irq", 0);
19975 + /* create /proc/irq/prof_cpu_mask */
19976 + entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
19978 + entry->nlink = 1;
19979 + entry->data = (void *)&prof_cpu_mask;
19980 + entry->read_proc = prof_cpu_mask_read_proc;
19981 + entry->write_proc = prof_cpu_mask_write_proc;
19984 + * Create entries for all existing IRQs.
19986 + for (i = 0; i < NR_IRQS; i++)
19987 + register_irq_proc(i);
19990 +static spinlock_t irq_spinlock = SPIN_LOCK_UNLOCKED;
19992 +unsigned long irq_lock(void)
19994 + unsigned long flags;
19996 + spin_lock_irqsave(&irq_spinlock, flags);
20000 +void irq_unlock(unsigned long flags)
20002 + spin_unlock_irqrestore(&irq_spinlock, flags);
20005 +unsigned long probe_irq_on(void)
20010 +int probe_irq_off(unsigned long val)
20015 +static unsigned int startup_SIGIO_irq(unsigned int irq)
20020 +static void shutdown_SIGIO_irq(unsigned int irq)
20024 +static void enable_SIGIO_irq(unsigned int irq)
20028 +static void disable_SIGIO_irq(unsigned int irq)
20032 +static void mask_and_ack_SIGIO(unsigned int irq)
20036 +static void end_SIGIO_irq(unsigned int irq)
20040 +static unsigned int startup_SIGVTALRM_irq(unsigned int irq)
20045 +static void shutdown_SIGVTALRM_irq(unsigned int irq)
20049 +static void enable_SIGVTALRM_irq(unsigned int irq)
20053 +static void disable_SIGVTALRM_irq(unsigned int irq)
20057 +static void mask_and_ack_SIGVTALRM(unsigned int irq)
20061 +static void end_SIGVTALRM_irq(unsigned int irq)
20065 +static struct hw_interrupt_type SIGIO_irq_type = {
20067 + startup_SIGIO_irq,
20068 + shutdown_SIGIO_irq,
20069 + enable_SIGIO_irq,
20070 + disable_SIGIO_irq,
20071 + mask_and_ack_SIGIO,
20076 +static struct hw_interrupt_type SIGVTALRM_irq_type = {
20078 + startup_SIGVTALRM_irq,
20079 + shutdown_SIGVTALRM_irq,
20080 + enable_SIGVTALRM_irq,
20081 + disable_SIGVTALRM_irq,
20082 + mask_and_ack_SIGVTALRM,
20083 + end_SIGVTALRM_irq,
20087 +void __init init_IRQ(void)
20091 + irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
20092 + irq_desc[TIMER_IRQ].action = 0;
20093 + irq_desc[TIMER_IRQ].depth = 1;
20094 + irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type;
20095 + enable_irq(TIMER_IRQ);
20096 + for(i=1;i<NR_IRQS;i++){
20097 + irq_desc[i].status = IRQ_DISABLED;
20098 + irq_desc[i].action = 0;
20099 + irq_desc[i].depth = 1;
20100 + irq_desc[i].handler = &SIGIO_irq_type;
20103 + init_irq_signals(0);
20107 + * Overrides for Emacs so that we follow Linus's tabbing style.
20108 + * Emacs will notice this stuff at the end of the file and automatically
20109 + * adjust the settings for this buffer only. This must remain at the end
20111 + * ---------------------------------------------------------------------------
20112 + * Local variables:
20113 + * c-file-style: "linux"
20116 diff -Naur -X ../exclude-files orig/arch/um/kernel/irq_user.c um/arch/um/kernel/irq_user.c
20117 --- orig/arch/um/kernel/irq_user.c 1969-12-31 19:00:00.000000000 -0500
20118 +++ um/arch/um/kernel/irq_user.c 2003-10-21 03:26:06.000000000 -0400
20121 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
20122 + * Licensed under the GPL
20125 +#include <stdlib.h>
20126 +#include <unistd.h>
20127 +#include <errno.h>
20128 +#include <signal.h>
20129 +#include <string.h>
20130 +#include <sys/poll.h>
20131 +#include <sys/types.h>
20132 +#include <sys/time.h>
20133 +#include "user_util.h"
20134 +#include "kern_util.h"
20136 +#include "process.h"
20137 +#include "signal_user.h"
20138 +#include "sigio.h"
20139 +#include "irq_user.h"
20143 + struct irq_fd *next;
20150 + int current_events;
20154 +static struct irq_fd *active_fds = NULL;
20155 +static struct irq_fd **last_irq_ptr = &active_fds;
20157 +static struct pollfd *pollfds = NULL;
20158 +static int pollfds_num = 0;
20159 +static int pollfds_size = 0;
20161 +extern int io_count, intr_count;
20163 +void sigio_handler(int sig, union uml_pt_regs *regs)
20165 + struct irq_fd *irq_fd, *next;
20168 + if(smp_sigio_handler()) return;
20170 + n = poll(pollfds, pollfds_num, 0);
20172 + if(errno == EINTR) continue;
20173 + printk("sigio_handler : poll returned %d, "
20174 + "errno = %d\n", n, errno);
20177 + if(n == 0) break;
20179 + irq_fd = active_fds;
20180 + for(i = 0; i < pollfds_num; i++){
20181 + if(pollfds[i].revents != 0){
20182 + irq_fd->current_events = pollfds[i].revents;
20183 + pollfds[i].fd = -1;
20185 + irq_fd = irq_fd->next;
20188 + for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){
20189 + next = irq_fd->next;
20190 + if(irq_fd->current_events != 0){
20191 + irq_fd->current_events = 0;
20192 + do_IRQ(irq_fd->irq, regs);
20194 + /* This is here because the next irq may be
20195 + * freed in the handler. If a console goes
20196 + * away, both the read and write irqs will be
20197 + * freed. After do_IRQ, ->next will point to
20199 + * Irqs can't be freed inside their handlers,
20200 + * so the next best thing is to have them
20201 + * marked as needing freeing, so that they
20202 + * can be freed here.
20204 + next = irq_fd->next;
20205 + if(irq_fd->freed)
20206 + free_irq(irq_fd->irq, irq_fd->id);
20212 +int activate_ipi(int fd, int pid)
20214 + return(os_set_fd_async(fd, pid));
20217 +static void maybe_sigio_broken(int fd, int type)
20220 + if((type == IRQ_WRITE) && !pty_output_sigio){
20221 + write_sigio_workaround();
20222 + add_sigio_fd(fd, 0);
20224 + else if((type == IRQ_READ) && !pty_close_sigio){
20225 + write_sigio_workaround();
20226 + add_sigio_fd(fd, 1);
20231 +int activate_fd(int irq, int fd, int type, void *dev_id)
20233 + struct pollfd *tmp_pfd;
20234 + struct irq_fd *new_fd, *irq_fd;
20235 + unsigned long flags;
20236 + int pid, events, err, n, size;
20238 + pid = os_getpid();
20239 + err = os_set_fd_async(fd, pid);
20243 + new_fd = um_kmalloc(sizeof(*new_fd));
20245 + if(new_fd == NULL)
20248 + if(type == IRQ_READ) events = POLLIN | POLLPRI;
20249 + else events = POLLOUT;
20250 + *new_fd = ((struct irq_fd) { .next = NULL,
20256 + .events = events,
20257 + .current_events = 0,
20260 + /* Critical section - locked by a spinlock because this stuff can
20261 + * be changed from interrupt handlers. The stuff above is done
20262 + * outside the lock because it allocates memory.
20265 + /* Actually, it only looks like it can be called from interrupt
20266 + * context. The culprit is reactivate_fd, which calls
20267 + * maybe_sigio_broken, which calls write_sigio_workaround,
20268 + * which calls activate_fd. However, write_sigio_workaround should
20269 + * only be called once, at boot time. That would make it clear that
20270 + * this is called only from process context, and can be locked with
20273 + flags = irq_lock();
20274 + for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
20275 + if((irq_fd->fd == fd) && (irq_fd->type == type)){
20276 + printk("Registering fd %d twice\n", fd);
20277 + printk("Irqs : %d, %d\n", irq_fd->irq, irq);
20278 + printk("Ids : 0x%x, 0x%x\n", irq_fd->id, dev_id);
20284 + if(n == pollfds_size){
20286 + /* Here we have to drop the lock in order to call
20287 + * kmalloc, which might sleep. If something else
20288 + * came in and changed the pollfds array, we free
20289 + * the buffer and try again.
20291 + irq_unlock(flags);
20292 + size = (pollfds_num + 1) * sizeof(pollfds[0]);
20293 + tmp_pfd = um_kmalloc(size);
20294 + flags = irq_lock();
20295 + if(tmp_pfd == NULL)
20297 + if(n == pollfds_size)
20301 + if(pollfds != NULL){
20302 + memcpy(tmp_pfd, pollfds,
20303 + sizeof(pollfds[0]) * pollfds_size);
20306 + pollfds = tmp_pfd;
20310 + if(type == IRQ_WRITE)
20313 + pollfds[pollfds_num] = ((struct pollfd) { .fd = fd,
20314 + .events = events,
20318 + *last_irq_ptr = new_fd;
20319 + last_irq_ptr = &new_fd->next;
20321 + irq_unlock(flags);
20323 + /* This calls activate_fd, so it has to be outside the critical
20326 + maybe_sigio_broken(fd, type);
20331 + irq_unlock(flags);
20337 +static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
20339 + struct irq_fd **prev;
20340 + unsigned long flags;
20343 + flags = irq_lock();
20344 + prev = &active_fds;
20345 + while(*prev != NULL){
20346 + if((*test)(*prev, arg)){
20347 + struct irq_fd *old_fd = *prev;
20348 + if((pollfds[i].fd != -1) &&
20349 + (pollfds[i].fd != (*prev)->fd)){
20350 + printk("free_irq_by_cb - mismatch between "
20351 + "active_fds and pollfds, fd %d vs %d\n",
20352 + (*prev)->fd, pollfds[i].fd);
20355 + memcpy(&pollfds[i], &pollfds[i + 1],
20356 + (pollfds_num - i - 1) * sizeof(pollfds[0]));
20358 + if(last_irq_ptr == &old_fd->next)
20359 + last_irq_ptr = prev;
20360 + *prev = (*prev)->next;
20361 + if(old_fd->type == IRQ_WRITE)
20362 + ignore_sigio_fd(old_fd->fd);
20366 + prev = &(*prev)->next;
20370 + irq_unlock(flags);
20373 +struct irq_and_dev {
20378 +static int same_irq_and_dev(struct irq_fd *irq, void *d)
20380 + struct irq_and_dev *data = d;
20382 + return((irq->irq == data->irq) && (irq->id == data->dev));
20385 +void free_irq_by_irq_and_dev(int irq, void *dev)
20387 + struct irq_and_dev data = ((struct irq_and_dev) { .irq = irq,
20390 + free_irq_by_cb(same_irq_and_dev, &data);
20393 +static int same_fd(struct irq_fd *irq, void *fd)
20395 + return(irq->fd == *((int *) fd));
20398 +void free_irq_by_fd(int fd)
20400 + free_irq_by_cb(same_fd, &fd);
20403 +static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
20405 + struct irq_fd *irq;
20408 + for(irq=active_fds; irq != NULL; irq = irq->next){
20409 + if((irq->fd == fd) && (irq->irq == irqnum)) break;
20413 + printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
20416 + if((pollfds[i].fd != -1) && (pollfds[i].fd != fd)){
20417 + printk("find_irq_by_fd - mismatch between active_fds and "
20418 + "pollfds, fd %d vs %d, need %d\n", irq->fd,
20419 + pollfds[i].fd, fd);
20428 +void free_irq_later(int irq, void *dev_id)
20430 + struct irq_fd *irq_fd;
20431 + unsigned long flags;
20433 + flags = irq_lock();
20434 + for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
20435 + if((irq_fd->irq == irq) && (irq_fd->id == dev_id))
20438 + if(irq_fd == NULL){
20439 + printk("free_irq_later found no irq, irq = %d, "
20440 + "dev_id = 0x%p\n", irq, dev_id);
20443 + irq_fd->freed = 1;
20445 + irq_unlock(flags);
20448 +void reactivate_fd(int fd, int irqnum)
20450 + struct irq_fd *irq;
20451 + unsigned long flags;
20454 + flags = irq_lock();
20455 + irq = find_irq_by_fd(fd, irqnum, &i);
20457 + irq_unlock(flags);
20461 + pollfds[i].fd = irq->fd;
20463 + irq_unlock(flags);
20465 + /* This calls activate_fd, so it has to be outside the critical
20468 + maybe_sigio_broken(fd, irq->type);
20471 +void deactivate_fd(int fd, int irqnum)
20473 + struct irq_fd *irq;
20474 + unsigned long flags;
20477 + flags = irq_lock();
20478 + irq = find_irq_by_fd(fd, irqnum, &i);
20481 + pollfds[i].fd = -1;
20483 + irq_unlock(flags);
20486 +void forward_ipi(int fd, int pid)
20490 + err = os_set_owner(fd, pid);
20492 + printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
20493 + "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
20496 +void forward_interrupts(int pid)
20498 + struct irq_fd *irq;
20499 + unsigned long flags;
20502 + flags = irq_lock();
20503 + for(irq=active_fds;irq != NULL;irq = irq->next){
20504 + err = os_set_owner(irq->fd, pid);
20506 + /* XXX Just remove the irq rather than
20507 + * print out an infinite stream of these
20509 + printk("Failed to forward %d to pid %d, err = %d\n",
20510 + irq->fd, pid, -err);
20515 + irq_unlock(flags);
20518 +void init_irq_signals(int on_sigstack)
20520 + __sighandler_t h;
20523 + flags = on_sigstack ? SA_ONSTACK : 0;
20524 + if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
20525 + else h = boot_timer_handler;
20527 + set_handler(SIGVTALRM, h, flags | SA_RESTART,
20528 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
20529 + set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
20530 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20531 + signal(SIGWINCH, SIG_IGN);
20535 + * Overrides for Emacs so that we follow Linus's tabbing style.
20536 + * Emacs will notice this stuff at the end of the file and automatically
20537 + * adjust the settings for this buffer only. This must remain at the end
20539 + * ---------------------------------------------------------------------------
20540 + * Local variables:
20541 + * c-file-style: "linux"
20544 diff -Naur -X ../exclude-files orig/arch/um/kernel/ksyms.c um/arch/um/kernel/ksyms.c
20545 --- orig/arch/um/kernel/ksyms.c 1969-12-31 19:00:00.000000000 -0500
20546 +++ um/arch/um/kernel/ksyms.c 2003-12-17 03:22:37.000000000 -0500
20549 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
20550 + * Licensed under the GPL
20553 +#include "linux/config.h"
20554 +#include "linux/module.h"
20555 +#include "linux/string.h"
20556 +#include "linux/smp_lock.h"
20557 +#include "linux/spinlock.h"
20558 +#include "asm/current.h"
20559 +#include "asm/delay.h"
20560 +#include "asm/processor.h"
20561 +#include "asm/unistd.h"
20562 +#include "asm/pgalloc.h"
20563 +#include "asm/pgtable.h"
20564 +#include "asm/page.h"
20565 +#include "kern_util.h"
20566 +#include "user_util.h"
20568 +#include "helper.h"
20570 +EXPORT_SYMBOL(stop);
20571 +EXPORT_SYMBOL(strtok);
20572 +EXPORT_SYMBOL(uml_physmem);
20573 +EXPORT_SYMBOL(set_signals);
20574 +EXPORT_SYMBOL(get_signals);
20575 +EXPORT_SYMBOL(kernel_thread);
20576 +EXPORT_SYMBOL(__const_udelay);
20577 +EXPORT_SYMBOL(__udelay);
20578 +EXPORT_SYMBOL(sys_waitpid);
20579 +EXPORT_SYMBOL(task_size);
20580 +EXPORT_SYMBOL(flush_tlb_range);
20581 +EXPORT_SYMBOL(host_task_size);
20582 +EXPORT_SYMBOL(arch_validate);
20583 +EXPORT_SYMBOL(get_kmem_end);
20585 +EXPORT_SYMBOL(high_physmem);
20586 +EXPORT_SYMBOL(empty_zero_page);
20587 +EXPORT_SYMBOL(um_virt_to_phys);
20588 +EXPORT_SYMBOL(__virt_to_page);
20589 +EXPORT_SYMBOL(to_phys);
20590 +EXPORT_SYMBOL(to_virt);
20591 +EXPORT_SYMBOL(mode_tt);
20592 +EXPORT_SYMBOL(handle_page_fault);
20594 +#ifdef CONFIG_MODE_TT
20595 +EXPORT_SYMBOL(copy_from_user_tt);
20596 +EXPORT_SYMBOL(copy_to_user_tt);
20599 +#ifdef CONFIG_MODE_SKAS
20600 +EXPORT_SYMBOL(copy_to_user_skas);
20601 +EXPORT_SYMBOL(copy_from_user_skas);
20604 +EXPORT_SYMBOL(os_stat_fd);
20605 +EXPORT_SYMBOL(os_stat_file);
20606 +EXPORT_SYMBOL(os_access);
20607 +EXPORT_SYMBOL(os_print_error);
20608 +EXPORT_SYMBOL(os_get_exec_close);
20609 +EXPORT_SYMBOL(os_set_exec_close);
20610 +EXPORT_SYMBOL(os_getpid);
20611 +EXPORT_SYMBOL(os_open_file);
20612 +EXPORT_SYMBOL(os_read_file);
20613 +EXPORT_SYMBOL(os_write_file);
20614 +EXPORT_SYMBOL(os_seek_file);
20615 +EXPORT_SYMBOL(os_lock_file);
20616 +EXPORT_SYMBOL(os_pipe);
20617 +EXPORT_SYMBOL(os_file_type);
20618 +EXPORT_SYMBOL(os_file_mode);
20619 +EXPORT_SYMBOL(os_file_size);
20620 +EXPORT_SYMBOL(os_flush_stdout);
20621 +EXPORT_SYMBOL(os_close_file);
20622 +EXPORT_SYMBOL(os_set_fd_async);
20623 +EXPORT_SYMBOL(os_set_fd_block);
20624 +EXPORT_SYMBOL(helper_wait);
20625 +EXPORT_SYMBOL(os_shutdown_socket);
20626 +EXPORT_SYMBOL(os_create_unix_socket);
20627 +EXPORT_SYMBOL(os_connect_socket);
20628 +EXPORT_SYMBOL(os_accept_connection);
20629 +EXPORT_SYMBOL(os_rcv_fd);
20630 +EXPORT_SYMBOL(run_helper);
20631 +EXPORT_SYMBOL(start_thread);
20632 +EXPORT_SYMBOL(dump_thread);
20634 +/* This is here because UML expands open to sys_open, not to a system
20635 + * call instruction.
20637 +EXPORT_SYMBOL(sys_open);
20638 +EXPORT_SYMBOL(sys_lseek);
20639 +EXPORT_SYMBOL(sys_read);
20640 +EXPORT_SYMBOL(sys_wait4);
20644 +/* required for SMP */
20646 +extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
20647 +EXPORT_SYMBOL_NOVERS(__write_lock_failed);
20649 +extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
20650 +EXPORT_SYMBOL_NOVERS(__read_lock_failed);
20652 +EXPORT_SYMBOL(kernel_flag_cacheline);
20653 +EXPORT_SYMBOL(smp_num_cpus);
20658 + * Overrides for Emacs so that we follow Linus's tabbing style.
20659 + * Emacs will notice this stuff at the end of the file and automatically
20660 + * adjust the settings for this buffer only. This must remain at the end
20662 + * ---------------------------------------------------------------------------
20663 + * Local variables:
20664 + * c-file-style: "linux"
20667 diff -Naur -X ../exclude-files orig/arch/um/kernel/Makefile um/arch/um/kernel/Makefile
20668 --- orig/arch/um/kernel/Makefile 1969-12-31 19:00:00.000000000 -0500
20669 +++ um/arch/um/kernel/Makefile 2003-10-21 03:26:06.000000000 -0400
20672 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
20673 +# Licensed under the GPL
20676 +O_TARGET = built-in.o
20678 +obj-y = config.o checksum.o exec_kern.o exitcode.o frame_kern.o frame.o \
20679 + helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \
20680 + physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
20681 + sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
20682 + syscall_kern.o syscall_user.o sysrq.o sys_call_table.o tempfile.o \
20683 + time.o time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o \
20684 + um_arch.o umid.o user_syms.o user_util.o
20686 +obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
20687 +obj-$(CONFIG_GPROF) += gprof_syms.o
20688 +obj-$(CONFIG_GCOV) += gmon_syms.o
20689 +obj-$(CONFIG_TTY_LOG) += tty_log.o
20691 +subdir-$(CONFIG_MODE_TT) += tt
20692 +subdir-$(CONFIG_MODE_SKAS) += skas
20694 +user-objs-$(CONFIG_TTY_LOG) += tty_log.o
20696 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
20698 +# user_syms.o not included here because Rules.make has its own ideas about
20699 +# building anything in export-objs
20701 +USER_OBJS = $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
20702 + process.o tempfile.o time.o umid.o user_util.o
20704 +DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__
20705 +DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__
20707 +export-objs-$(CONFIG_GPROF) += gprof_syms.o
20708 +export-objs-$(CONFIG_GCOV) += gmon_syms.o
20710 +export-objs = ksyms.o process_kern.o signal_kern.o user_syms.o $(export-objs-y)
20712 +CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \
20713 + -I/usr/include -I../include
20715 +CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
20717 +include $(TOPDIR)/Rules.make
20719 +$(USER_OBJS) : %.o: %.c
20720 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
20722 +# This has to be separate because it needs be compiled with frame pointers
20723 +# regardless of how the rest of the kernel is built.
20726 + $(CC) $(CFLAGS_$@) -c -o $@ $<
20728 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
20730 +config.c : config.c.in $(TOPDIR)/.config
20731 + $(PERL) -e $(QUOTE) < config.c.in > $@
20735 + for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
20743 +archmrproper: clean
20744 diff -Naur -X ../exclude-files orig/arch/um/kernel/mem.c um/arch/um/kernel/mem.c
20745 --- orig/arch/um/kernel/mem.c 1969-12-31 19:00:00.000000000 -0500
20746 +++ um/arch/um/kernel/mem.c 2003-11-13 23:26:35.000000000 -0500
20749 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
20750 + * Licensed under the GPL
20753 +#include "linux/stddef.h"
20754 +#include "linux/kernel.h"
20755 +#include "linux/mm.h"
20756 +#include "linux/bootmem.h"
20757 +#include "linux/highmem.h"
20758 +#include "asm/page.h"
20759 +#include "asm/fixmap.h"
20760 +#include "asm/pgalloc.h"
20761 +#include "user_util.h"
20762 +#include "kern_util.h"
20764 +#include "mem_user.h"
20765 +#include "uml_uaccess.h"
20768 +extern char __binary_start;
20770 +/* Changed during early boot */
20771 +unsigned long *empty_zero_page = NULL;
20772 +unsigned long *empty_bad_page = NULL;
20773 +pgd_t swapper_pg_dir[1024];
20774 +unsigned long highmem;
20775 +int kmalloc_ok = 0;
20777 +static unsigned long brk_end;
20778 +static unsigned long totalram_pages = 0;
20780 +void unmap_physmem(void)
20782 + os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
20785 +static void map_cb(void *unused)
20787 + map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
20790 +#ifdef CONFIG_HIGHMEM
20791 +static void setup_highmem(unsigned long highmem_start,
20792 + unsigned long highmem_len)
20794 + struct page *page;
20795 + unsigned long highmem_pfn;
20798 + highmem_start_page = virt_to_page(highmem_start);
20800 + highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT;
20801 + for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
20802 + page = &mem_map[highmem_pfn + i];
20803 + ClearPageReserved(page);
20804 + set_bit(PG_highmem, &page->flags);
20805 + atomic_set(&page->count, 1);
20806 + __free_page(page);
20811 +void mem_init(void)
20813 + unsigned long start;
20815 + /* clear the zero-page */
20816 + memset((void *) empty_zero_page, 0, PAGE_SIZE);
20818 + /* Map in the area just after the brk now that kmalloc is about
20819 + * to be turned on.
20821 + brk_end = (unsigned long) UML_ROUND_UP(sbrk(0));
20823 + initial_thread_cb(map_cb, NULL);
20824 + free_bootmem(__pa(brk_end), uml_reserved - brk_end);
20825 + uml_reserved = brk_end;
20827 + /* Fill in any hole at the start of the binary */
20828 + start = (unsigned long) &__binary_start;
20829 + if(uml_physmem != start){
20830 + map_memory(uml_physmem, __pa(uml_physmem), start - uml_physmem,
20834 + /* this will put all low memory onto the freelists */
20835 + totalram_pages = free_all_bootmem();
20836 + totalram_pages += highmem >> PAGE_SHIFT;
20837 + num_physpages = totalram_pages;
20838 + printk(KERN_INFO "Memory: %luk available\n",
20839 + (unsigned long) nr_free_pages() << (PAGE_SHIFT-10));
20842 +#ifdef CONFIG_HIGHMEM
20843 + setup_highmem(end_iomem, highmem);
20847 +static void __init fixrange_init(unsigned long start, unsigned long end,
20854 + unsigned long vaddr;
20857 + i = __pgd_offset(vaddr);
20858 + j = __pmd_offset(vaddr);
20859 + pgd = pgd_base + i;
20861 + for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
20862 + pmd = (pmd_t *)pgd;
20863 + for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
20864 + if (pmd_none(*pmd)) {
20865 + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
20866 + set_pmd(pmd, __pmd(_KERNPG_TABLE +
20867 + (unsigned long) __pa(pte)));
20868 + if (pte != pte_offset(pmd, 0))
20871 + vaddr += PMD_SIZE;
20877 +#if CONFIG_HIGHMEM
20879 +pgprot_t kmap_prot;
20881 +#define kmap_get_fixmap_pte(vaddr) \
20882 + pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
20884 +void __init kmap_init(void)
20886 + unsigned long kmap_vstart;
20888 + /* cache the first kmap pte */
20889 + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
20890 + kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
20892 + kmap_prot = PAGE_KERNEL;
20895 +static void init_highmem(void)
20900 + unsigned long vaddr;
20903 + * Permanent kmaps:
20905 + vaddr = PKMAP_BASE;
20906 + fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, swapper_pg_dir);
20908 + pgd = swapper_pg_dir + __pgd_offset(vaddr);
20909 + pmd = pmd_offset(pgd, vaddr);
20910 + pte = pte_offset(pmd, vaddr);
20911 + pkmap_page_table = pte;
20916 +#endif /* CONFIG_HIGHMEM */
20918 +void paging_init(void)
20920 + unsigned long zones_size[MAX_NR_ZONES], vaddr;
20923 + empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
20924 + empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
20925 + for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++)
20926 + zones_size[i] = 0;
20927 + zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
20928 + zones_size[2] = highmem >> PAGE_SHIFT;
20929 + free_area_init(zones_size);
20932 + * Fixed mappings, only the page table structure has to be
20933 + * created - mappings will be set by set_fixmap():
20935 + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
20936 + fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir);
20938 +#if CONFIG_HIGHMEM
20943 +struct page *arch_validate(struct page *page, int mask, int order)
20945 + unsigned long addr, zero = 0;
20949 + if(page == NULL) return(page);
20950 + if(PageHighMem(page)) return(page);
20952 + addr = (unsigned long) page_address(page);
20953 + for(i = 0; i < (1 << order); i++){
20954 + current->thread.fault_addr = (void *) addr;
20955 + if(__do_copy_to_user((void *) addr, &zero,
20957 + ¤t->thread.fault_addr,
20958 + ¤t->thread.fault_catcher)){
20959 + if(!(mask & __GFP_WAIT)) return(NULL);
20962 + addr += PAGE_SIZE;
20964 + if(i == (1 << order)) return(page);
20965 + page = _alloc_pages(mask, order);
20969 +/* This can't do anything because nothing in the kernel image can be freed
20970 + * since it's not in kernel physical memory.
20973 +void free_initmem(void)
20977 +#ifdef CONFIG_BLK_DEV_INITRD
20979 +void free_initrd_mem(unsigned long start, unsigned long end)
20982 + printk ("Freeing initrd memory: %ldk freed\n",
20983 + (end - start) >> 10);
20984 + for (; start < end; start += PAGE_SIZE) {
20985 + ClearPageReserved(virt_to_page(start));
20986 + set_page_count(virt_to_page(start), 1);
20987 + free_page(start);
20988 + totalram_pages++;
20994 +int do_check_pgt_cache(int low, int high)
20997 + if(pgtable_cache_size > high) {
20999 + if (pgd_quicklist) {
21000 + free_pgd_slow(get_pgd_fast());
21003 + if (pmd_quicklist) {
21004 + pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
21007 + if (pte_quicklist) {
21008 + pte_free_slow(pte_alloc_one_fast(NULL, 0));
21011 + } while(pgtable_cache_size > low);
21016 +void show_mem(void)
21018 + int i, total = 0, reserved = 0;
21019 + int shared = 0, cached = 0;
21022 + printk("Mem-info:\n");
21023 + show_free_areas();
21024 + printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
21028 + if(PageHighMem(mem_map + i))
21030 + if(PageReserved(mem_map + i))
21032 + else if(PageSwapCache(mem_map + i))
21034 + else if(page_count(mem_map + i))
21035 + shared += page_count(mem_map + i) - 1;
21037 + printk("%d pages of RAM\n", total);
21038 + printk("%d pages of HIGHMEM\n", highmem);
21039 + printk("%d reserved pages\n", reserved);
21040 + printk("%d pages shared\n", shared);
21041 + printk("%d pages swap cached\n", cached);
21042 + printk("%ld pages in page table cache\n", pgtable_cache_size);
21046 +/* Changed by meminfo_compat, which is a setup */
21047 +static int meminfo_22 = 0;
21049 +static int meminfo_compat(char *str)
21055 +__setup("22_meminfo", meminfo_compat);
21057 +void si_meminfo(struct sysinfo *val)
21059 + val->totalram = totalram_pages;
21060 + val->sharedram = 0;
21061 + val->freeram = nr_free_pages();
21062 + val->bufferram = atomic_read(&buffermem_pages);
21063 + val->totalhigh = highmem >> PAGE_SHIFT;
21064 + val->freehigh = nr_free_highpages();
21065 + val->mem_unit = PAGE_SIZE;
21067 + val->freeram <<= PAGE_SHIFT;
21068 + val->bufferram <<= PAGE_SHIFT;
21069 + val->totalram <<= PAGE_SHIFT;
21070 + val->sharedram <<= PAGE_SHIFT;
21075 + * Overrides for Emacs so that we follow Linus's tabbing style.
21076 + * Emacs will notice this stuff at the end of the file and automatically
21077 + * adjust the settings for this buffer only. This must remain at the end
21079 + * ---------------------------------------------------------------------------
21080 + * Local variables:
21081 + * c-file-style: "linux"
21084 diff -Naur -X ../exclude-files orig/arch/um/kernel/mem_user.c um/arch/um/kernel/mem_user.c
21085 --- orig/arch/um/kernel/mem_user.c 1969-12-31 19:00:00.000000000 -0500
21086 +++ um/arch/um/kernel/mem_user.c 2003-12-14 11:30:57.000000000 -0500
21089 + * arch/um/kernel/mem_user.c
21091 + * BRIEF MODULE DESCRIPTION
21092 + * user side memory routines for supporting IO memory inside user mode linux
21094 + * Copyright (C) 2001 RidgeRun, Inc.
21095 + * Author: RidgeRun, Inc.
21096 + * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
21098 + * This program is free software; you can redistribute it and/or modify it
21099 + * under the terms of the GNU General Public License as published by the
21100 + * Free Software Foundation; either version 2 of the License, or (at your
21101 + * option) any later version.
21103 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
21104 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21105 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
21106 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21107 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21108 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
21109 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21110 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21111 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21112 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21114 + * You should have received a copy of the GNU General Public License along
21115 + * with this program; if not, write to the Free Software Foundation, Inc.,
21116 + * 675 Mass Ave, Cambridge, MA 02139, USA.
21119 +#include <stdio.h>
21120 +#include <stdlib.h>
21121 +#include <stddef.h>
21122 +#include <stdarg.h>
21123 +#include <unistd.h>
21124 +#include <errno.h>
21125 +#include <string.h>
21126 +#include <fcntl.h>
21127 +#include <sys/types.h>
21128 +#include <sys/mman.h>
21129 +#include "kern_util.h"
21131 +#include "user_util.h"
21132 +#include "mem_user.h"
21135 +#include "tempfile.h"
21136 +#include "kern_constants.h"
21138 +extern struct mem_region physmem_region;
21140 +#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
21142 +static int create_tmp_file(unsigned long len)
21147 + fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
21149 + os_print_error(fd, "make_tempfile");
21153 + err = os_mode_fd(fd, 0777);
21155 + os_print_error(err, "os_mode_fd");
21158 + err = os_seek_file(fd, len);
21160 + os_print_error(err, "os_seek_file");
21164 + err = os_write_file(fd, &zero, 1);
21166 + os_print_error(err, "os_write_file");
21173 +static int have_devanon = 0;
21175 +void check_devanon(void)
21179 + printk("Checking for /dev/anon on the host...");
21180 + fd = open("/dev/anon", O_RDWR);
21182 + printk("Not available (open failed with errno %d)\n", errno);
21187 + have_devanon = 1;
21190 +static int create_anon_file(unsigned long len)
21195 + fd = open("/dev/anon", O_RDWR);
21197 + os_print_error(fd, "opening /dev/anon");
21201 + addr = mmap(NULL, len, PROT_READ | PROT_WRITE , MAP_PRIVATE, fd, 0);
21202 + if(addr == MAP_FAILED){
21203 + os_print_error((int) addr, "mapping physmem file");
21206 + munmap(addr, len);
21211 +int create_mem_file(unsigned long len)
21216 + fd = create_anon_file(len);
21217 + else fd = create_tmp_file(len);
21219 + err = os_set_exec_close(fd, 1);
21221 + os_print_error(err, "exec_close");
21225 +struct iomem_region *iomem_regions = NULL;
21226 +int iomem_size = 0;
21228 +static int __init parse_iomem(char *str, int *add)
21230 + struct iomem_region *new;
21231 + struct uml_stat buf;
21232 + char *file, *driver;
21236 + file = strchr(str,',');
21237 + if(file == NULL){
21238 + printf("parse_iomem : failed to parse iomem\n");
21243 + fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
21245 + os_print_error(fd, "parse_iomem - Couldn't open io file");
21248 + err = os_stat_fd(fd, &buf);
21250 + os_print_error(err, "parse_iomem - cannot stat_fd file");
21254 + new = malloc(sizeof(*new));
21256 + perror("Couldn't allocate iomem_region struct");
21260 + *new = ((struct iomem_region) { .next = iomem_regions,
21261 + .driver = driver,
21263 + .size = buf.ust_size,
21266 + iomem_regions = new;
21267 + iomem_size += new->size + UM_KERN_PAGE_SIZE;
21271 + os_close_file(fd);
21276 +__uml_setup("iomem=", parse_iomem,
21277 +"iomem=<name>,<file>\n"
21278 +" Configure <file> as an IO memory region named <name>.\n\n"
21281 +int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
21282 + int must_succeed)
21286 + err = os_protect_memory((void *) addr, len, r, w, x);
21289 + panic("protect failed, err = %d", -err);
21290 + else return(err);
21296 + * Overrides for Emacs so that we follow Linus's tabbing style.
21297 + * Emacs will notice this stuff at the end of the file and automatically
21298 + * adjust the settings for this buffer only. This must remain at the end
21300 + * ---------------------------------------------------------------------------
21301 + * Local variables:
21302 + * c-file-style: "linux"
21305 diff -Naur -X ../exclude-files orig/arch/um/kernel/mprot.h um/arch/um/kernel/mprot.h
21306 --- orig/arch/um/kernel/mprot.h 1969-12-31 19:00:00.000000000 -0500
21307 +++ um/arch/um/kernel/mprot.h 2003-10-21 03:26:06.000000000 -0400
21309 +#ifndef __MPROT_H__
21310 +#define __MPROT_H__
21312 +extern void no_access(unsigned long addr, unsigned int len);
21315 diff -Naur -X ../exclude-files orig/arch/um/kernel/physmem.c um/arch/um/kernel/physmem.c
21316 --- orig/arch/um/kernel/physmem.c 1969-12-31 19:00:00.000000000 -0500
21317 +++ um/arch/um/kernel/physmem.c 2003-11-14 02:59:20.000000000 -0500
21320 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
21321 + * Licensed under the GPL
21324 +#include "linux/mm.h"
21325 +#include "linux/ghash.h"
21326 +#include "linux/slab.h"
21327 +#include "linux/vmalloc.h"
21328 +#include "linux/bootmem.h"
21329 +#include "asm/types.h"
21330 +#include "asm/pgtable.h"
21331 +#include "kern_util.h"
21332 +#include "user_util.h"
21333 +#include "mode_kern.h"
21335 +#include "mem_user.h"
21340 +#define PHYS_HASHSIZE (8192)
21344 +DEF_HASH_STRUCTS(virtmem, PHYS_HASHSIZE, struct phys_desc);
21346 +struct phys_desc {
21347 + struct virtmem_ptrs virt_ptrs;
21351 + unsigned long phys;
21354 +struct virtmem_table virtmem_hash;
21356 +static int virt_cmp(void *virt1, void *virt2)
21358 + return(virt1 != virt2);
21361 +static int virt_hash(void *virt)
21363 + unsigned long addr = ((unsigned long) virt) >> PAGE_SHIFT;
21364 + return(addr % PHYS_HASHSIZE);
21367 +DEF_HASH(static, virtmem, struct phys_desc, virt_ptrs, void *, virt, virt_cmp,
21370 +int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
21372 + struct phys_desc *desc;
21373 + unsigned long phys;
21376 + virt = (void *) ((unsigned long) virt & PAGE_MASK);
21377 + err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
21381 + phys = __pa(virt);
21382 + if(find_virtmem_hash(&virtmem_hash, virt) != NULL)
21383 + panic("Address 0x%p is already substituted\n", virt);
21386 + desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
21390 + *desc = ((struct phys_desc) { .virt_ptrs = { NULL, NULL },
21392 + .offset = offset,
21394 + .phys = __pa(virt) });
21395 + insert_virtmem_hash(&virtmem_hash, desc);
21401 +static int physmem_fd = -1;
21403 +int physmem_remove_mapping(void *virt)
21405 + struct phys_desc *desc;
21408 + virt = (void *) ((unsigned long) virt & PAGE_MASK);
21409 + desc = find_virtmem_hash(&virtmem_hash, virt);
21413 + remove_virtmem_hash(&virtmem_hash, desc);
21416 + err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
21418 + panic("Failed to unmap block device page from physical memory, "
21419 + "errno = %d", -err);
21423 +void arch_free_page(struct page *page, int order)
21428 + for(i = 0; i < 1 << order; i++){
21429 + virt = __va(page_to_phys(page + i));
21430 + physmem_remove_mapping(virt);
21434 +int is_remapped(void *virt)
21436 + return(find_virtmem_hash(&virtmem_hash, virt) != NULL);
21439 +/* Changed during early boot */
21440 +unsigned long high_physmem;
21442 +extern unsigned long physmem_size;
21444 +void *to_virt(unsigned long phys)
21446 + return((void *) uml_physmem + phys);
21449 +unsigned long to_phys(void *virt)
21451 + return(((unsigned long) virt) - uml_physmem);
21454 +int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
21456 + struct page *p, *map;
21457 + unsigned long phys_len, phys_pages, highmem_len, highmem_pages;
21458 + unsigned long iomem_len, iomem_pages, total_len, total_pages;
21461 + phys_pages = physmem >> PAGE_SHIFT;
21462 + phys_len = phys_pages * sizeof(struct page);
21464 + iomem_pages = iomem >> PAGE_SHIFT;
21465 + iomem_len = iomem_pages * sizeof(struct page);
21467 + highmem_pages = highmem >> PAGE_SHIFT;
21468 + highmem_len = highmem_pages * sizeof(struct page);
21470 + total_pages = phys_pages + iomem_pages + highmem_pages;
21471 + total_len = phys_len + iomem_pages + highmem_len;
21474 + map = kmalloc(total_len, GFP_KERNEL);
21476 + map = vmalloc(total_len);
21478 + else map = alloc_bootmem_low_pages(total_len);
21483 + for(i = 0; i < total_pages; i++){
21485 + set_page_count(p, 0);
21486 + SetPageReserved(p);
21487 + INIT_LIST_HEAD(&p->list);
21491 + max_mapnr = total_pages;
21495 +struct page *phys_to_page(const unsigned long phys)
21497 + return(&mem_map[phys >> PAGE_SHIFT]);
21500 +struct page *__virt_to_page(const unsigned long virt)
21502 + return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
21505 +unsigned long page_to_phys(struct page *page)
21507 + return((page - mem_map) << PAGE_SHIFT);
21510 +pte_t mk_pte(struct page *page, pgprot_t pgprot)
21514 + pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot);
21515 + if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte));
21519 +/* Changed during early boot */
21520 +static unsigned long kmem_top = 0;
21522 +unsigned long get_kmem_end(void)
21524 + if(kmem_top == 0)
21525 + kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
21526 + return(kmem_top);
21529 +void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
21530 + int r, int w, int x)
21535 + fd = phys_mapping(phys, &offset);
21536 + err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
21538 + panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, "
21539 + "err = %d\n", virt, fd, offset, len, r, w, x, err);
21542 +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
21544 +void setup_physmem(unsigned long start, unsigned long reserve_end,
21545 + unsigned long len, unsigned long highmem)
21547 + unsigned long reserve = reserve_end - start;
21548 + int pfn = PFN_UP(__pa(reserve_end));
21549 + int delta = (len - reserve) >> PAGE_SHIFT;
21550 + int err, offset, bootmap_size;
21552 + physmem_fd = create_mem_file(len + highmem);
21554 + offset = uml_reserved - uml_physmem;
21555 + err = os_map_memory((void *) uml_reserved, physmem_fd, offset,
21556 + len - offset, 1, 1, 0);
21558 + os_print_error(err, "Mapping memory");
21562 + bootmap_size = init_bootmem(pfn, pfn + delta);
21563 + free_bootmem(__pa(reserve_end) + bootmap_size,
21564 + len - bootmap_size - reserve);
21567 +int phys_mapping(unsigned long phys, __u64 *offset_out)
21569 + struct phys_desc *desc = find_virtmem_hash(&virtmem_hash,
21570 + __va(phys & PAGE_MASK));
21573 + if(desc != NULL){
21575 + *offset_out = desc->offset;
21577 + else if(phys < physmem_size){
21579 + *offset_out = phys;
21581 + else if(phys < __pa(end_iomem)){
21582 + struct iomem_region *region = iomem_regions;
21584 + while(region != NULL){
21585 + if((phys >= region->phys) &&
21586 + (phys < region->phys + region->size)){
21588 + *offset_out = phys - region->phys;
21591 + region = region->next;
21594 + else if(phys < __pa(end_iomem) + highmem){
21596 + *offset_out = phys - iomem_size;
21602 +static int __init uml_mem_setup(char *line, int *add)
21605 + physmem_size = memparse(line,&retptr);
21608 +__uml_setup("mem=", uml_mem_setup,
21609 +"mem=<Amount of desired ram>\n"
21610 +" This controls how much \"physical\" memory the kernel allocates\n"
21611 +" for the system. The size is specified as a number followed by\n"
21612 +" one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
21613 +" This is not related to the amount of memory in the host. It can\n"
21614 +" be more, and the excess, if it's ever used, will just be swapped out.\n"
21615 +" Example: mem=64M\n\n"
21618 +unsigned long find_iomem(char *driver, unsigned long *len_out)
21620 + struct iomem_region *region = iomem_regions;
21622 + while(region != NULL){
21623 + if(!strcmp(region->driver, driver)){
21624 + *len_out = region->size;
21625 + return(region->virt);
21632 +int setup_iomem(void)
21634 + struct iomem_region *region = iomem_regions;
21635 + unsigned long iomem_start = high_physmem + PAGE_SIZE;
21638 + while(region != NULL){
21639 + err = os_map_memory((void *) iomem_start, region->fd, 0,
21640 + region->size, 1, 1, 0);
21642 + printk("Mapping iomem region for driver '%s' failed, "
21643 + "errno = %d\n", region->driver, -err);
21645 + region->virt = iomem_start;
21646 + region->phys = __pa(region->virt);
21649 + iomem_start += region->size + PAGE_SIZE;
21650 + region = region->next;
21656 +__initcall(setup_iomem);
21659 + * Overrides for Emacs so that we follow Linus's tabbing style.
21660 + * Emacs will notice this stuff at the end of the file and automatically
21661 + * adjust the settings for this buffer only. This must remain at the end
21663 + * ---------------------------------------------------------------------------
21664 + * Local variables:
21665 + * c-file-style: "linux"
21668 diff -Naur -X ../exclude-files orig/arch/um/kernel/process.c um/arch/um/kernel/process.c
21669 --- orig/arch/um/kernel/process.c 1969-12-31 19:00:00.000000000 -0500
21670 +++ um/arch/um/kernel/process.c 2003-11-07 02:09:21.000000000 -0500
21673 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
21674 + * Licensed under the GPL
21677 +#include <stdio.h>
21678 +#include <unistd.h>
21679 +#include <signal.h>
21680 +#include <sched.h>
21681 +#include <errno.h>
21682 +#include <stdarg.h>
21683 +#include <stdlib.h>
21684 +#include <setjmp.h>
21685 +#include <sys/time.h>
21686 +#include <sys/ptrace.h>
21687 +#include <sys/wait.h>
21688 +#include <sys/mman.h>
21689 +#include <asm/ptrace.h>
21690 +#include <asm/sigcontext.h>
21691 +#include <asm/unistd.h>
21692 +#include <asm/page.h>
21693 +#include "user_util.h"
21694 +#include "kern_util.h"
21696 +#include "process.h"
21697 +#include "signal_kern.h"
21698 +#include "signal_user.h"
21699 +#include "sysdep/ptrace.h"
21700 +#include "sysdep/sigcontext.h"
21701 +#include "irq_user.h"
21702 +#include "ptrace_user.h"
21703 +#include "time_user.h"
21706 +#include "uml-config.h"
21707 +#include "choose-mode.h"
21709 +#ifdef UML_CONFIG_MODE_SKAS
21711 +#include "skas_ptrace.h"
21714 +void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
21716 + int flags = 0, pages;
21718 + if(sig_stack != NULL){
21719 + pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
21720 + set_sigstack(sig_stack, pages * page_size());
21721 + flags = SA_ONSTACK;
21723 + if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
21726 +void init_new_thread_signals(int altstack)
21728 + int flags = altstack ? SA_ONSTACK : 0;
21730 + /* NODEFER is set here because SEGV isn't turned back on when the
21731 + * handler is ready to receive signals. This causes any segfault
21732 + * during a copy_user to kill the process because the fault is blocked.
21734 + set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags | SA_NODEFER,
21735 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21736 + set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags,
21737 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21738 + set_handler(SIGFPE, (__sighandler_t) sig_handler, flags,
21739 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21740 + set_handler(SIGILL, (__sighandler_t) sig_handler, flags,
21741 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21742 + set_handler(SIGBUS, (__sighandler_t) sig_handler, flags,
21743 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21744 + set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags,
21745 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21746 + set_handler(SIGUSR2, (__sighandler_t) sig_handler,
21747 + SA_NOMASK | flags, -1);
21748 + signal(SIGHUP, SIG_IGN);
21750 + init_irq_signals(altstack);
21754 + int (*tramp)(void *);
21755 + void *tramp_data;
21756 + unsigned long temp_stack;
21761 +/* See above for why sigkill is here */
21763 +int sigkill = SIGKILL;
21765 +int outer_tramp(void *arg)
21768 + int sig = sigkill;
21771 + t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2,
21772 + t->flags, t->tramp_data);
21773 + if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
21774 + kill(os_getpid(), sig);
21778 +int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
21779 + int clone_flags, int (*tramp)(void *))
21781 + struct tramp arg;
21782 + unsigned long sp;
21783 + int new_pid, status, err;
21785 + /* The trampoline will run on the temporary stack */
21786 + sp = stack_sp(temp_stack);
21788 + clone_flags |= CLONE_FILES | SIGCHLD;
21790 + arg.tramp = tramp;
21791 + arg.tramp_data = thread_arg;
21792 + arg.temp_stack = temp_stack;
21793 + arg.flags = clone_flags;
21795 + /* Start the process and wait for it to kill itself */
21796 + new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
21797 + if(new_pid < 0) return(-errno);
21798 + while(((err = waitpid(new_pid, &status, 0)) < 0) && (errno == EINTR)) ;
21799 + if(err < 0) panic("Waiting for outer trampoline failed - errno = %d",
21801 + if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
21802 + panic("outer trampoline didn't exit with SIGKILL");
21807 +void suspend_new_thread(int fd)
21811 + os_stop_process(os_getpid());
21813 + if(os_read_file(fd, &c, sizeof(c)) != sizeof(c))
21814 + panic("read failed in suspend_new_thread");
21817 +static int ptrace_child(void *arg)
21819 + int pid = os_getpid();
21821 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
21822 + perror("ptrace");
21823 + os_kill_process(pid, 0);
21825 + os_stop_process(pid);
21826 + _exit(os_getpid() == pid);
21829 +static int start_ptraced_child(void **stack_out)
21832 + unsigned long sp;
21833 + int pid, n, status;
21835 + stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
21836 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
21837 + if(stack == MAP_FAILED)
21838 + panic("check_ptrace : mmap failed, errno = %d", errno);
21839 + sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
21840 + pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
21842 + panic("check_ptrace : clone failed, errno = %d", errno);
21843 + n = waitpid(pid, &status, WUNTRACED);
21845 + panic("check_ptrace : wait failed, errno = %d", errno);
21846 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
21847 + panic("check_ptrace : expected SIGSTOP, got status = %d",
21850 + *stack_out = stack;
21854 +static void stop_ptraced_child(int pid, void *stack, int exitcode)
21858 + if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
21859 + panic("check_ptrace : ptrace failed, errno = %d", errno);
21860 + n = waitpid(pid, &status, 0);
21861 + if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode))
21862 + panic("check_ptrace : child exited with status 0x%x", status);
21864 + if(munmap(stack, PAGE_SIZE) < 0)
21865 + panic("check_ptrace : munmap failed, errno = %d", errno);
21868 +void __init check_ptrace(void)
21871 + int pid, syscall, n, status;
21873 + printk("Checking that ptrace can change system call numbers...");
21874 + pid = start_ptraced_child(&stack);
21877 + if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
21878 + panic("check_ptrace : ptrace failed, errno = %d",
21880 + n = waitpid(pid, &status, WUNTRACED);
21882 + panic("check_ptrace : wait failed, errno = %d", errno);
21883 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
21884 + panic("check_ptrace : expected SIGTRAP, "
21885 + "got status = %d", status);
21887 + syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET,
21889 + if(syscall == __NR_getpid){
21890 + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
21893 + panic("check_ptrace : failed to modify system "
21894 + "call, errno = %d", errno);
21898 + stop_ptraced_child(pid, stack, 0);
21902 +int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
21908 + n = sigsetjmp(buf, 1);
21915 +int can_do_skas(void)
21917 +#ifdef UML_CONFIG_MODE_SKAS
21918 + struct ptrace_faultinfo fi;
21920 + int pid, n, ret = 1;
21922 + printf("Checking for the skas3 patch in the host...");
21923 + pid = start_ptraced_child(&stack);
21925 + n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
21928 + printf("not found\n");
21929 + else printf("No (unexpected errno - %d)\n", errno);
21932 + else printf("found\n");
21934 + init_registers(pid);
21935 + stop_ptraced_child(pid, stack, 1);
21937 + printf("Checking for /proc/mm...");
21938 + if(os_access("/proc/mm", OS_ACC_W_OK) < 0){
21939 + printf("not found\n");
21942 + else printf("found\n");
21951 + * Overrides for Emacs so that we follow Linus's tabbing style.
21952 + * Emacs will notice this stuff at the end of the file and automatically
21953 + * adjust the settings for this buffer only. This must remain at the end
21955 + * ---------------------------------------------------------------------------
21956 + * Local variables:
21957 + * c-file-style: "linux"
21960 diff -Naur -X ../exclude-files orig/arch/um/kernel/process_kern.c um/arch/um/kernel/process_kern.c
21961 --- orig/arch/um/kernel/process_kern.c 1969-12-31 19:00:00.000000000 -0500
21962 +++ um/arch/um/kernel/process_kern.c 2003-11-08 08:37:04.000000000 -0500
21965 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
21966 + * Licensed under the GPL
21969 +#include "linux/config.h"
21970 +#include "linux/kernel.h"
21971 +#include "linux/sched.h"
21972 +#include "linux/interrupt.h"
21973 +#include "linux/mm.h"
21974 +#include "linux/slab.h"
21975 +#include "linux/utsname.h"
21976 +#include "linux/fs.h"
21977 +#include "linux/utime.h"
21978 +#include "linux/smp_lock.h"
21979 +#include "linux/module.h"
21980 +#include "linux/init.h"
21981 +#include "linux/capability.h"
21982 +#include "asm/unistd.h"
21983 +#include "asm/mman.h"
21984 +#include "asm/segment.h"
21985 +#include "asm/stat.h"
21986 +#include "asm/pgtable.h"
21987 +#include "asm/processor.h"
21988 +#include "asm/pgalloc.h"
21989 +#include "asm/spinlock.h"
21990 +#include "asm/uaccess.h"
21991 +#include "asm/user.h"
21992 +#include "user_util.h"
21993 +#include "kern_util.h"
21995 +#include "signal_kern.h"
21996 +#include "signal_user.h"
21998 +#include "irq_user.h"
21999 +#include "mem_user.h"
22000 +#include "time_user.h"
22002 +#include "frame_kern.h"
22003 +#include "sigcontext.h"
22004 +#include "2_5compat.h"
22007 +#include "mode_kern.h"
22008 +#include "choose-mode.h"
22010 +/* This is a per-cpu array. A processor only modifies its entry and it only
22011 + * cares about its entry, so it's OK if another processor is modifying its
22014 +struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
22016 +struct task_struct *get_task(int pid, int require)
22018 + struct task_struct *ret;
22020 + read_lock(&tasklist_lock);
22021 + ret = find_task_by_pid(pid);
22022 + read_unlock(&tasklist_lock);
22024 + if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
22028 +int external_pid(void *t)
22030 + struct task_struct *task = t ? t : current;
22032 + return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
22035 +int pid_to_processor_id(int pid)
22039 + for(i = 0; i < smp_num_cpus; i++){
22040 + if(cpu_tasks[i].pid == pid) return(i);
22045 +void free_stack(unsigned long stack, int order)
22047 + free_pages(stack, order);
22050 +unsigned long alloc_stack(int order, int atomic)
22052 + unsigned long page;
22053 + int flags = GFP_KERNEL;
22055 + if(atomic) flags |= GFP_ATOMIC;
22056 + page = __get_free_pages(flags, order);
22059 + stack_protections(page);
22063 +int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
22067 + current->thread.request.u.thread.proc = fn;
22068 + current->thread.request.u.thread.arg = arg;
22069 + pid = do_fork(CLONE_VM | flags, 0, NULL, 0);
22070 +#if 0 /* CLONE_UNTRACED for 2.6 */
22071 + pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0);
22074 + panic("do_fork failed in kernel_thread, errno = %d", pid);
22078 +void switch_mm(struct mm_struct *prev, struct mm_struct *next,
22079 + struct task_struct *tsk, unsigned cpu)
22081 + if (prev != next)
22082 + clear_bit(cpu, &prev->cpu_vm_mask);
22083 + set_bit(cpu, &next->cpu_vm_mask);
22086 +void set_current(void *t)
22088 + struct task_struct *task = t;
22090 + cpu_tasks[task->processor] = ((struct cpu_task)
22091 + { external_pid(task), task });
22094 +void *_switch_to(void *prev, void *next)
22096 + return(CHOOSE_MODE(_switch_to_tt(prev, next),
22097 + _switch_to_skas(prev, next)));
22100 +void interrupt_end(void)
22102 + if(current->need_resched) schedule();
22103 + if(current->sigpending != 0) do_signal(0);
22106 +void release_thread(struct task_struct *task)
22108 + CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
22111 +void exit_thread(void)
22113 + CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
22114 + unprotect_stack((unsigned long) current);
22117 +void *get_current(void)
22122 +int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
22123 + unsigned long stack_top, struct task_struct * p,
22124 + struct pt_regs *regs)
22126 + p->thread = (struct thread_struct) INIT_THREAD;
22127 + p->thread.kernel_stack = (unsigned long) p + 2 * PAGE_SIZE;
22129 + return(CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr,
22130 + clone_flags, sp, stack_top, p, regs));
22133 +void initial_thread_cb(void (*proc)(void *), void *arg)
22135 + int save_kmalloc_ok = kmalloc_ok;
22138 + CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc,
22140 + kmalloc_ok = save_kmalloc_ok;
22143 +unsigned long stack_sp(unsigned long page)
22145 + return(page + PAGE_SIZE - sizeof(void *));
22148 +int current_pid(void)
22150 + return(current->pid);
22153 +void cpu_idle(void)
22155 + CHOOSE_MODE(init_idle_tt(), init_idle_skas());
22157 + atomic_inc(&init_mm.mm_count);
22158 + current->mm = &init_mm;
22159 + current->active_mm = &init_mm;
22162 + /* endless idle loop with no priority at all */
22163 + SET_PRI(current);
22166 + * although we are an idle CPU, we do not want to
22167 + * get into the scheduler unnecessarily.
22169 + if (current->need_resched) {
22171 + check_pgt_cache();
22177 +int page_size(void)
22179 + return(PAGE_SIZE);
22182 +int page_mask(void)
22184 + return(PAGE_MASK);
22187 +void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
22194 + if(task->mm == NULL)
22195 + return(ERR_PTR(-EINVAL));
22196 + pgd = pgd_offset(task->mm, addr);
22197 + pmd = pmd_offset(pgd, addr);
22198 + if(!pmd_present(*pmd))
22199 + return(ERR_PTR(-EINVAL));
22200 + pte = pte_offset(pmd, addr);
22201 + if(!pte_present(*pte))
22202 + return(ERR_PTR(-EINVAL));
22203 + if(pte_out != NULL)
22205 + return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK));
22208 +char *current_cmd(void)
22210 +#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
22211 + return("(Unknown)");
22213 + void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
22214 + return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
22218 +void force_sigbus(void)
22220 + printk(KERN_ERR "Killing pid %d because of a lack of memory\n",
22223 + sigaddset(¤t->pending.signal, SIGBUS);
22224 + recalc_sigpending(current);
22225 + current->flags |= PF_SIGNALED;
22226 + do_exit(SIGBUS | 0x80);
22229 +void dump_thread(struct pt_regs *regs, struct user *u)
22233 +void enable_hlt(void)
22235 + panic("enable_hlt");
22238 +void disable_hlt(void)
22240 + panic("disable_hlt");
22243 +extern int signal_frame_size;
22245 +void *um_kmalloc(int size)
22247 + return(kmalloc(size, GFP_KERNEL));
22250 +void *um_kmalloc_atomic(int size)
22252 + return(kmalloc(size, GFP_ATOMIC));
22255 +unsigned long get_fault_addr(void)
22257 + return((unsigned long) current->thread.fault_addr);
22260 +EXPORT_SYMBOL(get_fault_addr);
22262 +void not_implemented(void)
22264 + printk(KERN_DEBUG "Something isn't implemented in here\n");
22267 +EXPORT_SYMBOL(not_implemented);
22269 +int user_context(unsigned long sp)
22271 + unsigned long stack;
22273 + stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
22274 + stack += 2 * PAGE_SIZE;
22275 + return(stack != current->thread.kernel_stack);
22278 +extern void remove_umid_dir(void);
22280 +__uml_exitcall(remove_umid_dir);
22282 +extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
22284 +void do_uml_exitcalls(void)
22286 + exitcall_t *call;
22288 + call = &__uml_exitcall_end;
22289 + while (--call >= &__uml_exitcall_begin)
22293 +char *uml_strdup(char *string)
22297 + new = kmalloc(strlen(string) + 1, GFP_KERNEL);
22298 + if(new == NULL) return(NULL);
22299 + strcpy(new, string);
22303 +void *get_init_task(void)
22305 + return(&init_task_union.task);
22308 +int copy_to_user_proc(void *to, void *from, int size)
22310 + return(copy_to_user(to, from, size));
22313 +int copy_from_user_proc(void *to, void *from, int size)
22315 + return(copy_from_user(to, from, size));
22318 +int clear_user_proc(void *buf, int size)
22320 + return(clear_user(buf, size));
22323 +int strlen_user_proc(char *str)
22325 + return(strlen_user(str));
22328 +int smp_sigio_handler(void)
22331 + int cpu = current->processor;
22333 + IPI_handler(cpu);
22340 +int um_in_interrupt(void)
22342 + return(in_interrupt());
22347 + return(current->processor);
22351 + * Overrides for Emacs so that we follow Linus's tabbing style.
22352 + * Emacs will notice this stuff at the end of the file and automatically
22353 + * adjust the settings for this buffer only. This must remain at the end
22355 + * ---------------------------------------------------------------------------
22356 + * Local variables:
22357 + * c-file-style: "linux"
22360 diff -Naur -X ../exclude-files orig/arch/um/kernel/ptrace.c um/arch/um/kernel/ptrace.c
22361 --- orig/arch/um/kernel/ptrace.c 1969-12-31 19:00:00.000000000 -0500
22362 +++ um/arch/um/kernel/ptrace.c 2003-10-21 03:26:06.000000000 -0400
22365 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
22366 + * Licensed under the GPL
22369 +#include "linux/sched.h"
22370 +#include "linux/mm.h"
22371 +#include "linux/errno.h"
22372 +#include "linux/smp_lock.h"
22373 +#ifdef CONFIG_PROC_MM
22374 +#include "linux/proc_mm.h"
22376 +#include "asm/ptrace.h"
22377 +#include "asm/uaccess.h"
22378 +#include "kern_util.h"
22379 +#include "ptrace_user.h"
22382 + * Called by kernel/ptrace.c when detaching..
22384 +void ptrace_disable(struct task_struct *child)
22388 +extern long do_mmap2(struct task_struct *task, unsigned long addr,
22389 + unsigned long len, unsigned long prot,
22390 + unsigned long flags, unsigned long fd,
22391 + unsigned long pgoff);
22393 +int sys_ptrace(long request, long pid, long addr, long data)
22395 + struct task_struct *child;
22400 + if (request == PTRACE_TRACEME) {
22401 + /* are we already being traced? */
22402 + if (current->ptrace & PT_PTRACED)
22404 + /* set the ptrace bit in the process flags. */
22405 + current->ptrace |= PT_PTRACED;
22410 + read_lock(&tasklist_lock);
22411 + child = find_task_by_pid(pid);
22413 + get_task_struct(child);
22414 + read_unlock(&tasklist_lock);
22419 + if (pid == 1) /* you may not mess with init */
22422 + if (request == PTRACE_ATTACH) {
22423 + ret = ptrace_attach(child);
22427 + ret = ptrace_check_attach(child, request == PTRACE_KILL);
22431 + switch (request) {
22432 + /* when I and D space are separate, these will need to be fixed. */
22433 + case PTRACE_PEEKTEXT: /* read word at location addr. */
22434 + case PTRACE_PEEKDATA: {
22435 + unsigned long tmp;
22439 + copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
22440 + if (copied != sizeof(tmp))
22442 + ret = put_user(tmp,(unsigned long *) data);
22446 + /* read the word at location addr in the USER area. */
22447 + case PTRACE_PEEKUSR: {
22448 + unsigned long tmp;
22451 + if ((addr & 3) || addr < 0)
22454 + tmp = 0; /* Default return condition */
22455 + if(addr < FRAME_SIZE_OFFSET){
22456 + tmp = getreg(child, addr);
22458 + else if((addr >= offsetof(struct user, u_debugreg[0])) &&
22459 + (addr <= offsetof(struct user, u_debugreg[7]))){
22460 + addr -= offsetof(struct user, u_debugreg[0]);
22461 + addr = addr >> 2;
22462 + tmp = child->thread.arch.debugregs[addr];
22464 + ret = put_user(tmp, (unsigned long *) data);
22468 + /* when I and D space are separate, this will have to be fixed. */
22469 + case PTRACE_POKETEXT: /* write the word at location addr. */
22470 + case PTRACE_POKEDATA:
22472 + if (access_process_vm(child, addr, &data, sizeof(data),
22473 + 1) != sizeof(data))
22478 + case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
22480 + if ((addr & 3) || addr < 0)
22483 + if (addr < FRAME_SIZE_OFFSET) {
22484 + ret = putreg(child, addr, data);
22487 + else if((addr >= offsetof(struct user, u_debugreg[0])) &&
22488 + (addr <= offsetof(struct user, u_debugreg[7]))){
22489 + addr -= offsetof(struct user, u_debugreg[0]);
22490 + addr = addr >> 2;
22491 + if((addr == 4) || (addr == 5)) break;
22492 + child->thread.arch.debugregs[addr] = data;
22498 + case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
22499 + case PTRACE_CONT: { /* restart after signal. */
22501 + if ((unsigned long) data > _NSIG)
22503 + if (request == PTRACE_SYSCALL)
22504 + child->ptrace |= PT_TRACESYS;
22506 + child->ptrace &= ~PT_TRACESYS;
22507 + child->exit_code = data;
22508 + wake_up_process(child);
22514 + * make the child exit. Best I can do is send it a sigkill.
22515 + * perhaps it should be put in the status that it wants to
22518 + case PTRACE_KILL: {
22520 + if (child->state == TASK_ZOMBIE) /* already dead */
22522 + child->exit_code = SIGKILL;
22523 + wake_up_process(child);
22527 + case PTRACE_SINGLESTEP: { /* set the trap flag. */
22529 + if ((unsigned long) data > _NSIG)
22531 + child->ptrace &= ~PT_TRACESYS;
22532 + child->ptrace |= PT_DTRACE;
22533 + child->exit_code = data;
22534 + /* give it a chance to run. */
22535 + wake_up_process(child);
22540 + case PTRACE_DETACH:
22541 + /* detach a process that was attached. */
22542 + ret = ptrace_detach(child, data);
22545 +#ifdef PTRACE_GETREGS
22546 + case PTRACE_GETREGS: { /* Get all gp regs from the child. */
22547 + if (!access_ok(VERIFY_WRITE, (unsigned long *)data,
22548 + FRAME_SIZE_OFFSET)) {
22552 + for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
22553 + __put_user(getreg(child, i), (unsigned long *) data);
22554 + data += sizeof(long);
22560 +#ifdef PTRACE_SETREGS
22561 + case PTRACE_SETREGS: { /* Set all gp regs in the child. */
22562 + unsigned long tmp = 0;
22563 + if (!access_ok(VERIFY_READ, (unsigned *)data,
22564 + FRAME_SIZE_OFFSET)) {
22568 + for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
22569 + __get_user(tmp, (unsigned long *) data);
22570 + putreg(child, i, tmp);
22571 + data += sizeof(long);
22577 +#ifdef PTRACE_GETFPREGS
22578 + case PTRACE_GETFPREGS: /* Get the child FPU state. */
22579 + ret = get_fpregs(data, child);
22582 +#ifdef PTRACE_SETFPREGS
22583 + case PTRACE_SETFPREGS: /* Set the child FPU state. */
22584 + ret = set_fpregs(data, child);
22587 +#ifdef PTRACE_GETFPXREGS
22588 + case PTRACE_GETFPXREGS: /* Get the child FPU state. */
22589 + ret = get_fpxregs(data, child);
22592 +#ifdef PTRACE_SETFPXREGS
22593 + case PTRACE_SETFPXREGS: /* Set the child FPU state. */
22594 + ret = set_fpxregs(data, child);
22597 + case PTRACE_FAULTINFO: {
22598 + struct ptrace_faultinfo fault;
22600 + fault = ((struct ptrace_faultinfo)
22601 + { .is_write = child->thread.err,
22602 + .addr = child->thread.cr2 });
22603 + ret = copy_to_user((unsigned long *) data, &fault,
22609 + case PTRACE_SIGPENDING:
22610 + ret = copy_to_user((unsigned long *) data,
22611 + &child->pending.signal,
22612 + sizeof(child->pending.signal));
22615 + case PTRACE_LDT: {
22616 + struct ptrace_ldt ldt;
22618 + if(copy_from_user(&ldt, (unsigned long *) data,
22624 + /* This one is confusing, so just punt and return -EIO for
22630 +#ifdef CONFIG_PROC_MM
22631 + case PTRACE_SWITCH_MM: {
22632 + struct mm_struct *old = child->mm;
22633 + struct mm_struct *new = proc_mm_get_mm(data);
22636 + ret = PTR_ERR(new);
22640 + atomic_inc(&new->mm_users);
22642 + child->active_mm = new;
22653 + free_task_struct(child);
22659 +void syscall_trace(void)
22661 + if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
22662 + != (PT_PTRACED|PT_TRACESYS))
22664 + current->exit_code = SIGTRAP;
22665 + current->state = TASK_STOPPED;
22666 + notify_parent(current, SIGCHLD);
22669 + * this isn't the same as continuing with a signal, but it will do
22670 + * for normal use. strace only continues with a signal if the
22671 + * stopping signal is not SIGTRAP. -brl
22673 + if (current->exit_code) {
22674 + send_sig(current->exit_code, current, 1);
22675 + current->exit_code = 0;
22680 + * Overrides for Emacs so that we follow Linus's tabbing style.
22681 + * Emacs will notice this stuff at the end of the file and automatically
22682 + * adjust the settings for this buffer only. This must remain at the end
22684 + * ---------------------------------------------------------------------------
22685 + * Local variables:
22686 + * c-file-style: "linux"
22689 diff -Naur -X ../exclude-files orig/arch/um/kernel/reboot.c um/arch/um/kernel/reboot.c
22690 --- orig/arch/um/kernel/reboot.c 1969-12-31 19:00:00.000000000 -0500
22691 +++ um/arch/um/kernel/reboot.c 2003-10-21 03:26:06.000000000 -0400
22694 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
22695 + * Licensed under the GPL
22698 +#include "linux/sched.h"
22699 +#include "user_util.h"
22700 +#include "kern_util.h"
22704 +#include "choose-mode.h"
22707 +static void kill_idlers(int me)
22709 +#ifdef CONFIG_MODE_TT
22710 + struct task_struct *p;
22713 + for(i = 0; i < sizeof(init_tasks)/sizeof(init_tasks[0]); i++){
22714 + p = init_tasks[i];
22715 + if((p != NULL) && (p->thread.mode.tt.extern_pid != me) &&
22716 + (p->thread.mode.tt.extern_pid != -1))
22717 + os_kill_process(p->thread.mode.tt.extern_pid, 0);
22723 +static void kill_off_processes(void)
22725 + CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas());
22727 + kill_idlers(os_getpid());
22731 +void uml_cleanup(void)
22733 + kill_off_processes();
22734 + do_uml_exitcalls();
22737 +void machine_restart(char * __unused)
22739 + do_uml_exitcalls();
22740 + kill_off_processes();
22741 + CHOOSE_MODE(reboot_tt(), reboot_skas());
22744 +void machine_power_off(void)
22746 + do_uml_exitcalls();
22747 + kill_off_processes();
22748 + CHOOSE_MODE(halt_tt(), halt_skas());
22751 +void machine_halt(void)
22753 + machine_power_off();
22757 + * Overrides for Emacs so that we follow Linus's tabbing style.
22758 + * Emacs will notice this stuff at the end of the file and automatically
22759 + * adjust the settings for this buffer only. This must remain at the end
22761 + * ---------------------------------------------------------------------------
22762 + * Local variables:
22763 + * c-file-style: "linux"
22766 diff -Naur -X ../exclude-files orig/arch/um/kernel/resource.c um/arch/um/kernel/resource.c
22767 --- orig/arch/um/kernel/resource.c 1969-12-31 19:00:00.000000000 -0500
22768 +++ um/arch/um/kernel/resource.c 2003-10-21 03:26:06.000000000 -0400
22771 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
22772 + * Licensed under the GPL
22775 +#include "linux/pci.h"
22777 +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
22778 + unsigned long start, unsigned long size)
22784 + * Overrides for Emacs so that we follow Linus's tabbing style.
22785 + * Emacs will notice this stuff at the end of the file and automatically
22786 + * adjust the settings for this buffer only. This must remain at the end
22788 + * ---------------------------------------------------------------------------
22789 + * Local variables:
22790 + * c-file-style: "linux"
22793 diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_kern.c um/arch/um/kernel/sigio_kern.c
22794 --- orig/arch/um/kernel/sigio_kern.c 1969-12-31 19:00:00.000000000 -0500
22795 +++ um/arch/um/kernel/sigio_kern.c 2003-10-21 03:26:07.000000000 -0400
22798 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22799 + * Licensed under the GPL
22802 +#include "linux/kernel.h"
22803 +#include "linux/list.h"
22804 +#include "linux/slab.h"
22805 +#include "asm/irq.h"
22807 +#include "sigio.h"
22808 +#include "irq_user.h"
22809 +#include "irq_kern.h"
22811 +/* Protected by sigio_lock() called from write_sigio_workaround */
22812 +static int sigio_irq_fd = -1;
22814 +void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
22816 + read_sigio_fd(sigio_irq_fd);
22817 + reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
22820 +int write_sigio_irq(int fd)
22822 + if(um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
22823 + SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio",
22825 + printk("write_sigio_irq : um_request_irq failed\n");
22828 + sigio_irq_fd = fd;
22832 +static spinlock_t sigio_spinlock = SPIN_LOCK_UNLOCKED;
22834 +void sigio_lock(void)
22836 + spin_lock(&sigio_spinlock);
22839 +void sigio_unlock(void)
22841 + spin_unlock(&sigio_spinlock);
22845 + * Overrides for Emacs so that we follow Linus's tabbing style.
22846 + * Emacs will notice this stuff at the end of the file and automatically
22847 + * adjust the settings for this buffer only. This must remain at the end
22849 + * ---------------------------------------------------------------------------
22850 + * Local variables:
22851 + * c-file-style: "linux"
22854 diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_user.c um/arch/um/kernel/sigio_user.c
22855 --- orig/arch/um/kernel/sigio_user.c 1969-12-31 19:00:00.000000000 -0500
22856 +++ um/arch/um/kernel/sigio_user.c 2003-11-07 01:41:13.000000000 -0500
22859 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22860 + * Licensed under the GPL
22863 +#include <unistd.h>
22864 +#include <stdlib.h>
22865 +#include <termios.h>
22867 +#include <signal.h>
22868 +#include <errno.h>
22869 +#include <string.h>
22870 +#include <sched.h>
22871 +#include <sys/socket.h>
22872 +#include <sys/poll.h>
22875 +#include "kern_util.h"
22876 +#include "sigio.h"
22877 +#include "helper.h"
22880 +/* Changed during early boot */
22881 +int pty_output_sigio = 0;
22882 +int pty_close_sigio = 0;
22884 +/* Used as a flag during SIGIO testing early in boot */
22885 +static volatile int got_sigio = 0;
22887 +void __init handler(int sig)
22892 +struct openpty_arg {
22898 +static void openpty_cb(void *arg)
22900 + struct openpty_arg *info = arg;
22903 + if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
22904 + info->err = -errno;
22907 +void __init check_one_sigio(void (*proc)(int, int))
22909 + struct sigaction old, new;
22910 + struct termios tt;
22911 + struct openpty_arg pty = { .master = -1, .slave = -1 };
22912 + int master, slave, err;
22914 + initial_thread_cb(openpty_cb, &pty);
22916 + printk("openpty failed, errno = %d\n", -pty.err);
22920 + master = pty.master;
22921 + slave = pty.slave;
22923 + if((master == -1) || (slave == -1)){
22924 + printk("openpty failed to allocate a pty\n");
22928 + /* XXX These can fail with EINTR */
22929 + if(tcgetattr(master, &tt) < 0)
22930 + panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
22932 + if(tcsetattr(master, TCSADRAIN, &tt) < 0)
22933 + panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
22935 + err = os_sigio_async(master, slave);
22937 + panic("tty_fds : sigio_async failed, err = %d\n", -err);
22939 + if(sigaction(SIGIO, NULL, &old) < 0)
22940 + panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
22942 + new.sa_handler = handler;
22943 + if(sigaction(SIGIO, &new, NULL) < 0)
22944 + panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
22947 + (*proc)(master, slave);
22949 + os_close_file(master);
22950 + os_close_file(slave);
22952 + if(sigaction(SIGIO, &old, NULL) < 0)
22953 + panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
22956 +static void tty_output(int master, int slave)
22961 + printk("Checking that host ptys support output SIGIO...");
22963 + memset(buf, 0, sizeof(buf));
22965 + while(os_write_file(master, buf, sizeof(buf)) > 0) ;
22966 + if(errno != EAGAIN)
22967 + panic("check_sigio : write failed, errno = %d\n", errno);
22968 + while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
22972 + pty_output_sigio = 1;
22974 + else if(n == -EAGAIN) printk("No, enabling workaround\n");
22975 + else panic("check_sigio : read failed, err = %d\n", n);
22978 +static void tty_close(int master, int slave)
22980 + printk("Checking that host ptys support SIGIO on close...");
22982 + os_close_file(slave);
22985 + pty_close_sigio = 1;
22987 + else printk("No, enabling workaround\n");
22990 +void __init check_sigio(void)
22992 + if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
22993 + (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
22994 + printk("No pseudo-terminals available - skipping pty SIGIO "
22998 + check_one_sigio(tty_output);
22999 + check_one_sigio(tty_close);
23002 +/* Protected by sigio_lock(), also used by sigio_cleanup, which is an
23005 +static int write_sigio_pid = -1;
23007 +/* These arrays are initialized before the sigio thread is started, and
23008 + * the descriptors closed after it is killed. So, it can't see them change.
23009 + * On the UML side, they are changed under the sigio_lock.
23011 +static int write_sigio_fds[2] = { -1, -1 };
23012 +static int sigio_private[2] = { -1, -1 };
23015 + struct pollfd *poll;
23020 +/* Protected by sigio_lock(). Used by the sigio thread, but the UML thread
23021 + * synchronizes with it.
23023 +struct pollfds current_poll = {
23029 +struct pollfds next_poll = {
23035 +static int write_sigio_thread(void *unused)
23037 + struct pollfds *fds, tmp;
23038 + struct pollfd *p;
23039 + int i, n, respond_fd;
23042 + fds = ¤t_poll;
23044 + n = poll(fds->poll, fds->used, -1);
23046 + if(errno == EINTR) continue;
23047 + printk("write_sigio_thread : poll returned %d, "
23048 + "errno = %d\n", n, errno);
23050 + for(i = 0; i < fds->used; i++){
23051 + p = &fds->poll[i];
23052 + if(p->revents == 0) continue;
23053 + if(p->fd == sigio_private[1]){
23054 + n = os_read_file(sigio_private[1], &c, sizeof(c));
23055 + if(n != sizeof(c))
23056 + printk("write_sigio_thread : "
23057 + "read failed, err = %d\n", -n);
23058 + tmp = current_poll;
23059 + current_poll = next_poll;
23061 + respond_fd = sigio_private[1];
23064 + respond_fd = write_sigio_fds[1];
23066 + memmove(&fds->poll[i], &fds->poll[i + 1],
23067 + (fds->used - i) * sizeof(*fds->poll));
23070 + n = os_write_file(respond_fd, &c, sizeof(c));
23071 + if(n != sizeof(c))
23072 + printk("write_sigio_thread : write failed, "
23073 + "err = %d\n", -n);
23078 +static int need_poll(int n)
23080 + if(n <= next_poll.size){
23081 + next_poll.used = n;
23084 + if(next_poll.poll != NULL) kfree(next_poll.poll);
23085 + next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
23086 + if(next_poll.poll == NULL){
23087 + printk("need_poll : failed to allocate new pollfds\n");
23088 + next_poll.size = 0;
23089 + next_poll.used = 0;
23092 + next_poll.size = n;
23093 + next_poll.used = n;
23097 +static void update_thread(void)
23099 + unsigned long flags;
23103 + flags = set_signals(0);
23104 + n = os_write_file(sigio_private[0], &c, sizeof(c));
23105 + if(n != sizeof(c)){
23106 + printk("update_thread : write failed, err = %d\n", -n);
23110 + n = os_read_file(sigio_private[0], &c, sizeof(c));
23111 + if(n != sizeof(c)){
23112 + printk("update_thread : read failed, err = %d\n", -n);
23116 + set_signals(flags);
23120 + if(write_sigio_pid != -1)
23121 + os_kill_process(write_sigio_pid, 1);
23122 + write_sigio_pid = -1;
23123 + os_close_file(sigio_private[0]);
23124 + os_close_file(sigio_private[1]);
23125 + os_close_file(write_sigio_fds[0]);
23126 + os_close_file(write_sigio_fds[1]);
23128 + set_signals(flags);
23131 +int add_sigio_fd(int fd, int read)
23133 + int err = 0, i, n, events;
23136 + for(i = 0; i < current_poll.used; i++){
23137 + if(current_poll.poll[i].fd == fd)
23141 + n = current_poll.used + 1;
23142 + err = need_poll(n);
23146 + for(i = 0; i < current_poll.used; i++)
23147 + next_poll.poll[i] = current_poll.poll[i];
23149 + if(read) events = POLLIN;
23150 + else events = POLLOUT;
23152 + next_poll.poll[n - 1] = ((struct pollfd) { .fd = fd,
23153 + .events = events,
23161 +int ignore_sigio_fd(int fd)
23163 + struct pollfd *p;
23164 + int err = 0, i, n = 0;
23167 + for(i = 0; i < current_poll.used; i++){
23168 + if(current_poll.poll[i].fd == fd) break;
23170 + if(i == current_poll.used)
23173 + err = need_poll(current_poll.used - 1);
23177 + for(i = 0; i < current_poll.used; i++){
23178 + p = ¤t_poll.poll[i];
23179 + if(p->fd != fd) next_poll.poll[n++] = current_poll.poll[i];
23182 + printk("ignore_sigio_fd : fd %d not found\n", fd);
23193 +static int setup_initial_poll(int fd)
23195 + struct pollfd *p;
23197 + p = um_kmalloc(sizeof(struct pollfd));
23199 + printk("setup_initial_poll : failed to allocate poll\n");
23202 + *p = ((struct pollfd) { .fd = fd,
23203 + .events = POLLIN,
23205 + current_poll = ((struct pollfds) { .poll = p,
23211 +void write_sigio_workaround(void)
23213 + unsigned long stack;
23217 + if(write_sigio_pid != -1)
23220 + err = os_pipe(write_sigio_fds, 1, 1);
23222 + printk("write_sigio_workaround - os_pipe 1 failed, "
23223 + "err = %d\n", -err);
23226 + err = os_pipe(sigio_private, 1, 1);
23228 + printk("write_sigio_workaround - os_pipe 2 failed, "
23229 + "err = %d\n", -err);
23232 + if(setup_initial_poll(sigio_private[1]))
23235 + write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
23236 + CLONE_FILES | CLONE_VM, &stack, 0);
23238 + if(write_sigio_pid < 0) goto out_close2;
23240 + if(write_sigio_irq(write_sigio_fds[0]))
23248 + os_kill_process(write_sigio_pid, 1);
23249 + write_sigio_pid = -1;
23251 + os_close_file(sigio_private[0]);
23252 + os_close_file(sigio_private[1]);
23254 + os_close_file(write_sigio_fds[0]);
23255 + os_close_file(write_sigio_fds[1]);
23259 +int read_sigio_fd(int fd)
23264 + n = os_read_file(fd, &c, sizeof(c));
23265 + if(n != sizeof(c)){
23267 + printk("read_sigio_fd - read failed, err = %d\n", -n);
23271 + printk("read_sigio_fd - short read, bytes = %d\n", n);
23278 +static void sigio_cleanup(void)
23280 + if(write_sigio_pid != -1)
23281 + os_kill_process(write_sigio_pid, 1);
23284 +__uml_exitcall(sigio_cleanup);
23287 + * Overrides for Emacs so that we follow Linus's tabbing style.
23288 + * Emacs will notice this stuff at the end of the file and automatically
23289 + * adjust the settings for this buffer only. This must remain at the end
23291 + * ---------------------------------------------------------------------------
23292 + * Local variables:
23293 + * c-file-style: "linux"
23296 diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_kern.c um/arch/um/kernel/signal_kern.c
23297 --- orig/arch/um/kernel/signal_kern.c 1969-12-31 19:00:00.000000000 -0500
23298 +++ um/arch/um/kernel/signal_kern.c 2003-11-19 03:50:58.000000000 -0500
23301 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
23302 + * Licensed under the GPL
23305 +#include "linux/config.h"
23306 +#include "linux/stddef.h"
23307 +#include "linux/sys.h"
23308 +#include "linux/sched.h"
23309 +#include "linux/wait.h"
23310 +#include "linux/kernel.h"
23311 +#include "linux/smp_lock.h"
23312 +#include "linux/module.h"
23313 +#include "linux/slab.h"
23314 +#include "asm/signal.h"
23315 +#include "asm/uaccess.h"
23316 +#include "asm/ucontext.h"
23317 +#include "user_util.h"
23318 +#include "kern_util.h"
23319 +#include "signal_kern.h"
23320 +#include "signal_user.h"
23322 +#include "frame_kern.h"
23323 +#include "sigcontext.h"
23326 +EXPORT_SYMBOL(block_signals);
23327 +EXPORT_SYMBOL(unblock_signals);
23329 +static void force_segv(int sig)
23331 + if(sig == SIGSEGV){
23332 + struct k_sigaction *ka;
23334 + ka = ¤t->sig->action[SIGSEGV - 1];
23335 + ka->sa.sa_handler = SIG_DFL;
23337 + force_sig(SIGSEGV, current);
23340 +#define _S(nr) (1<<((nr)-1))
23342 +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
23345 + * OK, we're invoking a handler
23347 +static int handle_signal(struct pt_regs *regs, unsigned long signr,
23348 + struct k_sigaction *ka, siginfo_t *info,
23349 + sigset_t *oldset, int error)
23351 + __sighandler_t handler;
23352 + void (*restorer)(void);
23353 + unsigned long sp;
23359 + case -ERESTARTNOHAND:
23363 + case -ERESTARTSYS:
23364 + if (!(ka->sa.sa_flags & SA_RESTART)) {
23368 + /* fallthrough */
23369 + case -ERESTARTNOINTR:
23370 + PT_REGS_RESTART_SYSCALL(regs);
23371 + PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
23373 + /* This is because of the UM_SET_SYSCALL_RETURN and the fact
23374 + * that on i386 the system call number and return value are
23375 + * in the same register. When the system call restarts, %eax
23376 + * had better have the system call number in it. Since the
23377 + * return value doesn't matter (except that it shouldn't be
23378 + * -ERESTART*), we'll stick the system call number there.
23380 + ret = PT_REGS_SYSCALL_NR(regs);
23384 + handler = ka->sa.sa_handler;
23387 + if (ka->sa.sa_flags & SA_ONESHOT)
23388 + ka->sa.sa_handler = SIG_DFL;
23390 + if (!(ka->sa.sa_flags & SA_NODEFER)) {
23391 + spin_lock_irq(¤t->sigmask_lock);
23392 + sigorsets(¤t->blocked, ¤t->blocked,
23393 + &ka->sa.sa_mask);
23394 + sigaddset(¤t->blocked, signr);
23395 + recalc_sigpending(current);
23396 + spin_unlock_irq(¤t->sigmask_lock);
23399 + sp = PT_REGS_SP(regs);
23401 + if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
23402 + sp = current->sas_ss_sp + current->sas_ss_size;
23404 + if(error != 0) PT_REGS_SET_SYSCALL_RETURN(regs, ret);
23406 + if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer;
23407 + else restorer = NULL;
23409 + if(ka->sa.sa_flags & SA_SIGINFO)
23410 + err = setup_signal_stack_si(sp, signr, (unsigned long) handler,
23411 + restorer, regs, info, &save);
23413 + err = setup_signal_stack_sc(sp, signr, (unsigned long) handler,
23414 + restorer, regs, &save);
23415 + if(err) goto segv;
23419 + force_segv(signr);
23424 + * Note that 'init' is a special process: it doesn't get signals it doesn't
23425 + * want to handle. Thus you cannot kill init even with a SIGKILL even by
23429 +static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error)
23432 + struct k_sigaction *ka;
23436 + oldset = ¤t->blocked;
23439 + unsigned long signr;
23441 + spin_lock_irq(¤t->sigmask_lock);
23442 + signr = dequeue_signal(¤t->blocked, &info);
23443 + spin_unlock_irq(¤t->sigmask_lock);
23448 + if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
23449 + /* Let the debugger run. */
23450 + current->exit_code = signr;
23451 + current->state = TASK_STOPPED;
23452 + notify_parent(current, SIGCHLD);
23455 + /* We're back. Did the debugger cancel the sig? */
23456 + signr = current->exit_code;
23459 + current->exit_code = 0;
23461 + /* The debugger continued. Ignore SIGSTOP. */
23462 + if (signr == SIGSTOP)
23465 + /* Update the siginfo structure. Is this good? */
23466 + if (signr != info.si_signo) {
23467 + info.si_signo = signr;
23468 + info.si_errno = 0;
23469 + info.si_code = SI_USER;
23470 + info.si_pid = current->p_pptr->pid;
23471 + info.si_uid = current->p_pptr->uid;
23474 + /* If the (new) signal is now blocked, requeue it. */
23475 + if (sigismember(¤t->blocked, signr)) {
23476 + send_sig_info(signr, &info, current);
23481 + ka = ¤t->sig->action[signr-1];
23482 + if (ka->sa.sa_handler == SIG_IGN) {
23483 + if (signr != SIGCHLD)
23485 + /* Check for SIGCHLD: it's special. */
23486 + while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
23491 + if (ka->sa.sa_handler == SIG_DFL) {
23492 + int exit_code = signr;
23494 + /* Init gets no signals it doesn't want. */
23495 + if (current->pid == 1)
23499 + case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
23502 + case SIGTSTP: case SIGTTIN: case SIGTTOU:
23503 + if (is_orphaned_pgrp(current->pgrp))
23508 + struct signal_struct *sig;
23509 + current->state = TASK_STOPPED;
23510 + current->exit_code = signr;
23511 + sig = current->p_pptr->sig;
23512 + if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
23513 + notify_parent(current, SIGCHLD);
23517 + case SIGQUIT: case SIGILL: case SIGTRAP:
23518 + case SIGABRT: case SIGFPE: case SIGSEGV:
23519 + case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
23520 + if (do_coredump(signr, ¤t->thread.regs))
23521 + exit_code |= 0x80;
23525 + sig_exit(signr, exit_code, &info);
23530 + /* Whee! Actually deliver the signal. */
23531 + err = handle_signal(regs, signr, ka, &info, oldset, error);
23532 + if(!err) return(1);
23535 + /* Did we come from a system call? */
23536 + if(PT_REGS_SYSCALL_NR(regs) >= 0){
23537 + /* Restart the system call - no handlers present */
23538 + if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND ||
23539 + PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS ||
23540 + PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOINTR){
23541 + PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
23542 + PT_REGS_RESTART_SYSCALL(regs);
23546 + /* This closes a way to execute a system call on the host. If
23547 + * you set a breakpoint on a system call instruction and singlestep
23548 + * from it, the tracing thread used to PTRACE_SINGLESTEP the process
23549 + * rather than PTRACE_SYSCALL it, allowing the system call to execute
23550 + * on the host. The tracing thread will check this flag and
23551 + * PTRACE_SYSCALL if necessary.
23553 + if((current->ptrace & PT_DTRACE) &&
23554 + is_syscall(PT_REGS_IP(¤t->thread.regs)))
23555 + (void) CHOOSE_MODE(current->thread.mode.tt.singlestep_syscall = 1, 0);
23560 +int do_signal(int error)
23562 + return(kern_do_signal(¤t->thread.regs, NULL, error));
23566 + * Atomically swap in the new signal mask, and wait for a signal.
23568 +int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
23570 + sigset_t saveset;
23572 + mask &= _BLOCKABLE;
23573 + spin_lock_irq(¤t->sigmask_lock);
23574 + saveset = current->blocked;
23575 + siginitset(¤t->blocked, mask);
23576 + recalc_sigpending(current);
23577 + spin_unlock_irq(¤t->sigmask_lock);
23580 + current->state = TASK_INTERRUPTIBLE;
23582 + if(kern_do_signal(¤t->thread.regs, &saveset, -EINTR))
23587 +int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
23589 + sigset_t saveset, newset;
23591 + /* XXX: Don't preclude handling different sized sigset_t's. */
23592 + if (sigsetsize != sizeof(sigset_t))
23595 + if (copy_from_user(&newset, unewset, sizeof(newset)))
23597 + sigdelsetmask(&newset, ~_BLOCKABLE);
23599 + spin_lock_irq(¤t->sigmask_lock);
23600 + saveset = current->blocked;
23601 + current->blocked = newset;
23602 + recalc_sigpending(current);
23603 + spin_unlock_irq(¤t->sigmask_lock);
23606 + current->state = TASK_INTERRUPTIBLE;
23608 + if (kern_do_signal(¤t->thread.regs, &saveset, -EINTR))
23613 +extern int userspace_pid[];
23615 +static int copy_sc_from_user(struct pt_regs *to, void *from,
23616 + struct arch_frame_data *arch)
23620 + ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
23621 + copy_sc_from_user_skas(userspace_pid[0],
23622 + &to->regs, from));
23626 +int sys_sigreturn(struct pt_regs regs)
23628 + void *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
23629 + void *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
23630 + int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
23632 + spin_lock_irq(¤t->sigmask_lock);
23633 + copy_from_user(¤t->blocked.sig[0], sc_sigmask(sc),
23634 + sizeof(current->blocked.sig[0]));
23635 + copy_from_user(¤t->blocked.sig[1], mask, sig_size);
23636 + sigdelsetmask(¤t->blocked, ~_BLOCKABLE);
23637 + recalc_sigpending(current);
23638 + spin_unlock_irq(¤t->sigmask_lock);
23639 + copy_sc_from_user(¤t->thread.regs, sc,
23640 + &signal_frame_sc.common.arch);
23641 + return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
23644 +int sys_rt_sigreturn(struct pt_regs regs)
23646 + struct ucontext *uc = sp_to_uc(PT_REGS_SP(¤t->thread.regs));
23647 + int sig_size = _NSIG_WORDS * sizeof(unsigned long);
23649 + spin_lock_irq(¤t->sigmask_lock);
23650 + copy_from_user(¤t->blocked, &uc->uc_sigmask, sig_size);
23651 + sigdelsetmask(¤t->blocked, ~_BLOCKABLE);
23652 + recalc_sigpending(current);
23653 + spin_unlock_irq(¤t->sigmask_lock);
23654 + copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext,
23655 + &signal_frame_si.common.arch);
23656 + return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
23660 + * Overrides for Emacs so that we follow Linus's tabbing style.
23661 + * Emacs will notice this stuff at the end of the file and automatically
23662 + * adjust the settings for this buffer only. This must remain at the end
23664 + * ---------------------------------------------------------------------------
23665 + * Local variables:
23666 + * c-file-style: "linux"
23669 diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_user.c um/arch/um/kernel/signal_user.c
23670 --- orig/arch/um/kernel/signal_user.c 1969-12-31 19:00:00.000000000 -0500
23671 +++ um/arch/um/kernel/signal_user.c 2003-10-21 03:26:07.000000000 -0400
23674 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
23675 + * Licensed under the GPL
23678 +#include <stdio.h>
23679 +#include <unistd.h>
23680 +#include <stdlib.h>
23681 +#include <signal.h>
23682 +#include <errno.h>
23683 +#include <stdarg.h>
23684 +#include <string.h>
23685 +#include <sys/mman.h>
23686 +#include "user_util.h"
23687 +#include "kern_util.h"
23689 +#include "signal_user.h"
23690 +#include "signal_kern.h"
23691 +#include "sysdep/sigcontext.h"
23692 +#include "sigcontext.h"
23694 +void set_sigstack(void *sig_stack, int size)
23696 + stack_t stack = ((stack_t) { .ss_flags = 0,
23697 + .ss_sp = (__ptr_t) sig_stack,
23698 + .ss_size = size - sizeof(void *) });
23700 + if(sigaltstack(&stack, NULL) != 0)
23701 + panic("enabling signal stack failed, errno = %d\n", errno);
23704 +void set_handler(int sig, void (*handler)(int), int flags, ...)
23706 + struct sigaction action;
23710 + va_start(ap, flags);
23711 + action.sa_handler = handler;
23712 + sigemptyset(&action.sa_mask);
23713 + while((mask = va_arg(ap, int)) != -1){
23714 + sigaddset(&action.sa_mask, mask);
23716 + action.sa_flags = flags;
23717 + action.sa_restorer = NULL;
23718 + if(sigaction(sig, &action, NULL) < 0)
23719 + panic("sigaction failed");
23722 +int change_sig(int signal, int on)
23724 + sigset_t sigset, old;
23726 + sigemptyset(&sigset);
23727 + sigaddset(&sigset, signal);
23728 + sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
23729 + return(!sigismember(&old, signal));
23732 +static void change_signals(int type)
23736 + sigemptyset(&mask);
23737 + sigaddset(&mask, SIGVTALRM);
23738 + sigaddset(&mask, SIGALRM);
23739 + sigaddset(&mask, SIGIO);
23740 + sigaddset(&mask, SIGPROF);
23741 + if(sigprocmask(type, &mask, NULL) < 0)
23742 + panic("Failed to change signal mask - errno = %d", errno);
23745 +void block_signals(void)
23747 + change_signals(SIG_BLOCK);
23750 +void unblock_signals(void)
23752 + change_signals(SIG_UNBLOCK);
23755 +#define SIGIO_BIT 0
23756 +#define SIGVTALRM_BIT 1
23758 +static int enable_mask(sigset_t *mask)
23762 + sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
23763 + sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
23764 + sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
23768 +int get_signals(void)
23772 + if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
23773 + panic("Failed to get signal mask");
23774 + return(enable_mask(&mask));
23777 +int set_signals(int enable)
23782 + sigemptyset(&mask);
23783 + if(enable & (1 << SIGIO_BIT))
23784 + sigaddset(&mask, SIGIO);
23785 + if(enable & (1 << SIGVTALRM_BIT)){
23786 + sigaddset(&mask, SIGVTALRM);
23787 + sigaddset(&mask, SIGALRM);
23789 + if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
23790 + panic("Failed to enable signals");
23791 + ret = enable_mask(&mask);
23792 + sigemptyset(&mask);
23793 + if((enable & (1 << SIGIO_BIT)) == 0)
23794 + sigaddset(&mask, SIGIO);
23795 + if((enable & (1 << SIGVTALRM_BIT)) == 0){
23796 + sigaddset(&mask, SIGVTALRM);
23797 + sigaddset(&mask, SIGALRM);
23799 + if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
23800 + panic("Failed to block signals");
23806 + * Overrides for Emacs so that we follow Linus's tabbing style.
23807 + * Emacs will notice this stuff at the end of the file and automatically
23808 + * adjust the settings for this buffer only. This must remain at the end
23810 + * ---------------------------------------------------------------------------
23811 + * Local variables:
23812 + * c-file-style: "linux"
23815 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_kern.c um/arch/um/kernel/skas/exec_kern.c
23816 --- orig/arch/um/kernel/skas/exec_kern.c 1969-12-31 19:00:00.000000000 -0500
23817 +++ um/arch/um/kernel/skas/exec_kern.c 2003-10-21 03:26:07.000000000 -0400
23820 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23821 + * Licensed under the GPL
23824 +#include "linux/kernel.h"
23825 +#include "asm/current.h"
23826 +#include "asm/page.h"
23827 +#include "asm/signal.h"
23828 +#include "asm/ptrace.h"
23829 +#include "asm/uaccess.h"
23830 +#include "asm/mmu_context.h"
23836 +void flush_thread_skas(void)
23838 + force_flush_all();
23839 + switch_mm_skas(current->mm->context.skas.mm_fd);
23842 +void start_thread_skas(struct pt_regs *regs, unsigned long eip,
23843 + unsigned long esp)
23846 + PT_REGS_IP(regs) = eip;
23847 + PT_REGS_SP(regs) = esp;
23851 + * Overrides for Emacs so that we follow Linus's tabbing style.
23852 + * Emacs will notice this stuff at the end of the file and automatically
23853 + * adjust the settings for this buffer only. This must remain at the end
23855 + * ---------------------------------------------------------------------------
23856 + * Local variables:
23857 + * c-file-style: "linux"
23860 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_user.c um/arch/um/kernel/skas/exec_user.c
23861 --- orig/arch/um/kernel/skas/exec_user.c 1969-12-31 19:00:00.000000000 -0500
23862 +++ um/arch/um/kernel/skas/exec_user.c 2003-10-21 03:26:07.000000000 -0400
23865 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23866 + * Licensed under the GPL
23869 +#include <stdlib.h>
23870 +#include <errno.h>
23871 +#include <signal.h>
23872 +#include <sched.h>
23873 +#include <sys/wait.h>
23874 +#include <sys/ptrace.h>
23876 +#include "kern_util.h"
23878 +#include "time_user.h"
23880 +static int user_thread_tramp(void *arg)
23882 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
23883 + panic("user_thread_tramp - PTRACE_TRACEME failed, "
23884 + "errno = %d\n", errno);
23886 + os_stop_process(os_getpid());
23890 +int user_thread(unsigned long stack, int flags)
23894 + pid = clone(user_thread_tramp, (void *) stack_sp(stack),
23895 + flags | CLONE_FILES | SIGCHLD, NULL);
23897 + printk("user_thread - clone failed, errno = %d\n", errno);
23901 + if(waitpid(pid, &status, WUNTRACED) < 0){
23902 + printk("user_thread - waitpid failed, errno = %d\n", errno);
23906 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
23907 + printk("user_thread - trampoline didn't stop, status = %d\n",
23916 + * Overrides for Emacs so that we follow Linus's tabbing style.
23917 + * Emacs will notice this stuff at the end of the file and automatically
23918 + * adjust the settings for this buffer only. This must remain at the end
23920 + * ---------------------------------------------------------------------------
23921 + * Local variables:
23922 + * c-file-style: "linux"
23925 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mmu.h um/arch/um/kernel/skas/include/mmu.h
23926 --- orig/arch/um/kernel/skas/include/mmu.h 1969-12-31 19:00:00.000000000 -0500
23927 +++ um/arch/um/kernel/skas/include/mmu.h 2003-10-21 03:26:07.000000000 -0400
23930 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23931 + * Licensed under the GPL
23934 +#ifndef __SKAS_MMU_H
23935 +#define __SKAS_MMU_H
23937 +#include "linux/list.h"
23938 +#include "linux/spinlock.h"
23940 +struct mmu_context_skas {
23947 + * Overrides for Emacs so that we follow Linus's tabbing style.
23948 + * Emacs will notice this stuff at the end of the file and automatically
23949 + * adjust the settings for this buffer only. This must remain at the end
23951 + * ---------------------------------------------------------------------------
23952 + * Local variables:
23953 + * c-file-style: "linux"
23956 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode.h um/arch/um/kernel/skas/include/mode.h
23957 --- orig/arch/um/kernel/skas/include/mode.h 1969-12-31 19:00:00.000000000 -0500
23958 +++ um/arch/um/kernel/skas/include/mode.h 2003-11-19 03:27:36.000000000 -0500
23961 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23962 + * Licensed under the GPL
23965 +#ifndef __MODE_SKAS_H__
23966 +#define __MODE_SKAS_H__
23968 +extern unsigned long exec_regs[];
23969 +extern unsigned long exec_fp_regs[];
23970 +extern unsigned long exec_fpx_regs[];
23971 +extern int have_fpx_regs;
23973 +extern void user_time_init_skas(void);
23974 +extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs,
23976 +extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp,
23977 + union uml_pt_regs *regs,
23978 + unsigned long fault_addr, int fault_type);
23979 +extern void sig_handler_common_skas(int sig, void *sc_ptr);
23980 +extern void halt_skas(void);
23981 +extern void reboot_skas(void);
23982 +extern void kill_off_processes_skas(void);
23983 +extern int is_skas_winch(int pid, int fd, void *data);
23988 + * Overrides for Emacs so that we follow Linus's tabbing style.
23989 + * Emacs will notice this stuff at the end of the file and automatically
23990 + * adjust the settings for this buffer only. This must remain at the end
23992 + * ---------------------------------------------------------------------------
23993 + * Local variables:
23994 + * c-file-style: "linux"
23997 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode_kern.h um/arch/um/kernel/skas/include/mode_kern.h
23998 --- orig/arch/um/kernel/skas/include/mode_kern.h 1969-12-31 19:00:00.000000000 -0500
23999 +++ um/arch/um/kernel/skas/include/mode_kern.h 2003-10-21 03:26:07.000000000 -0400
24002 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24003 + * Licensed under the GPL
24006 +#ifndef __SKAS_MODE_KERN_H__
24007 +#define __SKAS_MODE_KERN_H__
24009 +#include "linux/sched.h"
24010 +#include "asm/page.h"
24011 +#include "asm/ptrace.h"
24013 +extern void flush_thread_skas(void);
24014 +extern void *_switch_to_skas(void *prev, void *next);
24015 +extern void start_thread_skas(struct pt_regs *regs, unsigned long eip,
24016 + unsigned long esp);
24017 +extern int copy_thread_skas(int nr, unsigned long clone_flags,
24018 + unsigned long sp, unsigned long stack_top,
24019 + struct task_struct *p, struct pt_regs *regs);
24020 +extern void release_thread_skas(struct task_struct *task);
24021 +extern void exit_thread_skas(void);
24022 +extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
24023 +extern void init_idle_skas(void);
24024 +extern void flush_tlb_kernel_vm_skas(void);
24025 +extern void __flush_tlb_one_skas(unsigned long addr);
24026 +extern void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start,
24027 + unsigned long end);
24028 +extern void flush_tlb_mm_skas(struct mm_struct *mm);
24029 +extern void force_flush_all_skas(void);
24030 +extern long execute_syscall_skas(void *r);
24031 +extern void before_mem_skas(unsigned long unused);
24032 +extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
24033 + unsigned long *task_size_out);
24034 +extern int start_uml_skas(void);
24035 +extern int external_pid_skas(struct task_struct *task);
24036 +extern int thread_pid_skas(struct thread_struct *thread);
24038 +#define kmem_end_skas (host_task_size - 1024 * 1024)
24043 + * Overrides for Emacs so that we follow Linus's tabbing style.
24044 + * Emacs will notice this stuff at the end of the file and automatically
24045 + * adjust the settings for this buffer only. This must remain at the end
24047 + * ---------------------------------------------------------------------------
24048 + * Local variables:
24049 + * c-file-style: "linux"
24052 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/proc_mm.h um/arch/um/kernel/skas/include/proc_mm.h
24053 --- orig/arch/um/kernel/skas/include/proc_mm.h 1969-12-31 19:00:00.000000000 -0500
24054 +++ um/arch/um/kernel/skas/include/proc_mm.h 2003-10-21 03:26:07.000000000 -0400
24057 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24058 + * Licensed under the GPL
24061 +#ifndef __SKAS_PROC_MM_H
24062 +#define __SKAS_PROC_MM_H
24064 +#define MM_MMAP 54
24065 +#define MM_MUNMAP 55
24066 +#define MM_MPROTECT 56
24067 +#define MM_COPY_SEGMENTS 57
24070 + unsigned long addr;
24071 + unsigned long len;
24072 + unsigned long prot;
24073 + unsigned long flags;
24074 + unsigned long fd;
24075 + unsigned long offset;
24078 +struct mm_munmap {
24079 + unsigned long addr;
24080 + unsigned long len;
24083 +struct mm_mprotect {
24084 + unsigned long addr;
24085 + unsigned long len;
24086 + unsigned int prot;
24089 +struct proc_mm_op {
24092 + struct mm_mmap mmap;
24093 + struct mm_munmap munmap;
24094 + struct mm_mprotect mprotect;
24095 + int copy_segments;
24102 + * Overrides for Emacs so that we follow Linus's tabbing style.
24103 + * Emacs will notice this stuff at the end of the file and automatically
24104 + * adjust the settings for this buffer only. This must remain at the end
24106 + * ---------------------------------------------------------------------------
24107 + * Local variables:
24108 + * c-file-style: "linux"
24111 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/ptrace-skas.h um/arch/um/kernel/skas/include/ptrace-skas.h
24112 --- orig/arch/um/kernel/skas/include/ptrace-skas.h 1969-12-31 19:00:00.000000000 -0500
24113 +++ um/arch/um/kernel/skas/include/ptrace-skas.h 2003-10-21 03:26:07.000000000 -0400
24116 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24117 + * Licensed under the GPL
24120 +#ifndef __PTRACE_SKAS_H
24121 +#define __PTRACE_SKAS_H
24123 +#include "uml-config.h"
24125 +#ifdef UML_CONFIG_MODE_SKAS
24127 +#include "skas_ptregs.h"
24129 +#define HOST_FRAME_SIZE 17
24131 +#define REGS_IP(r) ((r)[HOST_IP])
24132 +#define REGS_SP(r) ((r)[HOST_SP])
24133 +#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
24134 +#define REGS_EAX(r) ((r)[HOST_EAX])
24135 +#define REGS_EBX(r) ((r)[HOST_EBX])
24136 +#define REGS_ECX(r) ((r)[HOST_ECX])
24137 +#define REGS_EDX(r) ((r)[HOST_EDX])
24138 +#define REGS_ESI(r) ((r)[HOST_ESI])
24139 +#define REGS_EDI(r) ((r)[HOST_EDI])
24140 +#define REGS_EBP(r) ((r)[HOST_EBP])
24141 +#define REGS_CS(r) ((r)[HOST_CS])
24142 +#define REGS_SS(r) ((r)[HOST_SS])
24143 +#define REGS_DS(r) ((r)[HOST_DS])
24144 +#define REGS_ES(r) ((r)[HOST_ES])
24145 +#define REGS_FS(r) ((r)[HOST_FS])
24146 +#define REGS_GS(r) ((r)[HOST_GS])
24148 +#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res)
24150 +#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
24152 +#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
24154 +#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
24156 +#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
24163 + * Overrides for Emacs so that we follow Linus's tabbing style.
24164 + * Emacs will notice this stuff at the end of the file and automatically
24165 + * adjust the settings for this buffer only. This must remain at the end
24167 + * ---------------------------------------------------------------------------
24168 + * Local variables:
24169 + * c-file-style: "linux"
24172 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/skas.h um/arch/um/kernel/skas/include/skas.h
24173 --- orig/arch/um/kernel/skas/include/skas.h 1969-12-31 19:00:00.000000000 -0500
24174 +++ um/arch/um/kernel/skas/include/skas.h 2003-11-19 03:00:51.000000000 -0500
24177 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24178 + * Licensed under the GPL
24184 +#include "sysdep/ptrace.h"
24186 +extern int userspace_pid[];
24188 +extern void switch_threads(void *me, void *next);
24189 +extern void thread_wait(void *sw, void *fb);
24190 +extern void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
24191 + void (*handler)(int));
24192 +extern int start_idle_thread(void *stack, void *switch_buf_ptr,
24193 + void **fork_buf_ptr);
24194 +extern int user_thread(unsigned long stack, int flags);
24195 +extern void userspace(union uml_pt_regs *regs);
24196 +extern void new_thread_proc(void *stack, void (*handler)(int sig));
24197 +extern void remove_sigstack(void);
24198 +extern void new_thread_handler(int sig);
24199 +extern void handle_syscall(union uml_pt_regs *regs);
24200 +extern void map(int fd, unsigned long virt, unsigned long phys,
24201 + unsigned long len, int r, int w, int x);
24202 +extern int unmap(int fd, void *addr, int len);
24203 +extern int protect(int fd, unsigned long addr, unsigned long len,
24204 + int r, int w, int x, int must_succeed);
24205 +extern void user_signal(int sig, union uml_pt_regs *regs);
24206 +extern int singlestepping_skas(void);
24207 +extern int new_mm(int from);
24208 +extern void save_registers(union uml_pt_regs *regs);
24209 +extern void restore_registers(union uml_pt_regs *regs);
24210 +extern void start_userspace(int cpu);
24211 +extern void init_registers(int pid);
24216 + * Overrides for Emacs so that we follow Linus's tabbing style.
24217 + * Emacs will notice this stuff at the end of the file and automatically
24218 + * adjust the settings for this buffer only. This must remain at the end
24220 + * ---------------------------------------------------------------------------
24221 + * Local variables:
24222 + * c-file-style: "linux"
24225 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/uaccess.h um/arch/um/kernel/skas/include/uaccess.h
24226 --- orig/arch/um/kernel/skas/include/uaccess.h 1969-12-31 19:00:00.000000000 -0500
24227 +++ um/arch/um/kernel/skas/include/uaccess.h 2003-12-17 01:19:45.000000000 -0500
24230 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24231 + * Licensed under the GPL
24234 +#ifndef __SKAS_UACCESS_H
24235 +#define __SKAS_UACCESS_H
24237 +#define access_ok_skas(type, addr, size) \
24238 + ((segment_eq(get_fs(), KERNEL_DS)) || \
24239 + (((unsigned long) (addr) < TASK_SIZE) && \
24240 + ((unsigned long) (addr) + (size) <= TASK_SIZE)))
24242 +static inline int verify_area_skas(int type, const void * addr,
24243 + unsigned long size)
24245 + return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
24250 +extern int copy_from_user_skas(void *to, const void *from, int n);
24251 +extern int copy_to_user_skas(void *to, const void *from, int n);
24252 +extern int strncpy_from_user_skas(char *dst, const char *src, int count);
24253 +extern int __clear_user_skas(void *mem, int len);
24254 +extern int clear_user_skas(void *mem, int len);
24255 +extern int strnlen_user_skas(const void *str, int len);
24258 + * Overrides for Emacs so that we follow Linus's tabbing style.
24259 + * Emacs will notice this stuff at the end of the file and automatically
24260 + * adjust the settings for this buffer only. This must remain at the end
24262 + * ---------------------------------------------------------------------------
24263 + * Local variables:
24264 + * c-file-style: "linux"
24267 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/Makefile um/arch/um/kernel/skas/Makefile
24268 --- orig/arch/um/kernel/skas/Makefile 1969-12-31 19:00:00.000000000 -0500
24269 +++ um/arch/um/kernel/skas/Makefile 2003-11-11 06:36:12.000000000 -0500
24272 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24273 +# Licensed under the GPL
24278 +obj-y = exec_kern.o exec_user.o mem.o mem_user.o mmu.o process.o \
24279 + process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
24282 +subdir-y = sys-$(SUBARCH)
24284 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
24286 +USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
24288 +include $(TOPDIR)/Rules.make
24290 +include/skas_ptregs.h : util/mk_ptregs
24291 + util/mk_ptregs > $@
24296 +$(USER_OBJS) : %.o: %.c
24297 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
24300 + $(MAKE) -C util clean
24301 + $(RM) -f include/skas_ptregs.h
24302 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mem.c um/arch/um/kernel/skas/mem.c
24303 --- orig/arch/um/kernel/skas/mem.c 1969-12-31 19:00:00.000000000 -0500
24304 +++ um/arch/um/kernel/skas/mem.c 2003-10-21 03:26:07.000000000 -0400
24307 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24308 + * Licensed under the GPL
24311 +#include "linux/config.h"
24312 +#include "linux/mm.h"
24313 +#include "mem_user.h"
24315 +unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
24316 + unsigned long *task_size_out)
24318 + /* Round up to the nearest 4M */
24319 + unsigned long top = ROUND_4M((unsigned long) &arg);
24321 + *host_size_out = top;
24322 + *task_size_out = top;
24323 + return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
24327 + * Overrides for Emacs so that we follow Linus's tabbing style.
24328 + * Emacs will notice this stuff at the end of the file and automatically
24329 + * adjust the settings for this buffer only. This must remain at the end
24331 + * ---------------------------------------------------------------------------
24332 + * Local variables:
24333 + * c-file-style: "linux"
24336 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mem_user.c um/arch/um/kernel/skas/mem_user.c
24337 --- orig/arch/um/kernel/skas/mem_user.c 1969-12-31 19:00:00.000000000 -0500
24338 +++ um/arch/um/kernel/skas/mem_user.c 2003-10-21 03:26:07.000000000 -0400
24341 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24342 + * Licensed under the GPL
24345 +#include <errno.h>
24346 +#include <sys/mman.h>
24347 +#include <sys/ptrace.h>
24348 +#include "mem_user.h"
24352 +#include "proc_mm.h"
24354 +void map(int fd, unsigned long virt, unsigned long phys, unsigned long len,
24355 + int r, int w, int x)
24357 + struct proc_mm_op map;
24359 + int prot, n, phys_fd;
24361 + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
24362 + (x ? PROT_EXEC : 0);
24363 + phys_fd = phys_mapping(phys, &offset);
24365 + map = ((struct proc_mm_op) { .op = MM_MMAP,
24371 + .flags = MAP_SHARED |
24376 + n = os_write_file(fd, &map, sizeof(map));
24377 + if(n != sizeof(map))
24378 + printk("map : /proc/mm map failed, err = %d\n", -n);
24381 +int unmap(int fd, void *addr, int len)
24383 + struct proc_mm_op unmap;
24386 + unmap = ((struct proc_mm_op) { .op = MM_MUNMAP,
24389 + { .addr = (unsigned long) addr,
24390 + .len = len } } } );
24391 + n = os_write_file(fd, &unmap, sizeof(unmap));
24392 + if(n != sizeof(unmap)) {
24402 +int protect(int fd, unsigned long addr, unsigned long len, int r, int w,
24403 + int x, int must_succeed)
24405 + struct proc_mm_op protect;
24408 + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
24409 + (x ? PROT_EXEC : 0);
24411 + protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
24414 + { .addr = (unsigned long) addr,
24416 + .prot = prot } } } );
24418 + n = os_write_file(fd, &protect, sizeof(protect));
24419 + if(n != sizeof(protect)) {
24420 + if(n == 0) return(0);
24423 + panic("protect failed, err = %d", -n);
24431 +void before_mem_skas(unsigned long unused)
24436 + * Overrides for Emacs so that we follow Linus's tabbing style.
24437 + * Emacs will notice this stuff at the end of the file and automatically
24438 + * adjust the settings for this buffer only. This must remain at the end
24440 + * ---------------------------------------------------------------------------
24441 + * Local variables:
24442 + * c-file-style: "linux"
24445 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mmu.c um/arch/um/kernel/skas/mmu.c
24446 --- orig/arch/um/kernel/skas/mmu.c 1969-12-31 19:00:00.000000000 -0500
24447 +++ um/arch/um/kernel/skas/mmu.c 2003-11-15 22:25:20.000000000 -0500
24450 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24451 + * Licensed under the GPL
24454 +#include "linux/list.h"
24455 +#include "linux/spinlock.h"
24456 +#include "linux/slab.h"
24457 +#include "asm/segment.h"
24458 +#include "asm/mmu.h"
24462 +int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
24466 + if((current->mm != NULL) && (current->mm != &init_mm))
24467 + from = current->mm->context.skas.mm_fd;
24470 + mm->context.skas.mm_fd = new_mm(from);
24471 + if(mm->context.skas.mm_fd < 0){
24472 + printk("init_new_context_skas - new_mm failed, errno = %d\n",
24473 + mm->context.skas.mm_fd);
24474 + return(mm->context.skas.mm_fd);
24480 +void destroy_context_skas(struct mm_struct *mm)
24482 + os_close_file(mm->context.skas.mm_fd);
24486 + * Overrides for Emacs so that we follow Linus's tabbing style.
24487 + * Emacs will notice this stuff at the end of the file and automatically
24488 + * adjust the settings for this buffer only. This must remain at the end
24490 + * ---------------------------------------------------------------------------
24491 + * Local variables:
24492 + * c-file-style: "linux"
24495 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process.c um/arch/um/kernel/skas/process.c
24496 --- orig/arch/um/kernel/skas/process.c 1969-12-31 19:00:00.000000000 -0500
24497 +++ um/arch/um/kernel/skas/process.c 2003-11-19 03:00:01.000000000 -0500
24500 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24501 + * Licensed under the GPL
24504 +#include <stdlib.h>
24505 +#include <unistd.h>
24506 +#include <errno.h>
24507 +#include <signal.h>
24508 +#include <setjmp.h>
24509 +#include <sched.h>
24510 +#include <sys/wait.h>
24511 +#include <sys/ptrace.h>
24512 +#include <sys/mman.h>
24513 +#include <sys/user.h>
24514 +#include <asm/unistd.h>
24516 +#include "ptrace_user.h"
24517 +#include "time_user.h"
24518 +#include "sysdep/ptrace.h"
24519 +#include "user_util.h"
24520 +#include "kern_util.h"
24522 +#include "sysdep/sigcontext.h"
24524 +#include "proc_mm.h"
24525 +#include "skas_ptrace.h"
24526 +#include "chan_user.h"
24528 +int is_skas_winch(int pid, int fd, void *data)
24530 + if(pid != getpid())
24533 + register_winch_irq(-1, fd, -1, data);
24537 +/* These are set once at boot time and not changed thereafter */
24539 +unsigned long exec_regs[FRAME_SIZE];
24540 +unsigned long exec_fp_regs[HOST_FP_SIZE];
24541 +unsigned long exec_fpx_regs[HOST_XFP_SIZE];
24542 +int have_fpx_regs = 1;
24544 +static void handle_segv(int pid)
24546 + struct ptrace_faultinfo fault;
24549 + err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault);
24551 + panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n",
24554 + segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
24557 +static void handle_trap(int pid, union uml_pt_regs *regs)
24559 + int err, syscall_nr, status;
24561 + syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
24562 + UPT_SYSCALL_NR(regs) = syscall_nr;
24563 + if(syscall_nr < 1){
24564 + relay_signal(SIGTRAP, regs);
24568 + err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
24570 + panic("handle_trap - nullifying syscall failed errno = %d\n",
24573 + err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
24575 + panic("handle_trap - continuing to end of syscall failed, "
24576 + "errno = %d\n", errno);
24578 + err = waitpid(pid, &status, WUNTRACED);
24579 + if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
24580 + panic("handle_trap - failed to wait at end of syscall, "
24581 + "errno = %d, status = %d\n", errno, status);
24583 + handle_syscall(regs);
24586 +static int userspace_tramp(void *arg)
24588 + init_new_thread_signals(0);
24590 + ptrace(PTRACE_TRACEME, 0, 0, 0);
24591 + os_stop_process(os_getpid());
24595 +/* Each element set once, and only accessed by a single processor anyway */
24597 +int userspace_pid[NR_CPUS];
24599 +void start_userspace(int cpu)
24602 + unsigned long sp;
24603 + int pid, status, n;
24605 + stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
24606 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
24607 + if(stack == MAP_FAILED)
24608 + panic("start_userspace : mmap failed, errno = %d", errno);
24609 + sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
24611 + pid = clone(userspace_tramp, (void *) sp,
24612 + CLONE_FILES | CLONE_VM | SIGCHLD, NULL);
24614 + panic("start_userspace : clone failed, errno = %d", errno);
24617 + n = waitpid(pid, &status, WUNTRACED);
24619 + panic("start_userspace : wait failed, errno = %d",
24621 + } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
24623 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
24624 + panic("start_userspace : expected SIGSTOP, got status = %d",
24627 + if(munmap(stack, PAGE_SIZE) < 0)
24628 + panic("start_userspace : munmap failed, errno = %d\n", errno);
24630 + userspace_pid[cpu] = pid;
24633 +void userspace(union uml_pt_regs *regs)
24635 + int err, status, op, pid = userspace_pid[0];
24637 + restore_registers(regs);
24639 + err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
24641 + panic("userspace - PTRACE_SYSCALL failed, errno = %d\n",
24644 + err = waitpid(pid, &status, WUNTRACED);
24646 + panic("userspace - waitpid failed, errno = %d\n",
24649 + regs->skas.is_user = 1;
24650 + save_registers(regs);
24652 + if(WIFSTOPPED(status)){
24653 + switch(WSTOPSIG(status)){
24655 + handle_segv(pid);
24658 + handle_trap(pid, regs);
24666 + user_signal(WSTOPSIG(status), regs);
24669 + printk("userspace - child stopped with signal "
24670 + "%d\n", WSTOPSIG(status));
24675 + restore_registers(regs);
24677 + op = singlestepping_skas() ? PTRACE_SINGLESTEP :
24679 + err = ptrace(op, pid, 0, 0);
24681 + panic("userspace - PTRACE_SYSCALL failed, "
24682 + "errno = %d\n", errno);
24686 +void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
24687 + void (*handler)(int))
24689 + jmp_buf switch_buf, fork_buf;
24691 + *switch_buf_ptr = &switch_buf;
24692 + *fork_buf_ptr = &fork_buf;
24694 + if(sigsetjmp(fork_buf, 1) == 0)
24695 + new_thread_proc(stack, handler);
24697 + remove_sigstack();
24700 +void thread_wait(void *sw, void *fb)
24702 + jmp_buf buf, **switch_buf = sw, *fork_buf;
24704 + *switch_buf = &buf;
24706 + if(sigsetjmp(buf, 1) == 0)
24707 + siglongjmp(*fork_buf, 1);
24710 +static int move_registers(int pid, int int_op, int fp_op,
24711 + union uml_pt_regs *regs, unsigned long *fp_regs)
24713 + if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
24715 + if(ptrace(fp_op, pid, 0, fp_regs) < 0)
24720 +void save_registers(union uml_pt_regs *regs)
24722 + unsigned long *fp_regs;
24725 + if(have_fpx_regs){
24726 + fp_op = PTRACE_GETFPXREGS;
24727 + fp_regs = regs->skas.xfp;
24730 + fp_op = PTRACE_GETFPREGS;
24731 + fp_regs = regs->skas.fp;
24734 + err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs,
24737 + panic("save_registers - saving registers failed, errno = %d\n",
24741 +void restore_registers(union uml_pt_regs *regs)
24743 + unsigned long *fp_regs;
24746 + if(have_fpx_regs){
24747 + fp_op = PTRACE_SETFPXREGS;
24748 + fp_regs = regs->skas.xfp;
24751 + fp_op = PTRACE_SETFPREGS;
24752 + fp_regs = regs->skas.fp;
24755 + err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs,
24758 + panic("restore_registers - saving registers failed, "
24759 + "errno = %d\n", -err);
24762 +void switch_threads(void *me, void *next)
24764 + jmp_buf my_buf, **me_ptr = me, *next_buf = next;
24766 + *me_ptr = &my_buf;
24767 + if(sigsetjmp(my_buf, 1) == 0)
24768 + siglongjmp(*next_buf, 1);
24771 +static jmp_buf initial_jmpbuf;
24773 +/* XXX Make these percpu */
24774 +static void (*cb_proc)(void *arg);
24775 +static void *cb_arg;
24776 +static jmp_buf *cb_back;
24778 +int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
24780 + jmp_buf **switch_buf = switch_buf_ptr;
24783 + *fork_buf_ptr = &initial_jmpbuf;
24784 + n = sigsetjmp(initial_jmpbuf, 1);
24786 + new_thread_proc((void *) stack, new_thread_handler);
24788 + remove_sigstack();
24790 + (*cb_proc)(cb_arg);
24791 + siglongjmp(*cb_back, 1);
24801 + siglongjmp(**switch_buf, 1);
24804 +void remove_sigstack(void)
24806 + stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE,
24810 + if(sigaltstack(&stack, NULL) != 0)
24811 + panic("disabling signal stack failed, errno = %d\n", errno);
24814 +void initial_thread_cb_skas(void (*proc)(void *), void *arg)
24823 + if(sigsetjmp(here, 1) == 0)
24824 + siglongjmp(initial_jmpbuf, 2);
24825 + unblock_signals();
24832 +void halt_skas(void)
24835 + siglongjmp(initial_jmpbuf, 3);
24838 +void reboot_skas(void)
24841 + siglongjmp(initial_jmpbuf, 4);
24844 +int new_mm(int from)
24846 + struct proc_mm_op copy;
24847 + int n, fd = os_open_file("/proc/mm",
24848 + of_cloexec(of_write(OPENFLAGS())), 0);
24854 + copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS,
24856 + { .copy_segments = from } } );
24857 + n = os_write_file(fd, ©, sizeof(copy));
24858 + if(n != sizeof(copy))
24859 + printk("new_mm : /proc/mm copy_segments failed, "
24860 + "err = %d\n", -n);
24866 +void switch_mm_skas(int mm_fd)
24870 +#warning need cpu pid in switch_mm_skas
24871 + err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd);
24873 + panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
24877 +void kill_off_processes_skas(void)
24879 +#warning need to loop over userspace_pids in kill_off_processes_skas
24880 + os_kill_process(userspace_pid[0], 1);
24883 +void init_registers(int pid)
24887 + if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0)
24888 + panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
24891 + err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
24895 + have_fpx_regs = 0;
24897 + panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
24900 + err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
24902 + panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
24907 + * Overrides for Emacs so that we follow Linus's tabbing style.
24908 + * Emacs will notice this stuff at the end of the file and automatically
24909 + * adjust the settings for this buffer only. This must remain at the end
24911 + * ---------------------------------------------------------------------------
24912 + * Local variables:
24913 + * c-file-style: "linux"
24916 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process_kern.c um/arch/um/kernel/skas/process_kern.c
24917 --- orig/arch/um/kernel/skas/process_kern.c 1969-12-31 19:00:00.000000000 -0500
24918 +++ um/arch/um/kernel/skas/process_kern.c 2003-11-19 03:18:25.000000000 -0500
24921 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24922 + * Licensed under the GPL
24925 +#include "linux/sched.h"
24926 +#include "linux/slab.h"
24927 +#include "kern_util.h"
24928 +#include "time_user.h"
24929 +#include "signal_user.h"
24932 +#include "user_util.h"
24934 +#include "frame.h"
24938 +int singlestepping_skas(void)
24940 + int ret = current->ptrace & PT_DTRACE;
24942 + current->ptrace &= ~PT_DTRACE;
24946 +void *_switch_to_skas(void *prev, void *next)
24948 + struct task_struct *from, *to;
24953 + /* XXX need to check runqueues[cpu].idle */
24954 + if(current->pid == 0)
24955 + switch_timers(0);
24957 + to->thread.prev_sched = from;
24960 + switch_threads(&from->thread.mode.skas.switch_buf,
24961 + to->thread.mode.skas.switch_buf);
24963 + if(current->pid == 0)
24964 + switch_timers(1);
24966 + return(current->thread.prev_sched);
24969 +extern void schedule_tail(struct task_struct *prev);
24971 +void new_thread_handler(int sig)
24973 + int (*fn)(void *), n;
24976 + fn = current->thread.request.u.thread.proc;
24977 + arg = current->thread.request.u.thread.arg;
24978 + change_sig(SIGUSR1, 1);
24979 + thread_wait(¤t->thread.mode.skas.switch_buf,
24980 + current->thread.mode.skas.fork_buf);
24982 + if(current->thread.prev_sched != NULL)
24983 + schedule_tail(current->thread.prev_sched);
24984 + current->thread.prev_sched = NULL;
24986 + /* The return value is 1 if the kernel thread execs a process,
24987 + * 0 if it just exits
24989 + n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf);
24991 + userspace(¤t->thread.regs.regs);
24995 +void new_thread_proc(void *stack, void (*handler)(int sig))
24997 + init_new_thread_stack(stack, handler);
24998 + os_usr1_process(os_getpid());
25001 +void release_thread_skas(struct task_struct *task)
25005 +void exit_thread_skas(void)
25009 +void fork_handler(int sig)
25011 + change_sig(SIGUSR1, 1);
25012 + thread_wait(¤t->thread.mode.skas.switch_buf,
25013 + current->thread.mode.skas.fork_buf);
25015 + force_flush_all();
25016 + if(current->thread.prev_sched != NULL)
25017 + schedule_tail(current->thread.prev_sched);
25018 + current->thread.prev_sched = NULL;
25019 + unblock_signals();
25021 + userspace(¤t->thread.regs.regs);
25024 +int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
25025 + unsigned long stack_top, struct task_struct * p,
25026 + struct pt_regs *regs)
25028 + void (*handler)(int);
25030 + if(current->thread.forking){
25031 + memcpy(&p->thread.regs.regs.skas,
25032 + ¤t->thread.regs.regs.skas,
25033 + sizeof(p->thread.regs.regs.skas));
25034 + REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
25035 + if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
25037 + handler = fork_handler;
25040 + memcpy(p->thread.regs.regs.skas.regs, exec_regs,
25041 + sizeof(p->thread.regs.regs.skas.regs));
25042 + memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs,
25043 + sizeof(p->thread.regs.regs.skas.fp));
25044 + memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs,
25045 + sizeof(p->thread.regs.regs.skas.xfp));
25046 + p->thread.request.u.thread = current->thread.request.u.thread;
25047 + handler = new_thread_handler;
25050 + new_thread((void *) p->thread.kernel_stack,
25051 + &p->thread.mode.skas.switch_buf,
25052 + &p->thread.mode.skas.fork_buf, handler);
25056 +void init_idle_skas(void)
25058 + cpu_tasks[current->processor].pid = os_getpid();
25061 +extern void start_kernel(void);
25063 +static int start_kernel_proc(void *unused)
25068 + pid = os_getpid();
25070 + cpu_tasks[0].pid = pid;
25071 + cpu_tasks[0].task = current;
25073 + cpu_online_map = 1;
25079 +int start_uml_skas(void)
25081 + start_userspace(0);
25082 + capture_signal_stack();
25085 + init_new_thread_signals(1);
25087 + init_task.thread.request.u.thread.proc = start_kernel_proc;
25088 + init_task.thread.request.u.thread.arg = NULL;
25089 + return(start_idle_thread((void *) init_task.thread.kernel_stack,
25090 + &init_task.thread.mode.skas.switch_buf,
25091 + &init_task.thread.mode.skas.fork_buf));
25094 +int external_pid_skas(struct task_struct *task)
25096 +#warning Need to look up userspace_pid by cpu
25097 + return(userspace_pid[0]);
25100 +int thread_pid_skas(struct thread_struct *thread)
25102 +#warning Need to look up userspace_pid by cpu
25103 + return(userspace_pid[0]);
25107 + * Overrides for Emacs so that we follow Linus's tabbing style.
25108 + * Emacs will notice this stuff at the end of the file and automatically
25109 + * adjust the settings for this buffer only. This must remain at the end
25111 + * ---------------------------------------------------------------------------
25112 + * Local variables:
25113 + * c-file-style: "linux"
25116 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_kern.c um/arch/um/kernel/skas/syscall_kern.c
25117 --- orig/arch/um/kernel/skas/syscall_kern.c 1969-12-31 19:00:00.000000000 -0500
25118 +++ um/arch/um/kernel/skas/syscall_kern.c 2003-10-21 03:26:07.000000000 -0400
25121 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
25122 + * Licensed under the GPL
25125 +#include "linux/sys.h"
25126 +#include "asm/errno.h"
25127 +#include "asm/unistd.h"
25128 +#include "asm/ptrace.h"
25129 +#include "asm/current.h"
25130 +#include "sysdep/syscalls.h"
25131 +#include "kern_util.h"
25133 +extern syscall_handler_t *sys_call_table[];
25135 +long execute_syscall_skas(void *r)
25137 + struct pt_regs *regs = r;
25141 + current->thread.nsyscalls++;
25143 + syscall = UPT_SYSCALL_NR(®s->regs);
25145 + if((syscall >= NR_syscalls) || (syscall < 0))
25147 + else res = EXECUTE_SYSCALL(syscall, regs);
25153 + * Overrides for Emacs so that we follow Linus's tabbing style.
25154 + * Emacs will notice this stuff at the end of the file and automatically
25155 + * adjust the settings for this buffer only. This must remain at the end
25157 + * ---------------------------------------------------------------------------
25158 + * Local variables:
25159 + * c-file-style: "linux"
25162 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_user.c um/arch/um/kernel/skas/syscall_user.c
25163 --- orig/arch/um/kernel/skas/syscall_user.c 1969-12-31 19:00:00.000000000 -0500
25164 +++ um/arch/um/kernel/skas/syscall_user.c 2003-10-21 03:26:07.000000000 -0400
25167 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25168 + * Licensed under the GPL
25171 +#include <stdlib.h>
25172 +#include <signal.h>
25173 +#include "kern_util.h"
25174 +#include "syscall_user.h"
25175 +#include "sysdep/ptrace.h"
25176 +#include "sysdep/sigcontext.h"
25179 +#define ERESTARTSYS 512
25180 +#define ERESTARTNOINTR 513
25181 +#define ERESTARTNOHAND 514
25183 +void handle_syscall(union uml_pt_regs *regs)
25188 + index = record_syscall_start(UPT_SYSCALL_NR(regs));
25191 + result = execute_syscall(regs);
25193 + REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
25194 + if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) ||
25195 + (result == -ERESTARTNOINTR))
25196 + do_signal(result);
25199 + record_syscall_end(index, result);
25203 + * Overrides for Emacs so that we follow Linus's tabbing style.
25204 + * Emacs will notice this stuff at the end of the file and automatically
25205 + * adjust the settings for this buffer only. This must remain at the end
25207 + * ---------------------------------------------------------------------------
25208 + * Local variables:
25209 + * c-file-style: "linux"
25212 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/Makefile um/arch/um/kernel/skas/sys-i386/Makefile
25213 --- orig/arch/um/kernel/skas/sys-i386/Makefile 1969-12-31 19:00:00.000000000 -0500
25214 +++ um/arch/um/kernel/skas/sys-i386/Makefile 2003-10-21 03:26:07.000000000 -0400
25217 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25218 +# Licensed under the GPL
25221 +O_TARGET = sys-i386.o
25223 +obj-y = sigcontext.o
25225 +USER_OBJS = sigcontext.o
25227 +include $(TOPDIR)/Rules.make
25229 +$(USER_OBJS) : %.o: %.c
25230 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
25233 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/sigcontext.c um/arch/um/kernel/skas/sys-i386/sigcontext.c
25234 --- orig/arch/um/kernel/skas/sys-i386/sigcontext.c 1969-12-31 19:00:00.000000000 -0500
25235 +++ um/arch/um/kernel/skas/sys-i386/sigcontext.c 2003-11-19 03:27:43.000000000 -0500
25238 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25239 + * Licensed under the GPL
25242 +#include <errno.h>
25243 +#include <asm/sigcontext.h>
25244 +#include <sys/ptrace.h>
25245 +#include <linux/ptrace.h>
25246 +#include "sysdep/ptrace.h"
25247 +#include "sysdep/ptrace_user.h"
25248 +#include "kern_util.h"
25250 +#include "sigcontext.h"
25253 +int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr)
25255 + struct sigcontext sc, *from = from_ptr;
25256 + unsigned long fpregs[FP_FRAME_SIZE];
25259 + err = copy_from_user_proc(&sc, from, sizeof(sc));
25260 + err |= copy_from_user_proc(fpregs, sc.fpstate, sizeof(fpregs));
25264 + regs->skas.regs[GS] = sc.gs;
25265 + regs->skas.regs[FS] = sc.fs;
25266 + regs->skas.regs[ES] = sc.es;
25267 + regs->skas.regs[DS] = sc.ds;
25268 + regs->skas.regs[EDI] = sc.edi;
25269 + regs->skas.regs[ESI] = sc.esi;
25270 + regs->skas.regs[EBP] = sc.ebp;
25271 + regs->skas.regs[UESP] = sc.esp;
25272 + regs->skas.regs[EBX] = sc.ebx;
25273 + regs->skas.regs[EDX] = sc.edx;
25274 + regs->skas.regs[ECX] = sc.ecx;
25275 + regs->skas.regs[EAX] = sc.eax;
25276 + regs->skas.regs[EIP] = sc.eip;
25277 + regs->skas.regs[CS] = sc.cs;
25278 + regs->skas.regs[EFL] = sc.eflags;
25279 + regs->skas.regs[SS] = sc.ss;
25280 + regs->skas.fault_addr = sc.cr2;
25281 + regs->skas.fault_type = FAULT_WRITE(sc.err);
25282 + regs->skas.trap_type = sc.trapno;
25284 + err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
25286 + printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
25287 + "errno = %d\n", errno);
25294 +int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp,
25295 + union uml_pt_regs *regs, unsigned long fault_addr,
25298 + struct sigcontext sc, *to = to_ptr;
25299 + struct _fpstate *to_fp;
25300 + unsigned long fpregs[FP_FRAME_SIZE];
25303 + sc.gs = regs->skas.regs[GS];
25304 + sc.fs = regs->skas.regs[FS];
25305 + sc.es = regs->skas.regs[ES];
25306 + sc.ds = regs->skas.regs[DS];
25307 + sc.edi = regs->skas.regs[EDI];
25308 + sc.esi = regs->skas.regs[ESI];
25309 + sc.ebp = regs->skas.regs[EBP];
25310 + sc.esp = regs->skas.regs[UESP];
25311 + sc.ebx = regs->skas.regs[EBX];
25312 + sc.edx = regs->skas.regs[EDX];
25313 + sc.ecx = regs->skas.regs[ECX];
25314 + sc.eax = regs->skas.regs[EAX];
25315 + sc.eip = regs->skas.regs[EIP];
25316 + sc.cs = regs->skas.regs[CS];
25317 + sc.eflags = regs->skas.regs[EFL];
25318 + sc.esp_at_signal = regs->skas.regs[UESP];
25319 + sc.ss = regs->skas.regs[SS];
25320 + sc.cr2 = fault_addr;
25321 + sc.err = TO_SC_ERR(fault_type);
25322 + sc.trapno = regs->skas.trap_type;
25324 + err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
25326 + printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
25327 + "errno = %d\n", errno);
25330 + to_fp = (struct _fpstate *)
25331 + (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
25332 + sc.fpstate = to_fp;
25337 + return(copy_to_user_proc(to, &sc, sizeof(sc)) ||
25338 + copy_to_user_proc(to_fp, fpregs, sizeof(fpregs)));
25342 + * Overrides for Emacs so that we follow Linus's tabbing style.
25343 + * Emacs will notice this stuff at the end of the file and automatically
25344 + * adjust the settings for this buffer only. This must remain at the end
25346 + * ---------------------------------------------------------------------------
25347 + * Local variables:
25348 + * c-file-style: "linux"
25351 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/time.c um/arch/um/kernel/skas/time.c
25352 --- orig/arch/um/kernel/skas/time.c 1969-12-31 19:00:00.000000000 -0500
25353 +++ um/arch/um/kernel/skas/time.c 2003-10-21 03:26:07.000000000 -0400
25356 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25357 + * Licensed under the GPL
25360 +#include <sys/signal.h>
25361 +#include <sys/time.h>
25362 +#include "time_user.h"
25363 +#include "process.h"
25366 +void user_time_init_skas(void)
25368 + if(signal(SIGALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
25369 + panic("Couldn't set SIGALRM handler");
25370 + if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
25371 + panic("Couldn't set SIGVTALRM handler");
25372 + set_interval(ITIMER_VIRTUAL);
25376 + * Overrides for Emacs so that we follow Linus's tabbing style.
25377 + * Emacs will notice this stuff at the end of the file and automatically
25378 + * adjust the settings for this buffer only. This must remain at the end
25380 + * ---------------------------------------------------------------------------
25381 + * Local variables:
25382 + * c-file-style: "linux"
25385 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/tlb.c um/arch/um/kernel/skas/tlb.c
25386 --- orig/arch/um/kernel/skas/tlb.c 1969-12-31 19:00:00.000000000 -0500
25387 +++ um/arch/um/kernel/skas/tlb.c 2003-10-21 03:26:07.000000000 -0400
25390 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25391 + * Licensed under the GPL
25394 +#include "linux/stddef.h"
25395 +#include "linux/sched.h"
25396 +#include "asm/page.h"
25397 +#include "asm/pgtable.h"
25398 +#include "asm/mmu.h"
25399 +#include "user_util.h"
25400 +#include "mem_user.h"
25404 +static void fix_range(struct mm_struct *mm, unsigned long start_addr,
25405 + unsigned long end_addr, int force)
25410 + unsigned long addr;
25411 + int r, w, x, err, fd;
25413 + if(mm == NULL) return;
25414 + fd = mm->context.skas.mm_fd;
25415 + for(addr = start_addr; addr < end_addr;){
25416 + npgd = pgd_offset(mm, addr);
25417 + npmd = pmd_offset(npgd, addr);
25418 + if(pmd_present(*npmd)){
25419 + npte = pte_offset(npmd, addr);
25420 + r = pte_read(*npte);
25421 + w = pte_write(*npte);
25422 + x = pte_exec(*npte);
25423 + if(!pte_dirty(*npte)) w = 0;
25424 + if(!pte_young(*npte)){
25428 + if(force || pte_newpage(*npte)){
25429 + err = unmap(fd, (void *) addr, PAGE_SIZE);
25431 + panic("munmap failed, errno = %d\n",
25433 + if(pte_present(*npte))
25435 + pte_val(*npte) & PAGE_MASK,
25436 + PAGE_SIZE, r, w, x);
25438 + else if(pte_newprot(*npte)){
25439 + protect(fd, addr, PAGE_SIZE, r, w, x, 1);
25441 + *npte = pte_mkuptodate(*npte);
25442 + addr += PAGE_SIZE;
25445 + if(force || pmd_newpage(*npmd)){
25446 + err = unmap(fd, (void *) addr, PMD_SIZE);
25448 + panic("munmap failed, errno = %d\n",
25450 + pmd_mkuptodate(*npmd);
25452 + addr += PMD_SIZE;
25457 +static void flush_kernel_vm_range(unsigned long start, unsigned long end)
25459 + struct mm_struct *mm;
25463 + unsigned long addr;
25464 + int updated = 0, err;
25467 + for(addr = start_vm; addr < end_vm;){
25468 + pgd = pgd_offset(mm, addr);
25469 + pmd = pmd_offset(pgd, addr);
25470 + if(pmd_present(*pmd)){
25471 + pte = pte_offset(pmd, addr);
25472 + if(!pte_present(*pte) || pte_newpage(*pte)){
25474 + err = os_unmap_memory((void *) addr,
25477 + panic("munmap failed, errno = %d\n",
25479 + if(pte_present(*pte))
25481 + pte_val(*pte) & PAGE_MASK,
25482 + PAGE_SIZE, 1, 1, 1);
25484 + else if(pte_newprot(*pte)){
25486 + protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
25488 + addr += PAGE_SIZE;
25491 + if(pmd_newpage(*pmd)){
25493 + err = os_unmap_memory((void *) addr, PMD_SIZE);
25495 + panic("munmap failed, errno = %d\n",
25498 + addr += PMD_SIZE;
25503 +void flush_tlb_kernel_vm_skas(void)
25505 + flush_kernel_vm_range(start_vm, end_vm);
25508 +void __flush_tlb_one_skas(unsigned long addr)
25510 + flush_kernel_vm_range(addr, addr + PAGE_SIZE);
25513 +void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start,
25514 + unsigned long end)
25517 + flush_kernel_vm_range(start, end);
25518 + else fix_range(mm, start, end, 0);
25521 +void flush_tlb_mm_skas(struct mm_struct *mm)
25523 + flush_tlb_kernel_vm_skas();
25524 + fix_range(mm, 0, host_task_size, 0);
25527 +void force_flush_all_skas(void)
25529 + fix_range(current->mm, 0, host_task_size, 1);
25533 + * Overrides for Emacs so that we follow Linus's tabbing style.
25534 + * Emacs will notice this stuff at the end of the file and automatically
25535 + * adjust the settings for this buffer only. This must remain at the end
25537 + * ---------------------------------------------------------------------------
25538 + * Local variables:
25539 + * c-file-style: "linux"
25542 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/trap_user.c um/arch/um/kernel/skas/trap_user.c
25543 --- orig/arch/um/kernel/skas/trap_user.c 1969-12-31 19:00:00.000000000 -0500
25544 +++ um/arch/um/kernel/skas/trap_user.c 2003-12-14 11:17:37.000000000 -0500
25547 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
25548 + * Licensed under the GPL
25551 +#include <signal.h>
25552 +#include <errno.h>
25553 +#include <asm/sigcontext.h>
25554 +#include "sysdep/ptrace.h"
25555 +#include "signal_user.h"
25556 +#include "user_util.h"
25557 +#include "kern_util.h"
25559 +#include "sigcontext.h"
25561 +void sig_handler_common_skas(int sig, void *sc_ptr)
25563 + struct sigcontext *sc = sc_ptr;
25564 + struct skas_regs *r;
25565 + struct signal_info *info;
25566 + int save_errno = errno;
25568 + r = &TASK_REGS(get_current())->skas;
25570 + r->fault_addr = SC_FAULT_ADDR(sc);
25571 + r->fault_type = SC_FAULT_TYPE(sc);
25572 + r->trap_type = SC_TRAP_TYPE(sc);
25574 + change_sig(SIGUSR1, 1);
25575 + info = &sig_info[sig];
25576 + if(!info->is_irq) unblock_signals();
25578 + (*info->handler)(sig, (union uml_pt_regs *) r);
25580 + errno = save_errno;
25583 +extern int missed_ticks[];
25585 +void user_signal(int sig, union uml_pt_regs *regs)
25587 + struct signal_info *info;
25589 + regs->skas.is_user = 1;
25590 + regs->skas.fault_addr = 0;
25591 + regs->skas.fault_type = 0;
25592 + regs->skas.trap_type = 0;
25593 + info = &sig_info[sig];
25594 + (*info->handler)(sig, regs);
25596 + unblock_signals();
25600 + * Overrides for Emacs so that we follow Linus's tabbing style.
25601 + * Emacs will notice this stuff at the end of the file and automatically
25602 + * adjust the settings for this buffer only. This must remain at the end
25604 + * ---------------------------------------------------------------------------
25605 + * Local variables:
25606 + * c-file-style: "linux"
25609 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/uaccess.c um/arch/um/kernel/skas/uaccess.c
25610 --- orig/arch/um/kernel/skas/uaccess.c 1969-12-31 19:00:00.000000000 -0500
25611 +++ um/arch/um/kernel/skas/uaccess.c 2003-11-11 11:11:26.000000000 -0500
25614 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
25615 + * Licensed under the GPL
25618 +#include "linux/stddef.h"
25619 +#include "linux/kernel.h"
25620 +#include "linux/string.h"
25621 +#include "linux/fs.h"
25622 +#include "linux/highmem.h"
25623 +#include "asm/page.h"
25624 +#include "asm/pgtable.h"
25625 +#include "asm/uaccess.h"
25626 +#include "kern_util.h"
25628 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
25631 +static unsigned long maybe_map(unsigned long virt, int is_write)
25635 + void *phys = um_virt_to_phys(current, virt, &pte);
25638 + if(IS_ERR(phys) || (is_write && !pte_write(pte))){
25639 + if(!handle_page_fault(virt, 0, is_write, 0, &dummy_code))
25641 + phys = um_virt_to_phys(current, virt, NULL);
25643 + return((unsigned long) phys);
25646 +static int do_op(unsigned long addr, int len, int is_write,
25647 + int (*op)(unsigned long addr, int len, void *arg), void *arg)
25649 + struct page *page;
25652 + addr = maybe_map(addr, is_write);
25656 + page = phys_to_page(addr);
25657 + addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
25658 + n = (*op)(addr, len, arg);
25664 +static int buffer_op(unsigned long addr, int len, int is_write,
25665 + int (*op)(unsigned long addr, int len, void *arg),
25668 + int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
25669 + int remain = len, n;
25671 + n = do_op(addr, size, is_write, op, arg);
25673 + return(n < 0 ? remain : 0);
25680 + while(addr < ((addr + remain) & PAGE_MASK)){
25681 + n = do_op(addr, PAGE_SIZE, is_write, op, arg);
25683 + return(n < 0 ? remain : 0);
25685 + addr += PAGE_SIZE;
25686 + remain -= PAGE_SIZE;
25691 + n = do_op(addr, remain, is_write, op, arg);
25693 + return(n < 0 ? remain : 0);
25697 +static int copy_chunk_from_user(unsigned long from, int len, void *arg)
25699 + unsigned long *to_ptr = arg, to = *to_ptr;
25701 + memcpy((void *) to, (void *) from, len);
25706 +int copy_from_user_skas(void *to, const void *from, int n)
25708 + if(segment_eq(get_fs(), KERNEL_DS)){
25709 + memcpy(to, from, n);
25713 + return(access_ok_skas(VERIFY_READ, from, n) ?
25714 + buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
25718 +static int copy_chunk_to_user(unsigned long to, int len, void *arg)
25720 + unsigned long *from_ptr = arg, from = *from_ptr;
25722 + memcpy((void *) to, (void *) from, len);
25723 + *from_ptr += len;
25727 +int copy_to_user_skas(void *to, const void *from, int n)
25729 + if(segment_eq(get_fs(), KERNEL_DS)){
25730 + memcpy(to, from, n);
25734 + return(access_ok_skas(VERIFY_WRITE, to, n) ?
25735 + buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
25739 +static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
25741 + char **to_ptr = arg, *to = *to_ptr;
25744 + strncpy(to, (void *) from, len);
25745 + n = strnlen(to, len);
25753 +int strncpy_from_user_skas(char *dst, const char *src, int count)
25758 + if(segment_eq(get_fs(), KERNEL_DS)){
25759 + strncpy(dst, src, count);
25760 + return(strnlen(dst, count));
25763 + if(!access_ok_skas(VERIFY_READ, src, 1))
25766 + n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
25770 + return(strnlen(dst, count));
25773 +static int clear_chunk(unsigned long addr, int len, void *unused)
25775 + memset((void *) addr, 0, len);
25779 +int __clear_user_skas(void *mem, int len)
25781 + return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
25784 +int clear_user_skas(void *mem, int len)
25786 + if(segment_eq(get_fs(), KERNEL_DS)){
25787 + memset(mem, 0, len);
25791 + return(access_ok_skas(VERIFY_WRITE, mem, len) ?
25792 + buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
25795 +static int strnlen_chunk(unsigned long str, int len, void *arg)
25797 + int *len_ptr = arg, n;
25799 + n = strnlen((void *) str, len);
25807 +int strnlen_user_skas(const void *str, int len)
25809 + int count = 0, n;
25811 + if(segment_eq(get_fs(), KERNEL_DS))
25812 + return(strnlen(str, len) + 1);
25814 + n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
25816 + return(count + 1);
25821 + * Overrides for Emacs so that we follow Linus's tabbing style.
25822 + * Emacs will notice this stuff at the end of the file and automatically
25823 + * adjust the settings for this buffer only. This must remain at the end
25825 + * ---------------------------------------------------------------------------
25826 + * Local variables:
25827 + * c-file-style: "linux"
25830 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/Makefile um/arch/um/kernel/skas/util/Makefile
25831 --- orig/arch/um/kernel/skas/util/Makefile 1969-12-31 19:00:00.000000000 -0500
25832 +++ um/arch/um/kernel/skas/util/Makefile 2003-11-08 02:52:22.000000000 -0500
25836 +mk_ptregs : mk_ptregs.o
25837 + $(HOSTCC) -o mk_ptregs mk_ptregs.o
25839 +mk_ptregs.o : mk_ptregs.c
25843 + $(RM) -f mk_ptregs *.o *~
25844 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/mk_ptregs.c um/arch/um/kernel/skas/util/mk_ptregs.c
25845 --- orig/arch/um/kernel/skas/util/mk_ptregs.c 1969-12-31 19:00:00.000000000 -0500
25846 +++ um/arch/um/kernel/skas/util/mk_ptregs.c 2003-10-21 03:26:07.000000000 -0400
25848 +#include <asm/ptrace.h>
25849 +#include <asm/user.h>
25851 +#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val))
25853 +int main(int argc, char **argv)
25855 + printf("/* Automatically generated by "
25856 + "arch/um/kernel/skas/util/mk_ptregs */\n");
25858 + printf("#ifndef __SKAS_PT_REGS_\n");
25859 + printf("#define __SKAS_PT_REGS_\n");
25861 + printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE);
25862 + printf("#define HOST_FP_SIZE %d\n",
25863 + sizeof(struct user_i387_struct) / sizeof(unsigned long));
25864 + printf("#define HOST_XFP_SIZE %d\n",
25865 + sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
25867 + PRINT_REG("IP", EIP);
25868 + PRINT_REG("SP", UESP);
25869 + PRINT_REG("EFLAGS", EFL);
25870 + PRINT_REG("EAX", EAX);
25871 + PRINT_REG("EBX", EBX);
25872 + PRINT_REG("ECX", ECX);
25873 + PRINT_REG("EDX", EDX);
25874 + PRINT_REG("ESI", ESI);
25875 + PRINT_REG("EDI", EDI);
25876 + PRINT_REG("EBP", EBP);
25877 + PRINT_REG("CS", CS);
25878 + PRINT_REG("SS", SS);
25879 + PRINT_REG("DS", DS);
25880 + PRINT_REG("FS", FS);
25881 + PRINT_REG("ES", ES);
25882 + PRINT_REG("GS", GS);
25884 + printf("#endif\n");
25889 + * Overrides for Emacs so that we follow Linus's tabbing style.
25890 + * Emacs will notice this stuff at the end of the file and automatically
25891 + * adjust the settings for this buffer only. This must remain at the end
25893 + * ---------------------------------------------------------------------------
25894 + * Local variables:
25895 + * c-file-style: "linux"
25898 diff -Naur -X ../exclude-files orig/arch/um/kernel/smp.c um/arch/um/kernel/smp.c
25899 --- orig/arch/um/kernel/smp.c 1969-12-31 19:00:00.000000000 -0500
25900 +++ um/arch/um/kernel/smp.c 2003-11-15 02:59:25.000000000 -0500
25903 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
25904 + * Licensed under the GPL
25907 +#include "linux/config.h"
25911 +#include "linux/sched.h"
25912 +#include "linux/threads.h"
25913 +#include "linux/interrupt.h"
25914 +#include "asm/smp.h"
25915 +#include "asm/processor.h"
25916 +#include "asm/spinlock.h"
25917 +#include "asm/softirq.h"
25918 +#include "asm/hardirq.h"
25919 +#include "asm/tlb.h"
25920 +#include "user_util.h"
25921 +#include "kern_util.h"
25922 +#include "irq_user.h"
25926 +/* Total count of live CPUs, set by smp_boot_cpus */
25927 +int smp_num_cpus = 1;
25929 +/* The 'big kernel lock' */
25930 +spinlock_cacheline_t kernel_flag_cacheline = {SPIN_LOCK_UNLOCKED};
25932 +/* Per CPU bogomips and other parameters */
25934 +/* The only piece used here is the ipi pipe, which is set before SMP is
25935 + * started and never changed.
25937 +struct cpuinfo_um cpu_data[NR_CPUS];
25939 +/* CPU online map, set by smp_boot_cpus */
25940 +unsigned long cpu_online_map;
25942 +atomic_t global_bh_count;
25944 +/* Set when the idlers are all forked */
25945 +int smp_threads_ready = 0;
25947 +/* Not used by UML */
25948 +unsigned char global_irq_holder = 0;
25949 +unsigned volatile long global_irq_lock;
25951 +/* A statistic, can be a little off */
25952 +static int num_reschedules_sent = 0;
25954 +mmu_gather_t mmu_gathers[NR_CPUS];
25956 +void smp_send_reschedule(int cpu)
25958 + os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1);
25959 + num_reschedules_sent++;
25962 +static void show(char * str)
25964 + int cpu = smp_processor_id();
25966 + printk(KERN_INFO "\n%s, CPU %d:\n", str, cpu);
25969 +#define MAXCOUNT 100000000
25971 +static inline void wait_on_bh(void)
25973 + int count = MAXCOUNT;
25976 + show("wait_on_bh");
25979 + /* nothing .. wait for the other bh's to go away */
25980 + } while (atomic_read(&global_bh_count) != 0);
25984 + * This is called when we want to synchronize with
25985 + * bottom half handlers. We need to wait until
25986 + * no other CPU is executing any bottom half handler.
25988 + * Don't wait if we're already running in an interrupt
25989 + * context or are inside a bh handler.
25991 +void synchronize_bh(void)
25993 + if (atomic_read(&global_bh_count) && !in_interrupt())
25997 +void smp_send_stop(void)
26001 + printk(KERN_INFO "Stopping all CPUs...");
26002 + for(i = 0; i < ncpus; i++){
26003 + if(i == current->processor)
26005 + os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
26007 + printk("done\n");
26011 +static atomic_t smp_commenced = ATOMIC_INIT(0);
26012 +static volatile unsigned long smp_callin_map = 0;
26014 +void smp_commence(void)
26016 + printk("All CPUs are go!\n");
26019 + atomic_set(&smp_commenced, 1);
26022 +static int idle_proc(void *unused)
26026 + set_current(current);
26027 + del_from_runqueue(current);
26028 + unhash_process(current);
26030 + cpu = current->processor;
26031 + err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
26033 + panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
26035 + activate_ipi(cpu_data[cpu].ipi_pipe[0],
26036 + current->thread.mode.tt.extern_pid);
26039 + if (test_and_set_bit(current->processor, &smp_callin_map)) {
26040 + printk("huh, CPU#%d already present??\n", current->processor);
26044 + while (!atomic_read(&smp_commenced))
26052 +static int idle_thread(int (*fn)(void *), int cpu)
26054 + struct task_struct *new_task;
26058 + current->thread.request.u.thread.proc = fn;
26059 + current->thread.request.u.thread.arg = NULL;
26060 + pid = do_fork(CLONE_VM | CLONE_PID, 0, NULL, 0);
26062 + panic("do_fork failed in idle_thread");
26063 + new_task = get_task(pid, 1);
26065 + cpu_tasks[cpu] = ((struct cpu_task)
26066 + { .pid = new_task->thread.mode.tt.extern_pid,
26067 + .task = new_task } );
26068 + init_tasks[cpu] = new_task;
26069 + new_task->processor = cpu;
26070 + new_task->cpus_allowed = 1 << cpu;
26071 + new_task->cpus_runnable = new_task->cpus_allowed;
26072 + CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c,
26074 + ({ panic("skas mode doesn't support SMP"); }));
26075 + return(new_task->thread.mode.tt.extern_pid);
26078 +void smp_boot_cpus(void)
26082 + set_bit(0, &cpu_online_map);
26083 + set_bit(0, &smp_callin_map);
26085 + err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
26087 + panic("CPU#0 failed to create IPI pipe, err = %d", -err);
26089 + activate_ipi(cpu_data[0].ipi_pipe[0],
26090 + current->thread.mode.tt.extern_pid);
26093 + printk(KERN_INFO "ncpus set to 1\n");
26096 + else if(ncpus > NR_CPUS){
26098 + "ncpus can't be greater than NR_CPUS, set to %d\n",
26106 + printk(KERN_INFO "Starting up other processors:\n");
26107 + for(i=1;i<ncpus;i++){
26110 + /* Do this early, for hard_smp_processor_id() */
26111 + cpu_tasks[i].pid = -1;
26112 + set_bit(i, &cpu_online_map);
26115 + pid = idle_thread(idle_proc, i);
26116 + printk(KERN_INFO "\t#%d - idle thread pid = %d.. ",
26119 + waittime = 200000000;
26120 + while (waittime-- && !test_bit(i, &smp_callin_map))
26123 + if (test_bit(i, &smp_callin_map))
26124 + printk("online\n");
26126 + printk("failed\n");
26127 + clear_bit(i, &cpu_online_map);
26133 +int setup_profiling_timer(unsigned int multiplier)
26135 + printk(KERN_INFO "setup_profiling_timer\n");
26139 +void smp_call_function_slave(int cpu);
26141 +void IPI_handler(int cpu)
26146 + fd = cpu_data[cpu].ipi_pipe[0];
26147 + while (os_read_file(fd, &c, 1) == 1) {
26150 + smp_call_function_slave(cpu);
26154 + current->need_resched = 1;
26158 + printk("CPU#%d stopping\n", cpu);
26164 + printk("CPU#%d received unknown IPI [%c]!\n", cpu, c);
26170 +int hard_smp_processor_id(void)
26172 + return(pid_to_processor_id(os_getpid()));
26175 +static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
26176 +static atomic_t scf_started;
26177 +static atomic_t scf_finished;
26178 +static void (*func)(void *info);
26179 +static void *info;
26181 +void smp_call_function_slave(int cpu)
26183 + atomic_inc(&scf_started);
26185 + atomic_inc(&scf_finished);
26188 +int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic,
26191 + int cpus = smp_num_cpus - 1;
26197 + spin_lock_bh(&call_lock);
26198 + atomic_set(&scf_started, 0);
26199 + atomic_set(&scf_finished, 0);
26203 + for (i=0;i<NR_CPUS;i++)
26204 + if (i != current->processor && test_bit(i, &cpu_online_map))
26205 + os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
26207 + while (atomic_read(&scf_started) != cpus)
26211 + while (atomic_read(&scf_finished) != cpus)
26214 + spin_unlock_bh(&call_lock);
26221 + * Overrides for Emacs so that we follow Linus's tabbing style.
26222 + * Emacs will notice this stuff at the end of the file and automatically
26223 + * adjust the settings for this buffer only. This must remain at the end
26225 + * ---------------------------------------------------------------------------
26226 + * Local variables:
26227 + * c-file-style: "linux"
26230 diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_kern.c um/arch/um/kernel/syscall_kern.c
26231 --- orig/arch/um/kernel/syscall_kern.c 1969-12-31 19:00:00.000000000 -0500
26232 +++ um/arch/um/kernel/syscall_kern.c 2003-11-07 01:41:13.000000000 -0500
26235 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
26236 + * Licensed under the GPL
26239 +#include "linux/sched.h"
26240 +#include "linux/file.h"
26241 +#include "linux/smp_lock.h"
26242 +#include "linux/mm.h"
26243 +#include "linux/utsname.h"
26244 +#include "linux/msg.h"
26245 +#include "linux/shm.h"
26246 +#include "linux/sys.h"
26247 +#include "linux/unistd.h"
26248 +#include "linux/slab.h"
26249 +#include "linux/utime.h"
26250 +#include "asm/mman.h"
26251 +#include "asm/uaccess.h"
26252 +#include "asm/ipc.h"
26253 +#include "kern_util.h"
26254 +#include "user_util.h"
26255 +#include "sysdep/syscalls.h"
26256 +#include "mode_kern.h"
26257 +#include "choose-mode.h"
26259 +/* Unlocked, I don't care if this is a bit off */
26260 +int nsyscalls = 0;
26262 +long um_mount(char * dev_name, char * dir_name, char * type,
26263 + unsigned long new_flags, void * data)
26265 + if(type == NULL) type = "";
26266 + return(sys_mount(dev_name, dir_name, type, new_flags, data));
26269 +long sys_fork(void)
26273 + current->thread.forking = 1;
26274 + ret = do_fork(SIGCHLD, 0, NULL, 0);
26275 + current->thread.forking = 0;
26279 +long sys_clone(unsigned long clone_flags, unsigned long newsp)
26283 + current->thread.forking = 1;
26284 + ret = do_fork(clone_flags, newsp, NULL, 0);
26285 + current->thread.forking = 0;
26289 +long sys_vfork(void)
26293 + current->thread.forking = 1;
26294 + ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0);
26295 + current->thread.forking = 0;
26299 +/* common code for old and new mmaps */
26300 +long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
26301 + unsigned long prot, unsigned long flags, unsigned long fd,
26302 + unsigned long pgoff)
26304 + int error = -EBADF;
26305 + struct file * file = NULL;
26307 + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
26308 + if (!(flags & MAP_ANONYMOUS)) {
26314 + down_write(&mm->mmap_sem);
26315 + error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
26316 + up_write(&mm->mmap_sem);
26324 +long sys_mmap2(unsigned long addr, unsigned long len,
26325 + unsigned long prot, unsigned long flags,
26326 + unsigned long fd, unsigned long pgoff)
26328 + return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
26332 + * Perform the select(nd, in, out, ex, tv) and mmap() system
26333 + * calls. Linux/i386 didn't use to be able to handle more than
26334 + * 4 system call parameters, so these system calls used a memory
26335 + * block for parameter passing..
26338 +struct mmap_arg_struct {
26339 + unsigned long addr;
26340 + unsigned long len;
26341 + unsigned long prot;
26342 + unsigned long flags;
26343 + unsigned long fd;
26344 + unsigned long offset;
26347 +int old_mmap(unsigned long addr, unsigned long len,
26348 + unsigned long prot, unsigned long flags,
26349 + unsigned long fd, unsigned long offset)
26351 + int err = -EINVAL;
26352 + if (offset & ~PAGE_MASK)
26355 + err = do_mmap2(current->mm, addr, len, prot, flags, fd,
26356 + offset >> PAGE_SHIFT);
26361 + * sys_pipe() is the normal C calling standard for creating
26362 + * a pipe. It's not the way unix traditionally does this, though.
26364 +int sys_pipe(unsigned long * fildes)
26369 + error = do_pipe(fd);
26371 + if (copy_to_user(fildes, fd, sizeof(fd)))
26377 +int sys_pause(void)
26379 + current->state = TASK_INTERRUPTIBLE;
26381 + return -ERESTARTNOHAND;
26384 +int sys_sigaction(int sig, const struct old_sigaction *act,
26385 + struct old_sigaction *oact)
26387 + struct k_sigaction new_ka, old_ka;
26391 + old_sigset_t mask;
26392 + if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
26393 + __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
26394 + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
26396 + __get_user(new_ka.sa.sa_flags, &act->sa_flags);
26397 + __get_user(mask, &act->sa_mask);
26398 + siginitset(&new_ka.sa.sa_mask, mask);
26401 + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
26403 + if (!ret && oact) {
26404 + if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
26405 + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
26406 + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
26408 + __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
26409 + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
26416 + * sys_ipc() is the de-multiplexer for the SysV IPC calls..
26418 + * This is really horribly ugly.
26420 +int sys_ipc (uint call, int first, int second,
26421 + int third, void *ptr, long fifth)
26423 + int version, ret;
26425 + version = call >> 16; /* hack for backward compatibility */
26430 + return sys_semop (first, (struct sembuf *)ptr, second);
26432 + return sys_semget (first, second, third);
26434 + union semun fourth;
26437 + if (get_user(fourth.__pad, (void **) ptr))
26439 + return sys_semctl (first, second, third, fourth);
26443 + return sys_msgsnd (first, (struct msgbuf *) ptr,
26446 + switch (version) {
26448 + struct ipc_kludge tmp;
26452 + if (copy_from_user(&tmp,
26453 + (struct ipc_kludge *) ptr,
26456 + return sys_msgrcv (first, tmp.msgp, second,
26457 + tmp.msgtyp, third);
26460 + panic("msgrcv with version != 0");
26461 + return sys_msgrcv (first,
26462 + (struct msgbuf *) ptr,
26463 + second, fifth, third);
26466 + return sys_msgget ((key_t) first, second);
26468 + return sys_msgctl (first, second, (struct msqid_ds *) ptr);
26471 + switch (version) {
26474 + ret = sys_shmat (first, (char *) ptr, second, &raddr);
26477 + return put_user (raddr, (ulong *) third);
26479 + case 1: /* iBCS2 emulator entry point */
26480 + if (!segment_eq(get_fs(), get_ds()))
26482 + return sys_shmat (first, (char *) ptr, second, (ulong *) third);
26485 + return sys_shmdt ((char *)ptr);
26487 + return sys_shmget (first, second, third);
26489 + return sys_shmctl (first, second,
26490 + (struct shmid_ds *) ptr);
26496 +int sys_uname(struct old_utsname * name)
26501 + down_read(&uts_sem);
26502 + err=copy_to_user(name, &system_utsname, sizeof (*name));
26503 + up_read(&uts_sem);
26504 + return err?-EFAULT:0;
26507 +int sys_olduname(struct oldold_utsname * name)
26513 + if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
26516 + down_read(&uts_sem);
26518 + error = __copy_to_user(&name->sysname,&system_utsname.sysname,
26520 + error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
26521 + error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
26523 + error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
26524 + error |= __copy_to_user(&name->release,&system_utsname.release,
26526 + error |= __put_user(0,name->release+__OLD_UTS_LEN);
26527 + error |= __copy_to_user(&name->version,&system_utsname.version,
26529 + error |= __put_user(0,name->version+__OLD_UTS_LEN);
26530 + error |= __copy_to_user(&name->machine,&system_utsname.machine,
26532 + error |= __put_user(0,name->machine+__OLD_UTS_LEN);
26534 + up_read(&uts_sem);
26536 + error = error ? -EFAULT : 0;
26541 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
26543 + return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
26546 +long execute_syscall(void *r)
26548 + return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
26551 +spinlock_t syscall_lock = SPIN_LOCK_UNLOCKED;
26553 +static int syscall_index = 0;
26555 +int next_syscall_index(int limit)
26559 + spin_lock(&syscall_lock);
26560 + ret = syscall_index;
26561 + if(++syscall_index == limit)
26562 + syscall_index = 0;
26563 + spin_unlock(&syscall_lock);
26568 + * Overrides for Emacs so that we follow Linus's tabbing style.
26569 + * Emacs will notice this stuff at the end of the file and automatically
26570 + * adjust the settings for this buffer only. This must remain at the end
26572 + * ---------------------------------------------------------------------------
26573 + * Local variables:
26574 + * c-file-style: "linux"
26577 diff -Naur -X ../exclude-files orig/arch/um/kernel/sys_call_table.c um/arch/um/kernel/sys_call_table.c
26578 --- orig/arch/um/kernel/sys_call_table.c 1969-12-31 19:00:00.000000000 -0500
26579 +++ um/arch/um/kernel/sys_call_table.c 2003-10-21 03:26:07.000000000 -0400
26582 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
26583 + * Licensed under the GPL
26586 +#include "linux/unistd.h"
26587 +#include "linux/version.h"
26588 +#include "linux/sys.h"
26589 +#include "asm/signal.h"
26590 +#include "sysdep/syscalls.h"
26591 +#include "kern_util.h"
26593 +extern syscall_handler_t sys_ni_syscall;
26594 +extern syscall_handler_t sys_exit;
26595 +extern syscall_handler_t sys_fork;
26596 +extern syscall_handler_t sys_creat;
26597 +extern syscall_handler_t sys_link;
26598 +extern syscall_handler_t sys_unlink;
26599 +extern syscall_handler_t sys_chdir;
26600 +extern syscall_handler_t sys_mknod;
26601 +extern syscall_handler_t sys_chmod;
26602 +extern syscall_handler_t sys_lchown16;
26603 +extern syscall_handler_t sys_ni_syscall;
26604 +extern syscall_handler_t sys_stat;
26605 +extern syscall_handler_t sys_getpid;
26606 +extern syscall_handler_t sys_oldumount;
26607 +extern syscall_handler_t sys_setuid16;
26608 +extern syscall_handler_t sys_getuid16;
26609 +extern syscall_handler_t sys_ptrace;
26610 +extern syscall_handler_t sys_alarm;
26611 +extern syscall_handler_t sys_fstat;
26612 +extern syscall_handler_t sys_pause;
26613 +extern syscall_handler_t sys_utime;
26614 +extern syscall_handler_t sys_ni_syscall;
26615 +extern syscall_handler_t sys_ni_syscall;
26616 +extern syscall_handler_t sys_access;
26617 +extern syscall_handler_t sys_nice;
26618 +extern syscall_handler_t sys_ni_syscall;
26619 +extern syscall_handler_t sys_sync;
26620 +extern syscall_handler_t sys_kill;
26621 +extern syscall_handler_t sys_rename;
26622 +extern syscall_handler_t sys_mkdir;
26623 +extern syscall_handler_t sys_rmdir;
26624 +extern syscall_handler_t sys_pipe;
26625 +extern syscall_handler_t sys_times;
26626 +extern syscall_handler_t sys_ni_syscall;
26627 +extern syscall_handler_t sys_brk;
26628 +extern syscall_handler_t sys_setgid16;
26629 +extern syscall_handler_t sys_getgid16;
26630 +extern syscall_handler_t sys_signal;
26631 +extern syscall_handler_t sys_geteuid16;
26632 +extern syscall_handler_t sys_getegid16;
26633 +extern syscall_handler_t sys_acct;
26634 +extern syscall_handler_t sys_umount;
26635 +extern syscall_handler_t sys_ni_syscall;
26636 +extern syscall_handler_t sys_ioctl;
26637 +extern syscall_handler_t sys_fcntl;
26638 +extern syscall_handler_t sys_ni_syscall;
26639 +extern syscall_handler_t sys_setpgid;
26640 +extern syscall_handler_t sys_ni_syscall;
26641 +extern syscall_handler_t sys_olduname;
26642 +extern syscall_handler_t sys_umask;
26643 +extern syscall_handler_t sys_chroot;
26644 +extern syscall_handler_t sys_ustat;
26645 +extern syscall_handler_t sys_dup2;
26646 +extern syscall_handler_t sys_getppid;
26647 +extern syscall_handler_t sys_getpgrp;
26648 +extern syscall_handler_t sys_sigaction;
26649 +extern syscall_handler_t sys_sgetmask;
26650 +extern syscall_handler_t sys_ssetmask;
26651 +extern syscall_handler_t sys_setreuid16;
26652 +extern syscall_handler_t sys_setregid16;
26653 +extern syscall_handler_t sys_sigsuspend;
26654 +extern syscall_handler_t sys_sigpending;
26655 +extern syscall_handler_t sys_sethostname;
26656 +extern syscall_handler_t sys_setrlimit;
26657 +extern syscall_handler_t sys_old_getrlimit;
26658 +extern syscall_handler_t sys_getrusage;
26659 +extern syscall_handler_t sys_gettimeofday;
26660 +extern syscall_handler_t sys_settimeofday;
26661 +extern syscall_handler_t sys_getgroups16;
26662 +extern syscall_handler_t sys_setgroups16;
26663 +extern syscall_handler_t sys_symlink;
26664 +extern syscall_handler_t sys_lstat;
26665 +extern syscall_handler_t sys_readlink;
26666 +extern syscall_handler_t sys_uselib;
26667 +extern syscall_handler_t sys_swapon;
26668 +extern syscall_handler_t sys_reboot;
26669 +extern syscall_handler_t old_readdir;
26670 +extern syscall_handler_t sys_munmap;
26671 +extern syscall_handler_t sys_truncate;
26672 +extern syscall_handler_t sys_ftruncate;
26673 +extern syscall_handler_t sys_fchmod;
26674 +extern syscall_handler_t sys_fchown16;
26675 +extern syscall_handler_t sys_getpriority;
26676 +extern syscall_handler_t sys_setpriority;
26677 +extern syscall_handler_t sys_ni_syscall;
26678 +extern syscall_handler_t sys_statfs;
26679 +extern syscall_handler_t sys_fstatfs;
26680 +extern syscall_handler_t sys_ni_syscall;
26681 +extern syscall_handler_t sys_socketcall;
26682 +extern syscall_handler_t sys_syslog;
26683 +extern syscall_handler_t sys_setitimer;
26684 +extern syscall_handler_t sys_getitimer;
26685 +extern syscall_handler_t sys_newstat;
26686 +extern syscall_handler_t sys_newlstat;
26687 +extern syscall_handler_t sys_newfstat;
26688 +extern syscall_handler_t sys_uname;
26689 +extern syscall_handler_t sys_ni_syscall;
26690 +extern syscall_handler_t sys_vhangup;
26691 +extern syscall_handler_t sys_ni_syscall;
26692 +extern syscall_handler_t sys_ni_syscall;
26693 +extern syscall_handler_t sys_swapoff;
26694 +extern syscall_handler_t sys_sysinfo;
26695 +extern syscall_handler_t sys_ipc;
26696 +extern syscall_handler_t sys_fsync;
26697 +extern syscall_handler_t sys_sigreturn;
26698 +extern syscall_handler_t sys_rt_sigreturn;
26699 +extern syscall_handler_t sys_clone;
26700 +extern syscall_handler_t sys_setdomainname;
26701 +extern syscall_handler_t sys_newuname;
26702 +extern syscall_handler_t sys_ni_syscall;
26703 +extern syscall_handler_t sys_adjtimex;
26704 +extern syscall_handler_t sys_mprotect;
26705 +extern syscall_handler_t sys_sigprocmask;
26706 +extern syscall_handler_t sys_create_module;
26707 +extern syscall_handler_t sys_init_module;
26708 +extern syscall_handler_t sys_delete_module;
26709 +extern syscall_handler_t sys_get_kernel_syms;
26710 +extern syscall_handler_t sys_quotactl;
26711 +extern syscall_handler_t sys_getpgid;
26712 +extern syscall_handler_t sys_fchdir;
26713 +extern syscall_handler_t sys_bdflush;
26714 +extern syscall_handler_t sys_sysfs;
26715 +extern syscall_handler_t sys_personality;
26716 +extern syscall_handler_t sys_ni_syscall;
26717 +extern syscall_handler_t sys_setfsuid16;
26718 +extern syscall_handler_t sys_setfsgid16;
26719 +extern syscall_handler_t sys_llseek;
26720 +extern syscall_handler_t sys_getdents;
26721 +extern syscall_handler_t sys_flock;
26722 +extern syscall_handler_t sys_msync;
26723 +extern syscall_handler_t sys_readv;
26724 +extern syscall_handler_t sys_writev;
26725 +extern syscall_handler_t sys_getsid;
26726 +extern syscall_handler_t sys_fdatasync;
26727 +extern syscall_handler_t sys_sysctl;
26728 +extern syscall_handler_t sys_mlock;
26729 +extern syscall_handler_t sys_munlock;
26730 +extern syscall_handler_t sys_mlockall;
26731 +extern syscall_handler_t sys_munlockall;
26732 +extern syscall_handler_t sys_sched_setparam;
26733 +extern syscall_handler_t sys_sched_getparam;
26734 +extern syscall_handler_t sys_sched_setscheduler;
26735 +extern syscall_handler_t sys_sched_getscheduler;
26736 +extern syscall_handler_t sys_sched_get_priority_max;
26737 +extern syscall_handler_t sys_sched_get_priority_min;
26738 +extern syscall_handler_t sys_sched_rr_get_interval;
26739 +extern syscall_handler_t sys_nanosleep;
26740 +extern syscall_handler_t sys_mremap;
26741 +extern syscall_handler_t sys_setresuid16;
26742 +extern syscall_handler_t sys_getresuid16;
26743 +extern syscall_handler_t sys_ni_syscall;
26744 +extern syscall_handler_t sys_query_module;
26745 +extern syscall_handler_t sys_poll;
26746 +extern syscall_handler_t sys_nfsservctl;
26747 +extern syscall_handler_t sys_setresgid16;
26748 +extern syscall_handler_t sys_getresgid16;
26749 +extern syscall_handler_t sys_prctl;
26750 +extern syscall_handler_t sys_ni_syscall;
26751 +extern syscall_handler_t sys_rt_sigaction;
26752 +extern syscall_handler_t sys_rt_sigprocmask;
26753 +extern syscall_handler_t sys_rt_sigpending;
26754 +extern syscall_handler_t sys_rt_sigtimedwait;
26755 +extern syscall_handler_t sys_rt_sigqueueinfo;
26756 +extern syscall_handler_t sys_rt_sigsuspend;
26757 +extern syscall_handler_t sys_pread;
26758 +extern syscall_handler_t sys_pwrite;
26759 +extern syscall_handler_t sys_chown16;
26760 +extern syscall_handler_t sys_getcwd;
26761 +extern syscall_handler_t sys_capget;
26762 +extern syscall_handler_t sys_capset;
26763 +extern syscall_handler_t sys_sigaltstack;
26764 +extern syscall_handler_t sys_sendfile;
26765 +extern syscall_handler_t sys_ni_syscall;
26766 +extern syscall_handler_t sys_ni_syscall;
26767 +extern syscall_handler_t sys_vfork;
26768 +extern syscall_handler_t sys_getrlimit;
26769 +extern syscall_handler_t sys_mmap2;
26770 +extern syscall_handler_t sys_truncate64;
26771 +extern syscall_handler_t sys_ftruncate64;
26772 +extern syscall_handler_t sys_stat64;
26773 +extern syscall_handler_t sys_lstat64;
26774 +extern syscall_handler_t sys_fstat64;
26775 +extern syscall_handler_t sys_lchown;
26776 +extern syscall_handler_t sys_getuid;
26777 +extern syscall_handler_t sys_getgid;
26778 +extern syscall_handler_t sys_geteuid;
26779 +extern syscall_handler_t sys_getegid;
26780 +extern syscall_handler_t sys_setreuid;
26781 +extern syscall_handler_t sys_setregid;
26782 +extern syscall_handler_t sys_getgroups;
26783 +extern syscall_handler_t sys_setgroups;
26784 +extern syscall_handler_t sys_fchown;
26785 +extern syscall_handler_t sys_setresuid;
26786 +extern syscall_handler_t sys_getresuid;
26787 +extern syscall_handler_t sys_setresgid;
26788 +extern syscall_handler_t sys_getresgid;
26789 +extern syscall_handler_t sys_chown;
26790 +extern syscall_handler_t sys_setuid;
26791 +extern syscall_handler_t sys_setgid;
26792 +extern syscall_handler_t sys_setfsuid;
26793 +extern syscall_handler_t sys_setfsgid;
26794 +extern syscall_handler_t sys_pivot_root;
26795 +extern syscall_handler_t sys_mincore;
26796 +extern syscall_handler_t sys_madvise;
26797 +extern syscall_handler_t sys_fcntl64;
26798 +extern syscall_handler_t sys_getdents64;
26799 +extern syscall_handler_t sys_gettid;
26800 +extern syscall_handler_t sys_readahead;
26801 +extern syscall_handler_t sys_tkill;
26802 +extern syscall_handler_t sys_setxattr;
26803 +extern syscall_handler_t sys_lsetxattr;
26804 +extern syscall_handler_t sys_fsetxattr;
26805 +extern syscall_handler_t sys_getxattr;
26806 +extern syscall_handler_t sys_lgetxattr;
26807 +extern syscall_handler_t sys_fgetxattr;
26808 +extern syscall_handler_t sys_listxattr;
26809 +extern syscall_handler_t sys_llistxattr;
26810 +extern syscall_handler_t sys_flistxattr;
26811 +extern syscall_handler_t sys_removexattr;
26812 +extern syscall_handler_t sys_lremovexattr;
26813 +extern syscall_handler_t sys_fremovexattr;
26814 +extern syscall_handler_t sys_sendfile64;
26816 +extern syscall_handler_t um_mount;
26817 +extern syscall_handler_t um_time;
26818 +extern syscall_handler_t um_stime;
26820 +#define LAST_GENERIC_SYSCALL __NR_exit_group
26822 +#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
26823 +#define LAST_SYSCALL LAST_GENERIC_SYSCALL
26825 +#define LAST_SYSCALL LAST_ARCH_SYSCALL
26828 +syscall_handler_t *sys_call_table[] = {
26829 + [ 0 ] = sys_ni_syscall,
26830 + [ __NR_exit ] = sys_exit,
26831 + [ __NR_fork ] = sys_fork,
26832 + [ __NR_read ] = (syscall_handler_t *) sys_read,
26833 + [ __NR_write ] = (syscall_handler_t *) sys_write,
26835 + /* These three are declared differently in asm/unistd.h */
26836 + [ __NR_open ] = (syscall_handler_t *) sys_open,
26837 + [ __NR_close ] = (syscall_handler_t *) sys_close,
26838 + [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid,
26839 + [ __NR_creat ] = sys_creat,
26840 + [ __NR_link ] = sys_link,
26841 + [ __NR_unlink ] = sys_unlink,
26843 + /* declared differently in kern_util.h */
26844 + [ __NR_execve ] = (syscall_handler_t *) sys_execve,
26845 + [ __NR_chdir ] = sys_chdir,
26846 + [ __NR_time ] = um_time,
26847 + [ __NR_mknod ] = sys_mknod,
26848 + [ __NR_chmod ] = sys_chmod,
26849 + [ __NR_lchown ] = sys_lchown16,
26850 + [ __NR_break ] = sys_ni_syscall,
26851 + [ __NR_oldstat ] = sys_stat,
26852 + [ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
26853 + [ __NR_getpid ] = sys_getpid,
26854 + [ __NR_mount ] = um_mount,
26855 + [ __NR_umount ] = sys_oldumount,
26856 + [ __NR_setuid ] = sys_setuid16,
26857 + [ __NR_getuid ] = sys_getuid16,
26858 + [ __NR_stime ] = um_stime,
26859 + [ __NR_ptrace ] = sys_ptrace,
26860 + [ __NR_alarm ] = sys_alarm,
26861 + [ __NR_oldfstat ] = sys_fstat,
26862 + [ __NR_pause ] = sys_pause,
26863 + [ __NR_utime ] = sys_utime,
26864 + [ __NR_stty ] = sys_ni_syscall,
26865 + [ __NR_gtty ] = sys_ni_syscall,
26866 + [ __NR_access ] = sys_access,
26867 + [ __NR_nice ] = sys_nice,
26868 + [ __NR_ftime ] = sys_ni_syscall,
26869 + [ __NR_sync ] = sys_sync,
26870 + [ __NR_kill ] = sys_kill,
26871 + [ __NR_rename ] = sys_rename,
26872 + [ __NR_mkdir ] = sys_mkdir,
26873 + [ __NR_rmdir ] = sys_rmdir,
26875 + /* Declared differently in asm/unistd.h */
26876 + [ __NR_dup ] = (syscall_handler_t *) sys_dup,
26877 + [ __NR_pipe ] = sys_pipe,
26878 + [ __NR_times ] = sys_times,
26879 + [ __NR_prof ] = sys_ni_syscall,
26880 + [ __NR_brk ] = sys_brk,
26881 + [ __NR_setgid ] = sys_setgid16,
26882 + [ __NR_getgid ] = sys_getgid16,
26883 + [ __NR_signal ] = sys_signal,
26884 + [ __NR_geteuid ] = sys_geteuid16,
26885 + [ __NR_getegid ] = sys_getegid16,
26886 + [ __NR_acct ] = sys_acct,
26887 + [ __NR_umount2 ] = sys_umount,
26888 + [ __NR_lock ] = sys_ni_syscall,
26889 + [ __NR_ioctl ] = sys_ioctl,
26890 + [ __NR_fcntl ] = sys_fcntl,
26891 + [ __NR_mpx ] = sys_ni_syscall,
26892 + [ __NR_setpgid ] = sys_setpgid,
26893 + [ __NR_ulimit ] = sys_ni_syscall,
26894 + [ __NR_oldolduname ] = sys_olduname,
26895 + [ __NR_umask ] = sys_umask,
26896 + [ __NR_chroot ] = sys_chroot,
26897 + [ __NR_ustat ] = sys_ustat,
26898 + [ __NR_dup2 ] = sys_dup2,
26899 + [ __NR_getppid ] = sys_getppid,
26900 + [ __NR_getpgrp ] = sys_getpgrp,
26901 + [ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
26902 + [ __NR_sigaction ] = sys_sigaction,
26903 + [ __NR_sgetmask ] = sys_sgetmask,
26904 + [ __NR_ssetmask ] = sys_ssetmask,
26905 + [ __NR_setreuid ] = sys_setreuid16,
26906 + [ __NR_setregid ] = sys_setregid16,
26907 + [ __NR_sigsuspend ] = sys_sigsuspend,
26908 + [ __NR_sigpending ] = sys_sigpending,
26909 + [ __NR_sethostname ] = sys_sethostname,
26910 + [ __NR_setrlimit ] = sys_setrlimit,
26911 + [ __NR_getrlimit ] = sys_old_getrlimit,
26912 + [ __NR_getrusage ] = sys_getrusage,
26913 + [ __NR_gettimeofday ] = sys_gettimeofday,
26914 + [ __NR_settimeofday ] = sys_settimeofday,
26915 + [ __NR_getgroups ] = sys_getgroups16,
26916 + [ __NR_setgroups ] = sys_setgroups16,
26917 + [ __NR_symlink ] = sys_symlink,
26918 + [ __NR_oldlstat ] = sys_lstat,
26919 + [ __NR_readlink ] = sys_readlink,
26920 + [ __NR_uselib ] = sys_uselib,
26921 + [ __NR_swapon ] = sys_swapon,
26922 + [ __NR_reboot ] = sys_reboot,
26923 + [ __NR_readdir ] = old_readdir,
26924 + [ __NR_munmap ] = sys_munmap,
26925 + [ __NR_truncate ] = sys_truncate,
26926 + [ __NR_ftruncate ] = sys_ftruncate,
26927 + [ __NR_fchmod ] = sys_fchmod,
26928 + [ __NR_fchown ] = sys_fchown16,
26929 + [ __NR_getpriority ] = sys_getpriority,
26930 + [ __NR_setpriority ] = sys_setpriority,
26931 + [ __NR_profil ] = sys_ni_syscall,
26932 + [ __NR_statfs ] = sys_statfs,
26933 + [ __NR_fstatfs ] = sys_fstatfs,
26934 + [ __NR_ioperm ] = sys_ni_syscall,
26935 + [ __NR_socketcall ] = sys_socketcall,
26936 + [ __NR_syslog ] = sys_syslog,
26937 + [ __NR_setitimer ] = sys_setitimer,
26938 + [ __NR_getitimer ] = sys_getitimer,
26939 + [ __NR_stat ] = sys_newstat,
26940 + [ __NR_lstat ] = sys_newlstat,
26941 + [ __NR_fstat ] = sys_newfstat,
26942 + [ __NR_olduname ] = sys_uname,
26943 + [ __NR_iopl ] = sys_ni_syscall,
26944 + [ __NR_vhangup ] = sys_vhangup,
26945 + [ __NR_idle ] = sys_ni_syscall,
26946 + [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
26947 + [ __NR_swapoff ] = sys_swapoff,
26948 + [ __NR_sysinfo ] = sys_sysinfo,
26949 + [ __NR_ipc ] = sys_ipc,
26950 + [ __NR_fsync ] = sys_fsync,
26951 + [ __NR_sigreturn ] = sys_sigreturn,
26952 + [ __NR_clone ] = sys_clone,
26953 + [ __NR_setdomainname ] = sys_setdomainname,
26954 + [ __NR_uname ] = sys_newuname,
26955 + [ __NR_adjtimex ] = sys_adjtimex,
26956 + [ __NR_mprotect ] = sys_mprotect,
26957 + [ __NR_sigprocmask ] = sys_sigprocmask,
26958 + [ __NR_create_module ] = sys_create_module,
26959 + [ __NR_init_module ] = sys_init_module,
26960 + [ __NR_delete_module ] = sys_delete_module,
26961 + [ __NR_get_kernel_syms ] = sys_get_kernel_syms,
26962 + [ __NR_quotactl ] = sys_quotactl,
26963 + [ __NR_getpgid ] = sys_getpgid,
26964 + [ __NR_fchdir ] = sys_fchdir,
26965 + [ __NR_bdflush ] = sys_bdflush,
26966 + [ __NR_sysfs ] = sys_sysfs,
26967 + [ __NR_personality ] = sys_personality,
26968 + [ __NR_afs_syscall ] = sys_ni_syscall,
26969 + [ __NR_setfsuid ] = sys_setfsuid16,
26970 + [ __NR_setfsgid ] = sys_setfsgid16,
26971 + [ __NR__llseek ] = sys_llseek,
26972 + [ __NR_getdents ] = sys_getdents,
26973 + [ __NR__newselect ] = (syscall_handler_t *) sys_select,
26974 + [ __NR_flock ] = sys_flock,
26975 + [ __NR_msync ] = sys_msync,
26976 + [ __NR_readv ] = sys_readv,
26977 + [ __NR_writev ] = sys_writev,
26978 + [ __NR_getsid ] = sys_getsid,
26979 + [ __NR_fdatasync ] = sys_fdatasync,
26980 + [ __NR__sysctl ] = sys_sysctl,
26981 + [ __NR_mlock ] = sys_mlock,
26982 + [ __NR_munlock ] = sys_munlock,
26983 + [ __NR_mlockall ] = sys_mlockall,
26984 + [ __NR_munlockall ] = sys_munlockall,
26985 + [ __NR_sched_setparam ] = sys_sched_setparam,
26986 + [ __NR_sched_getparam ] = sys_sched_getparam,
26987 + [ __NR_sched_setscheduler ] = sys_sched_setscheduler,
26988 + [ __NR_sched_getscheduler ] = sys_sched_getscheduler,
26989 + [ __NR_sched_yield ] = (syscall_handler_t *) yield,
26990 + [ __NR_sched_get_priority_max ] = sys_sched_get_priority_max,
26991 + [ __NR_sched_get_priority_min ] = sys_sched_get_priority_min,
26992 + [ __NR_sched_rr_get_interval ] = sys_sched_rr_get_interval,
26993 + [ __NR_nanosleep ] = sys_nanosleep,
26994 + [ __NR_mremap ] = sys_mremap,
26995 + [ __NR_setresuid ] = sys_setresuid16,
26996 + [ __NR_getresuid ] = sys_getresuid16,
26997 + [ __NR_vm86 ] = sys_ni_syscall,
26998 + [ __NR_query_module ] = sys_query_module,
26999 + [ __NR_poll ] = sys_poll,
27000 + [ __NR_nfsservctl ] = sys_nfsservctl,
27001 + [ __NR_setresgid ] = sys_setresgid16,
27002 + [ __NR_getresgid ] = sys_getresgid16,
27003 + [ __NR_prctl ] = sys_prctl,
27004 + [ __NR_rt_sigreturn ] = sys_rt_sigreturn,
27005 + [ __NR_rt_sigaction ] = sys_rt_sigaction,
27006 + [ __NR_rt_sigprocmask ] = sys_rt_sigprocmask,
27007 + [ __NR_rt_sigpending ] = sys_rt_sigpending,
27008 + [ __NR_rt_sigtimedwait ] = sys_rt_sigtimedwait,
27009 + [ __NR_rt_sigqueueinfo ] = sys_rt_sigqueueinfo,
27010 + [ __NR_rt_sigsuspend ] = sys_rt_sigsuspend,
27011 + [ __NR_pread ] = sys_pread,
27012 + [ __NR_pwrite ] = sys_pwrite,
27013 + [ __NR_chown ] = sys_chown16,
27014 + [ __NR_getcwd ] = sys_getcwd,
27015 + [ __NR_capget ] = sys_capget,
27016 + [ __NR_capset ] = sys_capset,
27017 + [ __NR_sigaltstack ] = sys_sigaltstack,
27018 + [ __NR_sendfile ] = sys_sendfile,
27019 + [ __NR_getpmsg ] = sys_ni_syscall,
27020 + [ __NR_putpmsg ] = sys_ni_syscall,
27021 + [ __NR_vfork ] = sys_vfork,
27022 + [ __NR_ugetrlimit ] = sys_getrlimit,
27023 + [ __NR_mmap2 ] = sys_mmap2,
27024 + [ __NR_truncate64 ] = sys_truncate64,
27025 + [ __NR_ftruncate64 ] = sys_ftruncate64,
27026 + [ __NR_stat64 ] = sys_stat64,
27027 + [ __NR_lstat64 ] = sys_lstat64,
27028 + [ __NR_fstat64 ] = sys_fstat64,
27029 + [ __NR_fcntl64 ] = sys_fcntl64,
27030 + [ __NR_getdents64 ] = sys_getdents64,
27031 + [ __NR_security ] = sys_ni_syscall,
27032 + [ __NR_gettid ] = sys_gettid,
27033 + [ __NR_readahead ] = sys_readahead,
27034 + [ __NR_setxattr ] = sys_setxattr,
27035 + [ __NR_lsetxattr ] = sys_lsetxattr,
27036 + [ __NR_fsetxattr ] = sys_fsetxattr,
27037 + [ __NR_getxattr ] = sys_getxattr,
27038 + [ __NR_lgetxattr ] = sys_lgetxattr,
27039 + [ __NR_fgetxattr ] = sys_fgetxattr,
27040 + [ __NR_listxattr ] = sys_listxattr,
27041 + [ __NR_llistxattr ] = sys_llistxattr,
27042 + [ __NR_flistxattr ] = sys_flistxattr,
27043 + [ __NR_removexattr ] = sys_removexattr,
27044 + [ __NR_lremovexattr ] = sys_lremovexattr,
27045 + [ __NR_fremovexattr ] = sys_fremovexattr,
27046 + [ __NR_tkill ] = sys_tkill,
27047 + [ __NR_sendfile64 ] = sys_sendfile64,
27048 + [ __NR_futex ] = sys_ni_syscall,
27049 + [ __NR_sched_setaffinity ] = sys_ni_syscall,
27050 + [ __NR_sched_getaffinity ] = sys_ni_syscall,
27051 + [ __NR_set_thread_area ] = sys_ni_syscall,
27052 + [ __NR_get_thread_area ] = sys_ni_syscall,
27053 + [ __NR_io_setup ] = sys_ni_syscall,
27054 + [ __NR_io_destroy ] = sys_ni_syscall,
27055 + [ __NR_io_getevents ] = sys_ni_syscall,
27056 + [ __NR_io_submit ] = sys_ni_syscall,
27057 + [ __NR_io_cancel ] = sys_ni_syscall,
27058 + [ __NR_alloc_hugepages ] = sys_ni_syscall,
27059 + [ __NR_free_hugepages ] = sys_ni_syscall,
27060 + [ __NR_exit_group ] = sys_ni_syscall,
27063 + [ LAST_SYSCALL + 1 ... NR_syscalls ] =
27064 + (syscall_handler_t *) sys_ni_syscall
27068 + * Overrides for Emacs so that we follow Linus's tabbing style.
27069 + * Emacs will notice this stuff at the end of the file and automatically
27070 + * adjust the settings for this buffer only. This must remain at the end
27072 + * ---------------------------------------------------------------------------
27073 + * Local variables:
27074 + * c-file-style: "linux"
27077 diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_user.c um/arch/um/kernel/syscall_user.c
27078 --- orig/arch/um/kernel/syscall_user.c 1969-12-31 19:00:00.000000000 -0500
27079 +++ um/arch/um/kernel/syscall_user.c 2003-10-21 03:26:07.000000000 -0400
27082 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27083 + * Licensed under the GPL
27086 +#include <stdlib.h>
27087 +#include <sys/time.h>
27088 +#include "kern_util.h"
27089 +#include "syscall_user.h"
27095 + struct timeval start;
27096 + struct timeval end;
27097 +} syscall_record[1024];
27099 +int record_syscall_start(int syscall)
27103 + max = sizeof(syscall_record)/sizeof(syscall_record[0]);
27104 + index = next_syscall_index(max);
27106 + syscall_record[index].syscall = syscall;
27107 + syscall_record[index].pid = current_pid();
27108 + syscall_record[index].result = 0xdeadbeef;
27109 + gettimeofday(&syscall_record[index].start, NULL);
27113 +void record_syscall_end(int index, int result)
27115 + syscall_record[index].result = result;
27116 + gettimeofday(&syscall_record[index].end, NULL);
27120 + * Overrides for Emacs so that we follow Linus's tabbing style.
27121 + * Emacs will notice this stuff at the end of the file and automatically
27122 + * adjust the settings for this buffer only. This must remain at the end
27124 + * ---------------------------------------------------------------------------
27125 + * Local variables:
27126 + * c-file-style: "linux"
27129 diff -Naur -X ../exclude-files orig/arch/um/kernel/sysrq.c um/arch/um/kernel/sysrq.c
27130 --- orig/arch/um/kernel/sysrq.c 1969-12-31 19:00:00.000000000 -0500
27131 +++ um/arch/um/kernel/sysrq.c 2003-10-21 03:26:07.000000000 -0400
27134 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
27135 + * Licensed under the GPL
27138 +#include "linux/sched.h"
27139 +#include "linux/kernel.h"
27140 +#include "linux/module.h"
27141 +#include "asm/page.h"
27142 +#include "asm/processor.h"
27143 +#include "sysrq.h"
27144 +#include "user_util.h"
27147 + * If the address is either in the .text section of the
27148 + * kernel, or in the vmalloc'ed module regions, it *may*
27149 + * be the address of a calling routine
27152 +#ifdef CONFIG_MODULES
27154 +extern struct module *module_list;
27155 +extern struct module kernel_module;
27157 +static inline int kernel_text_address(unsigned long addr)
27160 + struct module *mod;
27162 + if (addr >= (unsigned long) &_stext &&
27163 + addr <= (unsigned long) &_etext)
27166 + for (mod = module_list; mod != &kernel_module; mod = mod->next) {
27167 + /* mod_bound tests for addr being inside the vmalloc'ed
27168 + * module area. Of course it'd be better to test only
27169 + * for the .text subset... */
27170 + if (mod_bound(addr, 0, mod)) {
27181 +static inline int kernel_text_address(unsigned long addr)
27183 + return (addr >= (unsigned long) &_stext &&
27184 + addr <= (unsigned long) &_etext);
27189 +void show_trace(unsigned long * stack)
27192 + unsigned long addr;
27195 + stack = (unsigned long*) &stack;
27197 + printk("Call Trace: ");
27199 + while (((long) stack & (THREAD_SIZE-1)) != 0) {
27201 + if (kernel_text_address(addr)) {
27202 + if (i && ((i % 6) == 0))
27204 + printk("[<%08lx>] ", addr);
27211 +void show_trace_task(struct task_struct *tsk)
27213 + unsigned long esp = PT_REGS_SP(&tsk->thread.regs);
27215 + /* User space on another CPU? */
27216 + if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
27218 + show_trace((unsigned long *)esp);
27222 + * Overrides for Emacs so that we follow Linus's tabbing style.
27223 + * Emacs will notice this stuff at the end of the file and automatically
27224 + * adjust the settings for this buffer only. This must remain at the end
27226 + * ---------------------------------------------------------------------------
27227 + * Local variables:
27228 + * c-file-style: "linux"
27231 diff -Naur -X ../exclude-files orig/arch/um/kernel/tempfile.c um/arch/um/kernel/tempfile.c
27232 --- orig/arch/um/kernel/tempfile.c 1969-12-31 19:00:00.000000000 -0500
27233 +++ um/arch/um/kernel/tempfile.c 2003-10-21 03:26:07.000000000 -0400
27236 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27237 + * Licensed under the GPL
27240 +#include <stdio.h>
27241 +#include <stdlib.h>
27242 +#include <unistd.h>
27243 +#include <string.h>
27244 +#include <errno.h>
27245 +#include <sys/param.h>
27248 +/* Modified from create_mem_file and start_debugger */
27249 +static char *tempdir = NULL;
27251 +static void __init find_tempdir(void)
27253 + char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
27255 + char *dir = NULL;
27257 + if(tempdir != NULL) return; /* We've already been called */
27258 + for(i = 0; dirs[i]; i++){
27259 + dir = getenv(dirs[i]);
27260 + if((dir != NULL) && (*dir != '\0'))
27263 + if((dir == NULL) || (*dir == '\0'))
27266 + tempdir = malloc(strlen(dir) + 2);
27267 + if(tempdir == NULL){
27268 + fprintf(stderr, "Failed to malloc tempdir, "
27269 + "errno = %d\n", errno);
27272 + strcpy(tempdir, dir);
27273 + strcat(tempdir, "/");
27276 +int make_tempfile(const char *template, char **out_tempname, int do_unlink)
27278 + char tempname[MAXPATHLEN];
27282 + if (*template != '/')
27283 + strcpy(tempname, tempdir);
27286 + strcat(tempname, template);
27287 + fd = mkstemp(tempname);
27289 + fprintf(stderr, "open - cannot create %s: %s\n", tempname,
27290 + strerror(errno));
27293 + if(do_unlink && (unlink(tempname) < 0)){
27294 + perror("unlink");
27297 + if(out_tempname){
27298 + *out_tempname = strdup(tempname);
27299 + if(*out_tempname == NULL){
27300 + perror("strdup");
27308 + * Overrides for Emacs so that we follow Linus's tabbing style.
27309 + * Emacs will notice this stuff at the end of the file and automatically
27310 + * adjust the settings for this buffer only. This must remain at the end
27312 + * ---------------------------------------------------------------------------
27313 + * Local variables:
27314 + * c-file-style: "linux"
27317 diff -Naur -X ../exclude-files orig/arch/um/kernel/time.c um/arch/um/kernel/time.c
27318 --- orig/arch/um/kernel/time.c 1969-12-31 19:00:00.000000000 -0500
27319 +++ um/arch/um/kernel/time.c 2003-12-17 01:08:27.000000000 -0500
27322 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
27323 + * Licensed under the GPL
27326 +#include <stdio.h>
27327 +#include <stdlib.h>
27328 +#include <unistd.h>
27330 +#include <sys/time.h>
27331 +#include <signal.h>
27332 +#include <errno.h>
27333 +#include "user_util.h"
27334 +#include "kern_util.h"
27336 +#include "process.h"
27337 +#include "signal_user.h"
27338 +#include "time_user.h"
27340 +extern struct timeval xtime;
27342 +struct timeval local_offset = { 0, 0 };
27346 + gettimeofday(&xtime, NULL);
27347 + timeradd(&xtime, &local_offset, &xtime);
27350 +void set_interval(int timer_type)
27352 + int usec = 1000000/hz();
27353 + struct itimerval interval = ((struct itimerval) { { 0, usec },
27356 + if(setitimer(timer_type, &interval, NULL) == -1)
27357 + panic("setitimer failed - errno = %d\n", errno);
27360 +void enable_timer(void)
27362 + int usec = 1000000/hz();
27363 + struct itimerval enable = ((struct itimerval) { { 0, usec },
27365 + if(setitimer(ITIMER_VIRTUAL, &enable, NULL))
27366 + printk("enable_timer - setitimer failed, errno = %d\n",
27370 +void switch_timers(int to_real)
27372 + struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
27373 + struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
27374 + { 0, 1000000/hz() }});
27378 + old = ITIMER_VIRTUAL;
27379 + new = ITIMER_REAL;
27382 + old = ITIMER_REAL;
27383 + new = ITIMER_VIRTUAL;
27386 + if((setitimer(old, &disable, NULL) < 0) ||
27387 + (setitimer(new, &enable, NULL)))
27388 + printk("switch_timers - setitimer failed, errno = %d\n",
27392 +void idle_timer(void)
27394 + if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
27395 + panic("Couldn't unset SIGVTALRM handler");
27397 + set_handler(SIGALRM, (__sighandler_t) alarm_handler,
27398 + SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
27399 + set_interval(ITIMER_REAL);
27402 +static unsigned long long get_host_hz(void)
27404 + char mhzline[16], *end;
27405 + int ret, mult, mhz, rest, len;
27407 + ret = cpu_feature("cpu MHz", mhzline,
27408 + sizeof(mhzline) / sizeof(mhzline[0]));
27410 + panic ("Could not get host MHZ");
27412 + mhz = strtoul(mhzline, &end, 10);
27414 + /* This business is to parse a floating point number without using
27415 + * floating types.
27422 + len = strlen(end);
27427 + rest = strtoul(end, NULL, 10);
27428 + while(mult-- > 0)
27432 + return(1000000 * mhz + rest);
27435 +unsigned long long host_hz = 0;
27437 +void time_init(void)
27439 + host_hz = get_host_hz();
27440 + if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
27441 + panic("Couldn't set SIGVTALRM handler");
27442 + set_interval(ITIMER_VIRTUAL);
27445 +void do_gettimeofday(struct timeval *tv)
27447 + unsigned long flags;
27449 + flags = time_lock();
27450 + gettimeofday(tv, NULL);
27451 + timeradd(tv, &local_offset, tv);
27452 + time_unlock(flags);
27455 +void do_settimeofday(struct timeval *tv)
27457 + struct timeval now;
27458 + unsigned long flags;
27460 + flags = time_lock();
27461 + gettimeofday(&now, NULL);
27462 + timersub(tv, &now, &local_offset);
27463 + time_unlock(flags);
27466 +void idle_sleep(int secs)
27468 + struct timespec ts;
27470 + ts.tv_sec = secs;
27472 + nanosleep(&ts, NULL);
27476 + * Overrides for Emacs so that we follow Linus's tabbing style.
27477 + * Emacs will notice this stuff at the end of the file and automatically
27478 + * adjust the settings for this buffer only. This must remain at the end
27480 + * ---------------------------------------------------------------------------
27481 + * Local variables:
27482 + * c-file-style: "linux"
27485 diff -Naur -X ../exclude-files orig/arch/um/kernel/time_kern.c um/arch/um/kernel/time_kern.c
27486 --- orig/arch/um/kernel/time_kern.c 1969-12-31 19:00:00.000000000 -0500
27487 +++ um/arch/um/kernel/time_kern.c 2003-12-17 01:07:51.000000000 -0500
27490 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
27491 + * Licensed under the GPL
27494 +#include "linux/kernel.h"
27495 +#include "linux/unistd.h"
27496 +#include "linux/stddef.h"
27497 +#include "linux/spinlock.h"
27498 +#include "linux/sched.h"
27499 +#include "linux/interrupt.h"
27500 +#include "linux/init.h"
27501 +#include "linux/delay.h"
27502 +#include "asm/irq.h"
27503 +#include "asm/param.h"
27504 +#include "asm/current.h"
27505 +#include "kern_util.h"
27506 +#include "user_util.h"
27507 +#include "time_user.h"
27510 +extern rwlock_t xtime_lock;
27517 +/* Changed at early boot */
27518 +int timer_irq_inited = 0;
27520 +/* missed_ticks will be modified after kernel memory has been
27521 + * write-protected, so this puts it in a section which will be left
27524 +int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
27526 +static int first_tick;
27527 +static unsigned long long prev_tsc;
27528 +static long long delta; /* Deviation per interval */
27530 +extern unsigned long long host_hz;
27532 +void timer_irq(union uml_pt_regs *regs)
27534 + unsigned long long ticks = 0;
27536 + if(!timer_irq_inited){
27537 + /* This is to ensure that ticks don't pile up when
27538 + * the timer handler is suspended */
27544 +#if defined(CONFIG_UML_REAL_TIME_CLOCK)
27545 + unsigned long long tsc;
27546 + /* We've had 1 tick */
27547 + tsc = time_stamp();
27549 + delta += tsc - prev_tsc;
27552 + ticks += (delta * HZ) / host_hz;
27553 + delta -= (ticks * host_hz) / HZ;
27559 + prev_tsc = time_stamp();
27563 + while(ticks > 0){
27564 + do_IRQ(TIMER_IRQ, regs);
27569 +void boot_timer_handler(int sig)
27571 + struct pt_regs regs;
27573 + CHOOSE_MODE((void)
27574 + (UPT_SC(®s.regs) = (struct sigcontext *) (&sig + 1)),
27575 + (void) (regs.regs.skas.is_user = 0));
27579 +void um_timer(int irq, void *dev, struct pt_regs *regs)
27582 + write_lock(&xtime_lock);
27586 + write_unlock(&xtime_lock);
27589 +long um_time(int * tloc)
27591 + struct timeval now;
27593 + do_gettimeofday(&now);
27595 + if (put_user(now.tv_sec,tloc))
27596 + now.tv_sec = -EFAULT;
27598 + return now.tv_sec;
27601 +long um_stime(int * tptr)
27604 + struct timeval new;
27606 + if (get_user(value, tptr))
27608 + new.tv_sec = value;
27610 + do_settimeofday(&new);
27614 +/* XXX Needs to be moved under sys-i386 */
27615 +void __delay(um_udelay_t time)
27617 + /* Stolen from the i386 __loop_delay */
27619 + __asm__ __volatile__(
27624 + "2:\tdecl %0\n\tjns 2b"
27629 +void __udelay(um_udelay_t usecs)
27633 + n = (loops_per_jiffy * HZ * usecs) / 1000000;
27634 + for(i=0;i<n;i++) ;
27637 +void __const_udelay(um_udelay_t usecs)
27641 + n = (loops_per_jiffy * HZ * usecs) / 1000000;
27642 + for(i=0;i<n;i++) ;
27645 +void timer_handler(int sig, union uml_pt_regs *regs)
27648 + update_process_times(user_context(UPT_SP(regs)));
27650 + if(current->processor == 0)
27654 +static spinlock_t timer_spinlock = SPIN_LOCK_UNLOCKED;
27656 +unsigned long time_lock(void)
27658 + unsigned long flags;
27660 + spin_lock_irqsave(&timer_spinlock, flags);
27664 +void time_unlock(unsigned long flags)
27666 + spin_unlock_irqrestore(&timer_spinlock, flags);
27669 +int __init timer_init(void)
27673 + CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
27674 + err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
27676 + printk(KERN_ERR "timer_init : request_irq failed - "
27677 + "errno = %d\n", -err);
27678 + timer_irq_inited = 1;
27682 +__initcall(timer_init);
27685 + * Overrides for Emacs so that we follow Linus's tabbing style.
27686 + * Emacs will notice this stuff at the end of the file and automatically
27687 + * adjust the settings for this buffer only. This must remain at the end
27689 + * ---------------------------------------------------------------------------
27690 + * Local variables:
27691 + * c-file-style: "linux"
27694 diff -Naur -X ../exclude-files orig/arch/um/kernel/tlb.c um/arch/um/kernel/tlb.c
27695 --- orig/arch/um/kernel/tlb.c 1969-12-31 19:00:00.000000000 -0500
27696 +++ um/arch/um/kernel/tlb.c 2003-10-21 03:26:07.000000000 -0400
27699 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
27700 + * Licensed under the GPL
27703 +#include "linux/mm.h"
27704 +#include "asm/page.h"
27705 +#include "asm/pgalloc.h"
27706 +#include "choose-mode.h"
27707 +#include "mode_kern.h"
27709 +void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
27711 + address &= PAGE_MASK;
27712 + flush_tlb_range(vma->vm_mm, address, address + PAGE_SIZE);
27715 +void flush_tlb_all(void)
27717 + flush_tlb_mm(current->mm);
27720 +void flush_tlb_kernel_vm(void)
27722 + CHOOSE_MODE(flush_tlb_kernel_vm_tt(), flush_tlb_kernel_vm_skas());
27725 +void __flush_tlb_one(unsigned long addr)
27727 + CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
27730 +void flush_tlb_range(struct mm_struct *mm, unsigned long start,
27731 + unsigned long end)
27733 + CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, mm, start,
27737 +void flush_tlb_mm(struct mm_struct *mm)
27739 + CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
27742 +void force_flush_all(void)
27744 + CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
27748 +pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
27750 + return(pgd_offset(mm, address));
27753 +pmd_t *pmd_offset_proc(pgd_t *pgd, unsigned long address)
27755 + return(pmd_offset(pgd, address));
27758 +pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
27760 + return(pte_offset(pmd, address));
27763 +pte_t *addr_pte(struct task_struct *task, unsigned long addr)
27765 + return(pte_offset(pmd_offset(pgd_offset(task->mm, addr), addr), addr));
27769 + * Overrides for Emacs so that we follow Linus's tabbing style.
27770 + * Emacs will notice this stuff at the end of the file and automatically
27771 + * adjust the settings for this buffer only. This must remain at the end
27773 + * ---------------------------------------------------------------------------
27774 + * Local variables:
27775 + * c-file-style: "linux"
27778 diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_kern.c um/arch/um/kernel/trap_kern.c
27779 --- orig/arch/um/kernel/trap_kern.c 1969-12-31 19:00:00.000000000 -0500
27780 +++ um/arch/um/kernel/trap_kern.c 2003-12-14 11:18:05.000000000 -0500
27783 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
27784 + * Licensed under the GPL
27787 +#include "linux/kernel.h"
27788 +#include "linux/sched.h"
27789 +#include "linux/mm.h"
27790 +#include "linux/spinlock.h"
27791 +#include "linux/config.h"
27792 +#include "linux/init.h"
27793 +#include "asm/semaphore.h"
27794 +#include "asm/pgtable.h"
27795 +#include "asm/pgalloc.h"
27796 +#include "asm/a.out.h"
27797 +#include "asm/current.h"
27798 +#include "asm/irq.h"
27799 +#include "user_util.h"
27800 +#include "kern_util.h"
27802 +#include "chan_kern.h"
27803 +#include "mconsole_kern.h"
27804 +#include "2_5compat.h"
27806 +#include "mem_kern.h"
27808 +unsigned long handle_page_fault(unsigned long address, unsigned long ip,
27809 + int is_write, int is_user, int *code_out)
27811 + struct mm_struct *mm = current->mm;
27812 + struct vm_area_struct *vma;
27816 + unsigned long page;
27819 + *code_out = SEGV_MAPERR;
27820 + down_read(&mm->mmap_sem);
27821 + vma = find_vma(mm, address);
27824 + else if(vma->vm_start <= address)
27826 + else if(!(vma->vm_flags & VM_GROWSDOWN))
27828 + else if(expand_stack(vma, address))
27832 + *code_out = SEGV_ACCERR;
27833 + if(is_write && !(vma->vm_flags & VM_WRITE))
27835 + page = address & PAGE_MASK;
27836 + if(page == (unsigned long) current + PAGE_SIZE)
27837 + panic("Kernel stack overflow");
27838 + pgd = pgd_offset(mm, page);
27839 + pmd = pmd_offset(pgd, page);
27842 + switch (handle_mm_fault(mm, vma, address, is_write)) {
27844 + current->min_flt++;
27847 + current->maj_flt++;
27850 + if (current->pid == 1) {
27851 + up_read(&mm->mmap_sem);
27853 + down_read(&mm->mmap_sem);
27856 + /* Fall through to bad area case */
27860 + pte = pte_offset(pmd, page);
27861 + } while(!pte_present(*pte));
27863 + *pte = pte_mkyoung(*pte);
27864 + if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
27865 + flush_tlb_page(vma, page);
27867 + up_read(&mm->mmap_sem);
27871 +LIST_HEAD(physmem_remappers);
27873 +void register_remapper(struct remapper *info)
27875 + list_add(&info->list, &physmem_remappers);
27878 +static int check_remapped_addr(unsigned long address, int is_write)
27880 + struct remapper *remapper;
27881 + struct list_head *ele;
27885 + fd = phys_mapping(__pa(address), &offset);
27889 + list_for_each(ele, &physmem_remappers){
27890 + remapper = list_entry(ele, struct remapper, list);
27891 + if((*remapper->proc)(fd, address, is_write, offset))
27898 +unsigned long segv(unsigned long address, unsigned long ip, int is_write,
27899 + int is_user, void *sc)
27901 + struct siginfo si;
27905 + if(!is_user && (address >= start_vm) && (address < end_vm)){
27906 + flush_tlb_kernel_vm();
27909 + else if(check_remapped_addr(address & PAGE_MASK, is_write))
27911 + else if(current->mm == NULL)
27912 + panic("Segfault with no mm");
27914 + handled = handle_page_fault(address, ip, is_write, is_user,
27917 + catcher = current->thread.fault_catcher;
27920 + else if(catcher != NULL){
27921 + current->thread.fault_addr = (void *) address;
27922 + do_longjmp(catcher, 1);
27924 + else if(current->thread.fault_addr != NULL)
27925 + panic("fault_addr set but no fault catcher");
27926 + else if(arch_fixup(ip, sc))
27930 + panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
27932 + si.si_signo = SIGSEGV;
27933 + si.si_addr = (void *) address;
27934 + current->thread.cr2 = address;
27935 + current->thread.err = is_write;
27936 + force_sig_info(SIGSEGV, &si, current);
27940 +void bad_segv(unsigned long address, unsigned long ip, int is_write)
27942 + struct siginfo si;
27944 + si.si_signo = SIGSEGV;
27945 + si.si_code = SEGV_ACCERR;
27946 + si.si_addr = (void *) address;
27947 + current->thread.cr2 = address;
27948 + current->thread.err = is_write;
27949 + force_sig_info(SIGSEGV, &si, current);
27952 +void relay_signal(int sig, union uml_pt_regs *regs)
27954 + if(arch_handle_signal(sig, regs)) return;
27955 + if(!UPT_IS_USER(regs))
27956 + panic("Kernel mode signal %d", sig);
27957 + force_sig(sig, current);
27960 +void bus_handler(int sig, union uml_pt_regs *regs)
27962 + if(current->thread.fault_catcher != NULL)
27963 + do_longjmp(current->thread.fault_catcher, 1);
27964 + else relay_signal(sig, regs);
27967 +void winch(int sig, union uml_pt_regs *regs)
27969 + do_IRQ(WINCH_IRQ, regs);
27972 +void trap_init(void)
27976 +spinlock_t trap_lock = SPIN_LOCK_UNLOCKED;
27978 +static int trap_index = 0;
27980 +int next_trap_index(int limit)
27984 + spin_lock(&trap_lock);
27985 + ret = trap_index;
27986 + if(++trap_index == limit)
27988 + spin_unlock(&trap_lock);
27993 + * Overrides for Emacs so that we follow Linus's tabbing style.
27994 + * Emacs will notice this stuff at the end of the file and automatically
27995 + * adjust the settings for this buffer only. This must remain at the end
27997 + * ---------------------------------------------------------------------------
27998 + * Local variables:
27999 + * c-file-style: "linux"
28002 diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_user.c um/arch/um/kernel/trap_user.c
28003 --- orig/arch/um/kernel/trap_user.c 1969-12-31 19:00:00.000000000 -0500
28004 +++ um/arch/um/kernel/trap_user.c 2003-10-21 03:26:07.000000000 -0400
28007 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
28008 + * Licensed under the GPL
28011 +#include <stdlib.h>
28012 +#include <errno.h>
28013 +#include <setjmp.h>
28014 +#include <signal.h>
28015 +#include <sys/time.h>
28016 +#include <sys/ptrace.h>
28017 +#include <sys/wait.h>
28018 +#include <asm/page.h>
28019 +#include <asm/unistd.h>
28020 +#include <asm/ptrace.h>
28022 +#include "sysdep/ptrace.h"
28023 +#include "sigcontext.h"
28024 +#include "sysdep/sigcontext.h"
28025 +#include "irq_user.h"
28026 +#include "frame_user.h"
28027 +#include "signal_user.h"
28028 +#include "time_user.h"
28031 +#include "choose-mode.h"
28032 +#include "kern_util.h"
28033 +#include "user_util.h"
28036 +void kill_child_dead(int pid)
28038 + kill(pid, SIGKILL);
28039 + kill(pid, SIGCONT);
28040 + while(waitpid(pid, NULL, 0) > 0) kill(pid, SIGCONT);
28043 +/* Unlocked - don't care if this is a bit off */
28044 +int nsegfaults = 0;
28047 + unsigned long address;
28050 + unsigned long sp;
28052 +} segfault_record[1024];
28054 +void segv_handler(int sig, union uml_pt_regs *regs)
28058 + if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){
28059 + bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs),
28060 + UPT_FAULT_WRITE(regs));
28063 + max = sizeof(segfault_record)/sizeof(segfault_record[0]);
28064 + index = next_trap_index(max);
28067 + segfault_record[index].address = UPT_FAULT_ADDR(regs);
28068 + segfault_record[index].pid = os_getpid();
28069 + segfault_record[index].is_write = UPT_FAULT_WRITE(regs);
28070 + segfault_record[index].sp = UPT_SP(regs);
28071 + segfault_record[index].is_user = UPT_IS_USER(regs);
28072 + segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs),
28073 + UPT_IS_USER(regs), regs);
28076 +void usr2_handler(int sig, union uml_pt_regs *regs)
28078 + CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
28081 +struct signal_info sig_info[] = {
28082 + [ SIGTRAP ] { .handler = relay_signal,
28084 + [ SIGFPE ] { .handler = relay_signal,
28086 + [ SIGILL ] { .handler = relay_signal,
28088 + [ SIGWINCH ] { .handler = winch,
28090 + [ SIGBUS ] { .handler = bus_handler,
28092 + [ SIGSEGV] { .handler = segv_handler,
28094 + [ SIGIO ] { .handler = sigio_handler,
28096 + [ SIGVTALRM ] { .handler = timer_handler,
28098 + [ SIGALRM ] { .handler = timer_handler,
28100 + [ SIGUSR2 ] { .handler = usr2_handler,
28104 +void sig_handler(int sig, struct sigcontext sc)
28106 + CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
28110 +extern int timer_irq_inited, missed_ticks[];
28112 +void alarm_handler(int sig, struct sigcontext sc)
28114 + if(!timer_irq_inited) return;
28115 + missed_ticks[cpu()]++;
28117 + if(sig == SIGALRM)
28118 + switch_timers(0);
28120 + CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
28123 + if(sig == SIGALRM)
28124 + switch_timers(1);
28127 +void do_longjmp(void *b, int val)
28129 + jmp_buf *buf = b;
28131 + siglongjmp(*buf, val);
28135 + * Overrides for Emacs so that we follow Linus's tabbing style.
28136 + * Emacs will notice this stuff at the end of the file and automatically
28137 + * adjust the settings for this buffer only. This must remain at the end
28139 + * ---------------------------------------------------------------------------
28140 + * Local variables:
28141 + * c-file-style: "linux"
28144 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_kern.c um/arch/um/kernel/tt/exec_kern.c
28145 --- orig/arch/um/kernel/tt/exec_kern.c 1969-12-31 19:00:00.000000000 -0500
28146 +++ um/arch/um/kernel/tt/exec_kern.c 2003-11-07 02:23:10.000000000 -0500
28149 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28150 + * Licensed under the GPL
28153 +#include "linux/kernel.h"
28154 +#include "linux/mm.h"
28155 +#include "asm/signal.h"
28156 +#include "asm/ptrace.h"
28157 +#include "asm/uaccess.h"
28158 +#include "asm/pgalloc.h"
28159 +#include "user_util.h"
28160 +#include "kern_util.h"
28161 +#include "irq_user.h"
28162 +#include "time_user.h"
28163 +#include "mem_user.h"
28168 +static int exec_tramp(void *sig_stack)
28170 + init_new_thread_stack(sig_stack, NULL);
28171 + init_new_thread_signals(1);
28172 + os_stop_process(os_getpid());
28176 +void flush_thread_tt(void)
28178 + unsigned long stack;
28181 + stack = alloc_stack(0, 0);
28184 + "flush_thread : failed to allocate temporary stack\n");
28185 + do_exit(SIGKILL);
28188 + new_pid = start_fork_tramp((void *) current->thread.kernel_stack,
28189 + stack, 0, exec_tramp);
28192 + "flush_thread : new thread failed, errno = %d\n",
28194 + do_exit(SIGKILL);
28197 + if(current->processor == 0)
28198 + forward_interrupts(new_pid);
28199 + current->thread.request.op = OP_EXEC;
28200 + current->thread.request.u.exec.pid = new_pid;
28201 + unprotect_stack((unsigned long) current);
28202 + os_usr1_process(os_getpid());
28205 + free_page(stack);
28206 + protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
28207 + task_protections((unsigned long) current);
28208 + force_flush_all();
28209 + unblock_signals();
28212 +void start_thread_tt(struct pt_regs *regs, unsigned long eip,
28213 + unsigned long esp)
28216 + flush_tlb_mm(current->mm);
28217 + PT_REGS_IP(regs) = eip;
28218 + PT_REGS_SP(regs) = esp;
28219 + PT_FIX_EXEC_STACK(esp);
28223 + * Overrides for Emacs so that we follow Linus's tabbing style.
28224 + * Emacs will notice this stuff at the end of the file and automatically
28225 + * adjust the settings for this buffer only. This must remain at the end
28227 + * ---------------------------------------------------------------------------
28228 + * Local variables:
28229 + * c-file-style: "linux"
28232 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_user.c um/arch/um/kernel/tt/exec_user.c
28233 --- orig/arch/um/kernel/tt/exec_user.c 1969-12-31 19:00:00.000000000 -0500
28234 +++ um/arch/um/kernel/tt/exec_user.c 2003-10-21 03:26:07.000000000 -0400
28237 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
28238 + * Licensed under the GPL
28241 +#include <stdio.h>
28242 +#include <unistd.h>
28243 +#include <stdlib.h>
28244 +#include <sched.h>
28245 +#include <errno.h>
28246 +#include <sys/wait.h>
28247 +#include <sys/ptrace.h>
28248 +#include <signal.h>
28249 +#include "user_util.h"
28250 +#include "kern_util.h"
28252 +#include "ptrace_user.h"
28254 +void do_exec(int old_pid, int new_pid)
28256 + unsigned long regs[FRAME_SIZE];
28258 + if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) ||
28259 + (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0) ||
28260 + (waitpid(new_pid, 0, WUNTRACED) < 0))
28261 + tracer_panic("do_exec failed to attach proc - errno = %d",
28264 + if(ptrace_getregs(old_pid, regs) < 0)
28265 + tracer_panic("do_exec failed to get registers - errno = %d",
28268 + kill(old_pid, SIGKILL);
28270 + if(ptrace_setregs(new_pid, regs) < 0)
28271 + tracer_panic("do_exec failed to start new proc - errno = %d",
28276 + * Overrides for Emacs so that we follow Linus's tabbing style.
28277 + * Emacs will notice this stuff at the end of the file and automatically
28278 + * adjust the settings for this buffer only. This must remain at the end
28280 + * ---------------------------------------------------------------------------
28281 + * Local variables:
28282 + * c-file-style: "linux"
28285 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb.c um/arch/um/kernel/tt/gdb.c
28286 --- orig/arch/um/kernel/tt/gdb.c 1969-12-31 19:00:00.000000000 -0500
28287 +++ um/arch/um/kernel/tt/gdb.c 2003-10-21 03:26:07.000000000 -0400
28290 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28291 + * Licensed under the GPL
28294 +#include <stdio.h>
28295 +#include <stdlib.h>
28296 +#include <errno.h>
28297 +#include <string.h>
28298 +#include <signal.h>
28299 +#include <sys/ptrace.h>
28300 +#include <sys/types.h>
28301 +#include "uml-config.h"
28302 +#include "kern_constants.h"
28303 +#include "chan_user.h"
28306 +#include "debug.h"
28307 +#include "kern_util.h"
28308 +#include "user_util.h"
28310 +#include "sysdep/thread.h"
28312 +extern int debugger_pid;
28313 +extern int debugger_fd;
28314 +extern int debugger_parent;
28316 +int detach(int pid, int sig)
28318 + return(ptrace(PTRACE_DETACH, pid, 0, sig));
28321 +int attach(int pid)
28325 + err = ptrace(PTRACE_ATTACH, pid, 0, 0);
28326 + if(err < 0) return(-errno);
28327 + else return(err);
28332 + return(ptrace(PTRACE_CONT, pid, 0, 0));
28335 +#ifdef UML_CONFIG_PT_PROXY
28337 +int debugger_signal(int status, pid_t pid)
28339 + return(debugger_proxy(status, pid));
28342 +void child_signal(pid_t pid, int status)
28344 + child_proxy(pid, status);
28347 +static void gdb_announce(char *dev_name, int dev)
28349 + printf("gdb assigned device '%s'\n", dev_name);
28352 +static struct chan_opts opts = {
28353 + .announce = gdb_announce,
28354 + .xterm_title = "UML kernel debugger",
28356 + .tramp_stack = 0,
28360 +/* Accessed by the tracing thread, which automatically serializes access */
28361 +static void *xterm_data;
28362 +static int xterm_fd;
28364 +extern void *xterm_init(char *, int, struct chan_opts *);
28365 +extern int xterm_open(int, int, int, void *, char **);
28366 +extern void xterm_close(int, void *);
28368 +int open_gdb_chan(void)
28370 + char stack[UM_KERN_PAGE_SIZE], *dummy;
28372 + opts.tramp_stack = (unsigned long) stack;
28373 + xterm_data = xterm_init("", 0, &opts);
28374 + xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy);
28375 + return(xterm_fd);
28378 +static void exit_debugger_cb(void *unused)
28380 + if(debugger_pid != -1){
28381 + if(gdb_pid != -1){
28382 + fake_child_exit();
28385 + else kill_child_dead(debugger_pid);
28386 + debugger_pid = -1;
28387 + if(debugger_parent != -1)
28388 + detach(debugger_parent, SIGINT);
28390 + if(xterm_data != NULL) xterm_close(xterm_fd, xterm_data);
28393 +static void exit_debugger(void)
28395 + initial_thread_cb(exit_debugger_cb, NULL);
28398 +__uml_exitcall(exit_debugger);
28405 +static void config_gdb_cb(void *arg)
28407 + struct gdb_data *data = arg;
28412 + if(debugger_pid != -1) exit_debugger_cb(NULL);
28413 + if(!strncmp(data->str, "pid,", strlen("pid,"))){
28414 + data->str += strlen("pid,");
28415 + pid = strtoul(data->str, NULL, 0);
28416 + task = cpu_tasks[0].task;
28417 + debugger_pid = attach_debugger(TASK_EXTERN_PID(task), pid, 0);
28418 + if(debugger_pid != -1){
28425 + debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
28426 + init_proxy(debugger_pid, 0, 0);
28429 +int gdb_config(char *str)
28431 + struct gdb_data data;
28433 + if(*str++ != '=') return(-1);
28435 + initial_thread_cb(config_gdb_cb, &data);
28436 + return(data.err);
28439 +void remove_gdb_cb(void *unused)
28441 + exit_debugger_cb(NULL);
28444 +int gdb_remove(char *unused)
28446 + initial_thread_cb(remove_gdb_cb, NULL);
28450 +void signal_usr1(int sig)
28452 + if(debugger_pid != -1){
28453 + printk(UM_KERN_ERR "The debugger is already running\n");
28456 + debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
28457 + init_proxy(debugger_pid, 0, 0);
28460 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
28464 + pid = start_debugger(linux_prog, startup, stop, &debugger_fd);
28465 + status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
28470 + init_proxy(pid, 1, status);
28474 +int attach_debugger(int idle_pid, int pid, int stop)
28476 + int status = 0, err;
28478 + err = attach(pid);
28480 + printf("Failed to attach pid %d, errno = %d\n", pid, -err);
28483 + if(stop) status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
28484 + init_proxy(pid, 1, status);
28488 +#ifdef notdef /* Put this back in when it does something useful */
28489 +static int __init uml_gdb_init_setup(char *line, int *add)
28491 + gdb_init = uml_strdup(line);
28495 +__uml_setup("gdb=", uml_gdb_init_setup,
28496 +"gdb=<channel description>\n\n"
28500 +static int __init uml_gdb_pid_setup(char *line, int *add)
28502 + gdb_pid = strtoul(line, NULL, 0);
28507 +__uml_setup("gdb-pid=", uml_gdb_pid_setup,
28509 +" gdb-pid is used to attach an external debugger to UML. This may be\n"
28510 +" an already-running gdb or a debugger-like process like strace.\n\n"
28515 +int debugger_signal(int status, pid_t pid){ return(0); }
28516 +void child_signal(pid_t pid, int status){ }
28517 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
28519 + printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
28520 + kill_child_dead(idle_pid);
28524 +void signal_usr1(int sig)
28526 + printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
28529 +int attach_debugger(int idle_pid, int pid, int stop)
28531 + printk(UM_KERN_ERR "attach_debugger called when CONFIG_PT_PROXY "
28536 +int config_gdb(char *str)
28541 +int remove_gdb(void)
28546 +int init_parent_proxy(int pid)
28551 +void debugger_parent_signal(int status, int pid)
28558 + * Overrides for Emacs so that we follow Linus's tabbing style.
28559 + * Emacs will notice this stuff at the end of the file and automatically
28560 + * adjust the settings for this buffer only. This must remain at the end
28562 + * ---------------------------------------------------------------------------
28563 + * Local variables:
28564 + * c-file-style: "linux"
28567 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb_kern.c um/arch/um/kernel/tt/gdb_kern.c
28568 --- orig/arch/um/kernel/tt/gdb_kern.c 1969-12-31 19:00:00.000000000 -0500
28569 +++ um/arch/um/kernel/tt/gdb_kern.c 2003-10-21 03:26:07.000000000 -0400
28572 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28573 + * Licensed under the GPL
28576 +#include "linux/init.h"
28577 +#include "linux/config.h"
28578 +#include "mconsole_kern.h"
28580 +#ifdef CONFIG_MCONSOLE
28582 +extern int gdb_config(char *str);
28583 +extern int gdb_remove(char *unused);
28585 +static struct mc_device gdb_mc = {
28587 + .config = gdb_config,
28588 + .remove = gdb_remove,
28591 +int gdb_mc_init(void)
28593 + mconsole_register_dev(&gdb_mc);
28597 +__initcall(gdb_mc_init);
28602 + * Overrides for Emacs so that we follow Linus's tabbing style.
28603 + * Emacs will notice this stuff at the end of the file and automatically
28604 + * adjust the settings for this buffer only. This must remain at the end
28606 + * ---------------------------------------------------------------------------
28607 + * Local variables:
28608 + * c-file-style: "linux"
28611 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/debug.h um/arch/um/kernel/tt/include/debug.h
28612 --- orig/arch/um/kernel/tt/include/debug.h 1969-12-31 19:00:00.000000000 -0500
28613 +++ um/arch/um/kernel/tt/include/debug.h 2003-10-21 03:26:07.000000000 -0400
28616 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) and
28617 + * Lars Brinkhoff.
28618 + * Licensed under the GPL
28624 +extern int debugger_proxy(int status, pid_t pid);
28625 +extern void child_proxy(pid_t pid, int status);
28626 +extern void init_proxy (pid_t pid, int waiting, int status);
28627 +extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
28628 +extern void fake_child_exit(void);
28629 +extern int gdb_config(char *str);
28630 +extern int gdb_remove(char *unused);
28635 + * Overrides for Emacs so that we follow Linus's tabbing style.
28636 + * Emacs will notice this stuff at the end of the file and automatically
28637 + * adjust the settings for this buffer only. This must remain at the end
28639 + * ---------------------------------------------------------------------------
28640 + * Local variables:
28641 + * c-file-style: "linux"
28644 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mmu.h um/arch/um/kernel/tt/include/mmu.h
28645 --- orig/arch/um/kernel/tt/include/mmu.h 1969-12-31 19:00:00.000000000 -0500
28646 +++ um/arch/um/kernel/tt/include/mmu.h 2003-10-21 03:26:07.000000000 -0400
28649 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28650 + * Licensed under the GPL
28653 +#ifndef __TT_MMU_H
28654 +#define __TT_MMU_H
28656 +struct mmu_context_tt {
28662 + * Overrides for Emacs so that we follow Linus's tabbing style.
28663 + * Emacs will notice this stuff at the end of the file and automatically
28664 + * adjust the settings for this buffer only. This must remain at the end
28666 + * ---------------------------------------------------------------------------
28667 + * Local variables:
28668 + * c-file-style: "linux"
28671 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode.h um/arch/um/kernel/tt/include/mode.h
28672 --- orig/arch/um/kernel/tt/include/mode.h 1969-12-31 19:00:00.000000000 -0500
28673 +++ um/arch/um/kernel/tt/include/mode.h 2003-11-07 01:42:09.000000000 -0500
28676 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28677 + * Licensed under the GPL
28680 +#ifndef __MODE_TT_H__
28681 +#define __MODE_TT_H__
28683 +#include "sysdep/ptrace.h"
28685 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
28687 +extern int tracing_pid;
28689 +extern int tracer(int (*init_proc)(void *), void *sp);
28690 +extern void user_time_init_tt(void);
28691 +extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data);
28692 +extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr,
28694 +extern void sig_handler_common_tt(int sig, void *sc);
28695 +extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
28696 +extern void reboot_tt(void);
28697 +extern void halt_tt(void);
28698 +extern int is_tracer_winch(int pid, int fd, void *data);
28699 +extern void kill_off_processes_tt(void);
28704 + * Overrides for Emacs so that we follow Linus's tabbing style.
28705 + * Emacs will notice this stuff at the end of the file and automatically
28706 + * adjust the settings for this buffer only. This must remain at the end
28708 + * ---------------------------------------------------------------------------
28709 + * Local variables:
28710 + * c-file-style: "linux"
28713 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode_kern.h um/arch/um/kernel/tt/include/mode_kern.h
28714 --- orig/arch/um/kernel/tt/include/mode_kern.h 1969-12-31 19:00:00.000000000 -0500
28715 +++ um/arch/um/kernel/tt/include/mode_kern.h 2003-10-21 03:26:07.000000000 -0400
28718 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28719 + * Licensed under the GPL
28722 +#ifndef __TT_MODE_KERN_H__
28723 +#define __TT_MODE_KERN_H__
28725 +#include "linux/sched.h"
28726 +#include "asm/page.h"
28727 +#include "asm/ptrace.h"
28728 +#include "asm/uaccess.h"
28730 +extern void *_switch_to_tt(void *prev, void *next);
28731 +extern void flush_thread_tt(void);
28732 +extern void start_thread_tt(struct pt_regs *regs, unsigned long eip,
28733 + unsigned long esp);
28734 +extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
28735 + unsigned long stack_top, struct task_struct *p,
28736 + struct pt_regs *regs);
28737 +extern void release_thread_tt(struct task_struct *task);
28738 +extern void exit_thread_tt(void);
28739 +extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
28740 +extern void init_idle_tt(void);
28741 +extern void flush_tlb_kernel_vm_tt(void);
28742 +extern void __flush_tlb_one_tt(unsigned long addr);
28743 +extern void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start,
28744 + unsigned long end);
28745 +extern void flush_tlb_mm_tt(struct mm_struct *mm);
28746 +extern void force_flush_all_tt(void);
28747 +extern long execute_syscall_tt(void *r);
28748 +extern void before_mem_tt(unsigned long brk_start);
28749 +extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
28750 + unsigned long *task_size_out);
28751 +extern int start_uml_tt(void);
28752 +extern int external_pid_tt(struct task_struct *task);
28753 +extern int thread_pid_tt(struct thread_struct *thread);
28755 +#define kmem_end_tt (host_task_size - ABOVE_KMEM)
28760 + * Overrides for Emacs so that we follow Linus's tabbing style.
28761 + * Emacs will notice this stuff at the end of the file and automatically
28762 + * adjust the settings for this buffer only. This must remain at the end
28764 + * ---------------------------------------------------------------------------
28765 + * Local variables:
28766 + * c-file-style: "linux"
28769 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/ptrace-tt.h um/arch/um/kernel/tt/include/ptrace-tt.h
28770 --- orig/arch/um/kernel/tt/include/ptrace-tt.h 1969-12-31 19:00:00.000000000 -0500
28771 +++ um/arch/um/kernel/tt/include/ptrace-tt.h 2003-10-21 03:26:07.000000000 -0400
28774 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
28775 + * Licensed under the GPL
28778 +#ifndef __PTRACE_TT_H
28779 +#define __PTRACE_TT_H
28781 +#include "uml-config.h"
28783 +#ifdef UML_CONFIG_MODE_TT
28784 +#include "sysdep/sc.h"
28790 + * Overrides for Emacs so that we follow Linus's tabbing style.
28791 + * Emacs will notice this stuff at the end of the file and automatically
28792 + * adjust the settings for this buffer only. This must remain at the end
28794 + * ---------------------------------------------------------------------------
28795 + * Local variables:
28796 + * c-file-style: "linux"
28799 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/tt.h um/arch/um/kernel/tt/include/tt.h
28800 --- orig/arch/um/kernel/tt/include/tt.h 1969-12-31 19:00:00.000000000 -0500
28801 +++ um/arch/um/kernel/tt/include/tt.h 2003-10-21 03:26:07.000000000 -0400
28804 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28805 + * Licensed under the GPL
28811 +#include "sysdep/ptrace.h"
28813 +extern int gdb_pid;
28815 +extern int debug_stop;
28816 +extern int debug_trace;
28818 +extern int honeypot;
28820 +extern int fork_tramp(void *sig_stack);
28821 +extern int do_proc_op(void *t, int proc_id);
28822 +extern int tracer(int (*init_proc)(void *), void *sp);
28823 +extern void attach_process(int pid);
28824 +extern void tracer_panic(char *format, ...);
28825 +extern void set_init_pid(int pid);
28826 +extern int set_user_mode(void *task);
28827 +extern void set_tracing(void *t, int tracing);
28828 +extern int is_tracing(void *task);
28829 +extern int singlestepping_tt(void *t);
28830 +extern void clear_singlestep(void *t);
28831 +extern void syscall_handler(int sig, union uml_pt_regs *regs);
28832 +extern void exit_kernel(int pid, void *task);
28833 +extern int do_syscall(void *task, int pid);
28834 +extern int is_valid_pid(int pid);
28835 +extern void remap_data(void *segment_start, void *segment_end, int w);
28840 + * Overrides for Emacs so that we follow Linus's tabbing style.
28841 + * Emacs will notice this stuff at the end of the file and automatically
28842 + * adjust the settings for this buffer only. This must remain at the end
28844 + * ---------------------------------------------------------------------------
28845 + * Local variables:
28846 + * c-file-style: "linux"
28849 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/uaccess.h um/arch/um/kernel/tt/include/uaccess.h
28850 --- orig/arch/um/kernel/tt/include/uaccess.h 1969-12-31 19:00:00.000000000 -0500
28851 +++ um/arch/um/kernel/tt/include/uaccess.h 2003-11-12 08:37:20.000000000 -0500
28854 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
28855 + * Licensed under the GPL
28858 +#ifndef __TT_UACCESS_H
28859 +#define __TT_UACCESS_H
28861 +#include "linux/string.h"
28862 +#include "linux/sched.h"
28863 +#include "asm/processor.h"
28864 +#include "asm/errno.h"
28865 +#include "asm/current.h"
28866 +#include "asm/a.out.h"
28867 +#include "uml_uaccess.h"
28869 +#define ABOVE_KMEM (16 * 1024 * 1024)
28871 +extern unsigned long end_vm;
28872 +extern unsigned long uml_physmem;
28874 +#define under_task_size(addr, size) \
28875 + (((unsigned long) (addr) < TASK_SIZE) && \
28876 + (((unsigned long) (addr) + (size)) < TASK_SIZE))
28878 +#define is_stack(addr, size) \
28879 + (((unsigned long) (addr) < STACK_TOP) && \
28880 + ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
28881 + (((unsigned long) (addr) + (size)) <= STACK_TOP))
28883 +#define access_ok_tt(type, addr, size) \
28884 + ((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \
28885 + (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
28886 + (under_task_size(addr, size) || is_stack(addr, size))))
28888 +static inline int verify_area_tt(int type, const void * addr,
28889 + unsigned long size)
28891 + return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
28894 +extern unsigned long get_fault_addr(void);
28896 +extern int __do_copy_from_user(void *to, const void *from, int n,
28897 + void **fault_addr, void **fault_catcher);
28898 +extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
28899 + void **fault_addr, void **fault_catcher);
28900 +extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
28901 + void **fault_catcher);
28902 +extern int __do_strnlen_user(const char *str, unsigned long n,
28903 + void **fault_addr, void **fault_catcher);
28905 +extern int copy_from_user_tt(void *to, const void *from, int n);
28906 +extern int copy_to_user_tt(void *to, const void *from, int n);
28907 +extern int strncpy_from_user_tt(char *dst, const char *src, int count);
28908 +extern int __clear_user_tt(void *mem, int len);
28909 +extern int clear_user_tt(void *mem, int len);
28910 +extern int strnlen_user_tt(const void *str, int len);
28915 + * Overrides for Emacs so that we follow Linus's tabbing style.
28916 + * Emacs will notice this stuff at the end of the file and automatically
28917 + * adjust the settings for this buffer only. This must remain at the end
28919 + * ---------------------------------------------------------------------------
28920 + * Local variables:
28921 + * c-file-style: "linux"
28924 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ksyms.c um/arch/um/kernel/tt/ksyms.c
28925 --- orig/arch/um/kernel/tt/ksyms.c 1969-12-31 19:00:00.000000000 -0500
28926 +++ um/arch/um/kernel/tt/ksyms.c 2003-10-21 03:26:07.000000000 -0400
28929 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
28930 + * Licensed under the GPL
28933 +#include "linux/module.h"
28934 +#include "asm/uaccess.h"
28937 +EXPORT_SYMBOL(__do_copy_from_user);
28938 +EXPORT_SYMBOL(__do_copy_to_user);
28939 +EXPORT_SYMBOL(__do_strncpy_from_user);
28940 +EXPORT_SYMBOL(__do_strnlen_user);
28941 +EXPORT_SYMBOL(__do_clear_user);
28943 +EXPORT_SYMBOL(tracing_pid);
28944 +EXPORT_SYMBOL(honeypot);
28947 + * Overrides for Emacs so that we follow Linus's tabbing style.
28948 + * Emacs will notice this stuff at the end of the file and automatically
28949 + * adjust the settings for this buffer only. This must remain at the end
28951 + * ---------------------------------------------------------------------------
28952 + * Local variables:
28953 + * c-file-style: "linux"
28956 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/Makefile um/arch/um/kernel/tt/Makefile
28957 --- orig/arch/um/kernel/tt/Makefile 1969-12-31 19:00:00.000000000 -0500
28958 +++ um/arch/um/kernel/tt/Makefile 2003-11-12 08:34:27.000000000 -0500
28961 +# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
28962 +# Licensed under the GPL
28967 +obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
28968 + syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
28969 + uaccess.o uaccess_user.o
28971 +obj-$(CONFIG_PT_PROXY) += gdb_kern.o
28973 +subdir-y = sys-$(SUBARCH)
28974 +subdir-$(CONFIG_PT_PROXY) += ptproxy
28976 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
28978 +export-objs = ksyms.o
28980 +USER_OBJS = $(filter %_user.o,$(obj-y)) gdb.o time.o tracer.o
28982 +UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS))
28983 +UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS))
28985 +include $(TOPDIR)/Rules.make
28987 +$(USER_OBJS) : %.o: %.c
28988 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
28990 +$(O_TARGET) : unmap_fin.o
28993 + $(CC) $(UNMAP_CFLAGS) -c -o $@ $<
28995 +unmap_fin.o : unmap.o
28996 + ld -r -o $@ $< -lc -L/usr/lib
28999 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem.c um/arch/um/kernel/tt/mem.c
29000 --- orig/arch/um/kernel/tt/mem.c 1969-12-31 19:00:00.000000000 -0500
29001 +++ um/arch/um/kernel/tt/mem.c 2003-10-21 03:26:07.000000000 -0400
29004 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29005 + * Licensed under the GPL
29008 +#include "linux/stddef.h"
29009 +#include "linux/config.h"
29010 +#include "linux/mm.h"
29011 +#include "asm/uaccess.h"
29012 +#include "mem_user.h"
29013 +#include "kern_util.h"
29014 +#include "user_util.h"
29018 +void before_mem_tt(unsigned long brk_start)
29020 + if(!jail || debug)
29021 + remap_data(UML_ROUND_DOWN(&_stext), UML_ROUND_UP(&_etext), 1);
29022 + remap_data(UML_ROUND_DOWN(&_sdata), UML_ROUND_UP(&_edata), 1);
29023 + remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(brk_start), 1);
29026 +#ifdef CONFIG_HOST_2G_2G
29027 +#define TOP 0x80000000
29029 +#define TOP 0xc0000000
29032 +#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
29033 +#define START (TOP - SIZE)
29035 +unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
29036 + unsigned long *task_size_out)
29038 + /* Round up to the nearest 4M */
29039 + *host_size_out = ROUND_4M((unsigned long) &arg);
29040 + *task_size_out = START;
29045 + * Overrides for Emacs so that we follow Linus's tabbing style.
29046 + * Emacs will notice this stuff at the end of the file and automatically
29047 + * adjust the settings for this buffer only. This must remain at the end
29049 + * ---------------------------------------------------------------------------
29050 + * Local variables:
29051 + * c-file-style: "linux"
29054 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem_user.c um/arch/um/kernel/tt/mem_user.c
29055 --- orig/arch/um/kernel/tt/mem_user.c 1969-12-31 19:00:00.000000000 -0500
29056 +++ um/arch/um/kernel/tt/mem_user.c 2003-10-21 03:26:07.000000000 -0400
29059 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29060 + * Licensed under the GPL
29063 +#include <stdlib.h>
29064 +#include <stdio.h>
29065 +#include <unistd.h>
29066 +#include <string.h>
29067 +#include <errno.h>
29068 +#include <sys/mman.h>
29070 +#include "mem_user.h"
29071 +#include "user_util.h"
29073 +void remap_data(void *segment_start, void *segment_end, int w)
29076 + unsigned long size;
29079 + if(w) prot = PROT_WRITE;
29081 + prot |= PROT_READ | PROT_EXEC;
29082 + size = (unsigned long) segment_end -
29083 + (unsigned long) segment_start;
29084 + data = create_mem_file(size);
29085 + addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0);
29086 + if(addr == MAP_FAILED){
29087 + perror("mapping new data segment");
29090 + memcpy(addr, segment_start, size);
29091 + if(switcheroo(data, prot, addr, segment_start, size) < 0){
29092 + printf("switcheroo failed\n");
29098 + * Overrides for Emacs so that we follow Linus's tabbing style.
29099 + * Emacs will notice this stuff at the end of the file and automatically
29100 + * adjust the settings for this buffer only. This must remain at the end
29102 + * ---------------------------------------------------------------------------
29103 + * Local variables:
29104 + * c-file-style: "linux"
29107 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/process_kern.c um/arch/um/kernel/tt/process_kern.c
29108 --- orig/arch/um/kernel/tt/process_kern.c 1969-12-31 19:00:00.000000000 -0500
29109 +++ um/arch/um/kernel/tt/process_kern.c 2003-10-21 03:26:07.000000000 -0400
29112 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29113 + * Licensed under the GPL
29116 +#include "linux/sched.h"
29117 +#include "linux/signal.h"
29118 +#include "linux/kernel.h"
29119 +#include "asm/system.h"
29120 +#include "asm/pgalloc.h"
29121 +#include "asm/ptrace.h"
29122 +#include "irq_user.h"
29123 +#include "signal_user.h"
29124 +#include "kern_util.h"
29125 +#include "user_util.h"
29128 +#include "sigcontext.h"
29129 +#include "time_user.h"
29130 +#include "mem_user.h"
29136 +void *_switch_to_tt(void *prev, void *next)
29138 + struct task_struct *from, *to;
29139 + unsigned long flags;
29140 + int err, vtalrm, alrm, prof, cpu;
29142 + /* jailing and SMP are incompatible, so this doesn't need to be
29145 + static int reading;
29150 + to->thread.prev_sched = from;
29152 + cpu = from->processor;
29154 + forward_interrupts(to->thread.mode.tt.extern_pid);
29156 + forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid);
29158 + local_irq_save(flags);
29160 + vtalrm = change_sig(SIGVTALRM, 0);
29161 + alrm = change_sig(SIGALRM, 0);
29162 + prof = change_sig(SIGPROF, 0);
29168 + err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
29169 + if(err != sizeof(c))
29170 + panic("write of switch_pipe failed, err = %d", -err);
29173 + if(from->state == TASK_ZOMBIE)
29174 + os_kill_process(os_getpid(), 0);
29176 + err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
29177 + if(err != sizeof(c))
29178 + panic("read of switch_pipe failed, errno = %d", -err);
29180 + /* This works around a nasty race with 'jail'. If we are switching
29181 + * between two threads of a threaded app and the incoming process
29182 + * runs before the outgoing process reaches the read, and it makes
29183 + * it all the way out to userspace, then it will have write-protected
29184 + * the outgoing process stack. Then, when the outgoing process
29185 + * returns from the write, it will segfault because it can no longer
29186 + * write its own stack. So, in order to avoid that, the incoming
29187 + * thread sits in a loop yielding until 'reading' is set. This
29188 + * isn't entirely safe, since there may be a reschedule from a timer
29189 + * happening between setting 'reading' and sleeping in read. But,
29190 + * it should get a whole quantum in which to reach the read and sleep,
29191 + * which should be enough.
29195 + while(!reading) sched_yield();
29198 + change_sig(SIGVTALRM, vtalrm);
29199 + change_sig(SIGALRM, alrm);
29200 + change_sig(SIGPROF, prof);
29205 + local_irq_restore(flags);
29207 + return(current->thread.prev_sched);
29210 +void release_thread_tt(struct task_struct *task)
29212 + os_kill_process(task->thread.mode.tt.extern_pid, 0);
29215 +void exit_thread_tt(void)
29217 + os_close_file(current->thread.mode.tt.switch_pipe[0]);
29218 + os_close_file(current->thread.mode.tt.switch_pipe[1]);
29221 +extern void schedule_tail(struct task_struct *prev);
29223 +static void new_thread_handler(int sig)
29225 + unsigned long disable;
29226 + int (*fn)(void *);
29229 + fn = current->thread.request.u.thread.proc;
29230 + arg = current->thread.request.u.thread.arg;
29232 + UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
29233 + disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
29234 + (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
29235 + SC_SIGMASK(UPT_SC(¤t->thread.regs.regs)) &= ~disable;
29237 + suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
29239 + init_new_thread_signals(1);
29241 + free_page(current->thread.temp_stack);
29242 + set_cmdline("(kernel thread)");
29243 + force_flush_all();
29245 + if(current->thread.prev_sched != NULL)
29246 + schedule_tail(current->thread.prev_sched);
29247 + current->thread.prev_sched = NULL;
29249 + change_sig(SIGUSR1, 1);
29250 + change_sig(SIGVTALRM, 1);
29251 + change_sig(SIGPROF, 1);
29253 + if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf))
29257 +static int new_thread_proc(void *stack)
29259 + /* cli is needed to block out signals until this thread is properly
29260 + * scheduled. Otherwise, the tracing thread will get mighty upset
29261 + * about any signals that arrive before that.
29262 + * This has the complication that it sets the saved signal mask in
29263 + * the sigcontext to block signals. This gets restored when this
29264 + * thread (or a descendant, since they get a copy of this sigcontext)
29265 + * returns to userspace.
29266 + * So, this is compensated for elsewhere.
29267 + * XXX There is still a small window until cli() actually finishes
29268 + * where signals are possible - shouldn't be a problem in practice
29269 + * since SIGIO hasn't been forwarded here yet, and the cli should
29270 + * finish before a SIGVTALRM has time to be delivered.
29273 + init_new_thread_stack(stack, new_thread_handler);
29274 + os_usr1_process(os_getpid());
29278 +/* Signal masking - signals are blocked at the start of fork_tramp. They
29279 + * are re-enabled when finish_fork_handler is entered by fork_tramp hitting
29280 + * itself with a SIGUSR1. set_user_mode has to be run with SIGUSR1 off,
29281 + * so it is blocked before it's called. They are re-enabled on sigreturn
29282 + * despite the fact that they were blocked when the SIGUSR1 was issued because
29283 + * copy_thread copies the parent's sigcontext, including the signal mask
29284 + * onto the signal frame.
29287 +static void finish_fork_handler(int sig)
29289 + UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
29290 + suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
29292 + init_new_thread_signals(1);
29295 + force_flush_all();
29296 + if(current->mm != current->p_pptr->mm)
29297 + protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
29299 + task_protections((unsigned long) current);
29301 + if(current->thread.prev_sched != NULL)
29302 + schedule_tail(current->thread.prev_sched);
29303 + current->thread.prev_sched = NULL;
29305 + free_page(current->thread.temp_stack);
29307 + change_sig(SIGUSR1, 0);
29308 + set_user_mode(current);
29311 +int fork_tramp(void *stack)
29314 + arch_init_thread();
29315 + init_new_thread_stack(stack, finish_fork_handler);
29316 + os_usr1_process(os_getpid());
29320 +int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
29321 + unsigned long stack_top, struct task_struct * p,
29322 + struct pt_regs *regs)
29324 + int (*tramp)(void *);
29325 + int new_pid, err;
29326 + unsigned long stack;
29328 + if(current->thread.forking)
29329 + tramp = fork_tramp;
29331 + tramp = new_thread_proc;
29332 + p->thread.request.u.thread = current->thread.request.u.thread;
29335 + err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
29337 + printk("copy_thread : pipe failed, err = %d\n", -err);
29341 + stack = alloc_stack(0, 0);
29343 + printk(KERN_ERR "copy_thread : failed to allocate "
29344 + "temporary stack\n");
29348 + clone_flags &= CLONE_VM;
29349 + p->thread.temp_stack = stack;
29350 + new_pid = start_fork_tramp((void *) p->thread.kernel_stack, stack,
29351 + clone_flags, tramp);
29353 + printk(KERN_ERR "copy_thread : clone failed - errno = %d\n",
29358 + if(current->thread.forking){
29359 + sc_to_sc(UPT_SC(&p->thread.regs.regs),
29360 + UPT_SC(¤t->thread.regs.regs));
29361 + SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
29362 + if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
29364 + p->thread.mode.tt.extern_pid = new_pid;
29366 + current->thread.request.op = OP_FORK;
29367 + current->thread.request.u.fork.pid = new_pid;
29368 + os_usr1_process(os_getpid());
29372 +void reboot_tt(void)
29374 + current->thread.request.op = OP_REBOOT;
29375 + os_usr1_process(os_getpid());
29376 + os_kill_process(os_getpid(), 0);
29379 +void halt_tt(void)
29381 + current->thread.request.op = OP_HALT;
29382 + os_usr1_process(os_getpid());
29383 + os_kill_process(os_getpid(), 0);
29386 +void kill_off_processes_tt(void)
29388 + struct task_struct *p;
29391 + me = os_getpid();
29392 + for_each_task(p){
29393 + int pid = p->thread.mode.tt.extern_pid;
29394 + if((pid != me) && (pid != -1))
29395 + os_kill_process(p->thread.mode.tt.extern_pid, 0);
29397 + if((init_task.thread.mode.tt.extern_pid != me) &&
29398 + (init_task.thread.mode.tt.extern_pid != -1))
29399 + os_kill_process(init_task.thread.mode.tt.extern_pid, 0);
29402 +void initial_thread_cb_tt(void (*proc)(void *), void *arg)
29404 + if(os_getpid() == tracing_pid){
29408 + current->thread.request.op = OP_CB;
29409 + current->thread.request.u.cb.proc = proc;
29410 + current->thread.request.u.cb.arg = arg;
29411 + os_usr1_process(os_getpid());
29415 +int do_proc_op(void *t, int proc_id)
29417 + struct task_struct *task;
29418 + struct thread_struct *thread;
29422 + thread = &task->thread;
29423 + op = thread->request.op;
29426 + case OP_TRACE_ON:
29429 + pid = thread->request.u.exec.pid;
29430 + do_exec(thread->mode.tt.extern_pid, pid);
29431 + thread->mode.tt.extern_pid = pid;
29432 + cpu_tasks[task->processor].pid = pid;
29435 + attach_process(thread->request.u.fork.pid);
29438 + (*thread->request.u.cb.proc)(thread->request.u.cb.arg);
29444 + tracer_panic("Bad op in do_proc_op");
29447 + thread->request.op = OP_NONE;
29451 +void init_idle_tt(void)
29456 +/* Changed by jail_setup, which is a setup */
29459 +int __init jail_setup(char *line, int *add)
29463 + if(jail) return(0);
29465 + printf("'jail' may not used used in a kernel with CONFIG_SMP "
29469 +#ifdef CONFIG_HOSTFS
29470 + printf("'jail' may not used used in a kernel with CONFIG_HOSTFS "
29474 +#ifdef CONFIG_MODULES
29475 + printf("'jail' may not used used in a kernel with CONFIG_MODULES "
29481 + /* CAP_SYS_RAWIO controls the ability to open /dev/mem and /dev/kmem.
29482 + * Removing it from the bounding set eliminates the ability of anything
29483 + * to acquire it, and thus read or write kernel memory.
29485 + cap_lower(cap_bset, CAP_SYS_RAWIO);
29490 +__uml_setup("jail", jail_setup,
29492 +" Enables the protection of kernel memory from processes.\n\n"
29495 +static void mprotect_kernel_mem(int w)
29497 + unsigned long start, end;
29500 + if(!jail || (current == &init_task)) return;
29502 + pages = (1 << CONFIG_KERNEL_STACK_ORDER);
29504 + start = (unsigned long) current + PAGE_SIZE;
29505 + end = (unsigned long) current + PAGE_SIZE * pages;
29506 + protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
29507 + protect_memory(end, high_physmem - end, 1, w, 1, 1);
29509 + start = (unsigned long) UML_ROUND_DOWN(&_stext);
29510 + end = (unsigned long) UML_ROUND_UP(&_etext);
29511 + protect_memory(start, end - start, 1, w, 1, 1);
29513 + start = (unsigned long) UML_ROUND_DOWN(&_unprotected_end);
29514 + end = (unsigned long) UML_ROUND_UP(&_edata);
29515 + protect_memory(start, end - start, 1, w, 1, 1);
29517 + start = (unsigned long) UML_ROUND_DOWN(&__bss_start);
29518 + end = (unsigned long) UML_ROUND_UP(brk_start);
29519 + protect_memory(start, end - start, 1, w, 1, 1);
29521 + mprotect_kernel_vm(w);
29524 +void unprotect_kernel_mem(void)
29526 + mprotect_kernel_mem(1);
29529 +void protect_kernel_mem(void)
29531 + mprotect_kernel_mem(0);
29534 +extern void start_kernel(void);
29536 +static int start_kernel_proc(void *unused)
29541 + pid = os_getpid();
29543 + cpu_tasks[0].pid = pid;
29544 + cpu_tasks[0].task = current;
29546 + cpu_online_map = 1;
29548 + if(debug) os_stop_process(pid);
29553 +void set_tracing(void *task, int tracing)
29555 + ((struct task_struct *) task)->thread.mode.tt.tracing = tracing;
29558 +int is_tracing(void *t)
29560 + return (((struct task_struct *) t)->thread.mode.tt.tracing);
29563 +int set_user_mode(void *t)
29565 + struct task_struct *task;
29567 + task = t ? t : current;
29568 + if(task->thread.mode.tt.tracing)
29570 + task->thread.request.op = OP_TRACE_ON;
29571 + os_usr1_process(os_getpid());
29575 +void set_init_pid(int pid)
29579 + init_task.thread.mode.tt.extern_pid = pid;
29580 + err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
29582 + panic("Can't create switch pipe for init_task, errno = %d",
29586 +int singlestepping_tt(void *t)
29588 + struct task_struct *task = t;
29590 + if(task->thread.mode.tt.singlestep_syscall)
29592 + return(task->ptrace & PT_DTRACE);
29595 +void clear_singlestep(void *t)
29597 + struct task_struct *task = t;
29599 + task->ptrace &= ~PT_DTRACE;
29602 +int start_uml_tt(void)
29607 + pages = (1 << CONFIG_KERNEL_STACK_ORDER) - 2;
29608 + sp = (void *) init_task.thread.kernel_stack + pages * PAGE_SIZE -
29609 + sizeof(unsigned long);
29610 + return(tracer(start_kernel_proc, sp));
29613 +int external_pid_tt(struct task_struct *task)
29615 + return(task->thread.mode.tt.extern_pid);
29618 +int thread_pid_tt(struct thread_struct *thread)
29620 + return(thread->mode.tt.extern_pid);
29623 +int is_valid_pid(int pid)
29625 + struct task_struct *task;
29627 + read_lock(&tasklist_lock);
29628 + for_each_task(task){
29629 + if(task->thread.mode.tt.extern_pid == pid){
29630 + read_unlock(&tasklist_lock);
29634 + read_unlock(&tasklist_lock);
29639 + * Overrides for Emacs so that we follow Linus's tabbing style.
29640 + * Emacs will notice this stuff at the end of the file and automatically
29641 + * adjust the settings for this buffer only. This must remain at the end
29643 + * ---------------------------------------------------------------------------
29644 + * Local variables:
29645 + * c-file-style: "linux"
29648 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/Makefile um/arch/um/kernel/tt/ptproxy/Makefile
29649 --- orig/arch/um/kernel/tt/ptproxy/Makefile 1969-12-31 19:00:00.000000000 -0500
29650 +++ um/arch/um/kernel/tt/ptproxy/Makefile 2003-10-21 03:26:07.000000000 -0400
29652 +O_TARGET = ptproxy.o
29654 +obj-y = proxy.o ptrace.o sysdep.o wait.o
29656 +USER_OBJS = $(obj-y)
29658 +include $(TOPDIR)/Rules.make
29660 +$(USER_OBJS) : %.o: %.c
29661 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
29664 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/proxy.c um/arch/um/kernel/tt/ptproxy/proxy.c
29665 --- orig/arch/um/kernel/tt/ptproxy/proxy.c 1969-12-31 19:00:00.000000000 -0500
29666 +++ um/arch/um/kernel/tt/ptproxy/proxy.c 2003-10-21 03:26:07.000000000 -0400
29668 +/**********************************************************************
29671 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
29672 +terms and conditions.
29674 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
29675 +**********************************************************************/
29677 +/* XXX This file shouldn't refer to CONFIG_* */
29679 +#include <errno.h>
29680 +#include <stdio.h>
29681 +#include <stdlib.h>
29682 +#include <unistd.h>
29683 +#include <signal.h>
29684 +#include <string.h>
29685 +#include <termios.h>
29686 +#include <sys/wait.h>
29687 +#include <sys/types.h>
29688 +#include <sys/ptrace.h>
29689 +#include <sys/ioctl.h>
29690 +#include <asm/unistd.h>
29692 +#include "ptproxy.h"
29693 +#include "sysdep.h"
29696 +#include "user_util.h"
29699 +#include "tempfile.h"
29701 +static int debugger_wait(debugger_state *debugger, int *status, int options,
29702 + int (*syscall)(debugger_state *debugger, pid_t child),
29703 + int (*normal_return)(debugger_state *debugger,
29705 + int (*wait_return)(debugger_state *debugger,
29708 + if(debugger->real_wait){
29709 + debugger->handle_trace = normal_return;
29710 + syscall_continue(debugger->pid);
29711 + debugger->real_wait = 0;
29714 + debugger->wait_status_ptr = status;
29715 + debugger->wait_options = options;
29716 + if((debugger->debugee != NULL) && debugger->debugee->event){
29717 + syscall_continue(debugger->pid);
29718 + wait_for_stop(debugger->pid, SIGTRAP, PTRACE_SYSCALL,
29720 + (*wait_return)(debugger, -1);
29723 + else if(debugger->wait_options & WNOHANG){
29724 + syscall_cancel(debugger->pid, 0);
29725 + debugger->handle_trace = syscall;
29729 + syscall_pause(debugger->pid);
29730 + debugger->handle_trace = wait_return;
29731 + debugger->waiting = 1;
29737 + * Handle debugger trap, i.e. syscall.
29740 +int debugger_syscall(debugger_state *debugger, pid_t child)
29742 + long arg1, arg2, arg3, arg4, arg5, result;
29743 + int syscall, ret = 0;
29745 + syscall = get_syscall(debugger->pid, &arg1, &arg2, &arg3, &arg4,
29749 + case __NR_execve:
29750 + /* execve never returns */
29751 + debugger->handle_trace = debugger_syscall;
29754 + case __NR_ptrace:
29755 + if(debugger->debugee->pid != 0) arg2 = debugger->debugee->pid;
29756 + if(!debugger->debugee->in_context)
29757 + child = debugger->debugee->pid;
29758 + result = proxy_ptrace(debugger, arg1, arg2, arg3, arg4, child,
29760 + syscall_cancel(debugger->pid, result);
29761 + debugger->handle_trace = debugger_syscall;
29764 + case __NR_waitpid:
29766 + if(!debugger_wait(debugger, (int *) arg2, arg3,
29767 + debugger_syscall, debugger_normal_return,
29768 + proxy_wait_return))
29773 + if(!debugger->debugee->in_context)
29774 + child = debugger->debugee->pid;
29775 + if(arg1 == debugger->debugee->pid){
29776 + result = kill(child, arg2);
29777 + syscall_cancel(debugger->pid, result);
29778 + debugger->handle_trace = debugger_syscall;
29781 + else debugger->handle_trace = debugger_normal_return;
29785 + debugger->handle_trace = debugger_normal_return;
29788 + syscall_continue(debugger->pid);
29792 +/* Used by the tracing thread */
29793 +static debugger_state parent;
29794 +static int parent_syscall(debugger_state *debugger, int pid);
29796 +int init_parent_proxy(int pid)
29798 + parent = ((debugger_state) { .pid = pid,
29799 + .wait_options = 0,
29800 + .wait_status_ptr = NULL,
29803 + .expecting_child = 0,
29804 + .handle_trace = parent_syscall,
29805 + .debugee = NULL } );
29809 +int parent_normal_return(debugger_state *debugger, pid_t unused)
29811 + debugger->handle_trace = parent_syscall;
29812 + syscall_continue(debugger->pid);
29816 +static int parent_syscall(debugger_state *debugger, int pid)
29818 + long arg1, arg2, arg3, arg4, arg5;
29821 + syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5);
29823 + if((syscall == __NR_waitpid) || (syscall == __NR_wait4)){
29824 + debugger_wait(&parent, (int *) arg2, arg3, parent_syscall,
29825 + parent_normal_return, parent_wait_return);
29827 + else ptrace(PTRACE_SYSCALL, pid, 0, 0);
29831 +int debugger_normal_return(debugger_state *debugger, pid_t unused)
29833 + debugger->handle_trace = debugger_syscall;
29834 + syscall_continue(debugger->pid);
29838 +void debugger_cancelled_return(debugger_state *debugger, int result)
29840 + debugger->handle_trace = debugger_syscall;
29841 + syscall_set_result(debugger->pid, result);
29842 + syscall_continue(debugger->pid);
29845 +/* Used by the tracing thread */
29846 +static debugger_state debugger;
29847 +static debugee_state debugee;
29849 +void init_proxy (pid_t debugger_pid, int stopped, int status)
29851 + debugger.pid = debugger_pid;
29852 + debugger.handle_trace = debugger_syscall;
29853 + debugger.debugee = &debugee;
29854 + debugger.waiting = 0;
29855 + debugger.real_wait = 0;
29856 + debugger.expecting_child = 0;
29859 + debugee.traced = 0;
29860 + debugee.stopped = stopped;
29861 + debugee.event = 0;
29862 + debugee.zombie = 0;
29863 + debugee.died = 0;
29864 + debugee.wait_status = status;
29865 + debugee.in_context = 1;
29868 +int debugger_proxy(int status, int pid)
29870 + int ret = 0, sig;
29872 + if(WIFSTOPPED(status)){
29873 + sig = WSTOPSIG(status);
29874 + if (sig == SIGTRAP)
29875 + ret = (*debugger.handle_trace)(&debugger, pid);
29877 + else if(sig == SIGCHLD){
29878 + if(debugger.expecting_child){
29879 + ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
29880 + debugger.expecting_child = 0;
29882 + else if(debugger.waiting)
29883 + real_wait_return(&debugger);
29885 + ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
29886 + debugger.real_wait = 1;
29889 + else ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
29891 + else if(WIFEXITED(status)){
29892 + tracer_panic("debugger (pid %d) exited with status %d",
29893 + debugger.pid, WEXITSTATUS(status));
29895 + else if(WIFSIGNALED(status)){
29896 + tracer_panic("debugger (pid %d) exited with signal %d",
29897 + debugger.pid, WTERMSIG(status));
29900 + tracer_panic("proxy got unknown status (0x%x) on debugger "
29901 + "(pid %d)", status, debugger.pid);
29906 +void child_proxy(pid_t pid, int status)
29908 + debugee.event = 1;
29909 + debugee.wait_status = status;
29911 + if(WIFSTOPPED(status)){
29912 + debugee.stopped = 1;
29913 + debugger.expecting_child = 1;
29914 + kill(debugger.pid, SIGCHLD);
29916 + else if(WIFEXITED(status) || WIFSIGNALED(status)){
29917 + debugee.zombie = 1;
29918 + debugger.expecting_child = 1;
29919 + kill(debugger.pid, SIGCHLD);
29921 + else panic("proxy got unknown status (0x%x) on child (pid %d)",
29925 +void debugger_parent_signal(int status, int pid)
29929 + if(WIFSTOPPED(status)){
29930 + sig = WSTOPSIG(status);
29931 + if(sig == SIGTRAP) (*parent.handle_trace)(&parent, pid);
29932 + else ptrace(PTRACE_SYSCALL, pid, 0, sig);
29936 +void fake_child_exit(void)
29940 + child_proxy(1, W_EXITCODE(0, 0));
29941 + while(debugger.waiting == 1){
29942 + pid = waitpid(debugger.pid, &status, WUNTRACED);
29943 + if(pid != debugger.pid){
29944 + printk("fake_child_exit - waitpid failed, "
29945 + "errno = %d\n", errno);
29948 + debugger_proxy(status, debugger.pid);
29950 + pid = waitpid(debugger.pid, &status, WUNTRACED);
29951 + if(pid != debugger.pid){
29952 + printk("fake_child_exit - waitpid failed, "
29953 + "errno = %d\n", errno);
29956 + if(ptrace(PTRACE_DETACH, debugger.pid, 0, SIGCONT) < 0)
29957 + printk("fake_child_exit - PTRACE_DETACH failed, errno = %d\n",
29961 +char gdb_init_string[] =
29965 +handle SIGWINCH nostop noprint pass \n\
29968 +int start_debugger(char *prog, int startup, int stop, int *fd_out)
29970 + int slave, child;
29972 + slave = open_gdb_chan();
29975 + char *tempname = NULL;
29978 + if(setsid() < 0) perror("setsid");
29979 + if((dup2(slave, 0) < 0) || (dup2(slave, 1) < 0) ||
29980 + (dup2(slave, 2) < 0)){
29981 + printk("start_debugger : dup2 failed, errno = %d\n",
29985 + if(ioctl(0, TIOCSCTTY, 0) < 0){
29986 + printk("start_debugger : TIOCSCTTY failed, "
29987 + "errno = %d\n", errno);
29990 + if(tcsetpgrp (1, os_getpid()) < 0){
29991 + printk("start_debugger : tcsetpgrp failed, "
29992 + "errno = %d\n", errno);
29997 + fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
29999 + printk("start_debugger : make_tempfile failed,"
30000 + "err = %d\n", -fd);
30003 + os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
30006 + os_write_file(fd, "b start_kernel\n",
30007 + strlen("b start_kernel\n"));
30009 + os_write_file(fd, "c\n", strlen("c\n"));
30011 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
30012 + printk("start_debugger : PTRACE_TRACEME failed, "
30013 + "errno = %d\n", errno);
30016 + execlp("gdb", "gdb", "--command", tempname, prog, NULL);
30017 + printk("start_debugger : exec of gdb failed, errno = %d\n",
30021 + printk("start_debugger : fork for gdb failed, errno = %d\n",
30030 + * Overrides for Emacs so that we follow Linus's tabbing style.
30031 + * Emacs will notice this stuff at the end of the file and automatically
30032 + * adjust the settings for this buffer only. This must remain at the end
30034 + * ---------------------------------------------------------------------------
30035 + * Local variables:
30036 + * c-file-style: "linux"
30039 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptproxy.h um/arch/um/kernel/tt/ptproxy/ptproxy.h
30040 --- orig/arch/um/kernel/tt/ptproxy/ptproxy.h 1969-12-31 19:00:00.000000000 -0500
30041 +++ um/arch/um/kernel/tt/ptproxy/ptproxy.h 2003-10-21 03:26:07.000000000 -0400
30043 +/**********************************************************************
30046 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
30047 +terms and conditions.
30048 +**********************************************************************/
30050 +#ifndef __PTPROXY_H
30051 +#define __PTPROXY_H
30053 +#include <sys/types.h>
30055 +typedef struct debugger debugger_state;
30056 +typedef struct debugee debugee_state;
30061 + int wait_options;
30062 + int *wait_status_ptr;
30063 + unsigned int waiting : 1;
30064 + unsigned int real_wait : 1;
30065 + unsigned int expecting_child : 1;
30066 + int (*handle_trace) (debugger_state *, pid_t);
30068 + debugee_state *debugee;
30075 + unsigned int died : 1;
30076 + unsigned int event : 1;
30077 + unsigned int stopped : 1;
30078 + unsigned int trace_singlestep : 1;
30079 + unsigned int trace_syscall : 1;
30080 + unsigned int traced : 1;
30081 + unsigned int zombie : 1;
30082 + unsigned int in_context : 1;
30085 +extern int debugger_syscall(debugger_state *debugger, pid_t pid);
30086 +extern int debugger_normal_return (debugger_state *debugger, pid_t unused);
30088 +extern long proxy_ptrace (struct debugger *, int, pid_t, long, long, pid_t,
30089 + int *strace_out);
30090 +extern void debugger_cancelled_return(debugger_state *debugger, int result);
30095 + * Overrides for Emacs so that we follow Linus's tabbing style.
30096 + * Emacs will notice this stuff at the end of the file and automatically
30097 + * adjust the settings for this buffer only. This must remain at the end
30099 + * ---------------------------------------------------------------------------
30100 + * Local variables:
30101 + * c-file-style: "linux"
30104 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptrace.c um/arch/um/kernel/tt/ptproxy/ptrace.c
30105 --- orig/arch/um/kernel/tt/ptproxy/ptrace.c 1969-12-31 19:00:00.000000000 -0500
30106 +++ um/arch/um/kernel/tt/ptproxy/ptrace.c 2003-10-21 03:26:07.000000000 -0400
30108 +/**********************************************************************
30111 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
30112 +terms and conditions.
30114 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
30115 +**********************************************************************/
30117 +#include <errno.h>
30118 +#include <unistd.h>
30119 +#include <signal.h>
30120 +#include <sys/types.h>
30121 +#include <sys/time.h>
30122 +#include <sys/ptrace.h>
30123 +#include <sys/wait.h>
30124 +#include <asm/ptrace.h>
30126 +#include "ptproxy.h"
30127 +#include "debug.h"
30128 +#include "user_util.h"
30129 +#include "kern_util.h"
30130 +#include "ptrace_user.h"
30133 +long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
30134 + long arg3, long arg4, pid_t child, int *ret)
30141 + if(debugger->debugee->died) return(-ESRCH);
30144 + case PTRACE_ATTACH:
30145 + if(debugger->debugee->traced) return(-EPERM);
30147 + debugger->debugee->pid = arg2;
30148 + debugger->debugee->traced = 1;
30150 + if(is_valid_pid(arg2) && (arg2 != child)){
30151 + debugger->debugee->in_context = 0;
30152 + kill(arg2, SIGSTOP);
30153 + debugger->debugee->event = 1;
30154 + debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);
30157 + debugger->debugee->in_context = 1;
30158 + if(debugger->debugee->stopped)
30159 + child_proxy(child, W_STOPCODE(SIGSTOP));
30160 + else kill(child, SIGSTOP);
30165 + case PTRACE_DETACH:
30166 + if(!debugger->debugee->traced) return(-EPERM);
30168 + debugger->debugee->traced = 0;
30169 + debugger->debugee->pid = 0;
30170 + if(!debugger->debugee->in_context)
30171 + kill(child, SIGCONT);
30175 + case PTRACE_CONT:
30176 + if(!debugger->debugee->in_context) return(-EPERM);
30177 + *ret = PTRACE_CONT;
30178 + return(ptrace(PTRACE_CONT, child, arg3, arg4));
30180 +#ifdef UM_HAVE_GETFPREGS
30181 + case PTRACE_GETFPREGS:
30183 + long regs[FP_FRAME_SIZE];
30186 + result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
30187 + if(result == -1) return(-errno);
30189 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30190 + ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
30196 +#ifdef UM_HAVE_GETFPXREGS
30197 + case PTRACE_GETFPXREGS:
30199 + long regs[FPX_FRAME_SIZE];
30202 + result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
30203 + if(result == -1) return(-errno);
30205 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30206 + ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
30212 +#ifdef UM_HAVE_GETREGS
30213 + case PTRACE_GETREGS:
30215 + long regs[FRAME_SIZE];
30218 + result = ptrace(PTRACE_GETREGS, child, 0, regs);
30219 + if(result == -1) return(-errno);
30221 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30222 + ptrace (PTRACE_POKEDATA, debugger->pid,
30223 + arg4 + 4 * i, regs[i]);
30229 + case PTRACE_KILL:
30230 + result = ptrace(PTRACE_KILL, child, arg3, arg4);
30231 + if(result == -1) return(-errno);
30235 + case PTRACE_PEEKDATA:
30236 + case PTRACE_PEEKTEXT:
30237 + case PTRACE_PEEKUSER:
30238 + /* The value being read out could be -1, so we have to
30239 + * check errno to see if there's an error, and zero it
30240 + * beforehand so we're not faked out by an old error
30244 + result = ptrace(arg1, child, arg3, 0);
30245 + if((result == -1) && (errno != 0)) return(-errno);
30247 + result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
30248 + if(result == -1) return(-errno);
30252 + case PTRACE_POKEDATA:
30253 + case PTRACE_POKETEXT:
30254 + case PTRACE_POKEUSER:
30255 + result = ptrace(arg1, child, arg3, arg4);
30256 + if(result == -1) return(-errno);
30258 + if(arg1 == PTRACE_POKEUSER) ptrace_pokeuser(arg3, arg4);
30261 +#ifdef UM_HAVE_SETFPREGS
30262 + case PTRACE_SETFPREGS:
30264 + long regs[FP_FRAME_SIZE];
30267 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30268 + regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
30269 + arg4 + 4 * i, 0);
30270 + result = ptrace(PTRACE_SETFPREGS, child, 0, regs);
30271 + if(result == -1) return(-errno);
30277 +#ifdef UM_HAVE_SETFPXREGS
30278 + case PTRACE_SETFPXREGS:
30280 + long regs[FPX_FRAME_SIZE];
30283 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30284 + regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
30285 + arg4 + 4 * i, 0);
30286 + result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);
30287 + if(result == -1) return(-errno);
30293 +#ifdef UM_HAVE_SETREGS
30294 + case PTRACE_SETREGS:
30296 + long regs[FRAME_SIZE];
30299 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30300 + regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,
30301 + arg4 + 4 * i, 0);
30302 + result = ptrace(PTRACE_SETREGS, child, 0, regs);
30303 + if(result == -1) return(-errno);
30309 + case PTRACE_SINGLESTEP:
30310 + if(!debugger->debugee->in_context) return(-EPERM);
30311 + sigemptyset(&relay);
30312 + sigaddset(&relay, SIGSEGV);
30313 + sigaddset(&relay, SIGILL);
30314 + sigaddset(&relay, SIGBUS);
30315 + result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4);
30316 + if(result == -1) return(-errno);
30318 + status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
30320 + child_proxy(child, status);
30323 + case PTRACE_SYSCALL:
30324 + if(!debugger->debugee->in_context) return(-EPERM);
30325 + result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);
30326 + if(result == -1) return(-errno);
30328 + *ret = PTRACE_SYSCALL;
30331 + case PTRACE_TRACEME:
30338 + * Overrides for Emacs so that we follow Linus's tabbing style.
30339 + * Emacs will notice this stuff at the end of the file and automatically
30340 + * adjust the settings for this buffer only. This must remain at the end
30342 + * ---------------------------------------------------------------------------
30343 + * Local variables:
30344 + * c-file-style: "linux"
30347 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.c um/arch/um/kernel/tt/ptproxy/sysdep.c
30348 --- orig/arch/um/kernel/tt/ptproxy/sysdep.c 1969-12-31 19:00:00.000000000 -0500
30349 +++ um/arch/um/kernel/tt/ptproxy/sysdep.c 2003-10-21 03:26:07.000000000 -0400
30351 +/**********************************************************************
30354 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
30355 +terms and conditions.
30356 +**********************************************************************/
30358 +#include <stdio.h>
30359 +#include <string.h>
30360 +#include <stdlib.h>
30361 +#include <signal.h>
30362 +#include <errno.h>
30363 +#include <sys/types.h>
30364 +#include <sys/ptrace.h>
30365 +#include <asm/ptrace.h>
30366 +#include <linux/unistd.h>
30367 +#include "ptrace_user.h"
30368 +#include "user_util.h"
30371 +int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4,
30374 + *arg1 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG1_OFFSET, 0);
30375 + *arg2 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG2_OFFSET, 0);
30376 + *arg3 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG3_OFFSET, 0);
30377 + *arg4 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG4_OFFSET, 0);
30378 + *arg5 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG5_OFFSET, 0);
30379 + return(ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET, 0));
30382 +void syscall_cancel(pid_t pid, int result)
30384 + if((ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
30385 + __NR_getpid) < 0) ||
30386 + (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) ||
30387 + (wait_for_stop(pid, SIGTRAP, PTRACE_SYSCALL, NULL) < 0) ||
30388 + (ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result) < 0) ||
30389 + (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0))
30390 + printk("ptproxy: couldn't cancel syscall: errno = %d\n",
30394 +void syscall_set_result(pid_t pid, long result)
30396 + ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result);
30399 +void syscall_continue(pid_t pid)
30401 + ptrace(PTRACE_SYSCALL, pid, 0, 0);
30404 +int syscall_pause(pid_t pid)
30406 + if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_pause) < 0){
30407 + printk("syscall_change - ptrace failed, errno = %d\n", errno);
30414 + * Overrides for Emacs so that we follow Linus's tabbing style.
30415 + * Emacs will notice this stuff at the end of the file and automatically
30416 + * adjust the settings for this buffer only. This must remain at the end
30418 + * ---------------------------------------------------------------------------
30419 + * Local variables:
30420 + * c-file-style: "linux"
30423 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.h um/arch/um/kernel/tt/ptproxy/sysdep.h
30424 --- orig/arch/um/kernel/tt/ptproxy/sysdep.h 1969-12-31 19:00:00.000000000 -0500
30425 +++ um/arch/um/kernel/tt/ptproxy/sysdep.h 2003-10-21 03:26:07.000000000 -0400
30427 +/**********************************************************************
30430 +Copyright (C) 1999 Lars Brinkhoff.
30431 +Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
30432 +See the file COPYING for licensing terms and conditions.
30433 +**********************************************************************/
30435 +extern int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3,
30436 + long *arg4, long *arg5);
30437 +extern void syscall_cancel (pid_t pid, long result);
30438 +extern void syscall_set_result (pid_t pid, long result);
30439 +extern void syscall_continue (pid_t pid);
30440 +extern int syscall_pause(pid_t pid);
30443 + * Overrides for Emacs so that we follow Linus's tabbing style.
30444 + * Emacs will notice this stuff at the end of the file and automatically
30445 + * adjust the settings for this buffer only. This must remain at the end
30447 + * ---------------------------------------------------------------------------
30448 + * Local variables:
30449 + * c-file-style: "linux"
30452 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.c um/arch/um/kernel/tt/ptproxy/wait.c
30453 --- orig/arch/um/kernel/tt/ptproxy/wait.c 1969-12-31 19:00:00.000000000 -0500
30454 +++ um/arch/um/kernel/tt/ptproxy/wait.c 2003-10-21 03:26:07.000000000 -0400
30456 +/**********************************************************************
30459 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
30460 +terms and conditions.
30462 +**********************************************************************/
30464 +#include <errno.h>
30465 +#include <signal.h>
30466 +#include <sys/wait.h>
30467 +#include <sys/ptrace.h>
30468 +#include <asm/ptrace.h>
30470 +#include "ptproxy.h"
30471 +#include "sysdep.h"
30473 +#include "user_util.h"
30474 +#include "sysdep/ptrace.h"
30475 +#include "sysdep/ptrace_user.h"
30476 +#include "sysdep/sigcontext.h"
30478 +int proxy_wait_return(struct debugger *debugger, pid_t unused)
30480 + debugger->waiting = 0;
30482 + if(debugger->debugee->died || (debugger->wait_options & __WCLONE)){
30483 + debugger_cancelled_return(debugger, -ECHILD);
30487 + if(debugger->debugee->zombie && debugger->debugee->event)
30488 + debugger->debugee->died = 1;
30490 + if(debugger->debugee->event){
30491 + debugger->debugee->event = 0;
30492 + ptrace(PTRACE_POKEDATA, debugger->pid,
30493 + debugger->wait_status_ptr,
30494 + debugger->debugee->wait_status);
30496 + ptrace (PTRACE_POKEDATA, pid, rusage_ptr, ...); */
30497 + debugger_cancelled_return(debugger, debugger->debugee->pid);
30501 + /* pause will return -EINTR, which happens to be right for wait */
30502 + debugger_normal_return(debugger, -1);
30506 +int parent_wait_return(struct debugger *debugger, pid_t unused)
30508 + return(debugger_normal_return(debugger, -1));
30511 +int real_wait_return(struct debugger *debugger)
30513 + unsigned long ip;
30516 + pid = debugger->pid;
30518 + ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
30519 + ip = IP_RESTART_SYSCALL(ip);
30521 + if(ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip) < 0)
30522 + tracer_panic("real_wait_return : Failed to restart system "
30523 + "call, errno = %d\n", errno);
30525 + if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
30526 + (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
30527 + (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
30528 + debugger_normal_return(debugger, -1))
30529 + tracer_panic("real_wait_return : gdb failed to wait, "
30530 + "errno = %d\n", errno);
30535 + * Overrides for Emacs so that we follow Linus's tabbing style.
30536 + * Emacs will notice this stuff at the end of the file and automatically
30537 + * adjust the settings for this buffer only. This must remain at the end
30539 + * ---------------------------------------------------------------------------
30540 + * Local variables:
30541 + * c-file-style: "linux"
30544 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.h um/arch/um/kernel/tt/ptproxy/wait.h
30545 --- orig/arch/um/kernel/tt/ptproxy/wait.h 1969-12-31 19:00:00.000000000 -0500
30546 +++ um/arch/um/kernel/tt/ptproxy/wait.h 2003-10-21 03:26:07.000000000 -0400
30548 +/**********************************************************************
30551 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
30552 +terms and conditions.
30553 +**********************************************************************/
30555 +#ifndef __PTPROXY_WAIT_H
30556 +#define __PTPROXY_WAIT_H
30558 +extern int proxy_wait_return(struct debugger *debugger, pid_t unused);
30559 +extern int real_wait_return(struct debugger *debugger);
30560 +extern int parent_wait_return(struct debugger *debugger, pid_t unused);
30563 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_kern.c um/arch/um/kernel/tt/syscall_kern.c
30564 --- orig/arch/um/kernel/tt/syscall_kern.c 1969-12-31 19:00:00.000000000 -0500
30565 +++ um/arch/um/kernel/tt/syscall_kern.c 2003-10-21 03:26:07.000000000 -0400
30568 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
30569 + * Licensed under the GPL
30572 +#include "linux/types.h"
30573 +#include "linux/utime.h"
30574 +#include "linux/sys.h"
30575 +#include "asm/unistd.h"
30576 +#include "asm/ptrace.h"
30577 +#include "asm/uaccess.h"
30578 +#include "sysdep/syscalls.h"
30579 +#include "kern_util.h"
30581 +static inline int check_area(void *ptr, int size)
30583 + return(verify_area(VERIFY_WRITE, ptr, size));
30586 +static int check_readlink(struct pt_regs *regs)
30588 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
30589 + UPT_SYSCALL_ARG2(®s->regs)));
30592 +static int check_utime(struct pt_regs *regs)
30594 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
30595 + sizeof(struct utimbuf)));
30598 +static int check_oldstat(struct pt_regs *regs)
30600 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
30601 + sizeof(struct __old_kernel_stat)));
30604 +static int check_stat(struct pt_regs *regs)
30606 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
30607 + sizeof(struct stat)));
30610 +static int check_stat64(struct pt_regs *regs)
30612 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
30613 + sizeof(struct stat64)));
30618 + int (*check_params)(struct pt_regs *);
30621 +struct bogus this_is_bogus[256] = {
30622 + [ __NR_mknod ] = { 1, NULL },
30623 + [ __NR_mkdir ] = { 1, NULL },
30624 + [ __NR_rmdir ] = { 1, NULL },
30625 + [ __NR_unlink ] = { 1, NULL },
30626 + [ __NR_symlink ] = { 1, NULL },
30627 + [ __NR_link ] = { 1, NULL },
30628 + [ __NR_rename ] = { 1, NULL },
30629 + [ __NR_umount ] = { 1, NULL },
30630 + [ __NR_mount ] = { 1, NULL },
30631 + [ __NR_pivot_root ] = { 1, NULL },
30632 + [ __NR_chdir ] = { 1, NULL },
30633 + [ __NR_chroot ] = { 1, NULL },
30634 + [ __NR_open ] = { 1, NULL },
30635 + [ __NR_quotactl ] = { 1, NULL },
30636 + [ __NR_sysfs ] = { 1, NULL },
30637 + [ __NR_readlink ] = { 1, check_readlink },
30638 + [ __NR_acct ] = { 1, NULL },
30639 + [ __NR_execve ] = { 1, NULL },
30640 + [ __NR_uselib ] = { 1, NULL },
30641 + [ __NR_statfs ] = { 1, NULL },
30642 + [ __NR_truncate ] = { 1, NULL },
30643 + [ __NR_access ] = { 1, NULL },
30644 + [ __NR_chmod ] = { 1, NULL },
30645 + [ __NR_chown ] = { 1, NULL },
30646 + [ __NR_lchown ] = { 1, NULL },
30647 + [ __NR_utime ] = { 1, check_utime },
30648 + [ __NR_oldlstat ] = { 1, check_oldstat },
30649 + [ __NR_oldstat ] = { 1, check_oldstat },
30650 + [ __NR_stat ] = { 1, check_stat },
30651 + [ __NR_lstat ] = { 1, check_stat },
30652 + [ __NR_stat64 ] = { 1, check_stat64 },
30653 + [ __NR_lstat64 ] = { 1, check_stat64 },
30654 + [ __NR_chown32 ] = { 1, NULL },
30659 +static int check_bogosity(struct pt_regs *regs)
30661 + struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(®s->regs)];
30663 + if(!bogon->kernel_ds) return(0);
30664 + if(bogon->check_params && (*bogon->check_params)(regs))
30666 + set_fs(KERNEL_DS);
30670 +extern syscall_handler_t *sys_call_table[];
30672 +long execute_syscall_tt(void *r)
30674 + struct pt_regs *regs = r;
30678 + current->thread.nsyscalls++;
30680 + syscall = UPT_SYSCALL_NR(®s->regs);
30682 + if((syscall >= NR_syscalls) || (syscall < 0))
30684 + else if(honeypot && check_bogosity(regs))
30686 + else res = EXECUTE_SYSCALL(syscall, regs);
30690 + if(current->thread.mode.tt.singlestep_syscall){
30691 + current->thread.mode.tt.singlestep_syscall = 0;
30692 + current->ptrace &= ~PT_DTRACE;
30693 + force_sig(SIGTRAP, current);
30700 + * Overrides for Emacs so that we follow Linus's tabbing style.
30701 + * Emacs will notice this stuff at the end of the file and automatically
30702 + * adjust the settings for this buffer only. This must remain at the end
30704 + * ---------------------------------------------------------------------------
30705 + * Local variables:
30706 + * c-file-style: "linux"
30709 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_user.c um/arch/um/kernel/tt/syscall_user.c
30710 --- orig/arch/um/kernel/tt/syscall_user.c 1969-12-31 19:00:00.000000000 -0500
30711 +++ um/arch/um/kernel/tt/syscall_user.c 2003-10-21 03:26:07.000000000 -0400
30714 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
30715 + * Licensed under the GPL
30718 +#include <unistd.h>
30719 +#include <signal.h>
30720 +#include <errno.h>
30721 +#include <sys/ptrace.h>
30722 +#include <asm/unistd.h>
30723 +#include "sysdep/ptrace.h"
30724 +#include "sigcontext.h"
30725 +#include "ptrace_user.h"
30727 +#include "user_util.h"
30728 +#include "kern_util.h"
30729 +#include "syscall_user.h"
30733 +#define ERESTARTSYS 512
30734 +#define ERESTARTNOINTR 513
30735 +#define ERESTARTNOHAND 514
30737 +void syscall_handler_tt(int sig, union uml_pt_regs *regs)
30741 + int index, syscall;
30743 + syscall = UPT_SYSCALL_NR(regs);
30744 + sc = UPT_SC(regs);
30745 + SC_START_SYSCALL(sc);
30747 + index = record_syscall_start(syscall);
30749 + result = execute_syscall(regs);
30751 + /* regs->sc may have changed while the system call ran (there may
30752 + * have been an interrupt or segfault), so it needs to be refreshed.
30754 + UPT_SC(regs) = sc;
30756 + SC_SET_SYSCALL_RETURN(sc, result);
30757 + if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) ||
30758 + (result == -ERESTARTNOINTR))
30759 + do_signal(result);
30762 + record_syscall_end(index, result);
30765 +int do_syscall(void *task, int pid)
30767 + unsigned long proc_regs[FRAME_SIZE];
30768 + union uml_pt_regs *regs;
30771 + if(ptrace_getregs(pid, proc_regs) < 0)
30772 + tracer_panic("Couldn't read registers");
30773 + syscall = PT_SYSCALL_NR(proc_regs);
30775 + regs = TASK_REGS(task);
30776 + UPT_SYSCALL_NR(regs) = syscall;
30778 + if(syscall < 1) return(0);
30780 + if((syscall != __NR_sigreturn) &&
30781 + ((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
30782 + ((unsigned long *) PT_IP(proc_regs) <= &_etext))
30783 + tracer_panic("I'm tracing myself and I can't get out");
30785 + if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
30786 + __NR_getpid) < 0)
30787 + tracer_panic("do_syscall : Nullifying syscall failed, "
30788 + "errno = %d", errno);
30793 + * Overrides for Emacs so that we follow Linus's tabbing style.
30794 + * Emacs will notice this stuff at the end of the file and automatically
30795 + * adjust the settings for this buffer only. This must remain at the end
30797 + * ---------------------------------------------------------------------------
30798 + * Local variables:
30799 + * c-file-style: "linux"
30802 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/Makefile um/arch/um/kernel/tt/sys-i386/Makefile
30803 --- orig/arch/um/kernel/tt/sys-i386/Makefile 1969-12-31 19:00:00.000000000 -0500
30804 +++ um/arch/um/kernel/tt/sys-i386/Makefile 2003-10-21 03:26:07.000000000 -0400
30807 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
30808 +# Licensed under the GPL
30811 +O_TARGET = sys-i386.o
30813 +obj-y = sigcontext.o
30815 +USER_OBJS = sigcontext.o
30817 +include $(TOPDIR)/Rules.make
30819 +$(USER_OBJS) : %.o: %.c
30820 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
30823 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/sigcontext.c um/arch/um/kernel/tt/sys-i386/sigcontext.c
30824 --- orig/arch/um/kernel/tt/sys-i386/sigcontext.c 1969-12-31 19:00:00.000000000 -0500
30825 +++ um/arch/um/kernel/tt/sys-i386/sigcontext.c 2003-10-21 03:26:07.000000000 -0400
30828 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
30829 + * Licensed under the GPL
30832 +#include <stdlib.h>
30833 +#include <asm/sigcontext.h>
30834 +#include "kern_util.h"
30835 +#include "sysdep/frame.h"
30837 +int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data)
30839 + struct arch_frame_data *arch = data;
30840 + struct sigcontext *to = to_ptr, *from = from_ptr;
30841 + struct _fpstate *to_fp, *from_fp;
30842 + unsigned long sigs;
30845 + to_fp = to->fpstate;
30846 + from_fp = from->fpstate;
30847 + sigs = to->oldmask;
30848 + err = copy_from_user_proc(to, from, sizeof(*to));
30849 + to->oldmask = sigs;
30850 + if(to_fp != NULL){
30851 + err |= copy_from_user_proc(&to->fpstate, &to_fp,
30852 + sizeof(to->fpstate));
30853 + err |= copy_from_user_proc(to_fp, from_fp, arch->fpstate_size);
30858 +int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data)
30860 + struct arch_frame_data *arch = data;
30861 + struct sigcontext *to = to_ptr, *from = from_ptr;
30862 + struct _fpstate *to_fp, *from_fp;
30865 + to_fp = (struct _fpstate *)
30866 + (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
30867 + from_fp = from->fpstate;
30868 + err = copy_to_user_proc(to, from, sizeof(*to));
30869 + if(from_fp != NULL){
30870 + err |= copy_to_user_proc(&to->fpstate, &to_fp,
30871 + sizeof(to->fpstate));
30872 + err |= copy_to_user_proc(to_fp, from_fp, arch->fpstate_size);
30878 + * Overrides for Emacs so that we follow Linus's tabbing style.
30879 + * Emacs will notice this stuff at the end of the file and automatically
30880 + * adjust the settings for this buffer only. This must remain at the end
30882 + * ---------------------------------------------------------------------------
30883 + * Local variables:
30884 + * c-file-style: "linux"
30887 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/time.c um/arch/um/kernel/tt/time.c
30888 --- orig/arch/um/kernel/tt/time.c 1969-12-31 19:00:00.000000000 -0500
30889 +++ um/arch/um/kernel/tt/time.c 2003-10-21 03:26:07.000000000 -0400
30892 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
30893 + * Licensed under the GPL
30896 +#include <signal.h>
30897 +#include <sys/time.h>
30898 +#include <time_user.h>
30899 +#include "process.h"
30902 +void user_time_init_tt(void)
30904 + if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
30905 + panic("Couldn't set SIGVTALRM handler");
30906 + set_interval(ITIMER_VIRTUAL);
30910 + * Overrides for Emacs so that we follow Linus's tabbing style.
30911 + * Emacs will notice this stuff at the end of the file and automatically
30912 + * adjust the settings for this buffer only. This must remain at the end
30914 + * ---------------------------------------------------------------------------
30915 + * Local variables:
30916 + * c-file-style: "linux"
30919 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tlb.c um/arch/um/kernel/tt/tlb.c
30920 --- orig/arch/um/kernel/tt/tlb.c 1969-12-31 19:00:00.000000000 -0500
30921 +++ um/arch/um/kernel/tt/tlb.c 2003-11-13 00:40:57.000000000 -0500
30924 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
30925 + * Licensed under the GPL
30928 +#include "linux/stddef.h"
30929 +#include "linux/kernel.h"
30930 +#include "linux/sched.h"
30931 +#include "asm/page.h"
30932 +#include "asm/pgtable.h"
30933 +#include "asm/uaccess.h"
30934 +#include "user_util.h"
30935 +#include "mem_user.h"
30938 +static void fix_range(struct mm_struct *mm, unsigned long start_addr,
30939 + unsigned long end_addr, int force)
30944 + unsigned long addr;
30945 + int r, w, x, err;
30947 + if((current->thread.mode.tt.extern_pid != -1) &&
30948 + (current->thread.mode.tt.extern_pid != os_getpid()))
30949 + panic("fix_range fixing wrong address space, current = 0x%p",
30951 + if(mm == NULL) return;
30952 + for(addr=start_addr;addr<end_addr;){
30953 + if(addr == TASK_SIZE){
30954 + /* Skip over kernel text, kernel data, and physical
30955 + * memory, which don't have ptes, plus kernel virtual
30956 + * memory, which is flushed separately, and remap
30957 + * the process stack. The only way to get here is
30958 + * if (end_addr == STACK_TOP) > TASK_SIZE, which is
30959 + * only true in the honeypot case.
30961 + addr = STACK_TOP - ABOVE_KMEM;
30964 + npgd = pgd_offset(mm, addr);
30965 + npmd = pmd_offset(npgd, addr);
30966 + if(pmd_present(*npmd)){
30967 + npte = pte_offset(npmd, addr);
30968 + r = pte_read(*npte);
30969 + w = pte_write(*npte);
30970 + x = pte_exec(*npte);
30971 + if(!pte_dirty(*npte)) w = 0;
30972 + if(!pte_young(*npte)){
30976 + if(force || pte_newpage(*npte)){
30977 + err = os_unmap_memory((void *) addr,
30980 + panic("munmap failed, errno = %d\n",
30982 + if(pte_present(*npte))
30984 + pte_val(*npte) & PAGE_MASK,
30985 + PAGE_SIZE, r, w, x);
30987 + else if(pte_newprot(*npte)){
30988 + protect_memory(addr, PAGE_SIZE, r, w, x, 1);
30990 + *npte = pte_mkuptodate(*npte);
30991 + addr += PAGE_SIZE;
30994 + if(force || pmd_newpage(*npmd)){
30995 + err = os_unmap_memory((void *) addr, PMD_SIZE);
30997 + panic("munmap failed, errno = %d\n",
30999 + pmd_mkuptodate(*npmd);
31001 + addr += PMD_SIZE;
31006 +atomic_t vmchange_seq = ATOMIC_INIT(1);
31008 +static void flush_kernel_vm_range(unsigned long start, unsigned long end,
31011 + struct mm_struct *mm;
31015 + unsigned long addr;
31016 + int updated = 0, err;
31019 + for(addr = start; addr < end;){
31020 + pgd = pgd_offset(mm, addr);
31021 + pmd = pmd_offset(pgd, addr);
31022 + if(pmd_present(*pmd)){
31023 + pte = pte_offset(pmd, addr);
31024 + if(!pte_present(*pte) || pte_newpage(*pte)){
31026 + err = os_unmap_memory((void *) addr,
31029 + panic("munmap failed, errno = %d\n",
31031 + if(pte_present(*pte))
31033 + pte_val(*pte) & PAGE_MASK,
31034 + PAGE_SIZE, 1, 1, 1);
31036 + else if(pte_newprot(*pte)){
31038 + protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
31040 + addr += PAGE_SIZE;
31043 + if(pmd_newpage(*pmd)){
31045 + err = os_unmap_memory((void *) addr, PMD_SIZE);
31047 + panic("munmap failed, errno = %d\n",
31050 + addr += PMD_SIZE;
31053 + if(updated && update_seq) atomic_inc(&vmchange_seq);
31056 +static void protect_vm_page(unsigned long addr, int w, int must_succeed)
31060 + err = protect_memory(addr, PAGE_SIZE, 1, w, 1, must_succeed);
31061 + if(err == 0) return;
31062 + else if((err == -EFAULT) || (err == -ENOMEM)){
31063 + flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
31064 + protect_vm_page(addr, w, 1);
31066 + else panic("protect_vm_page : protect failed, errno = %d\n", err);
31069 +void mprotect_kernel_vm(int w)
31071 + struct mm_struct *mm;
31075 + unsigned long addr;
31078 + for(addr = start_vm; addr < end_vm;){
31079 + pgd = pgd_offset(mm, addr);
31080 + pmd = pmd_offset(pgd, addr);
31081 + if(pmd_present(*pmd)){
31082 + pte = pte_offset(pmd, addr);
31083 + if(pte_present(*pte)) protect_vm_page(addr, w, 0);
31084 + addr += PAGE_SIZE;
31086 + else addr += PMD_SIZE;
31090 +void flush_tlb_kernel_vm_tt(void)
31092 + flush_kernel_vm_range(start_vm, end_vm, 1);
31095 +void __flush_tlb_one_tt(unsigned long addr)
31097 + flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
31100 +void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start,
31101 + unsigned long end)
31103 + if(mm != current->mm) return;
31105 + /* Assumes that the range start ... end is entirely within
31106 + * either process memory or kernel vm
31108 + if((start >= start_vm) && (start < end_vm))
31109 + flush_kernel_vm_range(start, end, 1);
31110 + else fix_range(mm, start, end, 0);
31113 +void flush_tlb_mm_tt(struct mm_struct *mm)
31115 + unsigned long seq;
31117 + if(mm != current->mm) return;
31119 + fix_range(mm, 0, STACK_TOP, 0);
31121 + seq = atomic_read(&vmchange_seq);
31122 + if(current->thread.mode.tt.vm_seq == seq) return;
31123 + current->thread.mode.tt.vm_seq = seq;
31124 + flush_kernel_vm_range(start_vm, end_vm, 0);
31127 +void force_flush_all_tt(void)
31129 + fix_range(current->mm, 0, STACK_TOP, 1);
31130 + flush_kernel_vm_range(start_vm, end_vm, 0);
31134 + * Overrides for Emacs so that we follow Linus's tabbing style.
31135 + * Emacs will notice this stuff at the end of the file and automatically
31136 + * adjust the settings for this buffer only. This must remain at the end
31138 + * ---------------------------------------------------------------------------
31139 + * Local variables:
31140 + * c-file-style: "linux"
31143 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tracer.c um/arch/um/kernel/tt/tracer.c
31144 --- orig/arch/um/kernel/tt/tracer.c 1969-12-31 19:00:00.000000000 -0500
31145 +++ um/arch/um/kernel/tt/tracer.c 2003-10-21 03:26:07.000000000 -0400
31148 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
31149 + * Licensed under the GPL
31152 +#include <stdio.h>
31153 +#include <stdlib.h>
31154 +#include <stdarg.h>
31155 +#include <unistd.h>
31156 +#include <signal.h>
31157 +#include <errno.h>
31158 +#include <sched.h>
31159 +#include <string.h>
31160 +#include <sys/mman.h>
31161 +#include <sys/ptrace.h>
31162 +#include <sys/time.h>
31163 +#include <sys/wait.h>
31165 +#include "sysdep/ptrace.h"
31166 +#include "sigcontext.h"
31167 +#include "sysdep/sigcontext.h"
31169 +#include "signal_user.h"
31170 +#include "user_util.h"
31171 +#include "mem_user.h"
31172 +#include "process.h"
31173 +#include "kern_util.h"
31174 +#include "frame.h"
31175 +#include "chan_user.h"
31176 +#include "ptrace_user.h"
31180 +static int tracer_winch[2];
31182 +int is_tracer_winch(int pid, int fd, void *data)
31184 + if(pid != tracing_pid)
31187 + register_winch_irq(tracer_winch[0], fd, -1, data);
31191 +static void tracer_winch_handler(int sig)
31196 + n = os_write_file(tracer_winch[1], &c, sizeof(c));
31197 + if(n != sizeof(c))
31198 + printk("tracer_winch_handler - write failed, err = %d\n", -n);
31201 +/* Called only by the tracing thread during initialization */
31203 +static void setup_tracer_winch(void)
31207 + err = os_pipe(tracer_winch, 1, 1);
31209 + printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
31212 + signal(SIGWINCH, tracer_winch_handler);
31215 +void attach_process(int pid)
31217 + if((ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) ||
31218 + (ptrace(PTRACE_CONT, pid, 0, 0) < 0))
31219 + tracer_panic("OP_FORK failed to attach pid");
31220 + wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
31221 + if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
31222 + tracer_panic("OP_FORK failed to continue process");
31225 +void tracer_panic(char *format, ...)
31229 + va_start(ap, format);
31230 + vprintf(format, ap);
31232 + while(1) pause();
31235 +static void tracer_segv(int sig, struct sigcontext sc)
31237 + printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
31238 + SC_FAULT_ADDR(&sc), SC_IP(&sc));
31243 +/* Changed early in boot, and then only read */
31245 +int debug_stop = 1;
31246 +int debug_parent = 0;
31249 +static int signal_tramp(void *arg)
31251 + int (*proc)(void *);
31253 + if(honeypot && munmap((void *) (host_task_size - 0x10000000),
31255 + panic("Unmapping stack failed");
31256 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
31257 + panic("ptrace PTRACE_TRACEME failed");
31258 + os_stop_process(os_getpid());
31259 + change_sig(SIGWINCH, 0);
31260 + signal(SIGUSR1, SIG_IGN);
31261 + change_sig(SIGCHLD, 0);
31262 + signal(SIGSEGV, (__sighandler_t) sig_handler);
31263 + set_cmdline("(idle thread)");
31264 + set_init_pid(os_getpid());
31266 + return((*proc)(NULL));
31269 +static void sleeping_process_signal(int pid, int sig)
31272 + /* These two result from UML being ^Z-ed and bg-ed. PTRACE_CONT is
31273 + * right because the process must be in the kernel already.
31277 + if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
31278 + tracer_panic("sleeping_process_signal : Failed to "
31279 + "continue pid %d, signal = %d, "
31280 + "errno = %d\n", pid, sig, errno);
31283 + /* This happens when the debugger (e.g. strace) is doing system call
31284 + * tracing on the kernel. During a context switch, the current task
31285 + * will be set to the incoming process and the outgoing process will
31286 + * hop into write and then read. Since it's not the current process
31287 + * any more, the trace of those will land here. So, we need to just
31288 + * PTRACE_SYSCALL it.
31291 + if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
31292 + tracer_panic("sleeping_process_signal : Failed to "
31293 + "PTRACE_SYSCALL pid %d, errno = %d\n",
31299 + tracer_panic("sleeping process %d got unexpected "
31300 + "signal : %d\n", pid, sig);
31305 +/* Accessed only by the tracing thread */
31306 +int debugger_pid = -1;
31307 +int debugger_parent = -1;
31308 +int debugger_fd = -1;
31314 + unsigned long addr;
31315 + struct timeval time;
31316 +} signal_record[1024][32];
31318 +int signal_index[32];
31320 +int debug_trace = 0;
31321 +extern int io_nsignals, io_count, intr_count;
31323 +extern void signal_usr1(int sig);
31325 +int tracing_pid = -1;
31327 +int tracer(int (*init_proc)(void *), void *sp)
31329 + void *task = NULL;
31330 + unsigned long eip = 0;
31331 + int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
31332 + int last_index, proc_id = 0, n, err, old_tracing = 0, strace = 0;
31334 + capture_signal_stack();
31335 + signal(SIGPIPE, SIG_IGN);
31336 + setup_tracer_winch();
31337 + tracing_pid = os_getpid();
31338 + printf("tracing thread pid = %d\n", tracing_pid);
31340 + pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
31341 + n = waitpid(pid, &status, WUNTRACED);
31343 + printf("waitpid on idle thread failed, errno = %d\n", errno);
31346 + if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
31347 + printf("Failed to continue idle thread, errno = %d\n", errno);
31351 + signal(SIGSEGV, (sighandler_t) tracer_segv);
31352 + signal(SIGUSR1, signal_usr1);
31354 + printf("Tracing thread pausing to be attached\n");
31358 + if(gdb_pid != -1)
31359 + debugger_pid = attach_debugger(pid, gdb_pid, 1);
31360 + else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop);
31361 + if(debug_parent){
31362 + debugger_parent = os_process_parent(debugger_pid);
31363 + init_parent_proxy(debugger_parent);
31364 + err = attach(debugger_parent);
31366 + printf("Failed to attach debugger parent %d, "
31367 + "errno = %d\n", debugger_parent, -err);
31368 + debugger_parent = -1;
31371 + if(ptrace(PTRACE_SYSCALL, debugger_parent,
31373 + printf("Failed to continue debugger "
31374 + "parent, errno = %d\n", errno);
31375 + debugger_parent = -1;
31380 + set_cmdline("(tracing thread)");
31382 + pid = waitpid(-1, &status, WUNTRACED);
31384 + if(errno != ECHILD){
31385 + printf("wait failed - errno = %d\n", errno);
31389 + if(pid == debugger_pid){
31392 + if(WIFEXITED(status) || WIFSIGNALED(status))
31393 + debugger_pid = -1;
31394 + /* XXX Figure out how to deal with gdb and SMP */
31395 + else cont = debugger_signal(status, cpu_tasks[0].pid);
31396 + if(cont == PTRACE_SYSCALL) strace = 1;
31399 + else if(pid == debugger_parent){
31400 + debugger_parent_signal(status, pid);
31404 + if(WIFEXITED(status)) ;
31407 + printf("Child %d exited with status %d\n", pid,
31408 + WEXITSTATUS(status));
31411 + else if(WIFSIGNALED(status)){
31412 + sig = WTERMSIG(status);
31414 + printf("Child %d exited with signal %d\n", pid,
31418 + else if(WIFSTOPPED(status)){
31419 + proc_id = pid_to_processor_id(pid);
31420 + sig = WSTOPSIG(status);
31421 + if(signal_index[proc_id] == 1024){
31422 + signal_index[proc_id] = 0;
31423 + last_index = 1023;
31425 + else last_index = signal_index[proc_id] - 1;
31426 + if(((sig == SIGPROF) || (sig == SIGVTALRM) ||
31427 + (sig == SIGALRM)) &&
31428 + (signal_record[proc_id][last_index].signal == sig)&&
31429 + (signal_record[proc_id][last_index].pid == pid))
31430 + signal_index[proc_id] = last_index;
31431 + signal_record[proc_id][signal_index[proc_id]].pid = pid;
31432 + gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL);
31433 + eip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
31434 + signal_record[proc_id][signal_index[proc_id]].addr = eip;
31435 + signal_record[proc_id][signal_index[proc_id]++].signal = sig;
31437 + if(proc_id == -1){
31438 + sleeping_process_signal(pid, sig);
31442 + task = cpu_tasks[proc_id].task;
31443 + tracing = is_tracing(task);
31444 + old_tracing = tracing;
31449 + op = do_proc_op(task, proc_id);
31451 + case OP_TRACE_ON:
31452 + arch_leave_kernel(task, pid);
31459 + ptrace(PTRACE_KILL, pid, 0, 0);
31460 + return(op == OP_REBOOT);
31462 + printf("Detaching pid %d\n", pid);
31463 + detach(pid, SIGSTOP);
31468 + /* OP_EXEC switches host processes on us,
31469 + * we want to continue the new one.
31471 + pid = cpu_tasks[proc_id].pid;
31474 + if(!tracing && (debugger_pid != -1)){
31475 + child_signal(pid, status);
31479 + if(do_syscall(task, pid)) sig = SIGUSR2;
31480 + else clear_singlestep(task);
31483 + if(tracing) sig = 0;
31501 + set_tracing(task, tracing);
31503 + if(!tracing && old_tracing)
31504 + arch_enter_kernel(task, pid);
31506 + if(!tracing && (debugger_pid != -1) && (sig != 0) &&
31507 + (sig != SIGALRM) && (sig != SIGVTALRM) &&
31508 + (sig != SIGSEGV) && (sig != SIGTRAP) &&
31509 + (sig != SIGUSR2) && (sig != SIGIO) &&
31510 + (sig != SIGFPE)){
31511 + child_signal(pid, status);
31516 + if(singlestepping_tt(task))
31517 + cont_type = PTRACE_SINGLESTEP;
31518 + else cont_type = PTRACE_SYSCALL;
31520 + else cont_type = PTRACE_CONT;
31522 + if((cont_type == PTRACE_CONT) &&
31523 + (debugger_pid != -1) && strace)
31524 + cont_type = PTRACE_SYSCALL;
31526 + if(ptrace(cont_type, pid, 0, sig) != 0){
31527 + tracer_panic("ptrace failed to continue "
31528 + "process - errno = %d\n",
31536 +static int __init uml_debug_setup(char *line, int *add)
31542 + if(*line != '=') return(0);
31545 + while(line != NULL){
31546 + next = strchr(line, ',');
31547 + if(next) *next++ = '\0';
31549 + if(!strcmp(line, "go")) debug_stop = 0;
31550 + else if(!strcmp(line, "parent")) debug_parent = 1;
31551 + else printf("Unknown debug option : '%s'\n", line);
31558 +__uml_setup("debug", uml_debug_setup,
31560 +" Starts up the kernel under the control of gdb. See the \n"
31561 +" kernel debugging tutorial and the debugging session pages\n"
31562 +" at http://user-mode-linux.sourceforge.net/ for more information.\n\n"
31565 +static int __init uml_debugtrace_setup(char *line, int *add)
31570 +__uml_setup("debugtrace", uml_debugtrace_setup,
31572 +" Causes the tracing thread to pause until it is attached by a\n"
31573 +" debugger and continued. This is mostly for debugging crashes\n"
31574 +" early during boot, and should be pretty much obsoleted by\n"
31575 +" the debug switch.\n\n"
31578 +static int __init uml_honeypot_setup(char *line, int *add)
31580 + jail_setup("", add);
31584 +__uml_setup("honeypot", uml_honeypot_setup,
31586 +" This makes UML put process stacks in the same location as they are\n"
31587 +" on the host, allowing expoits such as stack smashes to work against\n"
31588 +" UML. This implies 'jail'.\n\n"
31592 + * Overrides for Emacs so that we follow Linus's tabbing style.
31593 + * Emacs will notice this stuff at the end of the file and automatically
31594 + * adjust the settings for this buffer only. This must remain at the end
31596 + * ---------------------------------------------------------------------------
31597 + * Local variables:
31598 + * c-file-style: "linux"
31601 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/trap_user.c um/arch/um/kernel/tt/trap_user.c
31602 --- orig/arch/um/kernel/tt/trap_user.c 1969-12-31 19:00:00.000000000 -0500
31603 +++ um/arch/um/kernel/tt/trap_user.c 2003-10-21 03:26:07.000000000 -0400
31606 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
31607 + * Licensed under the GPL
31610 +#include <stdlib.h>
31611 +#include <errno.h>
31612 +#include <signal.h>
31613 +#include <asm/sigcontext.h>
31614 +#include "sysdep/ptrace.h"
31615 +#include "signal_user.h"
31616 +#include "user_util.h"
31617 +#include "kern_util.h"
31621 +void sig_handler_common_tt(int sig, void *sc_ptr)
31623 + struct sigcontext *sc = sc_ptr;
31624 + struct tt_regs save_regs, *r;
31625 + struct signal_info *info;
31626 + int save_errno = errno, is_user;
31628 + unprotect_kernel_mem();
31630 + r = &TASK_REGS(get_current())->tt;
31632 + is_user = user_context(SC_SP(sc));
31634 + if(sig != SIGUSR2)
31637 + change_sig(SIGUSR1, 1);
31638 + info = &sig_info[sig];
31639 + if(!info->is_irq) unblock_signals();
31641 + (*info->handler)(sig, (union uml_pt_regs *) r);
31646 + change_sig(SIGUSR1, 0);
31647 + set_user_mode(NULL);
31650 + errno = save_errno;
31651 + if(is_user) protect_kernel_mem();
31655 + * Overrides for Emacs so that we follow Linus's tabbing style.
31656 + * Emacs will notice this stuff at the end of the file and automatically
31657 + * adjust the settings for this buffer only. This must remain at the end
31659 + * ---------------------------------------------------------------------------
31660 + * Local variables:
31661 + * c-file-style: "linux"
31664 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/uaccess.c um/arch/um/kernel/tt/uaccess.c
31665 --- orig/arch/um/kernel/tt/uaccess.c 1969-12-31 19:00:00.000000000 -0500
31666 +++ um/arch/um/kernel/tt/uaccess.c 2003-11-13 00:12:45.000000000 -0500
31669 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
31670 + * Licensed under the GPL
31673 +#include "linux/sched.h"
31674 +#include "asm/uaccess.h"
31676 +int copy_from_user_tt(void *to, const void *from, int n)
31678 + if(!access_ok_tt(VERIFY_READ, from, n))
31681 + return(__do_copy_from_user(to, from, n, ¤t->thread.fault_addr,
31682 + ¤t->thread.fault_catcher));
31685 +int copy_to_user_tt(void *to, const void *from, int n)
31687 + if(!access_ok_tt(VERIFY_WRITE, to, n))
31690 + return(__do_copy_to_user(to, from, n, ¤t->thread.fault_addr,
31691 + ¤t->thread.fault_catcher));
31694 +int strncpy_from_user_tt(char *dst, const char *src, int count)
31698 + if(!access_ok_tt(VERIFY_READ, src, 1))
31701 + n = __do_strncpy_from_user(dst, src, count,
31702 + ¤t->thread.fault_addr,
31703 + ¤t->thread.fault_catcher);
31704 + if(n < 0) return(-EFAULT);
31708 +int __clear_user_tt(void *mem, int len)
31710 + return(__do_clear_user(mem, len,
31711 + ¤t->thread.fault_addr,
31712 + ¤t->thread.fault_catcher));
31715 +int clear_user_tt(void *mem, int len)
31717 + if(!access_ok_tt(VERIFY_WRITE, mem, len))
31720 + return(__do_clear_user(mem, len, ¤t->thread.fault_addr,
31721 + ¤t->thread.fault_catcher));
31724 +int strnlen_user_tt(const void *str, int len)
31726 + return(__do_strnlen_user(str, len,
31727 + ¤t->thread.fault_addr,
31728 + ¤t->thread.fault_catcher));
31732 + * Overrides for Emacs so that we follow Linus's tabbing style.
31733 + * Emacs will notice this stuff at the end of the file and automatically
31734 + * adjust the settings for this buffer only. This must remain at the end
31736 + * ---------------------------------------------------------------------------
31737 + * Local variables:
31738 + * c-file-style: "linux"
31741 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/uaccess_user.c um/arch/um/kernel/tt/uaccess_user.c
31742 --- orig/arch/um/kernel/tt/uaccess_user.c 1969-12-31 19:00:00.000000000 -0500
31743 +++ um/arch/um/kernel/tt/uaccess_user.c 2003-11-12 08:51:13.000000000 -0500
31746 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
31747 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
31748 + * Licensed under the GPL
31751 +#include <setjmp.h>
31752 +#include <string.h>
31753 +#include "user_util.h"
31754 +#include "uml_uaccess.h"
31756 +#include "kern_util.h"
31758 +int __do_copy_from_user(void *to, const void *from, int n,
31759 + void **fault_addr, void **fault_catcher)
31761 + struct tt_regs save = TASK_REGS(get_current())->tt;
31762 + unsigned long fault;
31765 + fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
31766 + __do_copy, &faulted);
31767 + TASK_REGS(get_current())->tt = save;
31769 + if(!faulted) return(0);
31770 + else return(n - (fault - (unsigned long) from));
31773 +static void __do_strncpy(void *dst, const void *src, int count)
31775 + strncpy(dst, src, count);
31778 +int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
31779 + void **fault_addr, void **fault_catcher)
31781 + struct tt_regs save = TASK_REGS(get_current())->tt;
31782 + unsigned long fault;
31785 + fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
31786 + __do_strncpy, &faulted);
31787 + TASK_REGS(get_current())->tt = save;
31789 + if(!faulted) return(strlen(dst));
31793 +static void __do_clear(void *to, const void *from, int n)
31795 + memset(to, 0, n);
31798 +int __do_clear_user(void *mem, unsigned long len,
31799 + void **fault_addr, void **fault_catcher)
31801 + struct tt_regs save = TASK_REGS(get_current())->tt;
31802 + unsigned long fault;
31805 + fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
31806 + __do_clear, &faulted);
31807 + TASK_REGS(get_current())->tt = save;
31809 + if(!faulted) return(0);
31810 + else return(len - (fault - (unsigned long) mem));
31813 +int __do_strnlen_user(const char *str, unsigned long n,
31814 + void **fault_addr, void **fault_catcher)
31816 + struct tt_regs save = TASK_REGS(get_current())->tt;
31818 + unsigned long *faddrp = (unsigned long *)fault_addr;
31821 + *fault_catcher = &jbuf;
31822 + if(sigsetjmp(jbuf, 1) == 0)
31823 + ret = strlen(str) + 1;
31824 + else ret = *faddrp - (unsigned long) str;
31826 + *fault_addr = NULL;
31827 + *fault_catcher = NULL;
31829 + TASK_REGS(get_current())->tt = save;
31834 + * Overrides for Emacs so that we follow Linus's tabbing style.
31835 + * Emacs will notice this stuff at the end of the file and automatically
31836 + * adjust the settings for this buffer only. This must remain at the end
31838 + * ---------------------------------------------------------------------------
31839 + * Local variables:
31840 + * c-file-style: "linux"
31843 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/unmap.c um/arch/um/kernel/tt/unmap.c
31844 --- orig/arch/um/kernel/tt/unmap.c 1969-12-31 19:00:00.000000000 -0500
31845 +++ um/arch/um/kernel/tt/unmap.c 2003-10-21 03:26:07.000000000 -0400
31848 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
31849 + * Licensed under the GPL
31852 +#include <sys/mman.h>
31854 +int switcheroo(int fd, int prot, void *from, void *to, int size)
31856 + if(munmap(to, size) < 0){
31859 + if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
31862 + if(munmap(from, size) < 0){
31869 + * Overrides for Emacs so that we follow Linus's tabbing style.
31870 + * Emacs will notice this stuff at the end of the file and automatically
31871 + * adjust the settings for this buffer only. This must remain at the end
31873 + * ---------------------------------------------------------------------------
31874 + * Local variables:
31875 + * c-file-style: "linux"
31878 diff -Naur -X ../exclude-files orig/arch/um/kernel/tty_log.c um/arch/um/kernel/tty_log.c
31879 --- orig/arch/um/kernel/tty_log.c 1969-12-31 19:00:00.000000000 -0500
31880 +++ um/arch/um/kernel/tty_log.c 2003-10-21 03:26:07.000000000 -0400
31883 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and
31884 + * geoffrey hing <ghing@net.ohio-state.edu>
31885 + * Licensed under the GPL
31888 +#include <errno.h>
31889 +#include <string.h>
31890 +#include <stdio.h>
31891 +#include <stdlib.h>
31892 +#include <unistd.h>
31893 +#include <sys/time.h>
31896 +#include "kern_util.h"
31899 +#define TTY_LOG_DIR "./"
31901 +/* Set early in boot and then unchanged */
31902 +static char *tty_log_dir = TTY_LOG_DIR;
31903 +static int tty_log_fd = -1;
31905 +#define TTY_LOG_OPEN 1
31906 +#define TTY_LOG_CLOSE 2
31907 +#define TTY_LOG_WRITE 3
31908 +#define TTY_LOG_EXEC 4
31910 +#define TTY_READ 1
31911 +#define TTY_WRITE 2
31913 +struct tty_log_buf {
31915 + unsigned long tty;
31918 + unsigned long sec;
31919 + unsigned long usec;
31922 +int open_tty_log(void *tty, void *current_tty)
31924 + struct timeval tv;
31925 + struct tty_log_buf data;
31926 + char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
31929 + gettimeofday(&tv, NULL);
31930 + if(tty_log_fd != -1){
31931 + data = ((struct tty_log_buf) { .what = TTY_LOG_OPEN,
31932 + .tty = (unsigned long) tty,
31933 + .len = sizeof(current_tty),
31935 + .sec = tv.tv_sec,
31936 + .usec = tv.tv_usec } );
31937 + os_write_file(tty_log_fd, &data, sizeof(data));
31938 + os_write_file(tty_log_fd, ¤t_tty, data.len);
31939 + return(tty_log_fd);
31942 + sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
31943 + (unsigned int) tv.tv_usec);
31945 + fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
31948 + printk("open_tty_log : couldn't open '%s', errno = %d\n",
31954 +void close_tty_log(int fd, void *tty)
31956 + struct tty_log_buf data;
31957 + struct timeval tv;
31959 + if(tty_log_fd != -1){
31960 + gettimeofday(&tv, NULL);
31961 + data = ((struct tty_log_buf) { .what = TTY_LOG_CLOSE,
31962 + .tty = (unsigned long) tty,
31965 + .sec = tv.tv_sec,
31966 + .usec = tv.tv_usec } );
31967 + os_write_file(tty_log_fd, &data, sizeof(data));
31970 + os_close_file(fd);
31973 +static int log_chunk(int fd, const char *buf, int len)
31975 + int total = 0, try, missed, n;
31979 + try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
31980 + missed = copy_from_user_proc(chunk, (char *) buf, try);
31982 + n = os_write_file(fd, chunk, try);
31999 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
32001 + struct timeval tv;
32002 + struct tty_log_buf data;
32005 + if(fd == tty_log_fd){
32006 + gettimeofday(&tv, NULL);
32007 + direction = is_read ? TTY_READ : TTY_WRITE;
32008 + data = ((struct tty_log_buf) { .what = TTY_LOG_WRITE,
32009 + .tty = (unsigned long) tty,
32011 + .direction = direction,
32012 + .sec = tv.tv_sec,
32013 + .usec = tv.tv_usec } );
32014 + os_write_file(tty_log_fd, &data, sizeof(data));
32017 + return(log_chunk(fd, buf, len));
32020 +void log_exec(char **argv, void *tty)
32022 + struct timeval tv;
32023 + struct tty_log_buf data;
32027 + if(tty_log_fd == -1) return;
32029 + gettimeofday(&tv, NULL);
32032 + for(ptr = argv; ; ptr++){
32033 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
32035 + if(arg == NULL) break;
32036 + len += strlen_user_proc(arg);
32039 + data = ((struct tty_log_buf) { .what = TTY_LOG_EXEC,
32040 + .tty = (unsigned long) tty,
32043 + .sec = tv.tv_sec,
32044 + .usec = tv.tv_usec } );
32045 + os_write_file(tty_log_fd, &data, sizeof(data));
32047 + for(ptr = argv; ; ptr++){
32048 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
32050 + if(arg == NULL) break;
32051 + log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
32055 +extern void register_tty_logger(int (*opener)(void *, void *),
32056 + int (*writer)(int, const char *, int,
32058 + void (*closer)(int, void *));
32060 +static int register_logger(void)
32062 + register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
32066 +__uml_initcall(register_logger);
32068 +static int __init set_tty_log_dir(char *name, int *add)
32070 + tty_log_dir = name;
32074 +__uml_setup("tty_log_dir=", set_tty_log_dir,
32075 +"tty_log_dir=<directory>\n"
32076 +" This is used to specify the directory where the logs of all pty\n"
32077 +" data from this UML machine will be written.\n\n"
32080 +static int __init set_tty_log_fd(char *name, int *add)
32084 + tty_log_fd = strtoul(name, &end, 0);
32085 + if((*end != '\0') || (end == name)){
32086 + printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
32092 +__uml_setup("tty_log_fd=", set_tty_log_fd,
32093 +"tty_log_fd=<fd>\n"
32094 +" This is used to specify a preconfigured file descriptor to which all\n"
32095 +" tty data will be written. Preconfigure the descriptor with something\n"
32096 +" like '10>tty_log tty_log_fd=10'.\n\n"
32101 + * Overrides for Emacs so that we follow Linus's tabbing style.
32102 + * Emacs will notice this stuff at the end of the file and automatically
32103 + * adjust the settings for this buffer only. This must remain at the end
32105 + * ---------------------------------------------------------------------------
32106 + * Local variables:
32107 + * c-file-style: "linux"
32110 diff -Naur -X ../exclude-files orig/arch/um/kernel/uaccess_user.c um/arch/um/kernel/uaccess_user.c
32111 --- orig/arch/um/kernel/uaccess_user.c 1969-12-31 19:00:00.000000000 -0500
32112 +++ um/arch/um/kernel/uaccess_user.c 2003-10-21 03:26:07.000000000 -0400
32115 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
32116 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32117 + * Licensed under the GPL
32120 +#include <setjmp.h>
32121 +#include <string.h>
32123 +/* These are here rather than tt/uaccess.c because skas mode needs them in
32124 + * order to do SIGBUS recovery when a tmpfs mount runs out of room.
32127 +unsigned long __do_user_copy(void *to, const void *from, int n,
32128 + void **fault_addr, void **fault_catcher,
32129 + void (*op)(void *to, const void *from,
32130 + int n), int *faulted_out)
32132 + unsigned long *faddrp = (unsigned long *) fault_addr, ret;
32135 + *fault_catcher = &jbuf;
32136 + if(sigsetjmp(jbuf, 1) == 0){
32137 + (*op)(to, from, n);
32139 + *faulted_out = 0;
32143 + *faulted_out = 1;
32145 + *fault_addr = NULL;
32146 + *fault_catcher = NULL;
32150 +void __do_copy(void *to, const void *from, int n)
32152 + memcpy(to, from, n);
32156 +int __do_copy_to_user(void *to, const void *from, int n,
32157 + void **fault_addr, void **fault_catcher)
32159 + unsigned long fault;
32162 + fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
32163 + __do_copy, &faulted);
32164 + if(!faulted) return(0);
32165 + else return(n - (fault - (unsigned long) to));
32169 + * Overrides for Emacs so that we follow Linus's tabbing style.
32170 + * Emacs will notice this stuff at the end of the file and automatically
32171 + * adjust the settings for this buffer only. This must remain at the end
32173 + * ---------------------------------------------------------------------------
32174 + * Local variables:
32175 + * c-file-style: "linux"
32178 diff -Naur -X ../exclude-files orig/arch/um/kernel/um_arch.c um/arch/um/kernel/um_arch.c
32179 --- orig/arch/um/kernel/um_arch.c 1969-12-31 19:00:00.000000000 -0500
32180 +++ um/arch/um/kernel/um_arch.c 2003-12-14 11:19:59.000000000 -0500
32183 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
32184 + * Licensed under the GPL
32187 +#include "linux/config.h"
32188 +#include "linux/kernel.h"
32189 +#include "linux/sched.h"
32190 +#include "linux/notifier.h"
32191 +#include "linux/mm.h"
32192 +#include "linux/types.h"
32193 +#include "linux/tty.h"
32194 +#include "linux/init.h"
32195 +#include "linux/bootmem.h"
32196 +#include "linux/spinlock.h"
32197 +#include "linux/utsname.h"
32198 +#include "linux/sysrq.h"
32199 +#include "linux/seq_file.h"
32200 +#include "linux/delay.h"
32201 +#include "asm/page.h"
32202 +#include "asm/pgtable.h"
32203 +#include "asm/ptrace.h"
32204 +#include "asm/elf.h"
32205 +#include "asm/user.h"
32206 +#include "ubd_user.h"
32207 +#include "asm/current.h"
32208 +#include "user_util.h"
32209 +#include "kern_util.h"
32211 +#include "mprot.h"
32212 +#include "mem_user.h"
32215 +#include "initrd.h"
32218 +#include "choose-mode.h"
32219 +#include "mode_kern.h"
32222 +#define DEFAULT_COMMAND_LINE "root=/dev/ubd0"
32224 +struct cpuinfo_um boot_cpu_data = {
32225 + .loops_per_jiffy = 0,
32226 + .pgd_quick = NULL,
32227 + .pmd_quick = NULL,
32228 + .pte_quick = NULL,
32229 + .pgtable_cache_sz = 0,
32230 + .ipi_pipe = { -1, -1 }
32233 +unsigned long thread_saved_pc(struct thread_struct *thread)
32235 + return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
32239 +static int show_cpuinfo(struct seq_file *m, void *v)
32244 + index = (struct cpuinfo_um *)v - cpu_data;
32245 + if (!(cpu_online_map & (1 << index)))
32249 + seq_printf(m, "processor\t: %d\n", index);
32250 + seq_printf(m, "vendor_id\t: User Mode Linux\n");
32251 + seq_printf(m, "model name\t: UML\n");
32252 + seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
32253 + seq_printf(m, "host\t\t: %s\n", host_info);
32254 + seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
32255 + loops_per_jiffy/(500000/HZ),
32256 + (loops_per_jiffy/(5000/HZ)) % 100);
32261 +static void *c_start(struct seq_file *m, loff_t *pos)
32263 + return *pos < NR_CPUS ? cpu_data + *pos : NULL;
32266 +static void *c_next(struct seq_file *m, void *v, loff_t *pos)
32269 + return c_start(m, pos);
32272 +static void c_stop(struct seq_file *m, void *v)
32276 +struct seq_operations cpuinfo_op = {
32277 + .start = c_start,
32280 + .show = show_cpuinfo,
32283 +pte_t * __bad_pagetable(void)
32285 + panic("Someone should implement __bad_pagetable");
32289 +/* Set in linux_main */
32290 +unsigned long host_task_size;
32291 +unsigned long task_size;
32292 +unsigned long uml_start;
32294 +/* Set in early boot */
32295 +unsigned long uml_physmem;
32296 +unsigned long uml_reserved;
32297 +unsigned long start_vm;
32298 +unsigned long end_vm;
32301 +#ifdef CONFIG_MODE_TT
32302 +/* Pointer set in linux_main, the array itself is private to each thread,
32303 + * and changed at address space creation time so this poses no concurrency
32306 +static char *argv1_begin = NULL;
32307 +static char *argv1_end = NULL;
32310 +/* Set in early boot */
32311 +static int have_root __initdata = 0;
32312 +long physmem_size = 32 * 1024 * 1024;
32314 +void set_cmdline(char *cmd)
32316 +#ifdef CONFIG_MODE_TT
32317 + char *umid, *ptr;
32319 + if(CHOOSE_MODE(honeypot, 0)) return;
32321 + umid = get_umid(1);
32322 + if(umid != NULL){
32323 + snprintf(argv1_begin,
32324 + (argv1_end - argv1_begin) * sizeof(*ptr),
32326 + ptr = &argv1_begin[strlen(argv1_begin)];
32328 + else ptr = argv1_begin;
32330 + snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
32331 + memset(argv1_begin + strlen(argv1_begin), '\0',
32332 + argv1_end - argv1_begin - strlen(argv1_begin));
32336 +static char *usage_string =
32337 +"User Mode Linux v%s\n"
32338 +" available at http://user-mode-linux.sourceforge.net/\n\n";
32340 +static int __init uml_version_setup(char *line, int *add)
32342 + printf("%s\n", system_utsname.release);
32346 +__uml_setup("--version", uml_version_setup,
32348 +" Prints the version number of the kernel.\n\n"
32351 +static int __init uml_root_setup(char *line, int *add)
32357 +__uml_setup("root=", uml_root_setup,
32358 +"root=<file containing the root fs>\n"
32359 +" This is actually used by the generic kernel in exactly the same\n"
32360 +" way as in any other kernel. If you configure a number of block\n"
32361 +" devices and want to boot off something other than ubd0, you \n"
32362 +" would use something like:\n"
32363 +" root=/dev/ubd5\n\n"
32367 +static int __init uml_ncpus_setup(char *line, int *add)
32369 + if (!sscanf(line, "%d", &ncpus)) {
32370 + printf("Couldn't parse [%s]\n", line);
32377 +__uml_setup("ncpus=", uml_ncpus_setup,
32378 +"ncpus=<# of desired CPUs>\n"
32379 +" This tells an SMP kernel how many virtual processors to start.\n\n"
32385 +#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
32386 +#define DEFAULT_TT 0
32388 +static int __init mode_tt_setup(char *line, int *add)
32395 +#ifdef CONFIG_MODE_SKAS
32397 +#define DEFAULT_TT 0
32399 +static int __init mode_tt_setup(char *line, int *add)
32401 + printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
32406 +#ifdef CONFIG_MODE_TT
32408 +#define DEFAULT_TT 1
32410 +static int __init mode_tt_setup(char *line, int *add)
32412 + printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
32418 +#error Either CONFIG_MODE_TT or CONFIG_MODE_SKAS must be enabled
32424 +__uml_setup("mode=tt", mode_tt_setup,
32426 +" When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n"
32427 +" forces UML to run in tt (tracing thread) mode. It is not the default\n"
32428 +" because it's slower and less secure than skas mode.\n\n"
32431 +int mode_tt = DEFAULT_TT;
32433 +static int __init Usage(char *line, int *add)
32437 + printf(usage_string, system_utsname.release);
32438 + p = &__uml_help_start;
32439 + while (p < &__uml_help_end) {
32440 + printf("%s", *p);
32446 +__uml_setup("--help", Usage,
32448 +" Prints this message.\n\n"
32451 +static int __init uml_checksetup(char *line, int *add)
32453 + struct uml_param *p;
32455 + p = &__uml_setup_start;
32456 + while(p < &__uml_setup_end) {
32459 + n = strlen(p->str);
32460 + if(!strncmp(line, p->str, n)){
32461 + if (p->setup_func(line + n, add)) return 1;
32468 +static void __init uml_postsetup(void)
32472 + p = &__uml_postsetup_start;
32473 + while(p < &__uml_postsetup_end){
32480 +/* Set during early boot */
32481 +unsigned long brk_start;
32482 +unsigned long end_iomem;
32484 +#define MIN_VMALLOC (32 * 1024 * 1024)
32486 +int linux_main(int argc, char **argv)
32488 + unsigned long avail;
32489 + unsigned long virtmem_size, max_physmem;
32490 + unsigned int i, add;
32492 + for (i = 1; i < argc; i++){
32493 + if((i == 1) && (argv[i][0] == ' ')) continue;
32495 + uml_checksetup(argv[i], &add);
32496 + if(add) add_arg(saved_command_line, argv[i]);
32498 + if(have_root == 0) add_arg(saved_command_line, DEFAULT_COMMAND_LINE);
32500 + mode_tt = force_tt ? 1 : !can_do_skas();
32501 + uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
32502 + &host_task_size, &task_size);
32504 + brk_start = (unsigned long) sbrk(0);
32505 + CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
32507 + uml_physmem = uml_start;
32509 + /* Reserve up to 4M after the current brk */
32510 + uml_reserved = ROUND_4M(brk_start) + (1 << 22);
32512 + setup_machinename(system_utsname.machine);
32514 +#ifdef CONFIG_MODE_TT
32515 + argv1_begin = argv[1];
32516 + argv1_end = &argv[1][strlen(argv[1])];
32520 + iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
32521 + max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
32523 + /* Zones have to begin on a 1 << MAX_ORDER page boundary,
32524 + * so this makes sure that's true for highmem
32526 + max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1);
32527 + if(physmem_size + iomem_size > max_physmem){
32528 + highmem = physmem_size + iomem_size - max_physmem;
32529 + physmem_size -= highmem;
32530 +#ifndef CONFIG_HIGHMEM
32532 + printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
32533 + "to %ld bytes\n", physmem_size);
32537 + high_physmem = uml_physmem + physmem_size;
32538 + end_iomem = high_physmem + iomem_size;
32539 + high_memory = (void *) end_iomem;
32541 + start_vm = VMALLOC_START;
32543 + setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
32544 + if(init_maps(physmem_size, iomem_size, highmem)){
32545 + printf("Failed to allocate mem_map for %ld bytes of physical "
32546 + "memory and %ld bytes of highmem\n", physmem_size,
32551 + virtmem_size = physmem_size;
32552 + avail = get_kmem_end() - start_vm;
32553 + if(physmem_size > avail) virtmem_size = avail;
32554 + end_vm = start_vm + virtmem_size;
32556 + if(virtmem_size < physmem_size)
32557 + printf("Kernel virtual memory size shrunk to %ld bytes\n",
32562 + init_task.thread.kernel_stack = (unsigned long) &init_task +
32565 + task_protections((unsigned long) &init_task);
32566 + os_flush_stdout();
32568 + return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
32571 +static int panic_exit(struct notifier_block *self, unsigned long unused1,
32574 +#ifdef CONFIG_SYSRQ
32575 + handle_sysrq('p', ¤t->thread.regs, NULL, NULL);
32581 +static struct notifier_block panic_exit_notifier = {
32582 + .notifier_call = panic_exit,
32587 +void __init setup_arch(char **cmdline_p)
32589 + notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
32591 + strcpy(command_line, saved_command_line);
32592 + *cmdline_p = command_line;
32593 + setup_hostinfo();
32596 +void __init check_bugs(void)
32598 + arch_check_bugs();
32605 + * Overrides for Emacs so that we follow Linus's tabbing style.
32606 + * Emacs will notice this stuff at the end of the file and automatically
32607 + * adjust the settings for this buffer only. This must remain at the end
32609 + * ---------------------------------------------------------------------------
32610 + * Local variables:
32611 + * c-file-style: "linux"
32614 diff -Naur -X ../exclude-files orig/arch/um/kernel/umid.c um/arch/um/kernel/umid.c
32615 --- orig/arch/um/kernel/umid.c 1969-12-31 19:00:00.000000000 -0500
32616 +++ um/arch/um/kernel/umid.c 2003-10-21 03:26:07.000000000 -0400
32619 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32620 + * Licensed under the GPL
32623 +#include <stdio.h>
32624 +#include <unistd.h>
32625 +#include <errno.h>
32626 +#include <string.h>
32627 +#include <stdlib.h>
32628 +#include <dirent.h>
32629 +#include <signal.h>
32630 +#include <sys/stat.h>
32631 +#include <sys/param.h>
32636 +#include "user_util.h"
32637 +#include "choose-mode.h"
32639 +#define UMID_LEN 64
32640 +#define UML_DIR "~/.uml/"
32642 +/* Changed by set_umid and make_umid, which are run early in boot */
32643 +static char umid[UMID_LEN] = { 0 };
32645 +/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
32646 +static char *uml_dir = UML_DIR;
32648 +/* Changed by set_umid */
32649 +static int umid_is_random = 1;
32650 +static int umid_inited = 0;
32652 +static int make_umid(int (*printer)(const char *fmt, ...));
32654 +static int __init set_umid(char *name, int is_random,
32655 + int (*printer)(const char *fmt, ...))
32658 + (*printer)("Unique machine name can't be set twice\n");
32662 + if(strlen(name) > UMID_LEN - 1)
32663 + (*printer)("Unique machine name is being truncated to %s "
32664 + "characters\n", UMID_LEN);
32665 + strncpy(umid, name, UMID_LEN - 1);
32666 + umid[UMID_LEN - 1] = '\0';
32668 + umid_is_random = is_random;
32673 +static int __init set_umid_arg(char *name, int *add)
32675 + return(set_umid(name, 0, printf));
32678 +__uml_setup("umid=", set_umid_arg,
32680 +" This is used to assign a unique identity to this UML machine and\n"
32681 +" is used for naming the pid file and management console socket.\n\n"
32684 +int __init umid_file_name(char *name, char *buf, int len)
32688 + if(!umid_inited && make_umid(printk)) return(-1);
32690 + n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
32692 + printk("umid_file_name : buffer too short\n");
32696 + sprintf(buf, "%s%s/%s", uml_dir, umid, name);
32700 +extern int tracing_pid;
32702 +static int __init create_pid_file(void)
32704 + char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
32705 + char pid[sizeof("nnnnn\0")];
32708 + if(umid_file_name("pid", file, sizeof(file))) return 0;
32710 + fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
32713 + printf("Open of machine pid file \"%s\" failed - "
32714 + "err = %d\n", file, -fd);
32718 + sprintf(pid, "%d\n", os_getpid());
32719 + n = os_write_file(fd, pid, strlen(pid));
32720 + if(n != strlen(pid))
32721 + printf("Write of pid file failed - err = %d\n", -n);
32722 + os_close_file(fd);
32726 +static int actually_do_remove(char *dir)
32729 + struct dirent *ent;
32733 + directory = opendir(dir);
32734 + if(directory == NULL){
32735 + printk("actually_do_remove : couldn't open directory '%s', "
32736 + "errno = %d\n", dir, errno);
32739 + while((ent = readdir(directory)) != NULL){
32740 + if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
32742 + len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
32743 + if(len > sizeof(file)){
32744 + printk("Not deleting '%s' from '%s' - name too long\n",
32745 + ent->d_name, dir);
32748 + sprintf(file, "%s/%s", dir, ent->d_name);
32749 + if(unlink(file) < 0){
32750 + printk("actually_do_remove : couldn't remove '%s' "
32751 + "from '%s', errno = %d\n", ent->d_name, dir,
32756 + if(rmdir(dir) < 0){
32757 + printk("actually_do_remove : couldn't rmdir '%s', "
32758 + "errno = %d\n", dir, errno);
32764 +void remove_umid_dir(void)
32766 + char dir[strlen(uml_dir) + UMID_LEN + 1];
32767 + if(!umid_inited) return;
32769 + sprintf(dir, "%s%s", uml_dir, umid);
32770 + actually_do_remove(dir);
32773 +char *get_umid(int only_if_set)
32775 + if(only_if_set && umid_is_random) return(NULL);
32779 +int not_dead_yet(char *dir)
32781 + char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
32782 + char pid[sizeof("nnnnn\0")], *end;
32783 + int dead, fd, p, n;
32785 + sprintf(file, "%s/pid", dir);
32787 + fd = os_open_file(file, of_read(OPENFLAGS()), 0);
32789 + if(fd != -ENOENT){
32790 + printk("not_dead_yet : couldn't open pid file '%s', "
32791 + "err = %d\n", file, -fd);
32797 + n = os_read_file(fd, pid, sizeof(pid));
32799 + printk("not_dead_yet : couldn't read pid file '%s', "
32800 + "err = %d\n", file, -n);
32803 + p = strtoul(pid, &end, 0);
32805 + printk("not_dead_yet : couldn't parse pid file '%s', "
32806 + "errno = %d\n", file, errno);
32809 + if(((kill(p, 0) < 0) && (errno == ESRCH)) ||
32810 + (p == CHOOSE_MODE(tracing_pid, os_getpid())))
32813 + if(!dead) return(1);
32814 + return(actually_do_remove(dir));
32817 +static int __init set_uml_dir(char *name, int *add)
32819 + if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
32820 + uml_dir = malloc(strlen(name) + 1);
32821 + if(uml_dir == NULL){
32822 + printf("Failed to malloc uml_dir - error = %d\n",
32827 + sprintf(uml_dir, "%s/", name);
32829 + else uml_dir = name;
32833 +static int __init make_uml_dir(void)
32835 + char dir[MAXPATHLEN + 1] = { '\0' };
32838 + if(*uml_dir == '~'){
32839 + char *home = getenv("HOME");
32841 + if(home == NULL){
32842 + printf("make_uml_dir : no value in environment for "
32846 + strncpy(dir, home, sizeof(dir));
32849 + len = strlen(dir);
32850 + strncat(dir, uml_dir, sizeof(dir) - len);
32851 + len = strlen(dir);
32852 + if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){
32854 + dir[len + 1] = '\0';
32857 + uml_dir = malloc(strlen(dir) + 1);
32858 + if(uml_dir == NULL){
32859 + printf("make_uml_dir : malloc failed, errno = %d\n", errno);
32862 + strcpy(uml_dir, dir);
32864 + if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
32865 + printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
32871 +static int __init make_umid(int (*printer)(const char *fmt, ...))
32874 + char tmp[strlen(uml_dir) + UMID_LEN + 1];
32876 + strncpy(tmp, uml_dir, sizeof(tmp) - 1);
32877 + tmp[sizeof(tmp) - 1] = '\0';
32879 + if(!umid_inited){
32880 + strcat(tmp, "XXXXXX");
32881 + fd = mkstemp(tmp);
32883 + (*printer)("make_umid - mkstemp failed, errno = %d\n",
32888 + os_close_file(fd);
32889 + /* There's a nice tiny little race between this unlink and
32890 + * the mkdir below. It'd be nice if there were a mkstemp
32891 + * for directories.
32894 + set_umid(&tmp[strlen(uml_dir)], 1, printer);
32897 + sprintf(tmp, "%s%s", uml_dir, umid);
32899 + err = mkdir(tmp, 0777);
32901 + if(errno == EEXIST){
32902 + if(not_dead_yet(tmp)){
32903 + (*printer)("umid '%s' is in use\n", umid);
32906 + err = mkdir(tmp, 0777);
32910 + (*printer)("Failed to create %s - errno = %d\n", umid, errno);
32917 +__uml_setup("uml_dir=", set_uml_dir,
32918 +"uml_dir=<directory>\n"
32919 +" The location to place the pid and umid files.\n\n"
32922 +__uml_postsetup(make_uml_dir);
32924 +static int __init make_umid_setup(void)
32926 + return(make_umid(printf));
32929 +__uml_postsetup(make_umid_setup);
32930 +__uml_postsetup(create_pid_file);
32933 + * Overrides for Emacs so that we follow Linus's tabbing style.
32934 + * Emacs will notice this stuff at the end of the file and automatically
32935 + * adjust the settings for this buffer only. This must remain at the end
32937 + * ---------------------------------------------------------------------------
32938 + * Local variables:
32939 + * c-file-style: "linux"
32942 diff -Naur -X ../exclude-files orig/arch/um/kernel/user_syms.c um/arch/um/kernel/user_syms.c
32943 --- orig/arch/um/kernel/user_syms.c 1969-12-31 19:00:00.000000000 -0500
32944 +++ um/arch/um/kernel/user_syms.c 2003-10-21 03:26:07.000000000 -0400
32946 +#include <stdio.h>
32947 +#include <unistd.h>
32948 +#include <dirent.h>
32949 +#include <fcntl.h>
32950 +#include <errno.h>
32951 +#include <utime.h>
32952 +#include <string.h>
32953 +#include <sys/stat.h>
32954 +#include <sys/vfs.h>
32955 +#include <sys/ioctl.h>
32956 +#include "user_util.h"
32957 +#include "mem_user.h"
32959 +/* XXX All the __CONFIG_* stuff is broken because this file can't include
32963 +/* Had to steal this from linux/module.h because that file can't be included
32964 + * since this includes various user-level headers.
32967 +struct module_symbol
32969 + unsigned long value;
32970 + const char *name;
32973 +/* Indirect stringification. */
32975 +#define __MODULE_STRING_1(x) #x
32976 +#define __MODULE_STRING(x) __MODULE_STRING_1(x)
32978 +#if !defined(__AUTOCONF_INCLUDED__)
32980 +#define __EXPORT_SYMBOL(sym,str) error config_must_be_included_before_module
32981 +#define EXPORT_SYMBOL(var) error config_must_be_included_before_module
32982 +#define EXPORT_SYMBOL_NOVERS(var) error config_must_be_included_before_module
32984 +#elif !defined(__CONFIG_MODULES__)
32986 +#define __EXPORT_SYMBOL(sym,str)
32987 +#define EXPORT_SYMBOL(var)
32988 +#define EXPORT_SYMBOL_NOVERS(var)
32992 +#define __EXPORT_SYMBOL(sym, str) \
32993 +const char __kstrtab_##sym[] \
32994 +__attribute__((section(".kstrtab"))) = str; \
32995 +const struct module_symbol __ksymtab_##sym \
32996 +__attribute__((section("__ksymtab"))) = \
32997 +{ (unsigned long)&sym, __kstrtab_##sym }
32999 +#if defined(__MODVERSIONS__) || !defined(__CONFIG_MODVERSIONS__)
33000 +#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var))
33002 +#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var)))
33005 +#define EXPORT_SYMBOL_NOVERS(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var))
33009 +EXPORT_SYMBOL(__errno_location);
33011 +EXPORT_SYMBOL(access);
33012 +EXPORT_SYMBOL(open);
33013 +EXPORT_SYMBOL(open64);
33014 +EXPORT_SYMBOL(close);
33015 +EXPORT_SYMBOL(read);
33016 +EXPORT_SYMBOL(write);
33017 +EXPORT_SYMBOL(dup2);
33018 +EXPORT_SYMBOL(__xstat);
33019 +EXPORT_SYMBOL(__lxstat);
33020 +EXPORT_SYMBOL(__lxstat64);
33021 +EXPORT_SYMBOL(lseek);
33022 +EXPORT_SYMBOL(lseek64);
33023 +EXPORT_SYMBOL(chown);
33024 +EXPORT_SYMBOL(truncate);
33025 +EXPORT_SYMBOL(utime);
33026 +EXPORT_SYMBOL(chmod);
33027 +EXPORT_SYMBOL(rename);
33028 +EXPORT_SYMBOL(__xmknod);
33030 +EXPORT_SYMBOL(symlink);
33031 +EXPORT_SYMBOL(link);
33032 +EXPORT_SYMBOL(unlink);
33033 +EXPORT_SYMBOL(readlink);
33035 +EXPORT_SYMBOL(mkdir);
33036 +EXPORT_SYMBOL(rmdir);
33037 +EXPORT_SYMBOL(opendir);
33038 +EXPORT_SYMBOL(readdir);
33039 +EXPORT_SYMBOL(closedir);
33040 +EXPORT_SYMBOL(seekdir);
33041 +EXPORT_SYMBOL(telldir);
33043 +EXPORT_SYMBOL(ioctl);
33045 +extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes,
33046 + __off64_t __offset);
33047 +extern ssize_t pwrite64 (int __fd, __const void *__buf, size_t __n,
33048 + __off64_t __offset);
33049 +EXPORT_SYMBOL(pread64);
33050 +EXPORT_SYMBOL(pwrite64);
33052 +EXPORT_SYMBOL(statfs);
33053 +EXPORT_SYMBOL(statfs64);
33055 +EXPORT_SYMBOL(memcpy);
33056 +EXPORT_SYMBOL(getuid);
33058 +EXPORT_SYMBOL(memset);
33059 +EXPORT_SYMBOL(strstr);
33061 +EXPORT_SYMBOL(find_iomem);
33062 diff -Naur -X ../exclude-files orig/arch/um/kernel/user_util.c um/arch/um/kernel/user_util.c
33063 --- orig/arch/um/kernel/user_util.c 1969-12-31 19:00:00.000000000 -0500
33064 +++ um/arch/um/kernel/user_util.c 2003-10-21 03:26:07.000000000 -0400
33067 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
33068 + * Licensed under the GPL
33071 +#include <stdio.h>
33072 +#include <stdlib.h>
33073 +#include <unistd.h>
33074 +#include <limits.h>
33075 +#include <sys/mman.h>
33076 +#include <sys/stat.h>
33077 +#include <sys/ptrace.h>
33078 +#include <sys/utsname.h>
33079 +#include <sys/param.h>
33080 +#include <sys/time.h>
33081 +#include "asm/types.h"
33082 +#include <ctype.h>
33083 +#include <signal.h>
33085 +#include <errno.h>
33086 +#include <stdarg.h>
33087 +#include <sched.h>
33088 +#include <termios.h>
33089 +#include <string.h>
33090 +#include "user_util.h"
33091 +#include "kern_util.h"
33093 +#include "mem_user.h"
33095 +#include "helper.h"
33096 +#include "uml-config.h"
33098 +#define COMMAND_LINE_SIZE _POSIX_ARG_MAX
33100 +/* Changed in linux_main and setup_arch, which run before SMP is started */
33101 +char saved_command_line[COMMAND_LINE_SIZE] = { 0 };
33102 +char command_line[COMMAND_LINE_SIZE] = { 0 };
33104 +void add_arg(char *cmd_line, char *arg)
33106 + if (strlen(cmd_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
33107 + printf("add_arg: Too much command line!\n");
33110 + if(strlen(cmd_line) > 0) strcat(cmd_line, " ");
33111 + strcat(cmd_line, arg);
33116 + while(1) sleep(1000000);
33119 +void stack_protections(unsigned long address)
33121 + int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
33123 + if(mprotect((void *) address, page_size(), prot) < 0)
33124 + panic("protecting stack failed, errno = %d", errno);
33127 +void task_protections(unsigned long address)
33129 + unsigned long guard = address + page_size();
33130 + unsigned long stack = guard + page_size();
33131 + int prot = 0, pages;
33133 + if(mprotect((void *) guard, page_size(), prot) < 0)
33134 + panic("protecting guard page failed, errno = %d", errno);
33136 + pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
33137 + prot = PROT_READ | PROT_WRITE | PROT_EXEC;
33138 + if(mprotect((void *) stack, pages * page_size(), prot) < 0)
33139 + panic("protecting stack failed, errno = %d", errno);
33142 +int wait_for_stop(int pid, int sig, int cont_type, void *relay)
33144 + sigset_t *relay_signals = relay;
33148 + ret = waitpid(pid, &status, WUNTRACED);
33150 + !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
33152 + if(errno == EINTR) continue;
33153 + printk("wait failed, errno = %d\n",
33156 + else if(WIFEXITED(status))
33157 + printk("process exited with status %d\n",
33158 + WEXITSTATUS(status));
33159 + else if(WIFSIGNALED(status))
33160 + printk("process exited with signal %d\n",
33161 + WTERMSIG(status));
33162 + else if((WSTOPSIG(status) == SIGVTALRM) ||
33163 + (WSTOPSIG(status) == SIGALRM) ||
33164 + (WSTOPSIG(status) == SIGIO) ||
33165 + (WSTOPSIG(status) == SIGPROF) ||
33166 + (WSTOPSIG(status) == SIGCHLD) ||
33167 + (WSTOPSIG(status) == SIGWINCH) ||
33168 + (WSTOPSIG(status) == SIGINT)){
33169 + ptrace(cont_type, pid, 0, WSTOPSIG(status));
33172 + else if((relay_signals != NULL) &&
33173 + sigismember(relay_signals, WSTOPSIG(status))){
33174 + ptrace(cont_type, pid, 0, WSTOPSIG(status));
33177 + else printk("process stopped with signal %d\n",
33178 + WSTOPSIG(status));
33179 + panic("wait_for_stop failed to wait for %d to stop "
33180 + "with %d\n", pid, sig);
33186 +int raw(int fd, int complain)
33188 + struct termios tt;
33191 + tcgetattr(fd, &tt);
33193 + err = tcsetattr(fd, TCSANOW, &tt);
33194 + if((err < 0) && complain){
33195 + printk("tcsetattr failed, errno = %d\n", errno);
33201 +void setup_machinename(char *machine_out)
33203 + struct utsname host;
33206 + strcpy(machine_out, host.machine);
33209 +char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1];
33211 +void setup_hostinfo(void)
33213 + struct utsname host;
33216 + sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename,
33217 + host.release, host.version, host.machine);
33221 + * Overrides for Emacs so that we follow Linus's tabbing style.
33222 + * Emacs will notice this stuff at the end of the file and automatically
33223 + * adjust the settings for this buffer only. This must remain at the end
33225 + * ---------------------------------------------------------------------------
33226 + * Local variables:
33227 + * c-file-style: "linux"
33230 diff -Naur -X ../exclude-files orig/arch/um/link.ld.in um/arch/um/link.ld.in
33231 --- orig/arch/um/link.ld.in 1969-12-31 19:00:00.000000000 -0500
33232 +++ um/arch/um/link.ld.in 2003-10-21 03:26:07.000000000 -0400
33234 +OUTPUT_FORMAT("ELF_FORMAT")
33235 +OUTPUT_ARCH(ELF_ARCH)
33240 + . = START() + SIZEOF_HEADERS;
33242 + __binary_start = .;
33243 +ifdef(`MODE_TT', `
33244 + .thread_private : {
33245 + __start_thread_private = .;
33248 + arch/um/kernel/tt/unmap_fin.o (.data)
33249 + __end_thread_private = .;
33252 + .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
33254 + . = ALIGN(4096); /* Init code and data */
33256 + __init_begin = .;
33257 + .text.init : { *(.text.init) }
33262 + /* .gnu.warning sections are handled specially by elf32.em. */
33264 + *(.gnu.linkonce.t*)
33266 + .fini : { *(.fini) } =0x9090
33267 + .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
33268 + .rodata1 : { *(.rodata1) }
33270 + PROVIDE (etext = .);
33273 + PROVIDE (_sdata = .);
33275 +include(`arch/um/common.ld.in')
33279 + . = ALIGN(KERNEL_STACK_SIZE); /* init_task */
33280 + *(.data.init_task)
33282 + *(.gnu.linkonce.d*)
33285 + .data1 : { *(.data1) }
33295 + .got : { *(.got.plt) *(.got) }
33296 + .dynamic : { *(.dynamic) }
33297 + /* We want the small data sections together, so single-instruction offsets
33298 + can access them all, and initialized data all before uninitialized, so
33299 + we can shorten the on-disk segment size. */
33300 + .sdata : { *(.sdata) }
33302 + PROVIDE (edata = .);
33303 + . = ALIGN(0x1000);
33307 + PROVIDE(_bss_start = .);
33318 + PROVIDE (end = .);
33319 + /* Stabs debugging sections. */
33320 + .stab 0 : { *(.stab) }
33321 + .stabstr 0 : { *(.stabstr) }
33322 + .stab.excl 0 : { *(.stab.excl) }
33323 + .stab.exclstr 0 : { *(.stab.exclstr) }
33324 + .stab.index 0 : { *(.stab.index) }
33325 + .stab.indexstr 0 : { *(.stab.indexstr) }
33326 + .comment 0 : { *(.comment) }
33328 diff -Naur -X ../exclude-files orig/arch/um/main.c um/arch/um/main.c
33329 --- orig/arch/um/main.c 1969-12-31 19:00:00.000000000 -0500
33330 +++ um/arch/um/main.c 2003-10-21 03:26:07.000000000 -0400
33333 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
33334 + * Licensed under the GPL
33337 +#include <unistd.h>
33338 +#include <stdio.h>
33339 +#include <stdlib.h>
33340 +#include <string.h>
33341 +#include <signal.h>
33342 +#include <errno.h>
33343 +#include <sys/resource.h>
33344 +#include <sys/mman.h>
33345 +#include <sys/user.h>
33346 +#include <asm/page.h>
33347 +#include "user_util.h"
33348 +#include "kern_util.h"
33349 +#include "mem_user.h"
33350 +#include "signal_user.h"
33354 +#include "choose-mode.h"
33355 +#include "uml-config.h"
33357 +/* Set in set_stklim, which is called from main and __wrap_malloc.
33358 + * __wrap_malloc only calls it if main hasn't started.
33360 +unsigned long stacksizelim;
33365 +#define PGD_BOUND (4 * 1024 * 1024)
33366 +#define STACKSIZE (8 * 1024 * 1024)
33367 +#define THREAD_NAME_LEN (256)
33369 +static void set_stklim(void)
33371 + struct rlimit lim;
33373 + if(getrlimit(RLIMIT_STACK, &lim) < 0){
33374 + perror("getrlimit");
33377 + if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){
33378 + lim.rlim_cur = STACKSIZE;
33379 + if(setrlimit(RLIMIT_STACK, &lim) < 0){
33380 + perror("setrlimit");
33384 + stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1);
33387 +static __init void do_uml_initcalls(void)
33389 + initcall_t *call;
33391 + call = &__uml_initcall_start;
33392 + while (call < &__uml_initcall_end){;
33398 +static void last_ditch_exit(int sig)
33400 + CHOOSE_MODE(kmalloc_ok = 0, (void) 0);
33401 + signal(SIGINT, SIG_DFL);
33402 + signal(SIGTERM, SIG_DFL);
33403 + signal(SIGHUP, SIG_DFL);
33408 +extern int uml_exitcode;
33410 +int main(int argc, char **argv, char **envp)
33416 + /* Enable all signals except SIGIO - in some environments, we can
33417 + * enter with some signals blocked
33420 + sigemptyset(&mask);
33421 + sigaddset(&mask, SIGIO);
33422 + if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){
33423 + perror("sigprocmask");
33427 +#ifdef UML_CONFIG_MODE_TT
33428 + /* Allocate memory for thread command lines */
33429 + if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
33431 + char padding[THREAD_NAME_LEN] = {
33432 + [ 0 ... THREAD_NAME_LEN - 2] = ' ', '\0'
33435 + new_argv = malloc((argc + 2) * sizeof(char*));
33437 + perror("Allocating extended argv");
33441 + new_argv[0] = argv[0];
33442 + new_argv[1] = padding;
33444 + for(i = 2; i <= argc; i++)
33445 + new_argv[i] = argv[i - 1];
33446 + new_argv[argc + 1] = NULL;
33448 + execvp(new_argv[0], new_argv);
33449 + perror("execing with extended args");
33454 + linux_prog = argv[0];
33458 + new_argv = malloc((argc + 1) * sizeof(char *));
33459 + if(new_argv == NULL){
33460 + perror("Mallocing argv");
33463 + for(i=0;i<argc;i++){
33464 + new_argv[i] = strdup(argv[i]);
33465 + if(new_argv[i] == NULL){
33466 + perror("Mallocing an arg");
33470 + new_argv[argc] = NULL;
33472 + set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
33473 + set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
33474 + set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
33476 + do_uml_initcalls();
33477 + ret = linux_main(argc, argv);
33482 + execvp(new_argv[0], new_argv);
33483 + perror("Failed to exec kernel");
33487 + return(uml_exitcode);
33490 +#define CAN_KMALLOC() \
33491 + (kmalloc_ok && CHOOSE_MODE((getpid() != tracing_pid), 1))
33493 +extern void *__real_malloc(int);
33495 +void *__wrap_malloc(int size)
33497 + if(CAN_KMALLOC())
33498 + return(um_kmalloc(size));
33500 + return(__real_malloc(size));
33503 +void *__wrap_calloc(int n, int size)
33505 + void *ptr = __wrap_malloc(n * size);
33507 + if(ptr == NULL) return(NULL);
33508 + memset(ptr, 0, n * size);
33512 +extern void __real_free(void *);
33514 +void __wrap_free(void *ptr)
33516 + if(CAN_KMALLOC()) kfree(ptr);
33517 + else __real_free(ptr);
33521 + * Overrides for Emacs so that we follow Linus's tabbing style.
33522 + * Emacs will notice this stuff at the end of the file and automatically
33523 + * adjust the settings for this buffer only. This must remain at the end
33525 + * ---------------------------------------------------------------------------
33526 + * Local variables:
33527 + * c-file-style: "linux"
33530 diff -Naur -X ../exclude-files orig/arch/um/Makefile um/arch/um/Makefile
33531 --- orig/arch/um/Makefile 1969-12-31 19:00:00.000000000 -0500
33532 +++ um/arch/um/Makefile 2003-12-17 03:02:28.000000000 -0500
33535 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33536 +# Licensed under the GPL
33539 +OS := $(shell uname -s)
33541 +ARCH_DIR = arch/um
33543 +core-y := kernel sys-$(SUBARCH) os-$(OS)
33544 +drivers-y := fs drivers
33545 +subdir-y := $(core-y) $(drivers-y)
33546 +SUBDIRS += $(foreach dir,$(subdir-y),$(ARCH_DIR)/$(dir))
33548 +CORE_FILES += $(foreach dir,$(core-y),$(ARCH_DIR)/$(dir)/built-in.o)
33549 +DRIVERS += $(foreach dir,$(drivers-y),$(ARCH_DIR)/$(dir)/built-in.o)
33551 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
33552 +include $(ARCH_DIR)/Makefile-os-$(OS)
33554 +MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
33555 +MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
33557 +ifneq ($(MAKEFILE-y),)
33558 + include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
33561 +EXTRAVERSION := $(EXTRAVERSION)-1um
33563 +include/linux/version.h: arch/$(ARCH)/Makefile
33565 +# Recalculate MODLIB to reflect the EXTRAVERSION changes (via KERNELRELEASE)
33566 +# The way the toplevel Makefile is written EXTRAVERSION is not supposed
33567 +# to be changed outside the toplevel Makefile, but recalculating MODLIB is
33568 +# a sufficient workaround until we no longer need architecture dependent
33570 +MODLIB := $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
33572 +ifeq ($(CONFIG_DEBUGSYM),y)
33573 +CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS))
33576 +CFLAGS-$(CONFIG_DEBUGSYM) += -g
33578 +ARCH_INCLUDE = -I$(TOPDIR)/$(ARCH_DIR)/include
33580 +# -Derrno=kernel_errno - This turns all kernel references to errno into
33581 +# kernel_errno to separate them from the libc errno. This allows -fno-common
33582 +# in CFLAGS. Otherwise, it would cause ld to complain about the two different
33585 +CFLAGS += $(ARCH_CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
33586 + -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
33591 +LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
33593 +# These are needed for clean and mrproper, since in that case .config is not
33594 +# included; the values here are meaningless
33596 +CONFIG_NEST_LEVEL ?= 0
33597 +CONFIG_KERNEL_HALF_GIGS ?= 0
33599 +SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
33601 +# These aren't in Makefile-tt because they are needed in the !CONFIG_MODE_TT +
33602 +# CONFIG_MODE_SKAS + CONFIG_STATIC_LINK case.
33605 +LD_SCRIPT_TT := link.ld
33607 +ifeq ($(CONFIG_STATIC_LINK),y)
33608 + LINK-y += $(LINK_TT)
33609 + LD_SCRIPT-y := $(LD_SCRIPT_TT)
33611 +ifeq ($(CONFIG_MODE_TT),y)
33612 + LINK-y += $(LINK_TT)
33613 + LD_SCRIPT-y := $(LD_SCRIPT_TT)
33615 +ifeq ($(CONFIG_MODE_SKAS),y)
33616 + LINK-y += $(LINK_SKAS)
33617 + LD_SCRIPT-y := $(LD_SCRIPT_SKAS)
33622 +LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
33623 +M4_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT)
33625 +$(LD_SCRIPT-y): $(LD_SCRIPT-y).in
33626 + pages=$$(( 1 << $(CONFIG_KERNEL_STACK_ORDER) )) ; \
33627 + m4 -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
33628 + -DELF_FORMAT=$(ELF_FORMAT) $(M4_MODE_TT) \
33629 + -DKERNEL_STACK_SIZE=$$(( 4096 * $$pages )) $< > $@
33631 +SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
33632 + include/asm-um/sigcontext.h include/asm-um/processor.h \
33633 + include/asm-um/ptrace.h include/asm-um/arch-signal.h
33635 +ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \
33636 + $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
33638 +ifeq ($(CONFIG_MODE_SKAS), y)
33639 +$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
33642 +GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
33644 +setup: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS)
33646 +linux: setup $(ARCH_DIR)/main.o vmlinux $(LD_SCRIPT-y)
33647 + mv vmlinux vmlinux.o
33648 + $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
33649 + -o linux $(ARCH_DIR)/main.o vmlinux.o -L/usr/lib -lutil
33651 +USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
33652 +USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
33653 +USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
33656 +# To get a definition of F_SETSIG
33657 +USER_CFLAGS += -D_GNU_SOURCE
33659 +CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/link.ld $(ARCH_DIR)/dyn_link.ld \
33660 + $(GEN_HEADERS) $(ARCH_DIR)/include/uml-config.h
33662 +$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
33663 + $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
33666 + rm -f $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
33667 + $(LD_SCRIPT) $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
33669 +archclean: sysclean
33670 + find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
33671 + -o -name '*.gcov' \) -type f -print | xargs rm -f
33672 + cd $(ARCH_DIR) ; \
33673 + for dir in $(subdir-y) util ; do $(MAKE) -C $$dir clean; done
33677 +$(SYMLINK_HEADERS):
33678 + cd $(TOPDIR)/$(dir $@) ; \
33679 + ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
33681 +include/asm-um/arch:
33682 + cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
33684 +arch/um/include/sysdep:
33685 + cd $(TOPDIR)/arch/um/include && ln -sf sysdep-$(SUBARCH) sysdep
33688 + cd $(ARCH_DIR) && ln -sf os-$(OS) os
33690 +$(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
33693 +$(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
33696 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
33697 + sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
33699 +$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/util/mk_task_user.c \
33700 + $(ARCH_DIR)/util/mk_task_kern.c $(SYS_HEADERS)
33701 + $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_task
33703 +$(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util/mk_constants_user.c \
33704 + $(ARCH_DIR)/util/mk_constants_kern.c
33705 + $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_constants
33707 +export SUBARCH USER_CFLAGS OS
33708 diff -Naur -X ../exclude-files orig/arch/um/Makefile-i386 um/arch/um/Makefile-i386
33709 --- orig/arch/um/Makefile-i386 1969-12-31 19:00:00.000000000 -0500
33710 +++ um/arch/um/Makefile-i386 2003-10-21 03:26:07.000000000 -0400
33712 +ifeq ($(CONFIG_HOST_2G_2G), y)
33713 +TOP_ADDR = 0x80000000
33715 +TOP_ADDR = 0xc0000000
33718 +ARCH_CFLAGS = -U__$(SUBARCH)__ -U$(SUBARCH) -DUM_FASTCALL
33719 +ELF_ARCH = $(SUBARCH)
33720 +ELF_FORMAT = elf32-$(SUBARCH)
33722 +I386_H = $(ARCH_DIR)/include/sysdep-i386
33723 +SYS = $(ARCH_DIR)/sys-i386
33724 +UTIL = $(SYS)/util
33725 +SUBDIRS += $(UTIL)
33727 +SYS_HEADERS = $(I386_H)/sc.h $(I386_H)/thread.h
33729 +$(I386_H)/sc.h : $(UTIL)/mk_sc
33730 + $(UTIL)/mk_sc > $@
33732 +$(I386_H)/thread.h : $(UTIL)/mk_thread
33733 + $(UTIL)/mk_thread > $@
33735 +$(UTIL)/mk_sc : $(UTIL)/mk_sc.c
33736 + $(MAKE) -C $(UTIL) mk_sc
33738 +$(UTIL)/mk_thread : $(UTIL)/mk_thread_user.c $(UTIL)/mk_thread_kern.c \
33740 + $(MAKE) -C $(UTIL) mk_thread
33743 + rm -f $(SYS_HEADERS)
33744 + $(MAKE) -C $(UTIL) clean
33745 + $(MAKE) -C $(SYS) clean
33747 diff -Naur -X ../exclude-files orig/arch/um/Makefile-ia64 um/arch/um/Makefile-ia64
33748 --- orig/arch/um/Makefile-ia64 1969-12-31 19:00:00.000000000 -0500
33749 +++ um/arch/um/Makefile-ia64 2003-10-21 03:26:07.000000000 -0400
33751 +START_ADDR = 0x1000000000000000
33752 diff -Naur -X ../exclude-files orig/arch/um/Makefile-os-Linux um/arch/um/Makefile-os-Linux
33753 --- orig/arch/um/Makefile-os-Linux 1969-12-31 19:00:00.000000000 -0500
33754 +++ um/arch/um/Makefile-os-Linux 2003-10-21 03:26:07.000000000 -0400
33757 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
33758 +# Licensed under the GPL
33761 +SUBDIRS += $(ARCH_DIR)/os-$(OS)/drivers
33762 +DRIVERS += $(ARCH_DIR)/os-$(OS)/drivers/drivers.o
33763 diff -Naur -X ../exclude-files orig/arch/um/Makefile-ppc um/arch/um/Makefile-ppc
33764 --- orig/arch/um/Makefile-ppc 1969-12-31 19:00:00.000000000 -0500
33765 +++ um/arch/um/Makefile-ppc 2003-10-21 03:26:07.000000000 -0400
33767 +ifeq ($(CONFIG_HOST_2G_2G), y)
33768 +START_ADDR = 0x80000000
33770 +START_ADDR = 0xc0000000
33772 +ARCH_CFLAGS = -U__powerpc__ -D__UM_PPC__
33774 +# The arch is ppc, but the elf32 name is powerpc
33775 +ELF_SUBARCH = powerpc
33776 diff -Naur -X ../exclude-files orig/arch/um/Makefile-skas um/arch/um/Makefile-skas
33777 --- orig/arch/um/Makefile-skas 1969-12-31 19:00:00.000000000 -0500
33778 +++ um/arch/um/Makefile-skas 2003-10-21 03:26:07.000000000 -0400
33781 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33782 +# Licensed under the GPL
33787 +CFLAGS-$(CONFIG_GCOV) += -fprofile-arcs -ftest-coverage
33788 +CFLAGS-$(CONFIG_GPROF) += $(PROFILE)
33789 +LINK-$(CONFIG_GPROF) += $(PROFILE)
33791 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/skas/include
33793 +LINK_SKAS = -Wl,-rpath,/lib
33794 +LD_SCRIPT_SKAS = dyn_link.ld
33796 +GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
33798 +$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
33799 + $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
33800 diff -Naur -X ../exclude-files orig/arch/um/Makefile-tt um/arch/um/Makefile-tt
33801 --- orig/arch/um/Makefile-tt 1969-12-31 19:00:00.000000000 -0500
33802 +++ um/arch/um/Makefile-tt 2003-10-21 03:26:07.000000000 -0400
33805 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33806 +# Licensed under the GPL
33809 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/tt/include
33811 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/etap.h um/arch/um/os-Linux/drivers/etap.h
33812 --- orig/arch/um/os-Linux/drivers/etap.h 1969-12-31 19:00:00.000000000 -0500
33813 +++ um/arch/um/os-Linux/drivers/etap.h 2003-10-21 03:26:07.000000000 -0400
33816 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
33817 + * Licensed under the GPL
33820 +#include "net_user.h"
33822 +struct ethertap_data {
33830 +extern struct net_user_info ethertap_user_info;
33833 + * Overrides for Emacs so that we follow Linus's tabbing style.
33834 + * Emacs will notice this stuff at the end of the file and automatically
33835 + * adjust the settings for this buffer only. This must remain at the end
33837 + * ---------------------------------------------------------------------------
33838 + * Local variables:
33839 + * c-file-style: "linux"
33842 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_kern.c um/arch/um/os-Linux/drivers/ethertap_kern.c
33843 --- orig/arch/um/os-Linux/drivers/ethertap_kern.c 1969-12-31 19:00:00.000000000 -0500
33844 +++ um/arch/um/os-Linux/drivers/ethertap_kern.c 2003-10-21 03:26:07.000000000 -0400
33847 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
33848 + * James Leu (jleu@mindspring.net).
33849 + * Copyright (C) 2001 by various other people who didn't put their name here.
33850 + * Licensed under the GPL.
33853 +#include "linux/init.h"
33854 +#include "linux/netdevice.h"
33855 +#include "linux/etherdevice.h"
33856 +#include "linux/init.h"
33857 +#include "net_kern.h"
33858 +#include "net_user.h"
33861 +struct ethertap_init {
33866 +static void etap_init(struct net_device *dev, void *data)
33868 + struct uml_net_private *pri;
33869 + struct ethertap_data *epri;
33870 + struct ethertap_init *init = data;
33872 + init_etherdev(dev, 0);
33874 + epri = (struct ethertap_data *) pri->user;
33875 + *epri = ((struct ethertap_data)
33876 + { .dev_name = init->dev_name,
33877 + .gate_addr = init->gate_addr,
33879 + .control_fd = -1,
33882 + printk("ethertap backend - %s", epri->dev_name);
33883 + if(epri->gate_addr != NULL)
33884 + printk(", IP = %s", epri->gate_addr);
33888 +static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
33892 + *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
33893 + if(*skb == NULL) return(-ENOMEM);
33894 + len = net_recvfrom(fd, (*skb)->mac.raw,
33895 + (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
33896 + if(len <= 0) return(len);
33897 + skb_pull(*skb, 2);
33902 +static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
33904 + if(skb_headroom(*skb) < 2){
33905 + struct sk_buff *skb2;
33907 + skb2 = skb_realloc_headroom(*skb, 2);
33908 + dev_kfree_skb(*skb);
33909 + if (skb2 == NULL) return(-ENOMEM);
33912 + skb_push(*skb, 2);
33913 + return(net_send(fd, (*skb)->data, (*skb)->len));
33916 +struct net_kern_info ethertap_kern_info = {
33917 + .init = etap_init,
33918 + .protocol = eth_protocol,
33919 + .read = etap_read,
33920 + .write = etap_write,
33923 +int ethertap_setup(char *str, char **mac_out, void *data)
33925 + struct ethertap_init *init = data;
33927 + *init = ((struct ethertap_init)
33928 + { .dev_name = NULL,
33929 + .gate_addr = NULL });
33930 + if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
33931 + &init->gate_addr))
33933 + if(init->dev_name == NULL){
33934 + printk("ethertap_setup : Missing tap device name\n");
33941 +static struct transport ethertap_transport = {
33942 + .list = LIST_HEAD_INIT(ethertap_transport.list),
33943 + .name = "ethertap",
33944 + .setup = ethertap_setup,
33945 + .user = ðertap_user_info,
33946 + .kern = ðertap_kern_info,
33947 + .private_size = sizeof(struct ethertap_data),
33950 +static int register_ethertap(void)
33952 + register_transport(ðertap_transport);
33956 +__initcall(register_ethertap);
33959 + * Overrides for Emacs so that we follow Linus's tabbing style.
33960 + * Emacs will notice this stuff at the end of the file and automatically
33961 + * adjust the settings for this buffer only. This must remain at the end
33963 + * ---------------------------------------------------------------------------
33964 + * Local variables:
33965 + * c-file-style: "linux"
33968 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_user.c um/arch/um/os-Linux/drivers/ethertap_user.c
33969 --- orig/arch/um/os-Linux/drivers/ethertap_user.c 1969-12-31 19:00:00.000000000 -0500
33970 +++ um/arch/um/os-Linux/drivers/ethertap_user.c 2003-10-21 03:26:07.000000000 -0400
33973 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
33974 + * James Leu (jleu@mindspring.net).
33975 + * Copyright (C) 2001 by various other people who didn't put their name here.
33976 + * Licensed under the GPL.
33979 +#include <stdio.h>
33980 +#include <unistd.h>
33981 +#include <stddef.h>
33982 +#include <stdlib.h>
33983 +#include <sys/errno.h>
33984 +#include <sys/socket.h>
33985 +#include <sys/wait.h>
33986 +#include <sys/un.h>
33987 +#include <net/if.h>
33989 +#include "kern_util.h"
33990 +#include "net_user.h"
33992 +#include "helper.h"
33995 +#define MAX_PACKET ETH_MAX_PACKET
33997 +void etap_user_init(void *data, void *dev)
33999 + struct ethertap_data *pri = data;
34004 +struct addr_change {
34005 + enum { ADD_ADDR, DEL_ADDR } what;
34006 + unsigned char addr[4];
34007 + unsigned char netmask[4];
34010 +static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
34013 + struct addr_change change;
34017 + change.what = op;
34018 + memcpy(change.addr, addr, sizeof(change.addr));
34019 + memcpy(change.netmask, netmask, sizeof(change.netmask));
34020 + n = os_write_file(fd, &change, sizeof(change));
34021 + if(n != sizeof(change))
34022 + printk("etap_change - request failed, err = %d\n", -n);
34023 + output = um_kmalloc(page_size());
34024 + if(output == NULL)
34025 + printk("etap_change : Failed to allocate output buffer\n");
34026 + read_output(fd, output, page_size());
34027 + if(output != NULL){
34028 + printk("%s", output);
34033 +static void etap_open_addr(unsigned char *addr, unsigned char *netmask,
34036 + etap_change(ADD_ADDR, addr, netmask, *((int *) arg));
34039 +static void etap_close_addr(unsigned char *addr, unsigned char *netmask,
34042 + etap_change(DEL_ADDR, addr, netmask, *((int *) arg));
34045 +struct etap_pre_exec_data {
34046 + int control_remote;
34051 +static void etap_pre_exec(void *arg)
34053 + struct etap_pre_exec_data *data = arg;
34055 + dup2(data->control_remote, 1);
34056 + os_close_file(data->data_me);
34057 + os_close_file(data->control_me);
34060 +static int etap_tramp(char *dev, char *gate, int control_me,
34061 + int control_remote, int data_me, int data_remote)
34063 + struct etap_pre_exec_data pe_data;
34064 + int pid, status, err, n;
34065 + char version_buf[sizeof("nnnnn\0")];
34066 + char data_fd_buf[sizeof("nnnnnn\0")];
34067 + char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
34068 + char *setup_args[] = { "uml_net", version_buf, "ethertap", dev,
34069 + data_fd_buf, gate_buf, NULL };
34070 + char *nosetup_args[] = { "uml_net", version_buf, "ethertap",
34071 + dev, data_fd_buf, NULL };
34074 + sprintf(data_fd_buf, "%d", data_remote);
34075 + sprintf(version_buf, "%d", UML_NET_VERSION);
34076 + if(gate != NULL){
34077 + strcpy(gate_buf, gate);
34078 + args = setup_args;
34080 + else args = nosetup_args;
34083 + pe_data.control_remote = control_remote;
34084 + pe_data.control_me = control_me;
34085 + pe_data.data_me = data_me;
34086 + pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
34088 + if(pid < 0) err = pid;
34089 + os_close_file(data_remote);
34090 + os_close_file(control_remote);
34091 + n = os_read_file(control_me, &c, sizeof(c));
34092 + if(n != sizeof(c)){
34093 + printk("etap_tramp : read of status failed, err = %d\n", -n);
34097 + printk("etap_tramp : uml_net failed\n");
34099 + if(waitpid(pid, &status, 0) < 0)
34101 + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
34102 + printk("uml_net didn't exit with status 1\n");
34107 +static int etap_open(void *data)
34109 + struct ethertap_data *pri = data;
34111 + int data_fds[2], control_fds[2], err, output_len;
34113 + err = tap_open_common(pri->dev, pri->gate_addr);
34114 + if(err) return(err);
34116 + err = os_pipe(data_fds, 0, 0);
34118 + printk("data os_pipe failed - err = %d\n", -err);
34122 + err = os_pipe(control_fds, 1, 0);
34124 + printk("control os_pipe failed - err = %d\n", -err);
34128 + err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
34129 + control_fds[1], data_fds[0], data_fds[1]);
34130 + output_len = page_size();
34131 + output = um_kmalloc(output_len);
34132 + read_output(control_fds[0], output, output_len);
34134 + if(output == NULL)
34135 + printk("etap_open : failed to allocate output buffer\n");
34137 + printk("%s", output);
34142 + printk("etap_tramp failed - err = %d\n", -err);
34146 + pri->data_fd = data_fds[0];
34147 + pri->control_fd = control_fds[0];
34148 + iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
34149 + return(data_fds[0]);
34152 +static void etap_close(int fd, void *data)
34154 + struct ethertap_data *pri = data;
34156 + iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
34157 + os_close_file(fd);
34158 + os_shutdown_socket(pri->data_fd, 1, 1);
34159 + os_close_file(pri->data_fd);
34160 + pri->data_fd = -1;
34161 + os_close_file(pri->control_fd);
34162 + pri->control_fd = -1;
34165 +static int etap_set_mtu(int mtu, void *data)
34170 +static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
34173 + struct ethertap_data *pri = data;
34175 + tap_check_ips(pri->gate_addr, addr);
34176 + if(pri->control_fd == -1) return;
34177 + etap_open_addr(addr, netmask, &pri->control_fd);
34180 +static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
34183 + struct ethertap_data *pri = data;
34185 + if(pri->control_fd == -1) return;
34186 + etap_close_addr(addr, netmask, &pri->control_fd);
34189 +struct net_user_info ethertap_user_info = {
34190 + .init = etap_user_init,
34191 + .open = etap_open,
34192 + .close = etap_close,
34194 + .set_mtu = etap_set_mtu,
34195 + .add_address = etap_add_addr,
34196 + .delete_address = etap_del_addr,
34197 + .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP
34201 + * Overrides for Emacs so that we follow Linus's tabbing style.
34202 + * Emacs will notice this stuff at the end of the file and automatically
34203 + * adjust the settings for this buffer only. This must remain at the end
34205 + * ---------------------------------------------------------------------------
34206 + * Local variables:
34207 + * c-file-style: "linux"
34210 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/Makefile um/arch/um/os-Linux/drivers/Makefile
34211 --- orig/arch/um/os-Linux/drivers/Makefile 1969-12-31 19:00:00.000000000 -0500
34212 +++ um/arch/um/os-Linux/drivers/Makefile 2003-10-21 03:26:07.000000000 -0400
34215 +# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
34216 +# Licensed under the GPL
34219 +O_TARGET := drivers.o
34221 +list-multi := tuntap.o ethertap.o
34223 +ethertap-objs := ethertap_kern.o ethertap_user.o
34224 +tuntap-objs := tuntap_kern.o tuntap_user.o
34227 +obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap.o
34228 +obj-$(CONFIG_UML_NET_TUNTAP) += tuntap.o
34230 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y)),$($(f)-objs))
34232 +USER_OBJS = $(filter %_user.o,$(obj-y) $(USER_SINGLE_OBJS))
34234 +include $(TOPDIR)/Rules.make
34236 +$(USER_OBJS) : %.o: %.c
34237 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
34239 +ethertap.o : $(ethertap-objs)
34241 +tuntap.o : $(tuntap-objs)
34243 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
34244 + $(LD) $(LD_RFLAG) -r -o $@ $($(patsubst %.o,%,$@)-objs)
34245 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap.h um/arch/um/os-Linux/drivers/tuntap.h
34246 --- orig/arch/um/os-Linux/drivers/tuntap.h 1969-12-31 19:00:00.000000000 -0500
34247 +++ um/arch/um/os-Linux/drivers/tuntap.h 2003-10-21 03:26:07.000000000 -0400
34250 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
34251 + * Licensed under the GPL
34254 +#ifndef __UM_TUNTAP_H
34255 +#define __UM_TUNTAP_H
34257 +#include "net_user.h"
34259 +struct tuntap_data {
34261 + int fixed_config;
34267 +extern struct net_user_info tuntap_user_info;
34272 + * Overrides for Emacs so that we follow Linus's tabbing style.
34273 + * Emacs will notice this stuff at the end of the file and automatically
34274 + * adjust the settings for this buffer only. This must remain at the end
34276 + * ---------------------------------------------------------------------------
34277 + * Local variables:
34278 + * c-file-style: "linux"
34281 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_kern.c um/arch/um/os-Linux/drivers/tuntap_kern.c
34282 --- orig/arch/um/os-Linux/drivers/tuntap_kern.c 1969-12-31 19:00:00.000000000 -0500
34283 +++ um/arch/um/os-Linux/drivers/tuntap_kern.c 2003-10-21 03:26:07.000000000 -0400
34286 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
34287 + * Licensed under the GPL
34290 +#include "linux/stddef.h"
34291 +#include "linux/netdevice.h"
34292 +#include "linux/etherdevice.h"
34293 +#include "linux/skbuff.h"
34294 +#include "linux/init.h"
34295 +#include "asm/errno.h"
34296 +#include "net_kern.h"
34297 +#include "net_user.h"
34298 +#include "tuntap.h"
34300 +struct tuntap_init {
34305 +static void tuntap_init(struct net_device *dev, void *data)
34307 + struct uml_net_private *pri;
34308 + struct tuntap_data *tpri;
34309 + struct tuntap_init *init = data;
34311 + init_etherdev(dev, 0);
34313 + tpri = (struct tuntap_data *) pri->user;
34314 + *tpri = ((struct tuntap_data)
34315 + { .dev_name = init->dev_name,
34316 + .fixed_config = (init->dev_name != NULL),
34317 + .gate_addr = init->gate_addr,
34320 + printk("TUN/TAP backend - ");
34321 + if(tpri->gate_addr != NULL)
34322 + printk("IP = %s", tpri->gate_addr);
34326 +static int tuntap_read(int fd, struct sk_buff **skb,
34327 + struct uml_net_private *lp)
34329 + *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
34330 + if(*skb == NULL) return(-ENOMEM);
34331 + return(net_read(fd, (*skb)->mac.raw,
34332 + (*skb)->dev->mtu + ETH_HEADER_OTHER));
34335 +static int tuntap_write(int fd, struct sk_buff **skb,
34336 + struct uml_net_private *lp)
34338 + return(net_write(fd, (*skb)->data, (*skb)->len));
34341 +struct net_kern_info tuntap_kern_info = {
34342 + .init = tuntap_init,
34343 + .protocol = eth_protocol,
34344 + .read = tuntap_read,
34345 + .write = tuntap_write,
34348 +int tuntap_setup(char *str, char **mac_out, void *data)
34350 + struct tuntap_init *init = data;
34352 + *init = ((struct tuntap_init)
34353 + { .dev_name = NULL,
34354 + .gate_addr = NULL });
34355 + if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
34356 + &init->gate_addr))
34362 +static struct transport tuntap_transport = {
34363 + .list = LIST_HEAD_INIT(tuntap_transport.list),
34364 + .name = "tuntap",
34365 + .setup = tuntap_setup,
34366 + .user = &tuntap_user_info,
34367 + .kern = &tuntap_kern_info,
34368 + .private_size = sizeof(struct tuntap_data),
34369 + .setup_size = sizeof(struct tuntap_init),
34372 +static int register_tuntap(void)
34374 + register_transport(&tuntap_transport);
34378 +__initcall(register_tuntap);
34381 + * Overrides for Emacs so that we follow Linus's tabbing style.
34382 + * Emacs will notice this stuff at the end of the file and automatically
34383 + * adjust the settings for this buffer only. This must remain at the end
34385 + * ---------------------------------------------------------------------------
34386 + * Local variables:
34387 + * c-file-style: "linux"
34390 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_user.c um/arch/um/os-Linux/drivers/tuntap_user.c
34391 --- orig/arch/um/os-Linux/drivers/tuntap_user.c 1969-12-31 19:00:00.000000000 -0500
34392 +++ um/arch/um/os-Linux/drivers/tuntap_user.c 2003-11-12 00:02:30.000000000 -0500
34395 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
34396 + * Licensed under the GPL
34399 +#include <stdio.h>
34400 +#include <stddef.h>
34401 +#include <stdlib.h>
34402 +#include <unistd.h>
34403 +#include <errno.h>
34404 +#include <sys/wait.h>
34405 +#include <sys/socket.h>
34406 +#include <sys/un.h>
34407 +#include <sys/uio.h>
34408 +#include <sys/ioctl.h>
34409 +#include <net/if.h>
34410 +#include <linux/if_tun.h>
34411 +#include "net_user.h"
34412 +#include "tuntap.h"
34413 +#include "kern_util.h"
34415 +#include "helper.h"
34418 +#define MAX_PACKET ETH_MAX_PACKET
34420 +void tuntap_user_init(void *data, void *dev)
34422 + struct tuntap_data *pri = data;
34427 +static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
34430 + struct tuntap_data *pri = data;
34432 + tap_check_ips(pri->gate_addr, addr);
34433 + if((pri->fd == -1) || pri->fixed_config) return;
34434 + open_addr(addr, netmask, pri->dev_name);
34437 +static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
34440 + struct tuntap_data *pri = data;
34442 + if((pri->fd == -1) || pri->fixed_config) return;
34443 + close_addr(addr, netmask, pri->dev_name);
34446 +struct tuntap_pre_exec_data {
34451 +static void tuntap_pre_exec(void *arg)
34453 + struct tuntap_pre_exec_data *data = arg;
34455 + dup2(data->stdout, 1);
34456 + os_close_file(data->close_me);
34459 +static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
34460 + char *buffer, int buffer_len, int *used_out)
34462 + struct tuntap_pre_exec_data data;
34463 + char version_buf[sizeof("nnnnn\0")];
34464 + char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate,
34466 + char buf[CMSG_SPACE(sizeof(*fd_out))];
34467 + struct msghdr msg;
34468 + struct cmsghdr *cmsg;
34469 + struct iovec iov;
34472 + sprintf(version_buf, "%d", UML_NET_VERSION);
34474 + data.stdout = remote;
34475 + data.close_me = me;
34477 + pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
34479 + if(pid < 0) return(-pid);
34481 + os_close_file(remote);
34483 + msg.msg_name = NULL;
34484 + msg.msg_namelen = 0;
34485 + if(buffer != NULL){
34486 + iov = ((struct iovec) { buffer, buffer_len });
34487 + msg.msg_iov = &iov;
34488 + msg.msg_iovlen = 1;
34491 + msg.msg_iov = NULL;
34492 + msg.msg_iovlen = 0;
34494 + msg.msg_control = buf;
34495 + msg.msg_controllen = sizeof(buf);
34496 + msg.msg_flags = 0;
34497 + n = recvmsg(me, &msg, 0);
34500 + printk("tuntap_open_tramp : recvmsg failed - errno = %d\n",
34504 + waitpid(pid, NULL, 0);
34506 + cmsg = CMSG_FIRSTHDR(&msg);
34507 + if(cmsg == NULL){
34508 + printk("tuntap_open_tramp : didn't receive a message\n");
34511 + if((cmsg->cmsg_level != SOL_SOCKET) ||
34512 + (cmsg->cmsg_type != SCM_RIGHTS)){
34513 + printk("tuntap_open_tramp : didn't receive a descriptor\n");
34516 + *fd_out = ((int *) CMSG_DATA(cmsg))[0];
34520 +static int tuntap_open(void *data)
34522 + struct ifreq ifr;
34523 + struct tuntap_data *pri = data;
34524 + char *output, *buffer;
34525 + int err, fds[2], len, used;
34527 + err = tap_open_common(pri->dev, pri->gate_addr);
34531 + if(pri->fixed_config){
34532 + pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
34534 + printk("Failed to open /dev/net/tun, err = %d\n",
34538 + memset(&ifr, 0, sizeof(ifr));
34539 + ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
34540 + strncpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name) - 1);
34541 + if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
34542 + printk("TUNSETIFF failed, errno = %d\n", errno);
34543 + os_close_file(pri->fd);
34548 + err = os_pipe(fds, 0, 0);
34550 + printk("tuntap_open : os_pipe failed - err = %d\n",
34555 + buffer = get_output_buffer(&len);
34556 + if(buffer != NULL) len--;
34559 + err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
34560 + fds[1], buffer, len, &used);
34564 + printk("%s", output);
34565 + free_output_buffer(buffer);
34566 + printk("tuntap_open_tramp failed - err = %d\n", -err);
34570 + pri->dev_name = uml_strdup(buffer);
34571 + output += IFNAMSIZ;
34572 + printk("%s", output);
34573 + free_output_buffer(buffer);
34575 + os_close_file(fds[0]);
34576 + iter_addresses(pri->dev, open_addr, pri->dev_name);
34582 +static void tuntap_close(int fd, void *data)
34584 + struct tuntap_data *pri = data;
34586 + if(!pri->fixed_config)
34587 + iter_addresses(pri->dev, close_addr, pri->dev_name);
34588 + os_close_file(fd);
34592 +static int tuntap_set_mtu(int mtu, void *data)
34597 +struct net_user_info tuntap_user_info = {
34598 + .init = tuntap_user_init,
34599 + .open = tuntap_open,
34600 + .close = tuntap_close,
34602 + .set_mtu = tuntap_set_mtu,
34603 + .add_address = tuntap_add_addr,
34604 + .delete_address = tuntap_del_addr,
34605 + .max_packet = MAX_PACKET
34609 + * Overrides for Emacs so that we follow Linus's tabbing style.
34610 + * Emacs will notice this stuff at the end of the file and automatically
34611 + * adjust the settings for this buffer only. This must remain at the end
34613 + * ---------------------------------------------------------------------------
34614 + * Local variables:
34615 + * c-file-style: "linux"
34618 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/file.c um/arch/um/os-Linux/file.c
34619 --- orig/arch/um/os-Linux/file.c 1969-12-31 19:00:00.000000000 -0500
34620 +++ um/arch/um/os-Linux/file.c 2003-11-30 20:18:39.000000000 -0500
34623 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34624 + * Licensed under the GPL
34627 +#include <stdio.h>
34628 +#include <unistd.h>
34629 +#include <errno.h>
34630 +#include <fcntl.h>
34631 +#include <signal.h>
34632 +#include <sys/types.h>
34633 +#include <sys/stat.h>
34634 +#include <sys/socket.h>
34635 +#include <sys/un.h>
34636 +#include <sys/ioctl.h>
34637 +#include <sys/mount.h>
34638 +#include <sys/uio.h>
34641 +#include "kern_util.h"
34643 +static void copy_stat(struct uml_stat *dst, struct stat64 *src)
34645 + *dst = ((struct uml_stat) {
34646 + .ust_dev = src->st_dev, /* device */
34647 + .ust_ino = src->st_ino, /* inode */
34648 + .ust_mode = src->st_mode, /* protection */
34649 + .ust_nlink = src->st_nlink, /* number of hard links */
34650 + .ust_uid = src->st_uid, /* user ID of owner */
34651 + .ust_gid = src->st_gid, /* group ID of owner */
34652 + .ust_size = src->st_size, /* total size, in bytes */
34653 + .ust_blksize = src->st_blksize, /* blocksize for filesys I/O */
34654 + .ust_blocks = src->st_blocks, /* number of blocks allocated */
34655 + .ust_atime = src->st_atime, /* time of last access */
34656 + .ust_mtime = src->st_mtime, /* time of last modification */
34657 + .ust_ctime = src->st_ctime, /* time of last change */
34661 +int os_stat_fd(const int fd, struct uml_stat *ubuf)
34663 + struct stat64 sbuf;
34667 + err = fstat64(fd, &sbuf);
34668 + } while((err < 0) && (errno == EINTR)) ;
34674 + copy_stat(ubuf, &sbuf);
34678 +int os_stat_file(const char *file_name, struct uml_stat *ubuf)
34680 + struct stat64 sbuf;
34684 + err = stat64(file_name, &sbuf);
34685 + } while((err < 0) && (errno == EINTR)) ;
34691 + copy_stat(ubuf, &sbuf);
34695 +int os_access(const char* file, int mode)
34699 + amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) |
34700 + (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ;
34702 + err = access(file, amode);
34709 +void os_print_error(int error, const char* str)
34711 + errno = error < 0 ? -error : error;
34716 +/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
34717 +int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
34721 + err = ioctl(fd, cmd, arg);
34728 +int os_window_size(int fd, int *rows, int *cols)
34730 + struct winsize size;
34732 + if(ioctl(fd, TIOCGWINSZ, &size) < 0)
34735 + *rows = size.ws_row;
34736 + *cols = size.ws_col;
34741 +int os_new_tty_pgrp(int fd, int pid)
34743 + if(ioctl(fd, TIOCSCTTY, 0) < 0){
34744 + printk("TIOCSCTTY failed, errno = %d\n", errno);
34748 + if(tcsetpgrp(fd, pid) < 0){
34749 + printk("tcsetpgrp failed, errno = %d\n", errno);
34756 +/* FIXME: ensure namebuf in os_get_if_name is big enough */
34757 +int os_get_ifname(int fd, char* namebuf)
34759 + if(ioctl(fd, SIOCGIFNAME, namebuf) < 0)
34765 +int os_set_slip(int fd)
34767 + int disc, sencap;
34770 + if(ioctl(fd, TIOCSETD, &disc) < 0){
34771 + printk("Failed to set slip line discipline - "
34772 + "errno = %d\n", errno);
34777 + if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){
34778 + printk("Failed to set slip encapsulation - "
34779 + "errno = %d\n", errno);
34786 +int os_set_owner(int fd, int pid)
34788 + if(fcntl(fd, F_SETOWN, pid) < 0){
34789 + int save_errno = errno;
34791 + if(fcntl(fd, F_GETOWN, 0) != pid){
34792 + return(-save_errno);
34799 +/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */
34800 +int os_sigio_async(int master, int slave)
34804 + flags = fcntl(master, F_GETFL);
34806 + printk("fcntl F_GETFL failed, errno = %d\n", errno);
34810 + if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
34811 + (fcntl(master, F_SETOWN, os_getpid()) < 0)){
34812 + printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", errno);
34816 + if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){
34817 + printk("fcntl F_SETFL failed, errno = %d\n", errno);
34824 +int os_mode_fd(int fd, int mode)
34829 + err = fchmod(fd, mode);
34830 + } while((err < 0) && (errno==EINTR)) ;
34838 +int os_file_type(char *file)
34840 + struct uml_stat buf;
34843 + err = os_stat_file(file, &buf);
34847 + if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR);
34848 + else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK);
34849 + else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV);
34850 + else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV);
34851 + else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO);
34852 + else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK);
34853 + else return(OS_TYPE_FILE);
34856 +int os_file_mode(char *file, struct openflags *mode_out)
34860 + *mode_out = OPENFLAGS();
34862 + err = os_access(file, OS_ACC_W_OK);
34863 + if((err < 0) && (err != -EACCES))
34866 + *mode_out = of_write(*mode_out);
34868 + err = os_access(file, OS_ACC_R_OK);
34869 + if((err < 0) && (err != -EACCES))
34872 + *mode_out = of_read(*mode_out);
34877 +int os_open_file(char *file, struct openflags flags, int mode)
34881 + if(flags.r && flags.w) f = O_RDWR;
34882 + else if(flags.r) f = O_RDONLY;
34883 + else if(flags.w) f = O_WRONLY;
34886 + if(flags.s) f |= O_SYNC;
34887 + if(flags.c) f |= O_CREAT;
34888 + if(flags.t) f |= O_TRUNC;
34889 + if(flags.e) f |= O_EXCL;
34891 + fd = open64(file, f, mode);
34895 + if(flags.cl && fcntl(fd, F_SETFD, 1)){
34896 + os_close_file(fd);
34903 +int os_connect_socket(char *name)
34905 + struct sockaddr_un sock;
34908 + sock.sun_family = AF_UNIX;
34909 + snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
34911 + fd = socket(AF_UNIX, SOCK_STREAM, 0);
34915 + err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
34922 +void os_close_file(int fd)
34927 +int os_seek_file(int fd, __u64 offset)
34931 + actual = lseek64(fd, offset, SEEK_SET);
34932 + if(actual != offset) return(-errno);
34936 +static int fault_buffer(void *start, int len,
34937 + int (*copy_proc)(void *addr, void *buf, int len))
34939 + int page = getpagesize(), i;
34942 + for(i = 0; i < len; i += page){
34943 + if((*copy_proc)(start + i, &c, sizeof(c)))
34946 + if((len % page) != 0){
34947 + if((*copy_proc)(start + len - 1, &c, sizeof(c)))
34953 +static int file_io(int fd, void *buf, int len,
34954 + int (*io_proc)(int fd, void *buf, int len),
34955 + int (*copy_user_proc)(void *addr, void *buf, int len))
34960 + n = (*io_proc)(fd, buf, len);
34961 + if((n < 0) && (errno == EFAULT)){
34962 + err = fault_buffer(buf, len, copy_user_proc);
34965 + n = (*io_proc)(fd, buf, len);
34967 + } while((n < 0) && (errno == EINTR));
34974 +int os_read_file(int fd, void *buf, int len)
34976 + return(file_io(fd, buf, len, (int (*)(int, void *, int)) read,
34977 + copy_from_user_proc));
34980 +int os_write_file(int fd, const void *buf, int len)
34982 + return(file_io(fd, (void *) buf, len,
34983 + (int (*)(int, void *, int)) write, copy_to_user_proc));
34986 +int os_file_size(char *file, long long *size_out)
34988 + struct uml_stat buf;
34991 + err = os_stat_file(file, &buf);
34993 + printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
34997 + if(S_ISBLK(buf.ust_mode)){
35000 + fd = os_open_file(file, of_read(OPENFLAGS()), 0);
35002 + printk("Couldn't open \"%s\", errno = %d\n", file, -fd);
35005 + if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
35006 + printk("Couldn't get the block size of \"%s\", "
35007 + "errno = %d\n", file, errno);
35009 + os_close_file(fd);
35012 + *size_out = ((long long) blocks) * 512;
35013 + os_close_file(fd);
35016 + *size_out = buf.ust_size;
35020 +int os_file_modtime(char *file, unsigned long *modtime)
35022 + struct uml_stat buf;
35025 + err = os_stat_file(file, &buf);
35027 + printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
35031 + *modtime = buf.ust_mtime;
35035 +int os_get_exec_close(int fd, int* close_on_exec)
35040 + ret = fcntl(fd, F_GETFD);
35041 + } while((ret < 0) && (errno == EINTR)) ;
35046 + *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0;
35050 +int os_set_exec_close(int fd, int close_on_exec)
35054 + if(close_on_exec) flag = FD_CLOEXEC;
35058 + err = fcntl(fd, F_SETFD, flag);
35059 + } while((err < 0) && (errno == EINTR)) ;
35066 +int os_pipe(int *fds, int stream, int close_on_exec)
35068 + int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
35070 + err = socketpair(AF_UNIX, type, 0, fds);
35074 + if(!close_on_exec)
35077 + err = os_set_exec_close(fds[0], 1);
35081 + err = os_set_exec_close(fds[1], 1);
35088 + printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
35089 + os_close_file(fds[1]);
35090 + os_close_file(fds[0]);
35094 +int os_set_fd_async(int fd, int owner)
35096 + /* XXX This should do F_GETFL first */
35097 + if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){
35098 + printk("os_set_fd_async : failed to set O_ASYNC and "
35099 + "O_NONBLOCK on fd # %d, errno = %d\n", fd, errno);
35103 + if(fcntl(fd, F_SETFD, 1) < 0){
35104 + printk("os_set_fd_async : Setting FD_CLOEXEC failed, "
35105 + "errno = %d\n", errno);
35109 + if((fcntl(fd, F_SETSIG, SIGIO) < 0) ||
35110 + (fcntl(fd, F_SETOWN, owner) < 0)){
35111 + printk("os_set_fd_async : Failed to fcntl F_SETOWN "
35112 + "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd,
35120 +int os_set_fd_block(int fd, int blocking)
35124 + flags = fcntl(fd, F_GETFL);
35126 + if(blocking) flags &= ~O_NONBLOCK;
35127 + else flags |= O_NONBLOCK;
35129 + if(fcntl(fd, F_SETFL, flags) < 0){
35130 + printk("Failed to change blocking on fd # %d, errno = %d\n",
35137 +int os_accept_connection(int fd)
35141 + new = accept(fd, NULL, 0);
35156 +#define SHUT_RDWR 2
35159 +int os_shutdown_socket(int fd, int r, int w)
35163 + if(r && w) what = SHUT_RDWR;
35164 + else if(r) what = SHUT_RD;
35165 + else if(w) what = SHUT_WR;
35167 + printk("os_shutdown_socket : neither r or w was set\n");
35170 + err = shutdown(fd, what);
35176 +int os_rcv_fd(int fd, int *helper_pid_out)
35179 + char buf[CMSG_SPACE(sizeof(new))];
35180 + struct msghdr msg;
35181 + struct cmsghdr *cmsg;
35182 + struct iovec iov;
35184 + msg.msg_name = NULL;
35185 + msg.msg_namelen = 0;
35186 + iov = ((struct iovec) { .iov_base = helper_pid_out,
35187 + .iov_len = sizeof(*helper_pid_out) });
35188 + msg.msg_iov = &iov;
35189 + msg.msg_iovlen = 1;
35190 + msg.msg_control = buf;
35191 + msg.msg_controllen = sizeof(buf);
35192 + msg.msg_flags = 0;
35194 + n = recvmsg(fd, &msg, 0);
35198 + else if(n != sizeof(iov.iov_len))
35199 + *helper_pid_out = -1;
35201 + cmsg = CMSG_FIRSTHDR(&msg);
35202 + if(cmsg == NULL){
35203 + printk("rcv_fd didn't receive anything, error = %d\n", errno);
35206 + if((cmsg->cmsg_level != SOL_SOCKET) ||
35207 + (cmsg->cmsg_type != SCM_RIGHTS)){
35208 + printk("rcv_fd didn't receive a descriptor\n");
35212 + new = ((int *) CMSG_DATA(cmsg))[0];
35216 +int os_create_unix_socket(char *file, int len, int close_on_exec)
35218 + struct sockaddr_un addr;
35221 + sock = socket(PF_UNIX, SOCK_DGRAM, 0);
35223 + printk("create_unix_socket - socket failed, errno = %d\n",
35228 + if(close_on_exec) {
35229 + err = os_set_exec_close(sock, 1);
35231 + printk("create_unix_socket : close_on_exec failed, "
35232 + "err = %d", -err);
35235 + addr.sun_family = AF_UNIX;
35237 + /* XXX Be more careful about overflow */
35238 + snprintf(addr.sun_path, len, "%s", file);
35240 + err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
35242 + printk("create_listening_socket at '%s' - bind failed, "
35243 + "errno = %d\n", file, errno);
35250 +void os_flush_stdout(void)
35255 +int os_lock_file(int fd, int excl)
35257 + int type = excl ? F_WRLCK : F_RDLCK;
35258 + struct flock lock = ((struct flock) { .l_type = type,
35259 + .l_whence = SEEK_SET,
35264 + err = fcntl(fd, F_SETLK, &lock);
35269 + err = fcntl(fd, F_GETLK, &lock);
35275 + printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
35282 + * Overrides for Emacs so that we follow Linus's tabbing style.
35283 + * Emacs will notice this stuff at the end of the file and automatically
35284 + * adjust the settings for this buffer only. This must remain at the end
35286 + * ---------------------------------------------------------------------------
35287 + * Local variables:
35288 + * c-file-style: "linux"
35291 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/include/file.h um/arch/um/os-Linux/include/file.h
35292 --- orig/arch/um/os-Linux/include/file.h 1969-12-31 19:00:00.000000000 -0500
35293 +++ um/arch/um/os-Linux/include/file.h 2003-10-21 03:26:07.000000000 -0400
35296 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
35297 + * Licensed under the GPL
35300 +#ifndef __OS_FILE_H__
35301 +#define __OS_FILE_H__
35303 +#define DEV_NULL "/dev/null"
35308 + * Overrides for Emacs so that we follow Linus's tabbing style.
35309 + * Emacs will notice this stuff at the end of the file and automatically
35310 + * adjust the settings for this buffer only. This must remain at the end
35312 + * ---------------------------------------------------------------------------
35313 + * Local variables:
35314 + * c-file-style: "linux"
35317 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/Makefile um/arch/um/os-Linux/Makefile
35318 --- orig/arch/um/os-Linux/Makefile 1969-12-31 19:00:00.000000000 -0500
35319 +++ um/arch/um/os-Linux/Makefile 2003-10-21 03:26:07.000000000 -0400
35322 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
35323 +# Licensed under the GPL
35326 +O_TARGET = built-in.o
35328 +obj-y = file.o process.o tty.o
35330 +include $(TOPDIR)/Rules.make
35332 +$(obj-y) : %.o: %.c
35333 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
35338 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/process.c um/arch/um/os-Linux/process.c
35339 --- orig/arch/um/os-Linux/process.c 1969-12-31 19:00:00.000000000 -0500
35340 +++ um/arch/um/os-Linux/process.c 2003-12-18 03:08:34.000000000 -0500
35343 + * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
35344 + * Licensed under the GPL
35347 +#include <unistd.h>
35348 +#include <stdio.h>
35349 +#include <errno.h>
35350 +#include <signal.h>
35351 +#include <sys/mman.h>
35352 +#include <sys/wait.h>
35356 +#define ARBITRARY_ADDR -1
35357 +#define FAILURE_PID -1
35359 +unsigned long os_process_pc(int pid)
35361 + char proc_stat[sizeof("/proc/#####/stat\0")], buf[256];
35362 + unsigned long pc;
35365 + sprintf(proc_stat, "/proc/%d/stat", pid);
35366 + fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
35368 + printk("os_process_pc - couldn't open '%s', err = %d\n",
35370 + return(ARBITRARY_ADDR);
35372 + err = os_read_file(fd, buf, sizeof(buf));
35374 + printk("os_process_pc - couldn't read '%s', err = %d\n",
35375 + proc_stat, -err);
35376 + os_close_file(fd);
35377 + return(ARBITRARY_ADDR);
35379 + os_close_file(fd);
35380 + pc = ARBITRARY_ADDR;
35381 + if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d "
35382 + "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
35383 + "%*d %*d %*d %*d %ld", &pc) != 1){
35384 + printk("os_process_pc - couldn't find pc in '%s'\n", buf);
35389 +int os_process_parent(int pid)
35391 + char stat[sizeof("/proc/nnnnn/stat\0")];
35393 + int parent, n, fd;
35395 + if(pid == -1) return(-1);
35397 + snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
35398 + fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
35400 + printk("Couldn't open '%s', err = %d\n", stat, -fd);
35401 + return(FAILURE_PID);
35404 + n = os_read_file(fd, data, sizeof(data));
35405 + os_close_file(fd);
35408 + printk("Couldn't read '%s', err = %d\n", stat, -n);
35409 + return(FAILURE_PID);
35412 + parent = FAILURE_PID;
35413 + /* XXX This will break if there is a space in the command */
35414 + n = sscanf(data, "%*d %*s %*c %d", &parent);
35416 + printk("Failed to scan '%s'\n", data);
35421 +void os_stop_process(int pid)
35423 + kill(pid, SIGSTOP);
35426 +void os_kill_process(int pid, int reap_child)
35428 + kill(pid, SIGKILL);
35430 + waitpid(pid, NULL, 0);
35434 +void os_usr1_process(int pid)
35436 + kill(pid, SIGUSR1);
35439 +int os_getpid(void)
35441 + return(getpid());
35444 +int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
35445 + int r, int w, int x)
35450 + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
35451 + (x ? PROT_EXEC : 0);
35453 + loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
35455 + if(loc == MAP_FAILED)
35460 +int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
35462 + int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
35463 + (x ? PROT_EXEC : 0));
35465 + if(mprotect(addr, len, prot) < 0)
35470 +int os_unmap_memory(void *addr, int len)
35474 + err = munmap(addr, len);
35481 + * Overrides for Emacs so that we follow Linus's tabbing style.
35482 + * Emacs will notice this stuff at the end of the file and automatically
35483 + * adjust the settings for this buffer only. This must remain at the end
35485 + * ---------------------------------------------------------------------------
35486 + * Local variables:
35487 + * c-file-style: "linux"
35490 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/tty.c um/arch/um/os-Linux/tty.c
35491 --- orig/arch/um/os-Linux/tty.c 1969-12-31 19:00:00.000000000 -0500
35492 +++ um/arch/um/os-Linux/tty.c 2003-10-21 03:26:07.000000000 -0400
35495 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
35496 + * Licensed under the GPL
35499 +#include <stdlib.h>
35500 +#include <errno.h>
35503 +#include "kern_util.h"
35505 +struct grantpt_info {
35511 +static void grantpt_cb(void *arg)
35513 + struct grantpt_info *info = arg;
35515 + info->res = grantpt(info->fd);
35516 + info->err = errno;
35521 + struct grantpt_info info;
35524 + fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0);
35526 + printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd);
35531 + initial_thread_cb(grantpt_cb, &info);
35533 + if(info.res < 0){
35534 + printk("get_pty : Couldn't grant pty - errno = %d\n",
35538 + if(unlockpt(fd) < 0){
35539 + printk("get_pty : Couldn't unlock pty - errno = %d\n", errno);
35546 + * Overrides for Emacs so that we follow Linus's tabbing style.
35547 + * Emacs will notice this stuff at the end of the file and automatically
35548 + * adjust the settings for this buffer only. This must remain at the end
35550 + * ---------------------------------------------------------------------------
35551 + * Local variables:
35552 + * c-file-style: "linux"
35555 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/bugs.c um/arch/um/sys-i386/bugs.c
35556 --- orig/arch/um/sys-i386/bugs.c 1969-12-31 19:00:00.000000000 -0500
35557 +++ um/arch/um/sys-i386/bugs.c 2003-11-15 02:54:48.000000000 -0500
35560 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
35561 + * Licensed under the GPL
35564 +#include <unistd.h>
35565 +#include <errno.h>
35566 +#include <string.h>
35567 +#include <sys/signal.h>
35568 +#include <asm/ldt.h>
35569 +#include "kern_util.h"
35571 +#include "sysdep/ptrace.h"
35575 +#define MAXTOKEN 64
35577 +/* Set during early boot */
35578 +int cpu_has_cmov = 1;
35579 +int cpu_has_xmm = 0;
35581 +static char token(int fd, char *buf, int len, char stop)
35584 + char *ptr, *end, c;
35589 + n = os_read_file(fd, ptr, sizeof(*ptr));
35591 + if(n != sizeof(*ptr)){
35592 + if(n == 0) return(0);
35593 + printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
35599 + } while((c != '\n') && (c != stop) && (ptr < end));
35602 + printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
35605 + *(ptr - 1) = '\0';
35609 +static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
35614 + scratch[len - 1] = '\0';
35616 + c = token(fd, scratch, len - 1, ':');
35619 + else if(c != ':'){
35620 + printk("Failed to find ':' in /proc/cpuinfo\n");
35624 + if(!strncmp(scratch, key, strlen(key)))
35628 + n = os_read_file(fd, &c, sizeof(c));
35629 + if(n != sizeof(c)){
35630 + printk("Failed to find newline in "
35631 + "/proc/cpuinfo, err = %d\n", -n);
35634 + } while(c != '\n');
35639 +int cpu_feature(char *what, char *buf, int len)
35643 + fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
35645 + printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
35649 + if(!find_cpuinfo_line(fd, what, buf, len)){
35650 + printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
35654 + token(fd, buf, len, '\n');
35658 + os_close_file(fd);
35662 +static int check_cpu_flag(char *feature, int *have_it)
35664 + char buf[MAXTOKEN], c;
35665 + int fd, len = sizeof(buf)/sizeof(buf[0]);
35667 + printk("Checking for host processor %s support...", feature);
35668 + fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
35670 + printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
35675 + if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0])))
35678 + c = token(fd, buf, len - 1, ' ');
35679 + if(c < 0) goto out;
35680 + else if(c != ' '){
35681 + printk("Failed to find ' ' in /proc/cpuinfo\n");
35686 + c = token(fd, buf, len - 1, ' ');
35687 + if(c < 0) goto out;
35688 + else if(c == '\n') break;
35690 + if(!strcmp(buf, feature)){
35696 + if(*have_it == 0) printk("No\n");
35697 + else if(*have_it == 1) printk("Yes\n");
35698 + os_close_file(fd);
35702 +#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems
35703 + * for some people.
35705 +static void disable_lcall(void)
35707 + struct modify_ldt_ldt_s ldt;
35710 + bzero(&ldt, sizeof(ldt));
35711 + ldt.entry_number = 7;
35712 + ldt.base_addr = 0;
35714 + err = modify_ldt(1, &ldt, sizeof(ldt));
35716 + printk("Failed to disable lcall7 - errno = %d\n", errno);
35720 +void arch_init_thread(void)
35727 +void arch_check_bugs(void)
35731 + if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){
35732 + printk("/proc/cpuinfo not available - skipping CPU capability "
35736 + if(check_cpu_flag("cmov", &have_it))
35737 + cpu_has_cmov = have_it;
35738 + if(check_cpu_flag("xmm", &have_it))
35739 + cpu_has_xmm = have_it;
35742 +int arch_handle_signal(int sig, union uml_pt_regs *regs)
35744 + unsigned long ip;
35746 + /* This is testing for a cmov (0x0f 0x4x) instruction causing a
35747 + * SIGILL in init.
35749 + if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0);
35751 + ip = UPT_IP(regs);
35752 + if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
35755 + if(cpu_has_cmov == 0)
35756 + panic("SIGILL caused by cmov, which this processor doesn't "
35757 + "implement, boot a filesystem compiled for older "
35759 + else if(cpu_has_cmov == 1)
35760 + panic("SIGILL caused by cmov, which this processor claims to "
35762 + else if(cpu_has_cmov == -1)
35763 + panic("SIGILL caused by cmov, couldn't tell if this processor "
35764 + "implements it, boot a filesystem compiled for older "
35766 + else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
35771 + * Overrides for Emacs so that we follow Linus's tabbing style.
35772 + * Emacs will notice this stuff at the end of the file and automatically
35773 + * adjust the settings for this buffer only. This must remain at the end
35775 + * ---------------------------------------------------------------------------
35776 + * Local variables:
35777 + * c-file-style: "linux"
35780 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/checksum.S um/arch/um/sys-i386/checksum.S
35781 --- orig/arch/um/sys-i386/checksum.S 1969-12-31 19:00:00.000000000 -0500
35782 +++ um/arch/um/sys-i386/checksum.S 2003-10-21 03:26:07.000000000 -0400
35785 + * INET An implementation of the TCP/IP protocol suite for the LINUX
35786 + * operating system. INET is implemented using the BSD Socket
35787 + * interface as the means of communication with the user level.
35789 + * IP/TCP/UDP checksumming routines
35791 + * Authors: Jorge Cwik, <jorge@laser.satlink.net>
35792 + * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
35793 + * Tom May, <ftom@netcom.com>
35794 + * Pentium Pro/II routines:
35795 + * Alexander Kjeldaas <astor@guardian.no>
35796 + * Finn Arne Gangstad <finnag@guardian.no>
35797 + * Lots of code moved from tcp.c and ip.c; see those files
35798 + * for more names.
35800 + * Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception
35802 + * Andi Kleen, add zeroing on error
35803 + * converted to pure assembler
35805 + * This program is free software; you can redistribute it and/or
35806 + * modify it under the terms of the GNU General Public License
35807 + * as published by the Free Software Foundation; either version
35808 + * 2 of the License, or (at your option) any later version.
35811 +#include <linux/config.h>
35812 +#include <asm/errno.h>
35815 + * computes a partial checksum, e.g. for TCP/UDP fragments
35819 +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
35824 +.globl arch_csum_partial
35826 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
35829 + * Experiments with Ethernet and SLIP connections show that buff
35830 + * is aligned on either a 2-byte or 4-byte boundary. We get at
35831 + * least a twofold speedup on 486 and Pentium if it is 4-byte aligned.
35832 + * Fortunately, it is easy to convert 2-byte alignment to 4-byte
35833 + * alignment for the unrolled loop.
35835 +arch_csum_partial:
35838 + movl 20(%esp),%eax # Function arg: unsigned int sum
35839 + movl 16(%esp),%ecx # Function arg: int len
35840 + movl 12(%esp),%esi # Function arg: unsigned char *buff
35841 + testl $2, %esi # Check alignment.
35842 + jz 2f # Jump if alignment is ok.
35843 + subl $2, %ecx # Alignment uses up two bytes.
35844 + jae 1f # Jump if we had at least two bytes.
35845 + addl $2, %ecx # ecx was < 2. Deal with it.
35847 +1: movw (%esi), %bx
35856 +1: movl (%esi), %ebx
35858 + movl 4(%esi), %ebx
35860 + movl 8(%esi), %ebx
35862 + movl 12(%esi), %ebx
35864 + movl 16(%esi), %ebx
35866 + movl 20(%esi), %ebx
35868 + movl 24(%esi), %ebx
35870 + movl 28(%esi), %ebx
35872 + lea 32(%esi), %esi
35876 +2: movl %edx, %ecx
35879 + shrl $2, %edx # This clears CF
35880 +3: adcl (%esi), %eax
35881 + lea 4(%esi), %esi
35890 + leal 2(%esi),%esi
35893 +5: movb (%esi),%cl
35903 +/* Version for PentiumII/PPro */
35905 +arch_csum_partial:
35908 + movl 20(%esp),%eax # Function arg: unsigned int sum
35909 + movl 16(%esp),%ecx # Function arg: int len
35910 + movl 12(%esp),%esi # Function arg: const unsigned char *buf
35922 + lea 45f(%ebx,%ebx,2), %ebx
35926 + # Handle 2-byte-aligned regions
35927 +20: addw (%esi), %ax
35928 + lea 2(%esi), %esi
35935 + movzbl (%esi),%ebx # csumming 1 byte, 2-aligned
35940 + addw (%esi), %ax # csumming 2 bytes, 2-aligned
35945 + addl -128(%esi), %eax
35946 + adcl -124(%esi), %eax
35947 + adcl -120(%esi), %eax
35948 + adcl -116(%esi), %eax
35949 + adcl -112(%esi), %eax
35950 + adcl -108(%esi), %eax
35951 + adcl -104(%esi), %eax
35952 + adcl -100(%esi), %eax
35953 + adcl -96(%esi), %eax
35954 + adcl -92(%esi), %eax
35955 + adcl -88(%esi), %eax
35956 + adcl -84(%esi), %eax
35957 + adcl -80(%esi), %eax
35958 + adcl -76(%esi), %eax
35959 + adcl -72(%esi), %eax
35960 + adcl -68(%esi), %eax
35961 + adcl -64(%esi), %eax
35962 + adcl -60(%esi), %eax
35963 + adcl -56(%esi), %eax
35964 + adcl -52(%esi), %eax
35965 + adcl -48(%esi), %eax
35966 + adcl -44(%esi), %eax
35967 + adcl -40(%esi), %eax
35968 + adcl -36(%esi), %eax
35969 + adcl -32(%esi), %eax
35970 + adcl -28(%esi), %eax
35971 + adcl -24(%esi), %eax
35972 + adcl -20(%esi), %eax
35973 + adcl -16(%esi), %eax
35974 + adcl -12(%esi), %eax
35975 + adcl -8(%esi), %eax
35976 + adcl -4(%esi), %eax
35978 + lea 128(%esi), %esi
35986 + # Handle the last 1-3 bytes without jumping
35987 + notl %ecx # 1->2, 2->1, 3->0, higher bits are masked
35988 + movl $0xffffff,%ebx # by the shll and shrl instructions
35991 + andl -128(%esi),%ebx # esi is 4-aligned so should be ok
36002 +unsigned int csum_partial_copy_generic (const char *src, char *dst,
36003 + int len, int sum, int *src_err_ptr, int *dst_err_ptr)
36007 + * Copy from ds while checksumming, otherwise like csum_partial
36009 + * The macros SRC and DST specify the type of access for the instruction.
36010 + * thus we can call a custom exception handler for all access types.
36012 + * FIXME: could someone double-check whether I haven't mixed up some SRC and
36013 + * DST definitions? It's damn hard to trigger all cases. I hope I got
36014 + * them all but there's no guarantee.
36017 +#define SRC(y...) \
36019 + .section __ex_table, "a"; \
36020 + .long 9999b, 6001f ; \
36023 +#define DST(y...) \
36025 + .section __ex_table, "a"; \
36026 + .long 9999b, 6002f ; \
36030 +.globl csum_partial_copy_generic_i386
36032 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
36034 +#define ARGBASE 16
36037 +csum_partial_copy_generic_i386:
36042 + movl ARGBASE+16(%esp),%eax # sum
36043 + movl ARGBASE+12(%esp),%ecx # len
36044 + movl ARGBASE+4(%esp),%esi # src
36045 + movl ARGBASE+8(%esp),%edi # dst
36047 + testl $2, %edi # Check alignment.
36048 + jz 2f # Jump if alignment is ok.
36049 + subl $2, %ecx # Alignment uses up two bytes.
36050 + jae 1f # Jump if we had at least two bytes.
36051 + addl $2, %ecx # ecx was < 2. Deal with it.
36053 +SRC(1: movw (%esi), %bx )
36055 +DST( movw %bx, (%edi) )
36060 + movl %ecx, FP(%esp)
36064 +SRC(1: movl (%esi), %ebx )
36065 +SRC( movl 4(%esi), %edx )
36067 +DST( movl %ebx, (%edi) )
36069 +DST( movl %edx, 4(%edi) )
36071 +SRC( movl 8(%esi), %ebx )
36072 +SRC( movl 12(%esi), %edx )
36074 +DST( movl %ebx, 8(%edi) )
36076 +DST( movl %edx, 12(%edi) )
36078 +SRC( movl 16(%esi), %ebx )
36079 +SRC( movl 20(%esi), %edx )
36081 +DST( movl %ebx, 16(%edi) )
36083 +DST( movl %edx, 20(%edi) )
36085 +SRC( movl 24(%esi), %ebx )
36086 +SRC( movl 28(%esi), %edx )
36088 +DST( movl %ebx, 24(%edi) )
36090 +DST( movl %edx, 28(%edi) )
36092 + lea 32(%esi), %esi
36093 + lea 32(%edi), %edi
36097 +2: movl FP(%esp), %edx
36101 + shrl $2, %edx # This clears CF
36102 +SRC(3: movl (%esi), %ebx )
36104 +DST( movl %ebx, (%edi) )
36105 + lea 4(%esi), %esi
36106 + lea 4(%edi), %edi
36114 +SRC( movw (%esi), %cx )
36115 + leal 2(%esi), %esi
36116 +DST( movw %cx, (%edi) )
36117 + leal 2(%edi), %edi
36120 +SRC(5: movb (%esi), %cl )
36121 +DST( movb %cl, (%edi) )
36122 +6: addl %ecx, %eax
36127 +# Exception handler:
36128 +.section .fixup, "ax"
36131 + movl ARGBASE+20(%esp), %ebx # src_err_ptr
36132 + movl $-EFAULT, (%ebx)
36134 + # zero the complete destination - computing the rest
36135 + # is too much work
36136 + movl ARGBASE+8(%esp), %edi # dst
36137 + movl ARGBASE+12(%esp), %ecx # len
36144 + movl ARGBASE+24(%esp), %ebx # dst_err_ptr
36145 + movl $-EFAULT,(%ebx)
36153 + popl %ecx # equivalent to addl $4,%esp
36158 +/* Version for PentiumII/PPro */
36160 +#define ROUND1(x) \
36161 + SRC(movl x(%esi), %ebx ) ; \
36162 + addl %ebx, %eax ; \
36163 + DST(movl %ebx, x(%edi) ) ;
36165 +#define ROUND(x) \
36166 + SRC(movl x(%esi), %ebx ) ; \
36167 + adcl %ebx, %eax ; \
36168 + DST(movl %ebx, x(%edi) ) ;
36170 +#define ARGBASE 12
36172 +csum_partial_copy_generic_i386:
36176 + movl ARGBASE+4(%esp),%esi #src
36177 + movl ARGBASE+8(%esp),%edi #dst
36178 + movl ARGBASE+12(%esp),%ecx #len
36179 + movl ARGBASE+16(%esp),%eax #sum
36188 + lea -1(%esi),%edx
36190 + lea 3f(%ebx,%ebx), %ebx
36195 + SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl)
36196 + ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52)
36197 + ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36)
36198 + ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20)
36199 + ROUND (-16) ROUND(-12) ROUND(-8) ROUND(-4)
36204 +4: movl ARGBASE+12(%esp),%edx #len
36209 +SRC( movw (%esi), %dx )
36210 + leal 2(%esi), %esi
36211 +DST( movw %dx, (%edi) )
36212 + leal 2(%edi), %edi
36216 +SRC( movb (%esi), %dl )
36217 +DST( movb %dl, (%edi) )
36218 +6: addl %edx, %eax
36221 +.section .fixup, "ax"
36222 +6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
36223 + movl $-EFAULT, (%ebx)
36224 + # zero the complete destination (computing the rest is too much work)
36225 + movl ARGBASE+8(%esp),%edi # dst
36226 + movl ARGBASE+12(%esp),%ecx # len
36230 +6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
36231 + movl $-EFAULT, (%ebx)
36244 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/fault.c um/arch/um/sys-i386/fault.c
36245 --- orig/arch/um/sys-i386/fault.c 1969-12-31 19:00:00.000000000 -0500
36246 +++ um/arch/um/sys-i386/fault.c 2003-10-21 03:26:07.000000000 -0400
36249 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36250 + * Licensed under the GPL
36253 +#include <signal.h>
36254 +#include "sysdep/ptrace.h"
36255 +#include "sysdep/sigcontext.h"
36257 +extern unsigned long search_exception_table(unsigned long addr);
36259 +int arch_fixup(unsigned long address, void *sc_ptr)
36261 + struct sigcontext *sc = sc_ptr;
36262 + unsigned long fixup;
36264 + fixup = search_exception_table(address);
36273 + * Overrides for Emacs so that we follow Linus's tabbing style.
36274 + * Emacs will notice this stuff at the end of the file and automatically
36275 + * adjust the settings for this buffer only. This must remain at the end
36277 + * ---------------------------------------------------------------------------
36278 + * Local variables:
36279 + * c-file-style: "linux"
36282 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ksyms.c um/arch/um/sys-i386/ksyms.c
36283 --- orig/arch/um/sys-i386/ksyms.c 1969-12-31 19:00:00.000000000 -0500
36284 +++ um/arch/um/sys-i386/ksyms.c 2003-10-21 03:26:07.000000000 -0400
36286 +#include "linux/module.h"
36287 +#include "linux/in6.h"
36288 +#include "linux/rwsem.h"
36289 +#include "asm/byteorder.h"
36290 +#include "asm/semaphore.h"
36291 +#include "asm/uaccess.h"
36292 +#include "asm/checksum.h"
36293 +#include "asm/errno.h"
36295 +EXPORT_SYMBOL(__down_failed);
36296 +EXPORT_SYMBOL(__down_failed_interruptible);
36297 +EXPORT_SYMBOL(__down_failed_trylock);
36298 +EXPORT_SYMBOL(__up_wakeup);
36300 +/* Networking helper routines. */
36301 +EXPORT_SYMBOL(csum_partial_copy_from);
36302 +EXPORT_SYMBOL(csum_partial_copy_to);
36303 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ldt.c um/arch/um/sys-i386/ldt.c
36304 --- orig/arch/um/sys-i386/ldt.c 1969-12-31 19:00:00.000000000 -0500
36305 +++ um/arch/um/sys-i386/ldt.c 2003-10-21 03:26:07.000000000 -0400
36308 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
36309 + * Licensed under the GPL
36312 +#include "linux/config.h"
36313 +#include "linux/slab.h"
36314 +#include "asm/uaccess.h"
36315 +#include "asm/ptrace.h"
36316 +#include "choose-mode.h"
36319 +#ifdef CONFIG_MODE_TT
36320 +extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
36322 +int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
36324 + if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT);
36325 + return(modify_ldt(func, ptr, bytecount));
36329 +#ifdef CONFIG_MODE_SKAS
36330 +extern int userspace_pid;
36332 +int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
36334 + struct ptrace_ldt ldt;
36338 + buf = kmalloc(bytecount, GFP_KERNEL);
36347 + res = copy_from_user(buf, ptr, bytecount);
36356 + ldt = ((struct ptrace_ldt) { .func = func,
36358 + .bytecount = bytecount });
36359 + res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt);
36367 + res = copy_to_user(ptr, buf, n);
36381 +int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
36383 + return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
36384 + ptr, bytecount));
36390 + * Overrides for Emacs so that we follow Linus's tabbing style.
36391 + * Emacs will notice this stuff at the end of the file and automatically
36392 + * adjust the settings for this buffer only. This must remain at the end
36394 + * ---------------------------------------------------------------------------
36395 + * Local variables:
36396 + * c-file-style: "linux"
36399 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/Makefile um/arch/um/sys-i386/Makefile
36400 --- orig/arch/um/sys-i386/Makefile 1969-12-31 19:00:00.000000000 -0500
36401 +++ um/arch/um/sys-i386/Makefile 2003-11-09 11:55:24.000000000 -0500
36404 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36405 +# Licensed under the GPL
36408 +O_TARGET = built-in.o
36410 +obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \
36411 + ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o time.o
36412 +export-objs = ksyms.o
36414 +USER_OBJS = bugs.o ptrace_user.o sigcontext.o fault.o
36416 +SYMLINKS = semaphore.c extable.c
36418 +semaphore.c-dir = kernel
36419 +extable.c-dir = mm
36421 +include $(TOPDIR)/Rules.make
36423 +$(USER_OBJS) : %.o: %.c
36424 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
36428 + ln -sf $(TOPDIR)/arch/i386/$($1-dir)/$1 $1
36432 + $(call make_link,$@)
36435 + $(MAKE) -C util clean
36436 + rm -f $(SYMLINKS)
36449 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace.c um/arch/um/sys-i386/ptrace.c
36450 --- orig/arch/um/sys-i386/ptrace.c 1969-12-31 19:00:00.000000000 -0500
36451 +++ um/arch/um/sys-i386/ptrace.c 2003-10-21 03:26:07.000000000 -0400
36454 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
36455 + * Licensed under the GPL
36458 +#include "linux/sched.h"
36459 +#include "asm/elf.h"
36460 +#include "asm/ptrace.h"
36461 +#include "asm/uaccess.h"
36462 +#include "ptrace_user.h"
36463 +#include "sysdep/sigcontext.h"
36464 +#include "sysdep/sc.h"
36466 +void arch_switch(void)
36468 + update_debugregs(current->thread.arch.debugregs_seq);
36471 +int is_syscall(unsigned long addr)
36473 + unsigned short instr;
36476 + n = copy_from_user(&instr, (void *) addr, sizeof(instr));
36478 + printk("is_syscall : failed to read instruction from 0x%lu\n",
36482 + return(instr == 0x80cd);
36485 +/* determines which flags the user has access to. */
36486 +/* 1 = access 0 = no access */
36487 +#define FLAG_MASK 0x00044dd5
36489 +int putreg(struct task_struct *child, int regno, unsigned long value)
36494 + if (value && (value & 3) != 3)
36496 + PT_REGS_FS(&child->thread.regs) = value;
36499 + if (value && (value & 3) != 3)
36501 + PT_REGS_GS(&child->thread.regs) = value;
36505 + if (value && (value & 3) != 3)
36511 + if ((value & 3) != 3)
36516 + value &= FLAG_MASK;
36517 + value |= PT_REGS_EFLAGS(&child->thread.regs);
36520 + PT_REGS_SET(&child->thread.regs, regno, value);
36524 +unsigned long getreg(struct task_struct *child, int regno)
36526 + unsigned long retval = ~0UL;
36537 + /* fall through */
36539 + retval &= PT_REG(&child->thread.regs, regno);
36544 +struct i387_fxsave_struct {
36545 + unsigned short cwd;
36546 + unsigned short swd;
36547 + unsigned short twd;
36548 + unsigned short fop;
36555 + long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
36556 + long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
36557 + long padding[56];
36561 + * FPU tag word conversions.
36564 +static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
36566 + unsigned int tmp; /* to avoid 16 bit prefixes in the code */
36568 + /* Transform each pair of bits into 01 (valid) or 00 (empty) */
36570 + tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
36571 + /* and move the valid bits to the lower byte. */
36572 + tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
36573 + tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
36574 + tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
36578 +static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
36580 + struct _fpxreg *st = NULL;
36581 + unsigned long twd = (unsigned long) fxsave->twd;
36582 + unsigned long tag;
36583 + unsigned long ret = 0xffff0000;
36586 +#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
36588 + for ( i = 0 ; i < 8 ; i++ ) {
36589 + if ( twd & 0x1 ) {
36590 + st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
36592 + switch ( st->exponent & 0x7fff ) {
36594 + tag = 2; /* Special */
36597 + if ( !st->significand[0] &&
36598 + !st->significand[1] &&
36599 + !st->significand[2] &&
36600 + !st->significand[3] ) {
36601 + tag = 1; /* Zero */
36603 + tag = 2; /* Special */
36607 + if ( st->significand[3] & 0x8000 ) {
36608 + tag = 0; /* Valid */
36610 + tag = 2; /* Special */
36615 + tag = 3; /* Empty */
36617 + ret |= (tag << (2 * i));
36624 + * FXSR floating point environment conversions.
36627 +#ifdef CONFIG_MODE_TT
36628 +static inline int convert_fxsr_to_user_tt(struct _fpstate *buf,
36629 + struct pt_regs *regs)
36631 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
36632 + unsigned long env[7];
36633 + struct _fpreg *to;
36634 + struct _fpxreg *from;
36637 + env[0] = (unsigned long)fxsave->cwd | 0xffff0000;
36638 + env[1] = (unsigned long)fxsave->swd | 0xffff0000;
36639 + env[2] = twd_fxsr_to_i387(fxsave);
36640 + env[3] = fxsave->fip;
36641 + env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
36642 + env[5] = fxsave->foo;
36643 + env[6] = fxsave->fos;
36645 + if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
36648 + to = &buf->_st[0];
36649 + from = (struct _fpxreg *) &fxsave->st_space[0];
36650 + for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
36651 + if ( __copy_to_user( to, from, sizeof(*to) ) )
36658 +static inline int convert_fxsr_to_user(struct _fpstate *buf,
36659 + struct pt_regs *regs)
36661 + return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0));
36664 +#ifdef CONFIG_MODE_TT
36665 +static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
36666 + struct _fpstate *buf)
36668 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
36669 + unsigned long env[7];
36670 + struct _fpxreg *to;
36671 + struct _fpreg *from;
36674 + if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
36677 + fxsave->cwd = (unsigned short)(env[0] & 0xffff);
36678 + fxsave->swd = (unsigned short)(env[1] & 0xffff);
36679 + fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
36680 + fxsave->fip = env[3];
36681 + fxsave->fop = (unsigned short)((env[4] & 0xffff0000) >> 16);
36682 + fxsave->fcs = (env[4] & 0xffff);
36683 + fxsave->foo = env[5];
36684 + fxsave->fos = env[6];
36686 + to = (struct _fpxreg *) &fxsave->st_space[0];
36687 + from = &buf->_st[0];
36688 + for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
36689 + if ( __copy_from_user( to, from, sizeof(*from) ) )
36696 +static inline int convert_fxsr_from_user(struct pt_regs *regs,
36697 + struct _fpstate *buf)
36699 + return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0));
36702 +int get_fpregs(unsigned long buf, struct task_struct *child)
36706 + err = convert_fxsr_to_user((struct _fpstate *) buf,
36707 + &child->thread.regs);
36708 + if(err) return(-EFAULT);
36712 +int set_fpregs(unsigned long buf, struct task_struct *child)
36716 + err = convert_fxsr_from_user(&child->thread.regs,
36717 + (struct _fpstate *) buf);
36718 + if(err) return(-EFAULT);
36722 +#ifdef CONFIG_MODE_TT
36723 +int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
36725 + struct pt_regs *regs = &tsk->thread.regs;
36726 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
36729 + err = __copy_to_user((void *) buf, fxsave,
36730 + sizeof(struct user_fxsr_struct));
36731 + if(err) return -EFAULT;
36736 +int get_fpxregs(unsigned long buf, struct task_struct *tsk)
36738 + return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0));
36741 +#ifdef CONFIG_MODE_TT
36742 +int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
36744 + struct pt_regs *regs = &tsk->thread.regs;
36745 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
36748 + err = __copy_from_user(fxsave, (void *) buf,
36749 + sizeof(struct user_fxsr_struct) );
36750 + if(err) return -EFAULT;
36755 +int set_fpxregs(unsigned long buf, struct task_struct *tsk)
36757 + return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0));
36761 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
36763 + fpu->cwd = (((SC_FP_CW(PT_REGS_SC(regs)) & 0xffff) << 16) |
36764 + (SC_FP_SW(PT_REGS_SC(regs)) & 0xffff));
36765 + fpu->swd = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
36766 + fpu->twd = SC_FP_IPOFF(PT_REGS_SC(regs));
36767 + fpu->fip = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
36768 + fpu->fcs = SC_FP_DATAOFF(PT_REGS_SC(regs));
36769 + fpu->foo = SC_FP_DATASEL(PT_REGS_SC(regs));
36771 + memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)),
36772 + sizeof(fpu->st_space));
36777 +#ifdef CONFIG_MODE_TT
36778 +static inline void copy_fpu_fxsave_tt(struct pt_regs *regs,
36779 + struct user_i387_struct *buf)
36781 + struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs));
36782 + unsigned short *to;
36783 + unsigned short *from;
36786 + memcpy( buf, fpu, 7 * sizeof(long) );
36788 + to = (unsigned short *) &buf->st_space[0];
36789 + from = (unsigned short *) &fpu->st_space[0];
36790 + for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) {
36791 + memcpy( to, from, 5 * sizeof(unsigned short) );
36796 +static inline void copy_fpu_fxsave(struct pt_regs *regs,
36797 + struct user_i387_struct *buf)
36799 + (void) CHOOSE_MODE(copy_fpu_fxsave_tt(regs, buf), 0);
36802 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
36804 + copy_fpu_fxsave(regs, (struct user_i387_struct *) fpu);
36809 + * Overrides for Emacs so that we follow Linus's tabbing style.
36810 + * Emacs will notice this stuff at the end of the file and automatically
36811 + * adjust the settings for this buffer only. This must remain at the end
36813 + * ---------------------------------------------------------------------------
36814 + * Local variables:
36815 + * c-file-style: "linux"
36818 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace_user.c um/arch/um/sys-i386/ptrace_user.c
36819 --- orig/arch/um/sys-i386/ptrace_user.c 1969-12-31 19:00:00.000000000 -0500
36820 +++ um/arch/um/sys-i386/ptrace_user.c 2003-12-17 01:33:17.000000000 -0500
36823 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36824 + * Licensed under the GPL
36827 +#include <stdio.h>
36828 +#include <errno.h>
36829 +#include <unistd.h>
36830 +#include <linux/stddef.h>
36831 +#include <sys/ptrace.h>
36832 +#include <asm/ptrace.h>
36833 +#include <asm/user.h>
36834 +#include "kern_util.h"
36835 +#include "sysdep/thread.h"
36839 +int ptrace_getregs(long pid, unsigned long *regs_out)
36841 + return(ptrace(PTRACE_GETREGS, pid, 0, regs_out));
36844 +int ptrace_setregs(long pid, unsigned long *regs)
36846 + return(ptrace(PTRACE_SETREGS, pid, 0, regs));
36849 +int ptrace_getfpregs(long pid, unsigned long *regs)
36851 + return(ptrace(PTRACE_GETFPREGS, pid, 0, regs));
36854 +static void write_debugregs(int pid, unsigned long *regs)
36856 + struct user *dummy;
36860 + nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
36861 + for(i = 0; i < nregs; i++){
36862 + if((i == 4) || (i == 5)) continue;
36863 + if(ptrace(PTRACE_POKEUSER, pid, &dummy->u_debugreg[i],
36865 + printk("write_debugregs - ptrace failed on "
36866 + "register %d, errno = %d\n", errno);
36870 +static void read_debugregs(int pid, unsigned long *regs)
36872 + struct user *dummy;
36876 + nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
36877 + for(i = 0; i < nregs; i++){
36878 + regs[i] = ptrace(PTRACE_PEEKUSER, pid,
36879 + &dummy->u_debugreg[i], 0);
36883 +/* Accessed only by the tracing thread */
36884 +static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
36885 +static int debugregs_seq = 0;
36887 +void arch_enter_kernel(void *task, int pid)
36889 + read_debugregs(pid, TASK_DEBUGREGS(task));
36890 + write_debugregs(pid, kernel_debugregs);
36893 +void arch_leave_kernel(void *task, int pid)
36895 + read_debugregs(pid, kernel_debugregs);
36896 + write_debugregs(pid, TASK_DEBUGREGS(task));
36899 +void ptrace_pokeuser(unsigned long addr, unsigned long data)
36901 + if((addr < offsetof(struct user, u_debugreg[0])) ||
36902 + (addr > offsetof(struct user, u_debugreg[7])))
36904 + addr -= offsetof(struct user, u_debugreg[0]);
36905 + addr = addr >> 2;
36906 + if(kernel_debugregs[addr] == data) return;
36908 + kernel_debugregs[addr] = data;
36912 +static void update_debugregs_cb(void *arg)
36914 + int pid = *((int *) arg);
36916 + write_debugregs(pid, kernel_debugregs);
36919 +void update_debugregs(int seq)
36923 + if(seq == debugregs_seq) return;
36925 + me = os_getpid();
36926 + initial_thread_cb(update_debugregs_cb, &me);
36930 + * Overrides for Emacs so that we follow Linus's tabbing style.
36931 + * Emacs will notice this stuff at the end of the file and automatically
36932 + * adjust the settings for this buffer only. This must remain at the end
36934 + * ---------------------------------------------------------------------------
36935 + * Local variables:
36936 + * c-file-style: "linux"
36939 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sigcontext.c um/arch/um/sys-i386/sigcontext.c
36940 --- orig/arch/um/sys-i386/sigcontext.c 1969-12-31 19:00:00.000000000 -0500
36941 +++ um/arch/um/sys-i386/sigcontext.c 2003-10-21 03:26:07.000000000 -0400
36944 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
36945 + * Licensed under the GPL
36948 +#include <stddef.h>
36949 +#include <string.h>
36950 +#include <asm/ptrace.h>
36951 +#include <asm/sigcontext.h>
36952 +#include "sysdep/ptrace.h"
36953 +#include "kern_util.h"
36954 +#include "frame_user.h"
36956 +int sc_size(void *data)
36958 + struct arch_frame_data *arch = data;
36960 + return(sizeof(struct sigcontext) + arch->fpstate_size);
36963 +void sc_to_sc(void *to_ptr, void *from_ptr)
36965 + struct sigcontext *to = to_ptr, *from = from_ptr;
36966 + int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size;
36968 + memcpy(to, from, size);
36969 + if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1);
36972 +unsigned long *sc_sigmask(void *sc_ptr)
36974 + struct sigcontext *sc = sc_ptr;
36976 + return(&sc->oldmask);
36979 +int sc_get_fpregs(unsigned long buf, void *sc_ptr)
36981 + struct sigcontext *sc = sc_ptr;
36982 + struct _fpstate *from = sc->fpstate, *to = (struct _fpstate *) buf;
36985 + if(from == NULL){
36986 + err |= clear_user_proc(&to->cw, sizeof(to->cw));
36987 + err |= clear_user_proc(&to->sw, sizeof(to->sw));
36988 + err |= clear_user_proc(&to->tag, sizeof(to->tag));
36989 + err |= clear_user_proc(&to->ipoff, sizeof(to->ipoff));
36990 + err |= clear_user_proc(&to->cssel, sizeof(to->cssel));
36991 + err |= clear_user_proc(&to->dataoff, sizeof(to->dataoff));
36992 + err |= clear_user_proc(&to->datasel, sizeof(to->datasel));
36993 + err |= clear_user_proc(&to->_st, sizeof(to->_st));
36996 + err |= copy_to_user_proc(&to->cw, &from->cw, sizeof(to->cw));
36997 + err |= copy_to_user_proc(&to->sw, &from->sw, sizeof(to->sw));
36998 + err |= copy_to_user_proc(&to->tag, &from->tag,
36999 + sizeof(to->tag));
37000 + err |= copy_to_user_proc(&to->ipoff, &from->ipoff,
37001 + sizeof(to->ipoff));
37002 + err |= copy_to_user_proc(&to->cssel,& from->cssel,
37003 + sizeof(to->cssel));
37004 + err |= copy_to_user_proc(&to->dataoff, &from->dataoff,
37005 + sizeof(to->dataoff));
37006 + err |= copy_to_user_proc(&to->datasel, &from->datasel,
37007 + sizeof(to->datasel));
37008 + err |= copy_to_user_proc(to->_st, from->_st, sizeof(to->_st));
37014 + * Overrides for Emacs so that we follow Linus's tabbing style.
37015 + * Emacs will notice this stuff at the end of the file and automatically
37016 + * adjust the settings for this buffer only. This must remain at the end
37018 + * ---------------------------------------------------------------------------
37019 + * Local variables:
37020 + * c-file-style: "linux"
37023 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/syscalls.c um/arch/um/sys-i386/syscalls.c
37024 --- orig/arch/um/sys-i386/syscalls.c 1969-12-31 19:00:00.000000000 -0500
37025 +++ um/arch/um/sys-i386/syscalls.c 2003-10-21 03:26:07.000000000 -0400
37028 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
37029 + * Licensed under the GPL
37032 +#include "asm/mman.h"
37033 +#include "asm/uaccess.h"
37034 +#include "asm/unistd.h"
37037 + * Perform the select(nd, in, out, ex, tv) and mmap() system
37038 + * calls. Linux/i386 didn't use to be able to handle more than
37039 + * 4 system call parameters, so these system calls used a memory
37040 + * block for parameter passing..
37043 +struct mmap_arg_struct {
37044 + unsigned long addr;
37045 + unsigned long len;
37046 + unsigned long prot;
37047 + unsigned long flags;
37048 + unsigned long fd;
37049 + unsigned long offset;
37052 +extern int old_mmap(unsigned long addr, unsigned long len,
37053 + unsigned long prot, unsigned long flags,
37054 + unsigned long fd, unsigned long offset);
37056 +int old_mmap_i386(struct mmap_arg_struct *arg)
37058 + struct mmap_arg_struct a;
37059 + int err = -EFAULT;
37061 + if (copy_from_user(&a, arg, sizeof(a)))
37064 + err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
37069 +struct sel_arg_struct {
37071 + fd_set *inp, *outp, *exp;
37072 + struct timeval *tvp;
37075 +int old_select(struct sel_arg_struct *arg)
37077 + struct sel_arg_struct a;
37079 + if (copy_from_user(&a, arg, sizeof(a)))
37081 + /* sys_select() does the appropriate kernel locking */
37082 + return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
37086 + * Overrides for Emacs so that we follow Linus's tabbing style.
37087 + * Emacs will notice this stuff at the end of the file and automatically
37088 + * adjust the settings for this buffer only. This must remain at the end
37090 + * ---------------------------------------------------------------------------
37091 + * Local variables:
37092 + * c-file-style: "linux"
37095 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sysrq.c um/arch/um/sys-i386/sysrq.c
37096 --- orig/arch/um/sys-i386/sysrq.c 1969-12-31 19:00:00.000000000 -0500
37097 +++ um/arch/um/sys-i386/sysrq.c 2003-10-21 03:26:07.000000000 -0400
37099 +#include "linux/kernel.h"
37100 +#include "linux/smp.h"
37101 +#include "linux/sched.h"
37102 +#include "asm/ptrace.h"
37103 +#include "sysrq.h"
37105 +void show_regs(struct pt_regs *regs)
37108 + printk("EIP: %04lx:[<%08lx>] CPU: %d %s",
37109 + 0xffff & PT_REGS_CS(regs), PT_REGS_IP(regs),
37110 + smp_processor_id(), print_tainted());
37111 + if (PT_REGS_CS(regs) & 3)
37112 + printk(" ESP: %04lx:%08lx", 0xffff & PT_REGS_SS(regs),
37113 + PT_REGS_SP(regs));
37114 + printk(" EFLAGS: %08lx\n %s\n", PT_REGS_EFLAGS(regs),
37115 + print_tainted());
37116 + printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
37117 + PT_REGS_EAX(regs), PT_REGS_EBX(regs),
37118 + PT_REGS_ECX(regs),
37119 + PT_REGS_EDX(regs));
37120 + printk("ESI: %08lx EDI: %08lx EBP: %08lx",
37121 + PT_REGS_ESI(regs), PT_REGS_EDI(regs),
37122 + PT_REGS_EBP(regs));
37123 + printk(" DS: %04lx ES: %04lx\n",
37124 + 0xffff & PT_REGS_DS(regs),
37125 + 0xffff & PT_REGS_ES(regs));
37127 + show_trace((unsigned long *) ®s);
37129 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/time.c um/arch/um/sys-i386/time.c
37130 --- orig/arch/um/sys-i386/time.c 1969-12-31 19:00:00.000000000 -0500
37131 +++ um/arch/um/sys-i386/time.c 2003-11-10 01:46:49.000000000 -0500
37134 + * sys-i386/time.c
37135 + * Created 25.9.2002 Sapan Bhatia
37139 +unsigned long long time_stamp(void)
37141 + unsigned long low, high;
37143 + asm("rdtsc" : "=a" (low), "=d" (high));
37144 + return((((unsigned long long) high) << 32) + low);
37148 + * Overrides for Emacs so that we follow Linus's tabbing style.
37149 + * Emacs will notice this stuff at the end of the file and automatically
37150 + * adjust the settings for this buffer only. This must remain at the end
37152 + * ---------------------------------------------------------------------------
37153 + * Local variables:
37154 + * c-file-style: "linux"
37157 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/Makefile um/arch/um/sys-i386/util/Makefile
37158 --- orig/arch/um/sys-i386/util/Makefile 1969-12-31 19:00:00.000000000 -0500
37159 +++ um/arch/um/sys-i386/util/Makefile 2003-11-08 08:26:40.000000000 -0500
37161 +EXE = mk_sc mk_thread
37163 +include $(TOPDIR)/Rules.make
37168 + $(HOSTCC) -o mk_sc mk_sc.o
37173 +mk_thread : mk_thread_user.o mk_thread_kern.o
37174 + $(HOSTCC) -o mk_thread mk_thread_user.o mk_thread_kern.o
37176 +mk_thread_user.o : mk_thread_user.c
37179 +mk_thread_kern.o : mk_thread_kern.c
37180 + $(HOSTCC) $(CFLAGS) -c $<
37185 +archmrproper : clean
37189 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/mk_sc.c um/arch/um/sys-i386/util/mk_sc.c
37190 --- orig/arch/um/sys-i386/util/mk_sc.c 1969-12-31 19:00:00.000000000 -0500
37191 +++ um/arch/um/sys-i386/util/mk_sc.c 2003-10-21 03:26:07.000000000 -0400
37193 +#include <stdio.h>
37194 +#include <signal.h>
37195 +#include <linux/stddef.h>
37197 +#define SC_OFFSET(name, field) \
37198 + printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
37199 + offsetof(struct sigcontext, field))
37201 +#define SC_FP_OFFSET(name, field) \
37202 + printf("#define " name \
37203 + "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
37204 + offsetof(struct _fpstate, field))
37206 +#define SC_FP_OFFSET_PTR(name, field, type) \
37207 + printf("#define " name \
37208 + "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
37209 + offsetof(struct _fpstate, field))
37211 +int main(int argc, char **argv)
37213 + SC_OFFSET("SC_IP", eip);
37214 + SC_OFFSET("SC_SP", esp);
37215 + SC_OFFSET("SC_FS", fs);
37216 + SC_OFFSET("SC_GS", gs);
37217 + SC_OFFSET("SC_DS", ds);
37218 + SC_OFFSET("SC_ES", es);
37219 + SC_OFFSET("SC_SS", ss);
37220 + SC_OFFSET("SC_CS", cs);
37221 + SC_OFFSET("SC_EFLAGS", eflags);
37222 + SC_OFFSET("SC_EAX", eax);
37223 + SC_OFFSET("SC_EBX", ebx);
37224 + SC_OFFSET("SC_ECX", ecx);
37225 + SC_OFFSET("SC_EDX", edx);
37226 + SC_OFFSET("SC_EDI", edi);
37227 + SC_OFFSET("SC_ESI", esi);
37228 + SC_OFFSET("SC_EBP", ebp);
37229 + SC_OFFSET("SC_TRAPNO", trapno);
37230 + SC_OFFSET("SC_ERR", err);
37231 + SC_OFFSET("SC_CR2", cr2);
37232 + SC_OFFSET("SC_FPSTATE", fpstate);
37233 + SC_OFFSET("SC_SIGMASK", oldmask);
37234 + SC_FP_OFFSET("SC_FP_CW", cw);
37235 + SC_FP_OFFSET("SC_FP_SW", sw);
37236 + SC_FP_OFFSET("SC_FP_TAG", tag);
37237 + SC_FP_OFFSET("SC_FP_IPOFF", ipoff);
37238 + SC_FP_OFFSET("SC_FP_CSSEL", cssel);
37239 + SC_FP_OFFSET("SC_FP_DATAOFF", dataoff);
37240 + SC_FP_OFFSET("SC_FP_DATASEL", datasel);
37241 + SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate");
37242 + SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void");
37245 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/mk_thread_kern.c um/arch/um/sys-i386/util/mk_thread_kern.c
37246 --- orig/arch/um/sys-i386/util/mk_thread_kern.c 1969-12-31 19:00:00.000000000 -0500
37247 +++ um/arch/um/sys-i386/util/mk_thread_kern.c 2003-10-21 03:26:07.000000000 -0400
37249 +#include "linux/config.h"
37250 +#include "linux/stddef.h"
37251 +#include "linux/sched.h"
37253 +extern void print_head(void);
37254 +extern void print_constant_ptr(char *name, int value);
37255 +extern void print_constant(char *name, char *type, int value);
37256 +extern void print_tail(void);
37258 +#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
37260 +int main(int argc, char **argv)
37263 + print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs));
37264 +#ifdef CONFIG_MODE_TT
37265 + print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
37271 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/mk_thread_user.c um/arch/um/sys-i386/util/mk_thread_user.c
37272 --- orig/arch/um/sys-i386/util/mk_thread_user.c 1969-12-31 19:00:00.000000000 -0500
37273 +++ um/arch/um/sys-i386/util/mk_thread_user.c 2003-10-21 03:26:07.000000000 -0400
37275 +#include <stdio.h>
37277 +void print_head(void)
37280 + printf(" * Generated by mk_thread\n");
37283 + printf("#ifndef __UM_THREAD_H\n");
37284 + printf("#define __UM_THREAD_H\n");
37288 +void print_constant_ptr(char *name, int value)
37290 + printf("#define %s(task) ((unsigned long *) "
37291 + "&(((char *) (task))[%d]))\n", name, value);
37294 +void print_constant(char *name, char *type, int value)
37296 + printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
37300 +void print_tail(void)
37303 + printf("#endif\n");
37305 diff -Naur -X ../exclude-files orig/arch/um/sys-ia64/Makefile um/arch/um/sys-ia64/Makefile
37306 --- orig/arch/um/sys-ia64/Makefile 1969-12-31 19:00:00.000000000 -0500
37307 +++ um/arch/um/sys-ia64/Makefile 2003-10-21 03:26:07.000000000 -0400
37317 + $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
37327 + @$(MAKEBOOT) clean
37334 +include $(TOPDIR)/Rules.make
37335 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/Makefile um/arch/um/sys-ppc/Makefile
37336 --- orig/arch/um/sys-ppc/Makefile 1969-12-31 19:00:00.000000000 -0500
37337 +++ um/arch/um/sys-ppc/Makefile 2003-10-21 03:26:07.000000000 -0400
37342 + $(CC) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
37344 +OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \
37345 + ptrace_user.o sysrq.o
37347 +EXTRA_AFLAGS := -DCONFIG_ALL_PPC -I. -I$(TOPDIR)/arch/ppc/kernel
37353 + $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
37355 +ptrace_user.o: ptrace_user.c
37356 + $(CC) -D__KERNEL__ $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
37358 +sigcontext.o: sigcontext.c
37359 + $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
37363 + ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
37367 + ln -s $(TOPDIR)/arch/ppc/lib/$@ $@
37371 + ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
37375 + ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
37377 +ppc_defs.h: mk_defs.c ppc_defs.head \
37378 + $(TOPDIR)/include/asm-ppc/mmu.h \
37379 + $(TOPDIR)/include/asm-ppc/processor.h \
37380 + $(TOPDIR)/include/asm-ppc/pgtable.h \
37381 + $(TOPDIR)/include/asm-ppc/ptrace.h
37382 +# $(CC) $(CFLAGS) -S mk_defs.c
37383 + cp ppc_defs.head ppc_defs.h
37384 +# for bk, this way we can write to the file even if it's not checked out
37385 + echo '#define THREAD 608' >> ppc_defs.h
37386 + echo '#define PT_REGS 8' >> ppc_defs.h
37387 + echo '#define CLONE_VM 256' >> ppc_defs.h
37388 +# chmod u+w ppc_defs.h
37389 +# grep '^#define' mk_defs.s >> ppc_defs.h
37392 +# the asm link is horrible, and breaks the other targets. This is also
37393 +# not going to work with parallel makes.
37395 +checksum.o: checksum.S
37397 + ln -s $(TOPDIR)/include/asm-ppc asm
37398 + $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
37401 +misc.o: misc.S ppc_defs.h
37403 + ln -s $(TOPDIR)/include/asm-ppc asm
37404 + $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
37410 + rm -f checksum.S semaphore.c mk_defs.c
37418 +include $(TOPDIR)/Rules.make
37419 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/misc.S um/arch/um/sys-ppc/misc.S
37420 --- orig/arch/um/sys-ppc/misc.S 1969-12-31 19:00:00.000000000 -0500
37421 +++ um/arch/um/sys-ppc/misc.S 2003-10-21 03:26:07.000000000 -0400
37424 + * This file contains miscellaneous low-level functions.
37425 + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
37427 + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
37428 + * and Paul Mackerras.
37430 + * A couple of functions stolen from arch/ppc/kernel/misc.S for UML
37431 + * by Chris Emerson.
37433 + * This program is free software; you can redistribute it and/or
37434 + * modify it under the terms of the GNU General Public License
37435 + * as published by the Free Software Foundation; either version
37436 + * 2 of the License, or (at your option) any later version.
37440 +#include <linux/config.h>
37441 +#include <asm/processor.h>
37442 +#include "ppc_asm.h"
37444 +#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
37445 +#define CACHE_LINE_SIZE 16
37446 +#define LG_CACHE_LINE_SIZE 4
37447 +#define MAX_COPY_PREFETCH 1
37448 +#elif !defined(CONFIG_PPC64BRIDGE)
37449 +#define CACHE_LINE_SIZE 32
37450 +#define LG_CACHE_LINE_SIZE 5
37451 +#define MAX_COPY_PREFETCH 4
37453 +#define CACHE_LINE_SIZE 128
37454 +#define LG_CACHE_LINE_SIZE 7
37455 +#define MAX_COPY_PREFETCH 1
37456 +#endif /* CONFIG_4xx || CONFIG_8xx */
37461 + * Clear a page using the dcbz instruction, which doesn't cause any
37462 + * memory traffic (except to write out any cache lines which get
37463 + * displaced). This only works on cacheable memory.
37465 +_GLOBAL(clear_page)
37466 + li r0,4096/CACHE_LINE_SIZE
37477 + addi r3,r3,CACHE_LINE_SIZE
37482 + * Copy a whole page. We use the dcbz instruction on the destination
37483 + * to reduce memory traffic (it eliminates the unnecessary reads of
37484 + * the destination into cache). This requires that the destination
37487 +#define COPY_16_BYTES \
37491 + lwzu r9,16(r4); \
37497 +_GLOBAL(copy_page)
37502 +#ifndef CONFIG_8xx
37503 +#if MAX_COPY_PREFETCH > 1
37504 + li r0,MAX_COPY_PREFETCH
37508 + addi r11,r11,CACHE_LINE_SIZE
37510 +#else /* MAX_COPY_PREFETCH == 1 */
37512 + li r11,CACHE_LINE_SIZE+4
37513 +#endif /* MAX_COPY_PREFETCH */
37514 +#endif /* CONFIG_8xx */
37516 + li r0,4096/CACHE_LINE_SIZE
37519 +#ifndef CONFIG_8xx
37524 +#if CACHE_LINE_SIZE >= 32
37526 +#if CACHE_LINE_SIZE >= 64
37529 +#if CACHE_LINE_SIZE >= 128
37539 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/miscthings.c um/arch/um/sys-ppc/miscthings.c
37540 --- orig/arch/um/sys-ppc/miscthings.c 1969-12-31 19:00:00.000000000 -0500
37541 +++ um/arch/um/sys-ppc/miscthings.c 2003-10-21 03:26:07.000000000 -0400
37543 +#include "linux/threads.h"
37544 +#include "linux/stddef.h" // for NULL
37545 +#include "linux/elf.h" // for AT_NULL
37547 +/* The following function nicked from arch/ppc/kernel/process.c and
37548 + * adapted slightly */
37550 + * XXX ld.so expects the auxiliary table to start on
37551 + * a 16-byte boundary, so we have to find it and
37552 + * move it up. :-(
37554 +void shove_aux_table(unsigned long sp)
37559 + unsigned long aux_start, offset;
37561 + argc = *(int *)sp;
37562 + sp += sizeof(int) + (argc + 1) * sizeof(char *);
37563 + /* skip over the environment pointers */
37565 + p = *(char **)sp;
37566 + sp += sizeof(char *);
37567 + } while (p != NULL);
37569 + /* skip to the end of the auxiliary table */
37571 + e = *(unsigned long *)sp;
37572 + sp += 2 * sizeof(unsigned long);
37573 + } while (e != AT_NULL);
37574 + offset = ((aux_start + 15) & ~15) - aux_start;
37575 + if (offset != 0) {
37577 + sp -= sizeof(unsigned long);
37578 + e = *(unsigned long *)sp;
37579 + *(unsigned long *)(sp + offset) = e;
37580 + } while (sp > aux_start);
37583 +/* END stuff taken from arch/ppc/kernel/process.c */
37587 + * Overrides for Emacs so that we follow Linus's tabbing style.
37588 + * Emacs will notice this stuff at the end of the file and automatically
37589 + * adjust the settings for this buffer only. This must remain at the end
37591 + * ---------------------------------------------------------------------------
37592 + * Local variables:
37593 + * c-file-style: "linux"
37596 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace.c um/arch/um/sys-ppc/ptrace.c
37597 --- orig/arch/um/sys-ppc/ptrace.c 1969-12-31 19:00:00.000000000 -0500
37598 +++ um/arch/um/sys-ppc/ptrace.c 2003-10-21 03:26:07.000000000 -0400
37600 +#include "linux/sched.h"
37601 +#include "asm/ptrace.h"
37603 +int putreg(struct task_struct *child, unsigned long regno,
37604 + unsigned long value)
37606 + child->thread.process_regs.regs[regno >> 2] = value;
37610 +unsigned long getreg(struct task_struct *child, unsigned long regno)
37612 + unsigned long retval = ~0UL;
37614 + retval &= child->thread.process_regs.regs[regno >> 2];
37619 + * Overrides for Emacs so that we follow Linus's tabbing style.
37620 + * Emacs will notice this stuff at the end of the file and automatically
37621 + * adjust the settings for this buffer only. This must remain at the end
37623 + * ---------------------------------------------------------------------------
37624 + * Local variables:
37625 + * c-file-style: "linux"
37628 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace_user.c um/arch/um/sys-ppc/ptrace_user.c
37629 --- orig/arch/um/sys-ppc/ptrace_user.c 1969-12-31 19:00:00.000000000 -0500
37630 +++ um/arch/um/sys-ppc/ptrace_user.c 2003-10-21 03:26:07.000000000 -0400
37632 +#include <sys/ptrace.h>
37633 +#include <errno.h>
37634 +#include <asm/ptrace.h>
37635 +#include "sysdep/ptrace.h"
37637 +int ptrace_getregs(long pid, unsigned long *regs_out)
37640 + for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
37642 + regs_out->regs[i] = ptrace(PTRACE_PEEKUSER, pid, i*4, 0);
37650 +int ptrace_setregs(long pid, unsigned long *regs_in)
37653 + for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
37654 + if (i != 34 /* FIXME: PT_ORIG_R3 */ && i <= PT_MQ) {
37655 + if (ptrace(PTRACE_POKEUSER, pid, i*4, regs_in->regs[i]) < 0) {
37663 + * Overrides for Emacs so that we follow Linus's tabbing style.
37664 + * Emacs will notice this stuff at the end of the file and automatically
37665 + * adjust the settings for this buffer only. This must remain at the end
37667 + * ---------------------------------------------------------------------------
37668 + * Local variables:
37669 + * c-file-style: "linux"
37672 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sigcontext.c um/arch/um/sys-ppc/sigcontext.c
37673 --- orig/arch/um/sys-ppc/sigcontext.c 1969-12-31 19:00:00.000000000 -0500
37674 +++ um/arch/um/sys-ppc/sigcontext.c 2003-10-21 03:26:07.000000000 -0400
37676 +#include "asm/ptrace.h"
37677 +#include "asm/sigcontext.h"
37678 +#include "sysdep/ptrace.h"
37679 +#include "user_util.h"
37682 + * Overrides for Emacs so that we follow Linus's tabbing style.
37683 + * Emacs will notice this stuff at the end of the file and automatically
37684 + * adjust the settings for this buffer only. This must remain at the end
37686 + * ---------------------------------------------------------------------------
37687 + * Local variables:
37688 + * c-file-style: "linux"
37691 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sysrq.c um/arch/um/sys-ppc/sysrq.c
37692 --- orig/arch/um/sys-ppc/sysrq.c 1969-12-31 19:00:00.000000000 -0500
37693 +++ um/arch/um/sys-ppc/sysrq.c 2003-10-21 03:26:07.000000000 -0400
37696 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
37697 + * Licensed under the GPL
37700 +#include "linux/kernel.h"
37701 +#include "linux/smp.h"
37702 +#include "asm/ptrace.h"
37703 +#include "sysrq.h"
37705 +void show_regs(struct pt_regs_subarch *regs)
37708 + printk("show_regs(): insert regs here.\n");
37711 + printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs, regs->eip,
37712 + smp_processor_id());
37713 + if (regs->xcs & 3)
37714 + printk(" ESP: %04x:%08lx",0xffff & regs->xss, regs->esp);
37715 + printk(" EFLAGS: %08lx\n", regs->eflags);
37716 + printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
37717 + regs->eax, regs->ebx, regs->ecx, regs->edx);
37718 + printk("ESI: %08lx EDI: %08lx EBP: %08lx",
37719 + regs->esi, regs->edi, regs->ebp);
37720 + printk(" DS: %04x ES: %04x\n",
37721 + 0xffff & regs->xds, 0xffff & regs->xes);
37724 + show_trace(®s->gpr[1]);
37729 + * Overrides for Emacs so that we follow Linus's tabbing style.
37730 + * Emacs will notice this stuff at the end of the file and automatically
37731 + * adjust the settings for this buffer only. This must remain at the end
37733 + * ---------------------------------------------------------------------------
37734 + * Local variables:
37735 + * c-file-style: "linux"
37738 diff -Naur -X ../exclude-files orig/arch/um/util/Makefile um/arch/um/util/Makefile
37739 --- orig/arch/um/util/Makefile 1969-12-31 19:00:00.000000000 -0500
37740 +++ um/arch/um/util/Makefile 2003-11-08 02:51:30.000000000 -0500
37742 +ALL = mk_task mk_constants
37746 +mk_task : mk_task_user.o mk_task_kern.o
37747 + $(HOSTCC) -o mk_task mk_task_user.o mk_task_kern.o
37749 +mk_task_user.o : mk_task_user.c
37752 +mk_task_kern.o : mk_task_kern.c
37753 + $(HOSTCC) $(CFLAGS) -c $<
37755 +mk_constants : mk_constants_user.o mk_constants_kern.o
37756 + $(HOSTCC) -o mk_constants mk_constants_user.o mk_constants_kern.o
37758 +mk_constants_user.o : mk_constants_user.c
37761 +mk_constants_kern.o : mk_constants_kern.c
37762 + $(HOSTCC) $(CFLAGS) -c $<
37765 + $(RM) $(ALL) *.o *~
37767 +archmrproper : clean
37768 diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_kern.c um/arch/um/util/mk_constants_kern.c
37769 --- orig/arch/um/util/mk_constants_kern.c 1969-12-31 19:00:00.000000000 -0500
37770 +++ um/arch/um/util/mk_constants_kern.c 2003-10-21 03:26:07.000000000 -0400
37772 +#include "linux/kernel.h"
37773 +#include "linux/stringify.h"
37774 +#include "asm/page.h"
37776 +extern void print_head(void);
37777 +extern void print_constant_str(char *name, char *value);
37778 +extern void print_constant_int(char *name, int value);
37779 +extern void print_tail(void);
37781 +int main(int argc, char **argv)
37784 + print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
37785 + print_constant_str("UM_KERN_EMERG", KERN_EMERG);
37786 + print_constant_str("UM_KERN_ALERT", KERN_ALERT);
37787 + print_constant_str("UM_KERN_CRIT", KERN_CRIT);
37788 + print_constant_str("UM_KERN_ERR", KERN_ERR);
37789 + print_constant_str("UM_KERN_WARNING", KERN_WARNING);
37790 + print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
37791 + print_constant_str("UM_KERN_INFO", KERN_INFO);
37792 + print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
37796 diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_user.c um/arch/um/util/mk_constants_user.c
37797 --- orig/arch/um/util/mk_constants_user.c 1969-12-31 19:00:00.000000000 -0500
37798 +++ um/arch/um/util/mk_constants_user.c 2003-10-21 03:26:07.000000000 -0400
37800 +#include <stdio.h>
37802 +void print_head(void)
37805 + printf(" * Generated by mk_constants\n");
37808 + printf("#ifndef __UM_CONSTANTS_H\n");
37809 + printf("#define __UM_CONSTANTS_H\n");
37813 +void print_constant_str(char *name, char *value)
37815 + printf("#define %s \"%s\"\n", name, value);
37818 +void print_constant_int(char *name, int value)
37820 + printf("#define %s %d\n", name, value);
37823 +void print_tail(void)
37826 + printf("#endif\n");
37828 diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_kern.c um/arch/um/util/mk_task_kern.c
37829 --- orig/arch/um/util/mk_task_kern.c 1969-12-31 19:00:00.000000000 -0500
37830 +++ um/arch/um/util/mk_task_kern.c 2003-10-21 03:26:07.000000000 -0400
37832 +#include "linux/sched.h"
37833 +#include "linux/stddef.h"
37835 +extern void print(char *name, char *type, int offset);
37836 +extern void print_ptr(char *name, char *type, int offset);
37837 +extern void print_head(void);
37838 +extern void print_tail(void);
37840 +int main(int argc, char **argv)
37843 + print_ptr("TASK_REGS", "union uml_pt_regs",
37844 + offsetof(struct task_struct, thread.regs));
37845 + print("TASK_PID", "int", offsetof(struct task_struct, pid));
37849 diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_user.c um/arch/um/util/mk_task_user.c
37850 --- orig/arch/um/util/mk_task_user.c 1969-12-31 19:00:00.000000000 -0500
37851 +++ um/arch/um/util/mk_task_user.c 2003-10-21 03:26:07.000000000 -0400
37853 +#include <stdio.h>
37855 +void print(char *name, char *type, int offset)
37857 + printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
37861 +void print_ptr(char *name, char *type, int offset)
37863 + printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
37867 +void print_head(void)
37870 + printf(" * Generated by mk_task\n");
37873 + printf("#ifndef __TASK_H\n");
37874 + printf("#define __TASK_H\n");
37878 +void print_tail(void)
37881 + printf("#endif\n");
37883 diff -Naur -X ../exclude-files orig/CREDITS um/CREDITS
37884 --- orig/CREDITS 2003-12-16 22:16:23.000000000 -0500
37885 +++ um/CREDITS 2003-12-16 22:17:22.000000000 -0500
37886 @@ -434,6 +434,7 @@
37888 W: http://lars.nocrew.org/
37889 D: dsp56k device driver
37890 +D: ptrace proxy in user mode kernel port
37894 @@ -719,7 +720,7 @@
37895 E: jdike@karaya.com
37896 W: http://user-mode-linux.sourceforge.net
37897 D: User mode kernel port
37899 +S: 375 Tubbs Hill Rd
37900 S: Deering NH 03244
37903 diff -Naur -X ../exclude-files orig/Documentation/Configure.help um/Documentation/Configure.help
37904 --- orig/Documentation/Configure.help 2003-12-16 22:16:23.000000000 -0500
37905 +++ um/Documentation/Configure.help 2003-12-16 22:17:22.000000000 -0500
37906 @@ -15821,6 +15821,63 @@
37907 The module will be called speedtch.o. If you want to compile it as
37908 a module, say M here and read <file:Documentation/modules.txt>.
37910 +Support for /proc/mm
37912 + Enables support for address space separation through /proc/mm.
37913 + A host kernel needs to have this enabled in order for UML to
37914 + run in skas mode. UML kernels do not need to have this option
37915 + unless they will host sub-UMLs.
37917 + If you don't know what this does just say Y.
37919 +Separate Kernel Address Space support
37921 + This option controls whether skas (separate kernel address space)
37922 + support is compiled in. If you have applied the skas patch to the
37923 + host and enabled support for /proc/mm in the host kernel, then you
37924 + certainly want to say Y here (and consider saying N to
37925 + CONFIG_MODE_TT). Otherwise, it is safe to say Y. Disabling this
37926 + option will shrink the UML binary slightly.
37928 +Tracing thread support
37930 + This option controls whether tracing thread support is compiled
37931 + into UML. Normally, this should be set to Y. If you intend to
37932 + use only skas mode (and the host has the skas patch applied to it),
37933 + then it is OK to say N here.
37935 +Force a static link
37936 +CONFIG_STATIC_LINK
37937 + If CONFIG_MODE_TT is disabled, then this option gives you the ability
37938 + to force a static link of UML. Normally, if only skas mode is built
37939 + in to UML, it will be linked as a shared binary. This is inconvenient
37940 + for use in a chroot jail. So, if you intend to run UML inside a
37941 + chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
37944 +2G/2G host address space split
37946 + Most Linux machines are configured so that the kernel occupies the
37947 + upper 1G of the 4G address space and processes use the lower 3G.
37948 + However, some machine are configured with a 2G/2G split, with the
37949 + kernel occupying the upper 2G and processes using the lower 2G.
37951 + To allow UML to run on a such host you have to say Y here. N should be
37952 + a safe choice most of the time.
37954 +Kernel stack size order
37955 +CONFIG_KERNEL_STACK_ORDER
37956 + This option determines the size of UML kernel stacks. They will
37957 + be 1 << order pages. The default is OK unless you're running Valgrind
37958 + on UML, in which case, set this to 3.
37960 +UML ubd block driver
37961 +CONFIG_BLK_DEV_UBD
37962 + The User-Mode Linux port includes a driver called UBD which will let
37963 + you access arbitrary files on the host computer as block devices.
37964 + Unless you know that you do not need such virtual block devices say
37968 USB is a master/slave protocol, organized with one master
37969 host (such as a PC) controlling up to 127 peripheral devices.
37970 @@ -15905,17 +15962,15 @@
37972 Always do synchronous disk IO for UBD
37973 CONFIG_BLK_DEV_UBD_SYNC
37974 - The User-Mode Linux port includes a driver called UBD which will let
37975 - you access arbitrary files on the host computer as block devices.
37976 - Writes to such a block device are not immediately written to the
37977 - host's disk; this may cause problems if, for example, the User-Mode
37978 - Linux 'Virtual Machine' uses a journalling file system and the host
37979 - computer crashes.
37980 + Writes to the virtual block device are not immediately written to the host's
37981 + disk; this may cause problems if, for example, the User-Mode Linux
37982 + 'Virtual Machine' uses a journalling filesystem and the host computer
37985 Synchronous operation (i.e. always writing data to the host's disk
37986 immediately) is configurable on a per-UBD basis by using a special
37987 kernel command line option. Alternatively, you can say Y here to
37988 - turn on synchronous operation by default for all block.
37989 + turn on synchronous operation by default for all block devices.
37991 If you're running a journalling file system (like reiserfs, for
37992 example) in your virtual machine, you will want to say Y here. If
37993 @@ -15927,6 +15982,7 @@
37995 This option enables a debugging interface which allows gdb to debug
37996 the kernel without needing to actually attach to kernel threads.
37997 + CONFIG_XTERM_CHAN must be enabled in order to enable CONFIG_PT_PROXY.
37998 If you want to do kernel debugging, say Y here; otherwise say N.
38001 @@ -15959,7 +16015,7 @@
38002 This option allows developers to retrieve coverage data from a UML
38005 - See <http://user-mode-linux.sourceforge.net/gcov.html> for more
38006 + See <http://user-mode-linux.sourceforge.net/gprof.html> for more
38009 If you're involved in UML kernel development and want to use gcov,
38010 @@ -15996,6 +16052,19 @@
38011 If you'd like to be able to work with files stored on the host,
38012 say Y or M here; otherwise say N.
38016 + hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
38017 + entries to be overridden, removed, or fabricated from the host.
38018 + Its purpose is to allow a UML to appear to be a physical machine
38019 + by removing or changing anything in /proc which gives away the
38020 + identity of a UML.
38022 + See <http://user-mode-linux.sf.net/hppfs.html> for more information.
38024 + You only need this if you are setting up a UML honeypot. Otherwise,
38025 + it is safe to say 'N' here.
38027 Example IO Memory driver
38029 The User-Mode Linux port can provide support for IO Memory
38030 @@ -16011,6 +16080,21 @@
38031 If you'd like to be able to provide a simulated IO port space for
38032 User-Mode Linux processes, say Y. If unsure, say N.
38034 +Anonymous Memory support
38036 + Don't ask. Just say Y.
38038 +Support for software watchdog inside UML
38039 +CONFIG_UML_WATCHDOG
38040 + Support for a virtual hardware watchdog. It's safe to say N here.
38044 + This is a layered driver which sits above two other block devices.
38045 + One is read-only, and the other is a read-write layer which stores
38046 + all changes. This provides the illusion that the read-only layer
38047 + can be mounted read-write and changed.
38049 Virtual Serial Line
38051 The User-Mode Linux environment allows you to create virtual serial
38052 @@ -16121,26 +16205,197 @@
38055 CONFIG_UML_NET_SLIP
38056 - The Slip User-Mode Linux network transport allows a running UML to
38057 + The slip User-Mode Linux network transport allows a running UML to
38058 network with its host over a point-to-point link. Unlike Ethertap,
38059 which can carry any Ethernet frame (and hence even non-IP packets),
38060 - the Slip transport can only carry IP packets.
38061 + the slip transport can only carry IP packets.
38063 - To use this, your host must support Slip devices.
38064 + To use this, your host must support slip devices.
38066 For more information, see
38067 <http://user-mode-linux.sourceforge.net/networking.html>. That site
38068 - has examples of the UML command line to use to enable Slip
38069 + has examples of the UML command line to use to enable slip
38070 networking, and details of a few quirks with it.
38072 - The Ethertap Transport is preferred over Slip because of its
38073 - limitation. If you prefer Slip, however, say Y here. Otherwise
38074 + The Ethertap Transport is preferred over slip because of its
38075 + limitations. If you prefer slip, however, say Y here. Otherwise
38076 choose the Multicast transport (to network multiple UMLs on
38077 multiple hosts), Ethertap (to network with the host and the
38078 outside world), and/or the Daemon transport (to network multiple
38079 UMLs on a single host). You may choose more than one without
38080 conflict. If you don't need UML networking, say N.
38083 +CONFIG_UML_NET_SLIRP
38084 + The SLiRP User-Mode Linux network transport allows a running UML
38085 + to network by invoking a program that can handle SLIP encapsulated
38086 + packets. This is commonly (but not limited to) the application
38087 + known as SLiRP, a program that can re-socket IP packets back onto
38088 + the host on which it is run. Only IP packets are supported,
38089 + unlike other network transports that can handle all Ethernet
38090 + frames. In general, slirp allows the UML the same IP connectivity
38091 + to the outside world that the host user is permitted, and unlike
38092 + other transports, SLiRP works without the need of root level
38093 + privleges, setuid binaries, or SLIP devices on the host. This
38094 + also means not every type of connection is possible, but most
38095 + situations can be accomodated with carefully crafted slirp
38096 + commands that can be passed along as part of the network device's
38097 + setup string. The effect of this transport on the UML is similar
38098 + that of a host behind a firewall that masquerades all network
38099 + connections passing through it (but is less secure).
38101 + To use this you should first have slirp compiled somewhere
38102 + accessible on the host, and have read its documentation. If you
38103 + don't need UML networking, say N.
38105 + Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
38108 +CONFIG_UML_NET_PCAP
38109 + The pcap transport makes a pcap packet stream on the host look
38110 + like an ethernet device inside UML. This is useful for making
38111 + UML act as a network monitor for the host. You must have libcap
38112 + installed in order to build the pcap transport into UML.
38114 + For more information, see
38115 + <http://user-mode-linux.sourceforge.net/networking.html> That site
38116 + has examples of the UML command line to use to enable this option.
38118 + If you intend to use UML as a network monitor for the host, say
38119 + Y here. Otherwise, say N.
38121 +Default main console channel initialization
38122 +CONFIG_CON_ZERO_CHAN
38123 + This is the string describing the channel to which the main console
38124 + will be attached by default. This value can be overridden from the
38125 + command line. The default value is "fd:0,fd:1", which attaches the
38126 + main console to stdin and stdout.
38127 + It is safe to leave this unchanged.
38129 +Default console channel initialization
38131 + This is the string describing the channel to which all consoles
38132 + except the main console will be attached by default. This value can
38133 + be overridden from the command line. The default value is "xterm",
38134 + which brings them up in xterms.
38135 + It is safe to leave this unchanged, although you may wish to change
38136 + this if you expect the UML that you build to be run in environments
38137 + which don't have X or xterm available.
38139 +Default serial line channel initialization
38141 + This is the string describing the channel to which the serial lines
38142 + will be attached by default. This value can be overridden from the
38143 + command line. The default value is "pty", which attaches them to
38144 + traditional pseudo-terminals.
38145 + It is safe to leave this unchanged, although you may wish to change
38146 + this if you expect the UML that you build to be run in environments
38147 + which don't have a set of /dev/pty* devices.
38151 + This is set to the number of layers of UMLs that this UML will be run
38152 + in. Normally, this is zero, meaning that it will run directly on the
38153 + host. Setting it to one will build a UML that can run inside a UML
38154 + that is running on the host. Generally, if you intend this UML to run
38155 + inside another UML, set CONFIG_NEST_LEVEL to one more than the host UML.
38156 + Note that if the hosting UML has its CONFIG_KERNEL_HALF_GIGS set to
38157 + greater than one, then the guest UML should have its CONFIG_NEST_LEVEL
38158 + set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
38159 + Only change this if you are running nested UMLs.
38161 +Kernel address space size (in .5G units)
38162 +CONFIG_KERNEL_HALF_GIGS
38163 + This determines the amount of address space that UML will allocate for
38164 + its own, measured in half Gigabyte units. The default is 1.
38165 + Change this only if you need to boot UML with an unusually large amount
38166 + of physical memory.
38170 + This option enables UML sound support. If enabled, it will pull in
38171 + soundcore and the UML hostaudio relay, which acts as a intermediary
38172 + between the host's dsp and mixer devices and the UML sound system.
38173 + It is safe to say 'Y' here.
38177 + This option enables UML SMP support. UML implements virtual SMP by
38178 + allowing as many processes to run simultaneously on the host as
38179 + there are virtual processors configured. Obviously, if the host is
38180 + a uniprocessor, those processes will timeshare, but, inside UML,
38181 + will appear to be running simultaneously. If the host is a
38182 + multiprocessor, then UML processes may run simultaneously, depending
38183 + on the host scheduler.
38184 + CONFIG_SMP will be set to whatever this option is set to.
38185 + It is safe to leave this unchanged.
38187 +file descriptor channel support
38189 + This option enables support for attaching UML consoles and serial
38190 + lines to already set up file descriptors. Generally, the main
38191 + console is attached to file descriptors 0 and 1 (stdin and stdout),
38192 + so it would be wise to leave this enabled unless you intend to
38193 + attach it to some other host device.
38195 +null device channel support
38197 + This option enables support for attaching UML consoles and serial
38198 + lines to a device similar to /dev/null. Data written to it disappears
38199 + and there is never any data to be read.
38201 +port channel support
38203 + This option enables support for attaching UML consoles and serial
38204 + lines to host portals. They may be accessed with 'telnet <host>
38205 + <port number>'. Any number of consoles and serial lines may be
38206 + attached to a single portal, although what UML device you get when
38207 + you telnet to that portal will be unpredictable.
38208 + It is safe to say 'Y' here.
38210 +pty channel support
38212 + This option enables support for attaching UML consoles and serial
38213 + lines to host pseudo-terminals. Access to both traditional
38214 + pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled
38215 + with this option. The assignment of UML devices to host devices
38216 + will be announced in the kernel message log.
38217 + It is safe to say 'Y' here.
38219 +tty channel support
38221 + This option enables support for attaching UML consoles and serial
38222 + lines to host terminals. Access to both virtual consoles
38223 + (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and
38224 + /dev/pts/*) are controlled by this option.
38225 + It is safe to say 'Y' here.
38227 +xterm channel support
38229 + This option enables support for attaching UML consoles and serial
38230 + lines to xterms. Each UML device so assigned will be brought up in
38232 + If you disable this option, then CONFIG_PT_PROXY will be disabled as
38233 + well, since UML's gdb currently requires an xterm.
38234 + It is safe to say 'Y' here.
38238 + This option enables logging of all data going through pseudo-terminals
38239 + to the host. This is primarily useful for honeypots, where you want
38240 + secure keystroke logging that can't be detected or disabled by root.
38241 + Say 'N' unless you are setting up a UML honeypot or otherwise know that
38242 + you want this option.
38244 +UML real-time clock support
38245 +CONFIG_UML_REAL_TIME_CLOCK
38246 + This option ties the UML clock to the host clock, so that time passes at
38247 + the same rate as on the host, regardless of how much CPU time the UML is
38248 + getting. This should normally be enabled. The exception would be if you're
38249 + debugging UML. In this case, time spent staring at the debugger with UML
38250 + stopped will cause lots of timer ticks to be backed up, and UML will spent
38251 + lots of time calling the timer when it is finally continued.
38253 Microtek USB scanner support
38254 CONFIG_USB_MICROTEK
38255 Say Y here if you want support for the Microtek X6USB and
38256 diff -Naur -X ../exclude-files orig/drivers/char/Makefile um/drivers/char/Makefile
38257 --- orig/drivers/char/Makefile 2003-12-16 22:16:26.000000000 -0500
38258 +++ um/drivers/char/Makefile 2003-12-16 22:17:25.000000000 -0500
38259 @@ -109,6 +109,12 @@
38272 diff -Naur -X ../exclude-files orig/drivers/char/mem.c um/drivers/char/mem.c
38273 --- orig/drivers/char/mem.c 2003-12-16 22:16:27.000000000 -0500
38274 +++ um/drivers/char/mem.c 2003-12-16 22:17:25.000000000 -0500
38275 @@ -220,7 +220,8 @@
38278 char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
38281 + p = (unsigned long) __va(p);
38282 if (p < (unsigned long) high_memory) {
38284 if (count > (unsigned long) high_memory - p)
38285 @@ -269,7 +270,7 @@
38287 free_page((unsigned long)kbuf);
38290 + *ppos = __pa((void *) p);
38291 return virtr + read;
38294 @@ -664,6 +665,8 @@
38298 +extern struct file_operations anon_file_operations;
38300 static int memory_open(struct inode * inode, struct file * filp)
38302 switch (MINOR(inode->i_rdev)) {
38303 @@ -693,6 +696,9 @@
38305 filp->f_op = &urandom_fops;
38308 + filp->f_op = &anon_file_operations;
38313 @@ -719,7 +725,8 @@
38314 {5, "zero", S_IRUGO | S_IWUGO, &zero_fops},
38315 {7, "full", S_IRUGO | S_IWUGO, &full_fops},
38316 {8, "random", S_IRUGO | S_IWUSR, &random_fops},
38317 - {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}
38318 + {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops},
38319 + {10, "anon", S_IRUGO | S_IWUSR, &anon_file_operations},
38323 diff -Naur -X ../exclude-files orig/drivers/char/tty_io.c um/drivers/char/tty_io.c
38324 --- orig/drivers/char/tty_io.c 2003-12-16 22:16:27.000000000 -0500
38325 +++ um/drivers/char/tty_io.c 2003-12-16 22:17:25.000000000 -0500
38326 @@ -649,6 +649,23 @@
38327 wake_up_interruptible(&tty->write_wait);
38330 +#ifdef CONFIG_TTY_LOG
38332 +int (*open_log)(void *, void *) = NULL;
38333 +int (*write_log)(int, const char *, int, void *, int) = NULL;
38334 +void (*close_log)(int, void *) = NULL;
38336 +void register_tty_logger(int (*opener)(void *, void *),
38337 + int (*writer)(int, const char *, int, void *, int),
38338 + void (*closer)(int, void *))
38340 + open_log = opener;
38341 + write_log = writer;
38342 + close_log = closer;
38347 static ssize_t tty_read(struct file * file, char * buf, size_t count,
38350 @@ -689,8 +706,13 @@
38356 inode->i_atime = CURRENT_TIME;
38357 +#ifdef CONFIG_TTY_LOG
38358 + if((tty->log_fd >= 0) && (write_log != NULL))
38359 + (*write_log)(tty->log_fd, buf, i, tty, 1);
38365 @@ -744,6 +766,10 @@
38367 file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
38369 +#ifdef CONFIG_TTY_LOG
38370 + if((tty->log_fd >= 0) && (write_log != NULL))
38371 + (*write_log)(tty->log_fd, buf - ret, ret, tty, 0);
38374 up(&tty->atomic_write);
38376 @@ -971,6 +997,7 @@
38377 goto release_mem_out;
38384 @@ -1290,6 +1317,11 @@
38385 run_task_queue(&tq_timer);
38386 flush_scheduled_tasks();
38388 +#ifdef CONFIG_TTY_LOG
38389 + if((tty->log_fd >= 0) && (close_log != NULL))
38390 + (*close_log)(tty->log_fd, tty);
38394 * The release_mem function takes care of the details of clearing
38395 * the slots and preserving the termios structure.
38396 @@ -1448,6 +1480,11 @@
38401 +#ifdef CONFIG_TTY_LOG
38402 + if((tty->log_fd < 0) && (open_log != NULL))
38403 + tty->log_fd = (*open_log)(tty, current->tty);
38408 @@ -2047,6 +2084,9 @@
38409 spin_lock_init(&tty->read_lock);
38410 INIT_LIST_HEAD(&tty->tty_files);
38411 INIT_TQUEUE(&tty->SAK_tq, 0, 0);
38412 +#ifdef CONFIG_TTY_LOG
38413 + tty->log_fd = -1;
38418 diff -Naur -X ../exclude-files orig/drivers/net/setup.c um/drivers/net/setup.c
38419 --- orig/drivers/net/setup.c 2002-09-15 12:13:19.000000000 -0400
38420 +++ um/drivers/net/setup.c 2003-10-21 03:26:07.000000000 -0400
38422 extern int lmc_setup(void);
38424 extern int madgemc_probe(void);
38425 -extern int uml_net_probe(void);
38427 /* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is string of 9 zeros. */
38428 #define __PAD6 "\0\0\0\0\0\0\0\0\0"
38429 @@ -103,9 +102,6 @@
38430 #ifdef CONFIG_MADGEMC
38431 {madgemc_probe, 0},
38433 -#ifdef CONFIG_UML_NET
38434 - {uml_net_probe, 0},
38439 diff -Naur -X ../exclude-files orig/fs/bad_inode.c um/fs/bad_inode.c
38440 --- orig/fs/bad_inode.c 2002-08-21 11:47:27.000000000 -0400
38441 +++ um/fs/bad_inode.c 2003-10-21 03:26:07.000000000 -0400
38444 void make_bad_inode(struct inode * inode)
38446 + inode->i_state = 0;
38447 inode->i_mode = S_IFREG;
38448 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
38449 inode->i_op = &bad_inode_ops;
38450 diff -Naur -X ../exclude-files orig/include/asm-i386/hardirq.h um/include/asm-i386/hardirq.h
38451 --- orig/include/asm-i386/hardirq.h 2003-12-16 22:16:35.000000000 -0500
38452 +++ um/include/asm-i386/hardirq.h 2003-12-17 02:16:13.000000000 -0500
38454 #include <linux/config.h>
38455 #include <linux/threads.h>
38456 #include <linux/irq.h>
38457 +#include <asm/processor.h> /* for cpu_relax */
38459 /* assembly code in softirq.h is sensitive to the offsets of these fields */
38461 diff -Naur -X ../exclude-files orig/include/asm-um/a.out.h um/include/asm-um/a.out.h
38462 --- orig/include/asm-um/a.out.h 1969-12-31 19:00:00.000000000 -0500
38463 +++ um/include/asm-um/a.out.h 2003-10-21 03:26:07.000000000 -0400
38465 +#ifndef __UM_A_OUT_H
38466 +#define __UM_A_OUT_H
38468 +#include "linux/config.h"
38469 +#include "asm/arch/a.out.h"
38470 +#include "choose-mode.h"
38474 +extern unsigned long stacksizelim;
38476 +extern unsigned long host_task_size;
38478 +#define STACK_ROOM (stacksizelim)
38480 +extern int honeypot;
38481 +#define STACK_TOP \
38482 + CHOOSE_MODE((honeypot ? host_task_size : task_size), task_size)
38485 diff -Naur -X ../exclude-files orig/include/asm-um/archparam-i386.h um/include/asm-um/archparam-i386.h
38486 --- orig/include/asm-um/archparam-i386.h 1969-12-31 19:00:00.000000000 -0500
38487 +++ um/include/asm-um/archparam-i386.h 2003-12-16 08:50:39.000000000 -0500
38490 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
38491 + * Licensed under the GPL
38494 +#ifndef __UM_ARCHPARAM_I386_H
38495 +#define __UM_ARCHPARAM_I386_H
38497 +/********* Bits for asm-um/elf.h ************/
38501 +#define ELF_PLATFORM "i586"
38503 +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
38505 +typedef struct user_i387_struct elf_fpregset_t;
38506 +typedef unsigned long elf_greg_t;
38508 +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
38509 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
38511 +#define ELF_DATA ELFDATA2LSB
38512 +#define ELF_ARCH EM_386
38514 +#define ELF_PLAT_INIT(regs, load_addr) do { \
38515 + PT_REGS_EBX(regs) = 0; \
38516 + PT_REGS_ECX(regs) = 0; \
38517 + PT_REGS_EDX(regs) = 0; \
38518 + PT_REGS_ESI(regs) = 0; \
38519 + PT_REGS_EDI(regs) = 0; \
38520 + PT_REGS_EBP(regs) = 0; \
38521 + PT_REGS_EAX(regs) = 0; \
38524 +/* Shamelessly stolen from include/asm-i386/elf.h */
38526 +#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \
38527 + pr_reg[0] = PT_REGS_EBX(regs); \
38528 + pr_reg[1] = PT_REGS_ECX(regs); \
38529 + pr_reg[2] = PT_REGS_EDX(regs); \
38530 + pr_reg[3] = PT_REGS_ESI(regs); \
38531 + pr_reg[4] = PT_REGS_EDI(regs); \
38532 + pr_reg[5] = PT_REGS_EBP(regs); \
38533 + pr_reg[6] = PT_REGS_EAX(regs); \
38534 + pr_reg[7] = PT_REGS_DS(regs); \
38535 + pr_reg[8] = PT_REGS_ES(regs); \
38536 + /* fake once used fs and gs selectors? */ \
38537 + pr_reg[9] = PT_REGS_DS(regs); \
38538 + pr_reg[10] = PT_REGS_DS(regs); \
38539 + pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \
38540 + pr_reg[12] = PT_REGS_IP(regs); \
38541 + pr_reg[13] = PT_REGS_CS(regs); \
38542 + pr_reg[14] = PT_REGS_EFLAGS(regs); \
38543 + pr_reg[15] = PT_REGS_SP(regs); \
38544 + pr_reg[16] = PT_REGS_SS(regs); \
38547 +/********* Bits for asm-um/delay.h **********/
38549 +typedef unsigned long um_udelay_t;
38551 +/********* Nothing for asm-um/hardirq.h **********/
38553 +/********* Nothing for asm-um/hw_irq.h **********/
38555 +/********* Nothing for asm-um/string.h **********/
38560 + * Overrides for Emacs so that we follow Linus's tabbing style.
38561 + * Emacs will notice this stuff at the end of the file and automatically
38562 + * adjust the settings for this buffer only. This must remain at the end
38564 + * ---------------------------------------------------------------------------
38565 + * Local variables:
38566 + * c-file-style: "linux"
38569 diff -Naur -X ../exclude-files orig/include/asm-um/archparam-ppc.h um/include/asm-um/archparam-ppc.h
38570 --- orig/include/asm-um/archparam-ppc.h 1969-12-31 19:00:00.000000000 -0500
38571 +++ um/include/asm-um/archparam-ppc.h 2003-10-21 03:26:07.000000000 -0400
38573 +#ifndef __UM_ARCHPARAM_PPC_H
38574 +#define __UM_ARCHPARAM_PPC_H
38576 +/********* Bits for asm-um/elf.h ************/
38578 +#define ELF_PLATFORM (0)
38580 +#define ELF_ET_DYN_BASE (0x08000000)
38582 +/* the following stolen from asm-ppc/elf.h */
38583 +#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
38584 +#define ELF_NFPREG 33 /* includes fpscr */
38585 +/* General registers */
38586 +typedef unsigned long elf_greg_t;
38587 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
38589 +/* Floating point registers */
38590 +typedef double elf_fpreg_t;
38591 +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
38593 +#define ELF_DATA ELFDATA2MSB
38594 +#define ELF_ARCH EM_PPC
38596 +/********* Bits for asm-um/delay.h **********/
38598 +typedef unsigned int um_udelay_t;
38600 +/********* Bits for asm-um/hw_irq.h **********/
38602 +struct hw_interrupt_type;
38604 +/********* Bits for asm-um/hardirq.h **********/
38606 +#define irq_enter(cpu, irq) hardirq_enter(cpu)
38607 +#define irq_exit(cpu, irq) hardirq_exit(cpu)
38609 +/********* Bits for asm-um/string.h **********/
38611 +#define __HAVE_ARCH_STRRCHR
38614 diff -Naur -X ../exclude-files orig/include/asm-um/arch-signal-i386.h um/include/asm-um/arch-signal-i386.h
38615 --- orig/include/asm-um/arch-signal-i386.h 1969-12-31 19:00:00.000000000 -0500
38616 +++ um/include/asm-um/arch-signal-i386.h 2003-10-21 03:26:07.000000000 -0400
38619 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38620 + * Licensed under the GPL
38623 +#ifndef __UM_ARCH_SIGNAL_I386_H
38624 +#define __UM_ARCH_SIGNAL_I386_H
38626 +struct arch_signal_context {
38627 + unsigned long extrasigs[_NSIG_WORDS];
38633 + * Overrides for Emacs so that we follow Linus's tabbing style.
38634 + * Emacs will notice this stuff at the end of the file and automatically
38635 + * adjust the settings for this buffer only. This must remain at the end
38637 + * ---------------------------------------------------------------------------
38638 + * Local variables:
38639 + * c-file-style: "linux"
38642 diff -Naur -X ../exclude-files orig/include/asm-um/atomic.h um/include/asm-um/atomic.h
38643 --- orig/include/asm-um/atomic.h 1969-12-31 19:00:00.000000000 -0500
38644 +++ um/include/asm-um/atomic.h 2003-12-17 02:16:13.000000000 -0500
38646 +#ifndef __UM_ATOMIC_H
38647 +#define __UM_ATOMIC_H
38649 +#include "asm/arch/atomic.h"
38652 diff -Naur -X ../exclude-files orig/include/asm-um/bitops.h um/include/asm-um/bitops.h
38653 --- orig/include/asm-um/bitops.h 1969-12-31 19:00:00.000000000 -0500
38654 +++ um/include/asm-um/bitops.h 2003-12-17 02:16:13.000000000 -0500
38656 +#ifndef __UM_BITOPS_H
38657 +#define __UM_BITOPS_H
38659 +#include "asm/arch/bitops.h"
38662 diff -Naur -X ../exclude-files orig/include/asm-um/boot.h um/include/asm-um/boot.h
38663 --- orig/include/asm-um/boot.h 1969-12-31 19:00:00.000000000 -0500
38664 +++ um/include/asm-um/boot.h 2003-10-21 03:26:07.000000000 -0400
38666 +#ifndef __UM_BOOT_H
38667 +#define __UM_BOOT_H
38669 +#include "asm/arch/boot.h"
38672 diff -Naur -X ../exclude-files orig/include/asm-um/bugs.h um/include/asm-um/bugs.h
38673 --- orig/include/asm-um/bugs.h 1969-12-31 19:00:00.000000000 -0500
38674 +++ um/include/asm-um/bugs.h 2003-10-21 03:26:07.000000000 -0400
38676 +#ifndef __UM_BUGS_H
38677 +#define __UM_BUGS_H
38679 +void check_bugs(void);
38682 diff -Naur -X ../exclude-files orig/include/asm-um/byteorder.h um/include/asm-um/byteorder.h
38683 --- orig/include/asm-um/byteorder.h 1969-12-31 19:00:00.000000000 -0500
38684 +++ um/include/asm-um/byteorder.h 2003-12-16 22:26:55.000000000 -0500
38686 +#ifndef __UM_BYTEORDER_H
38687 +#define __UM_BYTEORDER_H
38689 +#include "asm/arch/byteorder.h"
38692 diff -Naur -X ../exclude-files orig/include/asm-um/cache.h um/include/asm-um/cache.h
38693 --- orig/include/asm-um/cache.h 1969-12-31 19:00:00.000000000 -0500
38694 +++ um/include/asm-um/cache.h 2003-10-21 03:26:07.000000000 -0400
38696 +#ifndef __UM_CACHE_H
38697 +#define __UM_CACHE_H
38699 +#define L1_CACHE_BYTES 32
38702 diff -Naur -X ../exclude-files orig/include/asm-um/checksum.h um/include/asm-um/checksum.h
38703 --- orig/include/asm-um/checksum.h 1969-12-31 19:00:00.000000000 -0500
38704 +++ um/include/asm-um/checksum.h 2003-10-21 03:26:07.000000000 -0400
38706 +#ifndef __UM_CHECKSUM_H
38707 +#define __UM_CHECKSUM_H
38709 +#include "sysdep/checksum.h"
38712 diff -Naur -X ../exclude-files orig/include/asm-um/cobalt.h um/include/asm-um/cobalt.h
38713 --- orig/include/asm-um/cobalt.h 1969-12-31 19:00:00.000000000 -0500
38714 +++ um/include/asm-um/cobalt.h 2003-10-21 03:26:07.000000000 -0400
38716 +#ifndef __UM_COBALT_H
38717 +#define __UM_COBALT_H
38719 +#include "asm/arch/cobalt.h"
38722 diff -Naur -X ../exclude-files orig/include/asm-um/current.h um/include/asm-um/current.h
38723 --- orig/include/asm-um/current.h 1969-12-31 19:00:00.000000000 -0500
38724 +++ um/include/asm-um/current.h 2003-12-17 02:16:13.000000000 -0500
38727 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
38728 + * Licensed under the GPL
38731 +#ifndef __UM_CURRENT_H
38732 +#define __UM_CURRENT_H
38734 +#ifndef __ASSEMBLY__
38736 +#include "linux/config.h"
38737 +#include "asm/page.h"
38739 +struct task_struct;
38741 +#define CURRENT_TASK(dummy) (((unsigned long) &dummy) & \
38742 + (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
38744 +#define current ({ int dummy; (struct task_struct *) CURRENT_TASK(dummy); })
38746 +#endif /* __ASSEMBLY__ */
38751 + * Overrides for Emacs so that we follow Linus's tabbing style.
38752 + * Emacs will notice this stuff at the end of the file and automatically
38753 + * adjust the settings for this buffer only. This must remain at the end
38755 + * ---------------------------------------------------------------------------
38756 + * Local variables:
38757 + * c-file-style: "linux"
38760 diff -Naur -X ../exclude-files orig/include/asm-um/delay.h um/include/asm-um/delay.h
38761 --- orig/include/asm-um/delay.h 1969-12-31 19:00:00.000000000 -0500
38762 +++ um/include/asm-um/delay.h 2003-12-16 22:26:58.000000000 -0500
38764 +#ifndef __UM_DELAY_H
38765 +#define __UM_DELAY_H
38767 +#include "asm/arch/delay.h"
38768 +#include "asm/archparam.h"
38771 diff -Naur -X ../exclude-files orig/include/asm-um/desc.h um/include/asm-um/desc.h
38772 --- orig/include/asm-um/desc.h 1969-12-31 19:00:00.000000000 -0500
38773 +++ um/include/asm-um/desc.h 2003-10-21 03:26:07.000000000 -0400
38775 +#ifndef __UM_DESC_H
38776 +#define __UM_DESC_H
38778 +#include "asm/arch/desc.h"
38781 diff -Naur -X ../exclude-files orig/include/asm-um/div64.h um/include/asm-um/div64.h
38782 --- orig/include/asm-um/div64.h 1969-12-31 19:00:00.000000000 -0500
38783 +++ um/include/asm-um/div64.h 2003-10-21 03:26:07.000000000 -0400
38785 +#ifndef _UM_DIV64_H
38786 +#define _UM_DIV64_H
38788 +#include "asm/arch/div64.h"
38791 diff -Naur -X ../exclude-files orig/include/asm-um/dma.h um/include/asm-um/dma.h
38792 --- orig/include/asm-um/dma.h 1969-12-31 19:00:00.000000000 -0500
38793 +++ um/include/asm-um/dma.h 2003-12-15 00:26:39.000000000 -0500
38795 +#ifndef __UM_DMA_H
38796 +#define __UM_DMA_H
38798 +#include "asm/io.h"
38800 +extern unsigned long uml_physmem;
38802 +#define MAX_DMA_ADDRESS (uml_physmem)
38805 diff -Naur -X ../exclude-files orig/include/asm-um/elf.h um/include/asm-um/elf.h
38806 --- orig/include/asm-um/elf.h 1969-12-31 19:00:00.000000000 -0500
38807 +++ um/include/asm-um/elf.h 2003-12-16 22:29:20.000000000 -0500
38809 +#ifndef __UM_ELF_H
38810 +#define __UM_ELF_H
38812 +#include "asm/archparam.h"
38814 +#define ELF_HWCAP (0)
38816 +#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
38818 +#define ELF_EXEC_PAGESIZE 4096
38820 +#define elf_check_arch(x) (1)
38822 +#define ELF_CLASS ELFCLASS32
38824 +#define USE_ELF_CORE_DUMP
38827 diff -Naur -X ../exclude-files orig/include/asm-um/errno.h um/include/asm-um/errno.h
38828 --- orig/include/asm-um/errno.h 1969-12-31 19:00:00.000000000 -0500
38829 +++ um/include/asm-um/errno.h 2003-10-21 03:26:07.000000000 -0400
38831 +#ifndef __UM_ERRNO_H
38832 +#define __UM_ERRNO_H
38834 +#include "asm/arch/errno.h"
38837 diff -Naur -X ../exclude-files orig/include/asm-um/fcntl.h um/include/asm-um/fcntl.h
38838 --- orig/include/asm-um/fcntl.h 1969-12-31 19:00:00.000000000 -0500
38839 +++ um/include/asm-um/fcntl.h 2003-10-21 03:26:07.000000000 -0400
38841 +#ifndef __UM_FCNTL_H
38842 +#define __UM_FCNTL_H
38844 +#include "asm/arch/fcntl.h"
38847 diff -Naur -X ../exclude-files orig/include/asm-um/fixmap.h um/include/asm-um/fixmap.h
38848 --- orig/include/asm-um/fixmap.h 1969-12-31 19:00:00.000000000 -0500
38849 +++ um/include/asm-um/fixmap.h 2003-12-17 02:16:14.000000000 -0500
38851 +#ifndef __UM_FIXMAP_H
38852 +#define __UM_FIXMAP_H
38854 +#include <linux/config.h>
38855 +#include <asm/kmap_types.h>
38858 + * Here we define all the compile-time 'special' virtual
38859 + * addresses. The point is to have a constant address at
38860 + * compile time, but to set the physical address only
38861 + * in the boot process. We allocate these special addresses
38862 + * from the end of virtual memory (0xfffff000) backwards.
38863 + * Also this lets us do fail-safe vmalloc(), we
38864 + * can guarantee that these special addresses and
38865 + * vmalloc()-ed addresses never overlap.
38867 + * these 'compile-time allocated' memory buffers are
38868 + * fixed-size 4k pages. (or larger if used with an increment
38869 + * highger than 1) use fixmap_set(idx,phys) to associate
38870 + * physical memory with fixmap indices.
38872 + * TLB entries of such buffers will not be flushed across
38877 + * on UP currently we will have no trace of the fixmap mechanizm,
38878 + * no page table allocations, etc. This might change in the
38879 + * future, say framebuffers for the console driver(s) could be
38882 +enum fixed_addresses {
38883 +#ifdef CONFIG_HIGHMEM
38884 + FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
38885 + FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
38887 + __end_of_fixed_addresses
38890 +extern void __set_fixmap (enum fixed_addresses idx,
38891 + unsigned long phys, pgprot_t flags);
38893 +#define set_fixmap(idx, phys) \
38894 + __set_fixmap(idx, phys, PAGE_KERNEL)
38896 + * Some hardware wants to get fixmapped without caching.
38898 +#define set_fixmap_nocache(idx, phys) \
38899 + __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
38901 + * used by vmalloc.c.
38903 + * Leave one empty page between vmalloc'ed areas and
38904 + * the start of the fixmap, and leave one page empty
38905 + * at the top of mem..
38907 +extern unsigned long get_kmem_end(void);
38909 +#define FIXADDR_TOP (get_kmem_end() - 0x2000)
38910 +#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
38911 +#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
38913 +#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
38915 +extern void __this_fixmap_does_not_exist(void);
38918 + * 'index to address' translation. If anyone tries to use the idx
38919 + * directly without tranlation, we catch the bug with a NULL-deference
38920 + * kernel oops. Illegal ranges of incoming indices are caught too.
38922 +static inline unsigned long fix_to_virt(const unsigned int idx)
38925 + * this branch gets completely eliminated after inlining,
38926 + * except when someone tries to use fixaddr indices in an
38927 + * illegal way. (such as mixing up address types or using
38928 + * out-of-range indices).
38930 + * If it doesn't get removed, the linker will complain
38931 + * loudly with a reasonably clear error message..
38933 + if (idx >= __end_of_fixed_addresses)
38934 + __this_fixmap_does_not_exist();
38936 + return __fix_to_virt(idx);
38940 diff -Naur -X ../exclude-files orig/include/asm-um/floppy.h um/include/asm-um/floppy.h
38941 --- orig/include/asm-um/floppy.h 1969-12-31 19:00:00.000000000 -0500
38942 +++ um/include/asm-um/floppy.h 2003-10-21 03:26:07.000000000 -0400
38944 +#ifndef __UM_FLOPPY_H
38945 +#define __UM_FLOPPY_H
38947 +#include "asm/arch/floppy.h"
38950 diff -Naur -X ../exclude-files orig/include/asm-um/hardirq.h um/include/asm-um/hardirq.h
38951 --- orig/include/asm-um/hardirq.h 1969-12-31 19:00:00.000000000 -0500
38952 +++ um/include/asm-um/hardirq.h 2003-12-17 02:16:13.000000000 -0500
38954 +#ifndef __UM_HARDIRQ_H
38955 +#define __UM_HARDIRQ_H
38957 +#include "asm/arch/hardirq.h"
38960 diff -Naur -X ../exclude-files orig/include/asm-um/hdreg.h um/include/asm-um/hdreg.h
38961 --- orig/include/asm-um/hdreg.h 1969-12-31 19:00:00.000000000 -0500
38962 +++ um/include/asm-um/hdreg.h 2003-10-21 03:26:07.000000000 -0400
38964 +#ifndef __UM_HDREG_H
38965 +#define __UM_HDREG_H
38967 +#include "asm/arch/hdreg.h"
38970 diff -Naur -X ../exclude-files orig/include/asm-um/highmem.h um/include/asm-um/highmem.h
38971 --- orig/include/asm-um/highmem.h 1969-12-31 19:00:00.000000000 -0500
38972 +++ um/include/asm-um/highmem.h 2003-12-17 02:16:14.000000000 -0500
38974 +#ifndef __UM_HIGHMEM_H
38975 +#define __UM_HIGHMEM_H
38977 +#include "asm/page.h"
38978 +#include "asm/fixmap.h"
38979 +#include "asm/arch/highmem.h"
38983 +#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK)
38986 diff -Naur -X ../exclude-files orig/include/asm-um/hw_irq.h um/include/asm-um/hw_irq.h
38987 --- orig/include/asm-um/hw_irq.h 1969-12-31 19:00:00.000000000 -0500
38988 +++ um/include/asm-um/hw_irq.h 2003-12-16 22:26:55.000000000 -0500
38990 +#ifndef _ASM_UM_HW_IRQ_H
38991 +#define _ASM_UM_HW_IRQ_H
38993 +#include "asm/irq.h"
38994 +#include "asm/archparam.h"
38996 +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
39000 diff -Naur -X ../exclude-files orig/include/asm-um/ide.h um/include/asm-um/ide.h
39001 --- orig/include/asm-um/ide.h 1969-12-31 19:00:00.000000000 -0500
39002 +++ um/include/asm-um/ide.h 2003-12-15 00:29:05.000000000 -0500
39004 +#ifndef __UM_IDE_H
39005 +#define __UM_IDE_H
39007 +#include "asm/arch/ide.h"
39010 diff -Naur -X ../exclude-files orig/include/asm-um/init.h um/include/asm-um/init.h
39011 --- orig/include/asm-um/init.h 1969-12-31 19:00:00.000000000 -0500
39012 +++ um/include/asm-um/init.h 2003-10-21 03:26:07.000000000 -0400
39014 +#ifndef _UM_INIT_H
39015 +#define _UM_INIT_H
39019 +#define __initdata
39020 +#define __initfunc(__arginit) __arginit
39021 +#define __cacheline_aligned
39025 diff -Naur -X ../exclude-files orig/include/asm-um/ioctl.h um/include/asm-um/ioctl.h
39026 --- orig/include/asm-um/ioctl.h 1969-12-31 19:00:00.000000000 -0500
39027 +++ um/include/asm-um/ioctl.h 2003-10-21 03:26:07.000000000 -0400
39029 +#ifndef __UM_IOCTL_H
39030 +#define __UM_IOCTL_H
39032 +#include "asm/arch/ioctl.h"
39035 diff -Naur -X ../exclude-files orig/include/asm-um/ioctls.h um/include/asm-um/ioctls.h
39036 --- orig/include/asm-um/ioctls.h 1969-12-31 19:00:00.000000000 -0500
39037 +++ um/include/asm-um/ioctls.h 2003-11-07 02:10:43.000000000 -0500
39039 +#ifndef __UM_IOCTLS_H
39040 +#define __UM_IOCTLS_H
39042 +#include "asm/arch/ioctls.h"
39045 diff -Naur -X ../exclude-files orig/include/asm-um/io.h um/include/asm-um/io.h
39046 --- orig/include/asm-um/io.h 1969-12-31 19:00:00.000000000 -0500
39047 +++ um/include/asm-um/io.h 2003-12-15 00:26:39.000000000 -0500
39052 +#include "asm/page.h"
39054 +#define IO_SPACE_LIMIT 0xdeadbeef /* Sure hope nothing uses this */
39056 +static inline int inb(unsigned long i) { return(0); }
39057 +static inline void outb(char c, unsigned long i) { }
39060 + * Change virtual addresses to physical addresses and vv.
39061 + * These are pretty trivial
39063 +static inline unsigned long virt_to_phys(volatile void * address)
39065 + return __pa((void *) address);
39068 +static inline void * phys_to_virt(unsigned long address)
39070 + return __va(address);
39074 diff -Naur -X ../exclude-files orig/include/asm-um/ipcbuf.h um/include/asm-um/ipcbuf.h
39075 --- orig/include/asm-um/ipcbuf.h 1969-12-31 19:00:00.000000000 -0500
39076 +++ um/include/asm-um/ipcbuf.h 2003-10-21 03:26:07.000000000 -0400
39078 +#ifndef __UM_IPCBUF_H
39079 +#define __UM_IPCBUF_H
39081 +#include "asm/arch/ipcbuf.h"
39084 diff -Naur -X ../exclude-files orig/include/asm-um/ipc.h um/include/asm-um/ipc.h
39085 --- orig/include/asm-um/ipc.h 1969-12-31 19:00:00.000000000 -0500
39086 +++ um/include/asm-um/ipc.h 2003-10-21 03:26:07.000000000 -0400
39088 +#ifndef __UM_IPC_H
39089 +#define __UM_IPC_H
39091 +#include "asm/arch/ipc.h"
39094 diff -Naur -X ../exclude-files orig/include/asm-um/irq.h um/include/asm-um/irq.h
39095 --- orig/include/asm-um/irq.h 1969-12-31 19:00:00.000000000 -0500
39096 +++ um/include/asm-um/irq.h 2003-10-21 03:26:07.000000000 -0400
39098 +#ifndef __UM_IRQ_H
39099 +#define __UM_IRQ_H
39101 +#define TIMER_IRQ 0
39103 +#define CONSOLE_IRQ 2
39104 +#define CONSOLE_WRITE_IRQ 3
39106 +#define UM_ETH_IRQ 5
39108 +#define SSL_WRITE_IRQ 7
39109 +#define ACCEPT_IRQ 8
39110 +#define MCONSOLE_IRQ 9
39111 +#define WINCH_IRQ 10
39112 +#define SIGIO_WRITE_IRQ 11
39113 +#define TELNETD_IRQ 12
39114 +#define XTERM_IRQ 13
39116 +#define LAST_IRQ XTERM_IRQ
39117 +#define NR_IRQS (LAST_IRQ + 1)
39120 diff -Naur -X ../exclude-files orig/include/asm-um/keyboard.h um/include/asm-um/keyboard.h
39121 --- orig/include/asm-um/keyboard.h 1969-12-31 19:00:00.000000000 -0500
39122 +++ um/include/asm-um/keyboard.h 2003-10-21 03:26:07.000000000 -0400
39124 +#ifndef __UM_KEYBOARD_H
39125 +#define __UM_KEYBOARD_H
39127 +#include "asm/arch/keyboard.h"
39130 diff -Naur -X ../exclude-files orig/include/asm-um/kmap_types.h um/include/asm-um/kmap_types.h
39131 --- orig/include/asm-um/kmap_types.h 1969-12-31 19:00:00.000000000 -0500
39132 +++ um/include/asm-um/kmap_types.h 2003-10-21 03:26:07.000000000 -0400
39135 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39136 + * Licensed under the GPL
39139 +#ifndef __UM_KMAP_TYPES_H
39140 +#define __UM_KMAP_TYPES_H
39142 +#include "asm/arch/kmap_types.h"
39145 diff -Naur -X ../exclude-files orig/include/asm-um/linux_logo.h um/include/asm-um/linux_logo.h
39146 --- orig/include/asm-um/linux_logo.h 1969-12-31 19:00:00.000000000 -0500
39147 +++ um/include/asm-um/linux_logo.h 2003-10-21 03:26:07.000000000 -0400
39149 +#ifndef __UM_LINUX_LOGO_H
39150 +#define __UM_LINUX_LOGO_H
39152 +#include "asm/arch/linux_logo.h"
39155 diff -Naur -X ../exclude-files orig/include/asm-um/locks.h um/include/asm-um/locks.h
39156 --- orig/include/asm-um/locks.h 1969-12-31 19:00:00.000000000 -0500
39157 +++ um/include/asm-um/locks.h 2003-10-21 03:26:07.000000000 -0400
39159 +#ifndef __UM_LOCKS_H
39160 +#define __UM_LOCKS_H
39162 +#include "asm/arch/locks.h"
39165 diff -Naur -X ../exclude-files orig/include/asm-um/mca_dma.h um/include/asm-um/mca_dma.h
39166 --- orig/include/asm-um/mca_dma.h 1969-12-31 19:00:00.000000000 -0500
39167 +++ um/include/asm-um/mca_dma.h 2003-10-21 03:26:07.000000000 -0400
39169 +#ifndef mca___UM_DMA_H
39170 +#define mca___UM_DMA_H
39172 +#include "asm/arch/mca_dma.h"
39175 diff -Naur -X ../exclude-files orig/include/asm-um/mman.h um/include/asm-um/mman.h
39176 --- orig/include/asm-um/mman.h 1969-12-31 19:00:00.000000000 -0500
39177 +++ um/include/asm-um/mman.h 2003-10-21 03:26:07.000000000 -0400
39179 +#ifndef __UM_MMAN_H
39180 +#define __UM_MMAN_H
39182 +#include "asm/arch/mman.h"
39185 diff -Naur -X ../exclude-files orig/include/asm-um/mmu_context.h um/include/asm-um/mmu_context.h
39186 --- orig/include/asm-um/mmu_context.h 1969-12-31 19:00:00.000000000 -0500
39187 +++ um/include/asm-um/mmu_context.h 2003-12-17 02:16:13.000000000 -0500
39190 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39191 + * Licensed under the GPL
39194 +#ifndef __UM_MMU_CONTEXT_H
39195 +#define __UM_MMU_CONTEXT_H
39197 +#include "linux/sched.h"
39198 +#include "choose-mode.h"
39200 +#define get_mmu_context(task) do ; while(0)
39201 +#define activate_context(tsk) do ; while(0)
39203 +static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
39207 +extern void switch_mm_skas(int mm_fd);
39209 +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
39210 + struct task_struct *tsk, unsigned cpu)
39212 + if(prev != next){
39213 + clear_bit(cpu, &prev->cpu_vm_mask);
39214 + set_bit(cpu, &next->cpu_vm_mask);
39215 + if(next != &init_mm)
39216 + CHOOSE_MODE((void) 0,
39217 + switch_mm_skas(next->context.skas.mm_fd));
39221 +static inline void enter_lazy_tlb(struct mm_struct *mm,
39222 + struct task_struct *tsk, unsigned cpu)
39226 +extern int init_new_context_skas(struct task_struct *task,
39227 + struct mm_struct *mm);
39229 +static inline int init_new_context_tt(struct task_struct *task,
39230 + struct mm_struct *mm)
39235 +static inline int init_new_context(struct task_struct *task,
39236 + struct mm_struct *mm)
39238 + return(CHOOSE_MODE_PROC(init_new_context_tt, init_new_context_skas,
39242 +extern void destroy_context_skas(struct mm_struct *mm);
39244 +static inline void destroy_context(struct mm_struct *mm)
39246 + CHOOSE_MODE((void) 0, destroy_context_skas(mm));
39252 + * Overrides for Emacs so that we follow Linus's tabbing style.
39253 + * Emacs will notice this stuff at the end of the file and automatically
39254 + * adjust the settings for this buffer only. This must remain at the end
39256 + * ---------------------------------------------------------------------------
39257 + * Local variables:
39258 + * c-file-style: "linux"
39261 diff -Naur -X ../exclude-files orig/include/asm-um/mmu.h um/include/asm-um/mmu.h
39262 --- orig/include/asm-um/mmu.h 1969-12-31 19:00:00.000000000 -0500
39263 +++ um/include/asm-um/mmu.h 2003-10-21 03:26:07.000000000 -0400
39266 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39267 + * Licensed under the GPL
39273 +#include "um_mmu.h"
39278 + * Overrides for Emacs so that we follow Linus's tabbing style.
39279 + * Emacs will notice this stuff at the end of the file and automatically
39280 + * adjust the settings for this buffer only. This must remain at the end
39282 + * ---------------------------------------------------------------------------
39283 + * Local variables:
39284 + * c-file-style: "linux"
39287 diff -Naur -X ../exclude-files orig/include/asm-um/module.h um/include/asm-um/module.h
39288 --- orig/include/asm-um/module.h 1969-12-31 19:00:00.000000000 -0500
39289 +++ um/include/asm-um/module.h 2003-10-21 03:26:07.000000000 -0400
39291 +#ifndef __UM_MODULE_H
39292 +#define __UM_MODULE_H
39294 +#include "asm/arch/module.h"
39297 diff -Naur -X ../exclude-files orig/include/asm-um/msgbuf.h um/include/asm-um/msgbuf.h
39298 --- orig/include/asm-um/msgbuf.h 1969-12-31 19:00:00.000000000 -0500
39299 +++ um/include/asm-um/msgbuf.h 2003-10-21 03:26:07.000000000 -0400
39301 +#ifndef __UM_MSGBUF_H
39302 +#define __UM_MSGBUF_H
39304 +#include "asm/arch/msgbuf.h"
39307 diff -Naur -X ../exclude-files orig/include/asm-um/mtrr.h um/include/asm-um/mtrr.h
39308 --- orig/include/asm-um/mtrr.h 1969-12-31 19:00:00.000000000 -0500
39309 +++ um/include/asm-um/mtrr.h 2003-12-17 10:48:33.000000000 -0500
39311 +#ifndef __UM_MTRR_H
39312 +#define __UM_MTRR_H
39314 +#include "asm/arch/mtrr.h"
39317 diff -Naur -X ../exclude-files orig/include/asm-um/namei.h um/include/asm-um/namei.h
39318 --- orig/include/asm-um/namei.h 1969-12-31 19:00:00.000000000 -0500
39319 +++ um/include/asm-um/namei.h 2003-10-21 03:26:07.000000000 -0400
39321 +#ifndef __UM_NAMEI_H
39322 +#define __UM_NAMEI_H
39324 +#include "asm/arch/namei.h"
39327 diff -Naur -X ../exclude-files orig/include/asm-um/page.h um/include/asm-um/page.h
39328 --- orig/include/asm-um/page.h 1969-12-31 19:00:00.000000000 -0500
39329 +++ um/include/asm-um/page.h 2003-12-15 00:26:37.000000000 -0500
39332 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
39333 + * Licensed under the GPL
39336 +#ifndef __UM_PAGE_H
39337 +#define __UM_PAGE_H
39341 +#include "asm/arch/page.h"
39347 +#undef virt_to_page
39349 +#undef PAGE_OFFSET
39352 +extern unsigned long uml_physmem;
39354 +#define PAGE_OFFSET (uml_physmem)
39355 +#define KERNELBASE PAGE_OFFSET
39357 +#ifndef __ASSEMBLY__
39359 +extern void stop(void);
39361 +#define BUG() do { \
39362 + panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
39365 +#define PAGE_BUG(page) do { \
39369 +#endif /* __ASSEMBLY__ */
39371 +#define __va_space (8*1024*1024)
39373 +extern unsigned long to_phys(void *virt);
39374 +extern void *to_virt(unsigned long phys);
39376 +#define __pa(virt) to_phys((void *) virt)
39377 +#define __va(phys) to_virt((unsigned long) phys)
39379 +#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
39381 +extern struct page *arch_validate(struct page *page, int mask, int order);
39382 +#define HAVE_ARCH_VALIDATE
39384 +extern void arch_free_page(struct page *page, int order);
39385 +#define HAVE_ARCH_FREE_PAGE
39390 + * Overrides for Emacs so that we follow Linus's tabbing style.
39391 + * Emacs will notice this stuff at the end of the file and automatically
39392 + * adjust the settings for this buffer only. This must remain at the end
39394 + * ---------------------------------------------------------------------------
39395 + * Local variables:
39396 + * c-file-style: "linux"
39399 diff -Naur -X ../exclude-files orig/include/asm-um/page_offset.h um/include/asm-um/page_offset.h
39400 --- orig/include/asm-um/page_offset.h 1969-12-31 19:00:00.000000000 -0500
39401 +++ um/include/asm-um/page_offset.h 2003-10-21 03:26:07.000000000 -0400
39403 +#define PAGE_OFFSET_RAW (uml_physmem)
39404 diff -Naur -X ../exclude-files orig/include/asm-um/param.h um/include/asm-um/param.h
39405 --- orig/include/asm-um/param.h 1969-12-31 19:00:00.000000000 -0500
39406 +++ um/include/asm-um/param.h 2003-10-21 03:26:07.000000000 -0400
39408 +#ifndef _UM_PARAM_H
39409 +#define _UM_PARAM_H
39415 +#define EXEC_PAGESIZE 4096
39418 +#define NGROUPS 32
39422 +#define NOGROUP (-1)
39425 +#define MAXHOSTNAMELEN 64 /* max length of hostname */
39428 +# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */
39432 diff -Naur -X ../exclude-files orig/include/asm-um/pci.h um/include/asm-um/pci.h
39433 --- orig/include/asm-um/pci.h 1969-12-31 19:00:00.000000000 -0500
39434 +++ um/include/asm-um/pci.h 2003-10-21 03:26:07.000000000 -0400
39436 +#ifndef __UM_PCI_H
39437 +#define __UM_PCI_H
39439 +#define PCI_DMA_BUS_IS_PHYS (1)
39442 diff -Naur -X ../exclude-files orig/include/asm-um/pgalloc.h um/include/asm-um/pgalloc.h
39443 --- orig/include/asm-um/pgalloc.h 1969-12-31 19:00:00.000000000 -0500
39444 +++ um/include/asm-um/pgalloc.h 2003-12-17 02:16:14.000000000 -0500
39447 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
39448 + * Derived from include/asm-i386/pgalloc.h and include/asm-i386/pgtable.h
39449 + * Licensed under the GPL
39452 +#ifndef __UM_PGALLOC_H
39453 +#define __UM_PGALLOC_H
39455 +#include "linux/config.h"
39456 +#include "linux/mm.h"
39457 +#include "asm/fixmap.h"
39458 +#include "choose-mode.h"
39460 +#define pgd_quicklist (current_cpu_data.pgd_quick)
39461 +#define pmd_quicklist (current_cpu_data.pmd_quick)
39462 +#define pte_quicklist (current_cpu_data.pte_quick)
39463 +#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
39465 +#define pmd_populate(mm, pmd, pte) set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
39468 + * Allocate and free page tables.
39471 +static inline pgd_t *get_pgd_slow_tt(void)
39473 + pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
39476 + memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
39477 + memcpy(pgd + USER_PTRS_PER_PGD,
39478 + swapper_pg_dir + USER_PTRS_PER_PGD,
39479 + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
39484 +static inline pgd_t *get_pgd_slow_skas(void)
39486 + pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
39489 + memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
39493 +static inline pgd_t *get_pgd_slow(void)
39495 + return(CHOOSE_MODE(get_pgd_slow_tt(), get_pgd_slow_skas()));
39498 +static inline pgd_t *get_pgd_fast(void)
39500 + unsigned long *ret;
39502 + ret = pgd_quicklist;
39503 + if (ret != NULL) {
39504 + pgd_quicklist = (unsigned long *)(*ret);
39506 + pgtable_cache_size--;
39508 + ret = (unsigned long *)get_pgd_slow();
39509 + return (pgd_t *)ret;
39512 +static inline void free_pgd_fast(pgd_t *pgd)
39514 + *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
39515 + pgd_quicklist = (unsigned long *) pgd;
39516 + pgtable_cache_size++;
39519 +static inline void free_pgd_slow(pgd_t *pgd)
39521 + free_page((unsigned long)pgd);
39524 +static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
39528 + pte = (pte_t *) __get_free_page(GFP_KERNEL);
39534 +static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
39536 + unsigned long *ret;
39538 + ret = (unsigned long *)pte_quicklist;
39539 + if (ret != NULL) {
39540 + pte_quicklist = (unsigned long *)(*ret);
39542 + pgtable_cache_size--;
39544 + return (pte_t *)ret;
39547 +static inline void pte_free_fast(pte_t *pte)
39549 + *(unsigned long *)pte = (unsigned long) pte_quicklist;
39550 + pte_quicklist = (unsigned long *) pte;
39551 + pgtable_cache_size++;
39554 +static inline void pte_free_slow(pte_t *pte)
39556 + free_page((unsigned long)pte);
39559 +#define pte_free(pte) pte_free_fast(pte)
39560 +#define pgd_free(pgd) free_pgd_slow(pgd)
39561 +#define pgd_alloc(mm) get_pgd_fast()
39564 + * allocating and freeing a pmd is trivial: the 1-entry pmd is
39565 + * inside the pgd, so has no extra memory associated with it.
39568 +#define pmd_alloc_one_fast(mm, addr) ({ BUG(); ((pmd_t *)1); })
39569 +#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
39570 +#define pmd_free_slow(x) do { } while (0)
39571 +#define pmd_free_fast(x) do { } while (0)
39572 +#define pmd_free(x) do { } while (0)
39573 +#define pgd_populate(mm, pmd, pte) BUG()
39578 + * - flush_tlb() flushes the current mm struct TLBs
39579 + * - flush_tlb_all() flushes all processes TLBs
39580 + * - flush_tlb_mm(mm) flushes the specified mm context TLB's
39581 + * - flush_tlb_page(vma, vmaddr) flushes one page
39582 + * - flush_tlb_kernel_vm() flushes the kernel vm area
39583 + * - flush_tlb_range(mm, start, end) flushes a range of pages
39584 + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
39587 +extern void flush_tlb_all(void);
39588 +extern void flush_tlb_mm(struct mm_struct *mm);
39589 +extern void flush_tlb_range(struct mm_struct *mm, unsigned long start,
39590 + unsigned long end);
39591 +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
39592 +extern void flush_tlb_kernel_vm(void);
39594 +static inline void flush_tlb_pgtables(struct mm_struct *mm,
39595 + unsigned long start, unsigned long end)
39601 + * Overrides for Emacs so that we follow Linus's tabbing style.
39602 + * Emacs will notice this stuff at the end of the file and automatically
39603 + * adjust the settings for this buffer only. This must remain at the end
39605 + * ---------------------------------------------------------------------------
39606 + * Local variables:
39607 + * c-file-style: "linux"
39610 diff -Naur -X ../exclude-files orig/include/asm-um/pgtable.h um/include/asm-um/pgtable.h
39611 --- orig/include/asm-um/pgtable.h 1969-12-31 19:00:00.000000000 -0500
39612 +++ um/include/asm-um/pgtable.h 2003-12-17 02:16:13.000000000 -0500
39615 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
39616 + * Derived from include/asm-i386/pgtable.h
39617 + * Licensed under the GPL
39620 +#ifndef __UM_PGTABLE_H
39621 +#define __UM_PGTABLE_H
39623 +#include "linux/sched.h"
39624 +#include "asm/processor.h"
39625 +#include "asm/page.h"
39627 +extern pgd_t swapper_pg_dir[1024];
39629 +#define flush_cache_all() do ; while (0)
39630 +#define flush_cache_mm(mm) do ; while (0)
39631 +#define flush_cache_range(vma, start, end) do ; while (0)
39632 +#define flush_cache_page(vma, vmaddr) do ; while (0)
39633 +#define flush_page_to_ram(page) do ; while (0)
39634 +#define flush_dcache_page(page) do ; while (0)
39635 +#define flush_icache_range(from, to) do ; while (0)
39636 +#define flush_icache_page(vma,pg) do ; while (0)
39637 +#define flush_icache_user_range(vma,pg,adr,len) do ; while (0)
39639 +extern void __flush_tlb_one(unsigned long addr);
39641 +extern void pte_free(pte_t *pte);
39643 +extern void pgd_free(pgd_t *pgd);
39645 +extern int do_check_pgt_cache(int, int);
39647 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
39650 +/* zero page used for uninitialized stuff */
39651 +extern unsigned long *empty_zero_page;
39653 +#define pgtable_cache_init() do ; while (0)
39655 +/* PMD_SHIFT determines the size of the area a second-level page table can map */
39656 +#define PMD_SHIFT 22
39657 +#define PMD_SIZE (1UL << PMD_SHIFT)
39658 +#define PMD_MASK (~(PMD_SIZE-1))
39660 +/* PGDIR_SHIFT determines what a third-level page table entry can map */
39661 +#define PGDIR_SHIFT 22
39662 +#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
39663 +#define PGDIR_MASK (~(PGDIR_SIZE-1))
39666 + * entries per page directory level: the i386 is two-level, so
39667 + * we don't really have any PMD directory physically.
39669 +#define PTRS_PER_PTE 1024
39670 +#define PTRS_PER_PMD 1
39671 +#define PTRS_PER_PGD 1024
39672 +#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
39673 +#define FIRST_USER_PGD_NR 0
39675 +#define pte_ERROR(e) \
39676 + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
39677 +#define pmd_ERROR(e) \
39678 + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
39679 +#define pgd_ERROR(e) \
39680 + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
39683 + * pgd entries used up by user/kernel:
39686 +#define USER_PGD_PTRS (TASK_SIZE >> PGDIR_SHIFT)
39687 +#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
39689 +#ifndef __ASSEMBLY__
39690 +/* Just any arbitrary offset to the start of the vmalloc VM area: the
39691 + * current 8MB value just means that there will be a 8MB "hole" after the
39692 + * physical memory until the kernel virtual memory starts. That means that
39693 + * any out-of-bounds memory accesses will hopefully be caught.
39694 + * The vmalloc() routines leaves a hole of 4kB between each vmalloced
39695 + * area for the same reason. ;)
39698 +extern unsigned long end_iomem;
39700 +#define VMALLOC_OFFSET (__va_space)
39701 +#define VMALLOC_START ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
39702 +#define VMALLOC_VMADDR(x) ((unsigned long)(x))
39704 +#if CONFIG_HIGHMEM
39705 +# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
39707 +# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
39710 +#define _PAGE_PRESENT 0x001
39711 +#define _PAGE_NEWPAGE 0x002
39712 +#define _PAGE_PROTNONE 0x004 /* If not present */
39713 +#define _PAGE_RW 0x008
39714 +#define _PAGE_USER 0x010
39715 +#define _PAGE_ACCESSED 0x020
39716 +#define _PAGE_DIRTY 0x040
39717 +#define _PAGE_NEWPROT 0x080
39719 +#define REGION_MASK 0xf0000000
39720 +#define REGION_SHIFT 28
39722 +#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
39723 +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
39724 +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
39726 +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
39727 +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
39728 +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
39729 +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
39730 +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
39731 +#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
39734 + * The i386 can't do page protection for execute, and considers that the same are read.
39735 + * Also, write permissions imply read permissions. This is the closest we can get..
39737 +#define __P000 PAGE_NONE
39738 +#define __P001 PAGE_READONLY
39739 +#define __P010 PAGE_COPY
39740 +#define __P011 PAGE_COPY
39741 +#define __P100 PAGE_READONLY
39742 +#define __P101 PAGE_READONLY
39743 +#define __P110 PAGE_COPY
39744 +#define __P111 PAGE_COPY
39746 +#define __S000 PAGE_NONE
39747 +#define __S001 PAGE_READONLY
39748 +#define __S010 PAGE_SHARED
39749 +#define __S011 PAGE_SHARED
39750 +#define __S100 PAGE_READONLY
39751 +#define __S101 PAGE_READONLY
39752 +#define __S110 PAGE_SHARED
39753 +#define __S111 PAGE_SHARED
39756 + * Define this if things work differently on an i386 and an i486:
39757 + * it will (on an i486) warn about kernel memory accesses that are
39758 + * done without a 'verify_area(VERIFY_WRITE,..)'
39760 +#undef TEST_VERIFY_AREA
39762 +/* page table for 0-4MB for everybody */
39763 +extern unsigned long pg0[1024];
39766 + * BAD_PAGETABLE is used when we need a bogus page-table, while
39767 + * BAD_PAGE is used for a bogus page.
39769 + * ZERO_PAGE is a global shared page that is always zero: used
39770 + * for zero-mapped memory areas etc..
39772 +extern pte_t __bad_page(void);
39773 +extern pte_t * __bad_pagetable(void);
39775 +#define BAD_PAGETABLE __bad_pagetable()
39776 +#define BAD_PAGE __bad_page()
39778 +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
39780 +/* number of bits that fit into a memory pointer */
39781 +#define BITS_PER_PTR (8*sizeof(unsigned long))
39783 +/* to align the pointer to a pointer address */
39784 +#define PTR_MASK (~(sizeof(void*)-1))
39786 +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
39787 +/* 64-bit machines, beware! SRB. */
39788 +#define SIZEOF_PTR_LOG2 2
39790 +/* to find an entry in a page-table */
39791 +#define PAGE_PTR(address) \
39792 +((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
39794 +#define pte_none(x) !(pte_val(x) & ~_PAGE_NEWPAGE)
39795 +#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
39797 +#define pte_clear(xp) do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
39799 +#define pmd_none(x) (!(pmd_val(x) & ~_PAGE_NEWPAGE))
39800 +#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
39801 +#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
39802 +#define pmd_clear(xp) do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
39804 +#define pmd_newpage(x) (pmd_val(x) & _PAGE_NEWPAGE)
39805 +#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE)
39808 + * The "pgd_xxx()" functions here are trivial for a folded two-level
39809 + * setup: the pgd is never bad, and a pmd always exists (as it's folded
39810 + * into the pgd entry)
39812 +static inline int pgd_none(pgd_t pgd) { return 0; }
39813 +static inline int pgd_bad(pgd_t pgd) { return 0; }
39814 +static inline int pgd_present(pgd_t pgd) { return 1; }
39815 +static inline void pgd_clear(pgd_t * pgdp) { }
39817 +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
39819 +#define pte_page(pte) virt_to_page(__va(pte_val(pte)))
39820 +#define pmd_page(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
39822 +extern struct page *phys_to_page(const unsigned long phys);
39823 +extern struct page *__virt_to_page(const unsigned long virt);
39824 +#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
39826 +static inline pte_t pte_mknewprot(pte_t pte)
39828 + pte_val(pte) |= _PAGE_NEWPROT;
39832 +static inline pte_t pte_mknewpage(pte_t pte)
39834 + pte_val(pte) |= _PAGE_NEWPAGE;
39838 +static inline void set_pte(pte_t *pteptr, pte_t pteval)
39840 + /* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so
39841 + * fix_range knows to unmap it. _PAGE_NEWPROT is specific to
39844 + *pteptr = pte_mknewpage(pteval);
39845 + if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr);
39849 + * (pmds are folded into pgds so this doesnt get actually called,
39850 + * but the define is needed for a generic inline function.)
39852 +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
39853 +#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
39856 + * The following only work if pte_present() is true.
39857 + * Undefined behaviour if not..
39859 +static inline int pte_read(pte_t pte)
39861 + return((pte_val(pte) & _PAGE_USER) &&
39862 + !(pte_val(pte) & _PAGE_PROTNONE));
39865 +static inline int pte_exec(pte_t pte){
39866 + return((pte_val(pte) & _PAGE_USER) &&
39867 + !(pte_val(pte) & _PAGE_PROTNONE));
39870 +static inline int pte_write(pte_t pte)
39872 + return((pte_val(pte) & _PAGE_RW) &&
39873 + !(pte_val(pte) & _PAGE_PROTNONE));
39876 +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
39877 +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
39878 +static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
39879 +static inline int pte_newprot(pte_t pte)
39881 + return(pte_present(pte) && (pte_val(pte) & _PAGE_NEWPROT));
39884 +static inline pte_t pte_rdprotect(pte_t pte)
39886 + pte_val(pte) &= ~_PAGE_USER;
39887 + return(pte_mknewprot(pte));
39890 +static inline pte_t pte_exprotect(pte_t pte)
39892 + pte_val(pte) &= ~_PAGE_USER;
39893 + return(pte_mknewprot(pte));
39896 +static inline pte_t pte_mkclean(pte_t pte)
39898 + pte_val(pte) &= ~_PAGE_DIRTY;
39902 +static inline pte_t pte_mkold(pte_t pte)
39904 + pte_val(pte) &= ~_PAGE_ACCESSED;
39908 +static inline pte_t pte_wrprotect(pte_t pte)
39910 + pte_val(pte) &= ~_PAGE_RW;
39911 + return(pte_mknewprot(pte));
39914 +static inline pte_t pte_mkread(pte_t pte)
39916 + pte_val(pte) |= _PAGE_USER;
39917 + return(pte_mknewprot(pte));
39920 +static inline pte_t pte_mkexec(pte_t pte)
39922 + pte_val(pte) |= _PAGE_USER;
39923 + return(pte_mknewprot(pte));
39926 +static inline pte_t pte_mkdirty(pte_t pte)
39928 + pte_val(pte) |= _PAGE_DIRTY;
39932 +static inline pte_t pte_mkyoung(pte_t pte)
39934 + pte_val(pte) |= _PAGE_ACCESSED;
39938 +static inline pte_t pte_mkwrite(pte_t pte)
39940 + pte_val(pte) |= _PAGE_RW;
39941 + return(pte_mknewprot(pte));
39944 +static inline pte_t pte_mkuptodate(pte_t pte)
39946 + pte_val(pte) &= ~_PAGE_NEWPAGE;
39947 + if(pte_present(pte)) pte_val(pte) &= ~_PAGE_NEWPROT;
39951 +extern unsigned long page_to_phys(struct page *page);
39954 + * Conversion functions: convert a page and protection to a page entry,
39955 + * and a page entry and page directory to the page they refer to.
39958 +extern pte_t mk_pte(struct page *page, pgprot_t pgprot);
39960 +/* This takes a physical page address that is used by the remapping
39963 +#define mk_pte_phys(phys, pgprot) \
39964 + (pte_mknewpage(mk_pte(virt_to_page(__va(phys)), pgprot)))
39966 +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
39968 + pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
39969 + if(pte_present(pte)) pte = pte_mknewpage(pte_mknewprot(pte));
39973 +/* to find an entry in a page-table-directory. */
39974 +#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
39975 +#define __pgd_offset(address) pgd_index(address)
39977 +/* to find an entry in a page-table-directory */
39978 +#define pgd_offset(mm, address) \
39979 +((mm)->pgd + ((address) >> PGDIR_SHIFT))
39981 +/* to find an entry in a kernel page-table-directory */
39982 +#define pgd_offset_k(address) pgd_offset(&init_mm, address)
39984 +#define __pmd_offset(address) \
39985 + (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
39987 +/* Find an entry in the second-level page table.. */
39988 +static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
39990 + return (pmd_t *) dir;
39993 +/* Find an entry in the third-level page table.. */
39994 +#define pte_offset(pmd, address) \
39995 + ((pte_t *) (pmd_page(*pmd) + ((address>>10) & ((PTRS_PER_PTE-1)<<2))))
39997 +#define update_mmu_cache(vma,address,pte) do ; while (0)
39999 +/* Encode and de-code a swap entry */
40000 +#define SWP_TYPE(x) (((x).val >> 3) & 0x7f)
40001 +#define SWP_OFFSET(x) ((x).val >> 10)
40003 +#define SWP_ENTRY(type, offset) \
40004 + ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
40005 +#define pte_to_swp_entry(pte) \
40006 + ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
40007 +#define swp_entry_to_pte(x) ((pte_t) { (x).val })
40009 +#define PageSkip(x) (0)
40010 +#define kern_addr_valid(addr) (1)
40012 +#include <asm-generic/pgtable.h>
40018 + * Overrides for Emacs so that we follow Linus's tabbing style.
40019 + * Emacs will notice this stuff at the end of the file and automatically
40020 + * adjust the settings for this buffer only. This must remain at the end
40022 + * ---------------------------------------------------------------------------
40023 + * Local variables:
40024 + * c-file-style: "linux"
40027 diff -Naur -X ../exclude-files orig/include/asm-um/poll.h um/include/asm-um/poll.h
40028 --- orig/include/asm-um/poll.h 1969-12-31 19:00:00.000000000 -0500
40029 +++ um/include/asm-um/poll.h 2003-10-21 03:26:07.000000000 -0400
40031 +#ifndef __UM_POLL_H
40032 +#define __UM_POLL_H
40034 +#include "asm/arch/poll.h"
40037 diff -Naur -X ../exclude-files orig/include/asm-um/posix_types.h um/include/asm-um/posix_types.h
40038 --- orig/include/asm-um/posix_types.h 1969-12-31 19:00:00.000000000 -0500
40039 +++ um/include/asm-um/posix_types.h 2003-10-21 03:26:07.000000000 -0400
40041 +#ifndef __UM_POSIX_TYPES_H
40042 +#define __UM_POSIX_TYPES_H
40044 +#include "asm/arch/posix_types.h"
40047 diff -Naur -X ../exclude-files orig/include/asm-um/processor-generic.h um/include/asm-um/processor-generic.h
40048 --- orig/include/asm-um/processor-generic.h 1969-12-31 19:00:00.000000000 -0500
40049 +++ um/include/asm-um/processor-generic.h 2003-12-17 02:16:13.000000000 -0500
40052 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
40053 + * Licensed under the GPL
40056 +#ifndef __UM_PROCESSOR_GENERIC_H
40057 +#define __UM_PROCESSOR_GENERIC_H
40061 +struct task_struct;
40063 +#include "linux/config.h"
40064 +#include "linux/signal.h"
40065 +#include "asm/ptrace.h"
40066 +#include "asm/siginfo.h"
40067 +#include "choose-mode.h"
40071 +#define current_text_addr() ((void *) 0)
40073 +#define cpu_relax() do ; while (0)
40075 +struct thread_struct {
40077 + unsigned long kernel_stack;
40079 + struct pt_regs regs;
40080 + unsigned long cr2;
40082 + unsigned long trap_no;
40083 + void *fault_addr;
40084 + void *fault_catcher;
40085 + struct task_struct *prev_sched;
40086 + unsigned long temp_stack;
40088 + struct arch_thread arch;
40090 +#ifdef CONFIG_MODE_TT
40094 + int switch_pipe[2];
40095 + int singlestep_syscall;
40099 +#ifdef CONFIG_MODE_SKAS
40101 + void *switch_buf;
40114 + int (*proc)(void *);
40118 + void (*proc)(void *);
40125 +#define INIT_THREAD \
40128 + .kernel_stack = 0, \
40129 + .nsyscalls = 0, \
40130 + .regs = EMPTY_REGS, \
40133 + .fault_addr = NULL, \
40134 + .prev_sched = NULL, \
40135 + .temp_stack = 0, \
40136 + .exec_buf = NULL, \
40137 + .arch = INIT_ARCH_THREAD, \
40138 + .request = { 0 } \
40141 +#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
40144 + unsigned long seg;
40147 +extern struct task_struct *alloc_task_struct(void);
40148 +extern void free_task_struct(struct task_struct *task);
40150 +#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count)
40152 +extern void release_thread(struct task_struct *);
40153 +extern int arch_kernel_thread(int (*fn)(void *), void * arg,
40154 + unsigned long flags);
40155 +extern void dump_thread(struct pt_regs *regs, struct user *u);
40157 +extern unsigned long thread_saved_pc(struct thread_struct *t);
40159 +static inline void mm_copy_segments(struct mm_struct *from_mm,
40160 + struct mm_struct *new_mm)
40164 +static inline void copy_segments(struct task_struct *p,
40165 + struct mm_struct *new_mm)
40169 +static inline void release_segments(struct mm_struct *mm)
40173 +#define init_task (init_task_union.task)
40174 +#define init_stack (init_task_union.stack)
40177 + * User space process size: 3GB (default).
40179 +extern unsigned long task_size;
40181 +#define TASK_SIZE (task_size)
40183 +/* This decides where the kernel will search for a free chunk of vm
40184 + * space during mmap's.
40186 +#define TASK_UNMAPPED_BASE (0x40000000)
40188 +extern void start_thread(struct pt_regs *regs, unsigned long entry,
40189 + unsigned long stack);
40191 +struct cpuinfo_um {
40192 + unsigned long loops_per_jiffy;
40193 + unsigned long *pgd_quick;
40194 + unsigned long *pmd_quick;
40195 + unsigned long *pte_quick;
40196 + unsigned long pgtable_cache_sz;
40200 +extern struct cpuinfo_um boot_cpu_data;
40202 +#define my_cpu_data cpu_data[smp_processor_id()]
40205 +extern struct cpuinfo_um cpu_data[];
40206 +#define current_cpu_data cpu_data[smp_processor_id()]
40208 +#define cpu_data (&boot_cpu_data)
40209 +#define current_cpu_data boot_cpu_data
40212 +#define KSTK_EIP(tsk) (PT_REGS_IP(&tsk->thread.regs))
40213 +#define KSTK_ESP(tsk) (PT_REGS_SP(&tsk->thread.regs))
40214 +#define get_wchan(p) (0)
40219 + * Overrides for Emacs so that we follow Linus's tabbing style.
40220 + * Emacs will notice this stuff at the end of the file and automatically
40221 + * adjust the settings for this buffer only. This must remain at the end
40223 + * ---------------------------------------------------------------------------
40224 + * Local variables:
40225 + * c-file-style: "linux"
40228 diff -Naur -X ../exclude-files orig/include/asm-um/processor-i386.h um/include/asm-um/processor-i386.h
40229 --- orig/include/asm-um/processor-i386.h 1969-12-31 19:00:00.000000000 -0500
40230 +++ um/include/asm-um/processor-i386.h 2003-12-17 02:16:13.000000000 -0500
40233 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40234 + * Licensed under the GPL
40237 +#ifndef __UM_PROCESSOR_I386_H
40238 +#define __UM_PROCESSOR_I386_H
40240 +extern int cpu_has_xmm;
40241 +extern int cpu_has_cmov;
40243 +struct arch_thread {
40244 + unsigned long debugregs[8];
40245 + int debugregs_seq;
40248 +#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \
40249 + .debugregs_seq = 0 }
40251 +#include "asm/arch/user.h"
40253 +#include "asm/processor-generic.h"
40258 + * Overrides for Emacs so that we follow Linus's tabbing style.
40259 + * Emacs will notice this stuff at the end of the file and automatically
40260 + * adjust the settings for this buffer only. This must remain at the end
40262 + * ---------------------------------------------------------------------------
40263 + * Local variables:
40264 + * c-file-style: "linux"
40267 diff -Naur -X ../exclude-files orig/include/asm-um/processor-ppc.h um/include/asm-um/processor-ppc.h
40268 --- orig/include/asm-um/processor-ppc.h 1969-12-31 19:00:00.000000000 -0500
40269 +++ um/include/asm-um/processor-ppc.h 2003-10-21 03:26:07.000000000 -0400
40271 +#ifndef __UM_PROCESSOR_PPC_H
40272 +#define __UM_PROCESSOR_PPC_H
40274 +#if defined(__ASSEMBLY__)
40276 +#define CONFIG_ALL_PPC
40277 +#include "arch/processor.h"
40281 +#include "asm/processor-generic.h"
40286 diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-generic.h um/include/asm-um/ptrace-generic.h
40287 --- orig/include/asm-um/ptrace-generic.h 1969-12-31 19:00:00.000000000 -0500
40288 +++ um/include/asm-um/ptrace-generic.h 2003-12-17 02:16:13.000000000 -0500
40291 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
40292 + * Licensed under the GPL
40295 +#ifndef __UM_PTRACE_GENERIC_H
40296 +#define __UM_PTRACE_GENERIC_H
40298 +#ifndef __ASSEMBLY__
40300 +#include "linux/config.h"
40302 +#include "asm/current.h"
40304 +#define pt_regs pt_regs_subarch
40305 +#define show_regs show_regs_subarch
40307 +#include "asm/arch/ptrace.h"
40312 +#undef instruction_pointer
40314 +#include "sysdep/ptrace.h"
40315 +#include "skas_ptrace.h"
40318 + union uml_pt_regs regs;
40321 +#define EMPTY_REGS { regs : EMPTY_UML_PT_REGS }
40323 +#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
40324 +#define PT_REGS_SP(r) UPT_SP(&(r)->regs)
40326 +#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg)
40327 +#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val)
40329 +#define PT_REGS_SET_SYSCALL_RETURN(r, res) \
40330 + UPT_SET_SYSCALL_RETURN(&(r)->regs, res)
40331 +#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs)
40333 +#define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs)
40335 +#define PT_REGS_SC(r) UPT_SC(&(r)->regs)
40337 +struct task_struct;
40339 +extern unsigned long getreg(struct task_struct *child, int regno);
40340 +extern int putreg(struct task_struct *child, int regno, unsigned long value);
40341 +extern int get_fpregs(unsigned long buf, struct task_struct *child);
40342 +extern int set_fpregs(unsigned long buf, struct task_struct *child);
40343 +extern int get_fpxregs(unsigned long buf, struct task_struct *child);
40344 +extern int set_fpxregs(unsigned long buf, struct task_struct *tsk);
40346 +extern void show_regs(struct pt_regs *regs);
40348 +#define INIT_TASK_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
40355 + * Overrides for Emacs so that we follow Linus's tabbing style.
40356 + * Emacs will notice this stuff at the end of the file and automatically
40357 + * adjust the settings for this buffer only. This must remain at the end
40359 + * ---------------------------------------------------------------------------
40360 + * Local variables:
40361 + * c-file-style: "linux"
40364 diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-i386.h um/include/asm-um/ptrace-i386.h
40365 --- orig/include/asm-um/ptrace-i386.h 1969-12-31 19:00:00.000000000 -0500
40366 +++ um/include/asm-um/ptrace-i386.h 2003-12-17 02:16:13.000000000 -0500
40369 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
40370 + * Licensed under the GPL
40373 +#ifndef __UM_PTRACE_I386_H
40374 +#define __UM_PTRACE_I386_H
40376 +#include "sysdep/ptrace.h"
40377 +#include "asm/ptrace-generic.h"
40379 +#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
40380 +#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs)
40381 +#define PT_REGS_ECX(r) UPT_ECX(&(r)->regs)
40382 +#define PT_REGS_EDX(r) UPT_EDX(&(r)->regs)
40383 +#define PT_REGS_ESI(r) UPT_ESI(&(r)->regs)
40384 +#define PT_REGS_EDI(r) UPT_EDI(&(r)->regs)
40385 +#define PT_REGS_EBP(r) UPT_EBP(&(r)->regs)
40387 +#define PT_REGS_CS(r) UPT_CS(&(r)->regs)
40388 +#define PT_REGS_SS(r) UPT_SS(&(r)->regs)
40389 +#define PT_REGS_DS(r) UPT_DS(&(r)->regs)
40390 +#define PT_REGS_ES(r) UPT_ES(&(r)->regs)
40391 +#define PT_REGS_FS(r) UPT_FS(&(r)->regs)
40392 +#define PT_REGS_GS(r) UPT_GS(&(r)->regs)
40394 +#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs)
40396 +#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_EAX(r)
40397 +#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r)
40398 +#define PT_FIX_EXEC_STACK(sp) do ; while(0)
40400 +#define user_mode(r) UPT_IS_USER(&(r)->regs)
40405 + * Overrides for Emacs so that we follow Linus's tabbing style.
40406 + * Emacs will notice this stuff at the end of the file and automatically
40407 + * adjust the settings for this buffer only. This must remain at the end
40409 + * ---------------------------------------------------------------------------
40410 + * Local variables:
40411 + * c-file-style: "linux"
40414 diff -Naur -X ../exclude-files orig/include/asm-um/resource.h um/include/asm-um/resource.h
40415 --- orig/include/asm-um/resource.h 1969-12-31 19:00:00.000000000 -0500
40416 +++ um/include/asm-um/resource.h 2003-10-21 03:26:07.000000000 -0400
40418 +#ifndef __UM_RESOURCE_H
40419 +#define __UM_RESOURCE_H
40421 +#include "asm/arch/resource.h"
40424 diff -Naur -X ../exclude-files orig/include/asm-um/rwlock.h um/include/asm-um/rwlock.h
40425 --- orig/include/asm-um/rwlock.h 1969-12-31 19:00:00.000000000 -0500
40426 +++ um/include/asm-um/rwlock.h 2003-10-21 03:26:07.000000000 -0400
40428 +#ifndef __UM_RWLOCK_H
40429 +#define __UM_RWLOCK_H
40431 +#include "asm/arch/rwlock.h"
40434 diff -Naur -X ../exclude-files orig/include/asm-um/rwsem.h um/include/asm-um/rwsem.h
40435 --- orig/include/asm-um/rwsem.h 1969-12-31 19:00:00.000000000 -0500
40436 +++ um/include/asm-um/rwsem.h 2003-12-17 02:16:13.000000000 -0500
40438 +#ifndef __UM_RWSEM_H__
40439 +#define __UM_RWSEM_H__
40441 +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
40442 +#define __builtin_expect(exp,c) (exp)
40445 +#include "asm/arch/rwsem.h"
40448 diff -Naur -X ../exclude-files orig/include/asm-um/scatterlist.h um/include/asm-um/scatterlist.h
40449 --- orig/include/asm-um/scatterlist.h 1969-12-31 19:00:00.000000000 -0500
40450 +++ um/include/asm-um/scatterlist.h 2003-10-21 03:26:07.000000000 -0400
40452 +#ifndef __UM_SCATTERLIST_H
40453 +#define __UM_SCATTERLIST_H
40455 +#include "asm/arch/scatterlist.h"
40458 diff -Naur -X ../exclude-files orig/include/asm-um/segment.h um/include/asm-um/segment.h
40459 --- orig/include/asm-um/segment.h 1969-12-31 19:00:00.000000000 -0500
40460 +++ um/include/asm-um/segment.h 2003-10-21 03:26:07.000000000 -0400
40462 +#ifndef __UM_SEGMENT_H
40463 +#define __UM_SEGMENT_H
40466 diff -Naur -X ../exclude-files orig/include/asm-um/semaphore.h um/include/asm-um/semaphore.h
40467 --- orig/include/asm-um/semaphore.h 1969-12-31 19:00:00.000000000 -0500
40468 +++ um/include/asm-um/semaphore.h 2003-12-17 02:16:13.000000000 -0500
40470 +#ifndef __UM_SEMAPHORE_H
40471 +#define __UM_SEMAPHORE_H
40473 +#include "asm/arch/semaphore.h"
40476 diff -Naur -X ../exclude-files orig/include/asm-um/sembuf.h um/include/asm-um/sembuf.h
40477 --- orig/include/asm-um/sembuf.h 1969-12-31 19:00:00.000000000 -0500
40478 +++ um/include/asm-um/sembuf.h 2003-10-21 03:26:07.000000000 -0400
40480 +#ifndef __UM_SEMBUF_H
40481 +#define __UM_SEMBUF_H
40483 +#include "asm/arch/sembuf.h"
40486 diff -Naur -X ../exclude-files orig/include/asm-um/serial.h um/include/asm-um/serial.h
40487 --- orig/include/asm-um/serial.h 1969-12-31 19:00:00.000000000 -0500
40488 +++ um/include/asm-um/serial.h 2003-10-21 03:26:07.000000000 -0400
40490 +#ifndef __UM_SERIAL_H
40491 +#define __UM_SERIAL_H
40493 +#include "asm/arch/serial.h"
40496 diff -Naur -X ../exclude-files orig/include/asm-um/shmbuf.h um/include/asm-um/shmbuf.h
40497 --- orig/include/asm-um/shmbuf.h 1969-12-31 19:00:00.000000000 -0500
40498 +++ um/include/asm-um/shmbuf.h 2003-10-21 03:26:07.000000000 -0400
40500 +#ifndef __UM_SHMBUF_H
40501 +#define __UM_SHMBUF_H
40503 +#include "asm/arch/shmbuf.h"
40506 diff -Naur -X ../exclude-files orig/include/asm-um/shmparam.h um/include/asm-um/shmparam.h
40507 --- orig/include/asm-um/shmparam.h 1969-12-31 19:00:00.000000000 -0500
40508 +++ um/include/asm-um/shmparam.h 2003-10-21 03:26:07.000000000 -0400
40510 +#ifndef __UM_SHMPARAM_H
40511 +#define __UM_SHMPARAM_H
40513 +#include "asm/arch/shmparam.h"
40516 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-generic.h um/include/asm-um/sigcontext-generic.h
40517 --- orig/include/asm-um/sigcontext-generic.h 1969-12-31 19:00:00.000000000 -0500
40518 +++ um/include/asm-um/sigcontext-generic.h 2003-10-21 03:26:07.000000000 -0400
40520 +#ifndef __UM_SIGCONTEXT_GENERIC_H
40521 +#define __UM_SIGCONTEXT_GENERIC_H
40523 +#include "asm/arch/sigcontext.h"
40526 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-i386.h um/include/asm-um/sigcontext-i386.h
40527 --- orig/include/asm-um/sigcontext-i386.h 1969-12-31 19:00:00.000000000 -0500
40528 +++ um/include/asm-um/sigcontext-i386.h 2003-10-21 03:26:07.000000000 -0400
40530 +#ifndef __UM_SIGCONTEXT_I386_H
40531 +#define __UM_SIGCONTEXT_I386_H
40533 +#include "asm/sigcontext-generic.h"
40536 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-ppc.h um/include/asm-um/sigcontext-ppc.h
40537 --- orig/include/asm-um/sigcontext-ppc.h 1969-12-31 19:00:00.000000000 -0500
40538 +++ um/include/asm-um/sigcontext-ppc.h 2003-10-21 03:26:07.000000000 -0400
40540 +#ifndef __UM_SIGCONTEXT_PPC_H
40541 +#define __UM_SIGCONTEXT_PPC_H
40543 +#define pt_regs sys_pt_regs
40545 +#include "asm/sigcontext-generic.h"
40550 diff -Naur -X ../exclude-files orig/include/asm-um/siginfo.h um/include/asm-um/siginfo.h
40551 --- orig/include/asm-um/siginfo.h 1969-12-31 19:00:00.000000000 -0500
40552 +++ um/include/asm-um/siginfo.h 2003-12-17 02:16:13.000000000 -0500
40554 +#ifndef __UM_SIGINFO_H
40555 +#define __UM_SIGINFO_H
40557 +#include "asm/arch/siginfo.h"
40560 diff -Naur -X ../exclude-files orig/include/asm-um/signal.h um/include/asm-um/signal.h
40561 --- orig/include/asm-um/signal.h 1969-12-31 19:00:00.000000000 -0500
40562 +++ um/include/asm-um/signal.h 2003-12-17 02:16:13.000000000 -0500
40565 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40566 + * Licensed under the GPL
40569 +#ifndef __UM_SIGNAL_H
40570 +#define __UM_SIGNAL_H
40572 +#include "asm/arch/signal.h"
40577 + * Overrides for Emacs so that we follow Linus's tabbing style.
40578 + * Emacs will notice this stuff at the end of the file and automatically
40579 + * adjust the settings for this buffer only. This must remain at the end
40581 + * ---------------------------------------------------------------------------
40582 + * Local variables:
40583 + * c-file-style: "linux"
40586 diff -Naur -X ../exclude-files orig/include/asm-um/smp.h um/include/asm-um/smp.h
40587 --- orig/include/asm-um/smp.h 1969-12-31 19:00:00.000000000 -0500
40588 +++ um/include/asm-um/smp.h 2003-12-17 02:16:13.000000000 -0500
40590 +#ifndef __UM_SMP_H
40591 +#define __UM_SMP_H
40595 +#include "linux/config.h"
40596 +#include "asm/current.h"
40598 +#define smp_processor_id() (current->processor)
40599 +#define cpu_logical_map(n) (n)
40600 +#define cpu_number_map(n) (n)
40601 +#define PROC_CHANGE_PENALTY 15 /* Pick a number, any number */
40602 +extern int hard_smp_processor_id(void);
40603 +extern unsigned long cpu_online_map;
40604 +#define NO_PROC_ID -1
40609 diff -Naur -X ../exclude-files orig/include/asm-um/smplock.h um/include/asm-um/smplock.h
40610 --- orig/include/asm-um/smplock.h 1969-12-31 19:00:00.000000000 -0500
40611 +++ um/include/asm-um/smplock.h 2003-12-17 02:16:13.000000000 -0500
40613 +#ifndef __UM_SMPLOCK_H
40614 +#define __UM_SMPLOCK_H
40616 +#include "asm/arch/smplock.h"
40619 diff -Naur -X ../exclude-files orig/include/asm-um/socket.h um/include/asm-um/socket.h
40620 --- orig/include/asm-um/socket.h 1969-12-31 19:00:00.000000000 -0500
40621 +++ um/include/asm-um/socket.h 2003-11-07 02:10:43.000000000 -0500
40623 +#ifndef __UM_SOCKET_H
40624 +#define __UM_SOCKET_H
40626 +#include "asm/arch/socket.h"
40629 diff -Naur -X ../exclude-files orig/include/asm-um/sockios.h um/include/asm-um/sockios.h
40630 --- orig/include/asm-um/sockios.h 1969-12-31 19:00:00.000000000 -0500
40631 +++ um/include/asm-um/sockios.h 2003-10-21 03:26:07.000000000 -0400
40633 +#ifndef __UM_SOCKIOS_H
40634 +#define __UM_SOCKIOS_H
40636 +#include "asm/arch/sockios.h"
40639 diff -Naur -X ../exclude-files orig/include/asm-um/softirq.h um/include/asm-um/softirq.h
40640 --- orig/include/asm-um/softirq.h 1969-12-31 19:00:00.000000000 -0500
40641 +++ um/include/asm-um/softirq.h 2003-12-17 02:16:13.000000000 -0500
40643 +#ifndef __UM_SOFTIRQ_H
40644 +#define __UM_SOFTIRQ_H
40646 +#include "linux/smp.h"
40647 +#include "asm/system.h"
40648 +#include "asm/processor.h"
40650 +/* A gratuitous name change */
40651 +#define i386_bh_lock um_bh_lock
40652 +#include "asm/arch/softirq.h"
40653 +#undef i386_bh_lock
40656 diff -Naur -X ../exclude-files orig/include/asm-um/spinlock.h um/include/asm-um/spinlock.h
40657 --- orig/include/asm-um/spinlock.h 1969-12-31 19:00:00.000000000 -0500
40658 +++ um/include/asm-um/spinlock.h 2003-12-17 02:16:13.000000000 -0500
40660 +#ifndef __UM_SPINLOCK_H
40661 +#define __UM_SPINLOCK_H
40663 +#include "linux/config.h"
40666 +#include "asm/arch/spinlock.h"
40670 diff -Naur -X ../exclude-files orig/include/asm-um/statfs.h um/include/asm-um/statfs.h
40671 --- orig/include/asm-um/statfs.h 1969-12-31 19:00:00.000000000 -0500
40672 +++ um/include/asm-um/statfs.h 2003-12-17 02:16:13.000000000 -0500
40674 +#ifndef _UM_STATFS_H
40675 +#define _UM_STATFS_H
40677 +#include "asm/arch/statfs.h"
40680 diff -Naur -X ../exclude-files orig/include/asm-um/stat.h um/include/asm-um/stat.h
40681 --- orig/include/asm-um/stat.h 1969-12-31 19:00:00.000000000 -0500
40682 +++ um/include/asm-um/stat.h 2003-10-21 03:26:07.000000000 -0400
40684 +#ifndef __UM_STAT_H
40685 +#define __UM_STAT_H
40687 +#include "asm/arch/stat.h"
40690 diff -Naur -X ../exclude-files orig/include/asm-um/string.h um/include/asm-um/string.h
40691 --- orig/include/asm-um/string.h 1969-12-31 19:00:00.000000000 -0500
40692 +++ um/include/asm-um/string.h 2003-12-16 22:26:55.000000000 -0500
40694 +#ifndef __UM_STRING_H
40695 +#define __UM_STRING_H
40697 +#include "asm/arch/string.h"
40698 +#include "asm/archparam.h"
40701 diff -Naur -X ../exclude-files orig/include/asm-um/system-generic.h um/include/asm-um/system-generic.h
40702 --- orig/include/asm-um/system-generic.h 1969-12-31 19:00:00.000000000 -0500
40703 +++ um/include/asm-um/system-generic.h 2003-12-17 02:16:13.000000000 -0500
40705 +#ifndef __UM_SYSTEM_GENERIC_H
40706 +#define __UM_SYSTEM_GENERIC_H
40708 +#include "asm/arch/system.h"
40710 +#undef prepare_to_switch
40712 +#undef __save_flags
40714 +#undef __restore_flags
40715 +#undef restore_flags
40720 +#undef local_irq_save
40721 +#undef local_irq_restore
40722 +#undef local_irq_disable
40723 +#undef local_irq_enable
40725 +#define prepare_to_switch() do ; while(0)
40727 +void *_switch_to(void *prev, void *next);
40729 +#define switch_to(prev, next, last) prev = _switch_to(prev, next)
40731 +extern int get_signals(void);
40732 +extern int set_signals(int enable);
40733 +extern void block_signals(void);
40734 +extern void unblock_signals(void);
40736 +#define local_irq_save(flags) do { (flags) = set_signals(0); } while(0)
40738 +#define local_irq_restore(flags) do { set_signals(flags); } while(0)
40740 +#define local_irq_enable() unblock_signals()
40741 +#define local_irq_disable() block_signals()
40743 +#define __sti() unblock_signals()
40744 +#define sti() unblock_signals()
40745 +#define __cli() block_signals()
40746 +#define cli() block_signals()
40748 +#define __save_flags(x) do { (x) = get_signals(); } while(0)
40749 +#define save_flags(x) __save_flags(x)
40751 +#define __restore_flags(x) local_irq_restore(x)
40752 +#define restore_flags(x) __restore_flags(x)
40755 diff -Naur -X ../exclude-files orig/include/asm-um/system-i386.h um/include/asm-um/system-i386.h
40756 --- orig/include/asm-um/system-i386.h 1969-12-31 19:00:00.000000000 -0500
40757 +++ um/include/asm-um/system-i386.h 2003-12-17 02:16:13.000000000 -0500
40759 +#ifndef __UM_SYSTEM_I386_H
40760 +#define __UM_SYSTEM_I386_H
40762 +#include "asm/system-generic.h"
40764 +#define __HAVE_ARCH_CMPXCHG 1
40766 +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
40767 + unsigned long new, int size)
40769 + unsigned long prev;
40772 + __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
40774 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
40778 + __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
40780 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
40784 + __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
40786 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
40793 +#define cmpxchg(ptr,o,n)\
40794 + ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
40795 + (unsigned long)(n),sizeof(*(ptr))))
40798 diff -Naur -X ../exclude-files orig/include/asm-um/system-ppc.h um/include/asm-um/system-ppc.h
40799 --- orig/include/asm-um/system-ppc.h 1969-12-31 19:00:00.000000000 -0500
40800 +++ um/include/asm-um/system-ppc.h 2003-10-21 03:26:07.000000000 -0400
40802 +#ifndef __UM_SYSTEM_PPC_H
40803 +#define __UM_SYSTEM_PPC_H
40805 +#define _switch_to _ppc_switch_to
40807 +#include "asm/arch/system.h"
40811 +#include "asm/system-generic.h"
40814 diff -Naur -X ../exclude-files orig/include/asm-um/termbits.h um/include/asm-um/termbits.h
40815 --- orig/include/asm-um/termbits.h 1969-12-31 19:00:00.000000000 -0500
40816 +++ um/include/asm-um/termbits.h 2003-11-07 02:10:43.000000000 -0500
40818 +#ifndef __UM_TERMBITS_H
40819 +#define __UM_TERMBITS_H
40821 +#include "asm/arch/termbits.h"
40824 diff -Naur -X ../exclude-files orig/include/asm-um/termios.h um/include/asm-um/termios.h
40825 --- orig/include/asm-um/termios.h 1969-12-31 19:00:00.000000000 -0500
40826 +++ um/include/asm-um/termios.h 2003-12-16 22:26:55.000000000 -0500
40828 +#ifndef __UM_TERMIOS_H
40829 +#define __UM_TERMIOS_H
40831 +#include "asm/arch/termios.h"
40834 diff -Naur -X ../exclude-files orig/include/asm-um/timex.h um/include/asm-um/timex.h
40835 --- orig/include/asm-um/timex.h 1969-12-31 19:00:00.000000000 -0500
40836 +++ um/include/asm-um/timex.h 2003-12-17 02:16:13.000000000 -0500
40838 +#ifndef __UM_TIMEX_H
40839 +#define __UM_TIMEX_H
40841 +#include "linux/time.h"
40843 +typedef unsigned long cycles_t;
40845 +#define cacheflush_time (0)
40847 +static inline cycles_t get_cycles (void)
40852 +#define vxtime_lock() do ; while (0)
40853 +#define vxtime_unlock() do ; while (0)
40856 diff -Naur -X ../exclude-files orig/include/asm-um/tlb.h um/include/asm-um/tlb.h
40857 --- orig/include/asm-um/tlb.h 1969-12-31 19:00:00.000000000 -0500
40858 +++ um/include/asm-um/tlb.h 2003-10-21 03:26:07.000000000 -0400
40860 +#include <asm-generic/tlb.h>
40861 diff -Naur -X ../exclude-files orig/include/asm-um/types.h um/include/asm-um/types.h
40862 --- orig/include/asm-um/types.h 1969-12-31 19:00:00.000000000 -0500
40863 +++ um/include/asm-um/types.h 2003-12-15 00:26:37.000000000 -0500
40865 +#ifndef __UM_TYPES_H
40866 +#define __UM_TYPES_H
40868 +#include "asm/arch/types.h"
40871 diff -Naur -X ../exclude-files orig/include/asm-um/uaccess.h um/include/asm-um/uaccess.h
40872 --- orig/include/asm-um/uaccess.h 1969-12-31 19:00:00.000000000 -0500
40873 +++ um/include/asm-um/uaccess.h 2003-12-17 02:16:13.000000000 -0500
40876 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40877 + * Licensed under the GPL
40880 +#ifndef __UM_UACCESS_H
40881 +#define __UM_UACCESS_H
40883 +#include "linux/sched.h"
40885 +#define VERIFY_READ 0
40886 +#define VERIFY_WRITE 1
40889 + * The fs value determines whether argument validity checking should be
40890 + * performed or not. If get_fs() == USER_DS, checking is performed, with
40891 + * get_fs() == KERNEL_DS, checking is bypassed.
40893 + * For historical reasons, these macros are grossly misnamed.
40896 +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
40898 +#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
40899 +#define USER_DS MAKE_MM_SEG(TASK_SIZE)
40901 +#define get_ds() (KERNEL_DS)
40902 +#define get_fs() (current->addr_limit)
40903 +#define set_fs(x) (current->addr_limit = (x))
40905 +#define segment_eq(a, b) ((a).seg == (b).seg)
40907 +#include "um_uaccess.h"
40909 +#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
40911 +#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
40913 +#define __get_user(x, ptr) \
40915 + const __typeof__(ptr) __private_ptr = ptr; \
40916 + __typeof__(*(__private_ptr)) __private_val; \
40917 + int __private_ret = -EFAULT; \
40919 + if (__copy_from_user(&__private_val, (__private_ptr), \
40920 + sizeof(*(__private_ptr))) == 0) {\
40921 + (x) = (__typeof__(*(__private_ptr))) __private_val; \
40922 + __private_ret = 0; \
40927 +#define get_user(x, ptr) \
40929 + const __typeof__((*ptr)) *private_ptr = (ptr); \
40930 + (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \
40931 + __get_user(x, private_ptr) : ((x) = 0, -EFAULT)); \
40934 +#define __put_user(x, ptr) \
40936 + __typeof__(ptr) __private_ptr = ptr; \
40937 + __typeof__(*(__private_ptr)) __private_val; \
40938 + int __private_ret = -EFAULT; \
40939 + __private_val = (__typeof__(*(__private_ptr))) (x); \
40940 + if (__copy_to_user((__private_ptr), &__private_val, \
40941 + sizeof(*(__private_ptr))) == 0) { \
40942 + __private_ret = 0; \
40947 +#define put_user(x, ptr) \
40949 + __typeof__(*(ptr)) *private_ptr = (ptr); \
40950 + (access_ok(VERIFY_WRITE, private_ptr, sizeof(*private_ptr)) ? \
40951 + __put_user(x, private_ptr) : -EFAULT); \
40954 +#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
40956 +struct exception_table_entry
40958 + unsigned long insn;
40959 + unsigned long fixup;
40965 + * Overrides for Emacs so that we follow Linus's tabbing style.
40966 + * Emacs will notice this stuff at the end of the file and automatically
40967 + * adjust the settings for this buffer only. This must remain at the end
40969 + * ---------------------------------------------------------------------------
40970 + * Local variables:
40971 + * c-file-style: "linux"
40974 diff -Naur -X ../exclude-files orig/include/asm-um/ucontext.h um/include/asm-um/ucontext.h
40975 --- orig/include/asm-um/ucontext.h 1969-12-31 19:00:00.000000000 -0500
40976 +++ um/include/asm-um/ucontext.h 2003-10-21 03:26:07.000000000 -0400
40978 +#ifndef _ASM_UM_UCONTEXT_H
40979 +#define _ASM_UM_UCONTEXT_H
40981 +#include "asm/arch/ucontext.h"
40984 diff -Naur -X ../exclude-files orig/include/asm-um/unaligned.h um/include/asm-um/unaligned.h
40985 --- orig/include/asm-um/unaligned.h 1969-12-31 19:00:00.000000000 -0500
40986 +++ um/include/asm-um/unaligned.h 2003-10-21 03:26:07.000000000 -0400
40988 +#ifndef __UM_UNALIGNED_H
40989 +#define __UM_UNALIGNED_H
40991 +#include "asm/arch/unaligned.h"
40994 diff -Naur -X ../exclude-files orig/include/asm-um/unistd.h um/include/asm-um/unistd.h
40995 --- orig/include/asm-um/unistd.h 1969-12-31 19:00:00.000000000 -0500
40996 +++ um/include/asm-um/unistd.h 2003-12-17 02:16:14.000000000 -0500
40999 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
41000 + * Licensed under the GPL
41003 +#ifndef _UM_UNISTD_H_
41004 +#define _UM_UNISTD_H_
41006 +#include "linux/resource.h"
41007 +#include "asm/uaccess.h"
41009 +extern long sys_open(const char *filename, int flags, int mode);
41010 +extern long sys_dup(unsigned int fildes);
41011 +extern long sys_close(unsigned int fd);
41012 +extern int um_execve(const char *file, char *const argv[], char *const env[]);
41013 +extern long sys_setsid(void);
41014 +extern long sys_waitpid(pid_t pid, unsigned int * stat_addr, int options);
41015 +extern long sys_wait4(pid_t pid,unsigned int *stat_addr, int options,
41016 + struct rusage *ru);
41017 +extern long sys_mount(char *dev_name, char *dir_name, char *type,
41018 + unsigned long flags, void *data);
41019 +extern long sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp,
41020 + struct timeval *tvp);
41021 +extern long sys_lseek(unsigned int fildes, unsigned long offset, int whence);
41022 +extern long sys_read(unsigned int fildes, char *buf, int len);
41023 +extern long sys_write(unsigned int fildes, char *buf, int len);
41025 +#ifdef __KERNEL_SYSCALLS__
41027 +#define KERNEL_CALL(ret_t, sys, args...) \
41028 + mm_segment_t fs = get_fs(); \
41030 + set_fs(KERNEL_DS); \
41031 + ret = sys(args); \
41035 + errno = -(long)ret; \
41038 +static inline long open(const char *pathname, int flags, int mode)
41040 + KERNEL_CALL(int, sys_open, pathname, flags, mode)
41043 +static inline long dup(unsigned int fd)
41045 + KERNEL_CALL(int, sys_dup, fd);
41048 +static inline long close(unsigned int fd)
41050 + KERNEL_CALL(int, sys_close, fd);
41053 +static inline int execve(const char *filename, char *const argv[],
41054 + char *const envp[])
41056 + KERNEL_CALL(int, um_execve, filename, argv, envp);
41059 +static inline long waitpid(pid_t pid, unsigned int *status, int options)
41061 + KERNEL_CALL(pid_t, sys_wait4, pid, status, options, NULL)
41064 +static inline pid_t wait(int *status)
41066 + KERNEL_CALL(pid_t, sys_wait4, -1, status, 0, NULL)
41069 +static inline pid_t setsid(void)
41071 + KERNEL_CALL(pid_t, sys_setsid)
41074 +static inline long lseek(unsigned int fd, off_t offset, unsigned int whence)
41076 + KERNEL_CALL(long, sys_lseek, fd, offset, whence)
41079 +static inline int read(unsigned int fd, char * buf, int len)
41081 + KERNEL_CALL(int, sys_read, fd, buf, len)
41084 +static inline int write(unsigned int fd, char * buf, int len)
41086 + KERNEL_CALL(int, sys_write, fd, buf, len)
41091 +/* Save the value of __KERNEL_SYSCALLS__, undefine it, include the underlying
41092 + * arch's unistd.h for the system call numbers, and restore the old
41093 + * __KERNEL_SYSCALLS__.
41096 +#ifdef __KERNEL_SYSCALLS__
41097 +#define __SAVE_KERNEL_SYSCALLS__ __KERNEL_SYSCALLS__
41100 +#undef __KERNEL_SYSCALLS__
41101 +#include "asm/arch/unistd.h"
41103 +#ifdef __KERNEL_SYSCALLS__
41104 +#define __KERNEL_SYSCALLS__ __SAVE_KERNEL_SYSCALLS__
41110 + * Overrides for Emacs so that we follow Linus's tabbing style.
41111 + * Emacs will notice this stuff at the end of the file and automatically
41112 + * adjust the settings for this buffer only. This must remain at the end
41114 + * ---------------------------------------------------------------------------
41115 + * Local variables:
41116 + * c-file-style: "linux"
41119 diff -Naur -X ../exclude-files orig/include/asm-um/user.h um/include/asm-um/user.h
41120 --- orig/include/asm-um/user.h 1969-12-31 19:00:00.000000000 -0500
41121 +++ um/include/asm-um/user.h 2003-12-17 02:18:31.000000000 -0500
41123 +#ifndef __UM_USER_H
41124 +#define __UM_USER_H
41126 +#include "asm/arch/user.h"
41129 diff -Naur -X ../exclude-files orig/include/asm-um/vga.h um/include/asm-um/vga.h
41130 --- orig/include/asm-um/vga.h 1969-12-31 19:00:00.000000000 -0500
41131 +++ um/include/asm-um/vga.h 2003-10-21 03:26:07.000000000 -0400
41133 +#ifndef __UM_VGA_H
41134 +#define __UM_VGA_H
41136 +#include "asm/arch/vga.h"
41139 diff -Naur -X ../exclude-files orig/include/asm-um/xor.h um/include/asm-um/xor.h
41140 --- orig/include/asm-um/xor.h 1969-12-31 19:00:00.000000000 -0500
41141 +++ um/include/asm-um/xor.h 2003-10-21 03:26:07.000000000 -0400
41143 +#ifndef __UM_XOR_H
41144 +#define __UM_XOR_H
41146 +#include "asm-generic/xor.h"
41149 diff -Naur -X ../exclude-files orig/include/linux/blk.h um/include/linux/blk.h
41150 --- orig/include/linux/blk.h 2002-09-15 12:13:19.000000000 -0400
41151 +++ um/include/linux/blk.h 2003-12-17 02:16:30.000000000 -0500
41152 @@ -320,6 +320,24 @@
41153 #define DEVICE_REQUEST do_ida_request
41154 #define DEVICE_NR(device) (MINOR(device) >> 4)
41156 +#elif (MAJOR_NR == UBD_MAJOR)
41158 +#define DEVICE_NAME "User-mode block device"
41159 +#define DEVICE_INTR do_ubd
41160 +#define DEVICE_REQUEST do_ubd_request
41161 +#define DEVICE_NR(device) (MINOR(device) >> UBD_SHIFT)
41162 +#define DEVICE_ON(device)
41163 +#define DEVICE_OFF(device)
41165 +#elif (MAJOR_NR == COW_MAJOR)
41167 +#define DEVICE_NAME "COW device"
41168 +#define DEVICE_INTR do_cow
41169 +#define DEVICE_REQUEST do_cow_request
41170 +#define DEVICE_NR(device) (MINOR(device) >> COW_SHIFT)
41171 +#define DEVICE_ON(device)
41172 +#define DEVICE_OFF(device)
41174 #endif /* MAJOR_NR == whatever */
41176 /* provide DEVICE_xxx defaults, if not explicitly defined
41177 diff -Naur -X ../exclude-files orig/include/linux/fs.h um/include/linux/fs.h
41178 --- orig/include/linux/fs.h 2003-12-16 22:16:36.000000000 -0500
41179 +++ um/include/linux/fs.h 2003-12-17 02:16:13.000000000 -0500
41180 @@ -320,6 +320,8 @@
41181 #include <linux/ncp_fs_i.h>
41182 #include <linux/proc_fs_i.h>
41183 #include <linux/usbdev_fs_i.h>
41184 +#include <linux/hostfs_fs_i.h>
41185 +#include <linux/hppfs_fs_i.h>
41186 #include <linux/jffs2_fs_i.h>
41187 #include <linux/cramfs_fs_sb.h>
41189 @@ -516,7 +518,9 @@
41190 struct proc_inode_info proc_i;
41191 struct socket socket_i;
41192 struct usbdev_inode_info usbdev_i;
41193 - struct jffs2_inode_info jffs2_i;
41194 + struct hostfs_inode_info hostfs_i;
41195 + struct hppfs_inode_info hppfs_i;
41196 + struct jffs2_inode_info jffs2_i;
41200 @@ -864,6 +868,8 @@
41201 unsigned int (*poll) (struct file *, struct poll_table_struct *);
41202 int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
41203 int (*mmap) (struct file *, struct vm_area_struct *);
41204 + void (*munmap) (struct file *, struct vm_area_struct *,
41205 + unsigned long start, unsigned long len);
41206 int (*open) (struct inode *, struct file *);
41207 int (*flush) (struct file *);
41208 int (*release) (struct inode *, struct file *);
41209 diff -Naur -X ../exclude-files orig/include/linux/ghash.h um/include/linux/ghash.h
41210 --- orig/include/linux/ghash.h 1997-07-07 11:24:28.000000000 -0400
41211 +++ um/include/linux/ghash.h 2003-10-21 03:26:07.000000000 -0400
41212 @@ -153,6 +153,26 @@
41216 +/* LINKAGE - empty or "static", depending on whether you want the definitions to
41217 + * be public or not
41218 + * NAME - a string to stick in names to make this hash table type distinct from
41220 + * HASHSIZE - number of buckets
41221 + * TYPE - type of data contained in the buckets - must be a structure, one
41222 + * field is of type NAME_ptrs, another is the hash key
41223 + * PTRS - TYPE must contain a field of type NAME_ptrs, PTRS is the name of that
41225 + * KEYTYPE - type of the key field within TYPE
41226 + * KEY - name of the key field within TYPE
41227 + * KEYCMP - pointer to function that compares KEYTYPEs to each other - the
41228 + * prototype is int KEYCMP(KEYTYPE, KEYTYPE), it returns zero for equal,
41229 + * non-zero for not equal
41230 + * HASHFN - the hash function - the prototype is int HASHFN(KEYTYPE),
41231 + * it returns a number in the range 0 ... HASHSIZE - 1
41232 + * Call DEF_HASH_STRUCTS, define your hash table as a NAME_table, then call
41236 #define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
41238 struct NAME##_table {\
41239 @@ -165,7 +185,7 @@
41243 -#define DEF_HASH(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
41244 +#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\
41246 LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
41248 @@ -206,12 +226,10 @@
41250 LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
41252 - int ix = hashfn(pos);\
41253 + int ix = HASHFN(pos);\
41254 TYPE * ptr = tbl->hashtable[ix];\
41255 while(ptr && KEYCMP(ptr->KEY, pos))\
41256 ptr = ptr->PTRS.next_hash;\
41257 - if(ptr && !KEYEQ(ptr->KEY, pos))\
41262 diff -Naur -X ../exclude-files orig/include/linux/hostfs_fs_i.h um/include/linux/hostfs_fs_i.h
41263 --- orig/include/linux/hostfs_fs_i.h 1969-12-31 19:00:00.000000000 -0500
41264 +++ um/include/linux/hostfs_fs_i.h 2003-10-21 03:26:07.000000000 -0400
41266 +#ifndef _HOSTFS_FS_I
41267 +#define _HOSTFS_FS_I
41269 +struct hostfs_inode_info {
41270 + char *host_filename;
41278 + * Overrides for Emacs so that we follow Linus's tabbing style.
41279 + * Emacs will notice this stuff at the end of the file and automatically
41280 + * adjust the settings for this buffer only. This must remain at the end
41282 + * ---------------------------------------------------------------------------
41283 + * Local variables:
41284 + * c-file-style: "linux"
41287 diff -Naur -X ../exclude-files orig/include/linux/hppfs_fs_i.h um/include/linux/hppfs_fs_i.h
41288 --- orig/include/linux/hppfs_fs_i.h 1969-12-31 19:00:00.000000000 -0500
41289 +++ um/include/linux/hppfs_fs_i.h 2003-10-21 03:26:07.000000000 -0400
41291 +#ifndef _HPPFS_FS_I
41292 +#define _HPPFS_FS_I
41294 +struct hppfs_inode_info {
41295 + struct dentry *proc_dentry;
41301 + * Overrides for Emacs so that we follow Linus's tabbing style.
41302 + * Emacs will notice this stuff at the end of the file and automatically
41303 + * adjust the settings for this buffer only. This must remain at the end
41305 + * ---------------------------------------------------------------------------
41306 + * Local variables:
41307 + * c-file-style: "linux"
41310 diff -Naur -X ../exclude-files orig/include/linux/kernel.h um/include/linux/kernel.h
41311 --- orig/include/linux/kernel.h 2003-02-27 13:04:27.000000000 -0500
41312 +++ um/include/linux/kernel.h 2003-12-17 02:16:13.000000000 -0500
41314 # define ATTRIB_NORET __attribute__((noreturn))
41315 # define NORET_AND noreturn,
41318 +#if defined(__i386__) || defined(UM_FASTCALL)
41319 #define FASTCALL(x) x __attribute__((regparm(3)))
41321 #define FASTCALL(x) x
41322 diff -Naur -X ../exclude-files orig/include/linux/kernel_stat.h um/include/linux/kernel_stat.h
41323 --- orig/include/linux/kernel_stat.h 2003-08-29 17:26:25.000000000 -0400
41324 +++ um/include/linux/kernel_stat.h 2003-12-17 02:16:13.000000000 -0500
41326 * used by rstatd/perfmeter
41329 -#define DK_MAX_MAJOR 16
41330 +#define DK_MAX_MAJOR 99
41331 #define DK_MAX_DISK 16
41333 struct kernel_stat {
41334 diff -Naur -X ../exclude-files orig/include/linux/mm.h um/include/linux/mm.h
41335 --- orig/include/linux/mm.h 2003-12-16 22:16:36.000000000 -0500
41336 +++ um/include/linux/mm.h 2003-12-17 02:16:13.000000000 -0500
41337 @@ -438,6 +438,18 @@
41338 extern struct page * FASTCALL(__alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist));
41339 extern struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order);
41341 +#ifndef HAVE_ARCH_VALIDATE
41342 +static inline struct page *arch_validate(struct page *page,
41343 + unsigned int gfp_mask, int order)
41349 +#ifndef HAVE_ARCH_FREE_PAGE
41350 +static inline void arch_free_page(struct page *page, int order) { }
41353 static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
41356 @@ -445,7 +457,7 @@
41358 if (order >= MAX_ORDER)
41360 - return _alloc_pages(gfp_mask, order);
41361 + return arch_validate(_alloc_pages(gfp_mask, order), gfp_mask, order);
41364 #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
41365 @@ -505,6 +517,9 @@
41366 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
41367 int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
41369 +extern long do_mprotect(struct mm_struct *mm, unsigned long start,
41370 + size_t len, unsigned long prot);
41373 * On a two-level page table, this ends up being trivial. Thus the
41374 * inlining and the symmetry break with pte_alloc() that does all
41375 @@ -552,9 +567,10 @@
41377 extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
41379 -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
41380 - unsigned long len, unsigned long prot,
41381 - unsigned long flag, unsigned long pgoff);
41382 +extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file,
41383 + unsigned long addr, unsigned long len,
41384 + unsigned long prot, unsigned long flag,
41385 + unsigned long pgoff);
41387 static inline unsigned long do_mmap(struct file *file, unsigned long addr,
41388 unsigned long len, unsigned long prot,
41389 @@ -564,7 +580,8 @@
41390 if ((offset + PAGE_ALIGN(len)) < offset)
41392 if (!(offset & ~PAGE_MASK))
41393 - ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
41394 + ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag,
41395 + offset >> PAGE_SHIFT);
41399 diff -Naur -X ../exclude-files orig/include/linux/proc_mm.h um/include/linux/proc_mm.h
41400 --- orig/include/linux/proc_mm.h 1969-12-31 19:00:00.000000000 -0500
41401 +++ um/include/linux/proc_mm.h 2003-12-17 02:17:30.000000000 -0500
41404 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
41405 + * Licensed under the GPL
41408 +#ifndef __PROC_MM_H
41409 +#define __PROC_MM_H
41411 +#include "linux/sched.h"
41413 +#define MM_MMAP 54
41414 +#define MM_MUNMAP 55
41415 +#define MM_MPROTECT 56
41416 +#define MM_COPY_SEGMENTS 57
41419 + unsigned long addr;
41420 + unsigned long len;
41421 + unsigned long prot;
41422 + unsigned long flags;
41423 + unsigned long fd;
41424 + unsigned long offset;
41427 +struct mm_munmap {
41428 + unsigned long addr;
41429 + unsigned long len;
41432 +struct mm_mprotect {
41433 + unsigned long addr;
41434 + unsigned long len;
41435 + unsigned int prot;
41438 +struct proc_mm_op {
41441 + struct mm_mmap mmap;
41442 + struct mm_munmap munmap;
41443 + struct mm_mprotect mprotect;
41444 + int copy_segments;
41448 +extern struct mm_struct *proc_mm_get_mm(int fd);
41451 diff -Naur -X ../exclude-files orig/include/linux/shmem_fs.h um/include/linux/shmem_fs.h
41452 --- orig/include/linux/shmem_fs.h 2003-09-02 15:44:03.000000000 -0400
41453 +++ um/include/linux/shmem_fs.h 2003-12-09 00:03:31.000000000 -0500
41455 unsigned long next_index;
41456 swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* for the first blocks */
41457 void **i_indirect; /* indirect blocks */
41458 + unsigned long map_direct[SHMEM_NR_DIRECT];
41459 + void **map_indirect;
41460 unsigned long swapped; /* data pages assigned to swap */
41461 unsigned long flags;
41462 struct list_head list;
41463 diff -Naur -X ../exclude-files orig/include/linux/tty.h um/include/linux/tty.h
41464 --- orig/include/linux/tty.h 2003-08-29 17:26:26.000000000 -0400
41465 +++ um/include/linux/tty.h 2003-12-17 02:16:13.000000000 -0500
41466 @@ -309,6 +309,9 @@
41467 spinlock_t read_lock;
41468 /* If the tty has a pending do_SAK, queue it here - akpm */
41469 struct tq_struct SAK_tq;
41470 +#ifdef CONFIG_TTY_LOG
41475 /* tty magic number */
41476 @@ -365,6 +368,7 @@
41477 extern int specialix_init(void);
41478 extern int espserial_init(void);
41479 extern int macserial_init(void);
41480 +extern int stdio_init(void);
41481 extern int a2232board_init(void);
41483 extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
41484 @@ -420,5 +424,7 @@
41485 extern int vt_ioctl(struct tty_struct *tty, struct file * file,
41486 unsigned int cmd, unsigned long arg);
41488 +extern void stdio_console_init(void);
41490 #endif /* __KERNEL__ */
41492 diff -Naur -X ../exclude-files orig/init/do_mounts.c um/init/do_mounts.c
41493 --- orig/init/do_mounts.c 2003-12-16 22:16:36.000000000 -0500
41494 +++ um/init/do_mounts.c 2003-12-16 22:17:32.000000000 -0500
41495 @@ -154,6 +154,22 @@
41497 { "apblock", APBLOCK_MAJOR << 8},
41498 { "ddv", DDV_MAJOR << 8},
41499 + { "ubd0", UBD_MAJOR << 8 | 0 << 4},
41500 + { "ubda", UBD_MAJOR << 8 | 0 << 4},
41501 + { "ubd1", UBD_MAJOR << 8 | 1 << 4},
41502 + { "ubdb", UBD_MAJOR << 8 | 1 << 4},
41503 + { "ubd2", UBD_MAJOR << 8 | 2 << 4},
41504 + { "ubdc", UBD_MAJOR << 8 | 2 << 4},
41505 + { "ubd3", UBD_MAJOR << 8 | 3 << 4},
41506 + { "ubdd", UBD_MAJOR << 8 | 3 << 4},
41507 + { "ubd4", UBD_MAJOR << 8 | 4 << 4},
41508 + { "ubde", UBD_MAJOR << 8 | 4 << 4},
41509 + { "ubd5", UBD_MAJOR << 8 | 5 << 4},
41510 + { "ubdf", UBD_MAJOR << 8 | 5 << 4},
41511 + { "ubd6", UBD_MAJOR << 8 | 6 << 4},
41512 + { "ubdg", UBD_MAJOR << 8 | 6 << 4},
41513 + { "ubd7", UBD_MAJOR << 8 | 7 << 4},
41514 + { "ubdh", UBD_MAJOR << 8 | 7 << 4},
41515 { "jsfd", JSFD_MAJOR << 8},
41516 #if defined(CONFIG_ARCH_S390)
41517 { "dasda", (DASD_MAJOR << MINORBITS) },
41518 diff -Naur -X ../exclude-files orig/kernel/panic.c um/kernel/panic.c
41519 --- orig/kernel/panic.c 2003-12-16 22:16:36.000000000 -0500
41520 +++ um/kernel/panic.c 2003-12-16 22:17:32.000000000 -0500
41525 - notifier_call_chain(&panic_notifier_list, 0, NULL);
41526 + notifier_call_chain(&panic_notifier_list, 0, buf);
41528 if (panic_timeout > 0)
41530 diff -Naur -X ../exclude-files orig/MAINTAINERS um/MAINTAINERS
41531 --- orig/MAINTAINERS 2003-12-16 22:16:23.000000000 -0500
41532 +++ um/MAINTAINERS 2003-12-16 22:17:22.000000000 -0500
41533 @@ -2055,6 +2055,14 @@
41534 L: linux-usb-devel@lists.sourceforge.net
41535 W: http://usb.in.tum.de
41540 +M: jdike@karaya.com
41541 +L: user-mode-linux-devel@lists.sourceforge.net
41542 +L: user-mode-linux-user@lists.sourceforge.net
41543 +W: http://user-mode-linux.sourceforge.net
41546 USB "USBNET" DRIVER
41548 diff -Naur -X ../exclude-files orig/Makefile um/Makefile
41549 --- orig/Makefile 2003-12-16 22:16:23.000000000 -0500
41550 +++ um/Makefile 2003-12-16 22:17:22.000000000 -0500
41553 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
41555 -ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
41556 +# SUBARCH tells the usermode build what the underlying arch is. That is set
41557 +# first, and if a usermode build is happening, the "ARCH=um" on the command
41558 +# line overrides the setting of ARCH below. If a native build is happening,
41559 +# then ARCH is assigned, getting whatever value it gets normally, and
41560 +# SUBARCH is subsequently ignored.
41562 +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
41563 +ARCH := $(SUBARCH)
41565 KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
41567 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
41568 diff -Naur -X ../exclude-files orig/mm/Makefile um/mm/Makefile
41569 --- orig/mm/Makefile 2002-08-21 11:47:43.000000000 -0400
41570 +++ um/mm/Makefile 2003-10-21 03:26:08.000000000 -0400
41574 obj-$(CONFIG_HIGHMEM) += highmem.o
41575 +obj-$(CONFIG_PROC_MM) += proc_mm.o
41577 include $(TOPDIR)/Rules.make
41578 diff -Naur -X ../exclude-files orig/mm/mmap.c um/mm/mmap.c
41579 --- orig/mm/mmap.c 2003-12-16 22:16:36.000000000 -0500
41580 +++ um/mm/mmap.c 2003-12-16 22:17:32.000000000 -0500
41581 @@ -390,10 +390,11 @@
41585 -unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned long len,
41586 - unsigned long prot, unsigned long flags, unsigned long pgoff)
41587 +unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file,
41588 + unsigned long addr, unsigned long len,
41589 + unsigned long prot, unsigned long flags,
41590 + unsigned long pgoff)
41592 - struct mm_struct * mm = current->mm;
41593 struct vm_area_struct * vma, * prev;
41594 unsigned int vm_flags;
41595 int correct_wcount = 0;
41596 @@ -994,6 +995,11 @@
41597 remove_shared_vm_struct(mpnt);
41600 + if((mpnt->vm_file != NULL) && (mpnt->vm_file->f_op != NULL) &&
41601 + (mpnt->vm_file->f_op->munmap != NULL))
41602 + mpnt->vm_file->f_op->munmap(mpnt->vm_file, mpnt, st,
41605 zap_page_range(mm, st, size);
41608 diff -Naur -X ../exclude-files orig/mm/mprotect.c um/mm/mprotect.c
41609 --- orig/mm/mprotect.c 2003-12-16 22:16:36.000000000 -0500
41610 +++ um/mm/mprotect.c 2003-12-16 22:17:32.000000000 -0500
41611 @@ -264,7 +264,8 @@
41615 -asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
41616 +long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
41617 + unsigned long prot)
41619 unsigned long nstart, end, tmp;
41620 struct vm_area_struct * vma, * next, * prev;
41621 @@ -281,9 +282,9 @@
41625 - down_write(¤t->mm->mmap_sem);
41626 + down_write(&mm->mmap_sem);
41628 - vma = find_vma_prev(current->mm, start, &prev);
41629 + vma = find_vma_prev(mm, start, &prev);
41631 if (!vma || vma->vm_start > start)
41633 @@ -332,6 +333,11 @@
41634 prev->vm_mm->map_count--;
41637 - up_write(¤t->mm->mmap_sem);
41638 + up_write(&mm->mmap_sem);
41642 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
41644 + return(do_mprotect(current->mm, start, len, prot));
41646 diff -Naur -X ../exclude-files orig/mm/page_alloc.c um/mm/page_alloc.c
41647 --- orig/mm/page_alloc.c 2003-12-16 22:16:36.000000000 -0500
41648 +++ um/mm/page_alloc.c 2003-12-16 22:17:32.000000000 -0500
41653 + arch_free_page(page, order);
41655 * Yes, think what happens when other parts of the kernel take
41656 * a reference to a page in order to pin it for io. -ben
41657 diff -Naur -X ../exclude-files orig/mm/proc_mm.c um/mm/proc_mm.c
41658 --- orig/mm/proc_mm.c 1969-12-31 19:00:00.000000000 -0500
41659 +++ um/mm/proc_mm.c 2003-10-21 03:26:08.000000000 -0400
41662 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
41663 + * Licensed under the GPL
41666 +#include "linux/init.h"
41667 +#include "linux/proc_fs.h"
41668 +#include "linux/proc_mm.h"
41669 +#include "linux/file.h"
41670 +#include "asm/uaccess.h"
41671 +#include "asm/mmu_context.h"
41673 +static struct file_operations proc_mm_fops;
41675 +struct mm_struct *proc_mm_get_mm(int fd)
41677 + struct mm_struct *ret = ERR_PTR(-EBADF);
41678 + struct file *file;
41684 + ret = ERR_PTR(-EINVAL);
41685 + if(file->f_op != &proc_mm_fops)
41688 + ret = file->private_data;
41695 +extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
41696 + unsigned long len, unsigned long prot,
41697 + unsigned long flags, unsigned long fd,
41698 + unsigned long pgoff);
41700 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
41701 + size_t count, loff_t *ppos)
41703 + struct mm_struct *mm = file->private_data;
41704 + struct proc_mm_op req;
41707 + if(count > sizeof(req))
41710 + n = copy_from_user(&req, buffer, count);
41717 + struct mm_mmap *map = &req.u.mmap;
41719 + ret = do_mmap2(mm, map->addr, map->len, map->prot,
41720 + map->flags, map->fd, map->offset >> PAGE_SHIFT);
41721 + if((ret & ~PAGE_MASK) == 0)
41726 + case MM_MUNMAP: {
41727 + struct mm_munmap *unmap = &req.u.munmap;
41729 + down_write(&mm->mmap_sem);
41730 + ret = do_munmap(mm, unmap->addr, unmap->len);
41731 + up_write(&mm->mmap_sem);
41737 + case MM_MPROTECT: {
41738 + struct mm_mprotect *protect = &req.u.mprotect;
41740 + ret = do_mprotect(mm, protect->addr, protect->len,
41747 + case MM_COPY_SEGMENTS: {
41748 + struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
41750 + if(IS_ERR(from)){
41751 + ret = PTR_ERR(from);
41755 + mm_copy_segments(from, mm);
41766 +static int open_proc_mm(struct inode *inode, struct file *file)
41768 + struct mm_struct *mm = mm_alloc();
41775 + ret = init_new_context(current, mm);
41779 + spin_lock(&mmlist_lock);
41780 + list_add(&mm->mmlist, ¤t->mm->mmlist);
41782 + spin_unlock(&mmlist_lock);
41784 + file->private_data = mm;
41794 +static int release_proc_mm(struct inode *inode, struct file *file)
41796 + struct mm_struct *mm = file->private_data;
41802 +static struct file_operations proc_mm_fops = {
41803 + .open = open_proc_mm,
41804 + .release = release_proc_mm,
41805 + .write = write_proc_mm,
41808 +static int make_proc_mm(void)
41810 + struct proc_dir_entry *ent;
41812 + ent = create_proc_entry("mm", 0222, &proc_root);
41814 + printk("make_proc_mm : Failed to register /proc/mm\n");
41817 + ent->proc_fops = &proc_mm_fops;
41822 +__initcall(make_proc_mm);
41825 + * Overrides for Emacs so that we follow Linus's tabbing style.
41826 + * Emacs will notice this stuff at the end of the file and automatically
41827 + * adjust the settings for this buffer only. This must remain at the end
41829 + * ---------------------------------------------------------------------------
41830 + * Local variables:
41831 + * c-file-style: "linux"
41834 diff -Naur -X ../exclude-files orig/mm/shmem.c um/mm/shmem.c
41835 --- orig/mm/shmem.c 2003-12-16 22:16:36.000000000 -0500
41836 +++ um/mm/shmem.c 2003-12-16 22:17:32.000000000 -0500
41837 @@ -128,16 +128,17 @@
41841 -static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, unsigned long *page)
41842 +static void *shmem_block(unsigned long index, unsigned long *page,
41843 + unsigned long *direct, void ***indirect)
41845 unsigned long offset;
41848 if (index < SHMEM_NR_DIRECT)
41849 - return info->i_direct+index;
41850 - if (!info->i_indirect) {
41851 + return direct+index;
41852 + if (!*indirect) {
41854 - info->i_indirect = (void **) *page;
41855 + *indirect = (void **) *page;
41858 return NULL; /* need another page */
41859 @@ -146,7 +147,7 @@
41860 index -= SHMEM_NR_DIRECT;
41861 offset = index % ENTRIES_PER_PAGE;
41862 index /= ENTRIES_PER_PAGE;
41863 - dir = info->i_indirect;
41866 if (index >= ENTRIES_PER_PAGE/2) {
41867 index -= ENTRIES_PER_PAGE/2;
41868 @@ -169,7 +170,21 @@
41869 *dir = (void *) *page;
41872 - return (swp_entry_t *) *dir + offset;
41873 + return (unsigned long **) *dir + offset;
41876 +static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, unsigned long *page)
41878 + return((swp_entry_t *) shmem_block(index, page,
41879 + (unsigned long *) info->i_direct,
41880 + &info->i_indirect));
41883 +static unsigned long *shmem_map_count(struct shmem_inode_info *info,
41884 + unsigned long index, unsigned long *page)
41886 + return((unsigned long *) shmem_block(index, page, info->map_direct,
41887 + &info->map_indirect));
41891 @@ -838,6 +853,7 @@
41892 ops = &shmem_vm_ops;
41893 if (!S_ISREG(inode->i_mode))
41896 UPDATE_ATIME(inode);
41899 @@ -1723,4 +1739,125 @@
41903 +static int adjust_map_counts(struct shmem_inode_info *info,
41904 + unsigned long offset, unsigned long len,
41907 + unsigned long idx, i, *count, page = 0;
41909 + spin_lock(&info->lock);
41910 + offset >>= PAGE_SHIFT;
41911 + len >>= PAGE_SHIFT;
41912 + for(i = 0; i < len; i++){
41913 + idx = (i + offset) >> (PAGE_CACHE_SHIFT - PAGE_SHIFT);
41915 + while((count = shmem_map_count(info, idx, &page)) == NULL){
41916 + spin_unlock(&info->lock);
41917 + page = get_zeroed_page(GFP_KERNEL);
41920 + spin_lock(&info->lock);
41926 + *count += adjust;
41928 + spin_unlock(&info->lock);
41932 EXPORT_SYMBOL(shmem_file_setup);
41934 +struct file_operations anon_file_operations;
41936 +static int anon_mmap(struct file *file, struct vm_area_struct *vma)
41938 + struct file *new;
41939 + struct inode *inode;
41940 + loff_t size = vma->vm_end - vma->vm_start;
41943 + if(file->private_data == NULL){
41944 + new = shmem_file_setup("dev/anon", size);
41946 + return(PTR_ERR(new));
41948 + new->f_op = &anon_file_operations;
41949 + file->private_data = new;
41952 + if (vma->vm_file)
41953 + fput(vma->vm_file);
41954 + vma->vm_file = file->private_data;
41955 + get_file(vma->vm_file);
41957 + inode = vma->vm_file->f_dentry->d_inode;
41958 + err = adjust_map_counts(SHMEM_I(inode), vma->vm_pgoff, size, 1);
41962 + vma->vm_ops = &shmem_vm_ops;
41966 +static void anon_munmap(struct file *file, struct vm_area_struct *vma,
41967 + unsigned long start, unsigned long len)
41969 + struct inode *inode = file->f_dentry->d_inode;
41970 + struct shmem_inode_info *info = SHMEM_I(inode);
41974 + struct page *page;
41975 + unsigned long addr, idx, *count;
41977 + for(addr = start; addr < start + len; addr += PAGE_SIZE){
41978 + idx = (addr - vma->vm_start + vma->vm_pgoff);
41979 + idx >>= PAGE_CACHE_SHIFT;
41981 + count = shmem_map_count(info, idx, NULL);
41982 + BUG_ON(count == NULL);
41988 + pgd = pgd_offset(vma->vm_mm, addr);
41989 + if(pgd_none(*pgd))
41992 + pmd = pmd_offset(pgd, addr);
41993 + if(pmd_none(*pmd))
41996 + pte = pte_offset(pmd, addr);
41997 + if(!pte_present(*pte)) /* XXX need to handle swapped pages */
42000 + *pte = pte_mkclean(*pte);
42002 + page = pte_page(*pte);
42004 + lru_cache_del(page);
42005 + ClearPageDirty(page);
42006 + remove_inode_page(page);
42007 + UnlockPage(page);
42009 + page_cache_release(page);
42013 +int anon_release(struct inode *inode, struct file *file)
42015 + if(file->private_data != NULL)
42016 + fput(file->private_data);
42020 +struct file_operations anon_file_operations = {
42021 + .mmap = anon_mmap,
42022 + .munmap = anon_munmap,
42023 + .release = anon_release,