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-02-04 19:35:13.000000000 -0500
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 2002-10-23 21:08:04.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 +tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
68 +dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
69 +tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
70 +if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
71 + int ' Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
73 +dep_bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM
75 +tristate 'Example IO memory driver' CONFIG_MMAPPER
78 diff -Naur -X ../exclude-files orig/arch/um/config_char.in um/arch/um/config_char.in
79 --- orig/arch/um/config_char.in 1969-12-31 19:00:00.000000000 -0500
80 +++ um/arch/um/config_char.in 2002-10-23 21:08:04.000000000 -0400
82 +mainmenu_option next_comment
83 +comment 'Character Devices'
85 +define_bool CONFIG_STDIO_CONSOLE y
87 +bool 'Virtual serial line' CONFIG_SSL
89 +bool 'file descriptor channel support' CONFIG_FD_CHAN
90 +bool 'null channel support' CONFIG_NULL_CHAN
91 +bool 'port channel support' CONFIG_PORT_CHAN
92 +bool 'pty channel support' CONFIG_PTY_CHAN
93 +bool 'tty channel support' CONFIG_TTY_CHAN
94 +bool 'xterm channel support' CONFIG_XTERM_CHAN
95 +string 'Default main console channel initialization' CONFIG_CON_ZERO_CHAN \
97 +string 'Default console channel initialization' CONFIG_CON_CHAN "xterm"
98 +string 'Default serial line channel initialization' CONFIG_SSL_CHAN "pty"
101 +bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
102 +if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
103 + int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
106 +bool 'Watchdog Timer Support' CONFIG_WATCHDOG
107 +dep_bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT \
109 +dep_tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG $CONFIG_WATCHDOG
110 +dep_tristate ' UML watchdog' CONFIG_UML_WATCHDOG $CONFIG_WATCHDOG
112 +tristate 'Sound support' CONFIG_UML_SOUND
113 +define_tristate CONFIG_SOUND $CONFIG_UML_SOUND
114 +define_tristate CONFIG_HOSTAUDIO $CONFIG_UML_SOUND
116 +bool 'Enable tty logging' CONFIG_TTY_LOG
119 diff -Naur -X ../exclude-files orig/arch/um/config.in um/arch/um/config.in
120 --- orig/arch/um/config.in 1969-12-31 19:00:00.000000000 -0500
121 +++ um/arch/um/config.in 2003-02-27 13:12:39.000000000 -0500
123 +define_bool CONFIG_USERMODE y
125 +mainmenu_name "Linux/Usermode Kernel Configuration"
127 +define_bool CONFIG_ISA n
128 +define_bool CONFIG_SBUS n
129 +define_bool CONFIG_PCI n
131 +define_bool CONFIG_UID16 y
133 +define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
135 +mainmenu_option next_comment
136 +comment 'Code maturity level options'
137 +bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
140 +mainmenu_option next_comment
141 +comment 'General Setup'
143 +bool 'Separate kernel address space support' CONFIG_MODE_SKAS
145 +# This is to ensure that at least one of the modes is enabled. When neither
146 +# is present in defconfig, they default to N, which is bad.
147 +if [ "$CONFIG_MODE_SKAS" != "y" ]; then
148 + define_bool CONFIG_MODE_TT y
151 +bool 'Tracing thread support' CONFIG_MODE_TT
152 +if [ "$CONFIG_MODE_TT" != "y" ]; then
153 + bool 'Statically linked binary when CONFIG_MODE_TT is disabled' CONFIG_STATIC_LINK
155 +bool 'Networking support' CONFIG_NET
156 +bool 'System V IPC' CONFIG_SYSVIPC
157 +bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
158 +bool 'Sysctl support' CONFIG_SYSCTL
159 +tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
160 +tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
161 +tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
162 +tristate 'Host filesystem' CONFIG_HOSTFS
163 +tristate 'Honeypot proc filesystem' CONFIG_HPPFS
164 +bool 'Management console' CONFIG_MCONSOLE
165 +dep_bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ $CONFIG_MCONSOLE
166 +bool '2G/2G host address space split' CONFIG_HOST_2G_2G
167 +bool 'Symmetric multi-processing support' CONFIG_UML_SMP
168 +define_bool CONFIG_SMP $CONFIG_UML_SMP
169 +int 'Nesting level' CONFIG_NEST_LEVEL 0
170 +int 'Kernel address space size (in .5G units)' CONFIG_KERNEL_HALF_GIGS 1
171 +bool 'Highmem support' CONFIG_HIGHMEM
172 +bool '/proc/mm' CONFIG_PROC_MM
173 +int 'Kernel stack size order' CONFIG_KERNEL_STACK_ORDER 2
176 +mainmenu_option next_comment
177 +comment 'Loadable module support'
178 +bool 'Enable loadable module support' CONFIG_MODULES
179 +if [ "$CONFIG_MODULES" = "y" ]; then
180 +# MODVERSIONS does not yet work in this architecture
181 +# bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
182 + bool ' Kernel module loader' CONFIG_KMOD
186 +source arch/um/config_char.in
188 +source arch/um/config_block.in
190 +define_bool CONFIG_NETDEVICES $CONFIG_NET
192 +if [ "$CONFIG_NET" = "y" ]; then
193 + source arch/um/config_net.in
194 + source net/Config.in
199 +mainmenu_option next_comment
200 +comment 'SCSI support'
202 +tristate 'SCSI support' CONFIG_SCSI
204 +if [ "$CONFIG_SCSI" != "n" ]; then
205 + source arch/um/config_scsi.in
209 +source drivers/md/Config.in
211 +source drivers/mtd/Config.in
213 +source lib/Config.in
215 +mainmenu_option next_comment
216 +comment 'Kernel hacking'
217 +bool 'Debug memory allocations' CONFIG_DEBUG_SLAB
218 +bool 'Enable kernel debugging symbols' CONFIG_DEBUGSYM
219 +if [ "$CONFIG_XTERM_CHAN" = "y" ]; then
220 + dep_bool 'Enable ptrace proxy' CONFIG_PT_PROXY $CONFIG_DEBUGSYM
222 + define_bool CONFIG_PT_PROXY n
224 +dep_bool 'Enable gprof support' CONFIG_GPROF $CONFIG_DEBUGSYM
225 +dep_bool 'Enable gcov support' CONFIG_GCOV $CONFIG_DEBUGSYM
227 diff -Naur -X ../exclude-files orig/arch/um/config_net.in um/arch/um/config_net.in
228 --- orig/arch/um/config_net.in 1969-12-31 19:00:00.000000000 -0500
229 +++ um/arch/um/config_net.in 2002-10-23 21:08:04.000000000 -0400
231 +mainmenu_option next_comment
232 +comment 'Network Devices'
234 +# UML virtual driver
235 +bool 'Virtual network device' CONFIG_UML_NET
237 +dep_bool ' Ethertap transport' CONFIG_UML_NET_ETHERTAP $CONFIG_UML_NET
238 +dep_bool ' TUN/TAP transport' CONFIG_UML_NET_TUNTAP $CONFIG_UML_NET
239 +dep_bool ' SLIP transport' CONFIG_UML_NET_SLIP $CONFIG_UML_NET
240 +dep_bool ' SLiRP transport' CONFIG_UML_NET_SLIRP $CONFIG_UML_NET
241 +dep_bool ' Daemon transport' CONFIG_UML_NET_DAEMON $CONFIG_UML_NET
242 +dep_bool ' Multicast transport' CONFIG_UML_NET_MCAST $CONFIG_UML_NET
243 +dep_bool ' pcap transport' CONFIG_UML_NET_PCAP $CONFIG_UML_NET
245 +# Below are hardware-independent drivers mirrored from
246 +# drivers/net/Config.in. It would be nice if Linux
247 +# had HW independent drivers separated from the other
248 +# but it does not. Until then each non-ISA/PCI arch
249 +# needs to provide it's own menu of network drivers
251 +tristate 'Dummy net driver support' CONFIG_DUMMY
252 +tristate 'Bonding driver support' CONFIG_BONDING
253 +tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
254 +tristate 'Universal TUN/TAP device driver support' CONFIG_TUN
255 +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
256 + if [ "$CONFIG_NETLINK" = "y" ]; then
257 + tristate 'Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP
261 +tristate 'PPP (point-to-point protocol) support' CONFIG_PPP
262 +if [ ! "$CONFIG_PPP" = "n" ]; then
263 + dep_bool ' PPP multilink support (EXPERIMENTAL)' CONFIG_PPP_MULTILINK $CONFIG_EXPERIMENTAL
264 + dep_bool ' PPP filtering' CONFIG_PPP_FILTER $CONFIG_FILTER
265 + dep_tristate ' PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP
266 + dep_tristate ' PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
267 + dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
268 + dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP
269 + dep_tristate ' PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP $CONFIG_EXPERIMENTAL
272 +tristate 'SLIP (serial line) support' CONFIG_SLIP
273 +dep_bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED $CONFIG_SLIP
274 +dep_bool ' Keepalive and linefill' CONFIG_SLIP_SMART $CONFIG_SLIP
275 +dep_bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 $CONFIG_SLIP
278 diff -Naur -X ../exclude-files orig/arch/um/config.release um/arch/um/config.release
279 --- orig/arch/um/config.release 1969-12-31 19:00:00.000000000 -0500
280 +++ um/arch/um/config.release 2002-10-23 21:08:04.000000000 -0400
283 +# Automatically generated make config: don't edit
286 +# CONFIG_ISA is not set
287 +# CONFIG_SBUS is not set
288 +# CONFIG_PCI is not set
290 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
293 +# Code maturity level options
295 +CONFIG_EXPERIMENTAL=y
302 +CONFIG_BSD_PROCESS_ACCT=y
304 +CONFIG_BINFMT_AOUT=y
306 +CONFIG_BINFMT_MISC=y
308 +# CONFIG_HPPFS is not set
310 +CONFIG_MAGIC_SYSRQ=y
311 +# CONFIG_HOST_2G_2G is not set
312 +# CONFIG_UML_SMP is not set
313 +# CONFIG_SMP is not set
315 +CONFIG_KERNEL_HALF_GIGS=1
318 +# Loadable module support
326 +CONFIG_STDIO_CONSOLE=y
329 +# CONFIG_NULL_CHAN is not set
334 +CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
335 +CONFIG_CON_CHAN="xterm"
336 +CONFIG_SSL_CHAN="pty"
337 +CONFIG_UNIX98_PTYS=y
338 +CONFIG_UNIX98_PTY_COUNT=256
339 +# CONFIG_WATCHDOG is not set
343 +# CONFIG_TTY_LOG is not set
348 +CONFIG_BLK_DEV_UBD=y
349 +# CONFIG_BLK_DEV_UBD_SYNC is not set
350 +CONFIG_BLK_DEV_LOOP=y
351 +CONFIG_BLK_DEV_NBD=y
352 +CONFIG_BLK_DEV_RAM=y
353 +CONFIG_BLK_DEV_RAM_SIZE=4096
354 +CONFIG_BLK_DEV_INITRD=y
355 +# CONFIG_MMAPPER is not set
362 +CONFIG_UML_NET_ETHERTAP=y
363 +CONFIG_UML_NET_TUNTAP=y
364 +CONFIG_UML_NET_SLIP=y
365 +CONFIG_UML_NET_DAEMON=y
366 +CONFIG_UML_NET_MCAST=y
372 +CONFIG_PPP_MULTILINK=y
373 +# CONFIG_PPP_ASYNC is not set
374 +CONFIG_PPP_SYNC_TTY=m
375 +CONFIG_PPP_DEFLATE=m
376 +CONFIG_PPP_BSDCOMP=m
381 +# Networking options
384 +CONFIG_PACKET_MMAP=y
385 +# CONFIG_NETLINK_DEV is not set
386 +# CONFIG_NETFILTER is not set
387 +# CONFIG_FILTER is not set
390 +# CONFIG_IP_MULTICAST is not set
391 +# CONFIG_IP_ADVANCED_ROUTER is not set
392 +# CONFIG_IP_PNP is not set
393 +# CONFIG_NET_IPIP is not set
394 +# CONFIG_NET_IPGRE is not set
395 +# CONFIG_ARPD is not set
396 +# CONFIG_INET_ECN is not set
397 +# CONFIG_SYN_COOKIES is not set
398 +# CONFIG_IPV6 is not set
399 +# CONFIG_KHTTPD is not set
400 +# CONFIG_ATM is not set
401 +# CONFIG_VLAN_8021Q is not set
406 +# CONFIG_IPX is not set
407 +# CONFIG_ATALK is not set
412 +# CONFIG_DECNET is not set
413 +# CONFIG_BRIDGE is not set
414 +# CONFIG_X25 is not set
415 +# CONFIG_LAPB is not set
416 +# CONFIG_LLC is not set
417 +# CONFIG_NET_DIVERT is not set
418 +# CONFIG_ECONET is not set
419 +# CONFIG_WAN_ROUTER is not set
420 +# CONFIG_NET_FASTROUTE is not set
421 +# CONFIG_NET_HW_FLOWCONTROL is not set
424 +# QoS and/or fair queueing
426 +# CONFIG_NET_SCHED is not set
431 +# CONFIG_NET_PKTGEN is not set
439 +CONFIG_REISERFS_FS=m
440 +# CONFIG_REISERFS_CHECK is not set
441 +# CONFIG_REISERFS_PROC_INFO is not set
443 +# CONFIG_ADFS_FS_RW is not set
449 +# CONFIG_JBD_DEBUG is not set
459 +# CONFIG_JOLIET is not set
460 +# CONFIG_ZISOFS is not set
463 +# CONFIG_NTFS_FS is not set
467 +CONFIG_DEVFS_MOUNT=y
468 +# CONFIG_DEVFS_DEBUG is not set
471 +# CONFIG_QNX4FS_RW is not set
476 +# CONFIG_UDF_RW is not set
478 +# CONFIG_UFS_FS_WRITE is not set
481 +# Network File Systems
483 +# CONFIG_CODA_FS is not set
484 +# CONFIG_INTERMEZZO_FS is not set
492 +# CONFIG_SMB_FS is not set
493 +# CONFIG_NCP_FS is not set
494 +# CONFIG_ZISOFS_FS is not set
495 +CONFIG_ZLIB_FS_INFLATE=m
500 +# CONFIG_PARTITION_ADVANCED is not set
501 +CONFIG_MSDOS_PARTITION=y
502 +# CONFIG_SMB_NLS is not set
506 +# Native Language Support
508 +CONFIG_NLS_DEFAULT="iso8859-1"
509 +# CONFIG_NLS_CODEPAGE_437 is not set
510 +# CONFIG_NLS_CODEPAGE_737 is not set
511 +# CONFIG_NLS_CODEPAGE_775 is not set
512 +# CONFIG_NLS_CODEPAGE_850 is not set
513 +# CONFIG_NLS_CODEPAGE_852 is not set
514 +# CONFIG_NLS_CODEPAGE_855 is not set
515 +# CONFIG_NLS_CODEPAGE_857 is not set
516 +# CONFIG_NLS_CODEPAGE_860 is not set
517 +# CONFIG_NLS_CODEPAGE_861 is not set
518 +# CONFIG_NLS_CODEPAGE_862 is not set
519 +# CONFIG_NLS_CODEPAGE_863 is not set
520 +# CONFIG_NLS_CODEPAGE_864 is not set
521 +# CONFIG_NLS_CODEPAGE_865 is not set
522 +# CONFIG_NLS_CODEPAGE_866 is not set
523 +# CONFIG_NLS_CODEPAGE_869 is not set
524 +# CONFIG_NLS_CODEPAGE_936 is not set
525 +# CONFIG_NLS_CODEPAGE_950 is not set
526 +# CONFIG_NLS_CODEPAGE_932 is not set
527 +# CONFIG_NLS_CODEPAGE_949 is not set
528 +# CONFIG_NLS_CODEPAGE_874 is not set
529 +# CONFIG_NLS_ISO8859_8 is not set
530 +# CONFIG_NLS_CODEPAGE_1250 is not set
531 +# CONFIG_NLS_CODEPAGE_1251 is not set
532 +# CONFIG_NLS_ISO8859_1 is not set
533 +# CONFIG_NLS_ISO8859_2 is not set
534 +# CONFIG_NLS_ISO8859_3 is not set
535 +# CONFIG_NLS_ISO8859_4 is not set
536 +# CONFIG_NLS_ISO8859_5 is not set
537 +# CONFIG_NLS_ISO8859_6 is not set
538 +# CONFIG_NLS_ISO8859_7 is not set
539 +# CONFIG_NLS_ISO8859_9 is not set
540 +# CONFIG_NLS_ISO8859_13 is not set
541 +# CONFIG_NLS_ISO8859_14 is not set
542 +# CONFIG_NLS_ISO8859_15 is not set
543 +# CONFIG_NLS_KOI8_R is not set
544 +# CONFIG_NLS_KOI8_U is not set
545 +# CONFIG_NLS_UTF8 is not set
553 +# SCSI support type (disk, tape, CD-ROM)
555 +# CONFIG_BLK_DEV_SD is not set
556 +# CONFIG_CHR_DEV_ST is not set
557 +# CONFIG_BLK_DEV_SR is not set
558 +# CONFIG_CHR_DEV_SG is not set
561 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
563 +# CONFIG_SCSI_DEBUG_QUEUES is not set
564 +# CONFIG_SCSI_MULTI_LUN is not set
565 +# CONFIG_SCSI_CONSTANTS is not set
566 +# CONFIG_SCSI_LOGGING is not set
570 +# Multi-device support (RAID and LVM)
572 +# CONFIG_MD is not set
575 +# Memory Technology Devices (MTD)
577 +# CONFIG_MTD is not set
582 +# CONFIG_DEBUG_SLAB is not set
583 +# CONFIG_DEBUGSYM is not set
584 diff -Naur -X ../exclude-files orig/arch/um/config_scsi.in um/arch/um/config_scsi.in
585 --- orig/arch/um/config_scsi.in 1969-12-31 19:00:00.000000000 -0500
586 +++ um/arch/um/config_scsi.in 2002-10-23 21:08:04.000000000 -0400
588 +comment 'SCSI support type (disk, tape, CD-ROM)'
590 +dep_tristate ' SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
592 +if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then
593 + int 'Maximum number of SCSI disks that can be loaded as modules' CONFIG_SD_EXTRA_DEVS 40
596 +dep_tristate ' SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
598 +dep_tristate ' SCSI CD-ROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
600 +if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
601 + bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
602 + int 'Maximum number of CDROM devices that can be loaded as modules' CONFIG_SR_EXTRA_DEVS 2
604 +dep_tristate ' SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
606 +comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
608 +#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
609 + bool ' Enable extra checks in new queueing code' CONFIG_SCSI_DEBUG_QUEUES
612 +bool ' Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
614 +bool ' Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
615 +bool ' SCSI logging facility' CONFIG_SCSI_LOGGING
617 +dep_tristate 'SCSI debugging host simulator (EXPERIMENTAL)' CONFIG_SCSI_DEBUG $CONFIG_SCSI
618 diff -Naur -X ../exclude-files orig/arch/um/defconfig um/arch/um/defconfig
619 --- orig/arch/um/defconfig 1969-12-31 19:00:00.000000000 -0500
620 +++ um/arch/um/defconfig 2003-01-20 11:26:54.000000000 -0500
623 +# Automatically generated make config: don't edit
626 +# CONFIG_ISA is not set
627 +# CONFIG_SBUS is not set
628 +# CONFIG_PCI is not set
630 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
633 +# Code maturity level options
635 +CONFIG_EXPERIMENTAL=y
644 +CONFIG_BSD_PROCESS_ACCT=y
646 +CONFIG_BINFMT_AOUT=y
648 +CONFIG_BINFMT_MISC=y
652 +CONFIG_MAGIC_SYSRQ=y
653 +# CONFIG_HOST_2G_2G is not set
654 +# CONFIG_UML_SMP is not set
655 +# CONFIG_SMP is not set
657 +CONFIG_KERNEL_HALF_GIGS=1
658 +# CONFIG_HIGHMEM is not set
660 +CONFIG_KERNEL_STACK_ORDER=2
663 +# Loadable module support
666 +# CONFIG_KMOD is not set
671 +CONFIG_STDIO_CONSOLE=y
679 +CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
680 +CONFIG_CON_CHAN="xterm"
681 +CONFIG_SSL_CHAN="pty"
682 +CONFIG_UNIX98_PTYS=y
683 +CONFIG_UNIX98_PTY_COUNT=256
684 +# CONFIG_WATCHDOG is not set
685 +# CONFIG_WATCHDOG_NOWAYOUT is not set
686 +# CONFIG_SOFT_WATCHDOG is not set
687 +# CONFIG_UML_WATCHDOG is not set
691 +# CONFIG_TTY_LOG is not set
696 +CONFIG_BLK_DEV_UBD=y
697 +# CONFIG_BLK_DEV_UBD_SYNC is not set
698 +CONFIG_BLK_DEV_LOOP=y
699 +CONFIG_BLK_DEV_NBD=y
700 +CONFIG_BLK_DEV_RAM=y
701 +CONFIG_BLK_DEV_RAM_SIZE=4096
702 +CONFIG_BLK_DEV_INITRD=y
703 +# CONFIG_MMAPPER is not set
710 +CONFIG_UML_NET_ETHERTAP=y
711 +CONFIG_UML_NET_TUNTAP=y
712 +CONFIG_UML_NET_SLIP=y
713 +CONFIG_UML_NET_SLIRP=y
714 +CONFIG_UML_NET_DAEMON=y
715 +CONFIG_UML_NET_MCAST=y
716 +# CONFIG_UML_NET_PCAP is not set
718 +# CONFIG_BONDING is not set
719 +# CONFIG_EQUALIZER is not set
722 +# CONFIG_PPP_MULTILINK is not set
723 +# CONFIG_PPP_FILTER is not set
724 +# CONFIG_PPP_ASYNC is not set
725 +# CONFIG_PPP_SYNC_TTY is not set
726 +# CONFIG_PPP_DEFLATE is not set
727 +# CONFIG_PPP_BSDCOMP is not set
728 +# CONFIG_PPPOE is not set
730 +# CONFIG_SLIP_COMPRESSED is not set
731 +# CONFIG_SLIP_SMART is not set
732 +# CONFIG_SLIP_MODE_SLIP6 is not set
735 +# Networking options
738 +CONFIG_PACKET_MMAP=y
739 +# CONFIG_NETLINK_DEV is not set
740 +# CONFIG_NETFILTER is not set
741 +# CONFIG_FILTER is not set
744 +# CONFIG_IP_MULTICAST is not set
745 +# CONFIG_IP_ADVANCED_ROUTER is not set
746 +# CONFIG_IP_PNP is not set
747 +# CONFIG_NET_IPIP is not set
748 +# CONFIG_NET_IPGRE is not set
749 +# CONFIG_ARPD is not set
750 +# CONFIG_INET_ECN is not set
751 +# CONFIG_SYN_COOKIES is not set
752 +# CONFIG_IPV6 is not set
753 +# CONFIG_KHTTPD is not set
754 +# CONFIG_ATM is not set
755 +# CONFIG_VLAN_8021Q is not set
760 +# CONFIG_IPX is not set
761 +# CONFIG_ATALK is not set
766 +# CONFIG_DEV_APPLETALK is not set
767 +# CONFIG_DECNET is not set
768 +# CONFIG_BRIDGE is not set
769 +# CONFIG_X25 is not set
770 +# CONFIG_LAPB is not set
771 +# CONFIG_LLC is not set
772 +# CONFIG_NET_DIVERT is not set
773 +# CONFIG_ECONET is not set
774 +# CONFIG_WAN_ROUTER is not set
775 +# CONFIG_NET_FASTROUTE is not set
776 +# CONFIG_NET_HW_FLOWCONTROL is not set
779 +# QoS and/or fair queueing
781 +# CONFIG_NET_SCHED is not set
786 +# CONFIG_NET_PKTGEN is not set
794 +CONFIG_REISERFS_FS=y
795 +# CONFIG_REISERFS_CHECK is not set
796 +# CONFIG_REISERFS_PROC_INFO is not set
797 +# CONFIG_ADFS_FS is not set
798 +# CONFIG_ADFS_FS_RW is not set
799 +# CONFIG_AFFS_FS is not set
800 +# CONFIG_HFS_FS is not set
801 +# CONFIG_BFS_FS is not set
802 +# CONFIG_EXT3_FS is not set
803 +# CONFIG_JBD is not set
804 +# CONFIG_JBD_DEBUG is not set
809 +# CONFIG_EFS_FS is not set
811 +CONFIG_JFFS_FS_VERBOSE=0
812 +CONFIG_JFFS_PROC_FS=y
814 +CONFIG_JFFS2_FS_DEBUG=0
815 +# CONFIG_CRAMFS is not set
816 +# CONFIG_TMPFS is not set
819 +# CONFIG_JOLIET is not set
820 +# CONFIG_ZISOFS is not set
822 +# CONFIG_VXFS_FS is not set
823 +# CONFIG_NTFS_FS is not set
824 +# CONFIG_NTFS_RW is not set
825 +# CONFIG_HPFS_FS is not set
828 +CONFIG_DEVFS_MOUNT=y
829 +# CONFIG_DEVFS_DEBUG is not set
831 +# CONFIG_QNX4FS_FS is not set
832 +# CONFIG_QNX4FS_RW is not set
833 +# CONFIG_ROMFS_FS is not set
835 +# CONFIG_SYSV_FS is not set
836 +# CONFIG_UDF_FS is not set
837 +# CONFIG_UDF_RW is not set
838 +# CONFIG_UFS_FS is not set
839 +# CONFIG_UFS_FS_WRITE is not set
842 +# Network File Systems
844 +# CONFIG_CODA_FS is not set
845 +# CONFIG_INTERMEZZO_FS is not set
846 +# CONFIG_NFS_FS is not set
847 +# CONFIG_NFS_V3 is not set
848 +# CONFIG_ROOT_NFS is not set
849 +# CONFIG_NFSD is not set
850 +# CONFIG_NFSD_V3 is not set
851 +# CONFIG_SUNRPC is not set
852 +# CONFIG_LOCKD is not set
853 +# CONFIG_SMB_FS is not set
854 +# CONFIG_NCP_FS is not set
855 +# CONFIG_NCPFS_PACKET_SIGNING is not set
856 +# CONFIG_NCPFS_IOCTL_LOCKING is not set
857 +# CONFIG_NCPFS_STRONG is not set
858 +# CONFIG_NCPFS_NFS_NS is not set
859 +# CONFIG_NCPFS_OS2_NS is not set
860 +# CONFIG_NCPFS_SMALLDOS is not set
861 +# CONFIG_NCPFS_NLS is not set
862 +# CONFIG_NCPFS_EXTRAS is not set
863 +# CONFIG_ZISOFS_FS is not set
864 +# CONFIG_ZLIB_FS_INFLATE is not set
869 +# CONFIG_PARTITION_ADVANCED is not set
870 +CONFIG_MSDOS_PARTITION=y
871 +# CONFIG_SMB_NLS is not set
875 +# Native Language Support
877 +CONFIG_NLS_DEFAULT="iso8859-1"
878 +# CONFIG_NLS_CODEPAGE_437 is not set
879 +# CONFIG_NLS_CODEPAGE_737 is not set
880 +# CONFIG_NLS_CODEPAGE_775 is not set
881 +# CONFIG_NLS_CODEPAGE_850 is not set
882 +# CONFIG_NLS_CODEPAGE_852 is not set
883 +# CONFIG_NLS_CODEPAGE_855 is not set
884 +# CONFIG_NLS_CODEPAGE_857 is not set
885 +# CONFIG_NLS_CODEPAGE_860 is not set
886 +# CONFIG_NLS_CODEPAGE_861 is not set
887 +# CONFIG_NLS_CODEPAGE_862 is not set
888 +# CONFIG_NLS_CODEPAGE_863 is not set
889 +# CONFIG_NLS_CODEPAGE_864 is not set
890 +# CONFIG_NLS_CODEPAGE_865 is not set
891 +# CONFIG_NLS_CODEPAGE_866 is not set
892 +# CONFIG_NLS_CODEPAGE_869 is not set
893 +# CONFIG_NLS_CODEPAGE_936 is not set
894 +# CONFIG_NLS_CODEPAGE_950 is not set
895 +# CONFIG_NLS_CODEPAGE_932 is not set
896 +# CONFIG_NLS_CODEPAGE_949 is not set
897 +# CONFIG_NLS_CODEPAGE_874 is not set
898 +# CONFIG_NLS_ISO8859_8 is not set
899 +# CONFIG_NLS_CODEPAGE_1250 is not set
900 +# CONFIG_NLS_CODEPAGE_1251 is not set
901 +# CONFIG_NLS_ISO8859_1 is not set
902 +# CONFIG_NLS_ISO8859_2 is not set
903 +# CONFIG_NLS_ISO8859_3 is not set
904 +# CONFIG_NLS_ISO8859_4 is not set
905 +# CONFIG_NLS_ISO8859_5 is not set
906 +# CONFIG_NLS_ISO8859_6 is not set
907 +# CONFIG_NLS_ISO8859_7 is not set
908 +# CONFIG_NLS_ISO8859_9 is not set
909 +# CONFIG_NLS_ISO8859_13 is not set
910 +# CONFIG_NLS_ISO8859_14 is not set
911 +# CONFIG_NLS_ISO8859_15 is not set
912 +# CONFIG_NLS_KOI8_R is not set
913 +# CONFIG_NLS_KOI8_U is not set
914 +# CONFIG_NLS_UTF8 is not set
922 +# SCSI support type (disk, tape, CD-ROM)
924 +# CONFIG_BLK_DEV_SD is not set
925 +# CONFIG_CHR_DEV_ST is not set
926 +# CONFIG_BLK_DEV_SR is not set
927 +# CONFIG_CHR_DEV_SG is not set
930 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
932 +# CONFIG_SCSI_DEBUG_QUEUES is not set
933 +# CONFIG_SCSI_MULTI_LUN is not set
934 +# CONFIG_SCSI_CONSTANTS is not set
935 +# CONFIG_SCSI_LOGGING is not set
939 +# Multi-device support (RAID and LVM)
941 +# CONFIG_MD is not set
942 +# CONFIG_BLK_DEV_MD is not set
943 +# CONFIG_MD_LINEAR is not set
944 +# CONFIG_MD_RAID0 is not set
945 +# CONFIG_MD_RAID1 is not set
946 +# CONFIG_MD_RAID5 is not set
947 +# CONFIG_MD_MULTIPATH is not set
948 +# CONFIG_BLK_DEV_LVM is not set
951 +# Memory Technology Devices (MTD)
954 +# CONFIG_MTD_DEBUG is not set
955 +# CONFIG_MTD_PARTITIONS is not set
956 +# CONFIG_MTD_CONCAT is not set
957 +# CONFIG_MTD_REDBOOT_PARTS is not set
960 +# User Modules And Translation Layers
964 +# CONFIG_FTL is not set
965 +# CONFIG_NFTL is not set
968 +# RAM/ROM/Flash chip drivers
970 +# CONFIG_MTD_CFI is not set
971 +# CONFIG_MTD_JEDECPROBE is not set
972 +# CONFIG_MTD_GEN_PROBE is not set
973 +# CONFIG_MTD_CFI_INTELEXT is not set
974 +# CONFIG_MTD_CFI_AMDSTD is not set
975 +# CONFIG_MTD_RAM is not set
976 +# CONFIG_MTD_ROM is not set
977 +# CONFIG_MTD_ABSENT is not set
978 +# CONFIG_MTD_OBSOLETE_CHIPS is not set
979 +# CONFIG_MTD_AMDSTD is not set
980 +# CONFIG_MTD_SHARP is not set
981 +# CONFIG_MTD_JEDEC is not set
984 +# Mapping drivers for chip access
986 +# CONFIG_MTD_PHYSMAP is not set
987 +# CONFIG_MTD_PCI is not set
990 +# Self-contained MTD device drivers
992 +# CONFIG_MTD_PMC551 is not set
993 +# CONFIG_MTD_SLRAM is not set
994 +# CONFIG_MTD_MTDRAM is not set
998 +# Disk-On-Chip Device Drivers
1000 +# CONFIG_MTD_DOC1000 is not set
1001 +# CONFIG_MTD_DOC2000 is not set
1002 +# CONFIG_MTD_DOC2001 is not set
1003 +# CONFIG_MTD_DOCPROBE is not set
1006 +# NAND Flash Device Drivers
1008 +# CONFIG_MTD_NAND is not set
1013 +# CONFIG_DEBUG_SLAB is not set
1016 +# CONFIG_GPROF is not set
1017 +# CONFIG_GCOV is not set
1018 diff -Naur -X ../exclude-files orig/arch/um/drivers/chan_kern.c um/arch/um/drivers/chan_kern.c
1019 --- orig/arch/um/drivers/chan_kern.c 1969-12-31 19:00:00.000000000 -0500
1020 +++ um/arch/um/drivers/chan_kern.c 2003-03-06 19:25:16.000000000 -0500
1023 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
1024 + * Licensed under the GPL
1027 +#include <linux/stddef.h>
1028 +#include <linux/kernel.h>
1029 +#include <linux/list.h>
1030 +#include <linux/slab.h>
1031 +#include <linux/tty.h>
1032 +#include <linux/string.h>
1033 +#include <linux/tty_flip.h>
1034 +#include <asm/irq.h>
1035 +#include "chan_kern.h"
1036 +#include "user_util.h"
1038 +#include "irq_user.h"
1042 +static void *not_configged_init(char *str, int device, struct chan_opts *opts)
1044 + printk(KERN_ERR "Using a channel type which is configured out of "
1049 +static int not_configged_open(int input, int output, int primary, void *data,
1052 + printk(KERN_ERR "Using a channel type which is configured out of "
1057 +static void not_configged_close(int fd, void *data)
1059 + printk(KERN_ERR "Using a channel type which is configured out of "
1063 +static int not_configged_read(int fd, char *c_out, void *data)
1065 + printk(KERN_ERR "Using a channel type which is configured out of "
1070 +static int not_configged_write(int fd, const char *buf, int len, void *data)
1072 + printk(KERN_ERR "Using a channel type which is configured out of "
1077 +static int not_configged_console_write(int fd, const char *buf, int len,
1080 + printk(KERN_ERR "Using a channel type which is configured out of "
1085 +static int not_configged_window_size(int fd, void *data, unsigned short *rows,
1086 + unsigned short *cols)
1088 + printk(KERN_ERR "Using a channel type which is configured out of "
1093 +static void not_configged_free(void *data)
1095 + printk(KERN_ERR "Using a channel type which is configured out of "
1099 +static struct chan_ops not_configged_ops = {
1100 + .init = not_configged_init,
1101 + .open = not_configged_open,
1102 + .close = not_configged_close,
1103 + .read = not_configged_read,
1104 + .write = not_configged_write,
1105 + .console_write = not_configged_console_write,
1106 + .window_size = not_configged_window_size,
1107 + .free = not_configged_free,
1111 +static void tty_receive_char(struct tty_struct *tty, char ch)
1113 + if(tty == NULL) return;
1115 + if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
1116 + if(ch == STOP_CHAR(tty)){
1120 + else if(ch == START_CHAR(tty)){
1126 + if((tty->flip.flag_buf_ptr == NULL) ||
1127 + (tty->flip.char_buf_ptr == NULL))
1129 + tty_insert_flip_char(tty, ch, TTY_NORMAL);
1132 +static int open_one_chan(struct chan *chan, int input, int output, int primary)
1136 + if(chan->opened) return(0);
1137 + if(chan->ops->open == NULL) fd = 0;
1138 + else fd = (*chan->ops->open)(input, output, primary, chan->data,
1140 + if(fd < 0) return(fd);
1147 +int open_chan(struct list_head *chans)
1149 + struct list_head *ele;
1150 + struct chan *chan;
1153 + list_for_each(ele, chans){
1154 + chan = list_entry(ele, struct chan, list);
1155 + ret = open_one_chan(chan, chan->input, chan->output,
1157 + if(chan->primary) err = ret;
1162 +void chan_enable_winch(struct list_head *chans, void *line)
1164 + struct list_head *ele;
1165 + struct chan *chan;
1167 + list_for_each(ele, chans){
1168 + chan = list_entry(ele, struct chan, list);
1169 + if(chan->primary && chan->output && chan->ops->winch){
1170 + register_winch(chan->fd, line);
1176 +void enable_chan(struct list_head *chans, void *data)
1178 + struct list_head *ele;
1179 + struct chan *chan;
1181 + list_for_each(ele, chans){
1182 + chan = list_entry(ele, struct chan, list);
1183 + if(!chan->opened) continue;
1185 + line_setup_irq(chan->fd, chan->input, chan->output, data);
1189 +void close_chan(struct list_head *chans)
1191 + struct list_head *ele;
1192 + struct chan *chan;
1194 + /* Close in reverse order as open in case more than one of them
1195 + * refers to the same device and they save and restore that device's
1196 + * state. Then, the first one opened will have the original state,
1197 + * so it must be the last closed.
1199 + for(ele = chans->prev; ele != chans; ele = ele->prev){
1200 + chan = list_entry(ele, struct chan, list);
1201 + if(!chan->opened) continue;
1202 + if(chan->ops->close != NULL)
1203 + (*chan->ops->close)(chan->fd, chan->data);
1209 +int write_chan(struct list_head *chans, const char *buf, int len,
1212 + struct list_head *ele;
1213 + struct chan *chan;
1216 + list_for_each(ele, chans){
1217 + chan = list_entry(ele, struct chan, list);
1218 + if(!chan->output || (chan->ops->write == NULL)) continue;
1219 + n = chan->ops->write(chan->fd, buf, len, chan->data);
1220 + if(chan->primary){
1222 + if((ret == -EAGAIN) || ((ret >= 0) && (ret < len))){
1223 + reactivate_fd(chan->fd, write_irq);
1224 + if(ret == -EAGAIN) ret = 0;
1231 +int console_write_chan(struct list_head *chans, const char *buf, int len)
1233 + struct list_head *ele;
1234 + struct chan *chan;
1237 + list_for_each(ele, chans){
1238 + chan = list_entry(ele, struct chan, list);
1239 + if(!chan->output || (chan->ops->console_write == NULL))
1241 + n = chan->ops->console_write(chan->fd, buf, len, chan->data);
1242 + if(chan->primary) ret = n;
1247 +int chan_window_size(struct list_head *chans, unsigned short *rows_out,
1248 + unsigned short *cols_out)
1250 + struct list_head *ele;
1251 + struct chan *chan;
1253 + list_for_each(ele, chans){
1254 + chan = list_entry(ele, struct chan, list);
1255 + if(chan->primary){
1256 + if(chan->ops->window_size == NULL) return(0);
1257 + return(chan->ops->window_size(chan->fd, chan->data,
1258 + rows_out, cols_out));
1264 +void free_one_chan(struct chan *chan)
1266 + list_del(&chan->list);
1267 + if(chan->ops->free != NULL)
1268 + (*chan->ops->free)(chan->data);
1269 + free_irq_by_fd(chan->fd);
1270 + if(chan->primary && chan->output) ignore_sigio_fd(chan->fd);
1274 +void free_chan(struct list_head *chans)
1276 + struct list_head *ele, *next;
1277 + struct chan *chan;
1279 + list_for_each_safe(ele, next, chans){
1280 + chan = list_entry(ele, struct chan, list);
1281 + free_one_chan(chan);
1285 +static int one_chan_config_string(struct chan *chan, char *str, int size,
1290 + CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
1292 + if(chan->dev == NULL){
1293 + CONFIG_CHUNK(str, size, n, "", 1);
1297 + CONFIG_CHUNK(str, size, n, ":", 0);
1298 + CONFIG_CHUNK(str, size, n, chan->dev, 0);
1303 +static int chan_pair_config_string(struct chan *in, struct chan *out,
1304 + char *str, int size, char **error_out)
1308 + n = one_chan_config_string(in, str, size, error_out);
1313 + CONFIG_CHUNK(str, size, n, "", 1);
1317 + CONFIG_CHUNK(str, size, n, ",", 1);
1318 + n = one_chan_config_string(out, str, size, error_out);
1321 + CONFIG_CHUNK(str, size, n, "", 1);
1326 +int chan_config_string(struct list_head *chans, char *str, int size,
1329 + struct list_head *ele;
1330 + struct chan *chan, *in = NULL, *out = NULL;
1332 + list_for_each(ele, chans){
1333 + chan = list_entry(ele, struct chan, list);
1334 + if(!chan->primary)
1342 + return(chan_pair_config_string(in, out, str, size, error_out));
1347 + struct chan_ops *ops;
1350 +struct chan_type chan_table[] = {
1351 +#ifdef CONFIG_FD_CHAN
1352 + { "fd", &fd_ops },
1354 + { "fd", ¬_configged_ops },
1357 +#ifdef CONFIG_NULL_CHAN
1358 + { "null", &null_ops },
1360 + { "null", ¬_configged_ops },
1363 +#ifdef CONFIG_PORT_CHAN
1364 + { "port", &port_ops },
1366 + { "port", ¬_configged_ops },
1369 +#ifdef CONFIG_PTY_CHAN
1370 + { "pty", &pty_ops },
1371 + { "pts", &pts_ops },
1373 + { "pty", ¬_configged_ops },
1374 + { "pts", ¬_configged_ops },
1377 +#ifdef CONFIG_TTY_CHAN
1378 + { "tty", &tty_ops },
1380 + { "tty", ¬_configged_ops },
1383 +#ifdef CONFIG_XTERM_CHAN
1384 + { "xterm", &xterm_ops },
1386 + { "xterm", ¬_configged_ops },
1390 +static struct chan *parse_chan(char *str, int pri, int device,
1391 + struct chan_opts *opts)
1393 + struct chan_type *entry;
1394 + struct chan_ops *ops;
1395 + struct chan *chan;
1401 + for(i = 0; i < sizeof(chan_table)/sizeof(chan_table[0]); i++){
1402 + entry = &chan_table[i];
1403 + if(!strncmp(str, entry->key, strlen(entry->key))){
1405 + str += strlen(entry->key);
1410 + printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n",
1414 + if(ops->init == NULL) return(NULL);
1415 + data = (*ops->init)(str, device, opts);
1416 + if(data == NULL) return(NULL);
1418 + chan = kmalloc(sizeof(*chan), GFP_KERNEL);
1419 + if(chan == NULL) return(NULL);
1420 + *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list),
1432 +int parse_chan_pair(char *str, struct list_head *chans, int pri, int device,
1433 + struct chan_opts *opts)
1435 + struct chan *new, *chan;
1438 + if(!list_empty(chans)){
1439 + chan = list_entry(chans->next, struct chan, list);
1440 + if(chan->pri >= pri) return(0);
1442 + INIT_LIST_HEAD(chans);
1445 + if((out = strchr(str, ',')) != NULL){
1449 + new = parse_chan(in, pri, device, opts);
1450 + if(new == NULL) return(-1);
1452 + list_add(&new->list, chans);
1454 + new = parse_chan(out, pri, device, opts);
1455 + if(new == NULL) return(-1);
1456 + list_add(&new->list, chans);
1460 + new = parse_chan(str, pri, device, opts);
1461 + if(new == NULL) return(-1);
1462 + list_add(&new->list, chans);
1469 +int chan_out_fd(struct list_head *chans)
1471 + struct list_head *ele;
1472 + struct chan *chan;
1474 + list_for_each(ele, chans){
1475 + chan = list_entry(ele, struct chan, list);
1476 + if(chan->primary && chan->output)
1482 +void chan_interrupt(struct list_head *chans, struct tq_struct *task,
1483 + struct tty_struct *tty, int irq, void *dev)
1485 + struct list_head *ele, *next;
1486 + struct chan *chan;
1490 + list_for_each_safe(ele, next, chans){
1491 + chan = list_entry(ele, struct chan, list);
1492 + if(!chan->input || (chan->ops->read == NULL)) continue;
1494 + if((tty != NULL) &&
1495 + (tty->flip.count >= TTY_FLIPBUF_SIZE)){
1496 + queue_task(task, &tq_timer);
1499 + err = chan->ops->read(chan->fd, &c, chan->data);
1500 + if(err > 0) tty_receive_char(tty, c);
1502 + if(err == 0) reactivate_fd(chan->fd, irq);
1504 + if(chan->primary){
1505 + if(tty != NULL) tty_hangup(tty);
1506 + line_disable(dev, irq);
1507 + close_chan(chans);
1512 + if(chan->ops->close != NULL)
1513 + chan->ops->close(chan->fd, chan->data);
1514 + free_one_chan(chan);
1519 + if(tty) tty_flip_buffer_push(tty);
1523 + * Overrides for Emacs so that we follow Linus's tabbing style.
1524 + * Emacs will notice this stuff at the end of the file and automatically
1525 + * adjust the settings for this buffer only. This must remain at the end
1527 + * ---------------------------------------------------------------------------
1528 + * Local variables:
1529 + * c-file-style: "linux"
1532 diff -Naur -X ../exclude-files orig/arch/um/drivers/chan_user.c um/arch/um/drivers/chan_user.c
1533 --- orig/arch/um/drivers/chan_user.c 1969-12-31 19:00:00.000000000 -0500
1534 +++ um/arch/um/drivers/chan_user.c 2003-03-26 13:23:48.000000000 -0500
1537 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
1538 + * Licensed under the GPL
1541 +#include <unistd.h>
1542 +#include <stdlib.h>
1544 +#include <termios.h>
1546 +#include <string.h>
1547 +#include <signal.h>
1548 +#include <sys/stat.h>
1549 +#include <sys/ioctl.h>
1550 +#include <sys/socket.h>
1551 +#include "kern_util.h"
1552 +#include "user_util.h"
1553 +#include "chan_user.h"
1555 +#include "helper.h"
1557 +#include "choose-mode.h"
1560 +void generic_close(int fd, void *unused)
1565 +int generic_read(int fd, char *c_out, void *unused)
1569 + n = read(fd, c_out, sizeof(*c_out));
1571 + if(errno == EAGAIN) return(0);
1574 + else if(n == 0) return(-EIO);
1578 +int generic_write(int fd, const char *buf, int n, void *unused)
1582 + count = write(fd, buf, n);
1583 + if(count < 0) return(-errno);
1587 +int generic_console_write(int fd, const char *buf, int n, void *unused)
1589 + struct termios save, new;
1593 + tcgetattr(fd, &save);
1595 + new.c_oflag |= OPOST;
1596 + tcsetattr(fd, TCSAFLUSH, &new);
1598 + err = generic_write(fd, buf, n, NULL);
1599 + if(isatty(fd)) tcsetattr(fd, TCSAFLUSH, &save);
1603 +int generic_window_size(int fd, void *unused, unsigned short *rows_out,
1604 + unsigned short *cols_out)
1606 + struct winsize size;
1609 + if(ioctl(fd, TIOCGWINSZ, &size) == 0){
1610 + ret = ((*rows_out != size.ws_row) ||
1611 + (*cols_out != size.ws_col));
1612 + *rows_out = size.ws_row;
1613 + *cols_out = size.ws_col;
1618 +void generic_free(void *data)
1623 +static void winch_handler(int sig)
1627 +struct winch_data {
1633 +static int winch_thread(void *arg)
1635 + struct winch_data *data = arg;
1637 + int pty_fd, pipe_fd;
1640 + close(data->close_me);
1641 + pty_fd = data->pty_fd;
1642 + pipe_fd = data->pipe_fd;
1643 + if(write(pipe_fd, &c, sizeof(c)) != sizeof(c))
1644 + printk("winch_thread : failed to write synchronization "
1645 + "byte, errno = %d\n", errno);
1647 + signal(SIGWINCH, winch_handler);
1648 + sigfillset(&sigs);
1649 + sigdelset(&sigs, SIGWINCH);
1650 + if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
1651 + printk("winch_thread : sigprocmask failed, errno = %d\n",
1657 + printk("winch_thread : setsid failed, errno = %d\n", errno);
1661 + if(ioctl(pty_fd, TIOCSCTTY, 0) < 0){
1662 + printk("winch_thread : TIOCSCTTY failed, errno = %d\n", errno);
1665 + if(tcsetpgrp(pty_fd, os_getpid()) < 0){
1666 + printk("winch_thread : tcsetpgrp failed, errno = %d\n", errno);
1670 + if(read(pipe_fd, &c, sizeof(c)) != sizeof(c))
1671 + printk("winch_thread : failed to read synchronization byte, "
1672 + "errno = %d\n", errno);
1677 + if(write(pipe_fd, &c, sizeof(c)) != sizeof(c)){
1678 + printk("winch_thread : write failed, errno = %d\n",
1684 +static int winch_tramp(int fd, void *device_data, int *fd_out)
1686 + struct winch_data data;
1687 + unsigned long stack;
1688 + int fds[2], pid, n, err;
1691 + err = os_pipe(fds, 1, 1);
1693 + printk("winch_tramp : os_pipe failed, errno = %d\n", -err);
1697 + data = ((struct winch_data) { .pty_fd = fd,
1698 + .pipe_fd = fds[1],
1699 + .close_me = fds[0] } );
1700 + pid = run_helper_thread(winch_thread, &data, 0, &stack, 0);
1702 + printk("fork of winch_thread failed - errno = %d\n", errno);
1708 + n = read(fds[0], &c, sizeof(c));
1709 + if(n != sizeof(c)){
1710 + printk("winch_tramp : failed to read synchronization byte\n");
1711 + printk("read returned %d, errno = %d\n", n, errno);
1712 + printk("fd %d will not support SIGWINCH\n", fd);
1718 +void register_winch(int fd, void *device_data)
1720 + int pid, thread, thread_fd;
1723 + if(!isatty(fd)) return;
1725 + pid = tcgetpgrp(fd);
1726 + if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd,
1727 + device_data) && (pid == -1)){
1728 + thread = winch_tramp(fd, device_data, &thread_fd);
1730 + register_winch_irq(thread_fd, fd, thread, device_data);
1732 + if(write(thread_fd, &c, sizeof(c)) != sizeof(c))
1733 + printk("register_winch : failed to write "
1734 + "synchronization byte\n");
1740 + * Overrides for Emacs so that we follow Linus's tabbing style.
1741 + * Emacs will notice this stuff at the end of the file and automatically
1742 + * adjust the settings for this buffer only. This must remain at the end
1744 + * ---------------------------------------------------------------------------
1745 + * Local variables:
1746 + * c-file-style: "linux"
1749 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow.h um/arch/um/drivers/cow.h
1750 --- orig/arch/um/drivers/cow.h 1969-12-31 19:00:00.000000000 -0500
1751 +++ um/arch/um/drivers/cow.h 2003-06-05 14:28:44.000000000 -0400
1756 +#include <asm/types.h>
1758 +#if __BYTE_ORDER == __BIG_ENDIAN
1759 +# define ntohll(x) (x)
1760 +# define htonll(x) (x)
1761 +#elif __BYTE_ORDER == __LITTLE_ENDIAN
1762 +# define ntohll(x) bswap_64(x)
1763 +# define htonll(x) bswap_64(x)
1765 +#error "__BYTE_ORDER not defined"
1768 +extern int init_cow_file(int fd, char *cow_file, char *backing_file,
1769 + int sectorsize, int *bitmap_offset_out,
1770 + unsigned long *bitmap_len_out, int *data_offset_out);
1771 +extern int read_cow_header(int fd, __u32 *magic_out, char **backing_file_out,
1772 + time_t *mtime_out, __u64 *size_out,
1773 + int *sectorsize_out, int *bitmap_offset_out);
1774 +extern int write_cow_header(char *cow_file, int fd, char *backing_file,
1775 + int sectorsize, long long *size);
1776 +extern void cow_sizes(__u64 size, int sectorsize, int bitmap_offset,
1777 + unsigned long *bitmap_len_out, int *data_offset_out);
1782 + * ---------------------------------------------------------------------------
1783 + * Local variables:
1784 + * c-file-style: "linux"
1787 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow_sys.h um/arch/um/drivers/cow_sys.h
1788 --- orig/arch/um/drivers/cow_sys.h 1969-12-31 19:00:00.000000000 -0500
1789 +++ um/arch/um/drivers/cow_sys.h 2003-06-05 14:29:25.000000000 -0400
1791 +#ifndef __COW_SYS_H__
1792 +#define __COW_SYS_H__
1794 +#include "kern_util.h"
1795 +#include "user_util.h"
1799 +static inline void *cow_malloc(int size)
1801 + return(um_kmalloc(size));
1804 +static inline void cow_free(void *ptr)
1809 +#define cow_printf printk
1811 +static inline char *cow_strdup(char *str)
1813 + return(uml_strdup(str));
1816 +static inline int cow_seek_file(int fd, __u64 offset)
1818 + return(os_seek_file(fd, offset));
1821 +static inline int cow_file_size(char *file, __u64 *size_out)
1823 + return(os_file_size(file, size_out));
1826 +static inline int cow_write_file(int fd, char *buf, int size)
1828 + return(os_write_file(fd, buf, size));
1834 + * ---------------------------------------------------------------------------
1835 + * Local variables:
1836 + * c-file-style: "linux"
1839 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow_user.c um/arch/um/drivers/cow_user.c
1840 --- orig/arch/um/drivers/cow_user.c 1969-12-31 19:00:00.000000000 -0500
1841 +++ um/arch/um/drivers/cow_user.c 2003-06-05 14:39:18.000000000 -0400
1843 +#include <stddef.h>
1844 +#include <string.h>
1846 +#include <unistd.h>
1847 +#include <byteswap.h>
1848 +#include <sys/stat.h>
1849 +#include <sys/time.h>
1850 +#include <sys/param.h>
1851 +#include <netinet/in.h>
1854 +#include "cow_sys.h"
1856 +#define PATH_LEN_V1 256
1858 +struct cow_header_v1 {
1861 + char backing_file[PATH_LEN_V1];
1867 +#define PATH_LEN_V2 MAXPATHLEN
1869 +struct cow_header_v2 {
1870 + unsigned long magic;
1871 + unsigned long version;
1872 + char backing_file[PATH_LEN_V2];
1879 + struct cow_header_v1 v1;
1880 + struct cow_header_v2 v2;
1883 +#define COW_MAGIC 0x4f4f4f4d /* MOOO */
1884 +#define COW_VERSION 2
1886 +void cow_sizes(__u64 size, int sectorsize, int bitmap_offset,
1887 + unsigned long *bitmap_len_out, int *data_offset_out)
1889 + *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
1891 + *data_offset_out = bitmap_offset + *bitmap_len_out;
1892 + *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
1893 + *data_offset_out *= sectorsize;
1896 +static int absolutize(char *to, int size, char *from)
1898 + char save_cwd[256], *slash;
1901 + if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
1902 + cow_printf("absolutize : unable to get cwd - errno = %d\n",
1906 + slash = strrchr(from, '/');
1907 + if(slash != NULL){
1911 + cow_printf("absolutize : Can't cd to '%s' - "
1912 + "errno = %d\n", from, errno);
1916 + if(getcwd(to, size) == NULL){
1917 + cow_printf("absolutize : unable to get cwd of '%s' - "
1918 + "errno = %d\n", from, errno);
1921 + remaining = size - strlen(to);
1922 + if(strlen(slash) + 1 > remaining){
1923 + cow_printf("absolutize : unable to fit '%s' into %d "
1924 + "chars\n", from, size);
1927 + strcat(to, slash);
1930 + if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
1931 + cow_printf("absolutize : unable to fit '%s' into %d "
1932 + "chars\n", from, size);
1935 + strcpy(to, save_cwd);
1943 +int write_cow_header(char *cow_file, int fd, char *backing_file,
1944 + int sectorsize, long long *size)
1946 + struct cow_header_v2 *header;
1947 + struct stat64 buf;
1950 + err = cow_seek_file(fd, 0);
1952 + cow_printf("write_cow_header - lseek failed, errno = %d\n",
1958 + header = cow_malloc(sizeof(*header));
1959 + if(header == NULL){
1960 + cow_printf("Failed to allocate COW V2 header\n");
1963 + header->magic = htonl(COW_MAGIC);
1964 + header->version = htonl(COW_VERSION);
1967 + if(strlen(backing_file) > sizeof(header->backing_file) - 1){
1968 + cow_printf("Backing file name \"%s\" is too long - names are "
1969 + "limited to %d characters\n", backing_file,
1970 + sizeof(header->backing_file) - 1);
1974 + if(absolutize(header->backing_file, sizeof(header->backing_file),
1978 + err = stat64(header->backing_file, &buf);
1980 + cow_printf("Stat of backing file '%s' failed, errno = %d\n",
1981 + header->backing_file, errno);
1986 + err = cow_file_size(header->backing_file, size);
1988 + cow_printf("Couldn't get size of backing file '%s', "
1989 + "errno = %d\n", header->backing_file, -*size);
1993 + header->mtime = htonl(buf.st_mtime);
1994 + header->size = htonll(*size);
1995 + header->sectorsize = htonl(sectorsize);
1997 + err = write(fd, header, sizeof(*header));
1998 + if(err != sizeof(*header)){
1999 + cow_printf("Write of header to new COW file '%s' failed, "
2000 + "errno = %d\n", cow_file, errno);
2010 +int read_cow_header(int fd, __u32 *magic_out, char **backing_file_out,
2011 + time_t *mtime_out, __u64 *size_out,
2012 + int *sectorsize_out, int *bitmap_offset_out)
2014 + union cow_header *header;
2017 + unsigned long version, magic;
2019 + header = cow_malloc(sizeof(*header));
2020 + if(header == NULL){
2021 + cow_printf("read_cow_header - Failed to allocate header\n");
2025 + n = read(fd, header, sizeof(*header));
2026 + if(n < offsetof(typeof(header->v1), backing_file)){
2027 + cow_printf("read_cow_header - short header\n");
2031 + magic = header->v1.magic;
2032 + if(magic == COW_MAGIC) {
2033 + version = header->v1.version;
2035 + else if(magic == ntohl(COW_MAGIC)){
2036 + version = ntohl(header->v1.version);
2040 + *magic_out = COW_MAGIC;
2043 + if(n < sizeof(header->v1)){
2044 + cow_printf("read_cow_header - failed to read V1 "
2048 + *mtime_out = header->v1.mtime;
2049 + *size_out = header->v1.size;
2050 + *sectorsize_out = header->v1.sectorsize;
2051 + *bitmap_offset_out = sizeof(header->v1);
2052 + file = header->v1.backing_file;
2054 + else if(version == 2){
2055 + if(n < sizeof(header->v2)){
2056 + cow_printf("read_cow_header - failed to read V2 "
2060 + *mtime_out = ntohl(header->v2.mtime);
2061 + *size_out = ntohll(header->v2.size);
2062 + *sectorsize_out = ntohl(header->v2.sectorsize);
2063 + *bitmap_offset_out = sizeof(header->v2);
2064 + file = header->v2.backing_file;
2067 + cow_printf("read_cow_header - invalid COW version\n");
2071 + *backing_file_out = cow_strdup(file);
2072 + if(*backing_file_out == NULL){
2073 + cow_printf("read_cow_header - failed to allocate backing "
2083 +int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
2084 + int *bitmap_offset_out, unsigned long *bitmap_len_out,
2085 + int *data_offset_out)
2087 + __u64 size, offset;
2091 + err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
2095 + cow_sizes(size, sectorsize, sizeof(struct cow_header_v2),
2096 + bitmap_len_out, data_offset_out);
2097 + *bitmap_offset_out = sizeof(struct cow_header_v2);
2099 + offset = *data_offset_out + size - sizeof(zero);
2100 + err = cow_seek_file(fd, offset);
2102 + cow_printf("cow bitmap lseek failed : errno = %d\n", errno);
2106 + /* does not really matter how much we write it is just to set EOF
2107 + * this also sets the entire COW bitmap
2108 + * to zero without having to allocate it
2110 + err = cow_write_file(fd, &zero, sizeof(zero));
2111 + if(err != sizeof(zero)){
2113 + cow_printf("Write of bitmap to new COW file '%s' failed, "
2114 + "errno = %d\n", cow_file, errno);
2125 + * ---------------------------------------------------------------------------
2126 + * Local variables:
2127 + * c-file-style: "linux"
2130 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon.h um/arch/um/drivers/daemon.h
2131 --- orig/arch/um/drivers/daemon.h 1969-12-31 19:00:00.000000000 -0500
2132 +++ um/arch/um/drivers/daemon.h 2002-10-23 21:08:04.000000000 -0400
2135 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
2136 + * Licensed under the GPL
2139 +#include "net_user.h"
2141 +#define SWITCH_VERSION 3
2143 +struct daemon_data {
2154 +extern struct net_user_info daemon_user_info;
2156 +extern int daemon_user_write(int fd, void *buf, int len,
2157 + struct daemon_data *pri);
2160 + * Overrides for Emacs so that we follow Linus's tabbing style.
2161 + * Emacs will notice this stuff at the end of the file and automatically
2162 + * adjust the settings for this buffer only. This must remain at the end
2164 + * ---------------------------------------------------------------------------
2165 + * Local variables:
2166 + * c-file-style: "linux"
2169 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon_kern.c um/arch/um/drivers/daemon_kern.c
2170 --- orig/arch/um/drivers/daemon_kern.c 1969-12-31 19:00:00.000000000 -0500
2171 +++ um/arch/um/drivers/daemon_kern.c 2002-12-15 21:19:17.000000000 -0500
2174 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
2175 + * James Leu (jleu@mindspring.net).
2176 + * Copyright (C) 2001 by various other people who didn't put their name here.
2177 + * Licensed under the GPL.
2180 +#include "linux/kernel.h"
2181 +#include "linux/init.h"
2182 +#include "linux/netdevice.h"
2183 +#include "linux/etherdevice.h"
2184 +#include "net_kern.h"
2185 +#include "net_user.h"
2186 +#include "daemon.h"
2188 +struct daemon_init {
2193 +void daemon_init(struct net_device *dev, void *data)
2195 + struct uml_net_private *pri;
2196 + struct daemon_data *dpri;
2197 + struct daemon_init *init = data;
2199 + init_etherdev(dev, 0);
2201 + dpri = (struct daemon_data *) pri->user;
2202 + *dpri = ((struct daemon_data)
2203 + { .sock_type = init->sock_type,
2204 + .ctl_sock = init->ctl_sock,
2206 + .data_addr = NULL,
2207 + .local_addr = NULL,
2212 + printk("daemon backend (uml_switch version %d) - %s:%s",
2213 + SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
2217 +static int daemon_read(int fd, struct sk_buff **skb,
2218 + struct uml_net_private *lp)
2220 + *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
2221 + if(*skb == NULL) return(-ENOMEM);
2222 + return(net_recvfrom(fd, (*skb)->mac.raw,
2223 + (*skb)->dev->mtu + ETH_HEADER_OTHER));
2226 +static int daemon_write(int fd, struct sk_buff **skb,
2227 + struct uml_net_private *lp)
2229 + return(daemon_user_write(fd, (*skb)->data, (*skb)->len,
2230 + (struct daemon_data *) &lp->user));
2233 +static struct net_kern_info daemon_kern_info = {
2234 + .init = daemon_init,
2235 + .protocol = eth_protocol,
2236 + .read = daemon_read,
2237 + .write = daemon_write,
2240 +int daemon_setup(char *str, char **mac_out, void *data)
2242 + struct daemon_init *init = data;
2245 + *init = ((struct daemon_init)
2246 + { .sock_type = "unix",
2247 + .ctl_sock = "/tmp/uml.ctl" });
2249 + remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
2251 + if(remain != NULL)
2252 + printk(KERN_WARNING "daemon_setup : Ignoring data socket "
2253 + "specification\n");
2258 +static struct transport daemon_transport = {
2259 + .list = LIST_HEAD_INIT(daemon_transport.list),
2261 + .setup = daemon_setup,
2262 + .user = &daemon_user_info,
2263 + .kern = &daemon_kern_info,
2264 + .private_size = sizeof(struct daemon_data),
2265 + .setup_size = sizeof(struct daemon_init),
2268 +static int register_daemon(void)
2270 + register_transport(&daemon_transport);
2274 +__initcall(register_daemon);
2277 + * Overrides for Emacs so that we follow Linus's tabbing style.
2278 + * Emacs will notice this stuff at the end of the file and automatically
2279 + * adjust the settings for this buffer only. This must remain at the end
2281 + * ---------------------------------------------------------------------------
2282 + * Local variables:
2283 + * c-file-style: "linux"
2286 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon_user.c um/arch/um/drivers/daemon_user.c
2287 --- orig/arch/um/drivers/daemon_user.c 1969-12-31 19:00:00.000000000 -0500
2288 +++ um/arch/um/drivers/daemon_user.c 2003-01-17 13:48:59.000000000 -0500
2291 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
2292 + * James Leu (jleu@mindspring.net).
2293 + * Copyright (C) 2001 by various other people who didn't put their name here.
2294 + * Licensed under the GPL.
2298 +#include <unistd.h>
2299 +#include <stdint.h>
2300 +#include <sys/socket.h>
2301 +#include <sys/un.h>
2302 +#include <sys/time.h>
2303 +#include "net_user.h"
2304 +#include "daemon.h"
2305 +#include "kern_util.h"
2306 +#include "user_util.h"
2310 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
2312 +enum request_type { REQ_NEW_CONTROL };
2314 +#define SWITCH_MAGIC 0xfeedface
2316 +struct request_v3 {
2319 + enum request_type type;
2320 + struct sockaddr_un sock;
2323 +static struct sockaddr_un *new_addr(void *name, int len)
2325 + struct sockaddr_un *sun;
2327 + sun = um_kmalloc(sizeof(struct sockaddr_un));
2329 + printk("new_addr: allocation of sockaddr_un failed\n");
2332 + sun->sun_family = AF_UNIX;
2333 + memcpy(sun->sun_path, name, len);
2337 +static int connect_to_switch(struct daemon_data *pri)
2339 + struct sockaddr_un *ctl_addr = pri->ctl_addr;
2340 + struct sockaddr_un *local_addr = pri->local_addr;
2341 + struct sockaddr_un *sun;
2342 + struct request_v3 req;
2345 + if((pri->control = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
2346 + printk("daemon_open : control socket failed, errno = %d\n",
2351 + if(connect(pri->control, (struct sockaddr *) ctl_addr,
2352 + sizeof(*ctl_addr)) < 0){
2353 + printk("daemon_open : control connect failed, errno = %d\n",
2359 + if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0){
2360 + printk("daemon_open : data socket failed, errno = %d\n",
2365 + if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){
2366 + printk("daemon_open : data bind failed, errno = %d\n",
2372 + sun = um_kmalloc(sizeof(struct sockaddr_un));
2374 + printk("new_addr: allocation of sockaddr_un failed\n");
2379 + req.magic = SWITCH_MAGIC;
2380 + req.version = SWITCH_VERSION;
2381 + req.type = REQ_NEW_CONTROL;
2382 + req.sock = *local_addr;
2383 + n = write(pri->control, &req, sizeof(req));
2384 + if(n != sizeof(req)){
2385 + printk("daemon_open : control setup request returned %d, "
2386 + "errno = %d\n", n, errno);
2391 + n = read(pri->control, sun, sizeof(*sun));
2392 + if(n != sizeof(*sun)){
2393 + printk("daemon_open : read of data socket returned %d, "
2394 + "errno = %d\n", n, errno);
2399 + pri->data_addr = sun;
2405 + close(pri->control);
2409 +static void daemon_user_init(void *data, void *dev)
2411 + struct daemon_data *pri = data;
2412 + struct timeval tv;
2419 + if(!strcmp(pri->sock_type, "unix"))
2420 + pri->ctl_addr = new_addr(pri->ctl_sock,
2421 + strlen(pri->ctl_sock) + 1);
2423 + name.pid = os_getpid();
2424 + gettimeofday(&tv, NULL);
2425 + name.usecs = tv.tv_usec;
2426 + pri->local_addr = new_addr(&name, sizeof(name));
2428 + pri->fd = connect_to_switch(pri);
2430 + kfree(pri->local_addr);
2431 + pri->local_addr = NULL;
2435 +static int daemon_open(void *data)
2437 + struct daemon_data *pri = data;
2441 +static void daemon_remove(void *data)
2443 + struct daemon_data *pri = data;
2446 + close(pri->control);
2447 + if(pri->data_addr != NULL) kfree(pri->data_addr);
2448 + if(pri->ctl_addr != NULL) kfree(pri->ctl_addr);
2449 + if(pri->local_addr != NULL) kfree(pri->local_addr);
2452 +int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
2454 + struct sockaddr_un *data_addr = pri->data_addr;
2456 + return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
2459 +static int daemon_set_mtu(int mtu, void *data)
2464 +struct net_user_info daemon_user_info = {
2465 + .init = daemon_user_init,
2466 + .open = daemon_open,
2468 + .remove = daemon_remove,
2469 + .set_mtu = daemon_set_mtu,
2470 + .add_address = NULL,
2471 + .delete_address = NULL,
2472 + .max_packet = MAX_PACKET - ETH_HEADER_OTHER
2476 + * Overrides for Emacs so that we follow Linus's tabbing style.
2477 + * Emacs will notice this stuff at the end of the file and automatically
2478 + * adjust the settings for this buffer only. This must remain at the end
2480 + * ---------------------------------------------------------------------------
2481 + * Local variables:
2482 + * c-file-style: "linux"
2485 diff -Naur -X ../exclude-files orig/arch/um/drivers/fd.c um/arch/um/drivers/fd.c
2486 --- orig/arch/um/drivers/fd.c 1969-12-31 19:00:00.000000000 -0500
2487 +++ um/arch/um/drivers/fd.c 2002-12-15 20:57:25.000000000 -0500
2490 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
2491 + * Licensed under the GPL
2495 +#include <stdlib.h>
2496 +#include <unistd.h>
2497 +#include <termios.h>
2499 +#include "user_util.h"
2500 +#include "chan_user.h"
2505 + struct termios tt;
2506 + char str[sizeof("1234567890\0")];
2509 +void *fd_init(char *str, int device, struct chan_opts *opts)
2511 + struct fd_chan *data;
2516 + printk("fd_init : channel type 'fd' must specify a file "
2521 + n = strtoul(str, &end, 0);
2522 + if((*end != '\0') || (end == str)){
2523 + printk("fd_init : couldn't parse file descriptor '%s'\n", str);
2526 + if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
2527 + *data = ((struct fd_chan) { .fd = n,
2528 + .raw = opts->raw });
2532 +int fd_open(int input, int output, int primary, void *d, char **dev_out)
2534 + struct fd_chan *data = d;
2536 + if(data->raw && isatty(data->fd)){
2537 + tcgetattr(data->fd, &data->tt);
2540 + sprintf(data->str, "%d", data->fd);
2541 + *dev_out = data->str;
2545 +void fd_close(int fd, void *d)
2547 + struct fd_chan *data = d;
2549 + if(data->raw && isatty(fd)){
2550 + tcsetattr(fd, TCSAFLUSH, &data->tt);
2555 +int fd_console_write(int fd, const char *buf, int n, void *d)
2557 + struct fd_chan *data = d;
2559 + return(generic_console_write(fd, buf, n, &data->tt));
2562 +struct chan_ops fd_ops = {
2566 + .close = fd_close,
2567 + .read = generic_read,
2568 + .write = generic_write,
2569 + .console_write = fd_console_write,
2570 + .window_size = generic_window_size,
2571 + .free = generic_free,
2576 + * Overrides for Emacs so that we follow Linus's tabbing style.
2577 + * Emacs will notice this stuff at the end of the file and automatically
2578 + * adjust the settings for this buffer only. This must remain at the end
2580 + * ---------------------------------------------------------------------------
2581 + * Local variables:
2582 + * c-file-style: "linux"
2585 diff -Naur -X ../exclude-files orig/arch/um/drivers/harddog_kern.c um/arch/um/drivers/harddog_kern.c
2586 --- orig/arch/um/drivers/harddog_kern.c 1969-12-31 19:00:00.000000000 -0500
2587 +++ um/arch/um/drivers/harddog_kern.c 2002-12-15 20:57:42.000000000 -0500
2589 +/* UML hardware watchdog, shamelessly stolen from:
2591 + * SoftDog 0.05: A Software Watchdog Device
2593 + * (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
2594 + * http://www.redhat.com
2596 + * This program is free software; you can redistribute it and/or
2597 + * modify it under the terms of the GNU General Public License
2598 + * as published by the Free Software Foundation; either version
2599 + * 2 of the License, or (at your option) any later version.
2601 + * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
2602 + * warranty for any of this software. This material is provided
2603 + * "AS-IS" and at no charge.
2605 + * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
2607 + * Software only watchdog driver. Unlike its big brother the WDT501P
2608 + * driver this won't always recover a failed machine.
2610 + * 03/96: Angelo Haritsis <ah@doc.ic.ac.uk> :
2612 + * Added soft_margin; use upon insmod to change the timer delay.
2613 + * NB: uses same minor as wdt (WATCHDOG_MINOR); we could use separate
2616 + * 19980911 Alan Cox
2617 + * Made SMP safe for 2.3.x
2619 + * 20011127 Joel Becker (jlbec@evilplan.org>
2620 + * Added soft_noboot; Allows testing the softdog trigger without
2621 + * requiring a recompile.
2622 + * Added WDIOC_GETTIMEOUT and WDIOC_SETTIMOUT.
2625 +#include <linux/module.h>
2626 +#include <linux/config.h>
2627 +#include <linux/types.h>
2628 +#include <linux/kernel.h>
2629 +#include <linux/fs.h>
2630 +#include <linux/mm.h>
2631 +#include <linux/miscdevice.h>
2632 +#include <linux/watchdog.h>
2633 +#include <linux/reboot.h>
2634 +#include <linux/smp_lock.h>
2635 +#include <linux/init.h>
2636 +#include <asm/uaccess.h>
2637 +#include "helper.h"
2638 +#include "mconsole.h"
2640 +MODULE_LICENSE("GPL");
2642 +/* Locked by the BKL in harddog_open and harddog_release */
2643 +static int timer_alive;
2644 +static int harddog_in_fd = -1;
2645 +static int harddog_out_fd = -1;
2648 + * Allow only one person to hold it open
2651 +extern int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock);
2653 +static int harddog_open(struct inode *inode, struct file *file)
2656 + char *sock = NULL;
2661 +#ifdef CONFIG_HARDDOG_NOWAYOUT
2662 + MOD_INC_USE_COUNT;
2665 +#ifdef CONFIG_MCONSOLE
2666 + sock = mconsole_notify_socket();
2668 + err = start_watchdog(&harddog_in_fd, &harddog_out_fd, sock);
2669 + if(err) return(err);
2676 +extern void stop_watchdog(int in_fd, int out_fd);
2678 +static int harddog_release(struct inode *inode, struct file *file)
2681 + * Shut off the timer.
2685 + stop_watchdog(harddog_in_fd, harddog_out_fd);
2686 + harddog_in_fd = -1;
2687 + harddog_out_fd = -1;
2694 +extern int ping_watchdog(int fd);
2696 +static ssize_t harddog_write(struct file *file, const char *data, size_t len,
2699 + /* Can't seek (pwrite) on this device */
2700 + if (ppos != &file->f_pos)
2704 + * Refresh the timer.
2707 + return(ping_watchdog(harddog_out_fd));
2711 +static int harddog_ioctl(struct inode *inode, struct file *file,
2712 + unsigned int cmd, unsigned long arg)
2714 + static struct watchdog_info ident = {
2717 + "UML Hardware Watchdog"
2722 + case WDIOC_GETSUPPORT:
2723 + if(copy_to_user((struct harddog_info *)arg, &ident,
2727 + case WDIOC_GETSTATUS:
2728 + case WDIOC_GETBOOTSTATUS:
2729 + return put_user(0,(int *)arg);
2730 + case WDIOC_KEEPALIVE:
2731 + return(ping_watchdog(harddog_out_fd));
2735 +static struct file_operations harddog_fops = {
2736 + .owner = THIS_MODULE,
2737 + .write = harddog_write,
2738 + .ioctl = harddog_ioctl,
2739 + .open = harddog_open,
2740 + .release = harddog_release,
2743 +static struct miscdevice harddog_miscdev = {
2744 + .minor = WATCHDOG_MINOR,
2745 + .name = "watchdog",
2746 + .fops = &harddog_fops,
2749 +static char banner[] __initdata = KERN_INFO "UML Watchdog Timer\n";
2751 +static int __init harddog_init(void)
2755 + ret = misc_register(&harddog_miscdev);
2765 +static void __exit harddog_exit(void)
2767 + misc_deregister(&harddog_miscdev);
2770 +module_init(harddog_init);
2771 +module_exit(harddog_exit);
2774 + * Overrides for Emacs so that we follow Linus's tabbing style.
2775 + * Emacs will notice this stuff at the end of the file and automatically
2776 + * adjust the settings for this buffer only. This must remain at the end
2778 + * ---------------------------------------------------------------------------
2779 + * Local variables:
2780 + * c-file-style: "linux"
2783 diff -Naur -X ../exclude-files orig/arch/um/drivers/harddog_user.c um/arch/um/drivers/harddog_user.c
2784 --- orig/arch/um/drivers/harddog_user.c 1969-12-31 19:00:00.000000000 -0500
2785 +++ um/arch/um/drivers/harddog_user.c 2002-12-04 16:38:05.000000000 -0500
2788 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2789 + * Licensed under the GPL
2793 +#include <unistd.h>
2795 +#include "user_util.h"
2797 +#include "helper.h"
2798 +#include "mconsole.h"
2800 +#include "choose-mode.h"
2809 +static void pre_exec(void *d)
2811 + struct dog_data *data = d;
2813 + dup2(data->stdin, 0);
2814 + dup2(data->stdout, 1);
2815 + dup2(data->stdout, 2);
2816 + close(data->stdin);
2817 + close(data->stdout);
2818 + close(data->close_me[0]);
2819 + close(data->close_me[1]);
2822 +int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
2824 + struct dog_data data;
2825 + int in_fds[2], out_fds[2], pid, n, err;
2826 + char pid_buf[sizeof("nnnnn\0")], c;
2827 + char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL };
2828 + char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL,
2830 + char **args = NULL;
2832 + err = os_pipe(in_fds, 1, 0);
2834 + printk("harddog_open - os_pipe failed, errno = %d\n", -err);
2838 + err = os_pipe(out_fds, 1, 0);
2840 + printk("harddog_open - os_pipe failed, errno = %d\n", -err);
2844 + data.stdin = out_fds[0];
2845 + data.stdout = in_fds[1];
2846 + data.close_me[0] = out_fds[1];
2847 + data.close_me[1] = in_fds[0];
2850 + mconsole_args[2] = sock;
2851 + args = mconsole_args;
2854 + /* XXX The os_getpid() is not SMP correct */
2855 + sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid()));
2859 + pid = run_helper(pre_exec, &data, args, NULL);
2861 + close(out_fds[0]);
2866 + printk("harddog_open - run_helper failed, errno = %d\n", err);
2870 + n = read(in_fds[0], &c, sizeof(c));
2872 + printk("harddog_open - EOF on watchdog pipe\n");
2878 + printk("harddog_open - read of watchdog pipe failed, "
2879 + "errno = %d\n", errno);
2884 + *in_fd_ret = in_fds[0];
2885 + *out_fd_ret = out_fds[1];
2888 + close(out_fds[1]);
2893 +void stop_watchdog(int in_fd, int out_fd)
2899 +int ping_watchdog(int fd)
2904 + n = write(fd, &c, sizeof(c));
2905 + if(n < sizeof(c)){
2906 + printk("ping_watchdog - write failed, errno = %d\n",
2915 + * Overrides for Emacs so that we follow Linus's tabbing style.
2916 + * Emacs will notice this stuff at the end of the file and automatically
2917 + * adjust the settings for this buffer only. This must remain at the end
2919 + * ---------------------------------------------------------------------------
2920 + * Local variables:
2921 + * c-file-style: "linux"
2924 diff -Naur -X ../exclude-files orig/arch/um/drivers/hostaudio_kern.c um/arch/um/drivers/hostaudio_kern.c
2925 --- orig/arch/um/drivers/hostaudio_kern.c 1969-12-31 19:00:00.000000000 -0500
2926 +++ um/arch/um/drivers/hostaudio_kern.c 2003-03-28 21:57:16.000000000 -0500
2929 + * Copyright (C) 2002 Steve Schmidtke
2930 + * Licensed under the GPL
2933 +#include "linux/config.h"
2934 +#include "linux/module.h"
2935 +#include "linux/version.h"
2936 +#include "linux/init.h"
2937 +#include "linux/slab.h"
2938 +#include "linux/fs.h"
2939 +#include "linux/sound.h"
2940 +#include "linux/soundcard.h"
2941 +#include "asm/uaccess.h"
2942 +#include "kern_util.h"
2944 +#include "hostaudio.h"
2946 +/* Only changed from linux_main at boot time */
2947 +char *dsp = HOSTAUDIO_DEV_DSP;
2948 +char *mixer = HOSTAUDIO_DEV_MIXER;
2951 +static int set_dsp(char *name, int *add)
2957 +__uml_setup("dsp=", set_dsp,
2958 +"dsp=<dsp device>\n"
2959 +" This is used to specify the host dsp device to the hostaudio driver.\n"
2960 +" The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
2963 +static int set_mixer(char *name, int *add)
2969 +__uml_setup("mixer=", set_mixer,
2970 +"mixer=<mixer device>\n"
2971 +" This is used to specify the host mixer device to the hostaudio driver.\n"
2972 +" The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
2976 +/* /dev/dsp file operations */
2978 +static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count,
2981 + struct hostaudio_state *state = file->private_data;
2986 + printk("hostaudio: read called, count = %d\n", count);
2989 + kbuf = kmalloc(count, GFP_KERNEL);
2993 + err = hostaudio_read_user(state, kbuf, count, ppos);
2997 + if(copy_to_user(buffer, kbuf, err))
3005 +static ssize_t hostaudio_write(struct file *file, const char *buffer,
3006 + size_t count, loff_t *ppos)
3008 + struct hostaudio_state *state = file->private_data;
3013 + printk("hostaudio: write called, count = %d\n", count);
3016 + kbuf = kmalloc(count, GFP_KERNEL);
3021 + if(copy_from_user(kbuf, buffer, count))
3024 + err = hostaudio_write_user(state, kbuf, count, ppos);
3033 +static unsigned int hostaudio_poll(struct file *file,
3034 + struct poll_table_struct *wait)
3036 + unsigned int mask = 0;
3039 + printk("hostaudio: poll called (unimplemented)\n");
3045 +static int hostaudio_ioctl(struct inode *inode, struct file *file,
3046 + unsigned int cmd, unsigned long arg)
3048 + struct hostaudio_state *state = file->private_data;
3049 + unsigned long data = 0;
3053 + printk("hostaudio: ioctl called, cmd = %u\n", cmd);
3056 + case SNDCTL_DSP_SPEED:
3057 + case SNDCTL_DSP_STEREO:
3058 + case SNDCTL_DSP_GETBLKSIZE:
3059 + case SNDCTL_DSP_CHANNELS:
3060 + case SNDCTL_DSP_SUBDIVIDE:
3061 + case SNDCTL_DSP_SETFRAGMENT:
3062 + if(get_user(data, (int *) arg))
3069 + err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
3072 + case SNDCTL_DSP_SPEED:
3073 + case SNDCTL_DSP_STEREO:
3074 + case SNDCTL_DSP_GETBLKSIZE:
3075 + case SNDCTL_DSP_CHANNELS:
3076 + case SNDCTL_DSP_SUBDIVIDE:
3077 + case SNDCTL_DSP_SETFRAGMENT:
3078 + if(put_user(data, (int *) arg))
3088 +static int hostaudio_open(struct inode *inode, struct file *file)
3090 + struct hostaudio_state *state;
3095 + printk("hostaudio: open called (host: %s)\n", dsp);
3098 + state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
3099 + if(state == NULL) return(-ENOMEM);
3101 + if(file->f_mode & FMODE_READ) r = 1;
3102 + if(file->f_mode & FMODE_WRITE) w = 1;
3104 + ret = hostaudio_open_user(state, r, w, dsp);
3110 + file->private_data = state;
3114 +static int hostaudio_release(struct inode *inode, struct file *file)
3116 + struct hostaudio_state *state = file->private_data;
3120 + printk("hostaudio: release called\n");
3123 + ret = hostaudio_release_user(state);
3129 +/* /dev/mixer file operations */
3131 +static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file,
3132 + unsigned int cmd, unsigned long arg)
3134 + struct hostmixer_state *state = file->private_data;
3137 + printk("hostmixer: ioctl called\n");
3140 + return(hostmixer_ioctl_mixdev_user(state, cmd, arg));
3143 +static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
3145 + struct hostmixer_state *state;
3150 + printk("hostmixer: open called (host: %s)\n", mixer);
3153 + state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL);
3154 + if(state == NULL) return(-ENOMEM);
3156 + if(file->f_mode & FMODE_READ) r = 1;
3157 + if(file->f_mode & FMODE_WRITE) w = 1;
3159 + ret = hostmixer_open_mixdev_user(state, r, w, mixer);
3166 + file->private_data = state;
3170 +static int hostmixer_release(struct inode *inode, struct file *file)
3172 + struct hostmixer_state *state = file->private_data;
3176 + printk("hostmixer: release called\n");
3179 + ret = hostmixer_release_mixdev_user(state);
3186 +/* kernel module operations */
3188 +static struct file_operations hostaudio_fops = {
3189 + .owner = THIS_MODULE,
3190 + .llseek = no_llseek,
3191 + .read = hostaudio_read,
3192 + .write = hostaudio_write,
3193 + .poll = hostaudio_poll,
3194 + .ioctl = hostaudio_ioctl,
3196 + .open = hostaudio_open,
3197 + .release = hostaudio_release,
3200 +static struct file_operations hostmixer_fops = {
3201 + .owner = THIS_MODULE,
3202 + .llseek = no_llseek,
3203 + .ioctl = hostmixer_ioctl_mixdev,
3204 + .open = hostmixer_open_mixdev,
3205 + .release = hostmixer_release,
3213 +MODULE_AUTHOR("Steve Schmidtke");
3214 +MODULE_DESCRIPTION("UML Audio Relay");
3215 +MODULE_LICENSE("GPL");
3217 +static int __init hostaudio_init_module(void)
3219 + printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
3222 + module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
3223 + if(module_data.dev_audio < 0){
3224 + printk(KERN_ERR "hostaudio: couldn't register DSP device!\n");
3228 + module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1);
3229 + if(module_data.dev_mixer < 0){
3230 + printk(KERN_ERR "hostmixer: couldn't register mixer "
3232 + unregister_sound_dsp(module_data.dev_audio);
3239 +static void __exit hostaudio_cleanup_module (void)
3241 + unregister_sound_mixer(module_data.dev_mixer);
3242 + unregister_sound_dsp(module_data.dev_audio);
3245 +module_init(hostaudio_init_module);
3246 +module_exit(hostaudio_cleanup_module);
3249 + * Overrides for Emacs so that we follow Linus's tabbing style.
3250 + * Emacs will notice this stuff at the end of the file and automatically
3251 + * adjust the settings for this buffer only. This must remain at the end
3253 + * ---------------------------------------------------------------------------
3254 + * Local variables:
3255 + * c-file-style: "linux"
3258 diff -Naur -X ../exclude-files orig/arch/um/drivers/hostaudio_user.c um/arch/um/drivers/hostaudio_user.c
3259 --- orig/arch/um/drivers/hostaudio_user.c 1969-12-31 19:00:00.000000000 -0500
3260 +++ um/arch/um/drivers/hostaudio_user.c 2002-10-23 21:08:04.000000000 -0400
3263 + * Copyright (C) 2002 Steve Schmidtke
3264 + * Licensed under the GPL
3267 +#include <sys/types.h>
3268 +#include <sys/stat.h>
3269 +#include <sys/ioctl.h>
3271 +#include <unistd.h>
3273 +#include "hostaudio.h"
3274 +#include "user_util.h"
3275 +#include "kern_util.h"
3279 +/* /dev/dsp file operations */
3281 +ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer,
3282 + size_t count, loff_t *ppos)
3287 + printk("hostaudio: read_user called, count = %d\n", count);
3290 + ret = read(state->fd, buffer, count);
3292 + if(ret < 0) return(-errno);
3296 +ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer,
3297 + size_t count, loff_t *ppos)
3302 + printk("hostaudio: write_user called, count = %d\n", count);
3305 + ret = write(state->fd, buffer, count);
3307 + if(ret < 0) return(-errno);
3311 +int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd,
3312 + unsigned long arg)
3316 + printk("hostaudio: ioctl_user called, cmd = %u\n", cmd);
3319 + ret = ioctl(state->fd, cmd, arg);
3321 + if(ret < 0) return(-errno);
3325 +int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp)
3328 + printk("hostaudio: open_user called\n");
3331 + state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
3333 + if(state->fd >= 0) return(0);
3335 + printk("hostaudio_open_user failed to open '%s', errno = %d\n",
3341 +int hostaudio_release_user(struct hostaudio_state *state)
3344 + printk("hostaudio: release called\n");
3346 + if(state->fd >= 0){
3354 +/* /dev/mixer file operations */
3356 +int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state,
3357 + unsigned int cmd, unsigned long arg)
3361 + printk("hostmixer: ioctl_user called cmd = %u\n",cmd);
3364 + ret = ioctl(state->fd, cmd, arg);
3370 +int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w,
3374 + printk("hostmixer: open_user called\n");
3377 + state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
3379 + if(state->fd >= 0) return(0);
3381 + printk("hostaudio_open_mixdev_user failed to open '%s', errno = %d\n",
3387 +int hostmixer_release_mixdev_user(struct hostmixer_state *state)
3390 + printk("hostmixer: release_user called\n");
3393 + if(state->fd >= 0){
3402 + * Overrides for Emacs so that we follow Linus's tabbing style.
3403 + * Emacs will notice this stuff at the end of the file and automatically
3404 + * adjust the settings for this buffer only. This must remain at the end
3406 + * ---------------------------------------------------------------------------
3407 + * Local variables:
3408 + * c-file-style: "linux"
3411 diff -Naur -X ../exclude-files orig/arch/um/drivers/line.c um/arch/um/drivers/line.c
3412 --- orig/arch/um/drivers/line.c 1969-12-31 19:00:00.000000000 -0500
3413 +++ um/arch/um/drivers/line.c 2003-03-26 15:09:44.000000000 -0500
3416 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3417 + * Licensed under the GPL
3420 +#include "linux/sched.h"
3421 +#include "linux/slab.h"
3422 +#include "linux/list.h"
3423 +#include "linux/devfs_fs_kernel.h"
3424 +#include "asm/irq.h"
3425 +#include "asm/uaccess.h"
3426 +#include "chan_kern.h"
3427 +#include "irq_user.h"
3430 +#include "user_util.h"
3431 +#include "kern_util.h"
3434 +#define LINE_BUFSIZE 4096
3436 +void line_interrupt(int irq, void *data, struct pt_regs *unused)
3438 + struct line *dev = data;
3440 + if(dev->count > 0)
3441 + chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq,
3445 +void line_timer_cb(void *arg)
3447 + struct line *dev = arg;
3449 + line_interrupt(dev->driver->read_irq, dev, NULL);
3452 +static void buffer_data(struct line *line, const char *buf, int len)
3456 + if(line->buffer == NULL){
3457 + line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
3458 + if(line->buffer == NULL){
3459 + printk("buffer_data - atomic allocation failed\n");
3462 + line->head = line->buffer;
3463 + line->tail = line->buffer;
3465 + end = line->buffer + LINE_BUFSIZE - line->tail;
3467 + memcpy(line->tail, buf, len);
3468 + line->tail += len;
3471 + memcpy(line->tail, buf, end);
3474 + memcpy(line->buffer, buf, len);
3475 + line->tail = line->buffer + len;
3479 +static int flush_buffer(struct line *line)
3483 + if((line->buffer == NULL) || (line->head == line->tail)) return(1);
3485 + if(line->tail < line->head){
3486 + count = line->buffer + LINE_BUFSIZE - line->head;
3487 + n = write_chan(&line->chan_list, line->head, count,
3488 + line->driver->write_irq);
3489 + if(n < 0) return(n);
3490 + if(n == count) line->head = line->buffer;
3497 + count = line->tail - line->head;
3498 + n = write_chan(&line->chan_list, line->head, count,
3499 + line->driver->write_irq);
3500 + if(n < 0) return(n);
3503 + return(line->head == line->tail);
3506 +int line_write(struct line *lines, struct tty_struct *tty, int from_user,
3507 + const char *buf, int len)
3509 + struct line *line;
3511 + unsigned long flags;
3514 + if(tty->stopped) return 0;
3517 + new = kmalloc(len, GFP_KERNEL);
3520 + n = copy_from_user(new, buf, len);
3526 + i = minor(tty->device) - tty->driver.minor_start;
3530 + if(line->head != line->tail){
3531 + local_irq_save(flags);
3532 + buffer_data(line, buf, len);
3533 + err = flush_buffer(line);
3534 + local_irq_restore(flags);
3539 + n = write_chan(&line->chan_list, buf, len,
3540 + line->driver->write_irq);
3546 + buffer_data(line, buf + n, len - n);
3556 +void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
3558 + struct line *dev = data;
3559 + struct tty_struct *tty = dev->tty;
3562 + err = flush_buffer(dev);
3563 + if(err == 0) return;
3565 + dev->head = dev->buffer;
3566 + dev->tail = dev->buffer;
3569 + if(tty == NULL) return;
3571 + if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
3572 + (tty->ldisc.write_wakeup != NULL))
3573 + (tty->ldisc.write_wakeup)(tty);
3576 + * In blocking mode, everything sleeps on tty->write_wait.
3577 + * Sleeping in the console driver would break non-blocking
3581 + if (waitqueue_active(&tty->write_wait))
3582 + wake_up_interruptible(&tty->write_wait);
3586 +int line_write_room(struct tty_struct *tty)
3588 + struct line *dev = tty->driver_data;
3591 + if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
3593 + n = dev->head - dev->tail;
3594 + if(n <= 0) n = LINE_BUFSIZE + n;
3598 +int line_setup_irq(int fd, int input, int output, void *data)
3600 + struct line *line = data;
3601 + struct line_driver *driver = line->driver;
3602 + int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
3604 + if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ,
3605 + line_interrupt, flags,
3606 + driver->read_irq_name, line);
3607 + if(err) return(err);
3608 + if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
3609 + line_write_interrupt, flags,
3610 + driver->write_irq_name, line);
3611 + line->have_irq = 1;
3615 +void line_disable(struct line *line, int current_irq)
3617 + if(!line->have_irq) return;
3619 + if(line->driver->read_irq == current_irq)
3620 + free_irq_later(line->driver->read_irq, line);
3622 + free_irq(line->driver->read_irq, line);
3624 + if(line->driver->write_irq == current_irq)
3625 + free_irq_later(line->driver->write_irq, line);
3627 + free_irq(line->driver->write_irq, line);
3629 + line->have_irq = 0;
3632 +int line_open(struct line *lines, struct tty_struct *tty,
3633 + struct chan_opts *opts)
3635 + struct line *line;
3638 + if(tty == NULL) n = 0;
3639 + else n = minor(tty->device) - tty->driver.minor_start;
3643 + if(line->count == 0){
3648 + if(list_empty(&line->chan_list)){
3649 + err = parse_chan_pair(line->init_str, &line->chan_list,
3650 + line->init_pri, n, opts);
3652 + err = open_chan(&line->chan_list);
3655 + enable_chan(&line->chan_list, line);
3656 + INIT_TQUEUE(&line->task, line_timer_cb, line);
3660 + chan_enable_winch(&line->chan_list, line);
3664 + /* This is outside the if because the initial console is opened
3665 + * with tty == NULL
3670 + tty->driver_data = line;
3671 + chan_window_size(&line->chan_list, &tty->winsize.ws_row,
3672 + &tty->winsize.ws_col);
3681 +void line_close(struct line *lines, struct tty_struct *tty)
3683 + struct line *line;
3686 + if(tty == NULL) n = 0;
3687 + else n = minor(tty->device) - tty->driver.minor_start;
3693 + /* I don't like this, but I can't think of anything better. What's
3694 + * going on is that the tty is in the process of being closed for
3695 + * the last time. Its count hasn't been dropped yet, so it's still
3696 + * at 1. This may happen when line->count != 0 because of the initial
3697 + * console open (without a tty) bumping it up to 1.
3699 + if((line->tty != NULL) && (line->tty->count == 1))
3701 + if(line->count == 0)
3702 + line_disable(line, -1);
3706 +void close_lines(struct line *lines, int nlines)
3710 + for(i = 0; i < nlines; i++)
3711 + close_chan(&lines[i].chan_list);
3714 +int line_setup(struct line *lines, int num, char *init, int all_allowed)
3719 + if(*init == '=') n = -1;
3721 + n = simple_strtoul(init, &end, 0);
3723 + printk(KERN_ERR "line_setup failed to parse \"%s\"\n",
3730 + if((n >= 0) && (n >= num)){
3731 + printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
3736 + if(lines[n].count > 0){
3737 + printk("line_setup - device %d is open\n", n);
3740 + if(lines[n].init_pri <= INIT_ONE){
3741 + lines[n].init_pri = INIT_ONE;
3742 + if(!strcmp(init, "none")) lines[n].valid = 0;
3744 + lines[n].init_str = init;
3745 + lines[n].valid = 1;
3749 + else if(!all_allowed){
3750 + printk("line_setup - can't configure all devices from "
3755 + for(i = 0; i < num; i++){
3756 + if(lines[i].init_pri <= INIT_ALL){
3757 + lines[i].init_pri = INIT_ALL;
3758 + if(!strcmp(init, "none")) lines[i].valid = 0;
3760 + lines[i].init_str = init;
3761 + lines[i].valid = 1;
3769 +int line_config(struct line *lines, int num, char *str)
3771 + char *new = uml_strdup(str);
3774 + printk("line_config - uml_strdup failed\n");
3777 + return(line_setup(lines, num, new, 0));
3780 +int line_get_config(char *name, struct line *lines, int num, char *str,
3781 + int size, char **error_out)
3783 + struct line *line;
3787 + dev = simple_strtoul(name, &end, 0);
3788 + if((*end != '\0') || (end == name)){
3789 + *error_out = "line_get_config failed to parse device number";
3793 + if((dev < 0) || (dev >= num)){
3794 + *error_out = "device number of of range";
3798 + line = &lines[dev];
3802 + CONFIG_CHUNK(str, size, n, "none", 1);
3803 + else if(line->count == 0)
3804 + CONFIG_CHUNK(str, size, n, line->init_str, 1);
3805 + else n = chan_config_string(&line->chan_list, str, size, error_out);
3811 +int line_remove(struct line *lines, int num, char *str)
3813 + char config[sizeof("conxxxx=none\0")];
3815 + sprintf(config, "%s=none", str);
3816 + return(line_setup(lines, num, config, 0));
3819 +void line_register_devfs(struct lines *set, struct line_driver *line_driver,
3820 + struct tty_driver *driver, struct line *lines,
3826 + driver->driver_name = line_driver->name;
3827 + driver->name = line_driver->devfs_name;
3828 + driver->major = line_driver->major;
3829 + driver->minor_start = line_driver->minor_start;
3830 + driver->type = line_driver->type;
3831 + driver->subtype = line_driver->subtype;
3832 + driver->magic = TTY_DRIVER_MAGIC;
3833 + driver->flags = TTY_DRIVER_REAL_RAW;
3837 + driver->table = kmalloc(n * sizeof(driver->table[0]), GFP_KERNEL);
3838 + driver->termios = kmalloc(n * sizeof(driver->termios[0]), GFP_KERNEL);
3839 + driver->termios_locked = kmalloc(n * sizeof(driver->termios_locked[0]),
3841 + if((driver->table == NULL) || (driver->termios == NULL) ||
3842 + (driver->termios_locked == NULL))
3843 + panic("Failed to allocate driver table");
3845 + memset(driver->table, 0, n * sizeof(driver->table[0]));
3846 + memset(driver->termios, 0, n * sizeof(driver->termios[0]));
3847 + memset(driver->termios_locked, 0,
3848 + n * sizeof(driver->termios_locked[0]));
3850 + driver->write_room = line_write_room;
3851 + driver->init_termios = tty_std_termios;
3853 + if (tty_register_driver(driver))
3854 + panic("line_register_devfs : Couldn't register driver\n");
3856 + from = line_driver->symlink_from;
3857 + to = line_driver->symlink_to;
3858 + err = devfs_mk_symlink(NULL, from, 0, to, NULL, NULL);
3859 + if(err) printk("Symlink creation from /dev/%s to /dev/%s "
3860 + "returned %d\n", from, to, err);
3862 + for(i = 0; i < nlines; i++){
3863 + if(!lines[i].valid)
3864 + tty_unregister_devfs(driver, driver->minor_start + i);
3867 + mconsole_register_dev(&line_driver->mc);
3870 +void lines_init(struct line *lines, int nlines)
3872 + struct line *line;
3875 + for(i = 0; i < nlines; i++){
3877 + INIT_LIST_HEAD(&line->chan_list);
3878 + sema_init(&line->sem, 1);
3879 + if(line->init_str != NULL){
3880 + line->init_str = uml_strdup(line->init_str);
3881 + if(line->init_str == NULL)
3882 + printk("lines_init - uml_strdup returned "
3889 + struct list_head list;
3893 + struct line *line;
3896 +void winch_interrupt(int irq, void *data, struct pt_regs *unused)
3898 + struct winch *winch = data;
3899 + struct tty_struct *tty;
3903 + if(winch->fd != -1){
3904 + err = generic_read(winch->fd, &c, NULL);
3906 + if(err != -EAGAIN){
3907 + printk("winch_interrupt : read failed, "
3908 + "errno = %d\n", -err);
3909 + printk("fd %d is losing SIGWINCH support\n",
3916 + tty = winch->line->tty;
3918 + chan_window_size(&winch->line->chan_list,
3919 + &tty->winsize.ws_row,
3920 + &tty->winsize.ws_col);
3921 + kill_pg(tty->pgrp, SIGWINCH, 1);
3924 + if(winch->fd != -1)
3925 + reactivate_fd(winch->fd, WINCH_IRQ);
3928 +DECLARE_MUTEX(winch_handler_sem);
3929 +LIST_HEAD(winch_handlers);
3931 +void register_winch_irq(int fd, int tty_fd, int pid, void *line)
3933 + struct winch *winch;
3935 + down(&winch_handler_sem);
3936 + winch = kmalloc(sizeof(*winch), GFP_KERNEL);
3937 + if(winch == NULL){
3938 + printk("register_winch_irq - kmalloc failed\n");
3941 + *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list),
3946 + list_add(&winch->list, &winch_handlers);
3947 + if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
3948 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
3949 + "winch", winch) < 0)
3950 + printk("register_winch_irq - failed to register IRQ\n");
3952 + up(&winch_handler_sem);
3955 +static void winch_cleanup(void)
3957 + struct list_head *ele;
3958 + struct winch *winch;
3960 + list_for_each(ele, &winch_handlers){
3961 + winch = list_entry(ele, struct winch, list);
3962 + if(winch->fd != -1){
3963 + deactivate_fd(winch->fd, WINCH_IRQ);
3966 + if(winch->pid != -1)
3967 + os_kill_process(winch->pid, 1);
3971 +__uml_exitcall(winch_cleanup);
3973 +char *add_xterm_umid(char *base)
3975 + char *umid, *title;
3978 + umid = get_umid(1);
3979 + if(umid == NULL) return(base);
3981 + len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
3982 + title = kmalloc(len, GFP_KERNEL);
3983 + if(title == NULL){
3984 + printk("Failed to allocate buffer for xterm title\n");
3988 + strncpy(title, base, len);
3989 + len -= strlen(title);
3990 + snprintf(&title[strlen(title)], len, " (%s)", umid);
3995 + * Overrides for Emacs so that we follow Linus's tabbing style.
3996 + * Emacs will notice this stuff at the end of the file and automatically
3997 + * adjust the settings for this buffer only. This must remain at the end
3999 + * ---------------------------------------------------------------------------
4000 + * Local variables:
4001 + * c-file-style: "linux"
4004 diff -Naur -X ../exclude-files orig/arch/um/drivers/Makefile um/arch/um/drivers/Makefile
4005 --- orig/arch/um/drivers/Makefile 1969-12-31 19:00:00.000000000 -0500
4006 +++ um/arch/um/drivers/Makefile 2003-06-05 13:48:51.000000000 -0400
4009 +# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
4010 +# Licensed under the GPL
4013 +O_TARGET := built-in.o
4015 +CHAN_OBJS := chan_kern.o chan_user.o line.o
4017 +list-multi := slip.o slirp.o daemon.o mcast.o mconsole.o net.o ubd.o \
4018 + hostaudio.o pcap.o port.o harddog.o
4020 +slip-objs := slip_kern.o slip_user.o
4021 +slirp-objs := slirp_kern.o slirp_user.o
4022 +daemon-objs := daemon_kern.o daemon_user.o
4023 +mcast-objs := mcast_kern.o mcast_user.o
4024 +pcap-objs := pcap_kern.o pcap_user.o -lpcap -L/usr/lib
4025 +net-objs := net_kern.o net_user.o
4026 +mconsole-objs := mconsole_kern.o mconsole_user.o
4027 +hostaudio-objs := hostaudio_kern.o hostaudio_user.o
4028 +ubd-objs := ubd_kern.o ubd_user.o cow_user.o
4029 +port-objs := port_kern.o port_user.o
4030 +harddog-objs := harddog_kern.o harddog_user.o
4032 +export-objs := mconsole_kern.o
4035 +obj-$(CONFIG_SSL) += ssl.o
4036 +obj-$(CONFIG_UML_NET_SLIP) += slip.o
4037 +obj-$(CONFIG_UML_NET_SLIRP) += slirp.o
4038 +obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
4039 +obj-$(CONFIG_UML_NET_MCAST) += mcast.o
4040 +obj-$(CONFIG_UML_NET_PCAP) += pcap.o
4041 +obj-$(CONFIG_UML_NET) += net.o
4042 +obj-$(CONFIG_MCONSOLE) += mconsole.o
4043 +obj-$(CONFIG_MMAPPER) += mmapper_kern.o
4044 +obj-$(CONFIG_BLK_DEV_UBD) += ubd.o
4045 +obj-$(CONFIG_HOSTAUDIO) += hostaudio.o
4046 +obj-$(CONFIG_FD_CHAN) += fd.o
4047 +obj-$(CONFIG_NULL_CHAN) += null.o
4048 +obj-$(CONFIG_PORT_CHAN) += port.o
4049 +obj-$(CONFIG_PTY_CHAN) += pty.o
4050 +obj-$(CONFIG_TTY_CHAN) += tty.o
4051 +obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
4052 +obj-$(CONFIG_UML_WATCHDOG) += harddog.o
4054 +CFLAGS_pcap_user.o = -I/usr/include/pcap
4056 +obj-y += stdio_console.o $(CHAN_OBJS)
4058 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
4060 +USER_OBJS = $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
4061 + null.o pty.o tty.o xterm.o
4063 +include $(TOPDIR)/Rules.make
4065 +$(USER_OBJS) : %.o: %.c
4066 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
4078 +daemon.o : $(daemon-objs)
4080 +slip.o : $(slip-objs)
4082 +slirp.o : $(slirp-objs)
4084 +mcast.o : $(mcast-objs)
4086 +pcap.o : $(pcap-objs)
4088 +mconsole.o : $(mconsole-objs)
4090 +net.o : $(net-objs)
4092 +hostaudio.o : $(hostaudio-objs)
4094 +ubd.o : $(ubd-objs)
4096 +port.o : $(port-objs)
4098 +harddog.o : $(harddog-objs)
4100 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
4101 + $(LD) $(LD_RFLAG) -r -o $@ $($(patsubst %.o,%,$@)-objs)
4102 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast.h um/arch/um/drivers/mcast.h
4103 --- orig/arch/um/drivers/mcast.h 1969-12-31 19:00:00.000000000 -0500
4104 +++ um/arch/um/drivers/mcast.h 2002-10-23 21:08:04.000000000 -0400
4107 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
4108 + * Licensed under the GPL
4111 +#include "net_user.h"
4113 +struct mcast_data {
4115 + unsigned short port;
4121 +extern struct net_user_info mcast_user_info;
4123 +extern int mcast_user_write(int fd, void *buf, int len,
4124 + struct mcast_data *pri);
4127 + * Overrides for Emacs so that we follow Linus's tabbing style.
4128 + * Emacs will notice this stuff at the end of the file and automatically
4129 + * adjust the settings for this buffer only. This must remain at the end
4131 + * ---------------------------------------------------------------------------
4132 + * Local variables:
4133 + * c-file-style: "linux"
4136 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_kern.c um/arch/um/drivers/mcast_kern.c
4137 --- orig/arch/um/drivers/mcast_kern.c 1969-12-31 19:00:00.000000000 -0500
4138 +++ um/arch/um/drivers/mcast_kern.c 2002-12-15 20:58:55.000000000 -0500
4141 + * user-mode-linux networking multicast transport
4142 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4144 + * based on the existing uml-networking code, which is
4145 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
4146 + * James Leu (jleu@mindspring.net).
4147 + * Copyright (C) 2001 by various other people who didn't put their name here.
4149 + * Licensed under the GPL.
4152 +#include "linux/kernel.h"
4153 +#include "linux/init.h"
4154 +#include "linux/netdevice.h"
4155 +#include "linux/etherdevice.h"
4156 +#include "linux/in.h"
4157 +#include "linux/inet.h"
4158 +#include "net_kern.h"
4159 +#include "net_user.h"
4162 +struct mcast_init {
4168 +void mcast_init(struct net_device *dev, void *data)
4170 + struct uml_net_private *pri;
4171 + struct mcast_data *dpri;
4172 + struct mcast_init *init = data;
4174 + init_etherdev(dev, 0);
4176 + dpri = (struct mcast_data *) pri->user;
4177 + *dpri = ((struct mcast_data)
4178 + { .addr = init->addr,
4179 + .port = init->port,
4181 + .mcast_addr = NULL,
4183 + printk("mcast backend ");
4184 + printk("multicast adddress: %s:%u, TTL:%u ",
4185 + dpri->addr, dpri->port, dpri->ttl);
4190 +static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
4192 + *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
4193 + if(*skb == NULL) return(-ENOMEM);
4194 + return(net_recvfrom(fd, (*skb)->mac.raw,
4195 + (*skb)->dev->mtu + ETH_HEADER_OTHER));
4198 +static int mcast_write(int fd, struct sk_buff **skb,
4199 + struct uml_net_private *lp)
4201 + return mcast_user_write(fd, (*skb)->data, (*skb)->len,
4202 + (struct mcast_data *) &lp->user);
4205 +static struct net_kern_info mcast_kern_info = {
4206 + .init = mcast_init,
4207 + .protocol = eth_protocol,
4208 + .read = mcast_read,
4209 + .write = mcast_write,
4212 +int mcast_setup(char *str, char **mac_out, void *data)
4214 + struct mcast_init *init = data;
4215 + char *port_str = NULL, *ttl_str = NULL, *remain;
4219 + *init = ((struct mcast_init)
4220 + { .addr = "239.192.168.1",
4224 + remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
4226 + if(remain != NULL){
4227 + printk(KERN_ERR "mcast_setup - Extra garbage on "
4228 + "specification : '%s'\n", remain);
4232 + if(port_str != NULL){
4233 + n = simple_strtoul(port_str, &last, 10);
4234 + if((*last != '\0') || (last == port_str)){
4235 + printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
4239 + init->port = htons(n);
4242 + if(ttl_str != NULL){
4243 + init->ttl = simple_strtoul(ttl_str, &last, 10);
4244 + if((*last != '\0') || (last == ttl_str)){
4245 + printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
4251 + printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
4252 + init->port, init->ttl);
4257 +static struct transport mcast_transport = {
4258 + .list = LIST_HEAD_INIT(mcast_transport.list),
4260 + .setup = mcast_setup,
4261 + .user = &mcast_user_info,
4262 + .kern = &mcast_kern_info,
4263 + .private_size = sizeof(struct mcast_data),
4264 + .setup_size = sizeof(struct mcast_init),
4267 +static int register_mcast(void)
4269 + register_transport(&mcast_transport);
4273 +__initcall(register_mcast);
4276 + * Overrides for Emacs so that we follow Linus's tabbing style.
4277 + * Emacs will notice this stuff at the end of the file and automatically
4278 + * adjust the settings for this buffer only. This must remain at the end
4280 + * ---------------------------------------------------------------------------
4281 + * Local variables:
4282 + * c-file-style: "linux"
4285 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_user.c um/arch/um/drivers/mcast_user.c
4286 --- orig/arch/um/drivers/mcast_user.c 1969-12-31 19:00:00.000000000 -0500
4287 +++ um/arch/um/drivers/mcast_user.c 2002-12-15 21:19:16.000000000 -0500
4290 + * user-mode-linux networking multicast transport
4291 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4293 + * based on the existing uml-networking code, which is
4294 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
4295 + * James Leu (jleu@mindspring.net).
4296 + * Copyright (C) 2001 by various other people who didn't put their name here.
4298 + * Licensed under the GPL.
4303 +#include <unistd.h>
4304 +#include <linux/inet.h>
4305 +#include <sys/socket.h>
4306 +#include <sys/un.h>
4307 +#include <sys/time.h>
4308 +#include <netinet/in.h>
4309 +#include "net_user.h"
4311 +#include "kern_util.h"
4312 +#include "user_util.h"
4315 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
4317 +static struct sockaddr_in *new_addr(char *addr, unsigned short port)
4319 + struct sockaddr_in *sin;
4321 + sin = um_kmalloc(sizeof(struct sockaddr_in));
4323 + printk("new_addr: allocation of sockaddr_in failed\n");
4326 + sin->sin_family = AF_INET;
4327 + sin->sin_addr.s_addr = in_aton(addr);
4328 + sin->sin_port = port;
4332 +static void mcast_user_init(void *data, void *dev)
4334 + struct mcast_data *pri = data;
4336 + pri->mcast_addr = new_addr(pri->addr, pri->port);
4340 +static int mcast_open(void *data)
4342 + struct mcast_data *pri = data;
4343 + struct sockaddr_in *sin = pri->mcast_addr;
4344 + struct ip_mreq mreq;
4348 + if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) {
4353 + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
4354 + printk("mcast_open : data socket failed, errno = %d\n",
4360 + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
4361 + printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
4368 + /* set ttl according to config */
4369 + if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
4370 + sizeof(pri->ttl)) < 0) {
4371 + printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
4378 + /* set LOOP, so data does get fed back to local sockets */
4379 + if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
4380 + printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
4387 + /* bind socket to mcast address */
4388 + if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
4389 + printk("mcast_open : data bind failed, errno = %d\n", errno);
4395 + /* subscribe to the multicast group */
4396 + mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
4397 + mreq.imr_interface.s_addr = 0;
4398 + if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
4399 + &mreq, sizeof(mreq)) < 0) {
4400 + printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n",
4402 + printk("There appears not to be a multicast-capable network "
4403 + "interface on the host.\n");
4404 + printk("eth0 should be configured in order to use the "
4405 + "multicast transport.\n");
4414 +static void mcast_close(int fd, void *data)
4416 + struct ip_mreq mreq;
4417 + struct mcast_data *pri = data;
4418 + struct sockaddr_in *sin = pri->mcast_addr;
4420 + mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
4421 + mreq.imr_interface.s_addr = 0;
4422 + if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
4423 + &mreq, sizeof(mreq)) < 0) {
4424 + printk("mcast_open: IP_DROP_MEMBERSHIP failed, error = %d\n",
4431 +int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
4433 + struct sockaddr_in *data_addr = pri->mcast_addr;
4435 + return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
4438 +static int mcast_set_mtu(int mtu, void *data)
4443 +struct net_user_info mcast_user_info = {
4444 + .init = mcast_user_init,
4445 + .open = mcast_open,
4446 + .close = mcast_close,
4448 + .set_mtu = mcast_set_mtu,
4449 + .add_address = NULL,
4450 + .delete_address = NULL,
4451 + .max_packet = MAX_PACKET - ETH_HEADER_OTHER
4455 + * Overrides for Emacs so that we follow Linus's tabbing style.
4456 + * Emacs will notice this stuff at the end of the file and automatically
4457 + * adjust the settings for this buffer only. This must remain at the end
4459 + * ---------------------------------------------------------------------------
4460 + * Local variables:
4461 + * c-file-style: "linux"
4464 diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_kern.c um/arch/um/drivers/mconsole_kern.c
4465 --- orig/arch/um/drivers/mconsole_kern.c 1969-12-31 19:00:00.000000000 -0500
4466 +++ um/arch/um/drivers/mconsole_kern.c 2003-03-28 21:58:11.000000000 -0500
4469 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
4470 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4471 + * Licensed under the GPL
4474 +#include "linux/kernel.h"
4475 +#include "linux/slab.h"
4476 +#include "linux/init.h"
4477 +#include "linux/notifier.h"
4478 +#include "linux/reboot.h"
4479 +#include "linux/utsname.h"
4480 +#include "linux/ctype.h"
4481 +#include "linux/interrupt.h"
4482 +#include "linux/sysrq.h"
4483 +#include "linux/tqueue.h"
4484 +#include "linux/module.h"
4485 +#include "linux/proc_fs.h"
4486 +#include "asm/irq.h"
4487 +#include "asm/uaccess.h"
4488 +#include "user_util.h"
4489 +#include "kern_util.h"
4491 +#include "mconsole.h"
4492 +#include "mconsole_kern.h"
4493 +#include "irq_user.h"
4498 +static int do_unlink_socket(struct notifier_block *notifier,
4499 + unsigned long what, void *data)
4501 + return(mconsole_unlink_socket());
4505 +static struct notifier_block reboot_notifier = {
4506 + .notifier_call = do_unlink_socket,
4510 +/* Safe without explicit locking for now. Tasklets provide their own
4511 + * locking, and the interrupt handler is safe because it can't interrupt
4512 + * itself and it can only happen on CPU 0.
4515 +LIST_HEAD(mc_requests);
4517 +void mc_task_proc(void *unused)
4519 + struct mconsole_entry *req;
4520 + unsigned long flags;
4524 + save_flags(flags);
4525 + req = list_entry(mc_requests.next, struct mconsole_entry,
4527 + list_del(&req->list);
4528 + done = list_empty(&mc_requests);
4529 + restore_flags(flags);
4530 + req->request.cmd->handler(&req->request);
4535 +struct tq_struct mconsole_task = {
4536 + .routine = mc_task_proc,
4540 +void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
4543 + struct mconsole_entry *new;
4544 + struct mc_request req;
4546 + fd = (int) dev_id;
4547 + while (mconsole_get_request(fd, &req)){
4548 + if(req.cmd->as_interrupt) (*req.cmd->handler)(&req);
4550 + new = kmalloc(sizeof(req), GFP_ATOMIC);
4552 + mconsole_reply(&req, "Out of memory", 1, 0);
4554 + new->request = req;
4555 + list_add(&new->list, &mc_requests);
4559 + if(!list_empty(&mc_requests)) schedule_task(&mconsole_task);
4560 + reactivate_fd(fd, MCONSOLE_IRQ);
4563 +void mconsole_version(struct mc_request *req)
4565 + char version[256];
4567 + sprintf(version, "%s %s %s %s %s", system_utsname.sysname,
4568 + system_utsname.nodename, system_utsname.release,
4569 + system_utsname.version, system_utsname.machine);
4570 + mconsole_reply(req, version, 0, 0);
4573 +#define UML_MCONSOLE_HELPTEXT \
4575 + version - Get kernel version \n\
4576 + help - Print this message \n\
4577 + halt - Halt UML \n\
4578 + reboot - Reboot UML \n\
4579 + config <dev>=<config> - Add a new device to UML; \n\
4580 + same syntax as command line \n\
4581 + config <dev> - Query the configuration of a device \n\
4582 + remove <dev> - Remove a device from UML \n\
4583 + sysrq <letter> - Performs the SysRq action controlled by the letter \n\
4584 + cad - invoke the Ctl-Alt-Del handler \n\
4585 + stop - pause the UML; it will do nothing until it receives a 'go' \n\
4586 + go - continue the UML after a 'stop' \n\
4589 +void mconsole_help(struct mc_request *req)
4591 + mconsole_reply(req, UML_MCONSOLE_HELPTEXT, 0, 0);
4594 +void mconsole_halt(struct mc_request *req)
4596 + mconsole_reply(req, "", 0, 0);
4600 +void mconsole_reboot(struct mc_request *req)
4602 + mconsole_reply(req, "", 0, 0);
4603 + machine_restart(NULL);
4606 +extern void ctrl_alt_del(void);
4608 +void mconsole_cad(struct mc_request *req)
4610 + mconsole_reply(req, "", 0, 0);
4614 +void mconsole_go(struct mc_request *req)
4616 + mconsole_reply(req, "Not stopped", 1, 0);
4619 +void mconsole_stop(struct mc_request *req)
4621 + deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
4622 + os_set_fd_block(req->originating_fd, 1);
4623 + mconsole_reply(req, "", 0, 0);
4624 + while(mconsole_get_request(req->originating_fd, req)){
4625 + if(req->cmd->handler == mconsole_go) break;
4626 + (*req->cmd->handler)(req);
4628 + os_set_fd_block(req->originating_fd, 0);
4629 + reactivate_fd(req->originating_fd, MCONSOLE_IRQ);
4630 + mconsole_reply(req, "", 0, 0);
4633 +/* This list is populated by __initcall routines. */
4635 +LIST_HEAD(mconsole_devices);
4637 +void mconsole_register_dev(struct mc_device *new)
4639 + list_add(&new->list, &mconsole_devices);
4642 +static struct mc_device *mconsole_find_dev(char *name)
4644 + struct list_head *ele;
4645 + struct mc_device *dev;
4647 + list_for_each(ele, &mconsole_devices){
4648 + dev = list_entry(ele, struct mc_device, list);
4649 + if(!strncmp(name, dev->name, strlen(dev->name)))
4655 +#define CONFIG_BUF_SIZE 64
4657 +static void mconsole_get_config(int (*get_config)(char *, char *, int,
4659 + struct mc_request *req, char *name)
4661 + char default_buf[CONFIG_BUF_SIZE], *error, *buf;
4664 + if(get_config == NULL){
4665 + mconsole_reply(req, "No get_config routine defined", 1, 0);
4670 + size = sizeof(default_buf)/sizeof(default_buf[0]);
4671 + buf = default_buf;
4674 + n = (*get_config)(name, buf, size, &error);
4675 + if(error != NULL){
4676 + mconsole_reply(req, error, 1, 0);
4681 + mconsole_reply(req, buf, 0, 0);
4685 + if(buf != default_buf)
4689 + buf = kmalloc(size, GFP_KERNEL);
4691 + mconsole_reply(req, "Failed to allocate buffer", 1, 0);
4696 + if(buf != default_buf)
4701 +void mconsole_config(struct mc_request *req)
4703 + struct mc_device *dev;
4704 + char *ptr = req->request.data, *name;
4707 + ptr += strlen("config");
4708 + while(isspace(*ptr)) ptr++;
4709 + dev = mconsole_find_dev(ptr);
4711 + mconsole_reply(req, "Bad configuration option", 1, 0);
4715 + name = &ptr[strlen(dev->name)];
4717 + while((*ptr != '=') && (*ptr != '\0'))
4721 + err = (*dev->config)(name);
4722 + mconsole_reply(req, "", err, 0);
4724 + else mconsole_get_config(dev->get_config, req, name);
4727 +void mconsole_remove(struct mc_request *req)
4729 + struct mc_device *dev;
4730 + char *ptr = req->request.data;
4733 + ptr += strlen("remove");
4734 + while(isspace(*ptr)) ptr++;
4735 + dev = mconsole_find_dev(ptr);
4737 + mconsole_reply(req, "Bad remove option", 1, 0);
4740 + err = (*dev->remove)(&ptr[strlen(dev->name)]);
4741 + mconsole_reply(req, "", err, 0);
4744 +#ifdef CONFIG_MAGIC_SYSRQ
4745 +void mconsole_sysrq(struct mc_request *req)
4747 + char *ptr = req->request.data;
4749 + ptr += strlen("sysrq");
4750 + while(isspace(*ptr)) ptr++;
4752 + handle_sysrq(*ptr, ¤t->thread.regs, NULL, NULL);
4753 + mconsole_reply(req, "", 0, 0);
4756 +void mconsole_sysrq(struct mc_request *req)
4758 + mconsole_reply(req, "Sysrq not compiled in", 1, 0);
4762 +/* Changed by mconsole_setup, which is __setup, and called before SMP is
4765 +static char *notify_socket = NULL;
4767 +int mconsole_init(void)
4772 + if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
4773 + snprintf(mconsole_socket_name, sizeof(file), "%s", file);
4775 + sock = create_unix_socket(file, sizeof(file));
4777 + printk("Failed to initialize management console\n");
4781 + register_reboot_notifier(&reboot_notifier);
4783 + err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
4784 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
4785 + "mconsole", (void *)sock);
4787 + printk("Failed to get IRQ for management console\n");
4791 + if(notify_socket != NULL){
4792 + notify_socket = uml_strdup(notify_socket);
4793 + if(notify_socket != NULL)
4794 + mconsole_notify(notify_socket, MCONSOLE_SOCKET,
4795 + mconsole_socket_name,
4796 + strlen(mconsole_socket_name) + 1);
4797 + else printk(KERN_ERR "mconsole_setup failed to strdup "
4801 + printk("mconsole (version %d) initialized on %s\n",
4802 + MCONSOLE_VERSION, mconsole_socket_name);
4806 +__initcall(mconsole_init);
4808 +static int write_proc_mconsole(struct file *file, const char *buffer,
4809 + unsigned long count, void *data)
4813 + buf = kmalloc(count + 1, GFP_KERNEL);
4817 + if(copy_from_user(buf, buffer, count))
4819 + buf[count] = '\0';
4821 + mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
4825 +static int create_proc_mconsole(void)
4827 + struct proc_dir_entry *ent;
4829 + if(notify_socket == NULL) return(0);
4831 + ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
4833 + printk("create_proc_mconsole : create_proc_entry failed\n");
4837 + ent->read_proc = NULL;
4838 + ent->write_proc = write_proc_mconsole;
4842 +static spinlock_t notify_spinlock = SPIN_LOCK_UNLOCKED;
4844 +void lock_notify(void)
4846 + spin_lock(¬ify_spinlock);
4849 +void unlock_notify(void)
4851 + spin_unlock(¬ify_spinlock);
4854 +__initcall(create_proc_mconsole);
4856 +#define NOTIFY "=notify:"
4858 +static int mconsole_setup(char *str)
4860 + if(!strncmp(str, NOTIFY, strlen(NOTIFY))){
4861 + str += strlen(NOTIFY);
4862 + notify_socket = str;
4864 + else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str);
4868 +__setup("mconsole", mconsole_setup);
4870 +__uml_help(mconsole_setup,
4871 +"mconsole=notify:<socket>\n"
4872 +" Requests that the mconsole driver send a message to the named Unix\n"
4873 +" socket containing the name of the mconsole socket. This also serves\n"
4874 +" to notify outside processes when UML has booted far enough to respond\n"
4875 +" to mconsole requests.\n\n"
4878 +static int notify_panic(struct notifier_block *self, unsigned long unused1,
4881 + char *message = ptr;
4883 + if(notify_socket == NULL) return(0);
4885 + mconsole_notify(notify_socket, MCONSOLE_PANIC, message,
4886 + strlen(message) + 1);
4890 +static struct notifier_block panic_exit_notifier = {
4891 + .notifier_call = notify_panic,
4896 +static int add_notifier(void)
4898 + notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
4902 +__initcall(add_notifier);
4904 +char *mconsole_notify_socket(void)
4906 + return(notify_socket);
4909 +EXPORT_SYMBOL(mconsole_notify_socket);
4912 + * Overrides for Emacs so that we follow Linus's tabbing style.
4913 + * Emacs will notice this stuff at the end of the file and automatically
4914 + * adjust the settings for this buffer only. This must remain at the end
4916 + * ---------------------------------------------------------------------------
4917 + * Local variables:
4918 + * c-file-style: "linux"
4921 diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_user.c um/arch/um/drivers/mconsole_user.c
4922 --- orig/arch/um/drivers/mconsole_user.c 1969-12-31 19:00:00.000000000 -0500
4923 +++ um/arch/um/drivers/mconsole_user.c 2002-10-23 21:08:04.000000000 -0400
4926 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
4927 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4928 + * Licensed under the GPL
4932 +#include <stdlib.h>
4934 +#include <signal.h>
4935 +#include <sys/socket.h>
4936 +#include <sys/types.h>
4937 +#include <sys/uio.h>
4938 +#include <sys/un.h>
4939 +#include <unistd.h>
4941 +#include "mconsole.h"
4944 +static struct mconsole_command commands[] = {
4945 + { "version", mconsole_version, 1 },
4946 + { "halt", mconsole_halt, 0 },
4947 + { "reboot", mconsole_reboot, 0 },
4948 + { "config", mconsole_config, 0 },
4949 + { "remove", mconsole_remove, 0 },
4950 + { "sysrq", mconsole_sysrq, 1 },
4951 + { "help", mconsole_help, 1 },
4952 + { "cad", mconsole_cad, 1 },
4953 + { "stop", mconsole_stop, 0 },
4954 + { "go", mconsole_go, 1 },
4957 +/* Initialized in mconsole_init, which is an initcall */
4958 +char mconsole_socket_name[256];
4960 +int mconsole_reply_v0(struct mc_request *req, char *reply)
4963 + struct msghdr msg;
4965 + iov.iov_base = reply;
4966 + iov.iov_len = strlen(reply);
4968 + msg.msg_name = &(req->origin);
4969 + msg.msg_namelen = req->originlen;
4970 + msg.msg_iov = &iov;
4971 + msg.msg_iovlen = 1;
4972 + msg.msg_control = NULL;
4973 + msg.msg_controllen = 0;
4974 + msg.msg_flags = 0;
4976 + return sendmsg(req->originating_fd, &msg, 0);
4979 +static struct mconsole_command *mconsole_parse(struct mc_request *req)
4981 + struct mconsole_command *cmd;
4984 + for(i=0;i<sizeof(commands)/sizeof(commands[0]);i++){
4985 + cmd = &commands[i];
4986 + if(!strncmp(req->request.data, cmd->command,
4987 + strlen(cmd->command))){
4994 +#define MIN(a,b) ((a)<(b) ? (a):(b))
4996 +#define STRINGX(x) #x
4997 +#define STRING(x) STRINGX(x)
4999 +int mconsole_get_request(int fd, struct mc_request *req)
5003 + req->originlen = sizeof(req->origin);
5004 + req->len = recvfrom(fd, &req->request, sizeof(req->request), 0,
5005 + (struct sockaddr *) req->origin, &req->originlen);
5009 + req->originating_fd = fd;
5011 + if(req->request.magic != MCONSOLE_MAGIC){
5012 + /* Unversioned request */
5013 + len = MIN(sizeof(req->request.data) - 1,
5014 + strlen((char *) &req->request));
5015 + memmove(req->request.data, &req->request, len);
5016 + req->request.data[len] = '\0';
5018 + req->request.magic = MCONSOLE_MAGIC;
5019 + req->request.version = 0;
5020 + req->request.len = len;
5022 + mconsole_reply_v0(req, "ERR Version 0 mconsole clients are "
5023 + "not supported by this driver");
5027 + if(req->request.len >= MCONSOLE_MAX_DATA){
5028 + mconsole_reply(req, "Request too large", 1, 0);
5031 + if(req->request.version != MCONSOLE_VERSION){
5032 + mconsole_reply(req, "This driver only supports version "
5033 + STRING(MCONSOLE_VERSION) " clients", 1, 0);
5036 + req->request.data[req->request.len] = '\0';
5037 + req->cmd = mconsole_parse(req);
5038 + if(req->cmd == NULL){
5039 + mconsole_reply(req, "Unknown command", 1, 0);
5046 +int mconsole_reply(struct mc_request *req, char *str, int err, int more)
5048 + struct mconsole_reply reply;
5049 + int total, len, n;
5051 + total = strlen(str);
5055 + /* err can only be true on the first packet */
5058 + len = MIN(total, MCONSOLE_MAX_DATA - 1);
5060 + if(len == total) reply.more = more;
5061 + else reply.more = 1;
5063 + memcpy(reply.data, str, len);
5064 + reply.data[len] = '\0';
5066 + reply.len = len + 1;
5068 + len = sizeof(reply) + reply.len - sizeof(reply.data);
5070 + n = sendto(req->originating_fd, &reply, len, 0,
5071 + (struct sockaddr *) req->origin, req->originlen);
5073 + if(n < 0) return(-errno);
5074 + } while(total > 0);
5078 +int mconsole_unlink_socket(void)
5080 + unlink(mconsole_socket_name);
5084 +static int notify_sock = -1;
5086 +int mconsole_notify(char *sock_name, int type, const void *data, int len)
5088 + struct sockaddr_un target;
5089 + struct mconsole_notify packet;
5093 + if(notify_sock < 0){
5094 + notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0);
5095 + if(notify_sock < 0){
5096 + printk("mconsole_notify - socket failed, errno = %d\n",
5106 + target.sun_family = AF_UNIX;
5107 + strcpy(target.sun_path, sock_name);
5109 + packet.magic = MCONSOLE_MAGIC;
5110 + packet.version = MCONSOLE_VERSION;
5111 + packet.type = type;
5112 + len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len;
5114 + memcpy(packet.data, data, len);
5117 + len = sizeof(packet) + packet.len - sizeof(packet.data);
5118 + n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target,
5121 + printk("mconsole_notify - sendto failed, errno = %d\n", errno);
5128 + * Overrides for Emacs so that we follow Linus's tabbing style.
5129 + * Emacs will notice this stuff at the end of the file and automatically
5130 + * adjust the settings for this buffer only. This must remain at the end
5132 + * ---------------------------------------------------------------------------
5133 + * Local variables:
5134 + * c-file-style: "linux"
5137 diff -Naur -X ../exclude-files orig/arch/um/drivers/mmapper_kern.c um/arch/um/drivers/mmapper_kern.c
5138 --- orig/arch/um/drivers/mmapper_kern.c 1969-12-31 19:00:00.000000000 -0500
5139 +++ um/arch/um/drivers/mmapper_kern.c 2002-12-15 21:03:08.000000000 -0500
5142 + * arch/um/drivers/mmapper_kern.c
5144 + * BRIEF MODULE DESCRIPTION
5146 + * Copyright (C) 2000 RidgeRun, Inc.
5147 + * Author: RidgeRun, Inc.
5148 + * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
5151 +#include <linux/kdev_t.h>
5152 +#include <linux/time.h>
5153 +#include <linux/devfs_fs_kernel.h>
5154 +#include <linux/module.h>
5155 +#include <linux/mm.h>
5156 +#include <linux/slab.h>
5157 +#include <linux/init.h>
5158 +#include <asm/uaccess.h>
5159 +#include <asm/irq.h>
5160 +#include <asm/smplock.h>
5161 +#include <asm/pgtable.h>
5162 +#include "mem_user.h"
5163 +#include "user_util.h"
5165 +/* These are set in mmapper_init, which is called at boot time */
5166 +static unsigned long mmapper_size;
5167 +static unsigned long p_buf = 0;
5168 +static char *v_buf = NULL;
5171 +mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos)
5173 + if(*ppos > mmapper_size)
5176 + if(count + *ppos > mmapper_size)
5177 + count = count + *ppos - mmapper_size;
5182 + copy_to_user(buf,&v_buf[*ppos],count);
5188 +mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
5190 + if(*ppos > mmapper_size)
5193 + if(count + *ppos > mmapper_size)
5194 + count = count + *ppos - mmapper_size;
5199 + copy_from_user(&v_buf[*ppos],buf,count);
5205 +mmapper_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
5206 + unsigned long arg)
5208 + return(-ENOIOCTLCMD);
5212 +mmapper_mmap(struct file *file, struct vm_area_struct * vma)
5214 + int ret = -EINVAL;
5218 + if (vma->vm_pgoff != 0)
5221 + size = vma->vm_end - vma->vm_start;
5222 + if(size > mmapper_size) return(-EFAULT);
5224 + /* XXX A comment above remap_page_range says it should only be
5225 + * called when the mm semaphore is held
5227 + if (remap_page_range(vma->vm_start, p_buf, size, vma->vm_page_prot))
5236 +mmapper_open(struct inode *inode, struct file *file)
5242 +mmapper_release(struct inode *inode, struct file *file)
5247 +static struct file_operations mmapper_fops = {
5248 + .owner = THIS_MODULE,
5249 + .read = mmapper_read,
5250 + .write = mmapper_write,
5251 + .ioctl = mmapper_ioctl,
5252 + .mmap = mmapper_mmap,
5253 + .open = mmapper_open,
5254 + .release = mmapper_release,
5257 +static int __init mmapper_init(void)
5259 + printk(KERN_INFO "Mapper v0.1\n");
5261 + v_buf = (char *) find_iomem("mmapper", &mmapper_size);
5262 + if(mmapper_size == 0) return(0);
5264 + p_buf = __pa(v_buf);
5266 + devfs_register (NULL, "mmapper", DEVFS_FL_DEFAULT,
5267 + 30, 0, S_IFCHR | S_IRUGO | S_IWUGO,
5268 + &mmapper_fops, NULL);
5269 + devfs_mk_symlink(NULL, "mmapper0", DEVFS_FL_DEFAULT, "mmapper",
5274 +static void mmapper_exit(void)
5278 +module_init(mmapper_init);
5279 +module_exit(mmapper_exit);
5281 +MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>");
5282 +MODULE_DESCRIPTION("DSPLinux simulator mmapper driver");
5284 + * ---------------------------------------------------------------------------
5285 + * Local variables:
5286 + * c-file-style: "linux"
5289 diff -Naur -X ../exclude-files orig/arch/um/drivers/net_kern.c um/arch/um/drivers/net_kern.c
5290 --- orig/arch/um/drivers/net_kern.c 1969-12-31 19:00:00.000000000 -0500
5291 +++ um/arch/um/drivers/net_kern.c 2002-12-15 21:19:16.000000000 -0500
5294 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
5295 + * James Leu (jleu@mindspring.net).
5296 + * Copyright (C) 2001 by various other people who didn't put their name here.
5297 + * Licensed under the GPL.
5300 +#include "linux/config.h"
5301 +#include "linux/kernel.h"
5302 +#include "linux/netdevice.h"
5303 +#include "linux/rtnetlink.h"
5304 +#include "linux/skbuff.h"
5305 +#include "linux/socket.h"
5306 +#include "linux/spinlock.h"
5307 +#include "linux/module.h"
5308 +#include "linux/init.h"
5309 +#include "linux/etherdevice.h"
5310 +#include "linux/list.h"
5311 +#include "linux/inetdevice.h"
5312 +#include "linux/ctype.h"
5313 +#include "linux/bootmem.h"
5314 +#include "user_util.h"
5315 +#include "kern_util.h"
5316 +#include "net_kern.h"
5317 +#include "net_user.h"
5318 +#include "mconsole_kern.h"
5320 +#include "irq_user.h"
5322 +static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
5325 +static int uml_net_rx(struct net_device *dev)
5327 + struct uml_net_private *lp = dev->priv;
5329 + struct sk_buff *skb;
5331 + /* If we can't allocate memory, try again next round. */
5332 + if ((skb = dev_alloc_skb(dev->mtu)) == NULL) {
5333 + lp->stats.rx_dropped++;
5338 + skb_put(skb, dev->mtu);
5339 + skb->mac.raw = skb->data;
5340 + pkt_len = (*lp->read)(lp->fd, &skb, lp);
5342 + if (pkt_len > 0) {
5343 + skb_trim(skb, pkt_len);
5344 + skb->protocol = (*lp->protocol)(skb);
5347 + lp->stats.rx_bytes += skb->len;
5348 + lp->stats.rx_packets++;
5356 +void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
5358 + struct net_device *dev = dev_id;
5359 + struct uml_net_private *lp = dev->priv;
5362 + if(!netif_running(dev))
5365 + spin_lock(&lp->lock);
5366 + while((err = uml_net_rx(dev)) > 0) ;
5369 + "Device '%s' read returned %d, shutting it down\n",
5374 + reactivate_fd(lp->fd, UM_ETH_IRQ);
5377 + spin_unlock(&lp->lock);
5380 +static int uml_net_open(struct net_device *dev)
5382 + struct uml_net_private *lp = dev->priv;
5383 + char addr[sizeof("255.255.255.255\0")];
5386 + spin_lock(&lp->lock);
5393 + if(!lp->have_mac){
5394 + dev_ip_addr(dev, addr, &lp->mac[2]);
5395 + set_ether_mac(dev, lp->mac);
5398 + lp->fd = (*lp->open)(&lp->user);
5404 + err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
5405 + SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
5407 + printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
5408 + if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
5410 + err = -ENETUNREACH;
5413 + lp->tl.data = (unsigned long) &lp->user;
5414 + netif_start_queue(dev);
5416 + spin_lock(&opened_lock);
5417 + list_add(&lp->list, &opened);
5418 + spin_unlock(&opened_lock);
5419 + MOD_INC_USE_COUNT;
5421 + spin_unlock(&lp->lock);
5425 +static int uml_net_close(struct net_device *dev)
5427 + struct uml_net_private *lp = dev->priv;
5429 + netif_stop_queue(dev);
5430 + spin_lock(&lp->lock);
5432 + free_irq(dev->irq, dev);
5433 + if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
5435 + spin_lock(&opened_lock);
5436 + list_del(&lp->list);
5437 + spin_unlock(&opened_lock);
5439 + MOD_DEC_USE_COUNT;
5440 + spin_unlock(&lp->lock);
5444 +static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
5446 + struct uml_net_private *lp = dev->priv;
5447 + unsigned long flags;
5450 + netif_stop_queue(dev);
5452 + spin_lock_irqsave(&lp->lock, flags);
5454 + len = (*lp->write)(lp->fd, &skb, lp);
5456 + if(len == skb->len) {
5457 + lp->stats.tx_packets++;
5458 + lp->stats.tx_bytes += skb->len;
5459 + dev->trans_start = jiffies;
5460 + netif_start_queue(dev);
5462 + /* this is normally done in the interrupt when tx finishes */
5463 + netif_wake_queue(dev);
5465 + else if(len == 0){
5466 + netif_start_queue(dev);
5467 + lp->stats.tx_dropped++;
5470 + netif_start_queue(dev);
5471 + printk(KERN_ERR "uml_net_start_xmit: failed(%d)\n", len);
5474 + spin_unlock_irqrestore(&lp->lock, flags);
5476 + dev_kfree_skb(skb);
5481 +static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
5483 + struct uml_net_private *lp = dev->priv;
5484 + return &lp->stats;
5487 +static void uml_net_set_multicast_list(struct net_device *dev)
5489 + if (dev->flags & IFF_PROMISC) return;
5490 + else if (dev->mc_count) dev->flags |= IFF_ALLMULTI;
5491 + else dev->flags &= ~IFF_ALLMULTI;
5494 +static void uml_net_tx_timeout(struct net_device *dev)
5496 + dev->trans_start = jiffies;
5497 + netif_wake_queue(dev);
5500 +static int uml_net_set_mac(struct net_device *dev, void *addr)
5502 + struct uml_net_private *lp = dev->priv;
5503 + struct sockaddr *hwaddr = addr;
5505 + spin_lock(&lp->lock);
5506 + memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
5507 + spin_unlock(&lp->lock);
5512 +static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
5514 + struct uml_net_private *lp = dev->priv;
5517 + spin_lock(&lp->lock);
5519 + new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
5525 + dev->mtu = new_mtu;
5528 + spin_unlock(&lp->lock);
5532 +static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
5537 +void uml_net_user_timer_expire(unsigned long _conn)
5540 + struct connection *conn = (struct connection *)_conn;
5542 + dprintk(KERN_INFO "uml_net_user_timer_expire [%p]\n", conn);
5548 + * default do nothing hard header packet routines for struct net_device init.
5549 + * real ethernet transports will overwrite with real routines.
5551 +static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
5552 + unsigned short type, void *daddr, void *saddr, unsigned len)
5554 + return(0); /* no change */
5557 +static int uml_net_rebuild_header(struct sk_buff *skb)
5559 + return(0); /* ignore */
5562 +static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
5564 + return(-1); /* fail */
5567 +static void uml_net_header_cache_update(struct hh_cache *hh,
5568 + struct net_device *dev, unsigned char * haddr)
5573 +static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
5575 + return(0); /* nothing */
5578 +static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
5579 +static struct list_head devices = LIST_HEAD_INIT(devices);
5581 +static int eth_configure(int n, void *init, char *mac,
5582 + struct transport *transport)
5584 + struct uml_net *device;
5585 + struct net_device *dev;
5586 + struct uml_net_private *lp;
5587 + int save, err, size;
5589 + size = transport->private_size + sizeof(struct uml_net_private) +
5590 + sizeof(((struct uml_net_private *) 0)->user);
5592 + device = kmalloc(sizeof(*device), GFP_KERNEL);
5593 + if(device == NULL){
5594 + printk(KERN_ERR "eth_configure failed to allocate uml_net\n");
5598 + *device = ((struct uml_net) { .list = LIST_HEAD_INIT(device->list),
5601 + .mac = { [ 0 ... 5 ] = 0 },
5604 + spin_lock(&devices_lock);
5605 + list_add(&device->list, &devices);
5606 + spin_unlock(&devices_lock);
5608 + if(setup_etheraddr(mac, device->mac))
5609 + device->have_mac = 1;
5611 + printk(KERN_INFO "Netdevice %d ", n);
5612 + if(device->have_mac) printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
5613 + device->mac[0], device->mac[1],
5614 + device->mac[2], device->mac[3],
5615 + device->mac[4], device->mac[5]);
5617 + dev = kmalloc(sizeof(*dev) + size, GFP_KERNEL);
5619 + printk(KERN_ERR "eth_configure: failed to allocate device\n");
5622 + memset(dev, 0, sizeof(*dev) + size);
5624 + snprintf(dev->name, sizeof(dev->name), "eth%d", n);
5625 + dev->priv = (void *) &dev[1];
5626 + device->dev = dev;
5628 + dev->hard_header = uml_net_hard_header;
5629 + dev->rebuild_header = uml_net_rebuild_header;
5630 + dev->hard_header_cache = uml_net_header_cache;
5631 + dev->header_cache_update= uml_net_header_cache_update;
5632 + dev->hard_header_parse = uml_net_header_parse;
5634 + (*transport->kern->init)(dev, init);
5636 + dev->mtu = transport->user->max_packet;
5637 + dev->open = uml_net_open;
5638 + dev->hard_start_xmit = uml_net_start_xmit;
5639 + dev->stop = uml_net_close;
5640 + dev->get_stats = uml_net_get_stats;
5641 + dev->set_multicast_list = uml_net_set_multicast_list;
5642 + dev->tx_timeout = uml_net_tx_timeout;
5643 + dev->set_mac_address = uml_net_set_mac;
5644 + dev->change_mtu = uml_net_change_mtu;
5645 + dev->do_ioctl = uml_net_ioctl;
5646 + dev->watchdog_timeo = (HZ >> 1);
5647 + dev->irq = UM_ETH_IRQ;
5650 + err = register_netdevice(dev);
5656 + /* lp.user is the first four bytes of the transport data, which
5657 + * has already been initialized. This structure assignment will
5658 + * overwrite that, so we make sure that .user gets overwritten with
5659 + * what it already has.
5661 + save = lp->user[0];
5662 + *lp = ((struct uml_net_private)
5663 + { .list = LIST_HEAD_INIT(lp->list),
5664 + .lock = SPIN_LOCK_UNLOCKED,
5667 + .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
5668 + .have_mac = device->have_mac,
5669 + .protocol = transport->kern->protocol,
5670 + .open = transport->user->open,
5671 + .close = transport->user->close,
5672 + .remove = transport->user->remove,
5673 + .read = transport->kern->read,
5674 + .write = transport->kern->write,
5675 + .add_address = transport->user->add_address,
5676 + .delete_address = transport->user->delete_address,
5677 + .set_mtu = transport->user->set_mtu,
5678 + .user = { save } });
5679 + init_timer(&lp->tl);
5680 + lp->tl.function = uml_net_user_timer_expire;
5681 + memset(&lp->stats, 0, sizeof(lp->stats));
5682 + if(lp->have_mac) memcpy(lp->mac, device->mac, sizeof(lp->mac));
5684 + if(transport->user->init)
5685 + (*transport->user->init)(&lp->user, dev);
5687 + if(device->have_mac)
5688 + set_ether_mac(dev, device->mac);
5692 +static struct uml_net *find_device(int n)
5694 + struct uml_net *device;
5695 + struct list_head *ele;
5697 + spin_lock(&devices_lock);
5698 + list_for_each(ele, &devices){
5699 + device = list_entry(ele, struct uml_net, list);
5700 + if(device->index == n)
5705 + spin_unlock(&devices_lock);
5709 +static int eth_parse(char *str, int *index_out, char **str_out)
5714 + n = simple_strtoul(str, &end, 0);
5716 + printk(KERN_ERR "eth_setup: Failed to parse '%s'\n", str);
5720 + printk(KERN_ERR "eth_setup: device %d is negative\n", n);
5726 + "eth_setup: expected '=' after device number\n");
5730 + if(find_device(n)){
5731 + printk(KERN_ERR "eth_setup: Device %d already configured\n",
5735 + if(index_out) *index_out = n;
5741 + struct list_head list;
5746 +/* Filled in at boot time. Will need locking if the transports become
5749 +struct list_head transports = LIST_HEAD_INIT(transports);
5751 +/* Filled in during early boot */
5752 +struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
5754 +static int check_transport(struct transport *transport, char *eth, int n,
5755 + void **init_out, char **mac_out)
5759 + len = strlen(transport->name);
5760 + if(strncmp(eth, transport->name, len))
5766 + else if(*eth != '\0')
5769 + *init_out = kmalloc(transport->setup_size, GFP_KERNEL);
5770 + if(*init_out == NULL)
5773 + if(!transport->setup(eth, mac_out, *init_out)){
5780 +void register_transport(struct transport *new)
5782 + struct list_head *ele, *next;
5783 + struct eth_init *eth;
5788 + list_add(&new->list, &transports);
5790 + list_for_each_safe(ele, next, ð_cmd_line){
5791 + eth = list_entry(ele, struct eth_init, list);
5792 + match = check_transport(new, eth->init, eth->index, &init,
5796 + else if(init != NULL){
5797 + eth_configure(eth->index, init, mac, new);
5800 + list_del(ð->list);
5804 +static int eth_setup_common(char *str, int index)
5806 + struct list_head *ele;
5807 + struct transport *transport;
5811 + list_for_each(ele, &transports){
5812 + transport = list_entry(ele, struct transport, list);
5813 + if(!check_transport(transport, str, index, &init, &mac))
5816 + eth_configure(index, init, mac, transport);
5824 +static int eth_setup(char *str)
5826 + struct eth_init *new;
5829 + err = eth_parse(str, &n, &str);
5830 + if(err) return(1);
5832 + new = alloc_bootmem(sizeof(new));
5834 + printk("eth_init : alloc_bootmem failed\n");
5837 + *new = ((struct eth_init) { .list = LIST_HEAD_INIT(new->list),
5840 + list_add_tail(&new->list, ð_cmd_line);
5844 +__setup("eth", eth_setup);
5845 +__uml_help(eth_setup,
5846 +"eth[0-9]+=<transport>,<options>\n"
5847 +" Configure a network device.\n\n"
5850 +static int eth_init(void)
5852 + struct list_head *ele, *next;
5853 + struct eth_init *eth;
5855 + list_for_each_safe(ele, next, ð_cmd_line){
5856 + eth = list_entry(ele, struct eth_init, list);
5858 + if(eth_setup_common(eth->init, eth->index))
5859 + list_del(ð->list);
5865 +__initcall(eth_init);
5867 +static int net_config(char *str)
5871 + err = eth_parse(str, &n, &str);
5872 + if(err) return(err);
5874 + str = uml_strdup(str);
5876 + printk(KERN_ERR "net_config failed to strdup string\n");
5879 + err = !eth_setup_common(str, n);
5885 +static int net_remove(char *str)
5887 + struct uml_net *device;
5888 + struct net_device *dev;
5889 + struct uml_net_private *lp;
5893 + n = simple_strtoul(str, &end, 0);
5894 + if((*end != '\0') || (end == str))
5897 + device = find_device(n);
5898 + if(device == NULL)
5901 + dev = device->dev;
5903 + if(lp->fd > 0) return(-1);
5904 + if(lp->remove != NULL) (*lp->remove)(&lp->user);
5905 + unregister_netdev(dev);
5907 + list_del(&device->list);
5912 +static struct mc_device net_mc = {
5914 + .config = net_config,
5915 + .get_config = NULL,
5916 + .remove = net_remove,
5919 +static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
5922 + struct in_ifaddr *ifa = ptr;
5923 + u32 addr = ifa->ifa_address;
5924 + u32 netmask = ifa->ifa_mask;
5925 + struct net_device *dev = ifa->ifa_dev->dev;
5926 + struct uml_net_private *lp;
5927 + void (*proc)(unsigned char *, unsigned char *, void *);
5928 + unsigned char addr_buf[4], netmask_buf[4];
5930 + if(dev->open != uml_net_open) return(NOTIFY_DONE);
5937 + proc = lp->add_address;
5940 + proc = lp->delete_address;
5944 + addr_buf[0] = addr & 0xff;
5945 + addr_buf[1] = (addr >> 8) & 0xff;
5946 + addr_buf[2] = (addr >> 16) & 0xff;
5947 + addr_buf[3] = addr >> 24;
5948 + netmask_buf[0] = netmask & 0xff;
5949 + netmask_buf[1] = (netmask >> 8) & 0xff;
5950 + netmask_buf[2] = (netmask >> 16) & 0xff;
5951 + netmask_buf[3] = netmask >> 24;
5952 + (*proc)(addr_buf, netmask_buf, &lp->user);
5954 + return(NOTIFY_DONE);
5957 +struct notifier_block uml_inetaddr_notifier = {
5958 + .notifier_call = uml_inetaddr_event,
5961 +static int uml_net_init(void)
5963 + struct list_head *ele;
5964 + struct uml_net_private *lp;
5965 + struct in_device *ip;
5966 + struct in_ifaddr *in;
5968 + mconsole_register_dev(&net_mc);
5969 + register_inetaddr_notifier(¨_inetaddr_notifier);
5971 + /* Devices may have been opened already, so the uml_inetaddr_notifier
5972 + * didn't get a chance to run for them. This fakes it so that
5973 + * addresses which have already been set up get handled properly.
5975 + list_for_each(ele, &opened){
5976 + lp = list_entry(ele, struct uml_net_private, list);
5977 + ip = lp->dev->ip_ptr;
5978 + if(ip == NULL) continue;
5979 + in = ip->ifa_list;
5980 + while(in != NULL){
5981 + uml_inetaddr_event(NULL, NETDEV_UP, in);
5982 + in = in->ifa_next;
5989 +__initcall(uml_net_init);
5991 +static void close_devices(void)
5993 + struct list_head *ele;
5994 + struct uml_net_private *lp;
5996 + list_for_each(ele, &opened){
5997 + lp = list_entry(ele, struct uml_net_private, list);
5998 + if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
5999 + if(lp->remove != NULL) (*lp->remove)(&lp->user);
6003 +__uml_exitcall(close_devices);
6005 +int setup_etheraddr(char *str, unsigned char *addr)
6013 + addr[i] = simple_strtoul(str, &end, 16);
6014 + if((end == str) ||
6015 + ((*end != ':') && (*end != ',') && (*end != '\0'))){
6017 + "setup_etheraddr: failed to parse '%s' "
6018 + "as an ethernet address\n", str);
6025 + "Attempt to assign a broadcast ethernet address to a "
6026 + "device disallowed\n");
6032 +void dev_ip_addr(void *d, char *buf, char *bin_buf)
6034 + struct net_device *dev = d;
6035 + struct in_device *ip = dev->ip_ptr;
6036 + struct in_ifaddr *in;
6039 + if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
6040 + printk(KERN_WARNING "dev_ip_addr - device not assigned an "
6044 + addr = in->ifa_address;
6045 + sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff,
6046 + (addr >> 16) & 0xff, addr >> 24);
6048 + bin_buf[0] = addr & 0xff;
6049 + bin_buf[1] = (addr >> 8) & 0xff;
6050 + bin_buf[2] = (addr >> 16) & 0xff;
6051 + bin_buf[3] = addr >> 24;
6055 +void set_ether_mac(void *d, unsigned char *addr)
6057 + struct net_device *dev = d;
6059 + memcpy(dev->dev_addr, addr, ETH_ALEN);
6062 +struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
6064 + if((skb != NULL) && (skb_tailroom(skb) < extra)){
6065 + struct sk_buff *skb2;
6067 + skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
6068 + dev_kfree_skb(skb);
6071 + if(skb != NULL) skb_put(skb, extra);
6075 +void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
6079 + struct net_device *dev = d;
6080 + struct in_device *ip = dev->ip_ptr;
6081 + struct in_ifaddr *in;
6082 + unsigned char address[4], netmask[4];
6084 + if(ip == NULL) return;
6085 + in = ip->ifa_list;
6086 + while(in != NULL){
6087 + address[0] = in->ifa_address & 0xff;
6088 + address[1] = (in->ifa_address >> 8) & 0xff;
6089 + address[2] = (in->ifa_address >> 16) & 0xff;
6090 + address[3] = in->ifa_address >> 24;
6091 + netmask[0] = in->ifa_mask & 0xff;
6092 + netmask[1] = (in->ifa_mask >> 8) & 0xff;
6093 + netmask[2] = (in->ifa_mask >> 16) & 0xff;
6094 + netmask[3] = in->ifa_mask >> 24;
6095 + (*cb)(address, netmask, arg);
6096 + in = in->ifa_next;
6100 +int dev_netmask(void *d, void *m)
6102 + struct net_device *dev = d;
6103 + struct in_device *ip = dev->ip_ptr;
6104 + struct in_ifaddr *in;
6105 + __u32 *mask_out = m;
6110 + in = ip->ifa_list;
6114 + *mask_out = in->ifa_mask;
6118 +void *get_output_buffer(int *len_out)
6122 + ret = (void *) __get_free_pages(GFP_KERNEL, 0);
6123 + if(ret) *len_out = PAGE_SIZE;
6124 + else *len_out = 0;
6128 +void free_output_buffer(void *buffer)
6130 + free_pages((unsigned long) buffer, 0);
6133 +int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out,
6138 + remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL);
6139 + if(remain != NULL){
6140 + printk("tap_setup_common - Extra garbage on specification : "
6141 + "'%s'\n", remain);
6148 +unsigned short eth_protocol(struct sk_buff *skb)
6150 + return(eth_type_trans(skb, skb->dev));
6154 + * Overrides for Emacs so that we follow Linus's tabbing style.
6155 + * Emacs will notice this stuff at the end of the file and automatically
6156 + * adjust the settings for this buffer only. This must remain at the end
6158 + * ---------------------------------------------------------------------------
6159 + * Local variables:
6160 + * c-file-style: "linux"
6163 diff -Naur -X ../exclude-files orig/arch/um/drivers/net_user.c um/arch/um/drivers/net_user.c
6164 --- orig/arch/um/drivers/net_user.c 1969-12-31 19:00:00.000000000 -0500
6165 +++ um/arch/um/drivers/net_user.c 2002-10-23 21:08:04.000000000 -0400
6168 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
6169 + * Licensed under the GPL
6172 +#include <stddef.h>
6173 +#include <stdarg.h>
6174 +#include <unistd.h>
6177 +#include <stdlib.h>
6178 +#include <string.h>
6179 +#include <sys/socket.h>
6180 +#include <sys/wait.h>
6182 +#include "user_util.h"
6183 +#include "kern_util.h"
6184 +#include "net_user.h"
6185 +#include "helper.h"
6188 +int tap_open_common(void *dev, char *gate_addr)
6192 + if(gate_addr == NULL) return(0);
6193 + if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
6194 + &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
6195 + printk("Invalid tap IP address - '%s'\n",
6202 +void tap_check_ips(char *gate_addr, char *eth_addr)
6206 + if((gate_addr != NULL) &&
6207 + (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
6208 + &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
6209 + (eth_addr[0] == tap_addr[0]) &&
6210 + (eth_addr[1] == tap_addr[1]) &&
6211 + (eth_addr[2] == tap_addr[2]) &&
6212 + (eth_addr[3] == tap_addr[3])){
6213 + printk("The tap IP address and the UML eth IP address"
6214 + " must be different\n");
6218 +void read_output(int fd, char *output, int len)
6220 + int remain, n, actual;
6223 + if(output == NULL){
6229 + if(read(fd, &remain, sizeof(remain)) != sizeof(remain)){
6230 + printk("read_output - read of length failed, errno = %d\n",
6235 + while(remain != 0){
6236 + n = (remain < len) ? remain : len;
6237 + actual = read(fd, output, n);
6239 + printk("read_output - read of data failed, "
6240 + "errno = %d\n", errno);
6248 +int net_read(int fd, void *buf, int len)
6252 + while(((n = read(fd, buf, len)) < 0) && (errno == EINTR)) ;
6255 + if(errno == EAGAIN) return(0);
6258 + else if(n == 0) return(-ENOTCONN);
6262 +int net_recvfrom(int fd, void *buf, int len)
6266 + while(((n = recvfrom(fd, buf, len, 0, NULL, NULL)) < 0) &&
6267 + (errno == EINTR)) ;
6270 + if(errno == EAGAIN) return(0);
6273 + else if(n == 0) return(-ENOTCONN);
6277 +int net_write(int fd, void *buf, int len)
6281 + while(((n = write(fd, buf, len)) < 0) && (errno == EINTR)) ;
6283 + if(errno == EAGAIN) return(0);
6286 + else if(n == 0) return(-ENOTCONN);
6290 +int net_send(int fd, void *buf, int len)
6294 + while(((n = send(fd, buf, len, 0)) < 0) && (errno == EINTR)) ;
6296 + if(errno == EAGAIN) return(0);
6299 + else if(n == 0) return(-ENOTCONN);
6303 +int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
6307 + while(((n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
6308 + sock_len)) < 0) && (errno == EINTR)) ;
6310 + if(errno == EAGAIN) return(0);
6313 + else if(n == 0) return(-ENOTCONN);
6317 +struct change_pre_exec_data {
6322 +static void change_pre_exec(void *arg)
6324 + struct change_pre_exec_data *data = arg;
6326 + close(data->close_me);
6327 + dup2(data->stdout, 1);
6330 +static int change_tramp(char **argv, char *output, int output_len)
6332 + int pid, fds[2], err;
6333 + struct change_pre_exec_data pe_data;
6335 + err = os_pipe(fds, 1, 0);
6337 + printk("change_tramp - pipe failed, errno = %d\n", -err);
6340 + pe_data.close_me = fds[0];
6341 + pe_data.stdout = fds[1];
6342 + pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
6345 + read_output(fds[0], output, output_len);
6346 + waitpid(pid, NULL, 0);
6350 +static void change(char *dev, char *what, unsigned char *addr,
6351 + unsigned char *netmask)
6353 + char addr_buf[sizeof("255.255.255.255\0")];
6354 + char netmask_buf[sizeof("255.255.255.255\0")];
6355 + char version[sizeof("nnnnn\0")];
6356 + char *argv[] = { "uml_net", version, what, dev, addr_buf,
6357 + netmask_buf, NULL };
6359 + int output_len, pid;
6361 + sprintf(version, "%d", UML_NET_VERSION);
6362 + sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
6363 + sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1],
6364 + netmask[2], netmask[3]);
6366 + output_len = page_size();
6367 + output = um_kmalloc(output_len);
6368 + if(output == NULL)
6369 + printk("change : failed to allocate output buffer\n");
6371 + pid = change_tramp(argv, output, output_len);
6372 + if(pid < 0) return;
6374 + if(output != NULL){
6375 + printk("%s", output);
6380 +void open_addr(unsigned char *addr, unsigned char *netmask, void *arg)
6382 + change(arg, "add", addr, netmask);
6385 +void close_addr(unsigned char *addr, unsigned char *netmask, void *arg)
6387 + change(arg, "del", addr, netmask);
6390 +char *split_if_spec(char *str, ...)
6395 + va_start(ap, str);
6396 + while((arg = va_arg(ap, char **)) != NULL){
6399 + end = strchr(str, ',');
6412 + * Overrides for Emacs so that we follow Linus's tabbing style.
6413 + * Emacs will notice this stuff at the end of the file and automatically
6414 + * adjust the settings for this buffer only. This must remain at the end
6416 + * ---------------------------------------------------------------------------
6417 + * Local variables:
6418 + * c-file-style: "linux"
6421 diff -Naur -X ../exclude-files orig/arch/um/drivers/null.c um/arch/um/drivers/null.c
6422 --- orig/arch/um/drivers/null.c 1969-12-31 19:00:00.000000000 -0500
6423 +++ um/arch/um/drivers/null.c 2002-12-15 21:04:00.000000000 -0500
6426 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
6427 + * Licensed under the GPL
6430 +#include <stdlib.h>
6433 +#include "chan_user.h"
6436 +static int null_chan;
6438 +void *null_init(char *str, int device, struct chan_opts *opts)
6440 + return(&null_chan);
6443 +int null_open(int input, int output, int primary, void *d, char **dev_out)
6446 + return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0));
6449 +int null_read(int fd, char *c_out, void *unused)
6454 +void null_free(void *data)
6458 +struct chan_ops null_ops = {
6460 + .init = null_init,
6461 + .open = null_open,
6462 + .close = generic_close,
6463 + .read = null_read,
6464 + .write = generic_write,
6465 + .console_write = generic_console_write,
6466 + .window_size = generic_window_size,
6467 + .free = null_free,
6472 + * Overrides for Emacs so that we follow Linus's tabbing style.
6473 + * Emacs will notice this stuff at the end of the file and automatically
6474 + * adjust the settings for this buffer only. This must remain at the end
6476 + * ---------------------------------------------------------------------------
6477 + * Local variables:
6478 + * c-file-style: "linux"
6481 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_kern.c um/arch/um/drivers/pcap_kern.c
6482 --- orig/arch/um/drivers/pcap_kern.c 1969-12-31 19:00:00.000000000 -0500
6483 +++ um/arch/um/drivers/pcap_kern.c 2002-12-15 21:19:15.000000000 -0500
6486 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
6487 + * Licensed under the GPL.
6490 +#include "linux/init.h"
6491 +#include "linux/netdevice.h"
6492 +#include "linux/etherdevice.h"
6493 +#include "net_kern.h"
6494 +#include "net_user.h"
6495 +#include "pcap_user.h"
6504 +void pcap_init(struct net_device *dev, void *data)
6506 + struct uml_net_private *pri;
6507 + struct pcap_data *ppri;
6508 + struct pcap_init *init = data;
6510 + init_etherdev(dev, 0);
6512 + ppri = (struct pcap_data *) pri->user;
6513 + *ppri = ((struct pcap_data)
6514 + { .host_if = init->host_if,
6515 + .promisc = init->promisc,
6516 + .optimize = init->optimize,
6517 + .filter = init->filter,
6522 +static int pcap_read(int fd, struct sk_buff **skb,
6523 + struct uml_net_private *lp)
6525 + *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
6526 + if(*skb == NULL) return(-ENOMEM);
6527 + return(pcap_user_read(fd, (*skb)->mac.raw,
6528 + (*skb)->dev->mtu + ETH_HEADER_OTHER,
6529 + (struct pcap_data *) &lp->user));
6532 +static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
6537 +static struct net_kern_info pcap_kern_info = {
6538 + .init = pcap_init,
6539 + .protocol = eth_protocol,
6540 + .read = pcap_read,
6541 + .write = pcap_write,
6544 +int pcap_setup(char *str, char **mac_out, void *data)
6546 + struct pcap_init *init = data;
6547 + char *remain, *host_if = NULL, *options[2] = { NULL, NULL };
6550 + *init = ((struct pcap_init)
6551 + { .host_if = "eth0",
6554 + .filter = NULL });
6556 + remain = split_if_spec(str, &host_if, &init->filter,
6557 + &options[0], &options[1], NULL);
6558 + if(remain != NULL){
6559 + printk(KERN_ERR "pcap_setup - Extra garbage on "
6560 + "specification : '%s'\n", remain);
6564 + if(host_if != NULL)
6565 + init->host_if = host_if;
6567 + for(i = 0; i < sizeof(options)/sizeof(options[0]); i++){
6568 + if(options[i] == NULL)
6570 + if(!strcmp(options[i], "promisc"))
6571 + init->promisc = 1;
6572 + else if(!strcmp(options[i], "nopromisc"))
6573 + init->promisc = 0;
6574 + else if(!strcmp(options[i], "optimize"))
6575 + init->optimize = 1;
6576 + else if(!strcmp(options[i], "nooptimize"))
6577 + init->optimize = 0;
6578 + else printk("pcap_setup : bad option - '%s'\n", options[i]);
6584 +static struct transport pcap_transport = {
6585 + .list = LIST_HEAD_INIT(pcap_transport.list),
6587 + .setup = pcap_setup,
6588 + .user = &pcap_user_info,
6589 + .kern = &pcap_kern_info,
6590 + .private_size = sizeof(struct pcap_data),
6591 + .setup_size = sizeof(struct pcap_init),
6594 +static int register_pcap(void)
6596 + register_transport(&pcap_transport);
6600 +__initcall(register_pcap);
6603 + * Overrides for Emacs so that we follow Linus's tabbing style.
6604 + * Emacs will notice this stuff at the end of the file and automatically
6605 + * adjust the settings for this buffer only. This must remain at the end
6607 + * ---------------------------------------------------------------------------
6608 + * Local variables:
6609 + * c-file-style: "linux"
6612 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.c um/arch/um/drivers/pcap_user.c
6613 --- orig/arch/um/drivers/pcap_user.c 1969-12-31 19:00:00.000000000 -0500
6614 +++ um/arch/um/drivers/pcap_user.c 2002-12-15 21:04:39.000000000 -0500
6617 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
6618 + * Licensed under the GPL.
6621 +#include <unistd.h>
6622 +#include <stdlib.h>
6623 +#include <string.h>
6626 +#include <asm/types.h>
6627 +#include "net_user.h"
6628 +#include "pcap_user.h"
6631 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
6633 +#define PCAP_FD(p) (*(int *)(p))
6635 +static void pcap_user_init(void *data, void *dev)
6637 + struct pcap_data *pri = data;
6639 + char errors[PCAP_ERRBUF_SIZE];
6641 + p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors);
6643 + printk("pcap_user_init : pcap_open_live failed - '%s'\n",
6652 +static int pcap_open(void *data)
6654 + struct pcap_data *pri = data;
6658 + if(pri->pcap == NULL)
6661 + if(pri->filter != NULL){
6662 + err = dev_netmask(pri->dev, &netmask);
6664 + printk("pcap_open : dev_netmask failed\n");
6668 + pri->compiled = um_kmalloc(sizeof(struct bpf_program));
6669 + if(pri->compiled == NULL){
6670 + printk("pcap_open : kmalloc failed\n");
6674 + err = pcap_compile(pri->pcap,
6675 + (struct bpf_program *) pri->compiled,
6676 + pri->filter, pri->optimize, netmask);
6678 + printk("pcap_open : pcap_compile failed - '%s'\n",
6679 + pcap_geterr(pri->pcap));
6683 + err = pcap_setfilter(pri->pcap, pri->compiled);
6685 + printk("pcap_open : pcap_setfilter failed - '%s'\n",
6686 + pcap_geterr(pri->pcap));
6691 + return(PCAP_FD(pri->pcap));
6694 +static void pcap_remove(void *data)
6696 + struct pcap_data *pri = data;
6698 + if(pri->compiled != NULL)
6699 + pcap_freecode(pri->compiled);
6701 + pcap_close(pri->pcap);
6704 +struct pcap_handler_data {
6709 +static void handler(u_char *data, const struct pcap_pkthdr *header,
6710 + const u_char *packet)
6714 + struct pcap_handler_data *hdata = (struct pcap_handler_data *) data;
6716 + len = hdata->len < header->caplen ? hdata->len : header->caplen;
6717 + memcpy(hdata->buffer, packet, len);
6721 +int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
6723 + struct pcap_handler_data hdata = ((struct pcap_handler_data)
6724 + { .buffer = buffer,
6728 + n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
6730 + printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap));
6735 + return(hdata.len);
6738 +struct net_user_info pcap_user_info = {
6739 + .init = pcap_user_init,
6740 + .open = pcap_open,
6742 + .remove = pcap_remove,
6744 + .add_address = NULL,
6745 + .delete_address = NULL,
6746 + .max_packet = MAX_PACKET - ETH_HEADER_OTHER
6750 + * Overrides for Emacs so that we follow Linus's tabbing style.
6751 + * Emacs will notice this stuff at the end of the file and automatically
6752 + * adjust the settings for this buffer only. This must remain at the end
6754 + * ---------------------------------------------------------------------------
6755 + * Local variables:
6756 + * c-file-style: "linux"
6759 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.h um/arch/um/drivers/pcap_user.h
6760 --- orig/arch/um/drivers/pcap_user.h 1969-12-31 19:00:00.000000000 -0500
6761 +++ um/arch/um/drivers/pcap_user.h 2002-10-23 21:08:04.000000000 -0400
6764 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
6765 + * Licensed under the GPL
6768 +#include "net_user.h"
6780 +extern struct net_user_info pcap_user_info;
6782 +extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
6785 + * Overrides for Emacs so that we follow Linus's tabbing style.
6786 + * Emacs will notice this stuff at the end of the file and automatically
6787 + * adjust the settings for this buffer only. This must remain at the end
6789 + * ---------------------------------------------------------------------------
6790 + * Local variables:
6791 + * c-file-style: "linux"
6794 diff -Naur -X ../exclude-files orig/arch/um/drivers/port.h um/arch/um/drivers/port.h
6795 --- orig/arch/um/drivers/port.h 1969-12-31 19:00:00.000000000 -0500
6796 +++ um/arch/um/drivers/port.h 2002-10-23 21:08:04.000000000 -0400
6799 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
6800 + * Licensed under the GPL
6806 +extern void *port_data(int port);
6807 +extern int port_wait(void *data);
6808 +extern void port_kern_close(void *d);
6809 +extern int port_connection(int fd, int *socket_out, int *pid_out);
6810 +extern int port_listen_fd(int port);
6811 +extern void port_read(int fd, void *data);
6812 +extern void port_kern_free(void *d);
6813 +extern int port_rcv_fd(int fd);
6814 +extern void port_remove_dev(void *d);
6819 + * Overrides for Emacs so that we follow Linus's tabbing style.
6820 + * Emacs will notice this stuff at the end of the file and automatically
6821 + * adjust the settings for this buffer only. This must remain at the end
6823 + * ---------------------------------------------------------------------------
6824 + * Local variables:
6825 + * c-file-style: "linux"
6828 diff -Naur -X ../exclude-files orig/arch/um/drivers/port_kern.c um/arch/um/drivers/port_kern.c
6829 --- orig/arch/um/drivers/port_kern.c 1969-12-31 19:00:00.000000000 -0500
6830 +++ um/arch/um/drivers/port_kern.c 2002-12-30 20:57:42.000000000 -0500
6833 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
6834 + * Licensed under the GPL
6837 +#include "linux/list.h"
6838 +#include "linux/sched.h"
6839 +#include "linux/slab.h"
6840 +#include "linux/irq.h"
6841 +#include "linux/spinlock.h"
6842 +#include "linux/errno.h"
6843 +#include "asm/semaphore.h"
6844 +#include "asm/errno.h"
6845 +#include "kern_util.h"
6847 +#include "irq_user.h"
6853 + struct list_head list;
6854 + int has_connection;
6855 + struct semaphore sem;
6859 + struct list_head pending;
6860 + struct list_head connections;
6864 + struct port_list *port;
6869 +struct connection {
6870 + struct list_head list;
6875 + struct port_list *port;
6878 +static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
6880 + struct connection *conn = data;
6883 + fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
6888 + printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
6890 + os_close_file(conn->fd);
6893 + list_del(&conn->list);
6896 + list_add(&conn->list, &conn->port->connections);
6898 + up(&conn->port->sem);
6901 +static int port_accept(struct port_list *port)
6903 + struct connection *conn;
6904 + int fd, socket[2], pid, ret = 0;
6906 + fd = port_connection(port->fd, socket, &pid);
6909 + printk(KERN_ERR "port_accept : port_connection "
6910 + "returned %d\n", -fd);
6914 + conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
6916 + printk(KERN_ERR "port_accept : failed to allocate "
6920 + *conn = ((struct connection)
6921 + { .list = LIST_HEAD_INIT(conn->list),
6923 + .socket = { socket[0], socket[1] },
6924 + .telnetd_pid = pid,
6927 + if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
6928 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
6929 + "telnetd", conn)){
6930 + printk(KERN_ERR "port_accept : failed to get IRQ for "
6935 + list_add(&conn->list, &port->pending);
6941 + os_close_file(fd);
6943 + os_kill_process(pid, 1);
6948 +DECLARE_MUTEX(ports_sem);
6949 +struct list_head ports = LIST_HEAD_INIT(ports);
6951 +void port_task_proc(void *unused)
6953 + struct port_list *port;
6954 + struct list_head *ele;
6955 + unsigned long flags;
6957 + save_flags(flags);
6958 + list_for_each(ele, &ports){
6959 + port = list_entry(ele, struct port_list, list);
6960 + if(!port->has_connection)
6962 + reactivate_fd(port->fd, ACCEPT_IRQ);
6963 + while(port_accept(port)) ;
6964 + port->has_connection = 0;
6966 + restore_flags(flags);
6969 +struct tq_struct port_task = {
6970 + .routine = port_task_proc,
6974 +static void port_interrupt(int irq, void *data, struct pt_regs *regs)
6976 + struct port_list *port = data;
6978 + port->has_connection = 1;
6979 + schedule_task(&port_task);
6982 +void *port_data(int port_num)
6984 + struct list_head *ele;
6985 + struct port_list *port;
6986 + struct port_dev *dev = NULL;
6990 + list_for_each(ele, &ports){
6991 + port = list_entry(ele, struct port_list, list);
6992 + if(port->port == port_num) goto found;
6994 + port = kmalloc(sizeof(struct port_list), GFP_KERNEL);
6996 + printk(KERN_ERR "Allocation of port list failed\n");
7000 + fd = port_listen_fd(port_num);
7002 + printk(KERN_ERR "binding to port %d failed, errno = %d\n",
7006 + if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
7007 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "port",
7009 + printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
7013 + *port = ((struct port_list)
7014 + { .list = LIST_HEAD_INIT(port->list),
7015 + .has_connection = 0,
7016 + .sem = __SEMAPHORE_INITIALIZER(port->sem,
7018 + .lock = SPIN_LOCK_UNLOCKED,
7021 + .pending = LIST_HEAD_INIT(port->pending),
7022 + .connections = LIST_HEAD_INIT(port->connections) });
7023 + list_add(&port->list, &ports);
7026 + dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL);
7028 + printk(KERN_ERR "Allocation of port device entry failed\n");
7032 + *dev = ((struct port_dev) { .port = port,
7034 + .telnetd_pid = -1 });
7040 + os_close_file(fd);
7046 +int port_wait(void *data)
7048 + struct port_dev *dev = data;
7049 + struct connection *conn;
7050 + struct port_list *port = dev->port;
7054 + if(down_interruptible(&port->sem))
7055 + return(-ERESTARTSYS);
7057 + spin_lock(&port->lock);
7059 + conn = list_entry(port->connections.next, struct connection,
7061 + list_del(&conn->list);
7062 + spin_unlock(&port->lock);
7064 + os_shutdown_socket(conn->socket[0], 1, 1);
7065 + os_close_file(conn->socket[0]);
7066 + os_shutdown_socket(conn->socket[1], 1, 1);
7067 + os_close_file(conn->socket[1]);
7069 + /* This is done here because freeing an IRQ can't be done
7070 + * within the IRQ handler. So, pipe_interrupt always ups
7071 + * the semaphore regardless of whether it got a successful
7072 + * connection. Then we loop here throwing out failed
7073 + * connections until a good one is found.
7075 + free_irq(TELNETD_IRQ, conn);
7077 + if(conn->fd >= 0) break;
7078 + os_close_file(conn->fd);
7083 + dev->helper_pid = conn->helper_pid;
7084 + dev->telnetd_pid = conn->telnetd_pid;
7090 +void port_remove_dev(void *d)
7092 + struct port_dev *dev = d;
7094 + if(dev->helper_pid != -1)
7095 + os_kill_process(dev->helper_pid, 0);
7096 + if(dev->telnetd_pid != -1)
7097 + os_kill_process(dev->telnetd_pid, 1);
7098 + dev->helper_pid = -1;
7099 + dev->telnetd_pid = -1;
7102 +void port_kern_free(void *d)
7104 + struct port_dev *dev = d;
7106 + port_remove_dev(dev);
7110 +static void free_port(void)
7112 + struct list_head *ele;
7113 + struct port_list *port;
7115 + list_for_each(ele, &ports){
7116 + port = list_entry(ele, struct port_list, list);
7117 + free_irq_by_fd(port->fd);
7118 + os_close_file(port->fd);
7122 +__uml_exitcall(free_port);
7125 + * Overrides for Emacs so that we follow Linus's tabbing style.
7126 + * Emacs will notice this stuff at the end of the file and automatically
7127 + * adjust the settings for this buffer only. This must remain at the end
7129 + * ---------------------------------------------------------------------------
7130 + * Local variables:
7131 + * c-file-style: "linux"
7134 diff -Naur -X ../exclude-files orig/arch/um/drivers/port_user.c um/arch/um/drivers/port_user.c
7135 --- orig/arch/um/drivers/port_user.c 1969-12-31 19:00:00.000000000 -0500
7136 +++ um/arch/um/drivers/port_user.c 2002-12-16 22:46:20.000000000 -0500
7139 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
7140 + * Licensed under the GPL
7144 +#include <stddef.h>
7145 +#include <stdlib.h>
7146 +#include <string.h>
7148 +#include <unistd.h>
7149 +#include <termios.h>
7150 +#include <sys/socket.h>
7151 +#include <sys/un.h>
7152 +#include <netinet/in.h>
7153 +#include "user_util.h"
7154 +#include "kern_util.h"
7156 +#include "chan_user.h"
7158 +#include "helper.h"
7163 + struct termios tt;
7164 + void *kernel_data;
7165 + char dev[sizeof("32768\0")];
7168 +void *port_init(char *str, int device, struct chan_opts *opts)
7170 + struct port_chan *data;
7176 + printk("port_init : channel type 'port' must specify a "
7181 + port = strtoul(str, &end, 0);
7182 + if((*end != '\0') || (end == str)){
7183 + printk("port_init : couldn't parse port '%s'\n", str);
7187 + if((kern_data = port_data(port)) == NULL)
7190 + if((data = um_kmalloc(sizeof(*data))) == NULL)
7193 + *data = ((struct port_chan) { .raw = opts->raw,
7194 + .kernel_data = kern_data });
7195 + sprintf(data->dev, "%d", port);
7199 + port_kern_free(kern_data);
7203 +void port_free(void *d)
7205 + struct port_chan *data = d;
7207 + port_kern_free(data->kernel_data);
7211 +int port_open(int input, int output, int primary, void *d, char **dev_out)
7213 + struct port_chan *data = d;
7216 + fd = port_wait(data->kernel_data);
7217 + if((fd >= 0) && data->raw){
7218 + tcgetattr(fd, &data->tt);
7221 + *dev_out = data->dev;
7225 +void port_close(int fd, void *d)
7227 + struct port_chan *data = d;
7229 + port_remove_dev(data->kernel_data);
7233 +int port_console_write(int fd, const char *buf, int n, void *d)
7235 + struct port_chan *data = d;
7237 + return(generic_console_write(fd, buf, n, &data->tt));
7240 +struct chan_ops port_ops = {
7242 + .init = port_init,
7243 + .open = port_open,
7244 + .close = port_close,
7245 + .read = generic_read,
7246 + .write = generic_write,
7247 + .console_write = port_console_write,
7248 + .window_size = generic_window_size,
7249 + .free = port_free,
7253 +int port_listen_fd(int port)
7255 + struct sockaddr_in addr;
7258 + fd = socket(PF_INET, SOCK_STREAM, 0);
7262 + addr.sin_family = AF_INET;
7263 + addr.sin_port = htons(port);
7264 + addr.sin_addr.s_addr = htonl(INADDR_ANY);
7265 + if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){
7270 + if((listen(fd, 1) < 0) || (os_set_fd_block(fd, 0))){
7277 + os_close_file(fd);
7281 +struct port_pre_exec_data {
7286 +void port_pre_exec(void *arg)
7288 + struct port_pre_exec_data *data = arg;
7290 + dup2(data->sock_fd, 0);
7291 + dup2(data->sock_fd, 1);
7292 + dup2(data->sock_fd, 2);
7293 + close(data->sock_fd);
7294 + dup2(data->pipe_fd, 3);
7295 + os_shutdown_socket(3, 1, 0);
7296 + close(data->pipe_fd);
7299 +int port_connection(int fd, int *socket, int *pid_out)
7302 + char *argv[] = { "/usr/sbin/in.telnetd", "-L",
7303 + "/usr/lib/uml/port-helper", NULL };
7304 + struct port_pre_exec_data data;
7306 + if((new = os_accept_connection(fd)) < 0)
7309 + err = os_pipe(socket, 0, 0);
7313 + data = ((struct port_pre_exec_data)
7315 + .pipe_fd = socket[1] });
7317 + err = run_helper(port_pre_exec, &data, argv, NULL);
7319 + goto out_shutdown;
7325 + os_shutdown_socket(socket[0], 1, 1);
7327 + os_shutdown_socket(socket[1], 1, 1);
7335 + * Overrides for Emacs so that we follow Linus's tabbing style.
7336 + * Emacs will notice this stuff at the end of the file and automatically
7337 + * adjust the settings for this buffer only. This must remain at the end
7339 + * ---------------------------------------------------------------------------
7340 + * Local variables:
7341 + * c-file-style: "linux"
7344 diff -Naur -X ../exclude-files orig/arch/um/drivers/pty.c um/arch/um/drivers/pty.c
7345 --- orig/arch/um/drivers/pty.c 1969-12-31 19:00:00.000000000 -0500
7346 +++ um/arch/um/drivers/pty.c 2002-12-15 21:06:01.000000000 -0500
7349 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7350 + * Licensed under the GPL
7354 +#include <unistd.h>
7355 +#include <string.h>
7358 +#include <termios.h>
7359 +#include "chan_user.h"
7361 +#include "user_util.h"
7362 +#include "kern_util.h"
7365 + void (*announce)(char *dev_name, int dev);
7368 + struct termios tt;
7369 + char dev_name[sizeof("/dev/pts/0123456\0")];
7372 +void *pty_chan_init(char *str, int device, struct chan_opts *opts)
7374 + struct pty_chan *data;
7376 + if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
7377 + *data = ((struct pty_chan) { .announce = opts->announce,
7379 + .raw = opts->raw });
7383 +int pts_open(int input, int output, int primary, void *d, char **dev_out)
7385 + struct pty_chan *data = d;
7389 + if((fd = get_pty()) < 0){
7390 + printk("open_pts : Failed to open pts\n");
7394 + tcgetattr(fd, &data->tt);
7398 + dev = ptsname(fd);
7399 + sprintf(data->dev_name, "%s", dev);
7400 + *dev_out = data->dev_name;
7401 + if(data->announce) (*data->announce)(dev, data->dev);
7405 +int getmaster(char *line)
7408 + char *pty, *bank, *cp;
7411 + pty = &line[strlen("/dev/ptyp")];
7412 + for (bank = "pqrs"; *bank; bank++) {
7413 + line[strlen("/dev/pty")] = *bank;
7415 + if (stat(line, &stb) < 0)
7417 + for (cp = "0123456789abcdef"; *cp; cp++) {
7419 + master = open(line, O_RDWR);
7420 + if (master >= 0) {
7421 + char *tp = &line[strlen("/dev/")];
7424 + /* verify slave side is usable */
7426 + ok = access(line, R_OK|W_OK) == 0;
7428 + if (ok) return(master);
7429 + (void) close(master);
7436 +int pty_open(int input, int output, int primary, void *d, char **dev_out)
7438 + struct pty_chan *data = d;
7440 + char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
7442 + fd = getmaster(dev);
7443 + if(fd < 0) return(-errno);
7445 + if(data->raw) raw(fd, 0);
7446 + if(data->announce) (*data->announce)(dev, data->dev);
7448 + sprintf(data->dev_name, "%s", dev);
7449 + *dev_out = data->dev_name;
7453 +int pty_console_write(int fd, const char *buf, int n, void *d)
7455 + struct pty_chan *data = d;
7457 + return(generic_console_write(fd, buf, n, &data->tt));
7460 +struct chan_ops pty_ops = {
7462 + .init = pty_chan_init,
7464 + .close = generic_close,
7465 + .read = generic_read,
7466 + .write = generic_write,
7467 + .console_write = pty_console_write,
7468 + .window_size = generic_window_size,
7469 + .free = generic_free,
7473 +struct chan_ops pts_ops = {
7475 + .init = pty_chan_init,
7477 + .close = generic_close,
7478 + .read = generic_read,
7479 + .write = generic_write,
7480 + .console_write = pty_console_write,
7481 + .window_size = generic_window_size,
7482 + .free = generic_free,
7487 + * Overrides for Emacs so that we follow Linus's tabbing style.
7488 + * Emacs will notice this stuff at the end of the file and automatically
7489 + * adjust the settings for this buffer only. This must remain at the end
7491 + * ---------------------------------------------------------------------------
7492 + * Local variables:
7493 + * c-file-style: "linux"
7496 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip.h um/arch/um/drivers/slip.h
7497 --- orig/arch/um/drivers/slip.h 1969-12-31 19:00:00.000000000 -0500
7498 +++ um/arch/um/drivers/slip.h 2002-10-23 21:08:04.000000000 -0400
7500 +#ifndef __UM_SLIP_H
7501 +#define __UM_SLIP_H
7503 +#define BUF_SIZE 1500
7504 + /* two bytes each for a (pathological) max packet of escaped chars + *
7505 + * terminating END char + initial END char */
7506 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
7510 + char name[sizeof("slnnnnn\0")];
7514 + char ibuf[ENC_BUF_SIZE];
7515 + char obuf[ENC_BUF_SIZE];
7516 + int more; /* more data: do not read fd until ibuf has been drained */
7521 +extern struct net_user_info slip_user_info;
7523 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
7524 +extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri);
7525 +extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri);
7530 + * Overrides for Emacs so that we follow Linus's tabbing style.
7531 + * Emacs will notice this stuff at the end of the file and automatically
7532 + * adjust the settings for this buffer only. This must remain at the end
7534 + * ---------------------------------------------------------------------------
7535 + * Local variables:
7536 + * c-file-style: "linux"
7539 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_kern.c um/arch/um/drivers/slip_kern.c
7540 --- orig/arch/um/drivers/slip_kern.c 1969-12-31 19:00:00.000000000 -0500
7541 +++ um/arch/um/drivers/slip_kern.c 2002-12-15 21:06:24.000000000 -0500
7543 +#include "linux/config.h"
7544 +#include "linux/kernel.h"
7545 +#include "linux/stddef.h"
7546 +#include "linux/init.h"
7547 +#include "linux/netdevice.h"
7548 +#include "linux/if_arp.h"
7549 +#include "net_kern.h"
7550 +#include "net_user.h"
7558 +void slip_init(struct net_device *dev, void *data)
7560 + struct uml_net_private *private;
7561 + struct slip_data *spri;
7562 + struct slip_init *init = data;
7564 + private = dev->priv;
7565 + spri = (struct slip_data *) private->user;
7566 + *spri = ((struct slip_data)
7567 + { .name = { '\0' },
7569 + .gate_addr = init->gate_addr,
7578 + dev->hard_header_len = 0;
7579 + dev->addr_len = 4;
7580 + dev->type = ARPHRD_ETHER;
7581 + dev->tx_queue_len = 256;
7582 + dev->flags = IFF_NOARP;
7583 + printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr);
7586 +static unsigned short slip_protocol(struct sk_buff *skbuff)
7588 + return(htons(ETH_P_IP));
7591 +static int slip_read(int fd, struct sk_buff **skb,
7592 + struct uml_net_private *lp)
7594 + return(slip_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu,
7595 + (struct slip_data *) &lp->user));
7598 +static int slip_write(int fd, struct sk_buff **skb,
7599 + struct uml_net_private *lp)
7601 + return(slip_user_write(fd, (*skb)->data, (*skb)->len,
7602 + (struct slip_data *) &lp->user));
7605 +struct net_kern_info slip_kern_info = {
7606 + .init = slip_init,
7607 + .protocol = slip_protocol,
7608 + .read = slip_read,
7609 + .write = slip_write,
7612 +static int slip_setup(char *str, char **mac_out, void *data)
7614 + struct slip_init *init = data;
7616 + *init = ((struct slip_init)
7617 + { .gate_addr = NULL });
7619 + if(str[0] != '\0')
7620 + init->gate_addr = str;
7624 +static struct transport slip_transport = {
7625 + .list = LIST_HEAD_INIT(slip_transport.list),
7627 + .setup = slip_setup,
7628 + .user = &slip_user_info,
7629 + .kern = &slip_kern_info,
7630 + .private_size = sizeof(struct slip_data),
7631 + .setup_size = sizeof(struct slip_init),
7634 +static int register_slip(void)
7636 + register_transport(&slip_transport);
7640 +__initcall(register_slip);
7643 + * Overrides for Emacs so that we follow Linus's tabbing style.
7644 + * Emacs will notice this stuff at the end of the file and automatically
7645 + * adjust the settings for this buffer only. This must remain at the end
7647 + * ---------------------------------------------------------------------------
7648 + * Local variables:
7649 + * c-file-style: "linux"
7652 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_proto.h um/arch/um/drivers/slip_proto.h
7653 --- orig/arch/um/drivers/slip_proto.h 1969-12-31 19:00:00.000000000 -0500
7654 +++ um/arch/um/drivers/slip_proto.h 2002-10-23 21:08:04.000000000 -0400
7657 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7658 + * Licensed under the GPL
7661 +#ifndef __UM_SLIP_PROTO_H__
7662 +#define __UM_SLIP_PROTO_H__
7664 +/* SLIP protocol characters. */
7665 +#define SLIP_END 0300 /* indicates end of frame */
7666 +#define SLIP_ESC 0333 /* indicates byte stuffing */
7667 +#define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */
7668 +#define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
7670 +static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc)
7683 + case SLIP_ESC_ESC:
7689 + case SLIP_ESC_END:
7696 + buf[(*pos)++] = c;
7700 +static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
7702 + unsigned char *ptr = d;
7706 + * Send an initial END character to flush out any
7707 + * data that may have accumulated in the receiver
7708 + * due to line noise.
7711 + *ptr++ = SLIP_END;
7714 + * For each byte in the packet, send the appropriate
7715 + * character sequence, according to the SLIP protocol.
7718 + while (len-- > 0) {
7719 + switch(c = *s++) {
7721 + *ptr++ = SLIP_ESC;
7722 + *ptr++ = SLIP_ESC_END;
7725 + *ptr++ = SLIP_ESC;
7726 + *ptr++ = SLIP_ESC_ESC;
7733 + *ptr++ = SLIP_END;
7740 + * Overrides for Emacs so that we follow Linus's tabbing style.
7741 + * Emacs will notice this stuff at the end of the file and automatically
7742 + * adjust the settings for this buffer only. This must remain at the end
7744 + * ---------------------------------------------------------------------------
7745 + * Local variables:
7746 + * c-file-style: "linux"
7749 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_user.c um/arch/um/drivers/slip_user.c
7750 --- orig/arch/um/drivers/slip_user.c 1969-12-31 19:00:00.000000000 -0500
7751 +++ um/arch/um/drivers/slip_user.c 2002-12-15 21:06:35.000000000 -0500
7754 +#include <stdlib.h>
7755 +#include <unistd.h>
7756 +#include <stddef.h>
7758 +#include <string.h>
7759 +#include <sys/fcntl.h>
7760 +#include <sys/errno.h>
7761 +#include <sys/termios.h>
7762 +#include <sys/wait.h>
7763 +#include <sys/ioctl.h>
7764 +#include <sys/signal.h>
7765 +#include "user_util.h"
7766 +#include "kern_util.h"
7768 +#include "net_user.h"
7770 +#include "slip_proto.h"
7771 +#include "helper.h"
7774 +void slip_user_init(void *data, void *dev)
7776 + struct slip_data *pri = data;
7781 +static int set_up_tty(int fd)
7784 + struct termios tios;
7786 + if (tcgetattr(fd, &tios) < 0) {
7787 + printk("could not get initial terminal attributes\n");
7791 + tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
7792 + tios.c_iflag = IGNBRK | IGNPAR;
7795 + for (i = 0; i < NCCS; i++)
7797 + tios.c_cc[VMIN] = 1;
7798 + tios.c_cc[VTIME] = 0;
7800 + cfsetospeed(&tios, B38400);
7801 + cfsetispeed(&tios, B38400);
7803 + if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
7804 + printk("failed to set terminal attributes\n");
7810 +struct slip_pre_exec_data {
7816 +static void slip_pre_exec(void *arg)
7818 + struct slip_pre_exec_data *data = arg;
7820 + if(data->stdin != -1) dup2(data->stdin, 0);
7821 + dup2(data->stdout, 1);
7822 + if(data->close_me != -1) close(data->close_me);
7825 +static int slip_tramp(char **argv, int fd)
7827 + struct slip_pre_exec_data pe_data;
7829 + int status, pid, fds[2], err, output_len;
7831 + err = os_pipe(fds, 1, 0);
7833 + printk("slip_tramp : pipe failed, errno = %d\n", -err);
7838 + pe_data.stdin = fd;
7839 + pe_data.stdout = fds[1];
7840 + pe_data.close_me = fds[0];
7841 + pid = run_helper(slip_pre_exec, &pe_data, argv, NULL);
7843 + if(pid < 0) err = pid;
7845 + output_len = page_size();
7846 + output = um_kmalloc(output_len);
7847 + if(output == NULL)
7848 + printk("slip_tramp : failed to allocate output "
7852 + read_output(fds[0], output, output_len);
7853 + if(output != NULL){
7854 + printk("%s", output);
7857 + if(waitpid(pid, &status, 0) < 0) err = errno;
7858 + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
7859 + printk("'%s' didn't exit with status 0\n", argv[0]);
7866 +static int slip_open(void *data)
7868 + struct slip_data *pri = data;
7869 + char version_buf[sizeof("nnnnn\0")];
7870 + char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
7871 + char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf,
7873 + int sfd, mfd, disc, sencap, err;
7875 + if((mfd = get_pty()) < 0){
7876 + printk("umn : Failed to open pty\n");
7879 + if((sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0)) < 0){
7880 + printk("Couldn't open tty for slip line\n");
7883 + if(set_up_tty(sfd)) return(-1);
7887 + if(pri->gate_addr != NULL){
7888 + sprintf(version_buf, "%d", UML_NET_VERSION);
7889 + strcpy(gate_buf, pri->gate_addr);
7891 + err = slip_tramp(argv, sfd);
7894 + printk("slip_tramp failed - errno = %d\n", err);
7897 + if(ioctl(pri->slave, SIOCGIFNAME, pri->name) < 0){
7898 + printk("SIOCGIFNAME failed, errno = %d\n", errno);
7901 + iter_addresses(pri->dev, open_addr, pri->name);
7905 + if(ioctl(sfd, TIOCSETD, &disc) < 0){
7906 + printk("Failed to set slip line discipline - "
7907 + "errno = %d\n", errno);
7911 + if(ioctl(sfd, SIOCSIFENCAP, &sencap) < 0){
7912 + printk("Failed to set slip encapsulation - "
7913 + "errno = %d\n", errno);
7920 +static void slip_close(int fd, void *data)
7922 + struct slip_data *pri = data;
7923 + char version_buf[sizeof("nnnnn\0")];
7924 + char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
7928 + if(pri->gate_addr != NULL)
7929 + iter_addresses(pri->dev, close_addr, pri->name);
7931 + sprintf(version_buf, "%d", UML_NET_VERSION);
7933 + err = slip_tramp(argv, -1);
7936 + printk("slip_tramp failed - errno = %d\n", err);
7938 + close(pri->slave);
7942 +int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
7944 + int i, n, size, start;
7948 + while(i < pri->more) {
7949 + size = slip_unesc(pri->ibuf[i++],
7950 + pri->ibuf, &pri->pos, &pri->esc);
7952 + memcpy(buf, pri->ibuf, size);
7953 + memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
7954 + pri->more=pri->more-i;
7961 + n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
7962 + if(n <= 0) return(n);
7965 + for(i = 0; i < n; i++){
7966 + size = slip_unesc(pri->ibuf[start + i],
7967 + pri->ibuf, &pri->pos, &pri->esc);
7969 + memcpy(buf, pri->ibuf, size);
7970 + memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
7971 + pri->more=n-(i+1);
7978 +int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
7982 + actual = slip_esc(buf, pri->obuf, len);
7983 + n = net_write(fd, pri->obuf, actual);
7984 + if(n < 0) return(n);
7988 +static int slip_set_mtu(int mtu, void *data)
7993 +static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
7996 + struct slip_data *pri = data;
7998 + if(pri->slave == -1) return;
7999 + open_addr(addr, netmask, pri->name);
8002 +static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
8005 + struct slip_data *pri = data;
8007 + if(pri->slave == -1) return;
8008 + close_addr(addr, netmask, pri->name);
8011 +struct net_user_info slip_user_info = {
8012 + .init = slip_user_init,
8013 + .open = slip_open,
8014 + .close = slip_close,
8016 + .set_mtu = slip_set_mtu,
8017 + .add_address = slip_add_addr,
8018 + .delete_address = slip_del_addr,
8019 + .max_packet = BUF_SIZE
8023 + * Overrides for Emacs so that we follow Linus's tabbing style.
8024 + * Emacs will notice this stuff at the end of the file and automatically
8025 + * adjust the settings for this buffer only. This must remain at the end
8027 + * ---------------------------------------------------------------------------
8028 + * Local variables:
8029 + * c-file-style: "linux"
8032 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp.h um/arch/um/drivers/slirp.h
8033 --- orig/arch/um/drivers/slirp.h 1969-12-31 19:00:00.000000000 -0500
8034 +++ um/arch/um/drivers/slirp.h 2002-10-23 21:08:04.000000000 -0400
8036 +#ifndef __UM_SLIRP_H
8037 +#define __UM_SLIRP_H
8039 +#define BUF_SIZE 1500
8040 + /* two bytes each for a (pathological) max packet of escaped chars + *
8041 + * terminating END char + initial END char */
8042 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8044 +#define SLIRP_MAX_ARGS 100
8046 + * XXX this next definition is here because I don't understand why this
8047 + * initializer doesn't work in slirp_kern.c:
8049 + * argv : { init->argv[ 0 ... SLIRP_MAX_ARGS-1 ] },
8051 + * or why I can't typecast like this:
8053 + * argv : (char* [SLIRP_MAX_ARGS])(init->argv),
8055 +struct arg_list_dummy_wrapper { char *argv[SLIRP_MAX_ARGS]; };
8057 +struct slirp_data {
8059 + struct arg_list_dummy_wrapper argw;
8062 + char ibuf[ENC_BUF_SIZE];
8063 + char obuf[ENC_BUF_SIZE];
8064 + int more; /* more data: do not read fd until ibuf has been drained */
8069 +extern struct net_user_info slirp_user_info;
8071 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
8072 +extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri);
8073 +extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri);
8078 + * Overrides for Emacs so that we follow Linus's tabbing style.
8079 + * Emacs will notice this stuff at the end of the file and automatically
8080 + * adjust the settings for this buffer only. This must remain at the end
8082 + * ---------------------------------------------------------------------------
8083 + * Local variables:
8084 + * c-file-style: "linux"
8087 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_kern.c um/arch/um/drivers/slirp_kern.c
8088 --- orig/arch/um/drivers/slirp_kern.c 1969-12-31 19:00:00.000000000 -0500
8089 +++ um/arch/um/drivers/slirp_kern.c 2002-12-15 21:06:54.000000000 -0500
8091 +#include "linux/kernel.h"
8092 +#include "linux/stddef.h"
8093 +#include "linux/init.h"
8094 +#include "linux/netdevice.h"
8095 +#include "linux/if_arp.h"
8096 +#include "net_kern.h"
8097 +#include "net_user.h"
8101 +struct slirp_init {
8102 + struct arg_list_dummy_wrapper argw; /* XXX should be simpler... */
8105 +void slirp_init(struct net_device *dev, void *data)
8107 + struct uml_net_private *private;
8108 + struct slirp_data *spri;
8109 + struct slirp_init *init = data;
8112 + private = dev->priv;
8113 + spri = (struct slirp_data *) private->user;
8114 + *spri = ((struct slirp_data)
8115 + { .argw = init->argw,
8125 + dev->hard_header_len = 0;
8126 + dev->addr_len = 4;
8127 + dev->type = ARPHRD_ETHER;
8128 + dev->tx_queue_len = 256;
8129 + dev->flags = IFF_NOARP;
8130 + printk("SLIRP backend - command line:");
8131 + for(i=0;spri->argw.argv[i]!=NULL;i++) {
8132 + printk(" '%s'",spri->argw.argv[i]);
8137 +static unsigned short slirp_protocol(struct sk_buff *skbuff)
8139 + return(htons(ETH_P_IP));
8142 +static int slirp_read(int fd, struct sk_buff **skb,
8143 + struct uml_net_private *lp)
8145 + return(slirp_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu,
8146 + (struct slirp_data *) &lp->user));
8149 +static int slirp_write(int fd, struct sk_buff **skb,
8150 + struct uml_net_private *lp)
8152 + return(slirp_user_write(fd, (*skb)->data, (*skb)->len,
8153 + (struct slirp_data *) &lp->user));
8156 +struct net_kern_info slirp_kern_info = {
8157 + .init = slirp_init,
8158 + .protocol = slirp_protocol,
8159 + .read = slirp_read,
8160 + .write = slirp_write,
8163 +static int slirp_setup(char *str, char **mac_out, void *data)
8165 + struct slirp_init *init = data;
8168 + *init = ((struct slirp_init)
8169 + { argw : { { "slirp", NULL } } });
8171 + str = split_if_spec(str, mac_out, NULL);
8173 + if(str == NULL) { /* no command line given after MAC addr */
8178 + if(i>=SLIRP_MAX_ARGS-1) {
8179 + printk("slirp_setup: truncating slirp arguments\n");
8182 + init->argw.argv[i++] = str;
8183 + while(*str && *str!=',') {
8184 + if(*str=='_') *str=' ';
8191 + init->argw.argv[i]=NULL;
8195 +static struct transport slirp_transport = {
8196 + .list = LIST_HEAD_INIT(slirp_transport.list),
8198 + .setup = slirp_setup,
8199 + .user = &slirp_user_info,
8200 + .kern = &slirp_kern_info,
8201 + .private_size = sizeof(struct slirp_data),
8202 + .setup_size = sizeof(struct slirp_init),
8205 +static int register_slirp(void)
8207 + register_transport(&slirp_transport);
8211 +__initcall(register_slirp);
8214 + * Overrides for Emacs so that we follow Linus's tabbing style.
8215 + * Emacs will notice this stuff at the end of the file and automatically
8216 + * adjust the settings for this buffer only. This must remain at the end
8218 + * ---------------------------------------------------------------------------
8219 + * Local variables:
8220 + * c-file-style: "linux"
8223 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_user.c um/arch/um/drivers/slirp_user.c
8224 --- orig/arch/um/drivers/slirp_user.c 1969-12-31 19:00:00.000000000 -0500
8225 +++ um/arch/um/drivers/slirp_user.c 2002-12-15 21:07:08.000000000 -0500
8228 +#include <stdlib.h>
8229 +#include <unistd.h>
8230 +#include <stddef.h>
8232 +#include <string.h>
8233 +#include <sys/fcntl.h>
8234 +#include <sys/errno.h>
8235 +#include <sys/wait.h>
8236 +#include <sys/signal.h>
8237 +#include "user_util.h"
8238 +#include "kern_util.h"
8240 +#include "net_user.h"
8242 +#include "slip_proto.h"
8243 +#include "helper.h"
8246 +void slirp_user_init(void *data, void *dev)
8248 + struct slirp_data *pri = data;
8253 +struct slirp_pre_exec_data {
8258 +static void slirp_pre_exec(void *arg)
8260 + struct slirp_pre_exec_data *data = arg;
8262 + if(data->stdin != -1) dup2(data->stdin, 0);
8263 + if(data->stdout != -1) dup2(data->stdout, 1);
8266 +static int slirp_tramp(char **argv, int fd)
8268 + struct slirp_pre_exec_data pe_data;
8271 + pe_data.stdin = fd;
8272 + pe_data.stdout = fd;
8273 + pid = run_helper(slirp_pre_exec, &pe_data, argv, NULL);
8278 +static int slirp_datachan(int *mfd, int *sfd)
8282 + err = os_pipe(fds, 1, 1);
8284 + printk("slirp_datachan: Failed to open pipe, errno = %d\n",
8294 +static int slirp_open(void *data)
8296 + struct slirp_data *pri = data;
8297 + int sfd, mfd, pid, err;
8299 + err = slirp_datachan(&mfd, &sfd);
8303 + pid = slirp_tramp(pri->argw.argv, sfd);
8306 + printk("slirp_tramp failed - errno = %d\n", pid);
8307 + os_close_file(sfd);
8308 + os_close_file(mfd);
8321 +static void slirp_close(int fd, void *data)
8323 + struct slirp_data *pri = data;
8327 + close(pri->slave);
8332 + printk("slirp_close: no child process to shut down\n");
8337 + if(kill(pri->pid, SIGHUP)<0) {
8338 + printk("slirp_close: sending hangup to %d failed (%d)\n",
8343 + err = waitpid(pri->pid, &status, WNOHANG);
8345 + printk("slirp_close: waitpid returned %d\n", errno);
8350 + printk("slirp_close: process %d has not exited\n");
8357 +int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
8359 + int i, n, size, start;
8363 + while(i < pri->more) {
8364 + size = slip_unesc(pri->ibuf[i++],
8365 + pri->ibuf,&pri->pos,&pri->esc);
8367 + memcpy(buf, pri->ibuf, size);
8368 + memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
8369 + pri->more=pri->more-i;
8376 + n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
8377 + if(n <= 0) return(n);
8380 + for(i = 0; i < n; i++){
8381 + size = slip_unesc(pri->ibuf[start + i],
8382 + pri->ibuf,&pri->pos,&pri->esc);
8384 + memcpy(buf, pri->ibuf, size);
8385 + memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
8386 + pri->more=n-(i+1);
8393 +int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
8397 + actual = slip_esc(buf, pri->obuf, len);
8398 + n = net_write(fd, pri->obuf, actual);
8399 + if(n < 0) return(n);
8403 +static int slirp_set_mtu(int mtu, void *data)
8408 +struct net_user_info slirp_user_info = {
8409 + .init = slirp_user_init,
8410 + .open = slirp_open,
8411 + .close = slirp_close,
8413 + .set_mtu = slirp_set_mtu,
8414 + .add_address = NULL,
8415 + .delete_address = NULL,
8416 + .max_packet = BUF_SIZE
8420 + * Overrides for Emacs so that we follow Linus's tabbing style.
8421 + * Emacs will notice this stuff at the end of the file and automatically
8422 + * adjust the settings for this buffer only. This must remain at the end
8424 + * ---------------------------------------------------------------------------
8425 + * Local variables:
8426 + * c-file-style: "linux"
8429 diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.c um/arch/um/drivers/ssl.c
8430 --- orig/arch/um/drivers/ssl.c 1969-12-31 19:00:00.000000000 -0500
8431 +++ um/arch/um/drivers/ssl.c 2003-03-06 18:55:01.000000000 -0500
8434 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
8435 + * Licensed under the GPL
8438 +#include "linux/config.h"
8439 +#include "linux/fs.h"
8440 +#include "linux/tty.h"
8441 +#include "linux/tty_driver.h"
8442 +#include "linux/major.h"
8443 +#include "linux/mm.h"
8444 +#include "linux/init.h"
8445 +#include "asm/termbits.h"
8446 +#include "asm/irq.h"
8449 +#include "chan_kern.h"
8450 +#include "user_util.h"
8451 +#include "kern_util.h"
8454 +#include "irq_user.h"
8455 +#include "mconsole_kern.h"
8456 +#include "2_5compat.h"
8458 +static int ssl_version = 1;
8460 +/* Referenced only by tty_driver below - presumably it's locked correctly
8461 + * by the tty driver.
8463 +static int ssl_refcount = 0;
8465 +static struct tty_driver ssl_driver;
8467 +#define NR_PORTS 64
8469 +void ssl_announce(char *dev_name, int dev)
8471 + printk(KERN_INFO "Serial line %d assigned device '%s'\n", dev,
8475 +static struct chan_opts opts = {
8476 + .announce = ssl_announce,
8477 + .xterm_title = "Serial Line #%d",
8483 +static int ssl_config(char *str);
8484 +static int ssl_get_config(char *dev, char *str, int size, char **error_out);
8485 +static int ssl_remove(char *str);
8487 +static struct line_driver driver = {
8488 + .name = "UML serial line",
8489 + .devfs_name = "tts/%d",
8490 + .major = TTY_MAJOR,
8491 + .minor_start = 64,
8492 + .type = TTY_DRIVER_TYPE_SERIAL,
8494 + .read_irq = SSL_IRQ,
8495 + .read_irq_name = "ssl",
8496 + .write_irq = SSL_WRITE_IRQ,
8497 + .write_irq_name = "ssl-write",
8498 + .symlink_from = "serial",
8499 + .symlink_to = "tts",
8502 + .config = ssl_config,
8503 + .get_config = ssl_get_config,
8504 + .remove = ssl_remove,
8508 +/* The array is initialized by line_init, which is an initcall. The
8509 + * individual elements are protected by individual semaphores.
8511 +static struct line serial_lines[NR_PORTS] =
8512 + { [0 ... NR_PORTS - 1] = LINE_INIT(CONFIG_SSL_CHAN, &driver) };
8514 +static struct lines lines = LINES_INIT(NR_PORTS);
8516 +static int ssl_config(char *str)
8518 + return(line_config(serial_lines,
8519 + sizeof(serial_lines)/sizeof(serial_lines[0]), str));
8522 +static int ssl_get_config(char *dev, char *str, int size, char **error_out)
8524 + return(line_get_config(dev, serial_lines,
8525 + sizeof(serial_lines)/sizeof(serial_lines[0]),
8526 + str, size, error_out));
8529 +static int ssl_remove(char *str)
8531 + return(line_remove(serial_lines,
8532 + sizeof(serial_lines)/sizeof(serial_lines[0]), str));
8535 +int ssl_open(struct tty_struct *tty, struct file *filp)
8537 + return(line_open(serial_lines, tty, &opts));
8540 +static void ssl_close(struct tty_struct *tty, struct file * filp)
8542 + line_close(serial_lines, tty);
8545 +static int ssl_write(struct tty_struct * tty, int from_user,
8546 + const unsigned char *buf, int count)
8548 + return(line_write(serial_lines, tty, from_user, buf, count));
8551 +static void ssl_put_char(struct tty_struct *tty, unsigned char ch)
8553 + line_write(serial_lines, tty, 0, &ch, sizeof(ch));
8556 +static void ssl_flush_chars(struct tty_struct *tty)
8561 +static int ssl_chars_in_buffer(struct tty_struct *tty)
8566 +static void ssl_flush_buffer(struct tty_struct *tty)
8571 +static int ssl_ioctl(struct tty_struct *tty, struct file * file,
8572 + unsigned int cmd, unsigned long arg)
8585 + ret = -ENOIOCTLCMD;
8589 + "Unimplemented ioctl in ssl_ioctl : 0x%x\n", cmd);
8590 + ret = -ENOIOCTLCMD;
8596 +static void ssl_throttle(struct tty_struct * tty)
8598 + printk(KERN_ERR "Someone should implement ssl_throttle\n");
8601 +static void ssl_unthrottle(struct tty_struct * tty)
8603 + printk(KERN_ERR "Someone should implement ssl_unthrottle\n");
8606 +static void ssl_set_termios(struct tty_struct *tty,
8607 + struct termios *old_termios)
8611 +static void ssl_stop(struct tty_struct *tty)
8613 + printk(KERN_ERR "Someone should implement ssl_stop\n");
8616 +static void ssl_start(struct tty_struct *tty)
8618 + printk(KERN_ERR "Someone should implement ssl_start\n");
8621 +void ssl_hangup(struct tty_struct *tty)
8625 +static struct tty_driver ssl_driver = {
8626 + .refcount = &ssl_refcount,
8628 + .close = ssl_close,
8629 + .write = ssl_write,
8630 + .put_char = ssl_put_char,
8631 + .flush_chars = ssl_flush_chars,
8632 + .chars_in_buffer = ssl_chars_in_buffer,
8633 + .flush_buffer = ssl_flush_buffer,
8634 + .ioctl = ssl_ioctl,
8635 + .throttle = ssl_throttle,
8636 + .unthrottle = ssl_unthrottle,
8637 + .set_termios = ssl_set_termios,
8639 + .start = ssl_start,
8640 + .hangup = ssl_hangup
8643 +/* Changed by ssl_init and referenced by ssl_exit, which are both serialized
8644 + * by being an initcall and exitcall, respectively.
8646 +static int ssl_init_done = 0;
8652 + printk(KERN_INFO "Initializing software serial port version %d\n",
8655 + line_register_devfs(&lines, &driver, &ssl_driver, serial_lines,
8656 + sizeof(serial_lines)/sizeof(serial_lines[0]));
8658 + lines_init(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]));
8660 + new_title = add_xterm_umid(opts.xterm_title);
8661 + if(new_title != NULL) opts.xterm_title = new_title;
8663 + ssl_init_done = 1;
8667 +__initcall(ssl_init);
8669 +static int ssl_chan_setup(char *str)
8671 + line_setup(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]),
8676 +__setup("ssl", ssl_chan_setup);
8677 +__channel_help(ssl_chan_setup, "ssl");
8679 +static void ssl_exit(void)
8681 + if(!ssl_init_done) return;
8682 + close_lines(serial_lines,
8683 + sizeof(serial_lines)/sizeof(serial_lines[0]));
8686 +__uml_exitcall(ssl_exit);
8689 + * Overrides for Emacs so that we follow Linus's tabbing style.
8690 + * Emacs will notice this stuff at the end of the file and automatically
8691 + * adjust the settings for this buffer only. This must remain at the end
8693 + * ---------------------------------------------------------------------------
8694 + * Local variables:
8695 + * c-file-style: "linux"
8698 diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.h um/arch/um/drivers/ssl.h
8699 --- orig/arch/um/drivers/ssl.h 1969-12-31 19:00:00.000000000 -0500
8700 +++ um/arch/um/drivers/ssl.h 2002-10-23 21:08:04.000000000 -0400
8703 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
8704 + * Licensed under the GPL
8710 +extern int ssl_read(int fd, int line);
8711 +extern void ssl_receive_char(int line, char ch);
8716 + * Overrides for Emacs so that we follow Linus's tabbing style.
8717 + * Emacs will notice this stuff at the end of the file and automatically
8718 + * adjust the settings for this buffer only. This must remain at the end
8720 + * ---------------------------------------------------------------------------
8721 + * Local variables:
8722 + * c-file-style: "linux"
8725 diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.c um/arch/um/drivers/stdio_console.c
8726 --- orig/arch/um/drivers/stdio_console.c 1969-12-31 19:00:00.000000000 -0500
8727 +++ um/arch/um/drivers/stdio_console.c 2002-12-15 21:08:20.000000000 -0500
8730 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
8731 + * Licensed under the GPL
8734 +#include "linux/config.h"
8735 +#include "linux/posix_types.h"
8736 +#include "linux/tty.h"
8737 +#include "linux/tty_flip.h"
8738 +#include "linux/types.h"
8739 +#include "linux/major.h"
8740 +#include "linux/kdev_t.h"
8741 +#include "linux/console.h"
8742 +#include "linux/string.h"
8743 +#include "linux/sched.h"
8744 +#include "linux/list.h"
8745 +#include "linux/init.h"
8746 +#include "linux/interrupt.h"
8747 +#include "linux/slab.h"
8748 +#include "asm/current.h"
8749 +#include "asm/softirq.h"
8750 +#include "asm/hardirq.h"
8751 +#include "asm/irq.h"
8752 +#include "stdio_console.h"
8754 +#include "chan_kern.h"
8755 +#include "user_util.h"
8756 +#include "kern_util.h"
8757 +#include "irq_user.h"
8758 +#include "mconsole_kern.h"
8760 +#include "2_5compat.h"
8762 +#define MAX_TTYS (8)
8764 +/* Referenced only by tty_driver below - presumably it's locked correctly
8765 + * by the tty driver.
8768 +static struct tty_driver console_driver;
8770 +static int console_refcount = 0;
8772 +static struct chan_ops init_console_ops = {
8773 + .type = "you shouldn't see this",
8779 + .console_write = generic_write,
8780 + .window_size = NULL,
8785 +static struct chan init_console_chan = {
8792 + .pri = INIT_STATIC,
8793 + .ops = &init_console_ops,
8797 +void stdio_announce(char *dev_name, int dev)
8799 + printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
8803 +static struct chan_opts opts = {
8804 + .announce = stdio_announce,
8805 + .xterm_title = "Virtual Console #%d",
8811 +static int con_config(char *str);
8812 +static int con_get_config(char *dev, char *str, int size, char **error_out);
8813 +static int con_remove(char *str);
8815 +static struct line_driver driver = {
8816 + .name = "UML console",
8817 + .devfs_name = "vc/%d",
8818 + .major = TTY_MAJOR,
8820 + .type = TTY_DRIVER_TYPE_CONSOLE,
8821 + .subtype = SYSTEM_TYPE_CONSOLE,
8822 + .read_irq = CONSOLE_IRQ,
8823 + .read_irq_name = "console",
8824 + .write_irq = CONSOLE_WRITE_IRQ,
8825 + .write_irq_name = "console-write",
8826 + .symlink_from = "ttys",
8827 + .symlink_to = "vc",
8830 + .config = con_config,
8831 + .get_config = con_get_config,
8832 + .remove = con_remove,
8836 +static struct lines console_lines = LINES_INIT(MAX_TTYS);
8838 +/* The array is initialized by line_init, which is an initcall. The
8839 + * individual elements are protected by individual semaphores.
8841 +struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
8842 + [ 1 ... MAX_TTYS - 1 ] =
8843 + LINE_INIT(CONFIG_CON_CHAN, &driver) };
8845 +static int con_config(char *str)
8847 + return(line_config(vts, sizeof(vts)/sizeof(vts[0]), str));
8850 +static int con_get_config(char *dev, char *str, int size, char **error_out)
8852 + return(line_get_config(dev, vts, sizeof(vts)/sizeof(vts[0]), str,
8853 + size, error_out));
8856 +static int con_remove(char *str)
8858 + return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str));
8861 +static int open_console(struct tty_struct *tty)
8863 + return(line_open(vts, tty, &opts));
8866 +static int con_open(struct tty_struct *tty, struct file *filp)
8868 + return(open_console(tty));
8871 +static void con_close(struct tty_struct *tty, struct file *filp)
8873 + line_close(vts, tty);
8876 +static int con_write(struct tty_struct *tty, int from_user,
8877 + const unsigned char *buf, int count)
8879 + return(line_write(vts, tty, from_user, buf, count));
8882 +static void set_termios(struct tty_struct *tty, struct termios * old)
8886 +static int chars_in_buffer(struct tty_struct *tty)
8891 +static int con_init_done = 0;
8893 +int stdio_init(void)
8897 + printk(KERN_INFO "Initializing stdio console driver\n");
8899 + line_register_devfs(&console_lines, &driver, &console_driver, vts,
8900 + sizeof(vts)/sizeof(vts[0]));
8902 + lines_init(vts, sizeof(vts)/sizeof(vts[0]));
8904 + new_title = add_xterm_umid(opts.xterm_title);
8905 + if(new_title != NULL) opts.xterm_title = new_title;
8907 + open_console(NULL);
8908 + con_init_done = 1;
8912 +__initcall(stdio_init);
8914 +static void console_write(struct console *console, const char *string,
8917 + if(con_init_done) down(&vts[console->index].sem);
8918 + console_write_chan(&vts[console->index].chan_list, string, len);
8919 + if(con_init_done) up(&vts[console->index].sem);
8922 +static struct tty_driver console_driver = {
8923 + .refcount = &console_refcount,
8925 + .close = con_close,
8926 + .write = con_write,
8927 + .chars_in_buffer = chars_in_buffer,
8928 + .set_termios = set_termios
8931 +static kdev_t console_device(struct console *c)
8933 + return mk_kdev(TTY_MAJOR, c->index);
8936 +static int console_setup(struct console *co, char *options)
8941 +static struct console stdiocons = INIT_CONSOLE("tty", console_write,
8942 + console_device, console_setup,
8945 +void stdio_console_init(void)
8947 + INIT_LIST_HEAD(&vts[0].chan_list);
8948 + list_add(&init_console_chan.list, &vts[0].chan_list);
8949 + register_console(&stdiocons);
8952 +static int console_chan_setup(char *str)
8954 + line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1);
8958 +__setup("con", console_chan_setup);
8959 +__channel_help(console_chan_setup, "con");
8961 +static void console_exit(void)
8963 + if(!con_init_done) return;
8964 + close_lines(vts, sizeof(vts)/sizeof(vts[0]));
8967 +__uml_exitcall(console_exit);
8970 + * Overrides for Emacs so that we follow Linus's tabbing style.
8971 + * Emacs will notice this stuff at the end of the file and automatically
8972 + * adjust the settings for this buffer only. This must remain at the end
8974 + * ---------------------------------------------------------------------------
8975 + * Local variables:
8976 + * c-file-style: "linux"
8979 diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.h um/arch/um/drivers/stdio_console.h
8980 --- orig/arch/um/drivers/stdio_console.h 1969-12-31 19:00:00.000000000 -0500
8981 +++ um/arch/um/drivers/stdio_console.h 2002-10-23 21:08:04.000000000 -0400
8984 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
8985 + * Licensed under the GPL
8988 +#ifndef __STDIO_CONSOLE_H
8989 +#define __STDIO_CONSOLE_H
8991 +extern void save_console_flags(void);
8995 + * Overrides for Emacs so that we follow Linus's tabbing style.
8996 + * Emacs will notice this stuff at the end of the file and automatically
8997 + * adjust the settings for this buffer only. This must remain at the end
8999 + * ---------------------------------------------------------------------------
9000 + * Local variables:
9001 + * c-file-style: "linux"
9004 diff -Naur -X ../exclude-files orig/arch/um/drivers/tty.c um/arch/um/drivers/tty.c
9005 --- orig/arch/um/drivers/tty.c 1969-12-31 19:00:00.000000000 -0500
9006 +++ um/arch/um/drivers/tty.c 2002-12-15 21:08:41.000000000 -0500
9009 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
9010 + * Licensed under the GPL
9014 +#include <termios.h>
9017 +#include <unistd.h>
9018 +#include "chan_user.h"
9019 +#include "user_util.h"
9026 + struct termios tt;
9029 +void *tty_chan_init(char *str, int device, struct chan_opts *opts)
9031 + struct tty_chan *data;
9034 + printk("tty_init : channel type 'tty' must specify "
9040 + if((data = um_kmalloc(sizeof(*data))) == NULL)
9042 + *data = ((struct tty_chan) { .dev = str,
9043 + .raw = opts->raw });
9048 +int tty_open(int input, int output, int primary, void *d, char **dev_out)
9050 + struct tty_chan *data = d;
9053 + fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0);
9054 + if(fd < 0) return(fd);
9056 + tcgetattr(fd, &data->tt);
9060 + *dev_out = data->dev;
9064 +int tty_console_write(int fd, const char *buf, int n, void *d)
9066 + struct tty_chan *data = d;
9068 + return(generic_console_write(fd, buf, n, &data->tt));
9071 +struct chan_ops tty_ops = {
9073 + .init = tty_chan_init,
9075 + .close = generic_close,
9076 + .read = generic_read,
9077 + .write = generic_write,
9078 + .console_write = tty_console_write,
9079 + .window_size = generic_window_size,
9080 + .free = generic_free,
9085 + * Overrides for Emacs so that we follow Linus's tabbing style.
9086 + * Emacs will notice this stuff at the end of the file and automatically
9087 + * adjust the settings for this buffer only. This must remain at the end
9089 + * ---------------------------------------------------------------------------
9090 + * Local variables:
9091 + * c-file-style: "linux"
9094 diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_kern.c um/arch/um/drivers/ubd_kern.c
9095 --- orig/arch/um/drivers/ubd_kern.c 1969-12-31 19:00:00.000000000 -0500
9096 +++ um/arch/um/drivers/ubd_kern.c 2003-03-11 15:46:36.000000000 -0500
9099 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9100 + * Licensed under the GPL
9103 +/* 2001-09-28...2002-04-17
9104 + * Partition stuff by James_McMechan@hotmail.com
9105 + * old style ubd by setting UBD_SHIFT to 0
9108 +#define MAJOR_NR UBD_MAJOR
9109 +#define UBD_SHIFT 4
9111 +#include "linux/config.h"
9112 +#include "linux/blk.h"
9113 +#include "linux/blkdev.h"
9114 +#include "linux/hdreg.h"
9115 +#include "linux/init.h"
9116 +#include "linux/devfs_fs_kernel.h"
9117 +#include "linux/cdrom.h"
9118 +#include "linux/proc_fs.h"
9119 +#include "linux/ctype.h"
9120 +#include "linux/capability.h"
9121 +#include "linux/mm.h"
9122 +#include "linux/vmalloc.h"
9123 +#include "linux/blkpg.h"
9124 +#include "linux/genhd.h"
9125 +#include "linux/spinlock.h"
9126 +#include "asm/segment.h"
9127 +#include "asm/uaccess.h"
9128 +#include "asm/irq.h"
9129 +#include "asm/types.h"
9130 +#include "user_util.h"
9131 +#include "mem_user.h"
9132 +#include "kern_util.h"
9134 +#include "mconsole_kern.h"
9136 +#include "irq_user.h"
9137 +#include "ubd_user.h"
9138 +#include "2_5compat.h"
9141 +static int ubd_open(struct inode * inode, struct file * filp);
9142 +static int ubd_release(struct inode * inode, struct file * file);
9143 +static int ubd_ioctl(struct inode * inode, struct file * file,
9144 + unsigned int cmd, unsigned long arg);
9145 +static int ubd_revalidate(kdev_t rdev);
9146 +static int ubd_revalidate1(kdev_t rdev);
9148 +#define MAX_DEV (8)
9149 +#define MAX_MINOR (MAX_DEV << UBD_SHIFT)
9151 +/* Not modified by this driver */
9152 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
9153 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
9155 +/* Protected by ubd_lock */
9156 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
9158 +static struct block_device_operations ubd_blops = {
9160 + .release = ubd_release,
9161 + .ioctl = ubd_ioctl,
9162 + .revalidate = ubd_revalidate,
9165 +/* Protected by ubd_lock, except in prepare_request and ubd_ioctl because
9166 + * the block layer should ensure that the device is idle before closing it.
9168 +static struct hd_struct ubd_part[MAX_MINOR] =
9169 + { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
9171 +/* Protected by io_request_lock */
9172 +static request_queue_t *ubd_queue;
9174 +/* Protected by ubd_lock */
9175 +static int fake_major = MAJOR_NR;
9177 +static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
9179 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
9182 + .major_name = name, \
9183 + .minor_shift = shift, \
9184 + .max_p = 1 << shift, \
9186 + .sizes = bsizes, \
9188 + .real_devices = NULL, \
9195 +static struct gendisk ubd_gendisk = INIT_GENDISK(MAJOR_NR, "ubd", ubd_part,
9196 + UBD_SHIFT, sizes, MAX_DEV,
9198 +static struct gendisk fake_gendisk = INIT_GENDISK(0, "ubd", ubd_part,
9199 + UBD_SHIFT, sizes, MAX_DEV,
9202 +#ifdef CONFIG_BLK_DEV_UBD_SYNC
9203 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
9206 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \
9210 +/* Not protected - changed only in ubd_setup_common and then only to
9211 + * to enable O_SYNC.
9213 +static struct openflags global_openflags = OPEN_FLAGS;
9218 + unsigned long *bitmap;
9219 + unsigned long bitmap_len;
9220 + int bitmap_offset;
9229 + struct openflags boot_openflags;
9230 + struct openflags openflags;
9231 + devfs_handle_t devfs;
9235 +#define DEFAULT_COW { \
9239 + .bitmap_offset = 0, \
9240 + .data_offset = 0, \
9243 +#define DEFAULT_UBD { \
9248 + .boot_openflags = OPEN_FLAGS, \
9249 + .openflags = OPEN_FLAGS, \
9251 + .cow = DEFAULT_COW, \
9254 +struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
9256 +static int ubd0_init(void)
9258 + struct ubd *dev = &ubd_dev[0];
9260 + if(dev->file == NULL)
9261 + dev->file = "root_fs";
9265 +__initcall(ubd0_init);
9267 +/* Only changed by fake_ide_setup which is a setup */
9268 +static int fake_ide = 0;
9269 +static struct proc_dir_entry *proc_ide_root = NULL;
9270 +static struct proc_dir_entry *proc_ide = NULL;
9272 +static void make_proc_ide(void)
9274 + proc_ide_root = proc_mkdir("ide", 0);
9275 + proc_ide = proc_mkdir("ide0", proc_ide_root);
9278 +static int proc_ide_read_media(char *page, char **start, off_t off, int count,
9279 + int *eof, void *data)
9283 + strcpy(page, "disk\n");
9284 + len = strlen("disk\n");
9288 + if (len <= 0) return 0;
9291 + *start = page + off;
9295 +static void make_ide_entries(char *dev_name)
9297 + struct proc_dir_entry *dir, *ent;
9300 + if(!fake_ide) return;
9302 + /* Without locking this could race if a UML was booted with no
9303 + * disks and then two mconsole requests which add disks came in
9304 + * at the same time.
9306 + spin_lock(&ubd_lock);
9307 + if(proc_ide_root == NULL) make_proc_ide();
9308 + spin_unlock(&ubd_lock);
9310 + dir = proc_mkdir(dev_name, proc_ide);
9313 + ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir);
9317 + ent->read_proc = proc_ide_read_media;
9318 + ent->write_proc = NULL;
9319 + sprintf(name,"ide0/%s", dev_name);
9320 + proc_symlink(dev_name, proc_ide_root, name);
9323 +static int fake_ide_setup(char *str)
9329 +__setup("fake_ide", fake_ide_setup);
9331 +__uml_help(fake_ide_setup,
9333 +" Create ide0 entries that map onto ubd devices.\n\n"
9336 +static int parse_unit(char **ptr)
9338 + char *str = *ptr, *end;
9341 + if(isdigit(*str)) {
9342 + n = simple_strtoul(str, &end, 0);
9347 + else if (('a' <= *str) && (*str <= 'h')) {
9355 +static int ubd_setup_common(char *str, int *index_out)
9357 + struct openflags flags = global_openflags;
9359 + char *backing_file;
9362 + if(index_out) *index_out = -1;
9369 + if(!strcmp(str, "sync")){
9370 + global_openflags.s = 1;
9373 + major = simple_strtoul(str, &end, 0);
9374 + if((*end != '\0') || (end == str)){
9376 + "ubd_setup : didn't parse major number\n");
9381 + spin_lock(&ubd_lock);
9382 + if(fake_major != MAJOR_NR){
9383 + printk(KERN_ERR "Can't assign a fake major twice\n");
9387 + fake_gendisk.major = major;
9388 + fake_major = major;
9390 + printk(KERN_INFO "Setting extra ubd major number to %d\n",
9394 + spin_unlock(&ubd_lock);
9398 + n = parse_unit(&str);
9400 + printk(KERN_ERR "ubd_setup : couldn't parse unit number "
9406 + printk(KERN_ERR "ubd_setup : index %d out of range "
9407 + "(%d devices)\n", n, MAX_DEV);
9412 + spin_lock(&ubd_lock);
9414 + dev = &ubd_dev[n];
9415 + if(dev->file != NULL){
9416 + printk(KERN_ERR "ubd_setup : device already configured\n");
9420 + if(index_out) *index_out = n;
9430 + if(*str++ != '='){
9431 + printk(KERN_ERR "ubd_setup : Expected '='\n");
9436 + backing_file = strchr(str, ',');
9438 + *backing_file = '\0';
9442 + dev->cow.file = backing_file;
9443 + dev->boot_openflags = flags;
9445 + spin_unlock(&ubd_lock);
9449 +static int ubd_setup(char *str)
9451 + ubd_setup_common(str, NULL);
9455 +__setup("ubd", ubd_setup);
9456 +__uml_help(ubd_setup,
9457 +"ubd<n>=<filename>\n"
9458 +" This is used to associate a device with a file in the underlying\n"
9459 +" filesystem. Usually, there is a filesystem in the file, but \n"
9460 +" that's not required. Swap devices containing swap files can be\n"
9461 +" specified like this. Also, a file which doesn't contain a\n"
9462 +" filesystem can have its contents read in the virtual \n"
9463 +" machine by running dd on the device. n must be in the range\n"
9464 +" 0 to 7. Appending an 'r' to the number will cause that device\n"
9465 +" to be mounted read-only. For example ubd1r=./ext_fs. Appending\n"
9466 +" an 's' (has to be _after_ 'r', if there is one) will cause data\n"
9467 +" to be written to disk on the host immediately.\n\n"
9470 +static int fakehd(char *str)
9473 + "fakehd : Changing ubd_gendisk.major_name to \"hd\".\n");
9474 + ubd_gendisk.major_name = "hd";
9478 +__setup("fakehd", fakehd);
9481 +" Change the ubd device name to \"hd\".\n\n"
9484 +static void do_ubd_request(request_queue_t * q);
9486 +/* Only changed by ubd_init, which is an initcall. */
9487 +int thread_fd = -1;
9489 +/* Changed by ubd_handler, which is serialized because interrupts only
9490 + * happen on CPU 0.
9492 +int intr_count = 0;
9494 +static void ubd_finish(int error)
9502 + nsect = CURRENT->current_nr_sectors;
9503 + CURRENT->sector += nsect;
9504 + CURRENT->buffer += nsect << 9;
9505 + CURRENT->errors = 0;
9506 + CURRENT->nr_sectors -= nsect;
9507 + CURRENT->current_nr_sectors = 0;
9511 +static void ubd_handler(void)
9513 + struct io_thread_req req;
9516 + DEVICE_INTR = NULL;
9518 + n = read_ubd_fs(thread_fd, &req, sizeof(req));
9519 + if(n != sizeof(req)){
9520 + printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
9521 + "errno = %d\n", os_getpid(), -n);
9522 + spin_lock(&io_request_lock);
9524 + spin_unlock(&io_request_lock);
9528 + if((req.offset != ((__u64) (CURRENT->sector)) << 9) ||
9529 + (req.length != (CURRENT->current_nr_sectors) << 9))
9530 + panic("I/O op mismatch");
9532 + spin_lock(&io_request_lock);
9533 + ubd_finish(req.error);
9534 + reactivate_fd(thread_fd, UBD_IRQ);
9535 + do_ubd_request(ubd_queue);
9536 + spin_unlock(&io_request_lock);
9539 +static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
9544 +/* Only changed by ubd_init, which is an initcall. */
9545 +static int io_pid = -1;
9547 +void kill_io_thread(void)
9550 + os_kill_process(io_pid, 1);
9553 +__uml_exitcall(kill_io_thread);
9555 +/* Initialized in an initcall, and unchanged thereafter */
9556 +devfs_handle_t ubd_dir_handle;
9558 +static int ubd_add(int n)
9560 + struct ubd *dev = &ubd_dev[n];
9561 + char name[sizeof("nnnnnn\0")], dev_name[sizeof("ubd0x")];
9562 + int err = -EISDIR;
9564 + if(dev->file == NULL)
9567 + err = ubd_revalidate1(MKDEV(MAJOR_NR, n << UBD_SHIFT));
9571 + sprintf(name, "%d", n);
9572 + dev->devfs = devfs_register(ubd_dir_handle, name, DEVFS_FL_REMOVABLE,
9573 + MAJOR_NR, n << UBD_SHIFT, S_IFBLK |
9574 + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
9575 + &ubd_blops, NULL);
9577 + if(!strcmp(ubd_gendisk.major_name, "ubd"))
9578 + sprintf(dev_name, "%s%d", ubd_gendisk.major_name, n);
9579 + else sprintf(dev_name, "%s%c", ubd_gendisk.major_name,
9582 + make_ide_entries(dev_name);
9589 +static int ubd_config(char *str)
9593 + str = uml_strdup(str);
9595 + printk(KERN_ERR "ubd_config failed to strdup string\n");
9598 + err = ubd_setup_common(str, &n);
9603 + if(n == -1) return(0);
9605 + spin_lock(&ubd_lock);
9608 + ubd_dev[n].file = NULL;
9609 + spin_unlock(&ubd_lock);
9614 +static int ubd_get_config(char *name, char *str, int size, char **error_out)
9620 + n = simple_strtoul(name, &end, 0);
9621 + if((*end != '\0') || (end == name)){
9622 + *error_out = "ubd_get_config : didn't parse device number";
9626 + if((n >= MAX_DEV) || (n < 0)){
9627 + *error_out = "ubd_get_config : device number out of range";
9631 + dev = &ubd_dev[n];
9632 + spin_lock(&ubd_lock);
9634 + if(dev->file == NULL){
9635 + CONFIG_CHUNK(str, size, len, "", 1);
9639 + CONFIG_CHUNK(str, size, len, dev->file, 0);
9641 + if(dev->cow.file != NULL){
9642 + CONFIG_CHUNK(str, size, len, ",", 0);
9643 + CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
9645 + else CONFIG_CHUNK(str, size, len, "", 1);
9648 + spin_unlock(&ubd_lock);
9652 +static int ubd_remove(char *str)
9655 + int n, err = -ENODEV;
9657 + if(isdigit(*str)){
9659 + n = simple_strtoul(str, &end, 0);
9660 + if ((*end != '\0') || (end == str))
9663 + else if (('a' <= *str) && (*str <= 'h'))
9666 + return(err); /* it should be a number 0-7/a-h */
9668 + if((n < 0) || (n >= MAX_DEV))
9671 + dev = &ubd_dev[n];
9673 + spin_lock(&ubd_lock);
9675 + if(dev->file == NULL)
9678 + if(dev->count > 0)
9680 + if(dev->devfs != NULL)
9681 + devfs_unregister(dev->devfs);
9683 + *dev = ((struct ubd) DEFAULT_UBD);
9686 + spin_unlock(&ubd_lock);
9690 +static struct mc_device ubd_mc = {
9692 + .config = ubd_config,
9693 + .get_config = ubd_get_config,
9694 + .remove = ubd_remove,
9697 +static int ubd_mc_init(void)
9699 + mconsole_register_dev(&ubd_mc);
9703 +__initcall(ubd_mc_init);
9705 +static request_queue_t *ubd_get_queue(kdev_t device)
9707 + return(ubd_queue);
9712 + unsigned long stack;
9715 + ubd_dir_handle = devfs_mk_dir (NULL, "ubd", NULL);
9716 + if (devfs_register_blkdev(MAJOR_NR, "ubd", &ubd_blops)) {
9717 + printk(KERN_ERR "ubd: unable to get major %d\n", MAJOR_NR);
9720 + read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */
9721 + blksize_size[MAJOR_NR] = blk_sizes;
9722 + blk_size[MAJOR_NR] = sizes;
9723 + INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
9725 + ubd_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
9726 + blk_init_queue(ubd_queue, DEVICE_REQUEST);
9727 + INIT_ELV(ubd_queue, &ubd_queue->elevator);
9729 + add_gendisk(&ubd_gendisk);
9730 + if (fake_major != MAJOR_NR){
9731 + /* major number 0 is used to auto select */
9732 + err = devfs_register_blkdev(fake_major, "fake", &ubd_blops);
9733 + if(fake_major == 0){
9734 + /* auto device number case */
9740 + /* not auto so normal error */
9741 + printk(KERN_ERR "ubd: error %d getting major %d\n",
9746 + blk_dev[fake_major].queue = ubd_get_queue;
9747 + read_ahead[fake_major] = 8; /* 8 sector (4kB) read-ahead */
9748 + blksize_size[fake_major] = blk_sizes;
9749 + blk_size[fake_major] = sizes;
9750 + INIT_HARDSECT(hardsect_size, fake_major, hardsect_sizes);
9751 + add_gendisk(&fake_gendisk);
9754 + for(i=0;i<MAX_DEV;i++)
9757 + if(global_openflags.s){
9758 + printk(KERN_INFO "ubd : Synchronous mode\n");
9761 + stack = alloc_stack(0, 0);
9762 + io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
9766 + "ubd : Failed to start I/O thread (errno = %d) - "
9767 + "falling back to synchronous I/O\n", -io_pid);
9770 + err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
9771 + SA_INTERRUPT, "ubd", ubd_dev);
9772 + if(err != 0) printk(KERN_ERR
9773 + "um_request_irq failed - errno = %d\n", -err);
9777 +__initcall(ubd_init);
9779 +static void ubd_close(struct ubd *dev)
9781 + os_close_file(dev->fd);
9782 + if(dev->cow.file != NULL) {
9783 + os_close_file(dev->cow.fd);
9784 + vfree(dev->cow.bitmap);
9785 + dev->cow.bitmap = NULL;
9789 +static int ubd_open_dev(struct ubd *dev)
9791 + struct openflags flags;
9792 + int err, create_cow, *create_ptr;
9794 + dev->openflags = dev->boot_openflags;
9796 + create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
9797 + dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
9798 + &dev->cow.bitmap_offset, &dev->cow.bitmap_len,
9799 + &dev->cow.data_offset, create_ptr);
9801 + if((dev->fd == -ENOENT) && create_cow){
9802 + dev->fd = create_cow_file(dev->file, dev->cow.file,
9803 + dev->openflags, 1 << 9,
9804 + &dev->cow.bitmap_offset,
9805 + &dev->cow.bitmap_len,
9806 + &dev->cow.data_offset);
9808 + printk(KERN_INFO "Creating \"%s\" as COW file for "
9809 + "\"%s\"\n", dev->file, dev->cow.file);
9813 + if(dev->fd < 0) return(dev->fd);
9815 + if(dev->cow.file != NULL){
9817 + dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
9818 + if(dev->cow.bitmap == NULL) goto error;
9819 + flush_tlb_kernel_vm();
9821 + err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
9822 + dev->cow.bitmap_offset,
9823 + dev->cow.bitmap_len);
9824 + if(err) goto error;
9826 + flags = dev->openflags;
9828 + err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL,
9830 + if(err < 0) goto error;
9831 + dev->cow.fd = err;
9835 + os_close_file(dev->fd);
9839 +static int ubd_file_size(struct ubd *dev, __u64 *size_out)
9843 + file = dev->cow.file ? dev->cow.file : dev->file;
9844 + return(os_file_size(file, size_out));
9847 +static int ubd_open(struct inode *inode, struct file *filp)
9850 + int n, offset, err = 0;
9852 + n = DEVICE_NR(inode->i_rdev);
9853 + dev = &ubd_dev[n];
9857 + spin_lock(&ubd_lock);
9858 + offset = n << UBD_SHIFT;
9860 + if(dev->count == 0){
9861 + err = ubd_open_dev(dev);
9863 + printk(KERN_ERR "ubd%d: Can't open \"%s\": "
9864 + "errno = %d\n", n, dev->file, -err);
9867 + err = ubd_file_size(dev, &dev->size);
9870 + sizes[offset] = dev->size / BLOCK_SIZE;
9871 + ubd_part[offset].nr_sects = dev->size / hardsect_sizes[offset];
9874 + if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
9875 + if(--dev->count == 0) ubd_close(dev);
9879 + spin_unlock(&ubd_lock);
9883 +static int ubd_release(struct inode * inode, struct file * file)
9887 + n = DEVICE_NR(inode->i_rdev);
9888 + offset = n << UBD_SHIFT;
9892 + spin_lock(&ubd_lock);
9893 + if(--ubd_dev[n].count == 0)
9894 + ubd_close(&ubd_dev[n]);
9895 + spin_unlock(&ubd_lock);
9900 +void cowify_req(struct io_thread_req *req, struct ubd *dev)
9902 + int i, update_bitmap, sector = req->offset >> 9;
9904 + if(req->length > (sizeof(req->sector_mask) * 8) << 9)
9905 + panic("Operation too long");
9906 + if(req->op == UBD_READ) {
9907 + for(i = 0; i < req->length >> 9; i++){
9908 + if(ubd_test_bit(sector + i, (unsigned char *)
9909 + dev->cow.bitmap)){
9910 + ubd_set_bit(i, (unsigned char *)
9911 + &req->sector_mask);
9916 + update_bitmap = 0;
9917 + for(i = 0; i < req->length >> 9; i++){
9918 + ubd_set_bit(i, (unsigned char *)
9919 + &req->sector_mask);
9920 + if(!ubd_test_bit(sector + i, (unsigned char *)
9922 + update_bitmap = 1;
9923 + ubd_set_bit(sector + i, (unsigned char *)
9926 + if(update_bitmap){
9927 + req->cow_offset = sector / (sizeof(unsigned long) * 8);
9928 + req->bitmap_words[0] =
9929 + dev->cow.bitmap[req->cow_offset];
9930 + req->bitmap_words[1] =
9931 + dev->cow.bitmap[req->cow_offset + 1];
9932 + req->cow_offset *= sizeof(unsigned long);
9933 + req->cow_offset += dev->cow.bitmap_offset;
9938 +static int prepare_request(struct request *req, struct io_thread_req *io_req)
9942 + int nsect, minor, n;
9944 + if(req->rq_status == RQ_INACTIVE) return(1);
9946 + minor = MINOR(req->rq_dev);
9947 + n = minor >> UBD_SHIFT;
9948 + dev = &ubd_dev[n];
9949 + if(IS_WRITE(req) && !dev->openflags.w){
9950 + printk("Write attempted on readonly ubd device %d\n", n);
9955 + req->sector += ubd_part[minor].start_sect;
9956 + block = req->sector;
9957 + nsect = req->current_nr_sectors;
9959 + io_req->op = (req->cmd == READ) ? UBD_READ : UBD_WRITE;
9960 + io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
9961 + io_req->fds[1] = dev->fd;
9962 + io_req->offsets[0] = 0;
9963 + io_req->offsets[1] = dev->cow.data_offset;
9964 + io_req->offset = ((__u64) block) << 9;
9965 + io_req->length = nsect << 9;
9966 + io_req->buffer = req->buffer;
9967 + io_req->sectorsize = 1 << 9;
9968 + io_req->sector_mask = 0;
9969 + io_req->cow_offset = -1;
9970 + io_req->error = 0;
9972 + if(dev->cow.file != NULL) cowify_req(io_req, dev);
9976 +static void do_ubd_request(request_queue_t *q)
9978 + struct io_thread_req io_req;
9979 + struct request *req;
9982 + if(thread_fd == -1){
9983 + while(!list_empty(&q->queue_head)){
9984 + req = blkdev_entry_next_request(&q->queue_head);
9985 + err = prepare_request(req, &io_req);
9988 + ubd_finish(io_req.error);
9993 + if(DEVICE_INTR || list_empty(&q->queue_head)) return;
9994 + req = blkdev_entry_next_request(&q->queue_head);
9995 + err = prepare_request(req, &io_req);
9997 + SET_INTR(ubd_handler);
9998 + n = write_ubd_fs(thread_fd, (char *) &io_req,
10000 + if(n != sizeof(io_req))
10001 + printk("write to io thread failed, "
10002 + "errno = %d\n", -n);
10007 +static int ubd_ioctl(struct inode * inode, struct file * file,
10008 + unsigned int cmd, unsigned long arg)
10010 + struct hd_geometry *loc = (struct hd_geometry *) arg;
10012 + int n, minor, err;
10013 + struct hd_driveid ubd_id = {
10019 + if(!inode) return(-EINVAL);
10020 + minor = MINOR(inode->i_rdev);
10021 + n = minor >> UBD_SHIFT;
10024 + dev = &ubd_dev[n];
10026 + struct hd_geometry g;
10027 + struct cdrom_volctrl volume;
10028 + case HDIO_GETGEO:
10029 + if(!loc) return(-EINVAL);
10032 + g.cylinders = dev->size / (128 * 32 * hardsect_sizes[minor]);
10034 + return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
10035 + case BLKGETSIZE: /* Return device size */
10036 + if(!arg) return(-EINVAL);
10037 + err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
10040 + put_user(ubd_part[minor].nr_sects, (long *) arg);
10042 + case BLKRRPART: /* Re-read partition tables */
10043 + return(ubd_revalidate(inode->i_rdev));
10045 + case HDIO_SET_UNMASKINTR:
10046 + if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
10047 + if((arg > 1) || (minor & 0x3F)) return(-EINVAL);
10050 + case HDIO_GET_UNMASKINTR:
10051 + if(!arg) return(-EINVAL);
10052 + err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
10057 + case HDIO_GET_MULTCOUNT:
10058 + if(!arg) return(-EINVAL);
10059 + err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
10064 + case HDIO_SET_MULTCOUNT:
10065 + if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
10066 + if(MINOR(inode->i_rdev) & 0x3F) return(-EINVAL);
10069 + case HDIO_GET_IDENTITY:
10070 + ubd_id.cyls = dev->size / (128 * 32 * hardsect_sizes[minor]);
10071 + if(copy_to_user((char *) arg, (char *) &ubd_id,
10076 + case CDROMVOLREAD:
10077 + if(copy_from_user(&volume, (char *) arg, sizeof(volume)))
10079 + volume.channel0 = 255;
10080 + volume.channel1 = 255;
10081 + volume.channel2 = 255;
10082 + volume.channel3 = 255;
10083 + if(copy_to_user((char *) arg, &volume, sizeof(volume)))
10088 + return blk_ioctl(inode->i_rdev, cmd, arg);
10092 +static int ubd_revalidate1(kdev_t rdev)
10094 + int i, n, offset, err = 0, pcount = 1 << UBD_SHIFT;
10096 + struct hd_struct *part;
10098 + n = DEVICE_NR(rdev);
10099 + offset = n << UBD_SHIFT;
10100 + dev = &ubd_dev[n];
10102 + part = &ubd_part[offset];
10104 + /* clear all old partition counts */
10105 + for(i = 1; i < pcount; i++) {
10106 + part[i].start_sect = 0;
10107 + part[i].nr_sects = 0;
10110 + /* If it already has been opened we can check the partitions
10114 + part->start_sect = 0;
10115 + register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount,
10116 + &ubd_blops, part->nr_sects);
10118 + else if(dev->file){
10119 + err = ubd_open_dev(dev);
10121 + printk(KERN_ERR "unable to open %s for validation\n",
10126 + /* have to recompute sizes since we opened it */
10127 + err = ubd_file_size(dev, &dev->size);
10132 + part->start_sect = 0;
10133 + part->nr_sects = dev->size / hardsect_sizes[offset];
10134 + register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount,
10135 + &ubd_blops, part->nr_sects);
10137 + /* we are done so close it */
10140 + else err = -ENODEV;
10145 +static int ubd_revalidate(kdev_t rdev)
10149 + spin_lock(&ubd_lock);
10150 + err = ubd_revalidate1(rdev);
10151 + spin_unlock(&ubd_lock);
10156 + * Overrides for Emacs so that we follow Linus's tabbing style.
10157 + * Emacs will notice this stuff at the end of the file and automatically
10158 + * adjust the settings for this buffer only. This must remain at the end
10160 + * ---------------------------------------------------------------------------
10161 + * Local variables:
10162 + * c-file-style: "linux"
10165 diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_user.c um/arch/um/drivers/ubd_user.c
10166 --- orig/arch/um/drivers/ubd_user.c 1969-12-31 19:00:00.000000000 -0500
10167 +++ um/arch/um/drivers/ubd_user.c 2003-06-05 14:39:22.000000000 -0400
10170 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
10171 + * Copyright (C) 2001 Ridgerun,Inc (glonnon@ridgerun.com)
10172 + * Licensed under the GPL
10175 +#include <stddef.h>
10176 +#include <unistd.h>
10177 +#include <errno.h>
10178 +#include <sched.h>
10179 +#include <signal.h>
10180 +#include <string.h>
10181 +#include <netinet/in.h>
10182 +#include <sys/stat.h>
10183 +#include <sys/time.h>
10184 +#include <sys/fcntl.h>
10185 +#include <sys/socket.h>
10186 +#include <string.h>
10187 +#include <sys/mman.h>
10188 +#include <sys/param.h>
10189 +#include "asm/types.h"
10190 +#include "user_util.h"
10191 +#include "kern_util.h"
10193 +#include "ubd_user.h"
10197 +#include <endian.h>
10198 +#include <byteswap.h>
10200 +static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
10202 + struct stat64 buf1, buf2;
10204 + if(from_cmdline == NULL) return(1);
10205 + if(!strcmp(from_cmdline, from_cow)) return(1);
10207 + if(stat64(from_cmdline, &buf1) < 0){
10208 + printk("Couldn't stat '%s', errno = %d\n", from_cmdline,
10212 + if(stat64(from_cow, &buf2) < 0){
10213 + printk("Couldn't stat '%s', errno = %d\n", from_cow, errno);
10216 + if((buf1.st_dev == buf2.st_dev) && (buf1.st_ino == buf2.st_ino))
10219 + printk("Backing file mismatch - \"%s\" requested,\n"
10220 + "\"%s\" specified in COW header of \"%s\"\n",
10221 + from_cmdline, from_cow, cow);
10225 +static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
10227 + struct stat64 buf;
10228 + long long actual;
10231 + printk("%ld", htonll(size));
10232 + if(stat64(file, &buf) < 0){
10233 + printk("Failed to stat backing file \"%s\", errno = %d\n",
10238 + err = os_file_size(file, &actual);
10240 + printk("Failed to get size of backing file \"%s\", "
10241 + "errno = %d\n", file, -err);
10245 + if(actual != size){
10246 + printk("Size mismatch (%ld vs %ld) of COW header vs backing "
10247 + "file\n", size, actual);
10250 + if(buf.st_mtime != mtime){
10251 + printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
10252 + "file\n", mtime, buf.st_mtime);
10258 +int read_cow_bitmap(int fd, void *buf, int offset, int len)
10262 + err = os_seek_file(fd, offset);
10263 + if(err != 0) return(-errno);
10264 + err = read(fd, buf, len);
10265 + if(err < 0) return(-errno);
10269 +int open_ubd_file(char *file, struct openflags *openflags,
10270 + char **backing_file_out, int *bitmap_offset_out,
10271 + unsigned long *bitmap_len_out, int *data_offset_out,
10272 + int *create_cow_out)
10276 + char *backing_file;
10277 + int fd, err, sectorsize, magic, same, mode = 0644;
10279 + if((fd = os_open_file(file, *openflags, mode)) < 0){
10280 + if((fd == -ENOENT) && (create_cow_out != NULL))
10281 + *create_cow_out = 1;
10282 + if(!openflags->w ||
10283 + ((errno != EROFS) && (errno != EACCES))) return(-errno);
10284 + openflags->w = 0;
10285 + if((fd = os_open_file(file, *openflags, mode)) < 0)
10289 + err = os_lock_file(fd, openflags->w);
10291 + printk("Failed to lock '%s', errno = %d\n", file, -err);
10295 + if(backing_file_out == NULL) return(fd);
10297 + err = read_cow_header(fd, &magic, &backing_file, &mtime, &size,
10298 + §orsize, bitmap_offset_out);
10299 + if(err && (*backing_file_out != NULL)){
10300 + printk("Failed to read COW header from COW file \"%s\", "
10301 + "errno = %d\n", file, err);
10304 + if(err) return(fd);
10306 + if(backing_file_out == NULL) return(fd);
10308 + same = same_backing_files(*backing_file_out, backing_file, file);
10310 + if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
10311 + printk("Switching backing file to '%s'\n", *backing_file_out);
10312 + err = write_cow_header(file, fd, *backing_file_out,
10313 + sectorsize, &size);
10315 + printk("Switch failed, errno = %d\n", err);
10320 + *backing_file_out = backing_file;
10321 + err = backing_file_mismatch(*backing_file_out, size, mtime);
10322 + if(err) goto error;
10325 + cow_sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out,
10326 + data_offset_out);
10330 + os_close_file(fd);
10334 +int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
10335 + int sectorsize, int *bitmap_offset_out,
10336 + unsigned long *bitmap_len_out, int *data_offset_out)
10341 + fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
10344 + printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
10349 + err = init_cow_file(fd, cow_file, backing_file, sectorsize,
10350 + bitmap_offset_out, bitmap_len_out,
10351 + data_offset_out);
10355 + os_close_file(fd);
10360 +int read_ubd_fs(int fd, void *buffer, int len)
10364 + n = read(fd, buffer, len);
10365 + if(n < 0) return(-errno);
10369 +int write_ubd_fs(int fd, char *buffer, int len)
10373 + n = write(fd, buffer, len);
10374 + if(n < 0) return(-errno);
10378 +void do_io(struct io_thread_req *req)
10381 + unsigned long len;
10382 + int n, nsectors, start, end, bit;
10385 + nsectors = req->length / req->sectorsize;
10388 + bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
10390 + while((end < nsectors) &&
10391 + (ubd_test_bit(end, (unsigned char *)
10392 + &req->sector_mask) == bit))
10395 + if(end != nsectors)
10396 + printk("end != nsectors\n");
10397 + off = req->offset + req->offsets[bit] +
10398 + start * req->sectorsize;
10399 + len = (end - start) * req->sectorsize;
10400 + buf = &req->buffer[start * req->sectorsize];
10402 + if(os_seek_file(req->fds[bit], off) != 0){
10403 + printk("do_io - lseek failed : errno = %d\n", errno);
10407 + if(req->op == UBD_READ){
10412 + n = read(req->fds[bit], buf, len);
10414 + printk("do_io - read returned %d : "
10415 + "errno = %d fd = %d\n", n,
10416 + errno, req->fds[bit]);
10420 + } while((n < len) && (n != 0));
10421 + if (n < len) memset(&buf[n], 0, len - n);
10424 + n = write(req->fds[bit], buf, len);
10426 + printk("do_io - write returned %d : "
10427 + "errno = %d fd = %d\n", n,
10428 + errno, req->fds[bit]);
10435 + } while(start < nsectors);
10437 + if(req->cow_offset != -1){
10438 + if(os_seek_file(req->fds[1], req->cow_offset) != 0){
10439 + printk("do_io - bitmap lseek failed : errno = %d\n",
10444 + n = write(req->fds[1], &req->bitmap_words,
10445 + sizeof(req->bitmap_words));
10446 + if(n != sizeof(req->bitmap_words)){
10447 + printk("do_io - bitmap update returned %d : "
10448 + "errno = %d fd = %d\n", n, errno, req->fds[1]);
10457 +/* Changed in start_io_thread, which is serialized by being called only
10458 + * from ubd_init, which is an initcall.
10460 +int kernel_fd = -1;
10462 +/* Only changed by the io thread */
10465 +int io_thread(void *arg)
10467 + struct io_thread_req req;
10470 + signal(SIGWINCH, SIG_IGN);
10472 + n = read(kernel_fd, &req, sizeof(req));
10473 + if(n < 0) printk("io_thread - read returned %d, errno = %d\n",
10475 + else if(n < sizeof(req)){
10476 + printk("io_thread - short read : length = %d\n", n);
10481 + n = write(kernel_fd, &req, sizeof(req));
10482 + if(n != sizeof(req))
10483 + printk("io_thread - write failed, errno = %d\n",
10488 +int start_io_thread(unsigned long sp, int *fd_out)
10490 + int pid, fds[2], err;
10492 + err = os_pipe(fds, 1, 1);
10494 + printk("start_io_thread - os_pipe failed, errno = %d\n", -err);
10497 + kernel_fd = fds[0];
10498 + *fd_out = fds[1];
10500 + pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
10503 + printk("start_io_thread - clone failed : errno = %d\n", errno);
10510 +int start_io_thread(unsigned long sp, int *fd_out)
10514 + if((kernel_fd = get_pty()) < 0) return(-1);
10515 + raw(kernel_fd, 0);
10516 + if((*fd_out = open(ptsname(kernel_fd), O_RDWR)) < 0){
10517 + printk("Couldn't open tty for IO\n");
10521 + pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
10524 + printk("start_io_thread - clone failed : errno = %d\n", errno);
10532 + * Overrides for Emacs so that we follow Linus's tabbing style.
10533 + * Emacs will notice this stuff at the end of the file and automatically
10534 + * adjust the settings for this buffer only. This must remain at the end
10536 + * ---------------------------------------------------------------------------
10537 + * Local variables:
10538 + * c-file-style: "linux"
10541 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.c um/arch/um/drivers/xterm.c
10542 --- orig/arch/um/drivers/xterm.c 1969-12-31 19:00:00.000000000 -0500
10543 +++ um/arch/um/drivers/xterm.c 2002-12-30 20:49:22.000000000 -0500
10546 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
10547 + * Licensed under the GPL
10550 +#include <stdio.h>
10551 +#include <stdlib.h>
10552 +#include <unistd.h>
10553 +#include <string.h>
10554 +#include <errno.h>
10555 +#include <fcntl.h>
10556 +#include <termios.h>
10557 +#include <signal.h>
10558 +#include <sched.h>
10559 +#include <sys/socket.h>
10560 +#include "kern_util.h"
10561 +#include "chan_user.h"
10562 +#include "helper.h"
10563 +#include "user_util.h"
10566 +#include "xterm.h"
10568 +struct xterm_chan {
10574 + struct termios tt;
10575 + unsigned long stack;
10579 +void *xterm_init(char *str, int device, struct chan_opts *opts)
10581 + struct xterm_chan *data;
10583 + if((data = malloc(sizeof(*data))) == NULL) return(NULL);
10584 + *data = ((struct xterm_chan) { .pid = -1,
10585 + .helper_pid = -1,
10586 + .device = device,
10587 + .title = opts->xterm_title,
10588 + .raw = opts->raw,
10589 + .stack = opts->tramp_stack,
10590 + .direct_rcv = !opts->in_kernel } );
10594 +/* Only changed by xterm_setup, which is a setup */
10595 +static char *terminal_emulator = "xterm";
10596 +static char *title_switch = "-T";
10597 +static char *exec_switch = "-e";
10599 +static int __init xterm_setup(char *line, int *add)
10602 + terminal_emulator = line;
10604 + line = strchr(line, ',');
10605 + if(line == NULL) return(0);
10607 + if(*line) title_switch = line;
10609 + line = strchr(line, ',');
10610 + if(line == NULL) return(0);
10612 + if(*line) exec_switch = line;
10617 +__uml_setup("xterm=", xterm_setup,
10618 +"xterm=<terminal emulator>,<title switch>,<exec switch>\n"
10619 +" Specifies an alternate terminal emulator to use for the debugger,\n"
10620 +" consoles, and serial lines when they are attached to the xterm channel.\n"
10621 +" The values are the terminal emulator binary, the switch it uses to set\n"
10622 +" its title, and the switch it uses to execute a subprocess,\n"
10623 +" respectively. The title switch must have the form '<switch> title',\n"
10624 +" not '<switch>=title'. Similarly, the exec switch must have the form\n"
10625 +" '<switch> command arg1 arg2 ...'.\n"
10626 +" The default values are 'xterm=xterm,-T,-e'. Values for gnome-terminal\n"
10627 +" are 'xterm=gnome-terminal,-t,-x'.\n\n"
10630 +int xterm_open(int input, int output, int primary, void *d, char **dev_out)
10632 + struct xterm_chan *data = d;
10633 + unsigned long stack;
10634 + int pid, fd, new, err;
10635 + char title[256], file[] = "/tmp/xterm-pipeXXXXXX";
10636 + char *argv[] = { terminal_emulator, title_switch, title, exec_switch,
10637 + "/usr/lib/uml/port-helper", "-uml-socket",
10640 + if(access(argv[4], X_OK))
10641 + argv[4] = "port-helper";
10643 + fd = mkstemp(file);
10645 + printk("xterm_open : mkstemp failed, errno = %d\n", errno);
10649 + if(unlink(file)){
10650 + printk("xterm_open : unlink failed, errno = %d\n", errno);
10655 + fd = create_unix_socket(file, sizeof(file));
10657 + printk("xterm_open : create_unix_socket failed, errno = %d\n",
10662 + sprintf(title, data->title, data->device);
10663 + stack = data->stack;
10664 + pid = run_helper(NULL, NULL, argv, &stack);
10666 + printk("xterm_open : run_helper failed, errno = %d\n", -pid);
10670 + if(data->stack == 0) free_stack(stack, 0);
10672 + if(data->direct_rcv)
10673 + new = os_rcv_fd(fd, &data->helper_pid);
10675 + if((err = os_set_fd_block(fd, 0)) != 0){
10676 + printk("xterm_open : failed to set descriptor "
10677 + "non-blocking, errno = %d\n", err);
10680 + new = xterm_fd(fd, &data->helper_pid);
10683 + printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new);
10687 + tcgetattr(new, &data->tt);
10688 + if(data->raw) raw(new, 0);
10697 +void xterm_close(int fd, void *d)
10699 + struct xterm_chan *data = d;
10701 + if(data->pid != -1)
10702 + os_kill_process(data->pid, 1);
10704 + if(data->helper_pid != -1)
10705 + os_kill_process(data->helper_pid, 0);
10706 + data->helper_pid = -1;
10710 +void xterm_free(void *d)
10715 +int xterm_console_write(int fd, const char *buf, int n, void *d)
10717 + struct xterm_chan *data = d;
10719 + return(generic_console_write(fd, buf, n, &data->tt));
10722 +struct chan_ops xterm_ops = {
10724 + .init = xterm_init,
10725 + .open = xterm_open,
10726 + .close = xterm_close,
10727 + .read = generic_read,
10728 + .write = generic_write,
10729 + .console_write = xterm_console_write,
10730 + .window_size = generic_window_size,
10731 + .free = xterm_free,
10736 + * Overrides for Emacs so that we follow Linus's tabbing style.
10737 + * Emacs will notice this stuff at the end of the file and automatically
10738 + * adjust the settings for this buffer only. This must remain at the end
10740 + * ---------------------------------------------------------------------------
10741 + * Local variables:
10742 + * c-file-style: "linux"
10745 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.h um/arch/um/drivers/xterm.h
10746 --- orig/arch/um/drivers/xterm.h 1969-12-31 19:00:00.000000000 -0500
10747 +++ um/arch/um/drivers/xterm.h 2002-10-23 21:08:04.000000000 -0400
10750 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10751 + * Licensed under the GPL
10754 +#ifndef __XTERM_H__
10755 +#define __XTERM_H__
10757 +extern int xterm_fd(int socket, int *pid_out);
10762 + * Overrides for Emacs so that we follow Linus's tabbing style.
10763 + * Emacs will notice this stuff at the end of the file and automatically
10764 + * adjust the settings for this buffer only. This must remain at the end
10766 + * ---------------------------------------------------------------------------
10767 + * Local variables:
10768 + * c-file-style: "linux"
10771 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm_kern.c um/arch/um/drivers/xterm_kern.c
10772 --- orig/arch/um/drivers/xterm_kern.c 1969-12-31 19:00:00.000000000 -0500
10773 +++ um/arch/um/drivers/xterm_kern.c 2002-12-17 17:31:20.000000000 -0500
10776 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10777 + * Licensed under the GPL
10780 +#include "linux/errno.h"
10781 +#include "linux/slab.h"
10782 +#include "asm/semaphore.h"
10783 +#include "asm/irq.h"
10784 +#include "irq_user.h"
10785 +#include "kern_util.h"
10787 +#include "xterm.h"
10789 +struct xterm_wait {
10790 + struct semaphore sem;
10796 +static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
10798 + struct xterm_wait *xterm = data;
10801 + fd = os_rcv_fd(xterm->fd, &xterm->pid);
10802 + if(fd == -EAGAIN)
10805 + xterm->new_fd = fd;
10809 +int xterm_fd(int socket, int *pid_out)
10811 + struct xterm_wait *data;
10814 + data = kmalloc(sizeof(*data), GFP_KERNEL);
10815 + if(data == NULL){
10816 + printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
10819 + *data = ((struct xterm_wait)
10820 + { .sem = __SEMAPHORE_INITIALIZER(data->sem, 0),
10825 + err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt,
10826 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
10829 + printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
10830 + "err = %d\n", err);
10833 + down(&data->sem);
10835 + free_irq(XTERM_IRQ, data);
10837 + ret = data->new_fd;
10838 + *pid_out = data->pid;
10845 + * Overrides for Emacs so that we follow Linus's tabbing style.
10846 + * Emacs will notice this stuff at the end of the file and automatically
10847 + * adjust the settings for this buffer only. This must remain at the end
10849 + * ---------------------------------------------------------------------------
10850 + * Local variables:
10851 + * c-file-style: "linux"
10854 diff -Naur -X ../exclude-files orig/arch/um/dyn_link.ld.in um/arch/um/dyn_link.ld.in
10855 --- orig/arch/um/dyn_link.ld.in 1969-12-31 19:00:00.000000000 -0500
10856 +++ um/arch/um/dyn_link.ld.in 2003-01-17 23:37:27.000000000 -0500
10858 +OUTPUT_FORMAT("ELF_FORMAT")
10859 +OUTPUT_ARCH(ELF_ARCH)
10861 +SEARCH_DIR("/usr/local/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
10862 +/* Do we need any of these for elf?
10863 + __DYNAMIC = 0; */
10866 + . = START() + SIZEOF_HEADERS;
10867 + .interp : { *(.interp) }
10869 + __binary_start = .;
10870 + . = ALIGN(4096); /* Init code and data */
10872 + __init_begin = .;
10873 + .text.init : { *(.text.init) }
10877 + /* Read-only sections, merged into text segment: */
10878 + .hash : { *(.hash) }
10879 + .dynsym : { *(.dynsym) }
10880 + .dynstr : { *(.dynstr) }
10881 + .gnu.version : { *(.gnu.version) }
10882 + .gnu.version_d : { *(.gnu.version_d) }
10883 + .gnu.version_r : { *(.gnu.version_r) }
10884 + .rel.init : { *(.rel.init) }
10885 + .rela.init : { *(.rela.init) }
10886 + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
10887 + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
10888 + .rel.fini : { *(.rel.fini) }
10889 + .rela.fini : { *(.rela.fini) }
10890 + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
10891 + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
10892 + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
10893 + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
10894 + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
10895 + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
10896 + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
10897 + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
10898 + .rel.ctors : { *(.rel.ctors) }
10899 + .rela.ctors : { *(.rela.ctors) }
10900 + .rel.dtors : { *(.rel.dtors) }
10901 + .rela.dtors : { *(.rela.dtors) }
10902 + .rel.got : { *(.rel.got) }
10903 + .rela.got : { *(.rela.got) }
10904 + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
10905 + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
10906 + .rel.plt : { *(.rel.plt) }
10907 + .rela.plt : { *(.rela.plt) }
10911 + .plt : { *(.plt) }
10913 + *(.text .stub .text.* .gnu.linkonce.t.*)
10914 + /* .gnu.warning sections are handled specially by elf32.em. */
10921 + PROVIDE (__etext = .);
10922 + PROVIDE (_etext = .);
10923 + PROVIDE (etext = .);
10924 + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
10925 + .rodata1 : { *(.rodata1) }
10926 + .eh_frame_hdr : { *(.eh_frame_hdr) }
10930 + PROVIDE (_sdata = .);
10932 +include(`arch/um/common.ld.in')
10934 + /* Ensure the __preinit_array_start label is properly aligned. We
10935 + could instead move the label definition inside the section, but
10936 + the linker would then create the section even if it turns out to
10937 + be empty, which isn't pretty. */
10938 + . = ALIGN(32 / 8);
10939 + .preinit_array : { *(.preinit_array) }
10940 + .init_array : { *(.init_array) }
10941 + .fini_array : { *(.fini_array) }
10943 + . = ALIGN(KERNEL_STACK_SIZE); /* init_task */
10944 + *(.data.init_task)
10945 + *(.data .data.* .gnu.linkonce.d.*)
10946 + SORT(CONSTRUCTORS)
10948 + .data1 : { *(.data1) }
10949 + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
10950 + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
10951 + .eh_frame : { KEEP (*(.eh_frame)) }
10952 + .gcc_except_table : { *(.gcc_except_table) }
10953 + .dynamic : { *(.dynamic) }
10955 + /* gcc uses crtbegin.o to find the start of
10956 + the constructors, so we make sure it is
10957 + first. Because this is a wildcard, it
10958 + doesn't matter if the user does not
10959 + actually link against crtbegin.o; the
10960 + linker won't look for a file to match a
10961 + wildcard. The wildcard also means that it
10962 + doesn't matter which directory crtbegin.o
10964 + KEEP (*crtbegin.o(.ctors))
10965 + /* We don't want to include the .ctor section from
10966 + from the crtend.o file until after the sorted ctors.
10967 + The .ctor section from the crtend file contains the
10968 + end of ctors marker and it must be last */
10969 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
10970 + KEEP (*(SORT(.ctors.*)))
10974 + KEEP (*crtbegin.o(.dtors))
10975 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
10976 + KEEP (*(SORT(.dtors.*)))
10979 + .jcr : { KEEP (*(.jcr)) }
10980 + .got : { *(.got.plt) *(.got) }
10982 + PROVIDE (edata = .);
10986 + *(.bss .bss.* .gnu.linkonce.b.*)
10988 + /* Align here to ensure that the .bss section occupies space up to
10989 + _end. Align after .bss to ensure correct alignment even if the
10990 + .bss section disappears because there are no input sections. */
10991 + . = ALIGN(32 / 8);
10992 + . = ALIGN(32 / 8);
10995 + PROVIDE (end = .);
10996 + /* Stabs debugging sections. */
10997 + .stab 0 : { *(.stab) }
10998 + .stabstr 0 : { *(.stabstr) }
10999 + .stab.excl 0 : { *(.stab.excl) }
11000 + .stab.exclstr 0 : { *(.stab.exclstr) }
11001 + .stab.index 0 : { *(.stab.index) }
11002 + .stab.indexstr 0 : { *(.stab.indexstr) }
11003 + .comment 0 : { *(.comment) }
11004 + /* DWARF debug sections.
11005 + Symbols in the DWARF debugging sections are relative to the beginning
11006 + of the section so we begin them at 0. */
11008 + .debug 0 : { *(.debug) }
11009 + .line 0 : { *(.line) }
11010 + /* GNU DWARF 1 extensions */
11011 + .debug_srcinfo 0 : { *(.debug_srcinfo) }
11012 + .debug_sfnames 0 : { *(.debug_sfnames) }
11013 + /* DWARF 1.1 and DWARF 2 */
11014 + .debug_aranges 0 : { *(.debug_aranges) }
11015 + .debug_pubnames 0 : { *(.debug_pubnames) }
11017 + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
11018 + .debug_abbrev 0 : { *(.debug_abbrev) }
11019 + .debug_line 0 : { *(.debug_line) }
11020 + .debug_frame 0 : { *(.debug_frame) }
11021 + .debug_str 0 : { *(.debug_str) }
11022 + .debug_loc 0 : { *(.debug_loc) }
11023 + .debug_macinfo 0 : { *(.debug_macinfo) }
11024 + /* SGI/MIPS DWARF 2 extensions */
11025 + .debug_weaknames 0 : { *(.debug_weaknames) }
11026 + .debug_funcnames 0 : { *(.debug_funcnames) }
11027 + .debug_typenames 0 : { *(.debug_typenames) }
11028 + .debug_varnames 0 : { *(.debug_varnames) }
11030 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs.h um/arch/um/fs/hostfs/hostfs.h
11031 --- orig/arch/um/fs/hostfs/hostfs.h 1969-12-31 19:00:00.000000000 -0500
11032 +++ um/arch/um/fs/hostfs/hostfs.h 2003-05-22 11:03:20.000000000 -0400
11034 +#ifndef __UM_FS_HOSTFS
11035 +#define __UM_FS_HOSTFS
11039 +/* These are exactly the same definitions as in fs.h, but the names are
11040 + * changed so that this file can be included in both kernel and user files.
11043 +#define HOSTFS_ATTR_MODE 1
11044 +#define HOSTFS_ATTR_UID 2
11045 +#define HOSTFS_ATTR_GID 4
11046 +#define HOSTFS_ATTR_SIZE 8
11047 +#define HOSTFS_ATTR_ATIME 16
11048 +#define HOSTFS_ATTR_MTIME 32
11049 +#define HOSTFS_ATTR_CTIME 64
11050 +#define HOSTFS_ATTR_ATIME_SET 128
11051 +#define HOSTFS_ATTR_MTIME_SET 256
11052 +#define HOSTFS_ATTR_FORCE 512 /* Not a change, but a change it */
11053 +#define HOSTFS_ATTR_ATTR_FLAG 1024
11055 +struct hostfs_iattr {
11056 + unsigned int ia_valid;
11064 + unsigned int ia_attr_flags;
11067 +extern int stat_file(const char *path, int *dev_out,
11068 + unsigned long long *inode_out, int *mode_out,
11069 + int *nlink_out, int *uid_out, int *gid_out,
11070 + unsigned long long *size_out, unsigned long *atime_out,
11071 + unsigned long *mtime_out, unsigned long *ctime_out,
11072 + int *blksize_out, unsigned long long *blocks_out);
11073 +extern int access_file(char *path, int r, int w, int x);
11074 +extern int open_file(char *path, int r, int w, int append);
11075 +extern int file_type(const char *path, int *rdev);
11076 +extern void *open_dir(char *path, int *err_out);
11077 +extern char *read_dir(void *stream, unsigned long long *pos,
11078 + unsigned long long *ino_out, int *len_out);
11079 +extern void close_file(void *stream);
11080 +extern void close_dir(void *stream);
11081 +extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
11082 +extern int write_file(int fd, unsigned long long *offset, const char *buf,
11084 +extern int lseek_file(int fd, long long offset, int whence);
11085 +extern int file_create(char *name, int ur, int uw, int ux, int gr,
11086 + int gw, int gx, int or, int ow, int ox);
11087 +extern int set_attr(const char *file, struct hostfs_iattr *attrs);
11088 +extern int make_symlink(const char *from, const char *to);
11089 +extern int unlink_file(const char *file);
11090 +extern int do_mkdir(const char *file, int mode);
11091 +extern int do_rmdir(const char *file);
11092 +extern int do_mknod(const char *file, int mode, int dev);
11093 +extern int link_file(const char *from, const char *to);
11094 +extern int do_readlink(char *file, char *buf, int size);
11095 +extern int rename_file(char *from, char *to);
11096 +extern int do_statfs(char *root, long *bsize_out, long long *blocks_out,
11097 + long long *bfree_out, long long *bavail_out,
11098 + long long *files_out, long long *ffree_out,
11099 + void *fsid_out, int fsid_size, long *namelen_out,
11100 + long *spare_out);
11103 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_kern.c um/arch/um/fs/hostfs/hostfs_kern.c
11104 --- orig/arch/um/fs/hostfs/hostfs_kern.c 1969-12-31 19:00:00.000000000 -0500
11105 +++ um/arch/um/fs/hostfs/hostfs_kern.c 2003-05-22 11:26:25.000000000 -0400
11108 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
11109 + * Licensed under the GPL
11112 +#include <linux/stddef.h>
11113 +#include <linux/fs.h>
11114 +#include <linux/version.h>
11115 +#include <linux/module.h>
11116 +#include <linux/init.h>
11117 +#include <linux/slab.h>
11118 +#include <linux/pagemap.h>
11119 +#include <linux/blkdev.h>
11120 +#include <asm/uaccess.h>
11121 +#include "hostfs.h"
11122 +#include "kern_util.h"
11124 +#include "user_util.h"
11125 +#include "2_5compat.h"
11128 +#define file_hostfs_i(file) (&(file)->f_dentry->d_inode->u.hostfs_i)
11130 +int hostfs_d_delete(struct dentry *dentry)
11135 +struct dentry_operations hostfs_dentry_ops = {
11136 + .d_delete = hostfs_d_delete,
11139 +/* Changed in hostfs_args before the kernel starts running */
11140 +static char *root_ino = "/";
11141 +static int append = 0;
11143 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
11145 +static struct inode_operations hostfs_iops;
11146 +static struct inode_operations hostfs_dir_iops;
11147 +static struct address_space_operations hostfs_link_aops;
11149 +static int __init hostfs_args(char *options, int *add)
11153 + ptr = strchr(options, ',');
11156 + if(*options != '\0')
11157 + root_ino = options;
11161 + ptr = strchr(options, ',');
11164 + if(*options != '\0'){
11165 + if(!strcmp(options, "append"))
11167 + else printf("hostfs_args - unsupported option - %s\n",
11175 +__uml_setup("hostfs=", hostfs_args,
11176 +"hostfs=<root dir>,<flags>,...\n"
11177 +" This is used to set hostfs parameters. The root directory argument\n"
11178 +" is used to confine all hostfs mounts to within the specified directory\n"
11179 +" tree on the host. If this isn't specified, then a user inside UML can\n"
11180 +" mount anything on the host that's accessible to the user that's running\n"
11182 +" The only flag currently supported is 'append', which specifies that all\n"
11183 +" files opened by hostfs will be opened in append mode.\n\n"
11186 +static char *dentry_name(struct dentry *dentry, int extra)
11188 + struct dentry *parent;
11189 + char *root, *name;
11194 + while(parent->d_parent != parent){
11195 + len += parent->d_name.len + 1;
11196 + parent = parent->d_parent;
11199 + root = parent->d_inode->u.hostfs_i.host_filename;
11200 + len += strlen(root);
11201 + name = kmalloc(len + extra + 1, GFP_KERNEL);
11202 + if(name == NULL) return(NULL);
11204 + name[len] = '\0';
11206 + while(parent->d_parent != parent){
11207 + len -= parent->d_name.len + 1;
11209 + strncpy(&name[len + 1], parent->d_name.name,
11210 + parent->d_name.len);
11211 + parent = parent->d_parent;
11213 + strncpy(name, root, strlen(root));
11217 +static char *inode_name(struct inode *ino, int extra)
11219 + struct dentry *dentry;
11221 + dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
11222 + return(dentry_name(dentry, extra));
11225 +static int read_name(struct inode *ino, char *name)
11227 + /* The non-int inode fields are copied into ints by stat_file and
11228 + * then copied into the inode because passing the actual pointers
11229 + * in and having them treated as int * breaks on big-endian machines
11232 + int i_dev, i_mode, i_nlink, i_blksize;
11233 + unsigned long long i_size;
11234 + unsigned long long i_ino;
11235 + unsigned long long i_blocks;
11236 + err = stat_file(name, &i_dev, &i_ino, &i_mode, &i_nlink,
11237 + &ino->i_uid, &ino->i_gid, &i_size, &ino->i_atime,
11238 + &ino->i_mtime, &ino->i_ctime, &i_blksize, &i_blocks);
11239 + if(err) return(err);
11240 + ino->i_ino = i_ino;
11241 + ino->i_dev = i_dev;
11242 + ino->i_mode = i_mode;
11243 + ino->i_nlink = i_nlink;
11244 + ino->i_size = i_size;
11245 + ino->i_blksize = i_blksize;
11246 + ino->i_blocks = i_blocks;
11247 + if(kdev_same(ino->i_sb->s_dev, ROOT_DEV) && (ino->i_uid == getuid()))
11252 +static char *follow_link(char *link)
11255 + char *name, *resolved, *end;
11260 + name = kmalloc(len, GFP_KERNEL);
11264 + n = do_readlink(link, name, len);
11276 + end = strrchr(link, '/');
11280 + *(end + 1) = '\0';
11281 + len = strlen(link) + strlen(name) + 1;
11283 + resolved = kmalloc(len, GFP_KERNEL);
11284 + if(resolved == NULL){
11289 + sprintf(resolved, "%s%s", link, name);
11292 + return(resolved);
11297 + return(ERR_PTR(n));
11300 +static int read_inode(struct inode *ino)
11306 + name = inode_name(ino, 0);
11310 + if(file_type(name, NULL) == OS_TYPE_SYMLINK){
11311 + name = follow_link(name);
11312 + if(IS_ERR(name)){
11313 + err = PTR_ERR(name);
11318 + err = read_name(ino, name);
11324 +void hostfs_delete_inode(struct inode *ino)
11326 + if(ino->u.hostfs_i.host_filename)
11327 + kfree(ino->u.hostfs_i.host_filename);
11328 + ino->u.hostfs_i.host_filename = NULL;
11330 + if(ino->u.hostfs_i.fd != -1)
11331 + close_file(&ino->u.hostfs_i.fd);
11333 + ino->u.hostfs_i.mode = 0;
11334 + clear_inode(ino);
11337 +int hostfs_statfs(struct super_block *sb, struct statfs *sf)
11339 + /* do_statfs uses struct statfs64 internally, but the linux kernel
11340 + * struct statfs still has 32-bit versions for most of these fields,
11341 + * so we convert them here
11344 + long long f_blocks;
11345 + long long f_bfree;
11346 + long long f_bavail;
11347 + long long f_files;
11348 + long long f_ffree;
11350 + err = do_statfs(sb->s_root->d_inode->u.hostfs_i.host_filename,
11351 + &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
11352 + &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
11353 + &sf->f_namelen, sf->f_spare);
11354 + if(err) return(err);
11355 + sf->f_blocks = f_blocks;
11356 + sf->f_bfree = f_bfree;
11357 + sf->f_bavail = f_bavail;
11358 + sf->f_files = f_files;
11359 + sf->f_ffree = f_ffree;
11360 + sf->f_type = HOSTFS_SUPER_MAGIC;
11364 +static struct super_operations hostfs_sbops = {
11365 + .put_inode = force_delete,
11366 + .delete_inode = hostfs_delete_inode,
11367 + .statfs = hostfs_statfs,
11370 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
11374 + unsigned long long next, ino;
11377 + name = dentry_name(file->f_dentry, 0);
11378 + if(name == NULL) return(-ENOMEM);
11379 + dir = open_dir(name, &error);
11381 + if(dir == NULL) return(-error);
11382 + next = file->f_pos;
11383 + while((name = read_dir(dir, &next, &ino, &len)) != NULL){
11384 + error = (*filldir)(ent, name, len, file->f_pos,
11385 + ino, DT_UNKNOWN);
11387 + file->f_pos = next;
11393 +int hostfs_file_open(struct inode *ino, struct file *file)
11396 + int mode = 0, r = 0, w = 0, fd;
11398 + mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
11399 + if((mode & ino->u.hostfs_i.mode) == mode)
11402 + /* The file may already have been opened, but with the wrong access,
11403 + * so this resets things and reopens the file with the new access.
11405 + if(ino->u.hostfs_i.fd != -1){
11406 + close_file(&ino->u.hostfs_i.fd);
11407 + ino->u.hostfs_i.fd = -1;
11410 + ino->u.hostfs_i.mode |= mode;
11411 + if(ino->u.hostfs_i.mode & FMODE_READ)
11413 + if(ino->u.hostfs_i.mode & FMODE_WRITE)
11418 + name = dentry_name(file->f_dentry, 0);
11422 + fd = open_file(name, r, w, append);
11424 + if(fd < 0) return(fd);
11425 + file_hostfs_i(file)->fd = fd;
11430 +int hostfs_dir_open(struct inode *ino, struct file *file)
11435 +int hostfs_dir_release(struct inode *ino, struct file *file)
11440 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
11445 +static struct file_operations hostfs_file_fops = {
11447 + .read = generic_file_read,
11448 + .write = generic_file_write,
11449 + .mmap = generic_file_mmap,
11450 + .open = hostfs_file_open,
11452 + .fsync = hostfs_fsync,
11455 +static struct file_operations hostfs_dir_fops = {
11457 + .readdir = hostfs_readdir,
11458 + .open = hostfs_dir_open,
11459 + .release = hostfs_dir_release,
11460 + .fsync = hostfs_fsync,
11463 +int hostfs_writepage(struct page *page)
11465 + struct address_space *mapping = page->mapping;
11466 + struct inode *inode = mapping->host;
11468 + unsigned long long base;
11469 + int count = PAGE_CACHE_SIZE;
11470 + int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
11473 + if (page->index >= end_index)
11474 + count = inode->i_size & (PAGE_CACHE_SIZE-1);
11476 + buffer = kmap(page);
11477 + base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
11479 + err = write_file(inode->u.hostfs_i.fd, &base, buffer, count);
11480 + if(err != count){
11481 + ClearPageUptodate(page);
11485 + if (base > inode->i_size)
11486 + inode->i_size = base;
11488 + if (PageError(page))
11489 + ClearPageError(page);
11495 + UnlockPage(page);
11499 +int hostfs_readpage(struct file *file, struct page *page)
11505 + start = (long long) page->index << PAGE_CACHE_SHIFT;
11506 + buffer = kmap(page);
11507 + err = read_file(file_hostfs_i(file)->fd, &start, buffer,
11508 + PAGE_CACHE_SIZE);
11509 + if(err < 0) goto out;
11511 + memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
11513 + flush_dcache_page(page);
11514 + SetPageUptodate(page);
11515 + if (PageError(page)) ClearPageError(page);
11519 + UnlockPage(page);
11523 +int hostfs_prepare_write(struct file *file, struct page *page,
11524 + unsigned int from, unsigned int to)
11527 + long long start, tmp;
11530 + start = (long long) page->index << PAGE_CACHE_SHIFT;
11531 + buffer = kmap(page);
11534 + err = read_file(file_hostfs_i(file)->fd, &tmp, buffer,
11536 + if(err < 0) goto out;
11538 + if(to != PAGE_CACHE_SIZE){
11540 + err = read_file(file_hostfs_i(file)->fd, &start, buffer + to,
11541 + PAGE_CACHE_SIZE - to);
11542 + if(err < 0) goto out;
11550 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
11553 + struct address_space *mapping = page->mapping;
11554 + struct inode *inode = mapping->host;
11559 + start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
11560 + buffer = kmap(page);
11561 + err = write_file(file_hostfs_i(file)->fd, &start, buffer + from,
11563 + if(err > 0) err = 0;
11564 + if(!err && (start > inode->i_size))
11565 + inode->i_size = start;
11571 +static struct address_space_operations hostfs_aops = {
11572 + .writepage = hostfs_writepage,
11573 + .readpage = hostfs_readpage,
11574 +/* .set_page_dirty = __set_page_dirty_nobuffers, */
11575 + .prepare_write = hostfs_prepare_write,
11576 + .commit_write = hostfs_commit_write
11579 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
11582 + struct inode *inode;
11584 + int type, err = -ENOMEM, rdev;
11586 + inode = new_inode(sb);
11587 + if(inode == NULL)
11590 + inode->u.hostfs_i.host_filename = NULL;
11591 + inode->u.hostfs_i.fd = -1;
11592 + inode->u.hostfs_i.mode = 0;
11593 + insert_inode_hash(inode);
11595 + name = dentry_name(dentry, 0);
11596 + if(name == NULL){
11600 + type = file_type(name, &rdev);
11603 + else type = OS_TYPE_DIR;
11604 + inode->i_sb = sb;
11607 + if(type == OS_TYPE_SYMLINK)
11608 + inode->i_op = &page_symlink_inode_operations;
11609 + else if(type == OS_TYPE_DIR)
11610 + inode->i_op = &hostfs_dir_iops;
11611 + else inode->i_op = &hostfs_iops;
11613 + if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
11614 + else inode->i_fop = &hostfs_file_fops;
11616 + if(type == OS_TYPE_SYMLINK)
11617 + inode->i_mapping->a_ops = &hostfs_link_aops;
11618 + else inode->i_mapping->a_ops = &hostfs_aops;
11621 + case OS_TYPE_CHARDEV:
11622 + init_special_inode(inode, S_IFCHR, rdev);
11624 + case OS_TYPE_BLOCKDEV:
11625 + init_special_inode(inode, S_IFBLK, rdev);
11627 + case OS_TYPE_FIFO:
11628 + init_special_inode(inode, S_IFIFO, 0);
11630 + case OS_TYPE_SOCK:
11631 + init_special_inode(inode, S_IFSOCK, 0);
11635 + if(error) *error = err;
11640 + if(error) *error = err;
11644 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode)
11646 + struct inode *inode;
11650 + inode = get_inode(dir->i_sb, dentry, &error);
11651 + if(error) return(error);
11652 + name = dentry_name(dentry, 0);
11653 + if(name == NULL){
11657 + fd = file_create(name,
11658 + mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
11659 + mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
11660 + mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
11663 + else error = read_name(inode, name);
11670 + inode->u.hostfs_i.fd = fd;
11671 + inode->u.hostfs_i.mode = FMODE_READ | FMODE_WRITE;
11672 + d_instantiate(dentry, inode);
11676 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry)
11678 + struct inode *inode;
11682 + inode = get_inode(ino->i_sb, dentry, &error);
11683 + if(error != 0) return(ERR_PTR(error));
11684 + name = dentry_name(dentry, 0);
11685 + if(name == NULL) return(ERR_PTR(-ENOMEM));
11686 + error = read_name(inode, name);
11690 + if(error == -ENOENT) inode = NULL;
11691 + else return(ERR_PTR(error));
11693 + d_add(dentry, inode);
11694 + dentry->d_op = &hostfs_dentry_ops;
11698 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
11703 + file = inode_name(ino, dentry->d_name.len + 1);
11704 + if(file == NULL) return(NULL);
11705 + strcat(file, "/");
11706 + len = strlen(file);
11707 + strncat(file, dentry->d_name.name, dentry->d_name.len);
11708 + file[len + dentry->d_name.len] = '\0';
11712 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
11714 + char *from_name, *to_name;
11717 + if((from_name = inode_dentry_name(ino, from)) == NULL)
11719 + to_name = dentry_name(to, 0);
11720 + if(to_name == NULL){
11721 + kfree(from_name);
11724 + err = link_file(to_name, from_name);
11725 + kfree(from_name);
11730 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
11735 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
11739 + err = unlink_file(file);
11744 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
11749 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
11750 + err = make_symlink(file, to);
11755 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
11760 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
11761 + err = do_mkdir(file, mode);
11766 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
11771 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
11772 + err = do_rmdir(file);
11777 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
11779 + struct inode *inode;
11783 + inode = get_inode(dir->i_sb, dentry, &error);
11784 + if(error) return(error);
11785 + name = dentry_name(dentry, 0);
11786 + if(name == NULL){
11790 + init_special_inode(inode, mode, dev);
11791 + error = do_mknod(name, mode, dev);
11792 + if(!error) error = read_name(inode, name);
11798 + d_instantiate(dentry, inode);
11802 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
11803 + struct inode *to_ino, struct dentry *to)
11805 + char *from_name, *to_name;
11808 + if((from_name = inode_dentry_name(from_ino, from)) == NULL)
11810 + if((to_name = inode_dentry_name(to_ino, to)) == NULL){
11811 + kfree(from_name);
11814 + err = rename_file(from_name, to_name);
11815 + kfree(from_name);
11820 +void hostfs_truncate(struct inode *ino)
11822 + not_implemented();
11825 +int hostfs_permission(struct inode *ino, int desired)
11828 + int r = 0, w = 0, x = 0, err;
11830 + if(desired & MAY_READ) r = 1;
11831 + if(desired & MAY_WRITE) w = 1;
11832 + if(desired & MAY_EXEC) x = 1;
11833 + name = inode_name(ino, 0);
11834 + if(name == NULL) return(-ENOMEM);
11835 + err = access_file(name, r, w, x);
11837 + if(!err) err = vfs_permission(ino, desired);
11841 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
11843 + struct hostfs_iattr attrs;
11848 + attr->ia_valid &= ~ATTR_SIZE;
11850 + attrs.ia_valid = 0;
11851 + if(attr->ia_valid & ATTR_MODE){
11852 + attrs.ia_valid |= HOSTFS_ATTR_MODE;
11853 + attrs.ia_mode = attr->ia_mode;
11855 + if(attr->ia_valid & ATTR_UID){
11856 + if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) &&
11857 + (attr->ia_uid == 0))
11858 + attr->ia_uid = getuid();
11859 + attrs.ia_valid |= HOSTFS_ATTR_UID;
11860 + attrs.ia_uid = attr->ia_uid;
11862 + if(attr->ia_valid & ATTR_GID){
11863 + if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) &&
11864 + (attr->ia_gid == 0))
11865 + attr->ia_gid = getuid();
11866 + attrs.ia_valid |= HOSTFS_ATTR_GID;
11867 + attrs.ia_gid = attr->ia_gid;
11869 + if(attr->ia_valid & ATTR_SIZE){
11870 + attrs.ia_valid |= HOSTFS_ATTR_SIZE;
11871 + attrs.ia_size = attr->ia_size;
11873 + if(attr->ia_valid & ATTR_ATIME){
11874 + attrs.ia_valid |= HOSTFS_ATTR_ATIME;
11875 + attrs.ia_atime = attr->ia_atime;
11877 + if(attr->ia_valid & ATTR_MTIME){
11878 + attrs.ia_valid |= HOSTFS_ATTR_MTIME;
11879 + attrs.ia_mtime = attr->ia_mtime;
11881 + if(attr->ia_valid & ATTR_CTIME){
11882 + attrs.ia_valid |= HOSTFS_ATTR_CTIME;
11883 + attrs.ia_ctime = attr->ia_ctime;
11885 + if(attr->ia_valid & ATTR_ATIME_SET){
11886 + attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
11888 + if(attr->ia_valid & ATTR_MTIME_SET){
11889 + attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
11891 + name = dentry_name(dentry, 0);
11892 + if(name == NULL) return(-ENOMEM);
11893 + err = set_attr(name, &attrs);
11898 + return(inode_setattr(dentry->d_inode, attr));
11901 +int hostfs_getattr(struct dentry *dentry, struct iattr *attr)
11903 + not_implemented();
11907 +static struct inode_operations hostfs_iops = {
11908 + .create = hostfs_create,
11909 + .link = hostfs_link,
11910 + .unlink = hostfs_unlink,
11911 + .symlink = hostfs_symlink,
11912 + .mkdir = hostfs_mkdir,
11913 + .rmdir = hostfs_rmdir,
11914 + .mknod = hostfs_mknod,
11915 + .rename = hostfs_rename,
11916 + .truncate = hostfs_truncate,
11917 + .permission = hostfs_permission,
11918 + .setattr = hostfs_setattr,
11919 + .getattr = hostfs_getattr,
11922 +static struct inode_operations hostfs_dir_iops = {
11923 + .create = hostfs_create,
11924 + .lookup = hostfs_lookup,
11925 + .link = hostfs_link,
11926 + .unlink = hostfs_unlink,
11927 + .symlink = hostfs_symlink,
11928 + .mkdir = hostfs_mkdir,
11929 + .rmdir = hostfs_rmdir,
11930 + .mknod = hostfs_mknod,
11931 + .rename = hostfs_rename,
11932 + .truncate = hostfs_truncate,
11933 + .permission = hostfs_permission,
11934 + .setattr = hostfs_setattr,
11935 + .getattr = hostfs_getattr,
11938 +int hostfs_link_readpage(struct file *file, struct page *page)
11940 + char *buffer, *name;
11944 + start = page->index << PAGE_CACHE_SHIFT;
11945 + buffer = kmap(page);
11946 + name = inode_name(page->mapping->host, 0);
11947 + if(name == NULL) return(-ENOMEM);
11948 + err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
11950 + if(err == PAGE_CACHE_SIZE)
11952 + else if(err > 0){
11953 + flush_dcache_page(page);
11954 + SetPageUptodate(page);
11955 + if (PageError(page)) ClearPageError(page);
11959 + UnlockPage(page);
11963 +static struct address_space_operations hostfs_link_aops = {
11964 + .readpage = hostfs_link_readpage,
11967 +static struct super_block *hostfs_read_super_common(struct super_block *sb,
11970 + struct inode *root_inode;
11973 + sb->s_blocksize = 1024;
11974 + sb->s_blocksize_bits = 10;
11975 + sb->s_magic = HOSTFS_SUPER_MAGIC;
11976 + sb->s_op = &hostfs_sbops;
11977 + if((data == NULL) || (*((char *) data) == '\0')) data = root_ino;
11978 + name = kmalloc(strlen(data) + 1, GFP_KERNEL);
11979 + if(name == NULL) return(NULL);
11980 + strcpy(name, data);
11981 + root_inode = get_inode(sb, NULL, NULL);
11982 + if(root_inode == NULL)
11985 + root_inode->u.hostfs_i.host_filename = name;
11986 + sb->s_root = d_alloc_root(root_inode);
11987 + if(read_inode(root_inode))
11994 + iput(root_inode);
11998 +struct super_block *hostfs_read_super(struct super_block *sb, void *data,
12001 + return(hostfs_read_super_common(sb, data));
12004 +DECLARE_FSTYPE(hostfs_type, "hostfs", hostfs_read_super, 0);
12006 +static int __init init_hostfs(void)
12008 + return(register_filesystem(&hostfs_type));
12011 +static void __exit exit_hostfs(void)
12013 + unregister_filesystem(&hostfs_type);
12016 +module_init(init_hostfs)
12017 +module_exit(exit_hostfs)
12018 +MODULE_LICENSE("GPL");
12021 + * Overrides for Emacs so that we follow Linus's tabbing style.
12022 + * Emacs will notice this stuff at the end of the file and automatically
12023 + * adjust the settings for this buffer only. This must remain at the end
12025 + * ---------------------------------------------------------------------------
12026 + * Local variables:
12027 + * c-file-style: "linux"
12030 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_user.c um/arch/um/fs/hostfs/hostfs_user.c
12031 --- orig/arch/um/fs/hostfs/hostfs_user.c 1969-12-31 19:00:00.000000000 -0500
12032 +++ um/arch/um/fs/hostfs/hostfs_user.c 2003-05-22 11:06:46.000000000 -0400
12035 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
12036 + * Licensed under the GPL
12039 +#include <unistd.h>
12040 +#include <stdio.h>
12041 +#include <fcntl.h>
12042 +#include <dirent.h>
12043 +#include <errno.h>
12044 +#include <utime.h>
12045 +#include <string.h>
12046 +#include <sys/stat.h>
12047 +#include <sys/time.h>
12048 +#include <sys/vfs.h>
12049 +#include "hostfs.h"
12050 +#include "kern_util.h"
12053 +int stat_file(const char *path, int *dev_out, unsigned long long *inode_out,
12054 + int *mode_out, int *nlink_out, int *uid_out, int *gid_out,
12055 + unsigned long long *size_out, unsigned long *atime_out,
12056 + unsigned long *mtime_out, unsigned long *ctime_out,
12057 + int *blksize_out, unsigned long long *blocks_out)
12059 + struct stat64 buf;
12061 + if(lstat64(path, &buf) < 0)
12063 + if(dev_out != NULL) *dev_out = buf.st_dev;
12065 + /* See the Makefile for why STAT64_INO_FIELD is passed in
12068 + if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
12069 + if(mode_out != NULL) *mode_out = buf.st_mode;
12070 + if(nlink_out != NULL) *nlink_out = buf.st_nlink;
12071 + if(uid_out != NULL) *uid_out = buf.st_uid;
12072 + if(gid_out != NULL) *gid_out = buf.st_gid;
12073 + if(size_out != NULL) *size_out = buf.st_size;
12074 + if(atime_out != NULL) *atime_out = buf.st_atime;
12075 + if(mtime_out != NULL) *mtime_out = buf.st_mtime;
12076 + if(ctime_out != NULL) *ctime_out = buf.st_ctime;
12077 + if(blksize_out != NULL) *blksize_out = buf.st_blksize;
12078 + if(blocks_out != NULL) *blocks_out = buf.st_blocks;
12082 +int file_type(const char *path, int *rdev)
12084 + struct stat64 buf;
12086 + if(lstat64(path, &buf) < 0)
12089 + *rdev = buf.st_rdev;
12091 + if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
12092 + else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
12093 + else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
12094 + else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
12095 + else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
12096 + else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
12097 + else return(OS_TYPE_FILE);
12100 +int access_file(char *path, int r, int w, int x)
12104 + if(r) mode = R_OK;
12105 + if(w) mode |= W_OK;
12106 + if(x) mode |= X_OK;
12107 + if(access(path, mode) != 0) return(-errno);
12111 +int open_file(char *path, int r, int w, int append)
12113 + int mode = 0, fd;
12121 + else panic("Impossible mode in open_file");
12124 + mode |= O_APPEND;
12125 + fd = open64(path, mode);
12126 + if(fd < 0) return(-errno);
12130 +void *open_dir(char *path, int *err_out)
12134 + dir = opendir(path);
12135 + *err_out = errno;
12136 + if(dir == NULL) return(NULL);
12140 +char *read_dir(void *stream, unsigned long long *pos,
12141 + unsigned long long *ino_out, int *len_out)
12143 + DIR *dir = stream;
12144 + struct dirent *ent;
12146 + seekdir(dir, *pos);
12147 + ent = readdir(dir);
12148 + if(ent == NULL) return(NULL);
12149 + *len_out = strlen(ent->d_name);
12150 + *ino_out = ent->d_ino;
12151 + *pos = telldir(dir);
12152 + return(ent->d_name);
12155 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
12159 + n = pread64(fd, buf, len, *offset);
12160 + if(n < 0) return(-errno);
12165 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
12169 + n = pwrite64(fd, buf, len, *offset);
12170 + if(n < 0) return(-errno);
12175 +int lseek_file(int fd, long long offset, int whence)
12179 + ret = lseek64(fd, offset, whence);
12180 + if(ret < 0) return(-errno);
12184 +void close_file(void *stream)
12186 + close(*((int *) stream));
12189 +void close_dir(void *stream)
12191 + closedir(stream);
12194 +int file_create(char *name, int ur, int uw, int ux, int gr,
12195 + int gw, int gx, int or, int ow, int ox)
12200 + mode |= ur ? S_IRUSR : 0;
12201 + mode |= uw ? S_IWUSR : 0;
12202 + mode |= ux ? S_IXUSR : 0;
12203 + mode |= gr ? S_IRGRP : 0;
12204 + mode |= gw ? S_IWGRP : 0;
12205 + mode |= gx ? S_IXGRP : 0;
12206 + mode |= or ? S_IROTH : 0;
12207 + mode |= ow ? S_IWOTH : 0;
12208 + mode |= ox ? S_IXOTH : 0;
12209 + fd = open64(name, O_CREAT | O_RDWR, mode);
12215 +int set_attr(const char *file, struct hostfs_iattr *attrs)
12217 + struct utimbuf buf;
12220 + if(attrs->ia_valid & HOSTFS_ATTR_MODE){
12221 + if(chmod(file, attrs->ia_mode) != 0) return(-errno);
12223 + if(attrs->ia_valid & HOSTFS_ATTR_UID){
12224 + if(chown(file, attrs->ia_uid, -1)) return(-errno);
12226 + if(attrs->ia_valid & HOSTFS_ATTR_GID){
12227 + if(chown(file, -1, attrs->ia_gid)) return(-errno);
12229 + if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
12230 + if(truncate(file, attrs->ia_size)) return(-errno);
12232 + ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
12233 + if((attrs->ia_valid & ma) == ma){
12234 + buf.actime = attrs->ia_atime;
12235 + buf.modtime = attrs->ia_mtime;
12236 + if(utime(file, &buf) != 0) return(-errno);
12239 + if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
12240 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
12241 + NULL, NULL, NULL, &buf.modtime, NULL,
12243 + if(err != 0) return(err);
12244 + buf.actime = attrs->ia_atime;
12245 + if(utime(file, &buf) != 0) return(-errno);
12247 + if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
12248 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
12249 + NULL, NULL, &buf.actime, NULL, NULL,
12251 + if(err != 0) return(err);
12252 + buf.modtime = attrs->ia_mtime;
12253 + if(utime(file, &buf) != 0) return(-errno);
12256 + if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
12257 + if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
12258 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
12259 + NULL, NULL, &attrs->ia_atime, &attrs->ia_mtime,
12260 + NULL, NULL, NULL);
12261 + if(err != 0) return(err);
12266 +int make_symlink(const char *from, const char *to)
12270 + err = symlink(to, from);
12271 + if(err) return(-errno);
12275 +int unlink_file(const char *file)
12279 + err = unlink(file);
12280 + if(err) return(-errno);
12284 +int do_mkdir(const char *file, int mode)
12288 + err = mkdir(file, mode);
12289 + if(err) return(-errno);
12293 +int do_rmdir(const char *file)
12297 + err = rmdir(file);
12298 + if(err) return(-errno);
12302 +int do_mknod(const char *file, int mode, int dev)
12306 + err = mknod(file, mode, dev);
12307 + if(err) return(-errno);
12311 +int link_file(const char *to, const char *from)
12315 + err = link(to, from);
12316 + if(err) return(-errno);
12320 +int do_readlink(char *file, char *buf, int size)
12324 + n = readlink(file, buf, size);
12332 +int rename_file(char *from, char *to)
12336 + err = rename(from, to);
12337 + if(err < 0) return(-errno);
12341 +int do_statfs(char *root, long *bsize_out, long long *blocks_out,
12342 + long long *bfree_out, long long *bavail_out,
12343 + long long *files_out, long long *ffree_out,
12344 + void *fsid_out, int fsid_size, long *namelen_out,
12347 + struct statfs64 buf;
12350 + err = statfs64(root, &buf);
12351 + if(err < 0) return(-errno);
12352 + *bsize_out = buf.f_bsize;
12353 + *blocks_out = buf.f_blocks;
12354 + *bfree_out = buf.f_bfree;
12355 + *bavail_out = buf.f_bavail;
12356 + *files_out = buf.f_files;
12357 + *ffree_out = buf.f_ffree;
12358 + memcpy(fsid_out, &buf.f_fsid,
12359 + sizeof(buf.f_fsid) > fsid_size ? fsid_size :
12360 + sizeof(buf.f_fsid));
12361 + *namelen_out = buf.f_namelen;
12362 + spare_out[0] = buf.f_spare[0];
12363 + spare_out[1] = buf.f_spare[1];
12364 + spare_out[2] = buf.f_spare[2];
12365 + spare_out[3] = buf.f_spare[3];
12366 + spare_out[4] = buf.f_spare[4];
12367 + spare_out[5] = buf.f_spare[5];
12372 + * Overrides for Emacs so that we follow Linus's tabbing style.
12373 + * Emacs will notice this stuff at the end of the file and automatically
12374 + * adjust the settings for this buffer only. This must remain at the end
12376 + * ---------------------------------------------------------------------------
12377 + * Local variables:
12378 + * c-file-style: "linux"
12381 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/Makefile um/arch/um/fs/hostfs/Makefile
12382 --- orig/arch/um/fs/hostfs/Makefile 1969-12-31 19:00:00.000000000 -0500
12383 +++ um/arch/um/fs/hostfs/Makefile 2002-10-23 21:08:04.000000000 -0400
12386 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
12387 +# Licensed under the GPL
12390 +# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino
12391 +# to __st_ino. It stayed in the same place, so as long as the correct name
12392 +# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa.
12394 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
12397 +USER_CFLAGS := $(USER_CFLAGS) -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
12399 +O_TARGET := hostfs.o
12400 +obj-y = hostfs_kern.o hostfs_user.o
12401 +obj-m = $(O_TARGET)
12403 +USER_OBJS = $(filter %_user.o,$(obj-y))
12405 +include $(TOPDIR)/Rules.make
12407 +$(USER_OBJS) : %.o: %.c
12408 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
12409 diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/hppfs_kern.c um/arch/um/fs/hppfs/hppfs_kern.c
12410 --- orig/arch/um/fs/hppfs/hppfs_kern.c 1969-12-31 19:00:00.000000000 -0500
12411 +++ um/arch/um/fs/hppfs/hppfs_kern.c 2003-02-27 13:14:26.000000000 -0500
12414 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
12415 + * Licensed under the GPL
12418 +#include <linux/fs.h>
12419 +#include <linux/module.h>
12420 +#include <linux/slab.h>
12421 +#include <linux/list.h>
12422 +#include <linux/kernel.h>
12423 +#include <linux/ctype.h>
12424 +#include <asm/uaccess.h>
12427 +struct hppfs_data {
12428 + struct list_head list;
12429 + char contents[PAGE_SIZE - sizeof(struct list_head)];
12432 +struct hppfs_private {
12433 + struct file proc_file;
12436 + struct hppfs_data *contents;
12439 +#define HPPFS_SUPER_MAGIC 0xb00000ee
12441 +static struct super_operations hppfs_sbops;
12443 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
12446 +static int is_pid(struct dentry *dentry)
12448 + struct super_block *sb;
12451 + sb = dentry->d_sb;
12452 + if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
12455 + for(i = 0; i < dentry->d_name.len; i++){
12456 + if(!isdigit(dentry->d_name.name[i]))
12462 +static char *dentry_name(struct dentry *dentry, int extra)
12464 + struct dentry *parent;
12465 + char *root, *name;
12466 + const char *seg_name;
12467 + int len, seg_len;
12471 + while(parent->d_parent != parent){
12472 + if(is_pid(parent))
12473 + len += strlen("pid") + 1;
12474 + else len += parent->d_name.len + 1;
12475 + parent = parent->d_parent;
12479 + len += strlen(root);
12480 + name = kmalloc(len + extra + 1, GFP_KERNEL);
12481 + if(name == NULL) return(NULL);
12483 + name[len] = '\0';
12485 + while(parent->d_parent != parent){
12486 + if(is_pid(parent)){
12487 + seg_name = "pid";
12488 + seg_len = strlen("pid");
12491 + seg_name = parent->d_name.name;
12492 + seg_len = parent->d_name.len;
12495 + len -= seg_len + 1;
12497 + strncpy(&name[len + 1], seg_name, seg_len);
12498 + parent = parent->d_parent;
12500 + strncpy(name, root, strlen(root));
12504 +struct dentry_operations hppfs_dentry_ops = {
12507 +static int file_removed(struct dentry *dentry, const char *file)
12513 + if(file != NULL) extra += strlen(file) + 1;
12515 + host_file = dentry_name(dentry, extra + strlen("/remove"));
12516 + if(host_file == NULL){
12517 + printk("file_removed : allocation failed\n");
12521 + if(file != NULL){
12522 + strcat(host_file, "/");
12523 + strcat(host_file, file);
12525 + strcat(host_file, "/remove");
12527 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
12528 + kfree(host_file);
12530 + os_close_file(fd);
12536 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry)
12538 + struct dentry *proc_dentry;
12539 + struct inode *inode;
12540 + int err, deleted;
12542 + deleted = file_removed(dentry, NULL);
12544 + return(ERR_PTR(deleted));
12546 + return(ERR_PTR(-ENOENT));
12548 + proc_dentry = lookup_hash(&dentry->d_name, ino->u.hppfs_i.proc_dentry);
12549 + if(IS_ERR(proc_dentry))
12550 + return(proc_dentry);
12552 + inode = get_inode(ino->i_sb, proc_dentry, &err);
12554 + return(ERR_PTR(err));
12556 + d_add(dentry, inode);
12557 + dentry->d_op = &hppfs_dentry_ops;
12561 +static struct inode_operations hppfs_file_iops = {
12564 +static struct inode_operations hppfs_dir_iops = {
12565 + .lookup = hppfs_lookup,
12568 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count,
12569 + loff_t *ppos, int is_user)
12571 + ssize_t (*read)(struct file *, char *, size_t, loff_t *);
12574 + read = file->f_dentry->d_inode->i_fop->read;
12577 + set_fs(KERNEL_DS);
12579 + n = (*read)(file, buf, count, &file->f_pos);
12584 + if(ppos) *ppos = file->f_pos;
12588 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
12595 + new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
12596 + if(new_buf == NULL){
12597 + printk("hppfs_read_file : kmalloc failed\n");
12601 + while(count > 0){
12602 + cur = min_t(ssize_t, count, PAGE_SIZE);
12603 + err = os_read_file(fd, new_buf, cur);
12605 + printk("hppfs_read : read failed, errno = %d\n",
12610 + else if(err == 0)
12613 + if(copy_to_user(buf, new_buf, err)){
12626 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
12629 + struct hppfs_private *hppfs = file->private_data;
12630 + struct hppfs_data *data;
12634 + if(hppfs->contents != NULL){
12635 + if(*ppos >= hppfs->len) return(0);
12637 + data = hppfs->contents;
12639 + while(off >= sizeof(data->contents)){
12640 + data = list_entry(data->list.next, struct hppfs_data,
12642 + off -= sizeof(data->contents);
12645 + if(off + count > hppfs->len)
12646 + count = hppfs->len - off;
12647 + copy_to_user(buf, &data->contents[off], count);
12650 + else if(hppfs->host_fd != -1){
12651 + err = os_seek_file(hppfs->host_fd, *ppos);
12653 + printk("hppfs_read : seek failed, errno = %d\n", err);
12656 + count = hppfs_read_file(hppfs->host_fd, buf, count);
12660 + else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
12665 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len,
12668 + struct hppfs_private *data = file->private_data;
12669 + struct file *proc_file = &data->proc_file;
12670 + ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
12673 + write = proc_file->f_dentry->d_inode->i_fop->write;
12675 + proc_file->f_pos = file->f_pos;
12676 + err = (*write)(proc_file, buf, len, &proc_file->f_pos);
12677 + file->f_pos = proc_file->f_pos;
12682 +static int open_host_sock(char *host_file, int *filter_out)
12687 + end = &host_file[strlen(host_file)];
12688 + strcpy(end, "/rw");
12690 + fd = os_connect_socket(host_file);
12694 + strcpy(end, "/r");
12696 + fd = os_connect_socket(host_file);
12700 +static void free_contents(struct hppfs_data *head)
12702 + struct hppfs_data *data;
12703 + struct list_head *ele, *next;
12705 + if(head == NULL) return;
12707 + list_for_each_safe(ele, next, &head->list){
12708 + data = list_entry(ele, struct hppfs_data, list);
12714 +static struct hppfs_data *hppfs_get_data(int fd, int filter,
12715 + struct file *proc_file,
12716 + struct file *hppfs_file,
12717 + loff_t *size_out)
12719 + struct hppfs_data *data, *new, *head;
12723 + data = kmalloc(sizeof(*data), GFP_KERNEL);
12724 + if(data == NULL){
12725 + printk("hppfs_get_data : head allocation failed\n");
12729 + INIT_LIST_HEAD(&data->list);
12735 + while((n = read_proc(proc_file, data->contents,
12736 + sizeof(data->contents), NULL, 0)) > 0)
12737 + os_write_file(fd, data->contents, n);
12738 + err = os_shutdown_socket(fd, 0, 1);
12740 + printk("hppfs_get_data : failed to shut down "
12742 + goto failed_free;
12746 + n = os_read_file(fd, data->contents, sizeof(data->contents));
12749 + printk("hppfs_get_data : read failed, errno = %d\n",
12751 + goto failed_free;
12758 + if(n < sizeof(data->contents))
12761 + new = kmalloc(sizeof(*data), GFP_KERNEL);
12763 + printk("hppfs_get_data : data allocation failed\n");
12765 + goto failed_free;
12768 + INIT_LIST_HEAD(&new->list);
12769 + list_add(&new->list, &data->list);
12775 + free_contents(head);
12777 + return(ERR_PTR(err));
12780 +static struct hppfs_private *hppfs_data(void)
12782 + struct hppfs_private *data;
12784 + data = kmalloc(sizeof(*data), GFP_KERNEL);
12788 + *data = ((struct hppfs_private ) { .host_fd = -1,
12790 + .contents = NULL } );
12794 +static int hppfs_open(struct inode *inode, struct file *file)
12796 + struct hppfs_private *data;
12797 + struct dentry *proc_dentry;
12799 + int err, fd, type, filter;
12802 + data = hppfs_data();
12806 + host_file = dentry_name(file->f_dentry, strlen("/rw"));
12807 + if(host_file == NULL)
12810 + proc_dentry = inode->u.hppfs_i.proc_dentry;
12811 + err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
12815 + type = os_file_type(host_file);
12816 + if(type == OS_TYPE_FILE){
12817 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
12819 + data->host_fd = fd;
12820 + else printk("hppfs_open : failed to open '%s', errno = %d\n",
12823 + data->contents = NULL;
12825 + else if(type == OS_TYPE_DIR){
12826 + fd = open_host_sock(host_file, &filter);
12828 + data->contents = hppfs_get_data(fd, filter,
12829 + &data->proc_file,
12830 + file, &data->len);
12831 + if(!IS_ERR(data->contents))
12832 + data->host_fd = fd;
12834 + else printk("hppfs_open : failed to open a socket in "
12835 + "'%s', errno = %d\n", host_file, -fd);
12837 + kfree(host_file);
12839 + file->private_data = data;
12843 + kfree(host_file);
12845 + free_contents(data->contents);
12851 +static int hppfs_dir_open(struct inode *inode, struct file *file)
12853 + struct hppfs_private *data;
12854 + struct dentry *proc_dentry;
12858 + data = hppfs_data();
12862 + proc_dentry = inode->u.hppfs_i.proc_dentry;
12863 + err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
12867 + file->private_data = data;
12876 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
12878 + struct hppfs_private *data = file->private_data;
12879 + struct file *proc_file = &data->proc_file;
12880 + loff_t (*llseek)(struct file *, loff_t, int);
12883 + llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
12884 + if(llseek != NULL){
12885 + ret = (*llseek)(proc_file, off, where);
12890 + return(default_llseek(file, off, where));
12893 +struct hppfs_dirent {
12894 + void *vfs_dirent;
12895 + filldir_t filldir;
12896 + struct dentry *dentry;
12899 +static int hppfs_filldir(void *d, const char *name, int size,
12900 + loff_t offset, ino_t inode, unsigned int type)
12902 + struct hppfs_dirent *dirent = d;
12904 + if(file_removed(dirent->dentry, name))
12907 + return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
12911 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
12913 + struct hppfs_private *data = file->private_data;
12914 + struct file *proc_file = &data->proc_file;
12915 + int (*readdir)(struct file *, void *, filldir_t);
12916 + struct hppfs_dirent dirent = ((struct hppfs_dirent)
12917 + { .vfs_dirent = ent,
12918 + .filldir = filldir,
12919 + .dentry = file->f_dentry } );
12922 + readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
12924 + proc_file->f_pos = file->f_pos;
12925 + err = (*readdir)(proc_file, &dirent, hppfs_filldir);
12926 + file->f_pos = proc_file->f_pos;
12931 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
12936 +static struct file_operations hppfs_file_fops = {
12938 + .llseek = hppfs_llseek,
12939 + .read = hppfs_read,
12940 + .write = hppfs_write,
12941 + .open = hppfs_open,
12944 +static struct file_operations hppfs_dir_fops = {
12946 + .readdir = hppfs_readdir,
12947 + .open = hppfs_dir_open,
12948 + .fsync = hppfs_fsync,
12951 +static int hppfs_statfs(struct super_block *sb, struct statfs *sf)
12953 + sf->f_blocks = 0;
12955 + sf->f_bavail = 0;
12958 + sf->f_type = HPPFS_SUPER_MAGIC;
12962 +static struct super_operations hppfs_sbops = {
12963 + .put_inode = force_delete,
12964 + .delete_inode = NULL,
12965 + .statfs = hppfs_statfs,
12968 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
12970 + struct file proc_file;
12971 + struct dentry *proc_dentry;
12972 + int (*readlink)(struct dentry *, char *, int);
12975 + proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
12976 + err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
12980 + readlink = proc_dentry->d_inode->i_op->readlink;
12981 + n = (*readlink)(proc_dentry, buffer, buflen);
12983 + if(proc_file.f_op->release)
12984 + (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
12989 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
12991 + struct file proc_file;
12992 + struct dentry *proc_dentry;
12993 + int (*follow_link)(struct dentry *, struct nameidata *);
12996 + proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
12997 + err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
13001 + follow_link = proc_dentry->d_inode->i_op->follow_link;
13002 + n = (*follow_link)(proc_dentry, nd);
13004 + if(proc_file.f_op->release)
13005 + (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
13010 +static struct inode_operations hppfs_link_iops = {
13011 + .readlink = hppfs_readlink,
13012 + .follow_link = hppfs_follow_link,
13015 +static void read_inode(struct inode *ino)
13017 + struct inode *proc_ino;
13019 + proc_ino = ino->u.hppfs_i.proc_dentry->d_inode;
13020 + ino->i_uid = proc_ino->i_uid;
13021 + ino->i_gid = proc_ino->i_gid;
13022 + ino->i_atime = proc_ino->i_atime;
13023 + ino->i_mtime = proc_ino->i_mtime;
13024 + ino->i_ctime = proc_ino->i_ctime;
13025 + ino->i_ino = proc_ino->i_ino;
13026 + ino->i_dev = proc_ino->i_dev;
13027 + ino->i_mode = proc_ino->i_mode;
13028 + ino->i_nlink = proc_ino->i_nlink;
13029 + ino->i_size = proc_ino->i_size;
13030 + ino->i_blksize = proc_ino->i_blksize;
13031 + ino->i_blocks = proc_ino->i_blocks;
13034 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
13037 + struct inode *inode;
13038 + int err = -ENOMEM;
13040 + inode = new_inode(sb);
13041 + if(inode == NULL)
13044 + insert_inode_hash(inode);
13045 + if(S_ISDIR(dentry->d_inode->i_mode)){
13046 + inode->i_op = &hppfs_dir_iops;
13047 + inode->i_fop = &hppfs_dir_fops;
13049 + else if(S_ISLNK(dentry->d_inode->i_mode)){
13050 + inode->i_op = &hppfs_link_iops;
13051 + inode->i_fop = &hppfs_file_fops;
13054 + inode->i_op = &hppfs_file_iops;
13055 + inode->i_fop = &hppfs_file_fops;
13058 + inode->i_sb = sb;
13059 + inode->u.hppfs_i.proc_dentry = dentry;
13061 + read_inode(inode);
13064 + if(error) *error = err;
13067 + if(error) *error = err;
13071 +static struct super_block *hppfs_read_super(struct super_block *sb, void *d,
13074 + struct inode *root_inode;
13075 + struct file_system_type *procfs;
13076 + struct super_block *proc_sb;
13078 + procfs = get_fs_type("proc");
13079 + if(procfs == NULL)
13082 + if(list_empty(&procfs->fs_supers))
13085 + proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
13088 + sb->s_blocksize = 1024;
13089 + sb->s_blocksize_bits = 10;
13090 + sb->s_magic = HPPFS_SUPER_MAGIC;
13091 + sb->s_op = &hppfs_sbops;
13093 + dget(proc_sb->s_root);
13094 + root_inode = get_inode(sb, proc_sb->s_root, NULL);
13095 + if(root_inode == NULL)
13098 + sb->s_root = d_alloc_root(root_inode);
13099 + if(sb->s_root == NULL)
13105 + iput(root_inode);
13107 + dput(proc_sb->s_root);
13112 +DECLARE_FSTYPE(hppfs_type, "hppfs", hppfs_read_super, 0);
13114 +static int __init init_hppfs(void)
13116 + return(register_filesystem(&hppfs_type));
13119 +static void __exit exit_hppfs(void)
13121 + unregister_filesystem(&hppfs_type);
13124 +module_init(init_hppfs)
13125 +module_exit(exit_hppfs)
13126 +MODULE_LICENSE("GPL");
13129 + * Overrides for Emacs so that we follow Linus's tabbing style.
13130 + * Emacs will notice this stuff at the end of the file and automatically
13131 + * adjust the settings for this buffer only. This must remain at the end
13133 + * ---------------------------------------------------------------------------
13134 + * Local variables:
13135 + * c-file-style: "linux"
13138 diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/Makefile um/arch/um/fs/hppfs/Makefile
13139 --- orig/arch/um/fs/hppfs/Makefile 1969-12-31 19:00:00.000000000 -0500
13140 +++ um/arch/um/fs/hppfs/Makefile 2002-10-23 21:08:04.000000000 -0400
13142 +O_TARGET := hppfs.o
13143 +obj-y = hppfs_kern.o #hppfs_user.o
13144 +obj-m = $(O_TARGET)
13146 +CFLAGS_hppfs_kern.o := $(CFLAGS)
13147 +#CFLAGS_hppfs_user.o := $(USER_CFLAGS)
13151 +include $(TOPDIR)/Rules.make
13152 diff -Naur -X ../exclude-files orig/arch/um/fs/Makefile um/arch/um/fs/Makefile
13153 --- orig/arch/um/fs/Makefile 1969-12-31 19:00:00.000000000 -0500
13154 +++ um/arch/um/fs/Makefile 2002-10-23 21:08:04.000000000 -0400
13157 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13158 +# Licensed under the GPL
13161 +O_TARGET := built-in.o
13166 +subdir-$(CONFIG_HOSTFS) += hostfs
13167 +subdir-$(CONFIG_HPPFS) += hppfs
13169 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
13170 +obj-m += $(join $(subdir-m),$(subdir-m:%=/%.o))
13172 +include $(TOPDIR)/Rules.make
13179 diff -Naur -X ../exclude-files orig/arch/um/include/2_5compat.h um/arch/um/include/2_5compat.h
13180 --- orig/arch/um/include/2_5compat.h 1969-12-31 19:00:00.000000000 -0500
13181 +++ um/arch/um/include/2_5compat.h 2003-02-27 20:15:19.000000000 -0500
13184 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
13185 + * Licensed under the GPL
13188 +#ifndef __2_5_COMPAT_H__
13189 +#define __2_5_COMPAT_H__
13191 +#include "linux/version.h"
13193 +#define INIT_CONSOLE(dev_name, write_proc, device_proc, setup_proc, f) { \
13194 + name : dev_name, \
13195 + write : write_proc, \
13197 + device : device_proc, \
13198 + unblank : NULL, \
13199 + setup : setup_proc, \
13206 +#define INIT_ELV(queue, elv) elevator_init(elv, ELV_NOOP)
13208 +#define ELV_NOOP ELEVATOR_NOOP
13210 +#define INIT_HARDSECT(arr, maj, sizes) arr[maj] = sizes
13212 +#define IS_WRITE(req) ((req)->cmd == WRITE)
13214 +#define SET_PRI(task) \
13215 + do { (task)->nice = 20; (task)->counter = -100; } while(0);
13220 + * Overrides for Emacs so that we follow Linus's tabbing style.
13221 + * Emacs will notice this stuff at the end of the file and automatically
13222 + * adjust the settings for this buffer only. This must remain at the end
13224 + * ---------------------------------------------------------------------------
13225 + * Local variables:
13226 + * c-file-style: "linux"
13229 diff -Naur -X ../exclude-files orig/arch/um/include/chan_kern.h um/arch/um/include/chan_kern.h
13230 --- orig/arch/um/include/chan_kern.h 1969-12-31 19:00:00.000000000 -0500
13231 +++ um/arch/um/include/chan_kern.h 2002-11-15 13:32:35.000000000 -0500
13234 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
13235 + * Licensed under the GPL
13238 +#ifndef __CHAN_KERN_H__
13239 +#define __CHAN_KERN_H__
13241 +#include "linux/tty.h"
13242 +#include "linux/list.h"
13243 +#include "chan_user.h"
13246 + struct list_head list;
13248 + unsigned int primary:1;
13249 + unsigned int input:1;
13250 + unsigned int output:1;
13251 + unsigned int opened:1;
13253 + enum chan_init_pri pri;
13254 + struct chan_ops *ops;
13258 +extern void chan_interrupt(struct list_head *chans, struct tq_struct *task,
13259 + struct tty_struct *tty, int irq, void *dev);
13260 +extern int parse_chan_pair(char *str, struct list_head *chans, int pri,
13261 + int device, struct chan_opts *opts);
13262 +extern int open_chan(struct list_head *chans);
13263 +extern int write_chan(struct list_head *chans, const char *buf, int len,
13265 +extern int console_write_chan(struct list_head *chans, const char *buf,
13267 +extern void close_chan(struct list_head *chans);
13268 +extern void chan_enable_winch(struct list_head *chans, void *line);
13269 +extern void enable_chan(struct list_head *chans, void *data);
13270 +extern int chan_window_size(struct list_head *chans,
13271 + unsigned short *rows_out,
13272 + unsigned short *cols_out);
13273 +extern int chan_out_fd(struct list_head *chans);
13274 +extern int chan_config_string(struct list_head *chans, char *str, int size,
13275 + char **error_out);
13280 + * Overrides for Emacs so that we follow Linus's tabbing style.
13281 + * Emacs will notice this stuff at the end of the file and automatically
13282 + * adjust the settings for this buffer only. This must remain at the end
13284 + * ---------------------------------------------------------------------------
13285 + * Local variables:
13286 + * c-file-style: "linux"
13289 diff -Naur -X ../exclude-files orig/arch/um/include/chan_user.h um/arch/um/include/chan_user.h
13290 --- orig/arch/um/include/chan_user.h 1969-12-31 19:00:00.000000000 -0500
13291 +++ um/arch/um/include/chan_user.h 2002-11-06 16:44:00.000000000 -0500
13294 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
13295 + * Licensed under the GPL
13298 +#ifndef __CHAN_USER_H__
13299 +#define __CHAN_USER_H__
13303 +struct chan_opts {
13304 + void (*announce)(char *dev_name, int dev);
13305 + char *xterm_title;
13307 + unsigned long tramp_stack;
13311 +enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE };
13315 + void *(*init)(char *, int, struct chan_opts *);
13316 + int (*open)(int, int, int, void *, char **);
13317 + void (*close)(int, void *);
13318 + int (*read)(int, char *, void *);
13319 + int (*write)(int, const char *, int, void *);
13320 + int (*console_write)(int, const char *, int, void *);
13321 + int (*window_size)(int, void *, unsigned short *, unsigned short *);
13322 + void (*free)(void *);
13326 +extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops,
13329 +extern void generic_close(int fd, void *unused);
13330 +extern int generic_read(int fd, char *c_out, void *unused);
13331 +extern int generic_write(int fd, const char *buf, int n, void *unused);
13332 +extern int generic_console_write(int fd, const char *buf, int n, void *state);
13333 +extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
13334 + unsigned short *cols_out);
13335 +extern void generic_free(void *data);
13337 +extern void register_winch(int fd, void *device_data);
13338 +extern void register_winch_irq(int fd, int tty_fd, int pid, void *line);
13340 +#define __channel_help(fn, prefix) \
13341 +__uml_help(fn, prefix "[0-9]*=<channel description>\n" \
13342 +" Attach a console or serial line to a host channel. See\n" \
13343 +" http://user-mode-linux.sourceforge.net/input.html for a complete\n" \
13344 +" description of this switch.\n\n" \
13350 + * Overrides for Emacs so that we follow Linus's tabbing style.
13351 + * Emacs will notice this stuff at the end of the file and automatically
13352 + * adjust the settings for this buffer only. This must remain at the end
13354 + * ---------------------------------------------------------------------------
13355 + * Local variables:
13356 + * c-file-style: "linux"
13359 diff -Naur -X ../exclude-files orig/arch/um/include/choose-mode.h um/arch/um/include/choose-mode.h
13360 --- orig/arch/um/include/choose-mode.h 1969-12-31 19:00:00.000000000 -0500
13361 +++ um/arch/um/include/choose-mode.h 2003-01-17 13:23:32.000000000 -0500
13364 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13365 + * Licensed under the GPL
13368 +#ifndef __CHOOSE_MODE_H__
13369 +#define __CHOOSE_MODE_H__
13371 +#include "uml-config.h"
13373 +#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS)
13374 +#define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas))
13376 +#elif defined(UML_CONFIG_MODE_SKAS)
13377 +#define CHOOSE_MODE(tt, skas) (skas)
13379 +#elif defined(UML_CONFIG_MODE_TT)
13380 +#define CHOOSE_MODE(tt, skas) (tt)
13383 +#define CHOOSE_MODE_PROC(tt, skas, args...) \
13384 + CHOOSE_MODE(tt(args), skas(args))
13389 + * Overrides for Emacs so that we follow Linus's tabbing style.
13390 + * Emacs will notice this stuff at the end of the file and automatically
13391 + * adjust the settings for this buffer only. This must remain at the end
13393 + * ---------------------------------------------------------------------------
13394 + * Local variables:
13395 + * c-file-style: "linux"
13398 diff -Naur -X ../exclude-files orig/arch/um/include/frame.h um/arch/um/include/frame.h
13399 --- orig/arch/um/include/frame.h 1969-12-31 19:00:00.000000000 -0500
13400 +++ um/arch/um/include/frame.h 2002-12-02 21:43:03.000000000 -0500
13403 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13404 + * Licensed under the GPL
13407 +#ifndef __FRAME_H_
13408 +#define __FRAME_H_
13410 +#include "sysdep/frame.h"
13412 +struct frame_common {
13419 + struct arch_frame_data arch;
13423 + struct frame_common common;
13427 +extern struct sc_frame signal_frame_sc;
13429 +extern struct sc_frame signal_frame_sc_sr;
13432 + struct frame_common common;
13439 +extern struct si_frame signal_frame_si;
13441 +extern void capture_signal_stack(void);
13446 + * Overrides for Emacs so that we follow Linus's tabbing style.
13447 + * Emacs will notice this stuff at the end of the file and automatically
13448 + * adjust the settings for this buffer only. This must remain at the end
13450 + * ---------------------------------------------------------------------------
13451 + * Local variables:
13452 + * c-file-style: "linux"
13455 diff -Naur -X ../exclude-files orig/arch/um/include/frame_kern.h um/arch/um/include/frame_kern.h
13456 --- orig/arch/um/include/frame_kern.h 1969-12-31 19:00:00.000000000 -0500
13457 +++ um/arch/um/include/frame_kern.h 2002-10-23 21:08:04.000000000 -0400
13460 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13461 + * Licensed under the GPL
13464 +#ifndef __FRAME_KERN_H_
13465 +#define __FRAME_KERN_H_
13467 +#include "frame.h"
13468 +#include "sysdep/frame_kern.h"
13470 +extern int setup_signal_stack_sc(unsigned long stack_top, int sig,
13471 + unsigned long handler,
13472 + void (*restorer)(void),
13473 + struct pt_regs *regs,
13475 +extern int setup_signal_stack_si(unsigned long stack_top, int sig,
13476 + unsigned long handler,
13477 + void (*restorer)(void),
13478 + struct pt_regs *regs, siginfo_t *info,
13484 + * Overrides for Emacs so that we follow Linus's tabbing style.
13485 + * Emacs will notice this stuff at the end of the file and automatically
13486 + * adjust the settings for this buffer only. This must remain at the end
13488 + * ---------------------------------------------------------------------------
13489 + * Local variables:
13490 + * c-file-style: "linux"
13493 diff -Naur -X ../exclude-files orig/arch/um/include/frame_user.h um/arch/um/include/frame_user.h
13494 --- orig/arch/um/include/frame_user.h 1969-12-31 19:00:00.000000000 -0500
13495 +++ um/arch/um/include/frame_user.h 2002-10-23 21:08:04.000000000 -0400
13498 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13499 + * Licensed under the GPL
13502 +#ifndef __FRAME_USER_H_
13503 +#define __FRAME_USER_H_
13505 +#include "sysdep/frame_user.h"
13506 +#include "frame.h"
13511 + * Overrides for Emacs so that we follow Linus's tabbing style.
13512 + * Emacs will notice this stuff at the end of the file and automatically
13513 + * adjust the settings for this buffer only. This must remain at the end
13515 + * ---------------------------------------------------------------------------
13516 + * Local variables:
13517 + * c-file-style: "linux"
13520 diff -Naur -X ../exclude-files orig/arch/um/include/helper.h um/arch/um/include/helper.h
13521 --- orig/arch/um/include/helper.h 1969-12-31 19:00:00.000000000 -0500
13522 +++ um/arch/um/include/helper.h 2002-10-23 21:08:04.000000000 -0400
13525 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13526 + * Licensed under the GPL
13529 +#ifndef __HELPER_H__
13530 +#define __HELPER_H__
13532 +extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
13533 + unsigned long *stack_out);
13534 +extern int run_helper_thread(int (*proc)(void *), void *arg,
13535 + unsigned int flags, unsigned long *stack_out,
13536 + int stack_order);
13537 +extern int helper_wait(int pid);
13542 + * Overrides for Emacs so that we follow Linus's tabbing style.
13543 + * Emacs will notice this stuff at the end of the file and automatically
13544 + * adjust the settings for this buffer only. This must remain at the end
13546 + * ---------------------------------------------------------------------------
13547 + * Local variables:
13548 + * c-file-style: "linux"
13551 diff -Naur -X ../exclude-files orig/arch/um/include/hostaudio.h um/arch/um/include/hostaudio.h
13552 --- orig/arch/um/include/hostaudio.h 1969-12-31 19:00:00.000000000 -0500
13553 +++ um/arch/um/include/hostaudio.h 2002-10-23 21:08:04.000000000 -0400
13556 + * Copyright (C) 2002 Steve Schmidtke
13557 + * Licensed under the GPL
13560 +#ifndef HOSTAUDIO_H
13561 +#define HOSTAUDIO_H
13563 +#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
13564 +#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
13566 +struct hostaudio_state {
13570 +struct hostmixer_state {
13574 +/* UML user-side protoypes */
13575 +extern ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer,
13576 + size_t count, loff_t *ppos);
13577 +extern ssize_t hostaudio_write_user(struct hostaudio_state *state,
13578 + const char *buffer, size_t count,
13580 +extern int hostaudio_ioctl_user(struct hostaudio_state *state,
13581 + unsigned int cmd, unsigned long arg);
13582 +extern int hostaudio_open_user(struct hostaudio_state *state, int r, int w,
13584 +extern int hostaudio_release_user(struct hostaudio_state *state);
13585 +extern int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state,
13586 + unsigned int cmd, unsigned long arg);
13587 +extern int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r,
13588 + int w, char *mixer);
13589 +extern int hostmixer_release_mixdev_user(struct hostmixer_state *state);
13591 +#endif /* HOSTAUDIO_H */
13594 + * Overrides for Emacs so that we follow Linus's tabbing style.
13595 + * Emacs will notice this stuff at the end of the file and automatically
13596 + * adjust the settings for this buffer only. This must remain at the end
13598 + * ---------------------------------------------------------------------------
13599 + * Local variables:
13600 + * c-file-style: "linux"
13603 diff -Naur -X ../exclude-files orig/arch/um/include/init.h um/arch/um/include/init.h
13604 --- orig/arch/um/include/init.h 1969-12-31 19:00:00.000000000 -0500
13605 +++ um/arch/um/include/init.h 2002-10-23 21:08:04.000000000 -0400
13607 +#ifndef _LINUX_UML_INIT_H
13608 +#define _LINUX_UML_INIT_H
13610 +/* These macros are used to mark some functions or
13611 + * initialized data (doesn't apply to uninitialized data)
13612 + * as `initialization' functions. The kernel can take this
13613 + * as hint that the function is used only during the initialization
13614 + * phase and free up used memory resources after
13619 + * You should add __init immediately before the function name, like:
13621 + * static void __init initme(int x, int y)
13623 + * extern int z; z = x * y;
13626 + * If the function has a prototype somewhere, you can also add
13627 + * __init between closing brace of the prototype and semicolon:
13629 + * extern int initialize_foobar_device(int, int, int) __init;
13631 + * For initialized data:
13632 + * You should insert __initdata between the variable name and equal
13633 + * sign followed by value, e.g.:
13635 + * static int init_variable __initdata = 0;
13636 + * static char linux_logo[] __initdata = { 0x32, 0x36, ... };
13638 + * Don't forget to initialize data not at file scope, i.e. within a function,
13639 + * as gcc otherwise puts the data into the bss section and not into the init
13642 + * Also note, that this data cannot be "const".
13645 +#ifndef _LINUX_INIT_H
13646 +typedef int (*initcall_t)(void);
13647 +typedef void (*exitcall_t)(void);
13649 +#define __init __attribute__ ((__section__ (".text.init")))
13650 +#define __exit __attribute__ ((unused, __section__(".text.exit")))
13651 +#define __initdata __attribute__ ((__section__ (".data.init")))
13656 +struct uml_param {
13658 + int (*setup_func)(char *, int *);
13661 +extern initcall_t __uml_initcall_start, __uml_initcall_end;
13662 +extern initcall_t __uml_postsetup_start, __uml_postsetup_end;
13663 +extern const char *__uml_help_start, *__uml_help_end;
13666 +#define __uml_initcall(fn) \
13667 + static initcall_t __uml_initcall_##fn __uml_init_call = fn
13669 +#define __uml_exitcall(fn) \
13670 + static exitcall_t __uml_exitcall_##fn __uml_exit_call = fn
13672 +extern struct uml_param __uml_setup_start, __uml_setup_end;
13674 +#define __uml_postsetup(fn) \
13675 + static initcall_t __uml_postsetup_##fn __uml_postsetup_call = fn
13677 +#define __non_empty_string(dummyname,string) \
13678 + struct __uml_non_empty_string_struct_##dummyname \
13680 + char _string[sizeof(string)-2]; \
13684 +#define __uml_setup(str, fn, help...) \
13685 + __non_empty_string(fn ##_setup, str); \
13686 + __uml_help(fn, help); \
13687 + static char __uml_setup_str_##fn[] __initdata = str; \
13688 + static struct uml_param __uml_setup_##fn __uml_init_setup = { __uml_setup_str_##fn, fn }
13690 +#define __uml_setup(str, fn, help...) \
13694 +#define __uml_help(fn, help...) \
13695 + __non_empty_string(fn ##__help, help); \
13696 + static char __uml_help_str_##fn[] __initdata = help; \
13697 + static const char *__uml_help_##fn __uml_setup_help = __uml_help_str_##fn
13700 + * Mark functions and data as being only used at initialization
13703 +#define __uml_init_setup __attribute__ ((unused,__section__ (".uml.setup.init")))
13704 +#define __uml_setup_help __attribute__ ((unused,__section__ (".uml.help.init")))
13705 +#define __uml_init_call __attribute__ ((unused,__section__ (".uml.initcall.init")))
13706 +#define __uml_postsetup_call __attribute__ ((unused,__section__ (".uml.postsetup.init")))
13707 +#define __uml_exit_call __attribute__ ((unused,__section__ (".uml.exitcall.exit")))
13709 +#endif /* _LINUX_UML_INIT_H */
13712 + * Overrides for Emacs so that we follow Linus's tabbing style.
13713 + * Emacs will notice this stuff at the end of the file and automatically
13714 + * adjust the settings for this buffer only. This must remain at the end
13716 + * ---------------------------------------------------------------------------
13717 + * Local variables:
13718 + * c-file-style: "linux"
13721 diff -Naur -X ../exclude-files orig/arch/um/include/initrd.h um/arch/um/include/initrd.h
13722 --- orig/arch/um/include/initrd.h 1969-12-31 19:00:00.000000000 -0500
13723 +++ um/arch/um/include/initrd.h 2002-10-23 21:08:04.000000000 -0400
13726 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13727 + * Licensed under the GPL
13730 +#ifndef __INITRD_USER_H__
13731 +#define __INITRD_USER_H__
13733 +extern int load_initrd(char *filename, void *buf, int size);
13738 + * Overrides for Emacs so that we follow Linus's tabbing style.
13739 + * Emacs will notice this stuff at the end of the file and automatically
13740 + * adjust the settings for this buffer only. This must remain at the end
13742 + * ---------------------------------------------------------------------------
13743 + * Local variables:
13744 + * c-file-style: "linux"
13747 diff -Naur -X ../exclude-files orig/arch/um/include/irq_kern.h um/arch/um/include/irq_kern.h
13748 --- orig/arch/um/include/irq_kern.h 1969-12-31 19:00:00.000000000 -0500
13749 +++ um/arch/um/include/irq_kern.h 2003-05-15 13:57:48.000000000 -0400
13752 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
13753 + * Licensed under the GPL
13756 +#ifndef __IRQ_KERN_H__
13757 +#define __IRQ_KERN_H__
13759 +#include "linux/interrupt.h"
13761 +extern int um_request_irq(unsigned int irq, int fd, int type,
13762 + void (*handler)(int, void *, struct pt_regs *),
13763 + unsigned long irqflags, const char * devname,
13769 + * Overrides for Emacs so that we follow Linus's tabbing style.
13770 + * Emacs will notice this stuff at the end of the file and automatically
13771 + * adjust the settings for this buffer only. This must remain at the end
13773 + * ---------------------------------------------------------------------------
13774 + * Local variables:
13775 + * c-file-style: "linux"
13778 diff -Naur -X ../exclude-files orig/arch/um/include/irq_user.h um/arch/um/include/irq_user.h
13779 --- orig/arch/um/include/irq_user.h 1969-12-31 19:00:00.000000000 -0500
13780 +++ um/arch/um/include/irq_user.h 2002-12-08 20:38:42.000000000 -0500
13783 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
13784 + * Licensed under the GPL
13787 +#ifndef __IRQ_USER_H__
13788 +#define __IRQ_USER_H__
13790 +enum { IRQ_READ, IRQ_WRITE };
13792 +extern void sigio_handler(int sig, union uml_pt_regs *regs);
13793 +extern int activate_fd(int irq, int fd, int type, void *dev_id);
13794 +extern void free_irq_by_irq_and_dev(int irq, void *dev_id);
13795 +extern void free_irq_by_fd(int fd);
13796 +extern void reactivate_fd(int fd, int irqnum);
13797 +extern void deactivate_fd(int fd, int irqnum);
13798 +extern void forward_interrupts(int pid);
13799 +extern void init_irq_signals(int on_sigstack);
13800 +extern void forward_ipi(int fd, int pid);
13801 +extern void free_irq_later(int irq, void *dev_id);
13802 +extern int activate_ipi(int fd, int pid);
13803 +extern unsigned long irq_lock(void);
13804 +extern void irq_unlock(unsigned long flags);
13808 + * Overrides for Emacs so that we follow Linus's tabbing style.
13809 + * Emacs will notice this stuff at the end of the file and automatically
13810 + * adjust the settings for this buffer only. This must remain at the end
13812 + * ---------------------------------------------------------------------------
13813 + * Local variables:
13814 + * c-file-style: "linux"
13817 diff -Naur -X ../exclude-files orig/arch/um/include/kern.h um/arch/um/include/kern.h
13818 --- orig/arch/um/include/kern.h 1969-12-31 19:00:00.000000000 -0500
13819 +++ um/arch/um/include/kern.h 2002-11-02 21:38:02.000000000 -0500
13822 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13823 + * Licensed under the GPL
13826 +#ifndef __KERN_H__
13827 +#define __KERN_H__
13829 +/* These are all user-mode things which are convenient to call directly
13830 + * from kernel code and for which writing a wrapper is too much of a pain.
13831 + * The regular include files can't be included because this file is included
13832 + * only into kernel code, and user-space includes conflict with kernel
13838 +extern int clone(int (*proc)(void *), void *sp, int flags, void *data);
13839 +extern int sleep(int);
13840 +extern int printf(char *fmt, ...);
13841 +extern char *strerror(int errnum);
13842 +extern char *ptsname(int __fd);
13843 +extern int munmap(void *, int);
13844 +extern void *sbrk(int increment);
13845 +extern void *malloc(int size);
13846 +extern void perror(char *err);
13847 +extern int kill(int pid, int sig);
13848 +extern int getuid(void);
13849 +extern int pause(void);
13850 +extern int write(int, const void *, int);
13851 +extern int exit(int);
13852 +extern int close(int);
13853 +extern int read(unsigned int, char *, int);
13854 +extern int pipe(int *);
13855 +extern int sched_yield(void);
13856 +extern int ptrace(int op, int pid, long addr, long data);
13860 + * Overrides for Emacs so that we follow Linus's tabbing style.
13861 + * Emacs will notice this stuff at the end of the file and automatically
13862 + * adjust the settings for this buffer only. This must remain at the end
13864 + * ---------------------------------------------------------------------------
13865 + * Local variables:
13866 + * c-file-style: "linux"
13869 diff -Naur -X ../exclude-files orig/arch/um/include/kern_util.h um/arch/um/include/kern_util.h
13870 --- orig/arch/um/include/kern_util.h 1969-12-31 19:00:00.000000000 -0500
13871 +++ um/arch/um/include/kern_util.h 2003-04-16 16:00:11.000000000 -0400
13874 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
13875 + * Licensed under the GPL
13878 +#ifndef __KERN_UTIL_H__
13879 +#define __KERN_UTIL_H__
13881 +#include "sysdep/ptrace.h"
13884 +extern char *linux_prog;
13885 +extern char *gdb_init;
13886 +extern int kmalloc_ok;
13887 +extern int timer_irq_inited;
13889 +extern int nsyscalls;
13891 +#define UML_ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK))
13892 +#define UML_ROUND_UP(addr) \
13893 + UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
13895 +extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg);
13896 +extern unsigned long stack_sp(unsigned long page);
13897 +extern int kernel_thread_proc(void *data);
13898 +extern void syscall_segv(int sig);
13899 +extern int current_pid(void);
13900 +extern unsigned long alloc_stack(int order, int atomic);
13901 +extern int do_signal(int error);
13902 +extern int is_stack_fault(unsigned long sp);
13903 +extern unsigned long segv(unsigned long address, unsigned long ip,
13904 + int is_write, int is_user, void *sc);
13905 +extern unsigned long handle_page_fault(unsigned long address, unsigned long ip,
13906 + int is_write, int is_user,
13908 +extern void syscall_ready(void);
13909 +extern int segv_syscall(void);
13910 +extern void kern_finish_exec(void *task, int new_pid, unsigned long stack);
13911 +extern int page_size(void);
13912 +extern int page_mask(void);
13913 +extern int need_finish_fork(void);
13914 +extern void free_stack(unsigned long stack, int order);
13915 +extern void add_input_request(int op, void (*proc)(int), void *arg);
13916 +extern int sys_execve(char *file, char **argv, char **env);
13917 +extern char *current_cmd(void);
13918 +extern void timer_handler(int sig, union uml_pt_regs *regs);
13919 +extern int set_signals(int enable);
13920 +extern void force_sigbus(void);
13921 +extern int pid_to_processor_id(int pid);
13922 +extern void block_signals(void);
13923 +extern void unblock_signals(void);
13924 +extern void deliver_signals(void *t);
13925 +extern int next_syscall_index(int max);
13926 +extern int next_trap_index(int max);
13927 +extern void cpu_idle(void);
13928 +extern void finish_fork(void);
13929 +extern void paging_init(void);
13930 +extern void init_flush_vm(void);
13931 +extern void *syscall_sp(void *t);
13932 +extern void syscall_trace(void);
13933 +extern int hz(void);
13934 +extern void idle_timer(void);
13935 +extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
13936 +extern int external_pid(void *t);
13937 +extern void boot_timer_handler(int sig);
13938 +extern void interrupt_end(void);
13939 +extern void initial_thread_cb(void (*proc)(void *), void *arg);
13940 +extern int debugger_signal(int status, int pid);
13941 +extern void debugger_parent_signal(int status, int pid);
13942 +extern void child_signal(int pid, int status);
13943 +extern int init_ptrace_proxy(int idle_pid, int startup, int stop);
13944 +extern int init_parent_proxy(int pid);
13945 +extern void check_stack_overflow(void *ptr);
13946 +extern void relay_signal(int sig, union uml_pt_regs *regs);
13947 +extern void not_implemented(void);
13948 +extern int user_context(unsigned long sp);
13949 +extern void timer_irq(union uml_pt_regs *regs);
13950 +extern void unprotect_stack(unsigned long stack);
13951 +extern void do_uml_exitcalls(void);
13952 +extern int attach_debugger(int idle_pid, int pid, int stop);
13953 +extern void bad_segv(unsigned long address, unsigned long ip, int is_write);
13954 +extern int config_gdb(char *str);
13955 +extern int remove_gdb(void);
13956 +extern char *uml_strdup(char *string);
13957 +extern void unprotect_kernel_mem(void);
13958 +extern void protect_kernel_mem(void);
13959 +extern void set_kmem_end(unsigned long);
13960 +extern void uml_cleanup(void);
13961 +extern void set_current(void *t);
13962 +extern void lock_signalled_task(void *t);
13963 +extern void IPI_handler(int cpu);
13964 +extern int jail_setup(char *line, int *add);
13965 +extern void *get_init_task(void);
13966 +extern int clear_user_proc(void *buf, int size);
13967 +extern int copy_to_user_proc(void *to, void *from, int size);
13968 +extern int copy_from_user_proc(void *to, void *from, int size);
13969 +extern int strlen_user_proc(char *str);
13970 +extern void bus_handler(int sig, union uml_pt_regs *regs);
13971 +extern void winch(int sig, union uml_pt_regs *regs);
13972 +extern long execute_syscall(void *r);
13973 +extern int smp_sigio_handler(void);
13974 +extern void *get_current(void);
13975 +extern struct task_struct *get_task(int pid, int require);
13976 +extern void machine_halt(void);
13977 +extern int is_syscall(unsigned long addr);
13978 +extern void arch_switch(void);
13979 +extern void free_irq(unsigned int, void *);
13980 +extern int um_in_interrupt(void);
13981 +extern int cpu(void);
13985 + * Overrides for Emacs so that we follow Linus's tabbing style.
13986 + * Emacs will notice this stuff at the end of the file and automatically
13987 + * adjust the settings for this buffer only. This must remain at the end
13989 + * ---------------------------------------------------------------------------
13990 + * Local variables:
13991 + * c-file-style: "linux"
13994 diff -Naur -X ../exclude-files orig/arch/um/include/line.h um/arch/um/include/line.h
13995 --- orig/arch/um/include/line.h 1969-12-31 19:00:00.000000000 -0500
13996 +++ um/arch/um/include/line.h 2002-11-15 13:44:44.000000000 -0500
13999 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14000 + * Licensed under the GPL
14003 +#ifndef __LINE_H__
14004 +#define __LINE_H__
14006 +#include "linux/list.h"
14007 +#include "linux/tqueue.h"
14008 +#include "linux/tty.h"
14009 +#include "asm/semaphore.h"
14010 +#include "chan_user.h"
14011 +#include "mconsole_kern.h"
14013 +struct line_driver {
14015 + char *devfs_name;
14017 + short minor_start;
14021 + char *read_irq_name;
14023 + char *write_irq_name;
14024 + char *symlink_from;
14025 + char *symlink_to;
14026 + struct mc_device mc;
14032 + struct list_head chan_list;
14035 + struct tty_struct *tty;
14036 + struct semaphore sem;
14041 + struct tq_struct task;
14042 + struct line_driver *driver;
14046 +#define LINE_INIT(str, d) \
14047 + { init_str : str, \
14048 + init_pri : INIT_STATIC, \
14049 + chan_list : { }, \
14065 +#define LINES_INIT(n) { num : n }
14067 +extern void line_interrupt(int irq, void *data, struct pt_regs *unused);
14068 +extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
14069 +extern void line_close(struct line *lines, struct tty_struct *tty);
14070 +extern int line_open(struct line *lines, struct tty_struct *tty,
14071 + struct chan_opts *opts);
14072 +extern int line_setup(struct line *lines, int num, char *init,
14073 + int all_allowed);
14074 +extern int line_write(struct line *line, struct tty_struct *tty, int from_user,
14075 + const char *buf, int len);
14076 +extern int line_write_room(struct tty_struct *tty);
14077 +extern char *add_xterm_umid(char *base);
14078 +extern int line_setup_irq(int fd, int input, int output, void *data);
14079 +extern void line_close_chan(struct line *line);
14080 +extern void line_disable(struct line *line, int current_irq);
14081 +extern void line_register_devfs(struct lines *set,
14082 + struct line_driver *line_driver,
14083 + struct tty_driver *driver, struct line *lines,
14085 +extern void lines_init(struct line *lines, int nlines);
14086 +extern void close_lines(struct line *lines, int nlines);
14087 +extern int line_config(struct line *lines, int num, char *str);
14088 +extern int line_remove(struct line *lines, int num, char *str);
14089 +extern int line_get_config(char *dev, struct line *lines, int num, char *str,
14090 + int size, char **error_out);
14095 + * Overrides for Emacs so that we follow Linus's tabbing style.
14096 + * Emacs will notice this stuff at the end of the file and automatically
14097 + * adjust the settings for this buffer only. This must remain at the end
14099 + * ---------------------------------------------------------------------------
14100 + * Local variables:
14101 + * c-file-style: "linux"
14104 diff -Naur -X ../exclude-files orig/arch/um/include/Makefile um/arch/um/include/Makefile
14105 --- orig/arch/um/include/Makefile 1969-12-31 19:00:00.000000000 -0500
14106 +++ um/arch/um/include/Makefile 2002-10-23 21:08:04.000000000 -0400
14110 +sc.h : ../util/mk_sc
14111 + ../util/mk_sc > $@
14114 + $(MAKE) -C ../util mk_sc
14115 diff -Naur -X ../exclude-files orig/arch/um/include/mconsole.h um/arch/um/include/mconsole.h
14116 --- orig/arch/um/include/mconsole.h 1969-12-31 19:00:00.000000000 -0500
14117 +++ um/arch/um/include/mconsole.h 2003-01-17 13:48:25.000000000 -0500
14120 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
14121 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14122 + * Licensed under the GPL
14125 +#ifndef __MCONSOLE_H__
14126 +#define __MCONSOLE_H__
14128 +#ifndef __KERNEL__
14129 +#include <stdint.h>
14130 +#define u32 uint32_t
14133 +#define MCONSOLE_MAGIC (0xcafebabe)
14134 +#define MCONSOLE_MAX_DATA (512)
14135 +#define MCONSOLE_VERSION 2
14137 +struct mconsole_request {
14141 + char data[MCONSOLE_MAX_DATA];
14144 +struct mconsole_reply {
14148 + char data[MCONSOLE_MAX_DATA];
14151 +struct mconsole_notify {
14154 + enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
14155 + MCONSOLE_USER_NOTIFY } type;
14157 + char data[MCONSOLE_MAX_DATA];
14160 +struct mc_request;
14162 +struct mconsole_command
14165 + void (*handler)(struct mc_request *req);
14166 + int as_interrupt;
14172 + int as_interrupt;
14174 + int originating_fd;
14176 + unsigned char origin[128]; /* sockaddr_un */
14178 + struct mconsole_request request;
14179 + struct mconsole_command *cmd;
14182 +extern char mconsole_socket_name[];
14184 +extern int mconsole_unlink_socket(void);
14185 +extern int mconsole_reply(struct mc_request *req, char *reply, int err,
14188 +extern void mconsole_version(struct mc_request *req);
14189 +extern void mconsole_help(struct mc_request *req);
14190 +extern void mconsole_halt(struct mc_request *req);
14191 +extern void mconsole_reboot(struct mc_request *req);
14192 +extern void mconsole_config(struct mc_request *req);
14193 +extern void mconsole_remove(struct mc_request *req);
14194 +extern void mconsole_sysrq(struct mc_request *req);
14195 +extern void mconsole_cad(struct mc_request *req);
14196 +extern void mconsole_stop(struct mc_request *req);
14197 +extern void mconsole_go(struct mc_request *req);
14199 +extern int mconsole_get_request(int fd, struct mc_request *req);
14200 +extern int mconsole_notify(char *sock_name, int type, const void *data,
14202 +extern char *mconsole_notify_socket(void);
14203 +extern void lock_notify(void);
14204 +extern void unlock_notify(void);
14209 + * Overrides for Emacs so that we follow Linus's tabbing style.
14210 + * Emacs will notice this stuff at the end of the file and automatically
14211 + * adjust the settings for this buffer only. This must remain at the end
14213 + * ---------------------------------------------------------------------------
14214 + * Local variables:
14215 + * c-file-style: "linux"
14218 diff -Naur -X ../exclude-files orig/arch/um/include/mconsole_kern.h um/arch/um/include/mconsole_kern.h
14219 --- orig/arch/um/include/mconsole_kern.h 1969-12-31 19:00:00.000000000 -0500
14220 +++ um/arch/um/include/mconsole_kern.h 2002-11-15 15:21:58.000000000 -0500
14223 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14224 + * Licensed under the GPL
14227 +#ifndef __MCONSOLE_KERN_H__
14228 +#define __MCONSOLE_KERN_H__
14230 +#include "linux/config.h"
14231 +#include "linux/list.h"
14232 +#include "mconsole.h"
14234 +struct mconsole_entry {
14235 + struct list_head list;
14236 + struct mc_request request;
14239 +struct mc_device {
14240 + struct list_head list;
14242 + int (*config)(char *);
14243 + int (*get_config)(char *, char *, int, char **);
14244 + int (*remove)(char *);
14247 +#define CONFIG_CHUNK(str, size, current, chunk, end) \
14249 + current += strlen(chunk); \
14250 + if(current >= size) \
14252 + if(str != NULL){ \
14253 + strcpy(str, chunk); \
14254 + str += strlen(chunk); \
14260 +#ifdef CONFIG_MCONSOLE
14262 +extern void mconsole_register_dev(struct mc_device *new);
14266 +static inline void mconsole_register_dev(struct mc_device *new)
14275 + * Overrides for Emacs so that we follow Linus's tabbing style.
14276 + * Emacs will notice this stuff at the end of the file and automatically
14277 + * adjust the settings for this buffer only. This must remain at the end
14279 + * ---------------------------------------------------------------------------
14280 + * Local variables:
14281 + * c-file-style: "linux"
14284 diff -Naur -X ../exclude-files orig/arch/um/include/mem.h um/arch/um/include/mem.h
14285 --- orig/arch/um/include/mem.h 1969-12-31 19:00:00.000000000 -0500
14286 +++ um/arch/um/include/mem.h 2002-10-23 21:08:04.000000000 -0400
14289 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14290 + * Licensed under the GPL
14296 +struct vm_reserved {
14297 + struct list_head list;
14298 + unsigned long start;
14299 + unsigned long end;
14302 +extern void set_usable_vm(unsigned long start, unsigned long end);
14303 +extern void set_kmem_end(unsigned long new);
14308 + * Overrides for Emacs so that we follow Linus's tabbing style.
14309 + * Emacs will notice this stuff at the end of the file and automatically
14310 + * adjust the settings for this buffer only. This must remain at the end
14312 + * ---------------------------------------------------------------------------
14313 + * Local variables:
14314 + * c-file-style: "linux"
14317 diff -Naur -X ../exclude-files orig/arch/um/include/mem_user.h um/arch/um/include/mem_user.h
14318 --- orig/arch/um/include/mem_user.h 1969-12-31 19:00:00.000000000 -0500
14319 +++ um/arch/um/include/mem_user.h 2002-10-23 21:08:04.000000000 -0400
14322 + * arch/um/include/mem_user.h
14324 + * BRIEF MODULE DESCRIPTION
14325 + * user side memory interface for support IO memory inside user mode linux
14327 + * Copyright (C) 2001 RidgeRun, Inc.
14328 + * Author: RidgeRun, Inc.
14329 + * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
14331 + * This program is free software; you can redistribute it and/or modify it
14332 + * under the terms of the GNU General Public License as published by the
14333 + * Free Software Foundation; either version 2 of the License, or (at your
14334 + * option) any later version.
14336 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
14337 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14338 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
14339 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
14340 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
14341 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
14342 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
14343 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14344 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
14345 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14347 + * You should have received a copy of the GNU General Public License along
14348 + * with this program; if not, write to the Free Software Foundation, Inc.,
14349 + * 675 Mass Ave, Cambridge, MA 02139, USA.
14352 +#ifndef _MEM_USER_H
14353 +#define _MEM_USER_H
14355 +struct mem_region {
14357 + unsigned long start_pfn;
14358 + unsigned long start;
14359 + unsigned long len;
14364 +extern struct mem_region *regions[];
14365 +extern struct mem_region physmem_region;
14367 +#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
14369 +extern unsigned long host_task_size;
14370 +extern unsigned long task_size;
14372 +extern int init_mem_user(void);
14373 +extern int create_mem_file(unsigned long len);
14374 +extern void setup_range(int fd, char *driver, unsigned long start,
14375 + unsigned long pfn, unsigned long total, int need_vm,
14376 + struct mem_region *region, void *reserved);
14377 +extern void setup_memory(void *entry);
14378 +extern unsigned long find_iomem(char *driver, unsigned long *len_out);
14379 +extern int init_maps(struct mem_region *region);
14380 +extern int nregions(void);
14381 +extern int reserve_vm(unsigned long start, unsigned long end, void *e);
14382 +extern unsigned long get_vm(unsigned long len);
14383 +extern void setup_physmem(unsigned long start, unsigned long usable,
14384 + unsigned long len);
14385 +extern int setup_region(struct mem_region *region, void *entry);
14386 +extern void add_iomem(char *name, int fd, unsigned long size);
14387 +extern struct mem_region *phys_region(unsigned long phys);
14388 +extern unsigned long phys_offset(unsigned long phys);
14389 +extern void unmap_physmem(void);
14390 +extern int map_memory(unsigned long virt, unsigned long phys,
14391 + unsigned long len, int r, int w, int x);
14392 +extern int protect_memory(unsigned long addr, unsigned long len,
14393 + int r, int w, int x, int must_succeed);
14394 +extern unsigned long get_kmem_end(void);
14399 + * Overrides for Emacs so that we follow Linus's tabbing style.
14400 + * Emacs will notice this stuff at the end of the file and automatically
14401 + * adjust the settings for this buffer only. This must remain at the end
14403 + * ---------------------------------------------------------------------------
14404 + * Local variables:
14405 + * c-file-style: "linux"
14408 diff -Naur -X ../exclude-files orig/arch/um/include/mode.h um/arch/um/include/mode.h
14409 --- orig/arch/um/include/mode.h 1969-12-31 19:00:00.000000000 -0500
14410 +++ um/arch/um/include/mode.h 2003-01-17 13:23:32.000000000 -0500
14413 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14414 + * Licensed under the GPL
14417 +#ifndef __MODE_H__
14418 +#define __MODE_H__
14420 +#include "uml-config.h"
14422 +#ifdef UML_CONFIG_MODE_TT
14423 +#include "../kernel/tt/include/mode.h"
14426 +#ifdef UML_CONFIG_MODE_SKAS
14427 +#include "../kernel/skas/include/mode.h"
14433 + * Overrides for Emacs so that we follow Linus's tabbing style.
14434 + * Emacs will notice this stuff at the end of the file and automatically
14435 + * adjust the settings for this buffer only. This must remain at the end
14437 + * ---------------------------------------------------------------------------
14438 + * Local variables:
14439 + * c-file-style: "linux"
14442 diff -Naur -X ../exclude-files orig/arch/um/include/mode_kern.h um/arch/um/include/mode_kern.h
14443 --- orig/arch/um/include/mode_kern.h 1969-12-31 19:00:00.000000000 -0500
14444 +++ um/arch/um/include/mode_kern.h 2002-10-23 21:08:04.000000000 -0400
14447 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14448 + * Licensed under the GPL
14451 +#ifndef __MODE_KERN_H__
14452 +#define __MODE_KERN_H__
14454 +#include "linux/config.h"
14456 +#ifdef CONFIG_MODE_TT
14457 +#include "../kernel/tt/include/mode_kern.h"
14460 +#ifdef CONFIG_MODE_SKAS
14461 +#include "../kernel/skas/include/mode_kern.h"
14467 + * Overrides for Emacs so that we follow Linus's tabbing style.
14468 + * Emacs will notice this stuff at the end of the file and automatically
14469 + * adjust the settings for this buffer only. This must remain at the end
14471 + * ---------------------------------------------------------------------------
14472 + * Local variables:
14473 + * c-file-style: "linux"
14476 diff -Naur -X ../exclude-files orig/arch/um/include/net_kern.h um/arch/um/include/net_kern.h
14477 --- orig/arch/um/include/net_kern.h 1969-12-31 19:00:00.000000000 -0500
14478 +++ um/arch/um/include/net_kern.h 2002-10-23 21:08:04.000000000 -0400
14481 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14482 + * Licensed under the GPL
14485 +#ifndef __UM_NET_KERN_H
14486 +#define __UM_NET_KERN_H
14488 +#include "linux/netdevice.h"
14489 +#include "linux/skbuff.h"
14490 +#include "linux/socket.h"
14491 +#include "linux/list.h"
14494 + struct list_head list;
14495 + struct net_device *dev;
14497 + unsigned char mac[ETH_ALEN];
14501 +struct uml_net_private {
14502 + struct list_head list;
14504 + struct net_device *dev;
14505 + struct timer_list tl;
14506 + struct net_device_stats stats;
14508 + unsigned char mac[ETH_ALEN];
14510 + unsigned short (*protocol)(struct sk_buff *);
14511 + int (*open)(void *);
14512 + void (*close)(int, void *);
14513 + void (*remove)(void *);
14514 + int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
14515 + int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
14517 + void (*add_address)(unsigned char *, unsigned char *, void *);
14518 + void (*delete_address)(unsigned char *, unsigned char *, void *);
14519 + int (*set_mtu)(int mtu, void *);
14523 +struct net_kern_info {
14524 + void (*init)(struct net_device *, void *);
14525 + unsigned short (*protocol)(struct sk_buff *);
14526 + int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
14527 + int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
14530 +struct transport {
14531 + struct list_head list;
14533 + int (*setup)(char *, char **, void *);
14534 + struct net_user_info *user;
14535 + struct net_kern_info *kern;
14536 + int private_size;
14540 +extern struct net_device *ether_init(int);
14541 +extern unsigned short ether_protocol(struct sk_buff *);
14542 +extern int setup_etheraddr(char *str, unsigned char *addr);
14543 +extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
14544 +extern int tap_setup_common(char *str, char *type, char **dev_name,
14545 + char **mac_out, char **gate_addr);
14546 +extern void register_transport(struct transport *new);
14547 +extern unsigned short eth_protocol(struct sk_buff *skb);
14552 + * Overrides for Emacs so that we follow Linus's tabbing style.
14553 + * Emacs will notice this stuff at the end of the file and automatically
14554 + * adjust the settings for this buffer only. This must remain at the end
14556 + * ---------------------------------------------------------------------------
14557 + * Local variables:
14558 + * c-file-style: "linux"
14561 diff -Naur -X ../exclude-files orig/arch/um/include/net_user.h um/arch/um/include/net_user.h
14562 --- orig/arch/um/include/net_user.h 1969-12-31 19:00:00.000000000 -0500
14563 +++ um/arch/um/include/net_user.h 2002-10-23 21:08:04.000000000 -0400
14566 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14567 + * Licensed under the GPL
14570 +#ifndef __UM_NET_USER_H__
14571 +#define __UM_NET_USER_H__
14573 +#define ETH_ADDR_LEN (6)
14574 +#define ETH_HEADER_ETHERTAP (16)
14575 +#define ETH_HEADER_OTHER (14)
14576 +#define ETH_MAX_PACKET (1500)
14578 +#define UML_NET_VERSION (4)
14580 +struct net_user_info {
14581 + void (*init)(void *, void *);
14582 + int (*open)(void *);
14583 + void (*close)(int, void *);
14584 + void (*remove)(void *);
14585 + int (*set_mtu)(int mtu, void *);
14586 + void (*add_address)(unsigned char *, unsigned char *, void *);
14587 + void (*delete_address)(unsigned char *, unsigned char *, void *);
14591 +extern void ether_user_init(void *data, void *dev);
14592 +extern void dev_ip_addr(void *d, char *buf, char *bin_buf);
14593 +extern void set_ether_mac(void *d, unsigned char *addr);
14594 +extern void iter_addresses(void *d, void (*cb)(unsigned char *,
14595 + unsigned char *, void *),
14598 +extern void *get_output_buffer(int *len_out);
14599 +extern void free_output_buffer(void *buffer);
14601 +extern int tap_open_common(void *dev, char *gate_addr);
14602 +extern void tap_check_ips(char *gate_addr, char *eth_addr);
14604 +extern void read_output(int fd, char *output_out, int len);
14606 +extern int net_read(int fd, void *buf, int len);
14607 +extern int net_recvfrom(int fd, void *buf, int len);
14608 +extern int net_write(int fd, void *buf, int len);
14609 +extern int net_send(int fd, void *buf, int len);
14610 +extern int net_sendto(int fd, void *buf, int len, void *to, int sock_len);
14612 +extern void open_addr(unsigned char *addr, unsigned char *netmask, void *arg);
14613 +extern void close_addr(unsigned char *addr, unsigned char *netmask, void *arg);
14615 +extern char *split_if_spec(char *str, ...);
14617 +extern int dev_netmask(void *d, void *m);
14622 + * Overrides for Emacs so that we follow Linus's tabbing style.
14623 + * Emacs will notice this stuff at the end of the file and automatically
14624 + * adjust the settings for this buffer only. This must remain at the end
14626 + * ---------------------------------------------------------------------------
14627 + * Local variables:
14628 + * c-file-style: "linux"
14631 diff -Naur -X ../exclude-files orig/arch/um/include/os.h um/arch/um/include/os.h
14632 --- orig/arch/um/include/os.h 1969-12-31 19:00:00.000000000 -0500
14633 +++ um/arch/um/include/os.h 2003-02-04 19:11:32.000000000 -0500
14636 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14637 + * Licensed under the GPL
14643 +#include "asm/types.h"
14644 +#include "../os/include/file.h"
14646 +#define OS_TYPE_FILE 1
14647 +#define OS_TYPE_DIR 2
14648 +#define OS_TYPE_SYMLINK 3
14649 +#define OS_TYPE_CHARDEV 4
14650 +#define OS_TYPE_BLOCKDEV 5
14651 +#define OS_TYPE_FIFO 6
14652 +#define OS_TYPE_SOCK 7
14654 +struct openflags {
14655 + unsigned int r : 1;
14656 + unsigned int w : 1;
14657 + unsigned int s : 1; /* O_SYNC */
14658 + unsigned int c : 1; /* O_CREAT */
14659 + unsigned int t : 1; /* O_TRUNC */
14660 + unsigned int a : 1; /* O_APPEND */
14661 + unsigned int e : 1; /* O_EXCL */
14662 + unsigned int cl : 1; /* FD_CLOEXEC */
14665 +#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
14666 + .t = 0, .a = 0, .e = 0, .cl = 0 })
14668 +static inline struct openflags of_read(struct openflags flags)
14674 +static inline struct openflags of_write(struct openflags flags)
14680 +static inline struct openflags of_rdwr(struct openflags flags)
14682 + return(of_read(of_write(flags)));
14685 +static inline struct openflags of_set_rw(struct openflags flags, int r, int w)
14692 +static inline struct openflags of_sync(struct openflags flags)
14698 +static inline struct openflags of_create(struct openflags flags)
14704 +static inline struct openflags of_trunc(struct openflags flags)
14710 +static inline struct openflags of_append(struct openflags flags)
14716 +static inline struct openflags of_excl(struct openflags flags)
14722 +static inline struct openflags of_cloexec(struct openflags flags)
14728 +extern int os_seek_file(int fd, __u64 offset);
14729 +extern int os_open_file(char *file, struct openflags flags, int mode);
14730 +extern int os_read_file(int fd, void *buf, int len);
14731 +extern int os_write_file(int fd, void *buf, int count);
14732 +extern int os_file_size(char *file, long long *size_out);
14733 +extern int os_pipe(int *fd, int stream, int close_on_exec);
14734 +extern int os_set_fd_async(int fd, int owner);
14735 +extern int os_set_fd_block(int fd, int blocking);
14736 +extern int os_accept_connection(int fd);
14737 +extern int os_shutdown_socket(int fd, int r, int w);
14738 +extern void os_close_file(int fd);
14739 +extern int os_rcv_fd(int fd, int *helper_pid_out);
14740 +extern int create_unix_socket(char *file, int len);
14741 +extern int os_connect_socket(char *name);
14742 +extern int os_file_type(char *file);
14743 +extern int os_file_mode(char *file, struct openflags *mode_out);
14744 +extern int os_lock_file(int fd, int excl);
14746 +extern unsigned long os_process_pc(int pid);
14747 +extern int os_process_parent(int pid);
14748 +extern void os_stop_process(int pid);
14749 +extern void os_kill_process(int pid, int reap_child);
14750 +extern void os_usr1_process(int pid);
14751 +extern int os_getpid(void);
14753 +extern int os_map_memory(void *virt, int fd, unsigned long off,
14754 + unsigned long len, int r, int w, int x);
14755 +extern int os_protect_memory(void *addr, unsigned long len,
14756 + int r, int w, int x);
14757 +extern int os_unmap_memory(void *addr, int len);
14758 +extern void os_flush_stdout(void);
14763 + * Overrides for Emacs so that we follow Linus's tabbing style.
14764 + * Emacs will notice this stuff at the end of the file and automatically
14765 + * adjust the settings for this buffer only. This must remain at the end
14767 + * ---------------------------------------------------------------------------
14768 + * Local variables:
14769 + * c-file-style: "linux"
14772 diff -Naur -X ../exclude-files orig/arch/um/include/process.h um/arch/um/include/process.h
14773 --- orig/arch/um/include/process.h 1969-12-31 19:00:00.000000000 -0500
14774 +++ um/arch/um/include/process.h 2002-10-23 21:08:04.000000000 -0400
14777 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
14778 + * Licensed under the GPL
14781 +#ifndef __PROCESS_H__
14782 +#define __PROCESS_H__
14784 +#include <asm/sigcontext.h>
14786 +extern void sig_handler(int sig, struct sigcontext sc);
14787 +extern void alarm_handler(int sig, struct sigcontext sc);
14792 + * Overrides for Emacs so that we follow Linus's tabbing style.
14793 + * Emacs will notice this stuff at the end of the file and automatically
14794 + * adjust the settings for this buffer only. This must remain at the end
14796 + * ---------------------------------------------------------------------------
14797 + * Local variables:
14798 + * c-file-style: "linux"
14801 diff -Naur -X ../exclude-files orig/arch/um/include/ptrace_user.h um/arch/um/include/ptrace_user.h
14802 --- orig/arch/um/include/ptrace_user.h 1969-12-31 19:00:00.000000000 -0500
14803 +++ um/arch/um/include/ptrace_user.h 2002-10-23 21:08:04.000000000 -0400
14806 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
14807 + * Licensed under the GPL
14810 +#ifndef __PTRACE_USER_H__
14811 +#define __PTRACE_USER_H__
14813 +#include "sysdep/ptrace_user.h"
14815 +extern int ptrace_getregs(long pid, unsigned long *regs_out);
14816 +extern int ptrace_setregs(long pid, unsigned long *regs_in);
14817 +extern int ptrace_getfpregs(long pid, unsigned long *regs_out);
14818 +extern void arch_enter_kernel(void *task, int pid);
14819 +extern void arch_leave_kernel(void *task, int pid);
14820 +extern void ptrace_pokeuser(unsigned long addr, unsigned long data);
14823 diff -Naur -X ../exclude-files orig/arch/um/include/sigcontext.h um/arch/um/include/sigcontext.h
14824 --- orig/arch/um/include/sigcontext.h 1969-12-31 19:00:00.000000000 -0500
14825 +++ um/arch/um/include/sigcontext.h 2002-10-23 21:08:04.000000000 -0400
14828 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14829 + * Licensed under the GPL
14832 +#ifndef __UML_SIGCONTEXT_H__
14833 +#define __UML_SIGCONTEXT_H__
14835 +#include "sysdep/sigcontext.h"
14837 +extern int sc_size(void *data);
14838 +extern void sc_to_sc(void *to_ptr, void *from_ptr);
14843 + * Overrides for Emacs so that we follow Linus's tabbing style.
14844 + * Emacs will notice this stuff at the end of the file and automatically
14845 + * adjust the settings for this buffer only. This must remain at the end
14847 + * ---------------------------------------------------------------------------
14848 + * Local variables:
14849 + * c-file-style: "linux"
14852 diff -Naur -X ../exclude-files orig/arch/um/include/sigio.h um/arch/um/include/sigio.h
14853 --- orig/arch/um/include/sigio.h 1969-12-31 19:00:00.000000000 -0500
14854 +++ um/arch/um/include/sigio.h 2002-10-23 21:08:04.000000000 -0400
14857 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14858 + * Licensed under the GPL
14861 +#ifndef __SIGIO_H__
14862 +#define __SIGIO_H__
14864 +extern int write_sigio_irq(int fd);
14865 +extern int register_sigio_fd(int fd);
14866 +extern int read_sigio_fd(int fd);
14867 +extern int add_sigio_fd(int fd, int read);
14868 +extern int ignore_sigio_fd(int fd);
14869 +extern void sigio_lock(void);
14870 +extern void sigio_unlock(void);
14875 + * Overrides for Emacs so that we follow Linus's tabbing style.
14876 + * Emacs will notice this stuff at the end of the file and automatically
14877 + * adjust the settings for this buffer only. This must remain at the end
14879 + * ---------------------------------------------------------------------------
14880 + * Local variables:
14881 + * c-file-style: "linux"
14884 diff -Naur -X ../exclude-files orig/arch/um/include/signal_kern.h um/arch/um/include/signal_kern.h
14885 --- orig/arch/um/include/signal_kern.h 1969-12-31 19:00:00.000000000 -0500
14886 +++ um/arch/um/include/signal_kern.h 2002-12-05 18:08:47.000000000 -0500
14889 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14890 + * Licensed under the GPL
14893 +#ifndef __SIGNAL_KERN_H__
14894 +#define __SIGNAL_KERN_H__
14896 +extern int have_signals(void *t);
14901 + * Overrides for Emacs so that we follow Linus's tabbing style.
14902 + * Emacs will notice this stuff at the end of the file and automatically
14903 + * adjust the settings for this buffer only. This must remain at the end
14905 + * ---------------------------------------------------------------------------
14906 + * Local variables:
14907 + * c-file-style: "linux"
14910 diff -Naur -X ../exclude-files orig/arch/um/include/signal_user.h um/arch/um/include/signal_user.h
14911 --- orig/arch/um/include/signal_user.h 1969-12-31 19:00:00.000000000 -0500
14912 +++ um/arch/um/include/signal_user.h 2002-10-23 21:08:04.000000000 -0400
14915 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
14916 + * Licensed under the GPL
14919 +#ifndef __SIGNAL_USER_H__
14920 +#define __SIGNAL_USER_H__
14922 +extern int signal_stack_size;
14924 +extern int change_sig(int signal, int on);
14925 +extern void set_sigstack(void *stack, int size);
14926 +extern void set_handler(int sig, void (*handler)(int), int flags, ...);
14931 + * Overrides for Emacs so that we follow Linus's tabbing style.
14932 + * Emacs will notice this stuff at the end of the file and automatically
14933 + * adjust the settings for this buffer only. This must remain at the end
14935 + * ---------------------------------------------------------------------------
14936 + * Local variables:
14937 + * c-file-style: "linux"
14940 diff -Naur -X ../exclude-files orig/arch/um/include/skas_ptrace.h um/arch/um/include/skas_ptrace.h
14941 --- orig/arch/um/include/skas_ptrace.h 1969-12-31 19:00:00.000000000 -0500
14942 +++ um/arch/um/include/skas_ptrace.h 2002-12-16 11:54:52.000000000 -0500
14945 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
14946 + * Licensed under the GPL
14949 +#ifndef __SKAS_PTRACE_H
14950 +#define __SKAS_PTRACE_H
14952 +struct ptrace_faultinfo {
14954 + unsigned long addr;
14957 +struct ptrace_ldt {
14960 + unsigned long bytecount;
14963 +#define PTRACE_FAULTINFO 52
14964 +#define PTRACE_SIGPENDING 53
14965 +#define PTRACE_LDT 54
14966 +#define PTRACE_SWITCH_MM 55
14971 + * Overrides for Emacs so that we follow Linus's tabbing style.
14972 + * Emacs will notice this stuff at the end of the file and automatically
14973 + * adjust the settings for this buffer only. This must remain at the end
14975 + * ---------------------------------------------------------------------------
14976 + * Local variables:
14977 + * c-file-style: "linux"
14980 diff -Naur -X ../exclude-files orig/arch/um/include/syscall_user.h um/arch/um/include/syscall_user.h
14981 --- orig/arch/um/include/syscall_user.h 1969-12-31 19:00:00.000000000 -0500
14982 +++ um/arch/um/include/syscall_user.h 2002-10-23 21:08:04.000000000 -0400
14985 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14986 + * Licensed under the GPL
14989 +#ifndef __SYSCALL_USER_H
14990 +#define __SYSCALL_USER_H
14992 +extern int record_syscall_start(int syscall);
14993 +extern void record_syscall_end(int index, int result);
14998 + * Overrides for Emacs so that we follow Linus's tabbing style.
14999 + * Emacs will notice this stuff at the end of the file and automatically
15000 + * adjust the settings for this buffer only. This must remain at the end
15002 + * ---------------------------------------------------------------------------
15003 + * Local variables:
15004 + * c-file-style: "linux"
15007 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/checksum.h um/arch/um/include/sysdep-i386/checksum.h
15008 --- orig/arch/um/include/sysdep-i386/checksum.h 1969-12-31 19:00:00.000000000 -0500
15009 +++ um/arch/um/include/sysdep-i386/checksum.h 2002-10-29 21:23:02.000000000 -0500
15012 + * Licensed under the GPL
15015 +#ifndef __UM_SYSDEP_CHECKSUM_H
15016 +#define __UM_SYSDEP_CHECKSUM_H
15018 +#include "linux/string.h"
15021 + * computes the checksum of a memory block at buff, length len,
15022 + * and adds in "sum" (32-bit)
15024 + * returns a 32-bit number suitable for feeding into itself
15025 + * or csum_tcpudp_magic
15027 + * this function must be called with even lengths, except
15028 + * for the last fragment, which may be odd
15030 + * it's best to have buff aligned on a 32-bit boundary
15032 +unsigned int csum_partial(const unsigned char * buff, int len,
15033 + unsigned int sum);
15036 + * the same as csum_partial, but copies from src while it
15037 + * checksums, and handles user-space pointer exceptions correctly, when needed.
15039 + * here even more important to align src and dst on a 32-bit (or even
15040 + * better 64-bit) boundary
15043 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len,
15044 + int sum, int *err_ptr);
15045 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len,
15046 + int sum, int *err_ptr);
15049 + * Note: when you get a NULL pointer exception here this means someone
15050 + * passed in an incorrect kernel address to one of these functions.
15052 + * If you use these functions directly please don't forget the
15057 +unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
15058 + int len, int sum)
15060 + memcpy(dst, src, len);
15061 + return(csum_partial(dst, len, sum));
15065 +unsigned int csum_partial_copy_from_user(const char *src, char *dst,
15066 + int len, int sum, int *err_ptr)
15068 + return csum_partial_copy_from(src, dst, len, sum, err_ptr);
15072 + * These are the old (and unsafe) way of doing checksums, a warning message
15073 + * will be printed if they are used and an exeption occurs.
15075 + * these functions should go away after some time.
15078 +#define csum_partial_copy_fromuser csum_partial_copy_from_user
15079 +unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
15082 + * This is a version of ip_compute_csum() optimized for IP headers,
15083 + * which always checksum on 4 octet boundaries.
15085 + * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
15086 + * Arnt Gulbrandsen.
15088 +static inline unsigned short ip_fast_csum(unsigned char * iph,
15089 + unsigned int ihl)
15091 + unsigned int sum;
15093 + __asm__ __volatile__(
15094 + "movl (%1), %0 ;\n"
15095 + "subl $4, %2 ;\n"
15097 + "addl 4(%1), %0 ;\n"
15098 + "adcl 8(%1), %0 ;\n"
15099 + "adcl 12(%1), %0 ;\n"
15100 +"1: adcl 16(%1), %0 ;\n"
15101 + "lea 4(%1), %1 ;\n"
15104 + "adcl $0, %0 ;\n"
15105 + "movl %0, %2 ;\n"
15106 + "shrl $16, %0 ;\n"
15107 + "addw %w2, %w0 ;\n"
15108 + "adcl $0, %0 ;\n"
15111 + /* Since the input registers which are loaded with iph and ipl
15112 + are modified, we must also specify them as outputs, or gcc
15113 + will assume they contain their original values. */
15114 + : "=r" (sum), "=r" (iph), "=r" (ihl)
15115 + : "1" (iph), "2" (ihl));
15120 + * Fold a partial checksum
15123 +static inline unsigned int csum_fold(unsigned int sum)
15126 + "addl %1, %0 ;\n"
15127 + "adcl $0xffff, %0 ;\n"
15129 + : "r" (sum << 16), "0" (sum & 0xffff0000)
15131 + return (~sum) >> 16;
15134 +static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
15135 + unsigned long daddr,
15136 + unsigned short len,
15137 + unsigned short proto,
15138 + unsigned int sum)
15141 + "addl %1, %0 ;\n"
15142 + "adcl %2, %0 ;\n"
15143 + "adcl %3, %0 ;\n"
15144 + "adcl $0, %0 ;\n"
15146 + : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum));
15151 + * computes the checksum of the TCP/UDP pseudo-header
15152 + * returns a 16-bit checksum, already complemented
15154 +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
15155 + unsigned long daddr,
15156 + unsigned short len,
15157 + unsigned short proto,
15158 + unsigned int sum)
15160 + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
15164 + * this routine is used for miscellaneous IP-like checksums, mainly
15168 +static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
15170 + return csum_fold (csum_partial(buff, len, 0));
15173 +#define _HAVE_ARCH_IPV6_CSUM
15174 +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
15175 + struct in6_addr *daddr,
15177 + unsigned short proto,
15178 + unsigned int sum)
15181 + "addl 0(%1), %0 ;\n"
15182 + "adcl 4(%1), %0 ;\n"
15183 + "adcl 8(%1), %0 ;\n"
15184 + "adcl 12(%1), %0 ;\n"
15185 + "adcl 0(%2), %0 ;\n"
15186 + "adcl 4(%2), %0 ;\n"
15187 + "adcl 8(%2), %0 ;\n"
15188 + "adcl 12(%2), %0 ;\n"
15189 + "adcl %3, %0 ;\n"
15190 + "adcl %4, %0 ;\n"
15191 + "adcl $0, %0 ;\n"
15193 + : "r" (saddr), "r" (daddr),
15194 + "r"(htonl(len)), "r"(htonl(proto)), "0"(sum));
15196 + return csum_fold(sum);
15200 + * Copy and checksum to user
15202 +#define HAVE_CSUM_COPY_USER
15203 +static __inline__ unsigned int csum_and_copy_to_user(const char *src,
15204 + char *dst, int len,
15205 + int sum, int *err_ptr)
15207 + if (access_ok(VERIFY_WRITE, dst, len))
15208 + return(csum_partial_copy_to(src, dst, len, sum, err_ptr));
15211 + *err_ptr = -EFAULT;
15213 + return -1; /* invalid checksum */
15219 + * Overrides for Emacs so that we follow Linus's tabbing style.
15220 + * Emacs will notice this stuff at the end of the file and automatically
15221 + * adjust the settings for this buffer only. This must remain at the end
15223 + * ---------------------------------------------------------------------------
15224 + * Local variables:
15225 + * c-file-style: "linux"
15228 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame.h um/arch/um/include/sysdep-i386/frame.h
15229 --- orig/arch/um/include/sysdep-i386/frame.h 1969-12-31 19:00:00.000000000 -0500
15230 +++ um/arch/um/include/sysdep-i386/frame.h 2002-12-06 14:07:54.000000000 -0500
15233 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15234 + * Licensed under the GPL
15237 +#ifndef __FRAME_I386_H
15238 +#define __FRAME_I386_H
15240 +struct arch_frame_data_raw {
15241 + unsigned long fp_start;
15242 + unsigned long sr;
15245 +struct arch_frame_data {
15246 + int fpstate_size;
15252 + * Overrides for Emacs so that we follow Linus's tabbing style.
15253 + * Emacs will notice this stuff at the end of the file and automatically
15254 + * adjust the settings for this buffer only. This must remain at the end
15256 + * ---------------------------------------------------------------------------
15257 + * Local variables:
15258 + * c-file-style: "linux"
15261 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_kern.h um/arch/um/include/sysdep-i386/frame_kern.h
15262 --- orig/arch/um/include/sysdep-i386/frame_kern.h 1969-12-31 19:00:00.000000000 -0500
15263 +++ um/arch/um/include/sysdep-i386/frame_kern.h 2002-12-02 21:45:04.000000000 -0500
15266 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15267 + * Licensed under the GPL
15270 +#ifndef __FRAME_KERN_I386_H
15271 +#define __FRAME_KERN_I386_H
15273 +/* This is called from sys_sigreturn. It takes the sp at the point of the
15274 + * sigreturn system call and returns the address of the sigcontext struct
15278 +static inline void *sp_to_sc(unsigned long sp)
15280 + return((void *) sp);
15283 +static inline void *sp_to_uc(unsigned long sp)
15285 + unsigned long uc;
15287 + uc = sp + signal_frame_si.uc_index -
15288 + signal_frame_si.common.sp_index - 4;
15289 + return((void *) uc);
15292 +static inline void *sp_to_rt_sc(unsigned long sp)
15294 + unsigned long sc;
15296 + sc = sp - signal_frame_si.common.sp_index +
15297 + signal_frame_si.common.len - 4;
15298 + return((void *) sc);
15301 +static inline void *sp_to_mask(unsigned long sp)
15303 + unsigned long mask;
15305 + mask = sp - signal_frame_sc.common.sp_index +
15306 + signal_frame_sc.common.len - 8;
15307 + return((void *) mask);
15310 +extern int sc_size(void *data);
15312 +static inline void *sp_to_rt_mask(unsigned long sp)
15314 + unsigned long mask;
15316 + mask = sp - signal_frame_si.common.sp_index +
15317 + signal_frame_si.common.len +
15318 + sc_size(&signal_frame_si.common.arch) - 4;
15319 + return((void *) mask);
15325 + * Overrides for Emacs so that we follow Linus's tabbing style.
15326 + * Emacs will notice this stuff at the end of the file and automatically
15327 + * adjust the settings for this buffer only. This must remain at the end
15329 + * ---------------------------------------------------------------------------
15330 + * Local variables:
15331 + * c-file-style: "linux"
15334 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_user.h um/arch/um/include/sysdep-i386/frame_user.h
15335 --- orig/arch/um/include/sysdep-i386/frame_user.h 1969-12-31 19:00:00.000000000 -0500
15336 +++ um/arch/um/include/sysdep-i386/frame_user.h 2002-12-06 14:13:59.000000000 -0500
15339 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15340 + * Licensed under the GPL
15343 +#ifndef __FRAME_USER_I386_H
15344 +#define __FRAME_USER_I386_H
15346 +#include <asm/page.h>
15347 +#include "sysdep/frame.h"
15349 +/* This stuff is to calculate the size of the fp state struct at runtime
15350 + * because it has changed between 2.2 and 2.4 and it would be good for a
15351 + * UML compiled on one to work on the other.
15352 + * So, setup_arch_frame_raw fills in the arch struct with the raw data, which
15353 + * just contains the address of the end of the sigcontext. This is invoked
15354 + * from the signal handler.
15355 + * setup_arch_frame uses that data to figure out what
15356 + * arch_frame_data.fpstate_size should be. It really has no idea, since it's
15357 + * not allowed to do sizeof(struct fpstate) but it's safe to consider that it's
15358 + * everything from the end of the sigcontext up to the top of the stack. So,
15359 + * it masks off the page number to get the offset within the page and subtracts
15360 + * that from the page size, and that's how big the fpstate struct will be
15361 + * considered to be.
15364 +static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data,
15365 + void *end, unsigned long srp)
15367 + unsigned long sr = *((unsigned long *) srp);
15369 + data->fp_start = (unsigned long) end;
15370 + if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK))
15372 + else data->sr = 0;
15375 +static inline void setup_arch_frame(struct arch_frame_data_raw *in,
15376 + struct arch_frame_data *out)
15378 + unsigned long fpstate_start = in->fp_start;
15381 + fpstate_start &= ~PAGE_MASK;
15382 + out->fpstate_size = PAGE_SIZE - fpstate_start;
15385 + out->fpstate_size = in->sr - fpstate_start;
15389 +/* This figures out where on the stack the SA_RESTORER function address
15390 + * is stored. For i386, it's the signal handler return address, so it's
15391 + * located next to the frame pointer.
15392 + * This is inlined, so __builtin_frame_address(0) is correct. Otherwise,
15393 + * it would have to be __builtin_frame_address(1).
15396 +static inline unsigned long frame_restorer(void)
15398 + unsigned long *fp;
15400 + fp = __builtin_frame_address(0);
15401 + return((unsigned long) (fp + 1));
15404 +/* Similarly, this returns the value of sp when the handler was first
15405 + * entered. This is used to calculate the proper sp when delivering
15409 +static inline unsigned long frame_sp(void)
15411 + unsigned long *fp;
15413 + fp = __builtin_frame_address(0);
15414 + return((unsigned long) (fp + 1));
15420 + * Overrides for Emacs so that we follow Linus's tabbing style.
15421 + * Emacs will notice this stuff at the end of the file and automatically
15422 + * adjust the settings for this buffer only. This must remain at the end
15424 + * ---------------------------------------------------------------------------
15425 + * Local variables:
15426 + * c-file-style: "linux"
15429 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace.h um/arch/um/include/sysdep-i386/ptrace.h
15430 --- orig/arch/um/include/sysdep-i386/ptrace.h 1969-12-31 19:00:00.000000000 -0500
15431 +++ um/arch/um/include/sysdep-i386/ptrace.h 2003-01-17 13:23:31.000000000 -0500
15434 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
15435 + * Licensed under the GPL
15438 +#ifndef __SYSDEP_I386_PTRACE_H
15439 +#define __SYSDEP_I386_PTRACE_H
15441 +#include "uml-config.h"
15443 +#ifdef UML_CONFIG_MODE_TT
15444 +#include "ptrace-tt.h"
15447 +#ifdef UML_CONFIG_MODE_SKAS
15448 +#include "ptrace-skas.h"
15451 +#include "choose-mode.h"
15453 +union uml_pt_regs {
15454 +#ifdef UML_CONFIG_MODE_TT
15460 +#ifdef UML_CONFIG_MODE_SKAS
15461 + struct skas_regs {
15462 + unsigned long regs[HOST_FRAME_SIZE];
15463 + unsigned long fp[HOST_FP_SIZE];
15464 + unsigned long xfp[HOST_XFP_SIZE];
15465 + unsigned long fault_addr;
15466 + unsigned long fault_type;
15467 + unsigned long trap_type;
15474 +#define EMPTY_UML_PT_REGS { }
15476 +extern int mode_tt;
15478 +#define UPT_SC(r) ((r)->tt.sc)
15479 +#define UPT_IP(r) \
15480 + CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
15481 +#define UPT_SP(r) \
15482 + CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
15483 +#define UPT_EFLAGS(r) \
15484 + CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
15485 +#define UPT_EAX(r) \
15486 + CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs))
15487 +#define UPT_EBX(r) \
15488 + CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs))
15489 +#define UPT_ECX(r) \
15490 + CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs))
15491 +#define UPT_EDX(r) \
15492 + CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs))
15493 +#define UPT_ESI(r) \
15494 + CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs))
15495 +#define UPT_EDI(r) \
15496 + CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs))
15497 +#define UPT_EBP(r) \
15498 + CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs))
15499 +#define UPT_ORIG_EAX(r) \
15500 + CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
15501 +#define UPT_CS(r) \
15502 + CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
15503 +#define UPT_SS(r) \
15504 + CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs))
15505 +#define UPT_DS(r) \
15506 + CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
15507 +#define UPT_ES(r) \
15508 + CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
15509 +#define UPT_FS(r) \
15510 + CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
15511 +#define UPT_GS(r) \
15512 + CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
15514 +#define UPT_SYSCALL_ARG1(r) UPT_EBX(r)
15515 +#define UPT_SYSCALL_ARG2(r) UPT_ECX(r)
15516 +#define UPT_SYSCALL_ARG3(r) UPT_EDX(r)
15517 +#define UPT_SYSCALL_ARG4(r) UPT_ESI(r)
15518 +#define UPT_SYSCALL_ARG5(r) UPT_EDI(r)
15519 +#define UPT_SYSCALL_ARG6(r) UPT_EBP(r)
15521 +extern int user_context(unsigned long sp);
15523 +#define UPT_IS_USER(r) \
15524 + CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
15526 +struct syscall_args {
15527 + unsigned long args[6];
15530 +#define SYSCALL_ARGS(r) ((struct syscall_args) \
15531 + { .args = { UPT_SYSCALL_ARG1(r), \
15532 + UPT_SYSCALL_ARG2(r), \
15533 + UPT_SYSCALL_ARG3(r), \
15534 + UPT_SYSCALL_ARG4(r), \
15535 + UPT_SYSCALL_ARG5(r), \
15536 + UPT_SYSCALL_ARG6(r) } } )
15538 +#define UPT_REG(regs, reg) \
15539 + ({ unsigned long val; \
15541 + case EIP: val = UPT_IP(regs); break; \
15542 + case UESP: val = UPT_SP(regs); break; \
15543 + case EAX: val = UPT_EAX(regs); break; \
15544 + case EBX: val = UPT_EBX(regs); break; \
15545 + case ECX: val = UPT_ECX(regs); break; \
15546 + case EDX: val = UPT_EDX(regs); break; \
15547 + case ESI: val = UPT_ESI(regs); break; \
15548 + case EDI: val = UPT_EDI(regs); break; \
15549 + case EBP: val = UPT_EBP(regs); break; \
15550 + case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \
15551 + case CS: val = UPT_CS(regs); break; \
15552 + case SS: val = UPT_SS(regs); break; \
15553 + case DS: val = UPT_DS(regs); break; \
15554 + case ES: val = UPT_ES(regs); break; \
15555 + case FS: val = UPT_FS(regs); break; \
15556 + case GS: val = UPT_GS(regs); break; \
15557 + case EFL: val = UPT_EFLAGS(regs); break; \
15559 + panic("Bad register in UPT_REG : %d\n", reg); \
15566 +#define UPT_SET(regs, reg, val) \
15569 + case EIP: UPT_IP(regs) = val; break; \
15570 + case UESP: UPT_SP(regs) = val; break; \
15571 + case EAX: UPT_EAX(regs) = val; break; \
15572 + case EBX: UPT_EBX(regs) = val; break; \
15573 + case ECX: UPT_ECX(regs) = val; break; \
15574 + case EDX: UPT_EDX(regs) = val; break; \
15575 + case ESI: UPT_ESI(regs) = val; break; \
15576 + case EDI: UPT_EDI(regs) = val; break; \
15577 + case EBP: UPT_EBP(regs) = val; break; \
15578 + case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \
15579 + case CS: UPT_CS(regs) = val; break; \
15580 + case SS: UPT_SS(regs) = val; break; \
15581 + case DS: UPT_DS(regs) = val; break; \
15582 + case ES: UPT_ES(regs) = val; break; \
15583 + case FS: UPT_FS(regs) = val; break; \
15584 + case GS: UPT_GS(regs) = val; break; \
15585 + case EFL: UPT_EFLAGS(regs) = val; break; \
15587 + panic("Bad register in UPT_SET : %d\n", reg); \
15592 +#define UPT_SET_SYSCALL_RETURN(r, res) \
15593 + CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \
15594 + REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
15596 +#define UPT_RESTART_SYSCALL(r) \
15597 + CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
15598 + REGS_RESTART_SYSCALL((r)->skas.regs))
15600 +#define UPT_ORIG_SYSCALL(r) UPT_EAX(r)
15601 +#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
15602 +#define UPT_SYSCALL_RET(r) UPT_EAX(r)
15604 +#define UPT_SEGV_IS_FIXABLE(r) \
15605 + CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
15606 + REGS_SEGV_IS_FIXABLE(&r->skas))
15608 +#define UPT_FAULT_ADDR(r) \
15609 + CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
15611 +#define UPT_FAULT_WRITE(r) \
15612 + CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
15617 + * Overrides for Emacs so that we follow Linus's tabbing style.
15618 + * Emacs will notice this stuff at the end of the file and automatically
15619 + * adjust the settings for this buffer only. This must remain at the end
15621 + * ---------------------------------------------------------------------------
15622 + * Local variables:
15623 + * c-file-style: "linux"
15626 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace_user.h um/arch/um/include/sysdep-i386/ptrace_user.h
15627 --- orig/arch/um/include/sysdep-i386/ptrace_user.h 1969-12-31 19:00:00.000000000 -0500
15628 +++ um/arch/um/include/sysdep-i386/ptrace_user.h 2002-10-23 21:08:04.000000000 -0400
15631 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15632 + * Licensed under the GPL
15635 +#ifndef __SYSDEP_I386_PTRACE_USER_H__
15636 +#define __SYSDEP_I386_PTRACE_USER_H__
15638 +#include <asm/ptrace.h>
15640 +#define PT_OFFSET(r) ((r) * sizeof(long))
15642 +#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX])
15643 +#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX)
15645 +#define PT_SYSCALL_ARG1_OFFSET PT_OFFSET(EBX)
15646 +#define PT_SYSCALL_ARG2_OFFSET PT_OFFSET(ECX)
15647 +#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX)
15648 +#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI)
15649 +#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI)
15651 +#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX)
15653 +#define PT_IP_OFFSET PT_OFFSET(EIP)
15654 +#define PT_IP(regs) ((regs)[EIP])
15655 +#define PT_SP(regs) ((regs)[UESP])
15657 +#ifndef FRAME_SIZE
15658 +#define FRAME_SIZE (17)
15660 +#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long))
15662 +#define FP_FRAME_SIZE (27)
15663 +#define FPX_FRAME_SIZE (128)
15665 +#ifdef PTRACE_GETREGS
15666 +#define UM_HAVE_GETREGS
15669 +#ifdef PTRACE_SETREGS
15670 +#define UM_HAVE_SETREGS
15673 +#ifdef PTRACE_GETFPREGS
15674 +#define UM_HAVE_GETFPREGS
15677 +#ifdef PTRACE_SETFPREGS
15678 +#define UM_HAVE_SETFPREGS
15681 +#ifdef PTRACE_GETFPXREGS
15682 +#define UM_HAVE_GETFPXREGS
15685 +#ifdef PTRACE_SETFPXREGS
15686 +#define UM_HAVE_SETFPXREGS
15689 +extern void update_debugregs(int seq);
15692 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/sigcontext.h um/arch/um/include/sysdep-i386/sigcontext.h
15693 --- orig/arch/um/include/sysdep-i386/sigcontext.h 1969-12-31 19:00:00.000000000 -0500
15694 +++ um/arch/um/include/sysdep-i386/sigcontext.h 2002-12-08 18:21:33.000000000 -0500
15697 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
15698 + * Licensed under the GPL
15701 +#ifndef __SYS_SIGCONTEXT_I386_H
15702 +#define __SYS_SIGCONTEXT_I386_H
15706 +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
15708 +#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
15709 +#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
15711 +#define SC_FAULT_ADDR(sc) SC_CR2(sc)
15712 +#define SC_FAULT_TYPE(sc) SC_ERR(sc)
15714 +#define FAULT_WRITE(err) (err & 2)
15715 +#define TO_SC_ERR(is_write) ((is_write) ? 2 : 0)
15717 +#define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc)))
15719 +#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
15721 +/* ptrace expects that, at the start of a system call, %eax contains
15722 + * -ENOSYS, so this makes it so.
15724 +#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
15726 +/* These are General Protection and Page Fault */
15727 +#define SEGV_IS_FIXABLE(trap) ((trap == 13) || (trap == 14))
15729 +#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
15731 +extern unsigned long *sc_sigmask(void *sc_ptr);
15732 +extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
15736 + * Overrides for Emacs so that we follow Linus's tabbing style.
15737 + * Emacs will notice this stuff at the end of the file and automatically
15738 + * adjust the settings for this buffer only. This must remain at the end
15740 + * ---------------------------------------------------------------------------
15741 + * Local variables:
15742 + * c-file-style: "linux"
15745 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/syscalls.h um/arch/um/include/sysdep-i386/syscalls.h
15746 --- orig/arch/um/include/sysdep-i386/syscalls.h 1969-12-31 19:00:00.000000000 -0500
15747 +++ um/arch/um/include/sysdep-i386/syscalls.h 2002-12-08 18:04:15.000000000 -0500
15750 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15751 + * Licensed under the GPL
15754 +#include "asm/unistd.h"
15755 +#include "sysdep/ptrace.h"
15757 +typedef long syscall_handler_t(struct pt_regs);
15759 +#define EXECUTE_SYSCALL(syscall, regs) \
15760 + ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs))
15762 +extern syscall_handler_t sys_modify_ldt;
15763 +extern syscall_handler_t old_mmap_i386;
15764 +extern syscall_handler_t old_select;
15765 +extern syscall_handler_t sys_ni_syscall;
15767 +#define ARCH_SYSCALLS \
15768 + [ __NR_mmap ] = old_mmap_i386, \
15769 + [ __NR_select ] = old_select, \
15770 + [ __NR_vm86old ] = sys_ni_syscall, \
15771 + [ __NR_modify_ldt ] = sys_modify_ldt, \
15772 + [ __NR_lchown32 ] = sys_lchown, \
15773 + [ __NR_getuid32 ] = sys_getuid, \
15774 + [ __NR_getgid32 ] = sys_getgid, \
15775 + [ __NR_geteuid32 ] = sys_geteuid, \
15776 + [ __NR_getegid32 ] = sys_getegid, \
15777 + [ __NR_setreuid32 ] = sys_setreuid, \
15778 + [ __NR_setregid32 ] = sys_setregid, \
15779 + [ __NR_getgroups32 ] = sys_getgroups, \
15780 + [ __NR_setgroups32 ] = sys_setgroups, \
15781 + [ __NR_fchown32 ] = sys_fchown, \
15782 + [ __NR_setresuid32 ] = sys_setresuid, \
15783 + [ __NR_getresuid32 ] = sys_getresuid, \
15784 + [ __NR_setresgid32 ] = sys_setresgid, \
15785 + [ __NR_getresgid32 ] = sys_getresgid, \
15786 + [ __NR_chown32 ] = sys_chown, \
15787 + [ __NR_setuid32 ] = sys_setuid, \
15788 + [ __NR_setgid32 ] = sys_setgid, \
15789 + [ __NR_setfsuid32 ] = sys_setfsuid, \
15790 + [ __NR_setfsgid32 ] = sys_setfsgid, \
15791 + [ __NR_pivot_root ] = sys_pivot_root, \
15792 + [ __NR_mincore ] = sys_mincore, \
15793 + [ __NR_madvise ] = sys_madvise, \
15794 + [ 222 ] = sys_ni_syscall,
15796 +/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
15798 +#define LAST_ARCH_SYSCALL 222
15801 + * Overrides for Emacs so that we follow Linus's tabbing style.
15802 + * Emacs will notice this stuff at the end of the file and automatically
15803 + * adjust the settings for this buffer only. This must remain at the end
15805 + * ---------------------------------------------------------------------------
15806 + * Local variables:
15807 + * c-file-style: "linux"
15810 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/ptrace.h um/arch/um/include/sysdep-ia64/ptrace.h
15811 --- orig/arch/um/include/sysdep-ia64/ptrace.h 1969-12-31 19:00:00.000000000 -0500
15812 +++ um/arch/um/include/sysdep-ia64/ptrace.h 2002-10-23 21:08:04.000000000 -0400
15815 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15816 + * Licensed under the GPL
15819 +#ifndef __SYSDEP_IA64_PTRACE_H
15820 +#define __SYSDEP_IA64_PTRACE_H
15822 +struct sys_pt_regs {
15826 +#define EMPTY_REGS { 0 }
15831 + * Overrides for Emacs so that we follow Linus's tabbing style.
15832 + * Emacs will notice this stuff at the end of the file and automatically
15833 + * adjust the settings for this buffer only. This must remain at the end
15835 + * ---------------------------------------------------------------------------
15836 + * Local variables:
15837 + * c-file-style: "linux"
15840 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/sigcontext.h um/arch/um/include/sysdep-ia64/sigcontext.h
15841 --- orig/arch/um/include/sysdep-ia64/sigcontext.h 1969-12-31 19:00:00.000000000 -0500
15842 +++ um/arch/um/include/sysdep-ia64/sigcontext.h 2002-10-23 21:08:04.000000000 -0400
15845 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15846 + * Licensed under the GPL
15849 +#ifndef __SYSDEP_IA64_SIGCONTEXT_H
15850 +#define __SYSDEP_IA64_SIGCONTEXT_H
15855 + * Overrides for Emacs so that we follow Linus's tabbing style.
15856 + * Emacs will notice this stuff at the end of the file and automatically
15857 + * adjust the settings for this buffer only. This must remain at the end
15859 + * ---------------------------------------------------------------------------
15860 + * Local variables:
15861 + * c-file-style: "linux"
15864 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/syscalls.h um/arch/um/include/sysdep-ia64/syscalls.h
15865 --- orig/arch/um/include/sysdep-ia64/syscalls.h 1969-12-31 19:00:00.000000000 -0500
15866 +++ um/arch/um/include/sysdep-ia64/syscalls.h 2002-10-23 21:08:04.000000000 -0400
15869 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15870 + * Licensed under the GPL
15873 +#ifndef __SYSDEP_IA64_SYSCALLS_H
15874 +#define __SYSDEP_IA64_SYSCALLS_H
15879 + * Overrides for Emacs so that we follow Linus's tabbing style.
15880 + * Emacs will notice this stuff at the end of the file and automatically
15881 + * adjust the settings for this buffer only. This must remain at the end
15883 + * ---------------------------------------------------------------------------
15884 + * Local variables:
15885 + * c-file-style: "linux"
15888 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/ptrace.h um/arch/um/include/sysdep-ppc/ptrace.h
15889 --- orig/arch/um/include/sysdep-ppc/ptrace.h 1969-12-31 19:00:00.000000000 -0500
15890 +++ um/arch/um/include/sysdep-ppc/ptrace.h 2002-10-23 21:08:04.000000000 -0400
15893 + * Licensed under the GPL
15896 +#ifndef __SYS_PTRACE_PPC_H
15897 +#define __SYS_PTRACE_PPC_H
15899 +#include "linux/config.h"
15900 +#include "linux/types.h"
15902 +/* the following taken from <asm-ppc/ptrace.h> */
15904 +#ifdef CONFIG_PPC64
15905 +#define PPC_REG unsigned long /*long*/
15907 +#define PPC_REG unsigned long
15909 +struct sys_pt_regs_s {
15913 + PPC_REG orig_gpr3; /* Used for restarting system calls */
15918 + PPC_REG mq; /* 601 only (not used at present) */
15919 + /* Used on APUS to hold IPL value. */
15920 + PPC_REG trap; /* Reason for being here */
15921 + PPC_REG dar; /* Fault registers */
15923 + PPC_REG result; /* Result of a system call */
15926 +#define NUM_REGS (sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG))
15928 +struct sys_pt_regs {
15929 + PPC_REG regs[sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG)];
15932 +#define UM_MAX_REG (PT_FPR0)
15933 +#define UM_MAX_REG_OFFSET (UM_MAX_REG * sizeof(PPC_REG))
15935 +#define EMPTY_REGS { { [ 0 ... NUM_REGS - 1] = 0 } }
15937 +#define UM_REG(r, n) ((r)->regs[n])
15939 +#define UM_SYSCALL_RET(r) UM_REG(r, PT_R3)
15940 +#define UM_SP(r) UM_REG(r, PT_R1)
15941 +#define UM_IP(r) UM_REG(r, PT_NIP)
15942 +#define UM_ELF_ZERO(r) UM_REG(r, PT_FPSCR)
15943 +#define UM_SYSCALL_NR(r) UM_REG(r, PT_R0)
15944 +#define UM_SYSCALL_ARG1(r) UM_REG(r, PT_ORIG_R3)
15945 +#define UM_SYSCALL_ARG2(r) UM_REG(r, PT_R4)
15946 +#define UM_SYSCALL_ARG3(r) UM_REG(r, PT_R5)
15947 +#define UM_SYSCALL_ARG4(r) UM_REG(r, PT_R6)
15948 +#define UM_SYSCALL_ARG5(r) UM_REG(r, PT_R7)
15949 +#define UM_SYSCALL_ARG6(r) UM_REG(r, PT_R8)
15951 +#define UM_SYSCALL_NR_OFFSET (PT_R0 * sizeof(PPC_REG))
15952 +#define UM_SYSCALL_RET_OFFSET (PT_R3 * sizeof(PPC_REG))
15953 +#define UM_SYSCALL_ARG1_OFFSET (PT_R3 * sizeof(PPC_REG))
15954 +#define UM_SYSCALL_ARG2_OFFSET (PT_R4 * sizeof(PPC_REG))
15955 +#define UM_SYSCALL_ARG3_OFFSET (PT_R5 * sizeof(PPC_REG))
15956 +#define UM_SYSCALL_ARG4_OFFSET (PT_R6 * sizeof(PPC_REG))
15957 +#define UM_SYSCALL_ARG5_OFFSET (PT_R7 * sizeof(PPC_REG))
15958 +#define UM_SYSCALL_ARG6_OFFSET (PT_R8 * sizeof(PPC_REG))
15959 +#define UM_SP_OFFSET (PT_R1 * sizeof(PPC_REG))
15960 +#define UM_IP_OFFSET (PT_NIP * sizeof(PPC_REG))
15961 +#define UM_ELF_ZERO_OFFSET (PT_R3 * sizeof(PPC_REG))
15963 +#define UM_SET_SYSCALL_RETURN(_regs, result) \
15965 + if (result < 0) { \
15966 + (_regs)->regs[PT_CCR] |= 0x10000000; \
15967 + UM_SYSCALL_RET((_regs)) = -result; \
15969 + UM_SYSCALL_RET((_regs)) = result; \
15973 +extern void shove_aux_table(unsigned long sp);
15974 +#define UM_FIX_EXEC_STACK(sp) shove_aux_table(sp);
15976 +/* These aren't actually defined. The undefs are just to make sure
15977 + * everyone's clear on the concept.
15979 +#undef UML_HAVE_GETREGS
15980 +#undef UML_HAVE_GETFPREGS
15981 +#undef UML_HAVE_SETREGS
15982 +#undef UML_HAVE_SETFPREGS
15987 + * Overrides for Emacs so that we follow Linus's tabbing style.
15988 + * Emacs will notice this stuff at the end of the file and automatically
15989 + * adjust the settings for this buffer only. This must remain at the end
15991 + * ---------------------------------------------------------------------------
15992 + * Local variables:
15993 + * c-file-style: "linux"
15996 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/sigcontext.h um/arch/um/include/sysdep-ppc/sigcontext.h
15997 --- orig/arch/um/include/sysdep-ppc/sigcontext.h 1969-12-31 19:00:00.000000000 -0500
15998 +++ um/arch/um/include/sysdep-ppc/sigcontext.h 2002-11-23 22:02:19.000000000 -0500
16001 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16002 + * Licensed under the GPL
16005 +#ifndef __SYS_SIGCONTEXT_PPC_H
16006 +#define __SYS_SIGCONTEXT_PPC_H
16008 +#define DSISR_WRITE 0x02000000
16010 +#define SC_FAULT_ADDR(sc) ({ \
16011 + struct sigcontext *_sc = (sc); \
16012 + long retval = -1; \
16013 + switch (_sc->regs->trap) { \
16015 + /* data exception */ \
16016 + retval = _sc->regs->dar; \
16019 + /* instruction exception */ \
16020 + retval = _sc->regs->nip; \
16023 + panic("SC_FAULT_ADDR: unhandled trap type\n"); \
16028 +#define SC_FAULT_WRITE(sc) ({ \
16029 + struct sigcontext *_sc = (sc); \
16030 + long retval = -1; \
16031 + switch (_sc->regs->trap) { \
16033 + /* data exception */ \
16034 + retval = !!(_sc->regs->dsisr & DSISR_WRITE); \
16037 + /* instruction exception: not a write */ \
16041 + panic("SC_FAULT_ADDR: unhandled trap type\n"); \
16046 +#define SC_IP(sc) ((sc)->regs->nip)
16047 +#define SC_SP(sc) ((sc)->regs->gpr[1])
16048 +#define SEGV_IS_FIXABLE(sc) (1)
16053 + * Overrides for Emacs so that we follow Linus's tabbing style.
16054 + * Emacs will notice this stuff at the end of the file and automatically
16055 + * adjust the settings for this buffer only. This must remain at the end
16057 + * ---------------------------------------------------------------------------
16058 + * Local variables:
16059 + * c-file-style: "linux"
16062 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/syscalls.h um/arch/um/include/sysdep-ppc/syscalls.h
16063 --- orig/arch/um/include/sysdep-ppc/syscalls.h 1969-12-31 19:00:00.000000000 -0500
16064 +++ um/arch/um/include/sysdep-ppc/syscalls.h 2002-10-23 21:08:04.000000000 -0400
16067 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16068 + * Licensed under the GPL
16071 +typedef long syscall_handler_t(unsigned long arg1, unsigned long arg2,
16072 + unsigned long arg3, unsigned long arg4,
16073 + unsigned long arg5, unsigned long arg6);
16075 +#define EXECUTE_SYSCALL(syscall, regs) \
16076 + (*sys_call_table[syscall])(UM_SYSCALL_ARG1(®s), \
16077 + UM_SYSCALL_ARG2(®s), \
16078 + UM_SYSCALL_ARG3(®s), \
16079 + UM_SYSCALL_ARG4(®s), \
16080 + UM_SYSCALL_ARG5(®s), \
16081 + UM_SYSCALL_ARG6(®s))
16083 +extern syscall_handler_t sys_mincore;
16084 +extern syscall_handler_t sys_madvise;
16086 +/* old_mmap needs the correct prototype since syscall_kern.c includes
16089 +int old_mmap(unsigned long addr, unsigned long len,
16090 + unsigned long prot, unsigned long flags,
16091 + unsigned long fd, unsigned long offset);
16093 +#define ARCH_SYSCALLS \
16094 + [ __NR_modify_ldt ] = sys_ni_syscall, \
16095 + [ __NR_pciconfig_read ] = sys_ni_syscall, \
16096 + [ __NR_pciconfig_write ] = sys_ni_syscall, \
16097 + [ __NR_pciconfig_iobase ] = sys_ni_syscall, \
16098 + [ __NR_pivot_root ] = sys_ni_syscall, \
16099 + [ __NR_multiplexer ] = sys_ni_syscall, \
16100 + [ __NR_mmap ] = old_mmap, \
16101 + [ __NR_madvise ] = sys_madvise, \
16102 + [ __NR_mincore ] = sys_mincore,
16104 +#define LAST_ARCH_SYSCALL __NR_mincore
16107 + * Overrides for Emacs so that we follow Linus's tabbing style.
16108 + * Emacs will notice this stuff at the end of the file and automatically
16109 + * adjust the settings for this buffer only. This must remain at the end
16111 + * ---------------------------------------------------------------------------
16112 + * Local variables:
16113 + * c-file-style: "linux"
16116 diff -Naur -X ../exclude-files orig/arch/um/include/sysrq.h um/arch/um/include/sysrq.h
16117 --- orig/arch/um/include/sysrq.h 1969-12-31 19:00:00.000000000 -0500
16118 +++ um/arch/um/include/sysrq.h 2002-10-23 21:08:04.000000000 -0400
16120 +#ifndef __UM_SYSRQ_H
16121 +#define __UM_SYSRQ_H
16123 +extern void show_trace(unsigned long *stack);
16126 diff -Naur -X ../exclude-files orig/arch/um/include/tempfile.h um/arch/um/include/tempfile.h
16127 --- orig/arch/um/include/tempfile.h 1969-12-31 19:00:00.000000000 -0500
16128 +++ um/arch/um/include/tempfile.h 2002-10-23 21:08:04.000000000 -0400
16131 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16132 + * Licensed under the GPL
16135 +#ifndef __TEMPFILE_H__
16136 +#define __TEMPFILE_H__
16138 +extern int make_tempfile(const char *template, char **tempname, int do_unlink);
16142 + * Overrides for Emacs so that we follow Linus's tabbing style.
16143 + * Emacs will notice this stuff at the end of the file and automatically
16144 + * adjust the settings for this buffer only. This must remain at the end
16146 + * ---------------------------------------------------------------------------
16147 + * Local variables:
16148 + * c-file-style: "linux"
16151 diff -Naur -X ../exclude-files orig/arch/um/include/time_user.h um/arch/um/include/time_user.h
16152 --- orig/arch/um/include/time_user.h 1969-12-31 19:00:00.000000000 -0500
16153 +++ um/arch/um/include/time_user.h 2003-01-08 12:55:47.000000000 -0500
16156 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16157 + * Licensed under the GPL
16160 +#ifndef __TIME_USER_H__
16161 +#define __TIME_USER_H__
16163 +extern void timer(void);
16164 +extern void switch_timers(int to_real);
16165 +extern void set_interval(int timer_type);
16166 +extern void idle_sleep(int secs);
16167 +extern void enable_timer(void);
16168 +extern unsigned long time_lock(void);
16169 +extern void time_unlock(unsigned long);
16172 diff -Naur -X ../exclude-files orig/arch/um/include/tlb.h um/arch/um/include/tlb.h
16173 --- orig/arch/um/include/tlb.h 1969-12-31 19:00:00.000000000 -0500
16174 +++ um/arch/um/include/tlb.h 2002-10-23 21:08:04.000000000 -0400
16177 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16178 + * Licensed under the GPL
16184 +extern void mprotect_kernel_vm(int w);
16185 +extern void force_flush_all(void);
16190 + * Overrides for Emacs so that we follow Linus's tabbing style.
16191 + * Emacs will notice this stuff at the end of the file and automatically
16192 + * adjust the settings for this buffer only. This must remain at the end
16194 + * ---------------------------------------------------------------------------
16195 + * Local variables:
16196 + * c-file-style: "linux"
16199 diff -Naur -X ../exclude-files orig/arch/um/include/ubd_user.h um/arch/um/include/ubd_user.h
16200 --- orig/arch/um/include/ubd_user.h 1969-12-31 19:00:00.000000000 -0500
16201 +++ um/arch/um/include/ubd_user.h 2003-03-06 18:09:14.000000000 -0500
16204 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16205 + * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com)
16206 + * Licensed under the GPL
16209 +#ifndef __UM_UBD_USER_H
16210 +#define __UM_UBD_USER_H
16214 +enum ubd_req { UBD_READ, UBD_WRITE };
16216 +struct io_thread_req {
16219 + unsigned long offsets[2];
16220 + unsigned long long offset;
16221 + unsigned long length;
16224 + unsigned long sector_mask;
16225 + unsigned long cow_offset;
16226 + unsigned long bitmap_words[2];
16230 +extern int open_ubd_file(char *file, struct openflags *openflags,
16231 + char **backing_file_out, int *bitmap_offset_out,
16232 + unsigned long *bitmap_len_out, int *data_offset_out,
16233 + int *create_cow_out);
16234 +extern int create_cow_file(char *cow_file, char *backing_file,
16235 + struct openflags flags, int sectorsize,
16236 + int *bitmap_offset_out,
16237 + unsigned long *bitmap_len_out,
16238 + int *data_offset_out);
16239 +extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
16240 +extern int read_ubd_fs(int fd, void *buffer, int len);
16241 +extern int write_ubd_fs(int fd, char *buffer, int len);
16242 +extern int start_io_thread(unsigned long sp, int *fds_out);
16243 +extern void do_io(struct io_thread_req *req);
16245 +static inline int ubd_test_bit(__u64 bit, unsigned char *data)
16250 + bits = sizeof(data[0]) * 8;
16252 + off = bit % bits;
16253 + return((data[n] & (1 << off)) != 0);
16256 +static inline void ubd_set_bit(__u64 bit, unsigned char *data)
16261 + bits = sizeof(data[0]) * 8;
16263 + off = bit % bits;
16264 + data[n] |= (1 << off);
16271 + * Overrides for Emacs so that we follow Linus's tabbing style.
16272 + * Emacs will notice this stuff at the end of the file and automatically
16273 + * adjust the settings for this buffer only. This must remain at the end
16275 + * ---------------------------------------------------------------------------
16276 + * Local variables:
16277 + * c-file-style: "linux"
16280 diff -Naur -X ../exclude-files orig/arch/um/include/umid.h um/arch/um/include/umid.h
16281 --- orig/arch/um/include/umid.h 1969-12-31 19:00:00.000000000 -0500
16282 +++ um/arch/um/include/umid.h 2002-12-16 20:52:19.000000000 -0500
16285 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
16286 + * Licensed under the GPL
16289 +#ifndef __UMID_H__
16290 +#define __UMID_H__
16292 +extern int umid_file_name(char *name, char *buf, int len);
16297 + * Overrides for Emacs so that we follow Linus's tabbing style.
16298 + * Emacs will notice this stuff at the end of the file and automatically
16299 + * adjust the settings for this buffer only. This must remain at the end
16301 + * ---------------------------------------------------------------------------
16302 + * Local variables:
16303 + * c-file-style: "linux"
16306 diff -Naur -X ../exclude-files orig/arch/um/include/uml_uaccess.h um/arch/um/include/uml_uaccess.h
16307 --- orig/arch/um/include/uml_uaccess.h 1969-12-31 19:00:00.000000000 -0500
16308 +++ um/arch/um/include/uml_uaccess.h 2002-12-19 13:15:22.000000000 -0500
16311 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
16312 + * Licensed under the GPL
16315 +#ifndef __UML_UACCESS_H__
16316 +#define __UML_UACCESS_H__
16318 +extern int __do_copy_to_user(void *to, const void *from, int n,
16319 + void **fault_addr, void **fault_catcher);
16320 +extern unsigned long __do_user_copy(void *to, const void *from, int n,
16321 + void **fault_addr, void **fault_catcher,
16322 + void (*op)(void *to, const void *from,
16323 + int n), int *faulted_out);
16324 +void __do_copy(void *to, const void *from, int n);
16329 + * Overrides for Emacs so that we follow Linus's tabbing style.
16330 + * Emacs will notice this stuff at the end of the file and automatically
16331 + * adjust the settings for this buffer only. This must remain at the end
16333 + * ---------------------------------------------------------------------------
16334 + * Local variables:
16335 + * c-file-style: "linux"
16338 diff -Naur -X ../exclude-files orig/arch/um/include/um_mmu.h um/arch/um/include/um_mmu.h
16339 --- orig/arch/um/include/um_mmu.h 1969-12-31 19:00:00.000000000 -0500
16340 +++ um/arch/um/include/um_mmu.h 2002-11-09 12:51:43.000000000 -0500
16343 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16344 + * Licensed under the GPL
16347 +#ifndef __ARCH_UM_MMU_H
16348 +#define __ARCH_UM_MMU_H
16350 +#include "linux/config.h"
16351 +#include "choose-mode.h"
16353 +#ifdef CONFIG_MODE_TT
16354 +#include "../kernel/tt/include/mmu.h"
16357 +#ifdef CONFIG_MODE_SKAS
16358 +#include "../kernel/skas/include/mmu.h"
16362 +#ifdef CONFIG_MODE_TT
16363 + struct mmu_context_tt tt;
16365 +#ifdef CONFIG_MODE_SKAS
16366 + struct mmu_context_skas skas;
16373 + * Overrides for Emacs so that we follow Linus's tabbing style.
16374 + * Emacs will notice this stuff at the end of the file and automatically
16375 + * adjust the settings for this buffer only. This must remain at the end
16377 + * ---------------------------------------------------------------------------
16378 + * Local variables:
16379 + * c-file-style: "linux"
16382 diff -Naur -X ../exclude-files orig/arch/um/include/umn.h um/arch/um/include/umn.h
16383 --- orig/arch/um/include/umn.h 1969-12-31 19:00:00.000000000 -0500
16384 +++ um/arch/um/include/umn.h 2002-10-23 21:08:04.000000000 -0400
16387 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16388 + * Licensed under the GPL
16394 +extern int open_umn_tty(int *slave_out, int *slipno_out);
16395 +extern void close_umn_tty(int master, int slave);
16396 +extern int umn_send_packet(int fd, void *data, int len);
16397 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
16398 +extern void slip_unesc(unsigned char s);
16399 +extern void umn_read(int fd);
16404 + * Overrides for Emacs so that we follow Linus's tabbing style.
16405 + * Emacs will notice this stuff at the end of the file and automatically
16406 + * adjust the settings for this buffer only. This must remain at the end
16408 + * ---------------------------------------------------------------------------
16409 + * Local variables:
16410 + * c-file-style: "linux"
16413 diff -Naur -X ../exclude-files orig/arch/um/include/um_uaccess.h um/arch/um/include/um_uaccess.h
16414 --- orig/arch/um/include/um_uaccess.h 1969-12-31 19:00:00.000000000 -0500
16415 +++ um/arch/um/include/um_uaccess.h 2002-11-23 22:03:02.000000000 -0500
16418 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16419 + * Licensed under the GPL
16422 +#ifndef __ARCH_UM_UACCESS_H
16423 +#define __ARCH_UM_UACCESS_H
16425 +#include "linux/config.h"
16426 +#include "choose-mode.h"
16428 +#ifdef CONFIG_MODE_TT
16429 +#include "../kernel/tt/include/uaccess.h"
16432 +#ifdef CONFIG_MODE_SKAS
16433 +#include "../kernel/skas/include/uaccess.h"
16436 +#define access_ok(type, addr, size) \
16437 + CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
16439 +static inline int verify_area(int type, const void * addr, unsigned long size)
16441 + return(CHOOSE_MODE_PROC(verify_area_tt, verify_area_skas, type, addr,
16445 +static inline int copy_from_user(void *to, const void *from, int n)
16447 + return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to,
16451 +static inline int copy_to_user(void *to, const void *from, int n)
16453 + return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to,
16457 +static inline int strncpy_from_user(char *dst, const char *src, int count)
16459 + return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
16460 + dst, src, count));
16463 +static inline int __clear_user(void *mem, int len)
16465 + return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
16468 +static inline int clear_user(void *mem, int len)
16470 + return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
16473 +static inline int strnlen_user(const void *str, int len)
16475 + return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
16481 + * Overrides for Emacs so that we follow Linus's tabbing style.
16482 + * Emacs will notice this stuff at the end of the file and automatically
16483 + * adjust the settings for this buffer only. This must remain at the end
16485 + * ---------------------------------------------------------------------------
16486 + * Local variables:
16487 + * c-file-style: "linux"
16490 diff -Naur -X ../exclude-files orig/arch/um/include/user.h um/arch/um/include/user.h
16491 --- orig/arch/um/include/user.h 1969-12-31 19:00:00.000000000 -0500
16492 +++ um/arch/um/include/user.h 2002-10-23 21:08:04.000000000 -0400
16495 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16496 + * Licensed under the GPL
16499 +#ifndef __USER_H__
16500 +#define __USER_H__
16502 +extern void panic(const char *fmt, ...);
16503 +extern int printk(const char *fmt, ...);
16504 +extern void schedule(void);
16505 +extern void *um_kmalloc(int size);
16506 +extern void *um_kmalloc_atomic(int size);
16507 +extern void kfree(void *ptr);
16508 +extern int in_aton(char *str);
16509 +extern int open_gdb_chan(void);
16514 + * Overrides for Emacs so that we follow Linus's tabbing style.
16515 + * Emacs will notice this stuff at the end of the file and automatically
16516 + * adjust the settings for this buffer only. This must remain at the end
16518 + * ---------------------------------------------------------------------------
16519 + * Local variables:
16520 + * c-file-style: "linux"
16523 diff -Naur -X ../exclude-files orig/arch/um/include/user_util.h um/arch/um/include/user_util.h
16524 --- orig/arch/um/include/user_util.h 1969-12-31 19:00:00.000000000 -0500
16525 +++ um/arch/um/include/user_util.h 2003-05-15 13:53:40.000000000 -0400
16528 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16529 + * Licensed under the GPL
16532 +#ifndef __USER_UTIL_H__
16533 +#define __USER_UTIL_H__
16535 +#include "sysdep/ptrace.h"
16537 +extern int mode_tt;
16539 +extern int grantpt(int __fd);
16540 +extern int unlockpt(int __fd);
16541 +extern char *ptsname(int __fd);
16543 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
16550 +extern struct cpu_task cpu_tasks[];
16552 +struct signal_info {
16553 + void (*handler)(int, union uml_pt_regs *);
16557 +extern struct signal_info sig_info[];
16559 +extern unsigned long low_physmem;
16560 +extern unsigned long high_physmem;
16561 +extern unsigned long uml_physmem;
16562 +extern unsigned long uml_reserved;
16563 +extern unsigned long end_vm;
16564 +extern unsigned long start_vm;
16565 +extern unsigned long highmem;
16567 +extern char host_info[];
16569 +extern char saved_command_line[];
16570 +extern char command_line[];
16572 +extern char *tempdir;
16574 +extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
16575 +extern unsigned long _unprotected_end;
16576 +extern unsigned long brk_start;
16578 +extern int pty_output_sigio;
16579 +extern int pty_close_sigio;
16581 +extern void stop(void);
16582 +extern void stack_protections(unsigned long address);
16583 +extern void task_protections(unsigned long address);
16584 +extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
16585 +extern void *add_signal_handler(int sig, void (*handler)(int));
16586 +extern int start_fork_tramp(void *arg, unsigned long temp_stack,
16587 + int clone_flags, int (*tramp)(void *));
16588 +extern int linux_main(int argc, char **argv);
16589 +extern void set_cmdline(char *cmd);
16590 +extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
16591 +extern int get_pty(void);
16592 +extern void *um_kmalloc(int size);
16593 +extern int raw(int fd, int complain);
16594 +extern int switcheroo(int fd, int prot, void *from, void *to, int size);
16595 +extern void setup_machinename(char *machine_out);
16596 +extern void setup_hostinfo(void);
16597 +extern void add_arg(char *cmd_line, char *arg);
16598 +extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
16599 +extern void init_new_thread_signals(int altstack);
16600 +extern void do_exec(int old_pid, int new_pid);
16601 +extern void tracer_panic(char *msg, ...);
16602 +extern char *get_umid(int only_if_set);
16603 +extern void do_longjmp(void *p, int val);
16604 +extern void suspend_new_thread(int fd);
16605 +extern int detach(int pid, int sig);
16606 +extern int attach(int pid);
16607 +extern void kill_child_dead(int pid);
16608 +extern int cont(int pid);
16609 +extern void check_ptrace(void);
16610 +extern void check_sigio(void);
16611 +extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
16612 +extern void write_sigio_workaround(void);
16613 +extern void arch_check_bugs(void);
16614 +extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
16615 +extern int arch_fixup(unsigned long address, void *sc_ptr);
16616 +extern int can_do_skas(void);
16617 +extern void arch_init_thread(void);
16622 + * Overrides for Emacs so that we follow Linus's tabbing style.
16623 + * Emacs will notice this stuff at the end of the file and automatically
16624 + * adjust the settings for this buffer only. This must remain at the end
16626 + * ---------------------------------------------------------------------------
16627 + * Local variables:
16628 + * c-file-style: "linux"
16631 diff -Naur -X ../exclude-files orig/arch/um/kernel/checksum.c um/arch/um/kernel/checksum.c
16632 --- orig/arch/um/kernel/checksum.c 1969-12-31 19:00:00.000000000 -0500
16633 +++ um/arch/um/kernel/checksum.c 2002-10-31 22:39:58.000000000 -0500
16635 +#include "asm/uaccess.h"
16636 +#include "linux/errno.h"
16638 +extern unsigned int arch_csum_partial(const char *buff, int len, int sum);
16640 +extern unsigned int csum_partial(char *buff, int len, int sum)
16642 + return(arch_csum_partial(buff, len, sum));
16645 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len,
16646 + int sum, int *err_ptr)
16648 + if(copy_to_user(dst, src, len)){
16649 + *err_ptr = -EFAULT;
16653 + return(arch_csum_partial(src, len, sum));
16656 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len,
16657 + int sum, int *err_ptr)
16659 + if(copy_from_user(dst, src, len)){
16660 + *err_ptr = -EFAULT;
16664 + return(arch_csum_partial(dst, len, sum));
16668 + * Overrides for Emacs so that we follow Linus's tabbing style.
16669 + * Emacs will notice this stuff at the end of the file and automatically
16670 + * adjust the settings for this buffer only. This must remain at the end
16672 + * ---------------------------------------------------------------------------
16673 + * Local variables:
16674 + * c-file-style: "linux"
16677 diff -Naur -X ../exclude-files orig/arch/um/kernel/config.c.in um/arch/um/kernel/config.c.in
16678 --- orig/arch/um/kernel/config.c.in 1969-12-31 19:00:00.000000000 -0500
16679 +++ um/arch/um/kernel/config.c.in 2003-04-10 11:17:55.000000000 -0400
16682 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16683 + * Licensed under the GPL
16686 +#include <stdio.h>
16687 +#include <stdlib.h>
16690 +static __initdata char *config = "CONFIG";
16692 +static int __init print_config(char *line, int *add)
16694 + printf("%s", config);
16698 +__uml_setup("--showconfig", print_config,
16700 +" Prints the config file that this UML binary was generated from.\n\n"
16704 + * Overrides for Emacs so that we follow Linus's tabbing style.
16705 + * Emacs will notice this stuff at the end of the file and automatically
16706 + * adjust the settings for this buffer only. This must remain at the end
16708 + * ---------------------------------------------------------------------------
16709 + * Local variables:
16710 + * c-file-style: "linux"
16713 diff -Naur -X ../exclude-files orig/arch/um/kernel/exec_kern.c um/arch/um/kernel/exec_kern.c
16714 --- orig/arch/um/kernel/exec_kern.c 1969-12-31 19:00:00.000000000 -0500
16715 +++ um/arch/um/kernel/exec_kern.c 2003-04-16 16:35:05.000000000 -0400
16718 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
16719 + * Licensed under the GPL
16722 +#include "linux/slab.h"
16723 +#include "linux/smp_lock.h"
16724 +#include "asm/ptrace.h"
16725 +#include "asm/pgtable.h"
16726 +#include "asm/pgalloc.h"
16727 +#include "asm/uaccess.h"
16728 +#include "user_util.h"
16729 +#include "kern_util.h"
16730 +#include "mem_user.h"
16732 +#include "irq_user.h"
16734 +#include "2_5compat.h"
16736 +#include "time_user.h"
16737 +#include "choose-mode.h"
16738 +#include "mode_kern.h"
16740 +void flush_thread(void)
16742 + CHOOSE_MODE(flush_thread_tt(), flush_thread_skas());
16745 +void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
16747 + CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
16750 +extern void log_exec(char **argv, void *tty);
16752 +static int execve1(char *file, char **argv, char **env)
16756 +#ifdef CONFIG_TTY_LOG
16757 + log_exec(argv, current->tty);
16759 + error = do_execve(file, argv, env, ¤t->thread.regs);
16761 + current->ptrace &= ~PT_DTRACE;
16762 + set_cmdline(current_cmd());
16767 +int um_execve(char *file, char **argv, char **env)
16771 + err = execve1(file, argv, env);
16773 + do_longjmp(current->thread.exec_buf, 1);
16777 +int sys_execve(char *file, char **argv, char **env)
16783 + filename = getname((char *) file);
16784 + error = PTR_ERR(filename);
16785 + if (IS_ERR(filename)) goto out;
16786 + error = execve1(filename, argv, env);
16787 + putname(filename);
16794 + * Overrides for Emacs so that we follow Linus's tabbing style.
16795 + * Emacs will notice this stuff at the end of the file and automatically
16796 + * adjust the settings for this buffer only. This must remain at the end
16798 + * ---------------------------------------------------------------------------
16799 + * Local variables:
16800 + * c-file-style: "linux"
16803 diff -Naur -X ../exclude-files orig/arch/um/kernel/exitcode.c um/arch/um/kernel/exitcode.c
16804 --- orig/arch/um/kernel/exitcode.c 1969-12-31 19:00:00.000000000 -0500
16805 +++ um/arch/um/kernel/exitcode.c 2002-11-07 18:22:04.000000000 -0500
16808 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16809 + * Licensed under the GPL
16812 +#include "linux/init.h"
16813 +#include "linux/ctype.h"
16814 +#include "linux/proc_fs.h"
16815 +#include "asm/uaccess.h"
16817 +/* If read and write race, the read will still atomically read a valid
16820 +int uml_exitcode = 0;
16822 +static int read_proc_exitcode(char *page, char **start, off_t off,
16823 + int count, int *eof, void *data)
16827 + len = sprintf(page, "%d\n", uml_exitcode);
16829 + if(len <= off+count) *eof = 1;
16830 + *start = page + off;
16831 + if(len > count) len = count;
16832 + if(len < 0) len = 0;
16836 +static int write_proc_exitcode(struct file *file, const char *buffer,
16837 + unsigned long count, void *data)
16839 + char *end, buf[sizeof("nnnnn\0")];
16842 + if(copy_from_user(buf, buffer, count))
16844 + tmp = simple_strtol(buf, &end, 0);
16845 + if((*end != '\0') && !isspace(*end))
16847 + uml_exitcode = tmp;
16851 +static int make_proc_exitcode(void)
16853 + struct proc_dir_entry *ent;
16855 + ent = create_proc_entry("exitcode", 0600, &proc_root);
16857 + printk("make_proc_exitcode : Failed to register "
16858 + "/proc/exitcode\n");
16862 + ent->read_proc = read_proc_exitcode;
16863 + ent->write_proc = write_proc_exitcode;
16868 +__initcall(make_proc_exitcode);
16871 + * Overrides for Emacs so that we follow Linus's tabbing style.
16872 + * Emacs will notice this stuff at the end of the file and automatically
16873 + * adjust the settings for this buffer only. This must remain at the end
16875 + * ---------------------------------------------------------------------------
16876 + * Local variables:
16877 + * c-file-style: "linux"
16880 diff -Naur -X ../exclude-files orig/arch/um/kernel/frame.c um/arch/um/kernel/frame.c
16881 --- orig/arch/um/kernel/frame.c 1969-12-31 19:00:00.000000000 -0500
16882 +++ um/arch/um/kernel/frame.c 2002-12-11 11:12:41.000000000 -0500
16885 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16886 + * Licensed under the GPL
16889 +#include <stdio.h>
16890 +#include <stdlib.h>
16891 +#include <unistd.h>
16892 +#include <string.h>
16893 +#include <signal.h>
16895 +#include <sched.h>
16896 +#include <errno.h>
16897 +#include <sys/ptrace.h>
16898 +#include <sys/syscall.h>
16899 +#include <sys/mman.h>
16900 +#include <asm/page.h>
16901 +#include <asm/ptrace.h>
16902 +#include <asm/sigcontext.h>
16903 +#include "sysdep/ptrace.h"
16904 +#include "sysdep/sigcontext.h"
16905 +#include "frame_user.h"
16906 +#include "kern_util.h"
16907 +#include "ptrace_user.h"
16910 +static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
16911 + unsigned long top, void **data_out)
16913 + unsigned long regs[FRAME_SIZE];
16914 + int pid, status, n, len;
16916 + /* Start the child as a thread */
16917 + pid = clone(child, sp, CLONE_VM | SIGCHLD, arg);
16919 + printf("capture_stack : clone failed - errno = %d\n", errno);
16923 + /* Wait for it to stop itself and continue it with a SIGUSR1 to force
16924 + * it into the signal handler.
16926 + n = waitpid(pid, &status, WUNTRACED);
16928 + printf("capture_stack : waitpid failed - errno = %d\n", errno);
16931 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
16932 + fprintf(stderr, "capture_stack : Expected SIGSTOP, "
16933 + "got status = 0x%x\n", status);
16936 + if(ptrace(PTRACE_CONT, pid, 0, SIGUSR1) < 0){
16937 + printf("capture_stack : PTRACE_CONT failed - errno = %d\n",
16942 + /* Wait for it to stop itself again and grab its registers again.
16943 + * At this point, the handler has stuffed the addresses of
16944 + * sig, sc, and SA_RESTORER in raw.
16946 + n = waitpid(pid, &status, WUNTRACED);
16948 + printf("capture_stack : waitpid failed - errno = %d\n", errno);
16951 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
16952 + fprintf(stderr, "capture_stack : Expected SIGSTOP, "
16953 + "got status = 0x%x\n", status);
16956 + if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0){
16957 + printf("capture_stack : PTRACE_GETREGS failed - errno = %d\n",
16962 + /* It has outlived its usefulness, so continue it so it can exit */
16963 + if(ptrace(PTRACE_CONT, pid, 0, 0) < 0){
16964 + printf("capture_stack : PTRACE_CONT failed - errno = %d\n",
16968 + if(waitpid(pid, &status, 0) < 0){
16969 + printf("capture_stack : waitpid failed - errno = %d\n", errno);
16972 + if(!WIFSIGNALED(status) || (WTERMSIG(status) != 9)){
16973 + printf("capture_stack : Expected exit signal 9, "
16974 + "got status = 0x%x\n", status);
16978 + /* The frame that we want is the top of the signal stack */
16980 + len = top - PT_SP(regs);
16981 + *data_out = malloc(len);
16982 + if(*data_out == NULL){
16983 + printf("capture_stack : malloc failed - errno = %d\n", errno);
16986 + memcpy(*data_out, (void *) PT_SP(regs), len);
16991 +struct common_raw {
16994 + unsigned long sig;
16995 + unsigned long sr;
16996 + unsigned long sp;
16997 + struct arch_frame_data_raw arch;
17000 +#define SA_RESTORER (0x04000000)
17002 +typedef unsigned long old_sigset_t;
17004 +struct old_sigaction {
17005 + __sighandler_t handler;
17006 + old_sigset_t sa_mask;
17007 + unsigned long sa_flags;
17008 + void (*sa_restorer)(void);
17011 +static void child_common(struct common_raw *common, sighandler_t handler,
17012 + int restorer, int flags)
17014 + stack_t ss = ((stack_t) { .ss_sp = common->stack,
17016 + .ss_size = common->size });
17019 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
17020 + printf("PTRACE_TRACEME failed, errno = %d\n", errno);
17022 + if(sigaltstack(&ss, NULL) < 0){
17023 + printf("sigaltstack failed - errno = %d\n", errno);
17024 + kill(getpid(), SIGKILL);
17028 + struct sigaction sa;
17030 + sa.sa_handler = handler;
17031 + sigemptyset(&sa.sa_mask);
17032 + sa.sa_flags = SA_ONSTACK | flags;
17033 + err = sigaction(SIGUSR1, &sa, NULL);
17036 + struct old_sigaction sa;
17038 + sa.handler = handler;
17040 + sa.sa_flags = (SA_ONSTACK | flags) & ~SA_RESTORER;
17041 + err = syscall(__NR_sigaction, SIGUSR1, &sa, NULL);
17045 + printf("sigaction failed - errno = %d\n", errno);
17046 + kill(getpid(), SIGKILL);
17049 + os_stop_process(os_getpid());
17052 +/* Changed only during early boot */
17053 +struct sc_frame signal_frame_sc;
17055 +struct sc_frame signal_frame_sc_sr;
17057 +struct sc_frame_raw {
17058 + struct common_raw common;
17059 + unsigned long sc;
17063 +/* Changed only during early boot */
17064 +static struct sc_frame_raw *raw_sc = NULL;
17066 +static void sc_handler(int sig, struct sigcontext sc)
17068 + raw_sc->common.sig = (unsigned long) &sig;
17069 + raw_sc->common.sr = frame_restorer();
17070 + raw_sc->common.sp = frame_sp();
17071 + raw_sc->sc = (unsigned long) ≻
17072 + setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr);
17074 + os_stop_process(os_getpid());
17075 + kill(getpid(), SIGKILL);
17078 +static int sc_child(void *arg)
17081 + child_common(&raw_sc->common, (sighandler_t) sc_handler,
17082 + raw_sc->restorer, 0);
17086 +/* Changed only during early boot */
17087 +struct si_frame signal_frame_si;
17089 +struct si_frame_raw {
17090 + struct common_raw common;
17091 + unsigned long sip;
17092 + unsigned long si;
17093 + unsigned long ucp;
17094 + unsigned long uc;
17097 +/* Changed only during early boot */
17098 +static struct si_frame_raw *raw_si = NULL;
17100 +static void si_handler(int sig, siginfo_t *si, struct ucontext *ucontext)
17102 + raw_si->common.sig = (unsigned long) &sig;
17103 + raw_si->common.sr = frame_restorer();
17104 + raw_si->common.sp = frame_sp();
17105 + raw_si->sip = (unsigned long) &si;
17106 + raw_si->si = (unsigned long) si;
17107 + raw_si->ucp = (unsigned long) &ucontext;
17108 + raw_si->uc = (unsigned long) ucontext;
17109 + setup_arch_frame_raw(&raw_si->common.arch,
17110 + ucontext->uc_mcontext.fpregs, raw_si->common.sr);
17112 + os_stop_process(os_getpid());
17113 + kill(getpid(), SIGKILL);
17116 +static int si_child(void *arg)
17119 + child_common(&raw_si->common, (sighandler_t) si_handler, 1,
17124 +static int relative_sr(unsigned long sr, int sr_index, void *stack,
17127 + unsigned long *srp = (unsigned long *) sr;
17128 + unsigned long frame = (unsigned long) framep;
17130 + if((*srp & PAGE_MASK) == (unsigned long) stack){
17132 + *((unsigned long *) (frame + sr_index)) = *srp;
17138 +static unsigned long capture_stack_common(int (*proc)(void *), void *arg,
17139 + struct common_raw *common_in,
17140 + void *top, void *sigstack,
17142 + struct frame_common *common_out)
17144 + unsigned long sig_top = (unsigned long) sigstack + stack_len, base;
17146 + common_in->stack = (void *) sigstack;
17147 + common_in->size = stack_len;
17148 + common_out->len = capture_stack(proc, arg, top, sig_top,
17149 + &common_out->data);
17150 + base = sig_top - common_out->len;
17151 + common_out->sig_index = common_in->sig - base;
17152 + common_out->sp_index = common_in->sp - base;
17153 + common_out->sr_index = common_in->sr - base;
17154 + common_out->sr_relative = relative_sr(common_in->sr,
17155 + common_out->sr_index, sigstack,
17156 + common_out->data);
17160 +void capture_signal_stack(void)
17162 + struct sc_frame_raw raw_sc;
17163 + struct si_frame_raw raw_si;
17164 + void *stack, *sigstack;
17165 + unsigned long top, sig_top, base;
17167 + stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
17168 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
17169 + sigstack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
17170 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
17171 + if((stack == MAP_FAILED) || (sigstack == MAP_FAILED)){
17172 + printf("capture_signal_stack : mmap failed - errno = %d\n",
17177 + top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
17178 + sig_top = (unsigned long) sigstack + PAGE_SIZE;
17180 + /* Get the sigcontext, no sigrestorer layout */
17181 + raw_sc.restorer = 0;
17182 + base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common,
17183 + (void *) top, sigstack, PAGE_SIZE,
17184 + &signal_frame_sc.common);
17186 + signal_frame_sc.sc_index = raw_sc.sc - base;
17187 + setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc.common.arch);
17189 + /* Ditto for the sigcontext, sigrestorer layout */
17190 + raw_sc.restorer = 1;
17191 + base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common,
17192 + (void *) top, sigstack, PAGE_SIZE,
17193 + &signal_frame_sc_sr.common);
17194 + signal_frame_sc_sr.sc_index = raw_sc.sc - base;
17195 + setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc_sr.common.arch);
17197 + /* And the siginfo layout */
17199 + base = capture_stack_common(si_child, &raw_si, &raw_si.common,
17200 + (void *) top, sigstack, PAGE_SIZE,
17201 + &signal_frame_si.common);
17202 + signal_frame_si.sip_index = raw_si.sip - base;
17203 + signal_frame_si.si_index = raw_si.si - base;
17204 + signal_frame_si.ucp_index = raw_si.ucp - base;
17205 + signal_frame_si.uc_index = raw_si.uc - base;
17206 + setup_arch_frame(&raw_si.common.arch, &signal_frame_si.common.arch);
17208 + if((munmap(stack, PAGE_SIZE) < 0) ||
17209 + (munmap(sigstack, PAGE_SIZE) < 0)){
17210 + printf("capture_signal_stack : munmap failed - errno = %d\n",
17217 + * Overrides for Emacs so that we follow Linus's tabbing style.
17218 + * Emacs will notice this stuff at the end of the file and automatically
17219 + * adjust the settings for this buffer only. This must remain at the end
17221 + * ---------------------------------------------------------------------------
17222 + * Local variables:
17223 + * c-file-style: "linux"
17226 diff -Naur -X ../exclude-files orig/arch/um/kernel/frame_kern.c um/arch/um/kernel/frame_kern.c
17227 --- orig/arch/um/kernel/frame_kern.c 1969-12-31 19:00:00.000000000 -0500
17228 +++ um/arch/um/kernel/frame_kern.c 2002-12-08 19:44:13.000000000 -0500
17231 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17232 + * Licensed under the GPL
17235 +#include "asm/ptrace.h"
17236 +#include "asm/uaccess.h"
17237 +#include "asm/signal.h"
17238 +#include "asm/uaccess.h"
17239 +#include "asm/ucontext.h"
17240 +#include "frame_kern.h"
17241 +#include "sigcontext.h"
17242 +#include "sysdep/ptrace.h"
17243 +#include "choose-mode.h"
17246 +int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
17248 + if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
17250 + if (from->si_code < 0)
17251 + return __copy_to_user(to, from, sizeof(siginfo_t));
17255 + /* If you change siginfo_t structure, please be sure
17256 + this code is fixed accordingly.
17257 + It should never copy any pad contained in the structure
17258 + to avoid security leaks, but must copy the generic
17259 + 3 ints plus the relevant union member. */
17260 + err = __put_user(from->si_signo, &to->si_signo);
17261 + err |= __put_user(from->si_errno, &to->si_errno);
17262 + err |= __put_user((short)from->si_code, &to->si_code);
17263 + /* First 32bits of unions are always present. */
17264 + err |= __put_user(from->si_pid, &to->si_pid);
17265 + switch (from->si_code >> 16) {
17266 + case __SI_FAULT >> 16:
17268 + case __SI_CHLD >> 16:
17269 + err |= __put_user(from->si_utime, &to->si_utime);
17270 + err |= __put_user(from->si_stime, &to->si_stime);
17271 + err |= __put_user(from->si_status, &to->si_status);
17273 + err |= __put_user(from->si_uid, &to->si_uid);
17280 +static int copy_restorer(void (*restorer)(void), unsigned long start,
17281 + unsigned long sr_index, int sr_relative)
17283 + unsigned long sr;
17286 + sr = (unsigned long) restorer;
17287 + sr += start + sr_index;
17288 + restorer = (void (*)(void)) sr;
17291 + return(copy_to_user((void *) (start + sr_index), &restorer,
17292 + sizeof(restorer)));
17295 +static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from,
17296 + struct arch_frame_data *arch)
17298 + return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
17300 + copy_sc_to_user_skas(to, fp, &from->regs,
17301 + current->thread.cr2,
17302 + current->thread.err)));
17305 +static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set,
17306 + unsigned long sp)
17310 + err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
17311 + err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
17312 + err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
17313 + err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs,
17314 + &signal_frame_si.common.arch);
17315 + err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
17319 +int setup_signal_stack_si(unsigned long stack_top, int sig,
17320 + unsigned long handler, void (*restorer)(void),
17321 + struct pt_regs *regs, siginfo_t *info,
17324 + unsigned long start;
17325 + void *sip, *ucp, *fp;
17327 + start = stack_top - signal_frame_si.common.len;
17328 + sip = (void *) (start + signal_frame_si.si_index);
17329 + ucp = (void *) (start + signal_frame_si.uc_index);
17330 + fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext));
17332 + if(restorer == NULL)
17333 + panic("setup_signal_stack_si - no restorer");
17335 + if(copy_to_user((void *) start, signal_frame_si.common.data,
17336 + signal_frame_si.common.len) ||
17337 + copy_to_user((void *) (start + signal_frame_si.common.sig_index),
17338 + &sig, sizeof(sig)) ||
17339 + copy_siginfo_to_user(sip, info) ||
17340 + copy_to_user((void *) (start + signal_frame_si.sip_index), &sip,
17342 + copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) ||
17343 + copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp,
17345 + copy_restorer(restorer, start, signal_frame_si.common.sr_index,
17346 + signal_frame_si.common.sr_relative))
17349 + PT_REGS_IP(regs) = handler;
17350 + PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
17354 +int setup_signal_stack_sc(unsigned long stack_top, int sig,
17355 + unsigned long handler, void (*restorer)(void),
17356 + struct pt_regs *regs, sigset_t *mask)
17358 + struct frame_common *frame = &signal_frame_sc_sr.common;
17360 + int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
17361 + unsigned long sigs, sr;
17362 + unsigned long start = stack_top - frame->len - sig_size;
17364 + user_sc = (void *) (start + signal_frame_sc_sr.sc_index);
17365 + if(restorer == NULL){
17366 + frame = &signal_frame_sc.common;
17367 + user_sc = (void *) (start + signal_frame_sc.sc_index);
17368 + sr = (unsigned long) frame->data;
17369 + sr += frame->sr_index;
17370 + sr = *((unsigned long *) sr);
17371 + restorer = ((void (*)(void)) sr);
17374 + sigs = start + frame->len;
17375 + if(copy_to_user((void *) start, frame->data, frame->len) ||
17376 + copy_to_user((void *) (start + frame->sig_index), &sig,
17378 + copy_sc_to_user(user_sc, NULL, regs,
17379 + &signal_frame_sc.common.arch) ||
17380 + copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) ||
17381 + copy_to_user((void *) sigs, &mask->sig[1], sig_size) ||
17382 + copy_restorer(restorer, start, frame->sr_index, frame->sr_relative))
17385 + PT_REGS_IP(regs) = handler;
17386 + PT_REGS_SP(regs) = start + frame->sp_index;
17392 + * Overrides for Emacs so that we follow Linus's tabbing style.
17393 + * Emacs will notice this stuff at the end of the file and automatically
17394 + * adjust the settings for this buffer only. This must remain at the end
17396 + * ---------------------------------------------------------------------------
17397 + * Local variables:
17398 + * c-file-style: "linux"
17401 diff -Naur -X ../exclude-files orig/arch/um/kernel/gmon_syms.c um/arch/um/kernel/gmon_syms.c
17402 --- orig/arch/um/kernel/gmon_syms.c 1969-12-31 19:00:00.000000000 -0500
17403 +++ um/arch/um/kernel/gmon_syms.c 2002-10-23 21:08:04.000000000 -0400
17406 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17407 + * Licensed under the GPL
17410 +#include "linux/module.h"
17412 +extern void __bb_init_func(void *);
17413 +EXPORT_SYMBOL(__bb_init_func);
17416 + * Overrides for Emacs so that we follow Linus's tabbing style.
17417 + * Emacs will notice this stuff at the end of the file and automatically
17418 + * adjust the settings for this buffer only. This must remain at the end
17420 + * ---------------------------------------------------------------------------
17421 + * Local variables:
17422 + * c-file-style: "linux"
17425 diff -Naur -X ../exclude-files orig/arch/um/kernel/gprof_syms.c um/arch/um/kernel/gprof_syms.c
17426 --- orig/arch/um/kernel/gprof_syms.c 1969-12-31 19:00:00.000000000 -0500
17427 +++ um/arch/um/kernel/gprof_syms.c 2002-10-23 21:08:04.000000000 -0400
17430 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17431 + * Licensed under the GPL
17434 +#include "linux/module.h"
17436 +extern void mcount(void);
17437 +EXPORT_SYMBOL(mcount);
17440 + * Overrides for Emacs so that we follow Linus's tabbing style.
17441 + * Emacs will notice this stuff at the end of the file and automatically
17442 + * adjust the settings for this buffer only. This must remain at the end
17444 + * ---------------------------------------------------------------------------
17445 + * Local variables:
17446 + * c-file-style: "linux"
17449 diff -Naur -X ../exclude-files orig/arch/um/kernel/helper.c um/arch/um/kernel/helper.c
17450 --- orig/arch/um/kernel/helper.c 1969-12-31 19:00:00.000000000 -0500
17451 +++ um/arch/um/kernel/helper.c 2002-10-31 10:34:23.000000000 -0500
17454 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17455 + * Licensed under the GPL
17458 +#include <stdio.h>
17459 +#include <stdlib.h>
17460 +#include <unistd.h>
17461 +#include <errno.h>
17462 +#include <fcntl.h>
17463 +#include <sched.h>
17464 +#include <sys/signal.h>
17465 +#include <sys/wait.h>
17467 +#include "kern_util.h"
17470 +struct helper_data {
17471 + void (*pre_exec)(void*);
17477 +/* Debugging aid, changed only from gdb */
17478 +int helper_pause = 0;
17480 +static void helper_hup(int sig)
17484 +static int helper_child(void *arg)
17486 + struct helper_data *data = arg;
17487 + char **argv = data->argv;
17489 + if(helper_pause){
17490 + signal(SIGHUP, helper_hup);
17493 + if(data->pre_exec != NULL)
17494 + (*data->pre_exec)(data->pre_data);
17495 + execvp(argv[0], argv);
17496 + printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
17497 + write(data->fd, &errno, sizeof(errno));
17498 + os_kill_process(os_getpid(), 0);
17502 +/* XXX The alloc_stack here breaks if this is called in the tracing thread */
17504 +int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
17505 + unsigned long *stack_out)
17507 + struct helper_data data;
17508 + unsigned long stack, sp;
17509 + int pid, fds[2], err, n;
17511 + if((stack_out != NULL) && (*stack_out != 0))
17512 + stack = *stack_out;
17513 + else stack = alloc_stack(0, um_in_interrupt());
17514 + if(stack == 0) return(-ENOMEM);
17516 + err = os_pipe(fds, 1, 0);
17518 + printk("run_helper : pipe failed, errno = %d\n", -err);
17521 + if(fcntl(fds[1], F_SETFD, 1) != 0){
17522 + printk("run_helper : setting FD_CLOEXEC failed, errno = %d\n",
17527 + sp = stack + page_size() - sizeof(void *);
17528 + data.pre_exec = pre_exec;
17529 + data.pre_data = pre_data;
17530 + data.argv = argv;
17531 + data.fd = fds[1];
17532 + pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
17534 + printk("run_helper : clone failed, errno = %d\n", errno);
17538 + n = read(fds[0], &err, sizeof(err));
17540 + printk("run_helper : read on pipe failed, errno = %d\n",
17545 + waitpid(pid, NULL, 0);
17549 + if(stack_out == NULL) free_stack(stack, 0);
17550 + else *stack_out = stack;
17554 +int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
17555 + unsigned long *stack_out, int stack_order)
17557 + unsigned long stack, sp;
17560 + stack = alloc_stack(stack_order, um_in_interrupt());
17561 + if(stack == 0) return(-ENOMEM);
17563 + sp = stack + (page_size() << stack_order) - sizeof(void *);
17564 + pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
17566 + printk("run_helper_thread : clone failed, errno = %d\n",
17570 + if(stack_out == NULL){
17571 + pid = waitpid(pid, &status, 0);
17573 + printk("run_helper_thread - wait failed, errno = %d\n",
17575 + if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
17576 + printk("run_helper_thread - thread returned status "
17577 + "0x%x\n", status);
17578 + free_stack(stack, stack_order);
17580 + else *stack_out = stack;
17584 +int helper_wait(int pid, int block)
17588 + ret = waitpid(pid, NULL, WNOHANG);
17590 + printk("helper_wait : waitpid failed, errno = %d\n", errno);
17597 + * Overrides for Emacs so that we follow Linus's tabbing style.
17598 + * Emacs will notice this stuff at the end of the file and automatically
17599 + * adjust the settings for this buffer only. This must remain at the end
17601 + * ---------------------------------------------------------------------------
17602 + * Local variables:
17603 + * c-file-style: "linux"
17606 diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_kern.c um/arch/um/kernel/initrd_kern.c
17607 --- orig/arch/um/kernel/initrd_kern.c 1969-12-31 19:00:00.000000000 -0500
17608 +++ um/arch/um/kernel/initrd_kern.c 2002-10-23 21:08:04.000000000 -0400
17611 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
17612 + * Licensed under the GPL
17615 +#include "linux/init.h"
17616 +#include "linux/bootmem.h"
17617 +#include "linux/blk.h"
17618 +#include "asm/types.h"
17619 +#include "user_util.h"
17620 +#include "kern_util.h"
17621 +#include "initrd.h"
17625 +/* Changed by uml_initrd_setup, which is a setup */
17626 +static char *initrd __initdata = NULL;
17628 +static int __init read_initrd(void)
17634 + if(initrd == NULL) return 0;
17635 + err = os_file_size(initrd, &size);
17636 + if(err) return 0;
17637 + area = alloc_bootmem(size);
17638 + if(area == NULL) return 0;
17639 + if(load_initrd(initrd, area, size) == -1) return 0;
17640 + initrd_start = (unsigned long) area;
17641 + initrd_end = initrd_start + size;
17645 +__uml_postsetup(read_initrd);
17647 +static int __init uml_initrd_setup(char *line, int *add)
17653 +__uml_setup("initrd=", uml_initrd_setup,
17654 +"initrd=<initrd image>\n"
17655 +" This is used to boot UML from an initrd image. The argument is the\n"
17656 +" name of the file containing the image.\n\n"
17660 + * Overrides for Emacs so that we follow Linus's tabbing style.
17661 + * Emacs will notice this stuff at the end of the file and automatically
17662 + * adjust the settings for this buffer only. This must remain at the end
17664 + * ---------------------------------------------------------------------------
17665 + * Local variables:
17666 + * c-file-style: "linux"
17669 diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_user.c um/arch/um/kernel/initrd_user.c
17670 --- orig/arch/um/kernel/initrd_user.c 1969-12-31 19:00:00.000000000 -0500
17671 +++ um/arch/um/kernel/initrd_user.c 2002-10-23 21:08:04.000000000 -0400
17674 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
17675 + * Licensed under the GPL
17678 +#include <unistd.h>
17679 +#include <sys/types.h>
17680 +#include <sys/stat.h>
17681 +#include <fcntl.h>
17682 +#include <errno.h>
17684 +#include "user_util.h"
17685 +#include "kern_util.h"
17687 +#include "initrd.h"
17690 +int load_initrd(char *filename, void *buf, int size)
17694 + if((fd = os_open_file(filename, of_read(OPENFLAGS()), 0)) < 0){
17695 + printk("Opening '%s' failed - errno = %d\n", filename, errno);
17698 + if((n = read(fd, buf, size)) != size){
17699 + printk("Read of %d bytes from '%s' returned %d, errno = %d\n",
17700 + size, filename, n, errno);
17707 + * Overrides for Emacs so that we follow Linus's tabbing style.
17708 + * Emacs will notice this stuff at the end of the file and automatically
17709 + * adjust the settings for this buffer only. This must remain at the end
17711 + * ---------------------------------------------------------------------------
17712 + * Local variables:
17713 + * c-file-style: "linux"
17716 diff -Naur -X ../exclude-files orig/arch/um/kernel/init_task.c um/arch/um/kernel/init_task.c
17717 --- orig/arch/um/kernel/init_task.c 1969-12-31 19:00:00.000000000 -0500
17718 +++ um/arch/um/kernel/init_task.c 2002-12-28 19:58:44.000000000 -0500
17721 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17722 + * Licensed under the GPL
17725 +#include "linux/config.h"
17726 +#include "linux/mm.h"
17727 +#include "linux/sched.h"
17728 +#include "linux/version.h"
17729 +#include "asm/uaccess.h"
17730 +#include "asm/pgtable.h"
17731 +#include "user_util.h"
17732 +#include "mem_user.h"
17734 +static struct fs_struct init_fs = INIT_FS;
17735 +static struct files_struct init_files = INIT_FILES;
17736 +static struct signal_struct init_signals = INIT_SIGNALS;
17737 +struct mm_struct init_mm = INIT_MM(init_mm);
17740 + * Initial task structure.
17742 + * We need to make sure that this is 16384-byte aligned due to the
17743 + * way process stacks are handled. This is done by having a special
17744 + * "init_task" linker map entry..
17747 +union task_union init_task_union
17748 +__attribute__((__section__(".data.init_task"))) =
17749 +{ INIT_TASK(init_task_union.task) };
17751 +struct task_struct *alloc_task_struct(void)
17753 + return((struct task_struct *)
17754 + __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
17757 +void unprotect_stack(unsigned long stack)
17759 + protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
17763 +void free_task_struct(struct task_struct *task)
17765 + /* free_pages decrements the page counter and only actually frees
17766 + * the pages if they are now not accessed by anything.
17768 + free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
17772 + * Overrides for Emacs so that we follow Linus's tabbing style.
17773 + * Emacs will notice this stuff at the end of the file and automatically
17774 + * adjust the settings for this buffer only. This must remain at the end
17776 + * ---------------------------------------------------------------------------
17777 + * Local variables:
17778 + * c-file-style: "linux"
17781 diff -Naur -X ../exclude-files orig/arch/um/kernel/irq.c um/arch/um/kernel/irq.c
17782 --- orig/arch/um/kernel/irq.c 1969-12-31 19:00:00.000000000 -0500
17783 +++ um/arch/um/kernel/irq.c 2003-03-26 14:45:29.000000000 -0500
17786 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17787 + * Licensed under the GPL
17788 + * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
17789 + * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
17792 +#include "linux/config.h"
17793 +#include "linux/kernel.h"
17794 +#include "linux/smp.h"
17795 +#include "linux/irq.h"
17796 +#include "linux/kernel_stat.h"
17797 +#include "linux/interrupt.h"
17798 +#include "linux/random.h"
17799 +#include "linux/slab.h"
17800 +#include "linux/file.h"
17801 +#include "linux/proc_fs.h"
17802 +#include "linux/init.h"
17803 +#include "linux/seq_file.h"
17804 +#include "asm/irq.h"
17805 +#include "asm/hw_irq.h"
17806 +#include "asm/hardirq.h"
17807 +#include "asm/atomic.h"
17808 +#include "asm/signal.h"
17809 +#include "asm/system.h"
17810 +#include "asm/errno.h"
17811 +#include "asm/uaccess.h"
17812 +#include "user_util.h"
17813 +#include "kern_util.h"
17814 +#include "irq_user.h"
17816 +static void register_irq_proc (unsigned int irq);
17818 +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
17819 + { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
17822 + * Generic no controller code
17825 +static void enable_none(unsigned int irq) { }
17826 +static unsigned int startup_none(unsigned int irq) { return 0; }
17827 +static void disable_none(unsigned int irq) { }
17828 +static void ack_none(unsigned int irq)
17831 + * 'what should we do if we get a hw irq event on an illegal vector'.
17832 + * each architecture has to answer this themselves, it doesnt deserve
17833 + * a generic callback i think.
17836 + printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
17837 +#ifdef CONFIG_X86_LOCAL_APIC
17839 + * Currently unexpected vectors happen only on SMP and APIC.
17840 + * We _must_ ack these because every local APIC has only N
17841 + * irq slots per priority level, and a 'hanging, unacked' IRQ
17842 + * holds up an irq slot - in excessive cases (when multiple
17843 + * unexpected vectors occur) that might lock up the APIC
17851 +/* startup is the same as "enable", shutdown is same as "disable" */
17852 +#define shutdown_none disable_none
17853 +#define end_none enable_none
17855 +struct hw_interrupt_type no_irq_type = {
17866 +volatile unsigned long irq_err_count;
17869 + * Generic, controller-independent functions:
17872 +int get_irq_list(char *buf)
17875 + unsigned long flags;
17876 + struct irqaction * action;
17879 + p += sprintf(p, " ");
17880 + for (j=0; j<smp_num_cpus; j++)
17881 + p += sprintf(p, "CPU%d ",j);
17884 + for (i = 0 ; i < NR_IRQS ; i++) {
17885 + spin_lock_irqsave(&irq_desc[i].lock, flags);
17886 + action = irq_desc[i].action;
17889 + p += sprintf(p, "%3d: ",i);
17890 +#ifndef CONFIG_SMP
17891 + p += sprintf(p, "%10u ", kstat_irqs(i));
17893 + for (j = 0; j < smp_num_cpus; j++)
17894 + p += sprintf(p, "%10u ",
17895 + kstat.irqs[cpu_logical_map(j)][i]);
17897 + p += sprintf(p, " %14s", irq_desc[i].handler->typename);
17898 + p += sprintf(p, " %s", action->name);
17900 + for (action=action->next; action; action = action->next)
17901 + p += sprintf(p, ", %s", action->name);
17904 + spin_unlock_irqrestore(&irq_desc[i].lock, flags);
17906 + p += sprintf(p, "\n");
17909 + p += sprintf(p, "LOC: ");
17910 + for (j = 0; j < smp_num_cpus; j++)
17911 + p += sprintf(p, "%10u ",
17912 + apic_timer_irqs[cpu_logical_map(j)]);
17913 + p += sprintf(p, "\n");
17916 + p += sprintf(p, "ERR: %10lu\n", irq_err_count);
17922 + * This should really return information about whether
17923 + * we should do bottom half handling etc. Right now we
17924 + * end up _always_ checking the bottom half, which is a
17925 + * waste of time and is not what some drivers would
17928 +int handle_IRQ_event(unsigned int irq, struct pt_regs * regs,
17929 + struct irqaction * action)
17932 + int cpu = smp_processor_id();
17934 + irq_enter(cpu, irq);
17936 + status = 1; /* Force the "do bottom halves" bit */
17938 + if (!(action->flags & SA_INTERRUPT))
17942 + status |= action->flags;
17943 + action->handler(irq, action->dev_id, regs);
17944 + action = action->next;
17945 + } while (action);
17946 + if (status & SA_SAMPLE_RANDOM)
17947 + add_interrupt_randomness(irq);
17950 + irq_exit(cpu, irq);
17956 + * Generic enable/disable code: this just calls
17957 + * down into the PIC-specific version for the actual
17958 + * hardware disable after having gotten the irq
17959 + * controller lock.
17963 + * disable_irq_nosync - disable an irq without waiting
17964 + * @irq: Interrupt to disable
17966 + * Disable the selected interrupt line. Disables of an interrupt
17967 + * stack. Unlike disable_irq(), this function does not ensure existing
17968 + * instances of the IRQ handler have completed before returning.
17970 + * This function may be called from IRQ context.
17973 +void inline disable_irq_nosync(unsigned int irq)
17975 + irq_desc_t *desc = irq_desc + irq;
17976 + unsigned long flags;
17978 + spin_lock_irqsave(&desc->lock, flags);
17979 + if (!desc->depth++) {
17980 + desc->status |= IRQ_DISABLED;
17981 + desc->handler->disable(irq);
17983 + spin_unlock_irqrestore(&desc->lock, flags);
17987 + * disable_irq - disable an irq and wait for completion
17988 + * @irq: Interrupt to disable
17990 + * Disable the selected interrupt line. Disables of an interrupt
17991 + * stack. That is for two disables you need two enables. This
17992 + * function waits for any pending IRQ handlers for this interrupt
17993 + * to complete before returning. If you use this function while
17994 + * holding a resource the IRQ handler may need you will deadlock.
17996 + * This function may be called - with care - from IRQ context.
17999 +void disable_irq(unsigned int irq)
18001 + disable_irq_nosync(irq);
18003 + if (!local_irq_count(smp_processor_id())) {
18006 + } while (irq_desc[irq].status & IRQ_INPROGRESS);
18011 + * enable_irq - enable interrupt handling on an irq
18012 + * @irq: Interrupt to enable
18014 + * Re-enables the processing of interrupts on this IRQ line
18015 + * providing no disable_irq calls are now in effect.
18017 + * This function may be called from IRQ context.
18020 +void enable_irq(unsigned int irq)
18022 + irq_desc_t *desc = irq_desc + irq;
18023 + unsigned long flags;
18025 + spin_lock_irqsave(&desc->lock, flags);
18026 + switch (desc->depth) {
18028 + unsigned int status = desc->status & ~IRQ_DISABLED;
18029 + desc->status = status;
18030 + if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
18031 + desc->status = status | IRQ_REPLAY;
18032 + hw_resend_irq(desc->handler,irq);
18034 + desc->handler->enable(irq);
18035 + /* fall-through */
18041 + printk(KERN_ERR "enable_irq() unbalanced from %p\n",
18042 + __builtin_return_address(0));
18044 + spin_unlock_irqrestore(&desc->lock, flags);
18048 + * do_IRQ handles all normal device IRQ's (the special
18049 + * SMP cross-CPU interrupts have their own specific
18052 +unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
18055 + * 0 return value means that this irq is already being
18056 + * handled by some other CPU. (or is disabled)
18058 + int cpu = smp_processor_id();
18059 + irq_desc_t *desc = irq_desc + irq;
18060 + struct irqaction * action;
18061 + unsigned int status;
18063 + kstat.irqs[cpu][irq]++;
18064 + spin_lock(&desc->lock);
18065 + desc->handler->ack(irq);
18067 + REPLAY is when Linux resends an IRQ that was dropped earlier
18068 + WAITING is used by probe to mark irqs that are being tested
18070 + status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
18071 + status |= IRQ_PENDING; /* we _want_ to handle it */
18074 + * If the IRQ is disabled for whatever reason, we cannot
18075 + * use the action we have.
18078 + if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
18079 + action = desc->action;
18080 + status &= ~IRQ_PENDING; /* we commit to handling */
18081 + status |= IRQ_INPROGRESS; /* we are handling it */
18083 + desc->status = status;
18086 + * If there is no IRQ handler or it was disabled, exit early.
18087 + Since we set PENDING, if another processor is handling
18088 + a different instance of this same irq, the other processor
18089 + will take care of it.
18095 + * Edge triggered interrupts need to remember
18096 + * pending events.
18097 + * This applies to any hw interrupts that allow a second
18098 + * instance of the same irq to arrive while we are in do_IRQ
18099 + * or in the handler. But the code here only handles the _second_
18100 + * instance of the irq, not the third or fourth. So it is mostly
18101 + * useful for irq hardware that does not mask cleanly in an
18102 + * SMP environment.
18105 + spin_unlock(&desc->lock);
18106 + handle_IRQ_event(irq, (struct pt_regs *) regs, action);
18107 + spin_lock(&desc->lock);
18109 + if (!(desc->status & IRQ_PENDING))
18111 + desc->status &= ~IRQ_PENDING;
18113 + desc->status &= ~IRQ_INPROGRESS;
18116 + * The ->end() handler has to deal with interrupts which got
18117 + * disabled while the handler was running.
18119 + desc->handler->end(irq);
18120 + spin_unlock(&desc->lock);
18122 + if (softirq_pending(cpu))
18128 + * request_irq - allocate an interrupt line
18129 + * @irq: Interrupt line to allocate
18130 + * @handler: Function to be called when the IRQ occurs
18131 + * @irqflags: Interrupt type flags
18132 + * @devname: An ascii name for the claiming device
18133 + * @dev_id: A cookie passed back to the handler function
18135 + * This call allocates interrupt resources and enables the
18136 + * interrupt line and IRQ handling. From the point this
18137 + * call is made your handler function may be invoked. Since
18138 + * your handler function must clear any interrupt the board
18139 + * raises, you must take care both to initialise your hardware
18140 + * and to set up the interrupt handler in the right order.
18142 + * Dev_id must be globally unique. Normally the address of the
18143 + * device data structure is used as the cookie. Since the handler
18144 + * receives this value it makes sense to use it.
18146 + * If your interrupt is shared you must pass a non NULL dev_id
18147 + * as this is required when freeing the interrupt.
18151 + * SA_SHIRQ Interrupt is shared
18153 + * SA_INTERRUPT Disable local interrupts while processing
18155 + * SA_SAMPLE_RANDOM The interrupt can be used for entropy
18159 +int request_irq(unsigned int irq,
18160 + void (*handler)(int, void *, struct pt_regs *),
18161 + unsigned long irqflags,
18162 + const char * devname,
18166 + struct irqaction * action;
18170 + * Sanity-check: shared interrupts should REALLY pass in
18171 + * a real dev-ID, otherwise we'll have trouble later trying
18172 + * to figure out which interrupt is which (messes up the
18173 + * interrupt freeing logic etc).
18175 + if (irqflags & SA_SHIRQ) {
18177 + printk(KERN_ERR "Bad boy: %s (at 0x%x) called us "
18178 + "without a dev_id!\n", devname, (&irq)[-1]);
18182 + if (irq >= NR_IRQS)
18187 + action = (struct irqaction *)
18188 + kmalloc(sizeof(struct irqaction), GFP_KERNEL);
18192 + action->handler = handler;
18193 + action->flags = irqflags;
18194 + action->mask = 0;
18195 + action->name = devname;
18196 + action->next = NULL;
18197 + action->dev_id = dev_id;
18199 + retval = setup_irq(irq, action);
18205 +int um_request_irq(unsigned int irq, int fd, int type,
18206 + void (*handler)(int, void *, struct pt_regs *),
18207 + unsigned long irqflags, const char * devname,
18212 + err = request_irq(irq, handler, irqflags, devname, dev_id);
18217 + err = activate_fd(irq, fd, type, dev_id);
18221 +/* this was setup_x86_irq but it seems pretty generic */
18222 +int setup_irq(unsigned int irq, struct irqaction * new)
18225 + unsigned long flags;
18226 + struct irqaction *old, **p;
18227 + irq_desc_t *desc = irq_desc + irq;
18230 + * Some drivers like serial.c use request_irq() heavily,
18231 + * so we have to be careful not to interfere with a
18232 + * running system.
18234 + if (new->flags & SA_SAMPLE_RANDOM) {
18236 + * This function might sleep, we want to call it first,
18237 + * outside of the atomic block.
18238 + * Yes, this might clear the entropy pool if the wrong
18239 + * driver is attempted to be loaded, without actually
18240 + * installing a new handler, but is this really a problem,
18241 + * only the sysadmin is able to do this.
18243 + rand_initialize_irq(irq);
18247 + * The following block of code has to be executed atomically
18249 + spin_lock_irqsave(&desc->lock,flags);
18250 + p = &desc->action;
18251 + if ((old = *p) != NULL) {
18252 + /* Can't share interrupts unless both agree to */
18253 + if (!(old->flags & new->flags & SA_SHIRQ)) {
18254 + spin_unlock_irqrestore(&desc->lock,flags);
18258 + /* add new interrupt at end of irq queue */
18270 + desc->status &= ~IRQ_DISABLED;
18271 + desc->handler->startup(irq);
18273 + spin_unlock_irqrestore(&desc->lock,flags);
18275 + register_irq_proc(irq);
18280 + * free_irq - free an interrupt
18281 + * @irq: Interrupt line to free
18282 + * @dev_id: Device identity to free
18284 + * Remove an interrupt handler. The handler is removed and if the
18285 + * interrupt line is no longer in use by any driver it is disabled.
18286 + * On a shared IRQ the caller must ensure the interrupt is disabled
18287 + * on the card it drives before calling this function. The function
18288 + * does not return until any executing interrupts for this IRQ
18289 + * have completed.
18291 + * This function may be called from interrupt context.
18293 + * Bugs: Attempting to free an irq in a handler for the same irq hangs
18297 +void free_irq(unsigned int irq, void *dev_id)
18299 + irq_desc_t *desc;
18300 + struct irqaction **p;
18301 + unsigned long flags;
18303 + if (irq >= NR_IRQS)
18306 + desc = irq_desc + irq;
18307 + spin_lock_irqsave(&desc->lock,flags);
18308 + p = &desc->action;
18310 + struct irqaction * action = *p;
18312 + struct irqaction **pp = p;
18313 + p = &action->next;
18314 + if (action->dev_id != dev_id)
18317 + /* Found it - now remove it from the list of entries */
18318 + *pp = action->next;
18319 + if (!desc->action) {
18320 + desc->status |= IRQ_DISABLED;
18321 + desc->handler->shutdown(irq);
18323 + free_irq_by_irq_and_dev(irq, dev_id);
18324 + spin_unlock_irqrestore(&desc->lock,flags);
18327 + /* Wait to make sure it's not being used on another CPU */
18328 + while (desc->status & IRQ_INPROGRESS)
18334 + printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
18335 + spin_unlock_irqrestore(&desc->lock,flags);
18340 +/* These are initialized by sysctl_init, which is called from init/main.c */
18341 +static struct proc_dir_entry * root_irq_dir;
18342 +static struct proc_dir_entry * irq_dir [NR_IRQS];
18343 +static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
18345 +/* These are read and written as longs, so a read won't see a partial write
18346 + * even during a race.
18348 +static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
18350 +#define HEX_DIGITS 8
18352 +static int irq_affinity_read_proc (char *page, char **start, off_t off,
18353 + int count, int *eof, void *data)
18355 + if (count < HEX_DIGITS+1)
18357 + return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
18360 +static unsigned int parse_hex_value (const char *buffer,
18361 + unsigned long count, unsigned long *ret)
18363 + unsigned char hexnum [HEX_DIGITS];
18364 + unsigned long value;
18369 + if (count > HEX_DIGITS)
18370 + count = HEX_DIGITS;
18371 + if (copy_from_user(hexnum, buffer, count))
18375 + * Parse the first 8 characters as a hex string, any non-hex char
18376 + * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
18380 + for (i = 0; i < count; i++) {
18381 + unsigned int c = hexnum[i];
18384 + case '0' ... '9': c -= '0'; break;
18385 + case 'a' ... 'f': c -= 'a'-10; break;
18386 + case 'A' ... 'F': c -= 'A'-10; break;
18390 + value = (value << 4) | c;
18397 +static int irq_affinity_write_proc (struct file *file, const char *buffer,
18398 + unsigned long count, void *data)
18400 + int irq = (long) data, full_count = count, err;
18401 + unsigned long new_value;
18403 + if (!irq_desc[irq].handler->set_affinity)
18406 + err = parse_hex_value(buffer, count, &new_value);
18410 + * Do not allow disabling IRQs completely - it's a too easy
18411 + * way to make the system unusable accidentally :-) At least
18412 + * one online CPU still has to be targeted.
18414 + if (!(new_value & cpu_online_map))
18418 + irq_affinity[irq] = new_value;
18419 + irq_desc[irq].handler->set_affinity(irq, new_value);
18421 + return full_count;
18424 +static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
18425 + int count, int *eof, void *data)
18427 + unsigned long *mask = (unsigned long *) data;
18428 + if (count < HEX_DIGITS+1)
18430 + return sprintf (page, "%08lx\n", *mask);
18433 +static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
18434 + unsigned long count, void *data)
18436 + unsigned long *mask = (unsigned long *) data, full_count = count, err;
18437 + unsigned long new_value;
18439 + err = parse_hex_value(buffer, count, &new_value);
18443 + *mask = new_value;
18444 + return full_count;
18447 +#define MAX_NAMELEN 10
18449 +static void register_irq_proc (unsigned int irq)
18451 + struct proc_dir_entry *entry;
18452 + char name [MAX_NAMELEN];
18454 + if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
18458 + memset(name, 0, MAX_NAMELEN);
18459 + sprintf(name, "%d", irq);
18461 + /* create /proc/irq/1234 */
18462 + irq_dir[irq] = proc_mkdir(name, root_irq_dir);
18464 + /* create /proc/irq/1234/smp_affinity */
18465 + entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
18467 + entry->nlink = 1;
18468 + entry->data = (void *)(long)irq;
18469 + entry->read_proc = irq_affinity_read_proc;
18470 + entry->write_proc = irq_affinity_write_proc;
18472 + smp_affinity_entry[irq] = entry;
18475 +/* Read and written as a long */
18476 +unsigned long prof_cpu_mask = -1;
18478 +void __init init_irq_proc (void)
18480 + struct proc_dir_entry *entry;
18483 + /* create /proc/irq */
18484 + root_irq_dir = proc_mkdir("irq", 0);
18486 + /* create /proc/irq/prof_cpu_mask */
18487 + entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
18489 + entry->nlink = 1;
18490 + entry->data = (void *)&prof_cpu_mask;
18491 + entry->read_proc = prof_cpu_mask_read_proc;
18492 + entry->write_proc = prof_cpu_mask_write_proc;
18495 + * Create entries for all existing IRQs.
18497 + for (i = 0; i < NR_IRQS; i++)
18498 + register_irq_proc(i);
18501 +static spinlock_t irq_spinlock = SPIN_LOCK_UNLOCKED;
18503 +unsigned long irq_lock(void)
18505 + unsigned long flags;
18507 + spin_lock_irqsave(&irq_spinlock, flags);
18511 +void irq_unlock(unsigned long flags)
18513 + spin_unlock_irqrestore(&irq_spinlock, flags);
18516 +unsigned long probe_irq_on(void)
18521 +int probe_irq_off(unsigned long val)
18526 +static unsigned int startup_SIGIO_irq(unsigned int irq)
18531 +static void shutdown_SIGIO_irq(unsigned int irq)
18535 +static void enable_SIGIO_irq(unsigned int irq)
18539 +static void disable_SIGIO_irq(unsigned int irq)
18543 +static void mask_and_ack_SIGIO(unsigned int irq)
18547 +static void end_SIGIO_irq(unsigned int irq)
18551 +static unsigned int startup_SIGVTALRM_irq(unsigned int irq)
18556 +static void shutdown_SIGVTALRM_irq(unsigned int irq)
18560 +static void enable_SIGVTALRM_irq(unsigned int irq)
18564 +static void disable_SIGVTALRM_irq(unsigned int irq)
18568 +static void mask_and_ack_SIGVTALRM(unsigned int irq)
18572 +static void end_SIGVTALRM_irq(unsigned int irq)
18576 +static struct hw_interrupt_type SIGIO_irq_type = {
18578 + startup_SIGIO_irq,
18579 + shutdown_SIGIO_irq,
18580 + enable_SIGIO_irq,
18581 + disable_SIGIO_irq,
18582 + mask_and_ack_SIGIO,
18587 +static struct hw_interrupt_type SIGVTALRM_irq_type = {
18589 + startup_SIGVTALRM_irq,
18590 + shutdown_SIGVTALRM_irq,
18591 + enable_SIGVTALRM_irq,
18592 + disable_SIGVTALRM_irq,
18593 + mask_and_ack_SIGVTALRM,
18594 + end_SIGVTALRM_irq,
18598 +void __init init_IRQ(void)
18602 + irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
18603 + irq_desc[TIMER_IRQ].action = 0;
18604 + irq_desc[TIMER_IRQ].depth = 1;
18605 + irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type;
18606 + enable_irq(TIMER_IRQ);
18607 + for(i=1;i<NR_IRQS;i++){
18608 + irq_desc[i].status = IRQ_DISABLED;
18609 + irq_desc[i].action = 0;
18610 + irq_desc[i].depth = 1;
18611 + irq_desc[i].handler = &SIGIO_irq_type;
18614 + init_irq_signals(0);
18618 + * Overrides for Emacs so that we follow Linus's tabbing style.
18619 + * Emacs will notice this stuff at the end of the file and automatically
18620 + * adjust the settings for this buffer only. This must remain at the end
18622 + * ---------------------------------------------------------------------------
18623 + * Local variables:
18624 + * c-file-style: "linux"
18627 diff -Naur -X ../exclude-files orig/arch/um/kernel/irq_user.c um/arch/um/kernel/irq_user.c
18628 --- orig/arch/um/kernel/irq_user.c 1969-12-31 19:00:00.000000000 -0500
18629 +++ um/arch/um/kernel/irq_user.c 2002-12-22 15:49:46.000000000 -0500
18632 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
18633 + * Licensed under the GPL
18636 +#include <stdlib.h>
18637 +#include <unistd.h>
18638 +#include <errno.h>
18639 +#include <fcntl.h>
18640 +#include <signal.h>
18641 +#include <string.h>
18642 +#include <sys/poll.h>
18643 +#include <sys/types.h>
18644 +#include <sys/time.h>
18645 +#include "user_util.h"
18646 +#include "kern_util.h"
18648 +#include "process.h"
18649 +#include "signal_user.h"
18650 +#include "sigio.h"
18651 +#include "irq_user.h"
18655 + struct irq_fd *next;
18662 + int current_events;
18666 +static struct irq_fd *active_fds = NULL;
18667 +static struct irq_fd **last_irq_ptr = &active_fds;
18669 +static struct pollfd *pollfds = NULL;
18670 +static int pollfds_num = 0;
18671 +static int pollfds_size = 0;
18673 +extern int io_count, intr_count;
18675 +void sigio_handler(int sig, union uml_pt_regs *regs)
18677 + struct irq_fd *irq_fd, *next;
18680 + if(smp_sigio_handler()) return;
18682 + if((n = poll(pollfds, pollfds_num, 0)) < 0){
18683 + if(errno == EINTR) continue;
18684 + printk("sigio_handler : poll returned %d, "
18685 + "errno = %d\n", n, errno);
18688 + if(n == 0) break;
18690 + irq_fd = active_fds;
18691 + for(i = 0; i < pollfds_num; i++){
18692 + if(pollfds[i].revents != 0){
18693 + irq_fd->current_events = pollfds[i].revents;
18694 + pollfds[i].fd = -1;
18696 + irq_fd = irq_fd->next;
18699 + for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){
18700 + next = irq_fd->next;
18701 + if(irq_fd->current_events != 0){
18702 + irq_fd->current_events = 0;
18703 + do_IRQ(irq_fd->irq, regs);
18705 + /* This is here because the next irq may be
18706 + * freed in the handler. If a console goes
18707 + * away, both the read and write irqs will be
18708 + * freed. After do_IRQ, ->next will point to
18710 + * Irqs can't be freed inside their handlers,
18711 + * so the next best thing is to have them
18712 + * marked as needing freeing, so that they
18713 + * can be freed here.
18715 + next = irq_fd->next;
18716 + if(irq_fd->freed)
18717 + free_irq(irq_fd->irq, irq_fd->id);
18723 +int activate_ipi(int fd, int pid)
18725 + return(os_set_fd_async(fd, pid));
18728 +static void maybe_sigio_broken(int fd, int type)
18731 + if((type == IRQ_WRITE) && !pty_output_sigio){
18732 + write_sigio_workaround();
18733 + add_sigio_fd(fd, 0);
18735 + else if((type == IRQ_READ) && !pty_close_sigio){
18736 + write_sigio_workaround();
18737 + add_sigio_fd(fd, 1);
18742 +int activate_fd(int irq, int fd, int type, void *dev_id)
18744 + struct pollfd *tmp_pfd;
18745 + struct irq_fd *new_fd, *irq_fd;
18746 + unsigned long flags;
18747 + int pid, events, err, n, size;
18749 + pid = os_getpid();
18750 + err = os_set_fd_async(fd, pid);
18754 + new_fd = um_kmalloc(sizeof(*new_fd));
18756 + if(new_fd == NULL)
18759 + if(type == IRQ_READ) events = POLLIN | POLLPRI;
18760 + else events = POLLOUT;
18761 + *new_fd = ((struct irq_fd) { .next = NULL,
18767 + .events = events,
18768 + .current_events = 0,
18771 + /* Critical section - locked by a spinlock because this stuff can
18772 + * be changed from interrupt handlers. The stuff above is done
18773 + * outside the lock because it allocates memory.
18776 + /* Actually, it only looks like it can be called from interrupt
18777 + * context. The culprit is reactivate_fd, which calls
18778 + * maybe_sigio_broken, which calls write_sigio_workaround,
18779 + * which calls activate_fd. However, write_sigio_workaround should
18780 + * only be called once, at boot time. That would make it clear that
18781 + * this is called only from process context, and can be locked with
18784 + flags = irq_lock();
18785 + for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
18786 + if((irq_fd->fd == fd) && (irq_fd->type == type)){
18787 + printk("Registering fd %d twice\n", fd);
18788 + printk("Irqs : %d, %d\n", irq_fd->irq, irq);
18789 + printk("Ids : 0x%x, 0x%x\n", irq_fd->id, dev_id);
18795 + if(n == pollfds_size){
18797 + /* Here we have to drop the lock in order to call
18798 + * kmalloc, which might sleep. If something else
18799 + * came in and changed the pollfds array, we free
18800 + * the buffer and try again.
18802 + irq_unlock(flags);
18803 + size = (pollfds_num + 1) * sizeof(pollfds[0]);
18804 + tmp_pfd = um_kmalloc(size);
18805 + flags = irq_lock();
18806 + if(tmp_pfd == NULL)
18808 + if(n == pollfds_size)
18812 + if(pollfds != NULL){
18813 + memcpy(tmp_pfd, pollfds,
18814 + sizeof(pollfds[0]) * pollfds_size);
18817 + pollfds = tmp_pfd;
18821 + if(type == IRQ_WRITE)
18824 + pollfds[pollfds_num] = ((struct pollfd) { .fd = fd,
18825 + .events = events,
18829 + *last_irq_ptr = new_fd;
18830 + last_irq_ptr = &new_fd->next;
18832 + irq_unlock(flags);
18834 + /* This calls activate_fd, so it has to be outside the critical
18837 + maybe_sigio_broken(fd, type);
18842 + irq_unlock(flags);
18848 +static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
18850 + struct irq_fd **prev;
18851 + unsigned long flags;
18854 + flags = irq_lock();
18855 + prev = &active_fds;
18856 + while(*prev != NULL){
18857 + if((*test)(*prev, arg)){
18858 + struct irq_fd *old_fd = *prev;
18859 + if((pollfds[i].fd != -1) &&
18860 + (pollfds[i].fd != (*prev)->fd)){
18861 + printk("free_irq_by_cb - mismatch between "
18862 + "active_fds and pollfds, fd %d vs %d\n",
18863 + (*prev)->fd, pollfds[i].fd);
18866 + memcpy(&pollfds[i], &pollfds[i + 1],
18867 + (pollfds_num - i - 1) * sizeof(pollfds[0]));
18869 + if(last_irq_ptr == &old_fd->next)
18870 + last_irq_ptr = prev;
18871 + *prev = (*prev)->next;
18872 + if(old_fd->type == IRQ_WRITE)
18873 + ignore_sigio_fd(old_fd->fd);
18877 + prev = &(*prev)->next;
18881 + irq_unlock(flags);
18884 +struct irq_and_dev {
18889 +static int same_irq_and_dev(struct irq_fd *irq, void *d)
18891 + struct irq_and_dev *data = d;
18893 + return((irq->irq == data->irq) && (irq->id == data->dev));
18896 +void free_irq_by_irq_and_dev(int irq, void *dev)
18898 + struct irq_and_dev data = ((struct irq_and_dev) { .irq = irq,
18901 + free_irq_by_cb(same_irq_and_dev, &data);
18904 +static int same_fd(struct irq_fd *irq, void *fd)
18906 + return(irq->fd == *((int *) fd));
18909 +void free_irq_by_fd(int fd)
18911 + free_irq_by_cb(same_fd, &fd);
18914 +static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
18916 + struct irq_fd *irq;
18919 + for(irq=active_fds; irq != NULL; irq = irq->next){
18920 + if((irq->fd == fd) && (irq->irq == irqnum)) break;
18924 + printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
18927 + if((pollfds[i].fd != -1) && (pollfds[i].fd != fd)){
18928 + printk("find_irq_by_fd - mismatch between active_fds and "
18929 + "pollfds, fd %d vs %d, need %d\n", irq->fd,
18930 + pollfds[i].fd, fd);
18939 +void free_irq_later(int irq, void *dev_id)
18941 + struct irq_fd *irq_fd;
18942 + unsigned long flags;
18944 + flags = irq_lock();
18945 + for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
18946 + if((irq_fd->irq == irq) && (irq_fd->id == dev_id))
18949 + if(irq_fd == NULL){
18950 + printk("free_irq_later found no irq, irq = %d, "
18951 + "dev_id = 0x%p\n", irq, dev_id);
18954 + irq_fd->freed = 1;
18956 + irq_unlock(flags);
18959 +void reactivate_fd(int fd, int irqnum)
18961 + struct irq_fd *irq;
18962 + unsigned long flags;
18965 + flags = irq_lock();
18966 + irq = find_irq_by_fd(fd, irqnum, &i);
18968 + irq_unlock(flags);
18972 + pollfds[i].fd = irq->fd;
18974 + irq_unlock(flags);
18976 + /* This calls activate_fd, so it has to be outside the critical
18979 + maybe_sigio_broken(fd, irq->type);
18982 +void deactivate_fd(int fd, int irqnum)
18984 + struct irq_fd *irq;
18985 + unsigned long flags;
18988 + flags = irq_lock();
18989 + irq = find_irq_by_fd(fd, irqnum, &i);
18992 + pollfds[i].fd = -1;
18994 + irq_unlock(flags);
18997 +void forward_ipi(int fd, int pid)
18999 + if(fcntl(fd, F_SETOWN, pid) < 0){
19000 + int save_errno = errno;
19001 + if(fcntl(fd, F_GETOWN, 0) != pid){
19002 + printk("forward_ipi: F_SETOWN failed, fd = %d, "
19003 + "me = %d, target = %d, errno = %d\n", fd,
19004 + os_getpid(), pid, save_errno);
19009 +void forward_interrupts(int pid)
19011 + struct irq_fd *irq;
19012 + unsigned long flags;
19014 + flags = irq_lock();
19015 + for(irq=active_fds;irq != NULL;irq = irq->next){
19016 + if(fcntl(irq->fd, F_SETOWN, pid) < 0){
19017 + int save_errno = errno;
19018 + if(fcntl(irq->fd, F_GETOWN, 0) != pid){
19019 + /* XXX Just remove the irq rather than
19020 + * print out an infinite stream of these
19022 + printk("Failed to forward %d to pid %d, "
19023 + "errno = %d\n", irq->fd, pid,
19029 + irq_unlock(flags);
19032 +void init_irq_signals(int on_sigstack)
19034 + __sighandler_t h;
19037 + flags = on_sigstack ? SA_ONSTACK : 0;
19038 + if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
19039 + else h = boot_timer_handler;
19041 + set_handler(SIGVTALRM, h, flags | SA_RESTART,
19042 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
19043 + set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
19044 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
19045 + signal(SIGWINCH, SIG_IGN);
19049 + * Overrides for Emacs so that we follow Linus's tabbing style.
19050 + * Emacs will notice this stuff at the end of the file and automatically
19051 + * adjust the settings for this buffer only. This must remain at the end
19053 + * ---------------------------------------------------------------------------
19054 + * Local variables:
19055 + * c-file-style: "linux"
19058 diff -Naur -X ../exclude-files orig/arch/um/kernel/ksyms.c um/arch/um/kernel/ksyms.c
19059 --- orig/arch/um/kernel/ksyms.c 1969-12-31 19:00:00.000000000 -0500
19060 +++ um/arch/um/kernel/ksyms.c 2002-12-17 13:29:43.000000000 -0500
19063 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
19064 + * Licensed under the GPL
19067 +#include "linux/config.h"
19068 +#include "linux/module.h"
19069 +#include "linux/string.h"
19070 +#include "linux/smp_lock.h"
19071 +#include "linux/spinlock.h"
19072 +#include "asm/current.h"
19073 +#include "asm/delay.h"
19074 +#include "asm/processor.h"
19075 +#include "asm/unistd.h"
19076 +#include "asm/pgalloc.h"
19077 +#include "asm/pgtable.h"
19078 +#include "asm/page.h"
19079 +#include "kern_util.h"
19080 +#include "user_util.h"
19082 +#include "helper.h"
19084 +EXPORT_SYMBOL(stop);
19085 +EXPORT_SYMBOL(strtok);
19086 +EXPORT_SYMBOL(uml_physmem);
19087 +EXPORT_SYMBOL(set_signals);
19088 +EXPORT_SYMBOL(get_signals);
19089 +EXPORT_SYMBOL(kernel_thread);
19090 +EXPORT_SYMBOL(__const_udelay);
19091 +EXPORT_SYMBOL(__udelay);
19092 +EXPORT_SYMBOL(sys_waitpid);
19093 +EXPORT_SYMBOL(task_size);
19094 +EXPORT_SYMBOL(flush_tlb_range);
19095 +EXPORT_SYMBOL(host_task_size);
19096 +EXPORT_SYMBOL(arch_validate);
19098 +EXPORT_SYMBOL(region_pa);
19099 +EXPORT_SYMBOL(region_va);
19100 +EXPORT_SYMBOL(phys_mem_map);
19101 +EXPORT_SYMBOL(page_mem_map);
19102 +EXPORT_SYMBOL(high_physmem);
19103 +EXPORT_SYMBOL(empty_zero_page);
19104 +EXPORT_SYMBOL(um_virt_to_phys);
19105 +EXPORT_SYMBOL(mode_tt);
19106 +EXPORT_SYMBOL(handle_page_fault);
19108 +EXPORT_SYMBOL(os_getpid);
19109 +EXPORT_SYMBOL(os_open_file);
19110 +EXPORT_SYMBOL(os_read_file);
19111 +EXPORT_SYMBOL(os_write_file);
19112 +EXPORT_SYMBOL(os_seek_file);
19113 +EXPORT_SYMBOL(os_pipe);
19114 +EXPORT_SYMBOL(os_file_type);
19115 +EXPORT_SYMBOL(os_close_file);
19116 +EXPORT_SYMBOL(helper_wait);
19117 +EXPORT_SYMBOL(os_shutdown_socket);
19118 +EXPORT_SYMBOL(os_connect_socket);
19119 +EXPORT_SYMBOL(run_helper);
19120 +EXPORT_SYMBOL(start_thread);
19121 +EXPORT_SYMBOL(dump_thread);
19123 +/* This is here because UML expands open to sys_open, not to a system
19124 + * call instruction.
19126 +EXPORT_SYMBOL(sys_open);
19127 +EXPORT_SYMBOL(sys_lseek);
19128 +EXPORT_SYMBOL(sys_read);
19129 +EXPORT_SYMBOL(sys_wait4);
19133 +/* required for SMP */
19135 +extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
19136 +EXPORT_SYMBOL_NOVERS(__write_lock_failed);
19138 +extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
19139 +EXPORT_SYMBOL_NOVERS(__read_lock_failed);
19141 +EXPORT_SYMBOL(kernel_flag_cacheline);
19142 +EXPORT_SYMBOL(smp_num_cpus);
19147 + * Overrides for Emacs so that we follow Linus's tabbing style.
19148 + * Emacs will notice this stuff at the end of the file and automatically
19149 + * adjust the settings for this buffer only. This must remain at the end
19151 + * ---------------------------------------------------------------------------
19152 + * Local variables:
19153 + * c-file-style: "linux"
19156 diff -Naur -X ../exclude-files orig/arch/um/kernel/Makefile um/arch/um/kernel/Makefile
19157 --- orig/arch/um/kernel/Makefile 1969-12-31 19:00:00.000000000 -0500
19158 +++ um/arch/um/kernel/Makefile 2003-04-10 11:14:55.000000000 -0400
19161 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
19162 +# Licensed under the GPL
19165 +O_TARGET = built-in.o
19167 +obj-y = config.o checksum.o exec_kern.o exitcode.o frame_kern.o frame.o \
19168 + helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \
19169 + process.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \
19170 + sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o \
19171 + syscall_user.o sysrq.o sys_call_table.o tempfile.o time.o \
19172 + time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
19173 + umid.o user_syms.o user_util.o
19175 +obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
19176 +obj-$(CONFIG_GPROF) += gprof_syms.o
19177 +obj-$(CONFIG_GCOV) += gmon_syms.o
19178 +obj-$(CONFIG_TTY_LOG) += tty_log.o
19180 +subdir-$(CONFIG_MODE_TT) += tt
19181 +subdir-$(CONFIG_MODE_SKAS) += skas
19183 +user-objs-$(CONFIG_TTY_LOG) += tty_log.o
19185 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
19187 +# user_syms.o not included here because Rules.make has its own ideas about
19188 +# building anything in export-objs
19190 +USER_OBJS = $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
19191 + process.o tempfile.o time.o umid.o user_util.o
19193 +DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__
19194 +DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__
19196 +export-objs-$(CONFIG_GPROF) += gprof_syms.o
19197 +export-objs-$(CONFIG_GCOV) += gmon_syms.o
19199 +export-objs = ksyms.o process_kern.o signal_kern.o user_syms.o $(export-objs-y)
19201 +CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \
19202 + -I/usr/include -I../include
19204 +CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
19206 +include $(TOPDIR)/Rules.make
19208 +$(USER_OBJS) : %.o: %.c
19209 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
19211 +# This has to be separate because it needs be compiled with frame pointers
19212 +# regardless of how the rest of the kernel is built.
19215 + $(CC) $(CFLAGS_$@) -c -o $@ $<
19217 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
19219 +config.c : config.c.in $(TOPDIR)/.config
19220 + $(PERL) -e $(QUOTE) < config.c.in > $@
19224 + for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
19232 +archmrproper: clean
19233 diff -Naur -X ../exclude-files orig/arch/um/kernel/mem.c um/arch/um/kernel/mem.c
19234 --- orig/arch/um/kernel/mem.c 1969-12-31 19:00:00.000000000 -0500
19235 +++ um/arch/um/kernel/mem.c 2003-03-30 14:30:26.000000000 -0500
19238 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
19239 + * Licensed under the GPL
19242 +#include "linux/config.h"
19243 +#include "linux/types.h"
19244 +#include "linux/mm.h"
19245 +#include "linux/fs.h"
19246 +#include "linux/init.h"
19247 +#include "linux/bootmem.h"
19248 +#include "linux/swap.h"
19249 +#include "linux/slab.h"
19250 +#include "linux/vmalloc.h"
19251 +#include "linux/highmem.h"
19252 +#include "asm/page.h"
19253 +#include "asm/pgtable.h"
19254 +#include "asm/pgalloc.h"
19255 +#include "asm/bitops.h"
19256 +#include "asm/uaccess.h"
19257 +#include "asm/tlb.h"
19258 +#include "user_util.h"
19259 +#include "kern_util.h"
19260 +#include "mem_user.h"
19265 +#include "mode_kern.h"
19266 +#include "uml_uaccess.h"
19268 +/* Changed during early boot */
19269 +pgd_t swapper_pg_dir[1024];
19270 +unsigned long high_physmem;
19271 +unsigned long vm_start;
19272 +unsigned long vm_end;
19273 +unsigned long highmem;
19274 +unsigned long *empty_zero_page = NULL;
19275 +unsigned long *empty_bad_page = NULL;
19277 +/* Not modified */
19278 +const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
19280 +/* Changed during early boot */
19281 +static unsigned long totalram_pages = 0;
19283 +extern char __init_begin, __init_end;
19284 +extern long physmem_size;
19287 +/* Not changed by UML */
19288 +mmu_gather_t mmu_gathers[NR_CPUS];
19291 +/* Changed during early boot */
19292 +int kmalloc_ok = 0;
19294 +#define NREGIONS (phys_region_index(0xffffffff) - phys_region_index(0x0) + 1)
19295 +struct mem_region *regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] = NULL };
19296 +#define REGION_SIZE ((0xffffffff & ~REGION_MASK) + 1)
19298 +/* Changed during early boot */
19299 +static unsigned long brk_end;
19301 +static void map_cb(void *unused)
19303 + map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
19306 +void unmap_physmem(void)
19308 + os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
19311 +extern char __binary_start;
19313 +void mem_init(void)
19315 + unsigned long start;
19317 +#ifdef CONFIG_HIGHMEM
19318 + highmem_start_page = phys_page(__pa(high_physmem));
19321 + /* clear the zero-page */
19322 + memset((void *) empty_zero_page, 0, PAGE_SIZE);
19324 + /* Map in the area just after the brk now that kmalloc is about
19325 + * to be turned on.
19327 + brk_end = (unsigned long) UML_ROUND_UP(sbrk(0));
19329 + initial_thread_cb(map_cb, NULL);
19330 + free_bootmem(__pa(brk_end), uml_reserved - brk_end);
19331 + uml_reserved = brk_end;
19333 + /* Fill in any hole at the start of the binary */
19334 + start = (unsigned long) &__binary_start;
19335 + if(uml_physmem != start){
19336 + map_memory(uml_physmem, __pa(uml_physmem), start - uml_physmem,
19340 + /* this will put all low memory onto the freelists */
19341 + totalram_pages = free_all_bootmem();
19342 + totalram_pages += highmem >> PAGE_SHIFT;
19343 + max_mapnr = totalram_pages;
19344 + num_physpages = totalram_pages;
19345 + printk(KERN_INFO "Memory: %luk available\n",
19346 + (unsigned long) nr_free_pages() << (PAGE_SHIFT-10));
19350 +/* Changed during early boot */
19351 +static unsigned long kmem_top = 0;
19353 +unsigned long get_kmem_end(void)
19355 + if(kmem_top == 0)
19356 + kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
19357 + return(kmem_top);
19360 +void set_kmem_end(unsigned long new)
19365 +#if CONFIG_HIGHMEM
19366 +/* Changed during early boot */
19368 +pgprot_t kmap_prot;
19370 +#define kmap_get_fixmap_pte(vaddr) \
19371 + pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
19373 +void __init kmap_init(void)
19375 + unsigned long kmap_vstart;
19377 + /* cache the first kmap pte */
19378 + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
19379 + kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
19381 + kmap_prot = PAGE_KERNEL;
19383 +#endif /* CONFIG_HIGHMEM */
19385 +static void __init fixrange_init(unsigned long start, unsigned long end,
19392 + unsigned long vaddr;
19395 + i = __pgd_offset(vaddr);
19396 + j = __pmd_offset(vaddr);
19397 + pgd = pgd_base + i;
19399 + for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
19400 + pmd = (pmd_t *)pgd;
19401 + for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
19402 + if (pmd_none(*pmd)) {
19403 + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
19404 + set_pmd(pmd, __pmd(_KERNPG_TABLE +
19405 + (unsigned long) __pa(pte)));
19406 + if (pte != pte_offset(pmd, 0))
19409 + vaddr += PMD_SIZE;
19415 +int init_maps(struct mem_region *region)
19417 + struct page *p, *map;
19420 + if(region == &physmem_region){
19421 + region->mem_map = mem_map;
19424 + else if(region->mem_map != NULL) return(0);
19426 + n = region->len >> PAGE_SHIFT;
19427 + len = n * sizeof(struct page);
19429 + map = kmalloc(len, GFP_KERNEL);
19430 + if(map == NULL) map = vmalloc(len);
19432 + else map = alloc_bootmem_low_pages(len);
19436 + for(i = 0; i < n; i++){
19438 + set_page_count(p, 0);
19439 + SetPageReserved(p);
19440 + INIT_LIST_HEAD(&p->list);
19442 + region->mem_map = map;
19446 +DECLARE_MUTEX(regions_sem);
19448 +static int setup_one_range(int fd, char *driver, unsigned long start,
19449 + unsigned long pfn, int len,
19450 + struct mem_region *region)
19454 + down(®ions_sem);
19455 + for(i = 0; i < NREGIONS; i++){
19456 + if(regions[i] == NULL) break;
19458 + if(i == NREGIONS){
19459 + printk("setup_one_range : no free regions\n");
19465 + fd = create_mem_file(len);
19467 + if(region == NULL){
19469 + region = kmalloc(sizeof(*region), GFP_KERNEL);
19470 + else region = alloc_bootmem_low_pages(sizeof(*region));
19471 + if(region == NULL)
19472 + panic("Failed to allocating mem_region");
19475 + *region = ((struct mem_region) { .driver = driver,
19476 + .start_pfn = pfn,
19480 + regions[i] = region;
19482 + up(®ions_sem);
19486 +#ifdef CONFIG_HIGHMEM
19487 +static void init_highmem(void)
19492 + unsigned long vaddr;
19495 + * Permanent kmaps:
19497 + vaddr = PKMAP_BASE;
19498 + fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, swapper_pg_dir);
19500 + pgd = swapper_pg_dir + __pgd_offset(vaddr);
19501 + pmd = pmd_offset(pgd, vaddr);
19502 + pte = pte_offset(pmd, vaddr);
19503 + pkmap_page_table = pte;
19508 +void setup_highmem(unsigned long len)
19510 + struct mem_region *region;
19511 + struct page *page, *map;
19512 + unsigned long phys;
19513 + int i, cur, index;
19515 + phys = physmem_size;
19517 + cur = min(len, (unsigned long) REGION_SIZE);
19518 + i = setup_one_range(-1, NULL, -1, phys >> PAGE_SHIFT, cur,
19521 + printk("setup_highmem - setup_one_range failed\n");
19524 + region = regions[i];
19525 + index = phys / PAGE_SIZE;
19526 + region->mem_map = &mem_map[index];
19528 + map = region->mem_map;
19529 + for(i = 0; i < (cur >> PAGE_SHIFT); i++){
19531 + ClearPageReserved(page);
19532 + set_bit(PG_highmem, &page->flags);
19533 + atomic_set(&page->count, 1);
19534 + __free_page(page);
19538 + } while(len > 0);
19542 +void paging_init(void)
19544 + struct mem_region *region;
19545 + unsigned long zones_size[MAX_NR_ZONES], start, end, vaddr;
19548 + empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
19549 + empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
19550 + for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++)
19551 + zones_size[i] = 0;
19552 + zones_size[0] = (high_physmem >> PAGE_SHIFT) -
19553 + (uml_physmem >> PAGE_SHIFT);
19554 + zones_size[2] = highmem >> PAGE_SHIFT;
19555 + free_area_init(zones_size);
19556 + start = phys_region_index(__pa(uml_physmem));
19557 + end = phys_region_index(__pa(high_physmem - 1));
19558 + for(i = start; i <= end; i++){
19559 + region = regions[i];
19560 + index = (region->start - uml_physmem) / PAGE_SIZE;
19561 + region->mem_map = &mem_map[index];
19562 + if(i > start) free_bootmem(__pa(region->start), region->len);
19566 + * Fixed mappings, only the page table structure has to be
19567 + * created - mappings will be set by set_fixmap():
19569 + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
19570 + fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir);
19572 +#if CONFIG_HIGHMEM
19574 + setup_highmem(highmem);
19578 +/* Changed by meminfo_compat, which is a setup */
19579 +static int meminfo_22 = 0;
19581 +static int meminfo_compat(char *str)
19587 +__setup("22_meminfo", meminfo_compat);
19589 +void si_meminfo(struct sysinfo *val)
19591 + val->totalram = totalram_pages;
19592 + val->sharedram = 0;
19593 + val->freeram = nr_free_pages();
19594 + val->bufferram = atomic_read(&buffermem_pages);
19595 + val->totalhigh = highmem >> PAGE_SHIFT;
19596 + val->freehigh = nr_free_highpages();
19597 + val->mem_unit = PAGE_SIZE;
19599 + val->freeram <<= PAGE_SHIFT;
19600 + val->bufferram <<= PAGE_SHIFT;
19601 + val->totalram <<= PAGE_SHIFT;
19602 + val->sharedram <<= PAGE_SHIFT;
19606 +pte_t __bad_page(void)
19608 + clear_page(empty_bad_page);
19609 + return pte_mkdirty(mk_pte((struct page *) empty_bad_page,
19613 +/* This can't do anything because nothing in the kernel image can be freed
19614 + * since it's not in kernel physical memory.
19617 +void free_initmem(void)
19621 +#ifdef CONFIG_BLK_DEV_INITRD
19623 +void free_initrd_mem(unsigned long start, unsigned long end)
19626 + printk ("Freeing initrd memory: %ldk freed\n",
19627 + (end - start) >> 10);
19628 + for (; start < end; start += PAGE_SIZE) {
19629 + ClearPageReserved(virt_to_page(start));
19630 + set_page_count(virt_to_page(start), 1);
19631 + free_page(start);
19632 + totalram_pages++;
19638 +int do_check_pgt_cache(int low, int high)
19641 + if(pgtable_cache_size > high) {
19643 + if (pgd_quicklist) {
19644 + free_pgd_slow(get_pgd_fast());
19647 + if (pmd_quicklist) {
19648 + pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
19651 + if (pte_quicklist) {
19652 + pte_free_slow(pte_alloc_one_fast(NULL, 0));
19655 + } while(pgtable_cache_size > low);
19660 +void show_mem(void)
19662 + int i, total = 0, reserved = 0;
19663 + int shared = 0, cached = 0;
19666 + printk("Mem-info:\n");
19667 + show_free_areas();
19668 + printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
19672 + if(PageHighMem(mem_map + i))
19674 + if(PageReserved(mem_map + i))
19676 + else if(PageSwapCache(mem_map + i))
19678 + else if(page_count(mem_map + i))
19679 + shared += page_count(mem_map + i) - 1;
19681 + printk("%d pages of RAM\n", total);
19682 + printk("%d pages of HIGHMEM\n", highmem);
19683 + printk("%d reserved pages\n", reserved);
19684 + printk("%d pages shared\n", shared);
19685 + printk("%d pages swap cached\n", cached);
19686 + printk("%ld pages in page table cache\n", pgtable_cache_size);
19690 +static int __init uml_mem_setup(char *line, int *add)
19693 + physmem_size = memparse(line,&retptr);
19696 +__uml_setup("mem=", uml_mem_setup,
19697 +"mem=<Amount of desired ram>\n"
19698 +" This controls how much \"physical\" memory the kernel allocates\n"
19699 +" for the system. The size is specified as a number followed by\n"
19700 +" one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
19701 +" This is not related to the amount of memory in the physical\n"
19702 +" machine. It can be more, and the excess, if it's ever used, will\n"
19703 +" just be swapped out.\n Example: mem=64M\n\n"
19706 +struct page *arch_validate(struct page *page, int mask, int order)
19708 + unsigned long addr, zero = 0;
19712 + if(page == NULL) return(page);
19713 + if(PageHighMem(page)) return(page);
19715 + addr = (unsigned long) page_address(page);
19716 + for(i = 0; i < (1 << order); i++){
19717 + current->thread.fault_addr = (void *) addr;
19718 + if(__do_copy_to_user((void *) addr, &zero,
19720 + ¤t->thread.fault_addr,
19721 + ¤t->thread.fault_catcher)){
19722 + if(!(mask & __GFP_WAIT)) return(NULL);
19725 + addr += PAGE_SIZE;
19727 + if(i == (1 << order)) return(page);
19728 + page = _alloc_pages(mask, order);
19732 +DECLARE_MUTEX(vm_reserved_sem);
19733 +static struct list_head vm_reserved = LIST_HEAD_INIT(vm_reserved);
19735 +/* Static structures, linked in to the list in early boot */
19736 +static struct vm_reserved head = {
19737 + .list = LIST_HEAD_INIT(head.list),
19739 + .end = 0xffffffff
19742 +static struct vm_reserved tail = {
19743 + .list = LIST_HEAD_INIT(tail.list),
19745 + .end = 0xffffffff
19748 +void set_usable_vm(unsigned long start, unsigned long end)
19750 + list_add(&head.list, &vm_reserved);
19751 + list_add(&tail.list, &head.list);
19752 + head.end = start;
19753 + tail.start = end;
19756 +int reserve_vm(unsigned long start, unsigned long end, void *e)
19759 + struct vm_reserved *entry = e, *reserved, *prev;
19760 + struct list_head *ele;
19763 + down(&vm_reserved_sem);
19764 + list_for_each(ele, &vm_reserved){
19765 + reserved = list_entry(ele, struct vm_reserved, list);
19766 + if(reserved->start >= end) goto found;
19768 + panic("Reserved vm out of range");
19770 + prev = list_entry(ele->prev, struct vm_reserved, list);
19771 + if(prev->end > start)
19772 + panic("Can't reserve vm");
19773 + if(entry == NULL)
19774 + entry = kmalloc(sizeof(*entry), GFP_KERNEL);
19775 + if(entry == NULL){
19776 + printk("reserve_vm : Failed to allocate entry\n");
19780 + *entry = ((struct vm_reserved)
19781 + { .list = LIST_HEAD_INIT(entry->list),
19784 + list_add(&entry->list, &prev->list);
19787 + up(&vm_reserved_sem);
19791 +unsigned long get_vm(unsigned long len)
19793 + struct vm_reserved *this, *next;
19794 + struct list_head *ele;
19795 + unsigned long start;
19798 + down(&vm_reserved_sem);
19799 + list_for_each(ele, &vm_reserved){
19800 + this = list_entry(ele, struct vm_reserved, list);
19801 + next = list_entry(ele->next, struct vm_reserved, list);
19802 + if((this->start < next->start) &&
19803 + (this->end + len + PAGE_SIZE <= next->start))
19806 + up(&vm_reserved_sem);
19809 + up(&vm_reserved_sem);
19810 + start = (unsigned long) UML_ROUND_UP(this->end) + PAGE_SIZE;
19811 + err = reserve_vm(start, start + len, NULL);
19812 + if(err) return(0);
19816 +int nregions(void)
19818 + return(NREGIONS);
19821 +void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn,
19822 + unsigned long len, int need_vm, struct mem_region *region,
19828 + cur = min(len, (unsigned long) REGION_SIZE);
19829 + i = setup_one_range(fd, driver, start, pfn, cur, region);
19830 + region = regions[i];
19831 + if(need_vm && setup_region(region, reserved)){
19833 + regions[i] = NULL;
19837 + if(pfn != -1) pfn += cur;
19839 + } while(len > 0);
19845 + unsigned long size;
19848 +/* iomem regions can only be added on the command line at the moment.
19849 + * Locking will be needed when they can be added via mconsole.
19852 +struct iomem iomem_regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] =
19857 +int num_iomem_regions = 0;
19859 +void add_iomem(char *name, int fd, unsigned long size)
19861 + if(num_iomem_regions == sizeof(iomem_regions)/sizeof(iomem_regions[0]))
19863 + size = (size + PAGE_SIZE - 1) & PAGE_MASK;
19864 + iomem_regions[num_iomem_regions++] =
19865 + ((struct iomem) { .name = name,
19867 + .size = size } );
19870 +int setup_iomem(void)
19872 + struct iomem *iomem;
19875 + for(i = 0; i < num_iomem_regions; i++){
19876 + iomem = &iomem_regions[i];
19877 + setup_range(iomem->fd, iomem->name, -1, -1, iomem->size, 1,
19883 +__initcall(setup_iomem);
19885 +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
19886 +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
19888 +/* Changed during early boot */
19889 +static struct mem_region physmem_region;
19890 +static struct vm_reserved physmem_reserved;
19892 +void setup_physmem(unsigned long start, unsigned long reserve_end,
19893 + unsigned long len)
19895 + struct mem_region *region = &physmem_region;
19896 + struct vm_reserved *reserved = &physmem_reserved;
19897 + unsigned long cur, pfn = 0;
19898 + int do_free = 1, bootmap_size;
19901 + cur = min(len, (unsigned long) REGION_SIZE);
19902 + if(region == NULL)
19903 + region = alloc_bootmem_low_pages(sizeof(*region));
19904 + if(reserved == NULL)
19905 + reserved = alloc_bootmem_low_pages(sizeof(*reserved));
19906 + if((region == NULL) || (reserved == NULL))
19907 + panic("Couldn't allocate physmem region or vm "
19908 + "reservation\n");
19909 + setup_range(-1, NULL, start, pfn, cur, 1, region, reserved);
19912 + unsigned long reserve = reserve_end - start;
19913 + int pfn = PFN_UP(__pa(reserve_end));
19914 + int delta = (len - reserve) >> PAGE_SHIFT;
19916 + bootmap_size = init_bootmem(pfn, pfn + delta);
19917 + free_bootmem(__pa(reserve_end) + bootmap_size,
19918 + cur - bootmap_size - reserve);
19922 + pfn += cur >> PAGE_SHIFT;
19926 + } while(len > 0);
19929 +struct mem_region *phys_region(unsigned long phys)
19931 + unsigned int n = phys_region_index(phys);
19933 + if(regions[n] == NULL)
19934 + panic("Physical address in uninitialized region");
19935 + return(regions[n]);
19938 +unsigned long phys_offset(unsigned long phys)
19940 + return(phys_addr(phys));
19943 +struct page *phys_mem_map(unsigned long phys)
19945 + return((struct page *) phys_region(phys)->mem_map);
19948 +struct page *pte_mem_map(pte_t pte)
19950 + return(phys_mem_map(pte_val(pte)));
19953 +struct mem_region *page_region(struct page *page, int *index_out)
19956 + struct mem_region *region;
19957 + struct page *map;
19959 + for(i = 0; i < NREGIONS; i++){
19960 + region = regions[i];
19961 + if(region == NULL) continue;
19962 + map = region->mem_map;
19963 + if((page >= map) && (page < &map[region->len >> PAGE_SHIFT])){
19964 + if(index_out != NULL) *index_out = i;
19968 + panic("No region found for page");
19972 +unsigned long page_to_pfn(struct page *page)
19974 + struct mem_region *region = page_region(page, NULL);
19976 + return(region->start_pfn + (page - (struct page *) region->mem_map));
19979 +struct mem_region *pfn_to_region(unsigned long pfn, int *index_out)
19981 + struct mem_region *region;
19984 + for(i = 0; i < NREGIONS; i++){
19985 + region = regions[i];
19986 + if(region == NULL)
19989 + if((region->start_pfn <= pfn) &&
19990 + (region->start_pfn + (region->len >> PAGE_SHIFT) > pfn)){
19991 + if(index_out != NULL)
19999 +struct page *pfn_to_page(unsigned long pfn)
20001 + struct mem_region *region = pfn_to_region(pfn, NULL);
20002 + struct page *mem_map = (struct page *) region->mem_map;
20004 + return(&mem_map[pfn - region->start_pfn]);
20007 +unsigned long phys_to_pfn(unsigned long p)
20009 + struct mem_region *region = regions[phys_region_index(p)];
20011 + return(region->start_pfn + (phys_addr(p) >> PAGE_SHIFT));
20014 +unsigned long pfn_to_phys(unsigned long pfn)
20017 + struct mem_region *region = pfn_to_region(pfn, &n);
20019 + return(mk_phys((pfn - region->start_pfn) << PAGE_SHIFT, n));
20022 +struct page *page_mem_map(struct page *page)
20024 + return((struct page *) page_region(page, NULL)->mem_map);
20027 +extern unsigned long region_pa(void *virt)
20029 + struct mem_region *region;
20030 + unsigned long addr = (unsigned long) virt;
20033 + for(i = 0; i < NREGIONS; i++){
20034 + region = regions[i];
20035 + if(region == NULL) continue;
20036 + if((region->start <= addr) &&
20037 + (addr <= region->start + region->len))
20038 + return(mk_phys(addr - region->start, i));
20040 + panic("region_pa : no region for virtual address");
20044 +extern void *region_va(unsigned long phys)
20046 + return((void *) (phys_region(phys)->start + phys_addr(phys)));
20049 +unsigned long page_to_phys(struct page *page)
20052 + struct mem_region *region = page_region(page, &n);
20053 + struct page *map = region->mem_map;
20054 + return(mk_phys((page - map) << PAGE_SHIFT, n));
20057 +struct page *phys_to_page(unsigned long phys)
20059 + struct page *mem_map;
20061 + mem_map = phys_mem_map(phys);
20062 + return(mem_map + (phys_offset(phys) >> PAGE_SHIFT));
20065 +static int setup_mem_maps(void)
20067 + struct mem_region *region;
20070 + for(i = 0; i < NREGIONS; i++){
20071 + region = regions[i];
20072 + if((region != NULL) && (region->fd > 0)) init_maps(region);
20077 +__initcall(setup_mem_maps);
20080 + * Overrides for Emacs so that we follow Linus's tabbing style.
20081 + * Emacs will notice this stuff at the end of the file and automatically
20082 + * adjust the settings for this buffer only. This must remain at the end
20084 + * ---------------------------------------------------------------------------
20085 + * Local variables:
20086 + * c-file-style: "linux"
20089 diff -Naur -X ../exclude-files orig/arch/um/kernel/mem_user.c um/arch/um/kernel/mem_user.c
20090 --- orig/arch/um/kernel/mem_user.c 1969-12-31 19:00:00.000000000 -0500
20091 +++ um/arch/um/kernel/mem_user.c 2003-03-06 16:05:21.000000000 -0500
20094 + * arch/um/kernel/mem_user.c
20096 + * BRIEF MODULE DESCRIPTION
20097 + * user side memory routines for supporting IO memory inside user mode linux
20099 + * Copyright (C) 2001 RidgeRun, Inc.
20100 + * Author: RidgeRun, Inc.
20101 + * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
20103 + * This program is free software; you can redistribute it and/or modify it
20104 + * under the terms of the GNU General Public License as published by the
20105 + * Free Software Foundation; either version 2 of the License, or (at your
20106 + * option) any later version.
20108 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
20109 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20110 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20111 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20112 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20113 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
20114 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20115 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20116 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20117 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20119 + * You should have received a copy of the GNU General Public License along
20120 + * with this program; if not, write to the Free Software Foundation, Inc.,
20121 + * 675 Mass Ave, Cambridge, MA 02139, USA.
20124 +#include <stdio.h>
20125 +#include <stdlib.h>
20126 +#include <stddef.h>
20127 +#include <stdarg.h>
20128 +#include <unistd.h>
20129 +#include <fcntl.h>
20130 +#include <errno.h>
20131 +#include <string.h>
20132 +#include <sys/stat.h>
20133 +#include <sys/types.h>
20134 +#include <sys/mman.h>
20135 +#include "kern_util.h"
20137 +#include "user_util.h"
20138 +#include "mem_user.h"
20141 +#include "tempfile.h"
20143 +extern struct mem_region physmem_region;
20145 +#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
20147 +int create_mem_file(unsigned long len)
20152 + fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
20153 + if (fchmod(fd, 0777) < 0){
20154 + perror("fchmod");
20157 + if(os_seek_file(fd, len) < 0){
20162 + if(write(fd, &zero, 1) != 1){
20166 + if(fcntl(fd, F_SETFD, 1) != 0)
20167 + perror("Setting FD_CLOEXEC failed");
20171 +int setup_region(struct mem_region *region, void *entry)
20173 + void *loc, *start;
20177 + if(region->start != -1){
20178 + err = reserve_vm(region->start,
20179 + region->start + region->len, entry);
20181 + printk("setup_region : failed to reserve "
20182 + "0x%x - 0x%x for driver '%s'\n",
20184 + region->start + region->len,
20189 + else region->start = get_vm(region->len);
20190 + if(region->start == 0){
20191 + if(region->driver == NULL) driver = "physmem";
20192 + else driver = region->driver;
20193 + printk("setup_region : failed to find vm for "
20194 + "driver '%s' (length %d)\n", driver, region->len);
20197 + if(region->start == uml_physmem){
20198 + start = (void *) uml_reserved;
20199 + offset = uml_reserved - uml_physmem;
20202 + start = (void *) region->start;
20206 + loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE,
20207 + MAP_SHARED | MAP_FIXED, region->fd, offset);
20208 + if(loc != start){
20209 + perror("Mapping memory");
20215 +static int __init parse_iomem(char *str, int *add)
20217 + struct stat64 buf;
20218 + char *file, *driver;
20222 + file = strchr(str,',');
20223 + if(file == NULL){
20224 + printf("parse_iomem : failed to parse iomem\n");
20229 + fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
20231 + printf("parse_iomem - Couldn't open io file, errno = %d\n",
20235 + if(fstat64(fd, &buf) < 0) {
20236 + printf("parse_iomem - cannot fstat file, errno = %d\n", errno);
20239 + add_iomem(driver, fd, buf.st_size);
20243 +__uml_setup("iomem=", parse_iomem,
20244 +"iomem=<name>,<file>\n"
20245 +" Configure <file> as an IO memory region named <name>.\n\n"
20250 +int logging_fd = -1;
20252 +int logging_line = 0;
20253 +char logging_buf[256];
20255 +void log(char *fmt, ...)
20258 + struct timeval tv;
20259 + struct openflags flags;
20261 + if(logging == 0) return;
20262 + if(logging_fd < 0){
20263 + flags = of_create(of_trunc(of_rdrw(OPENFLAGS())));
20264 + logging_fd = os_open_file("log", flags, 0644);
20266 + gettimeofday(&tv, NULL);
20267 + sprintf(logging_buf, "%d\t %u.%u ", logging_line++, tv.tv_sec,
20269 + va_start(ap, fmt);
20270 + vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
20272 + write(logging_fd, logging_buf, strlen(logging_buf));
20276 +int map_memory(unsigned long virt, unsigned long phys, unsigned long len,
20277 + int r, int w, int x)
20279 + struct mem_region *region = phys_region(phys);
20281 + return(os_map_memory((void *) virt, region->fd, phys_offset(phys), len,
20285 +int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
20286 + int must_succeed)
20288 + if(os_protect_memory((void *) addr, len, r, w, x) < 0){
20290 + panic("protect failed, errno = %d", errno);
20291 + else return(-errno);
20296 +unsigned long find_iomem(char *driver, unsigned long *len_out)
20298 + struct mem_region *region;
20302 + for(i = 0; i < n; i++){
20303 + region = regions[i];
20304 + if(region == NULL) continue;
20305 + if((region->driver != NULL) &&
20306 + !strcmp(region->driver, driver)){
20307 + *len_out = region->len;
20308 + return(region->start);
20316 + * Overrides for Emacs so that we follow Linus's tabbing style.
20317 + * Emacs will notice this stuff at the end of the file and automatically
20318 + * adjust the settings for this buffer only. This must remain at the end
20320 + * ---------------------------------------------------------------------------
20321 + * Local variables:
20322 + * c-file-style: "linux"
20325 diff -Naur -X ../exclude-files orig/arch/um/kernel/mprot.h um/arch/um/kernel/mprot.h
20326 --- orig/arch/um/kernel/mprot.h 1969-12-31 19:00:00.000000000 -0500
20327 +++ um/arch/um/kernel/mprot.h 2002-10-23 21:08:04.000000000 -0400
20329 +#ifndef __MPROT_H__
20330 +#define __MPROT_H__
20332 +extern void no_access(unsigned long addr, unsigned int len);
20335 diff -Naur -X ../exclude-files orig/arch/um/kernel/process.c um/arch/um/kernel/process.c
20336 --- orig/arch/um/kernel/process.c 1969-12-31 19:00:00.000000000 -0500
20337 +++ um/arch/um/kernel/process.c 2003-04-23 20:36:15.000000000 -0400
20340 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
20341 + * Licensed under the GPL
20344 +#include <stdio.h>
20345 +#include <unistd.h>
20346 +#include <signal.h>
20347 +#include <sched.h>
20348 +#include <errno.h>
20349 +#include <stdarg.h>
20350 +#include <fcntl.h>
20351 +#include <stdlib.h>
20352 +#include <setjmp.h>
20353 +#include <sys/time.h>
20354 +#include <sys/ptrace.h>
20355 +#include <sys/ioctl.h>
20356 +#include <sys/wait.h>
20357 +#include <sys/mman.h>
20358 +#include <asm/ptrace.h>
20359 +#include <asm/sigcontext.h>
20360 +#include <asm/unistd.h>
20361 +#include <asm/page.h>
20362 +#include "user_util.h"
20363 +#include "kern_util.h"
20365 +#include "process.h"
20366 +#include "signal_kern.h"
20367 +#include "signal_user.h"
20368 +#include "sysdep/ptrace.h"
20369 +#include "sysdep/sigcontext.h"
20370 +#include "irq_user.h"
20371 +#include "ptrace_user.h"
20372 +#include "time_user.h"
20375 +#include "uml-config.h"
20376 +#include "choose-mode.h"
20378 +#ifdef UML_CONFIG_MODE_SKAS
20380 +#include "skas_ptrace.h"
20383 +void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
20385 + int flags = 0, pages;
20387 + if(sig_stack != NULL){
20388 + pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
20389 + set_sigstack(sig_stack, pages * page_size());
20390 + flags = SA_ONSTACK;
20392 + if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
20395 +void init_new_thread_signals(int altstack)
20397 + int flags = altstack ? SA_ONSTACK : 0;
20399 + set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags,
20400 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20401 + set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags,
20402 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20403 + set_handler(SIGFPE, (__sighandler_t) sig_handler, flags,
20404 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20405 + set_handler(SIGILL, (__sighandler_t) sig_handler, flags,
20406 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20407 + set_handler(SIGBUS, (__sighandler_t) sig_handler, flags,
20408 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20409 + set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags,
20410 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20411 + set_handler(SIGUSR2, (__sighandler_t) sig_handler,
20412 + SA_NOMASK | flags, -1);
20413 + signal(SIGHUP, SIG_IGN);
20415 + init_irq_signals(altstack);
20419 + int (*tramp)(void *);
20420 + void *tramp_data;
20421 + unsigned long temp_stack;
20426 +/* See above for why sigkill is here */
20428 +int sigkill = SIGKILL;
20430 +int outer_tramp(void *arg)
20433 + int sig = sigkill;
20436 + t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2,
20437 + t->flags, t->tramp_data);
20438 + if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
20439 + kill(os_getpid(), sig);
20443 +int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
20444 + int clone_flags, int (*tramp)(void *))
20446 + struct tramp arg;
20447 + unsigned long sp;
20448 + int new_pid, status, err;
20450 + /* The trampoline will run on the temporary stack */
20451 + sp = stack_sp(temp_stack);
20453 + clone_flags |= CLONE_FILES | SIGCHLD;
20455 + arg.tramp = tramp;
20456 + arg.tramp_data = thread_arg;
20457 + arg.temp_stack = temp_stack;
20458 + arg.flags = clone_flags;
20460 + /* Start the process and wait for it to kill itself */
20461 + new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
20462 + if(new_pid < 0) return(-errno);
20463 + while((err = waitpid(new_pid, &status, 0) < 0) && (errno == EINTR)) ;
20464 + if(err < 0) panic("Waiting for outer trampoline failed - errno = %d",
20466 + if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
20467 + panic("outer trampoline didn't exit with SIGKILL");
20472 +void suspend_new_thread(int fd)
20476 + os_stop_process(os_getpid());
20478 + if(read(fd, &c, sizeof(c)) != sizeof(c))
20479 + panic("read failed in suspend_new_thread");
20482 +static int ptrace_child(void *arg)
20484 + int pid = os_getpid();
20486 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
20487 + perror("ptrace");
20488 + os_kill_process(pid, 0);
20490 + os_stop_process(pid);
20491 + _exit(os_getpid() == pid);
20494 +static int start_ptraced_child(void **stack_out)
20497 + unsigned long sp;
20498 + int pid, n, status;
20500 + stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
20501 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
20502 + if(stack == MAP_FAILED)
20503 + panic("check_ptrace : mmap failed, errno = %d", errno);
20504 + sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
20505 + pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
20507 + panic("check_ptrace : clone failed, errno = %d", errno);
20508 + n = waitpid(pid, &status, WUNTRACED);
20510 + panic("check_ptrace : wait failed, errno = %d", errno);
20511 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
20512 + panic("check_ptrace : expected SIGSTOP, got status = %d",
20515 + *stack_out = stack;
20519 +static void stop_ptraced_child(int pid, void *stack, int exitcode)
20523 + if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
20524 + panic("check_ptrace : ptrace failed, errno = %d", errno);
20525 + n = waitpid(pid, &status, 0);
20526 + if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode))
20527 + panic("check_ptrace : child exited with status 0x%x", status);
20529 + if(munmap(stack, PAGE_SIZE) < 0)
20530 + panic("check_ptrace : munmap failed, errno = %d", errno);
20533 +void __init check_ptrace(void)
20536 + int pid, syscall, n, status;
20538 + printk("Checking that ptrace can change system call numbers...");
20539 + pid = start_ptraced_child(&stack);
20542 + if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
20543 + panic("check_ptrace : ptrace failed, errno = %d",
20545 + n = waitpid(pid, &status, WUNTRACED);
20547 + panic("check_ptrace : wait failed, errno = %d", errno);
20548 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
20549 + panic("check_ptrace : expected SIGTRAP, "
20550 + "got status = %d", status);
20552 + syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET,
20554 + if(syscall == __NR_getpid){
20555 + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
20558 + panic("check_ptrace : failed to modify system "
20559 + "call, errno = %d", errno);
20563 + stop_ptraced_child(pid, stack, 0);
20567 +int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
20580 +int can_do_skas(void)
20582 +#ifdef UML_CONFIG_MODE_SKAS
20583 + struct ptrace_faultinfo fi;
20585 + int pid, n, ret = 1;
20587 + printf("Checking for the skas3 patch in the host...");
20588 + pid = start_ptraced_child(&stack);
20590 + n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
20593 + printf("not found\n");
20594 + else printf("No (unexpected errno - %d)\n", errno);
20597 + else printf("found\n");
20599 + init_registers(pid);
20600 + stop_ptraced_child(pid, stack, 1);
20602 + printf("Checking for /proc/mm...");
20603 + if(access("/proc/mm", W_OK)){
20604 + printf("not found\n");
20607 + else printf("found\n");
20616 + * Overrides for Emacs so that we follow Linus's tabbing style.
20617 + * Emacs will notice this stuff at the end of the file and automatically
20618 + * adjust the settings for this buffer only. This must remain at the end
20620 + * ---------------------------------------------------------------------------
20621 + * Local variables:
20622 + * c-file-style: "linux"
20625 diff -Naur -X ../exclude-files orig/arch/um/kernel/process_kern.c um/arch/um/kernel/process_kern.c
20626 --- orig/arch/um/kernel/process_kern.c 1969-12-31 19:00:00.000000000 -0500
20627 +++ um/arch/um/kernel/process_kern.c 2003-04-16 16:02:09.000000000 -0400
20630 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
20631 + * Licensed under the GPL
20634 +#include "linux/config.h"
20635 +#include "linux/kernel.h"
20636 +#include "linux/sched.h"
20637 +#include "linux/interrupt.h"
20638 +#include "linux/mm.h"
20639 +#include "linux/slab.h"
20640 +#include "linux/utsname.h"
20641 +#include "linux/fs.h"
20642 +#include "linux/utime.h"
20643 +#include "linux/smp_lock.h"
20644 +#include "linux/module.h"
20645 +#include "linux/init.h"
20646 +#include "linux/capability.h"
20647 +#include "asm/unistd.h"
20648 +#include "asm/mman.h"
20649 +#include "asm/segment.h"
20650 +#include "asm/stat.h"
20651 +#include "asm/pgtable.h"
20652 +#include "asm/processor.h"
20653 +#include "asm/pgalloc.h"
20654 +#include "asm/spinlock.h"
20655 +#include "asm/uaccess.h"
20656 +#include "asm/user.h"
20657 +#include "user_util.h"
20658 +#include "kern_util.h"
20660 +#include "signal_kern.h"
20661 +#include "signal_user.h"
20663 +#include "irq_user.h"
20664 +#include "mem_user.h"
20665 +#include "time_user.h"
20667 +#include "frame_kern.h"
20668 +#include "sigcontext.h"
20669 +#include "2_5compat.h"
20672 +#include "mode_kern.h"
20673 +#include "choose-mode.h"
20675 +/* This is a per-cpu array. A processor only modifies its entry and it only
20676 + * cares about its entry, so it's OK if another processor is modifying its
20679 +struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
20681 +struct task_struct *get_task(int pid, int require)
20683 + struct task_struct *ret;
20685 + read_lock(&tasklist_lock);
20686 + ret = find_task_by_pid(pid);
20687 + read_unlock(&tasklist_lock);
20689 + if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
20693 +int external_pid(void *t)
20695 + struct task_struct *task = t ? t : current;
20697 + return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
20700 +int pid_to_processor_id(int pid)
20704 + for(i = 0; i < smp_num_cpus; i++){
20705 + if(cpu_tasks[i].pid == pid) return(i);
20710 +void free_stack(unsigned long stack, int order)
20712 + free_pages(stack, order);
20715 +unsigned long alloc_stack(int order, int atomic)
20717 + unsigned long page;
20718 + int flags = GFP_KERNEL;
20720 + if(atomic) flags |= GFP_ATOMIC;
20721 + if((page = __get_free_pages(flags, order)) == 0)
20723 + stack_protections(page);
20727 +int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
20731 + current->thread.request.u.thread.proc = fn;
20732 + current->thread.request.u.thread.arg = arg;
20733 + pid = do_fork(CLONE_VM | flags, 0, NULL, 0);
20734 + if(pid < 0) panic("do_fork failed in kernel_thread");
20738 +void switch_mm(struct mm_struct *prev, struct mm_struct *next,
20739 + struct task_struct *tsk, unsigned cpu)
20741 + if (prev != next)
20742 + clear_bit(cpu, &prev->cpu_vm_mask);
20743 + set_bit(cpu, &next->cpu_vm_mask);
20746 +void set_current(void *t)
20748 + struct task_struct *task = t;
20750 + cpu_tasks[task->processor] = ((struct cpu_task)
20751 + { external_pid(task), task });
20754 +void *_switch_to(void *prev, void *next)
20756 + return(CHOOSE_MODE(_switch_to_tt(prev, next),
20757 + _switch_to_skas(prev, next)));
20760 +void interrupt_end(void)
20762 + if(current->need_resched) schedule();
20763 + if(current->sigpending != 0) do_signal(0);
20766 +void release_thread(struct task_struct *task)
20768 + CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
20771 +void exit_thread(void)
20773 + CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
20774 + unprotect_stack((unsigned long) current);
20777 +void *get_current(void)
20782 +int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
20783 + unsigned long stack_top, struct task_struct * p,
20784 + struct pt_regs *regs)
20786 + p->thread = (struct thread_struct) INIT_THREAD;
20787 + p->thread.kernel_stack = (unsigned long) p + 2 * PAGE_SIZE;
20789 + return(CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr,
20790 + clone_flags, sp, stack_top, p, regs));
20793 +void initial_thread_cb(void (*proc)(void *), void *arg)
20795 + int save_kmalloc_ok = kmalloc_ok;
20798 + CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc,
20800 + kmalloc_ok = save_kmalloc_ok;
20803 +unsigned long stack_sp(unsigned long page)
20805 + return(page + PAGE_SIZE - sizeof(void *));
20808 +int current_pid(void)
20810 + return(current->pid);
20813 +void cpu_idle(void)
20815 + CHOOSE_MODE(init_idle_tt(), init_idle_skas());
20817 + atomic_inc(&init_mm.mm_count);
20818 + current->mm = &init_mm;
20819 + current->active_mm = &init_mm;
20822 + /* endless idle loop with no priority at all */
20823 + SET_PRI(current);
20826 + * although we are an idle CPU, we do not want to
20827 + * get into the scheduler unnecessarily.
20829 + if (current->need_resched) {
20831 + check_pgt_cache();
20837 +int page_size(void)
20839 + return(PAGE_SIZE);
20842 +int page_mask(void)
20844 + return(PAGE_MASK);
20847 +void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
20854 + if(task->mm == NULL)
20855 + return(ERR_PTR(-EINVAL));
20856 + pgd = pgd_offset(task->mm, addr);
20857 + pmd = pmd_offset(pgd, addr);
20858 + if(!pmd_present(*pmd))
20859 + return(ERR_PTR(-EINVAL));
20860 + pte = pte_offset(pmd, addr);
20861 + if(!pte_present(*pte))
20862 + return(ERR_PTR(-EINVAL));
20863 + if(pte_out != NULL)
20865 + return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK));
20868 +char *current_cmd(void)
20870 +#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
20871 + return("(Unknown)");
20873 + void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
20874 + return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
20878 +void force_sigbus(void)
20880 + printk(KERN_ERR "Killing pid %d because of a lack of memory\n",
20883 + sigaddset(¤t->pending.signal, SIGBUS);
20884 + recalc_sigpending(current);
20885 + current->flags |= PF_SIGNALED;
20886 + do_exit(SIGBUS | 0x80);
20889 +void dump_thread(struct pt_regs *regs, struct user *u)
20893 +void enable_hlt(void)
20895 + panic("enable_hlt");
20898 +void disable_hlt(void)
20900 + panic("disable_hlt");
20903 +extern int signal_frame_size;
20905 +void *um_kmalloc(int size)
20907 + return(kmalloc(size, GFP_KERNEL));
20910 +void *um_kmalloc_atomic(int size)
20912 + return(kmalloc(size, GFP_ATOMIC));
20915 +unsigned long get_fault_addr(void)
20917 + return((unsigned long) current->thread.fault_addr);
20920 +EXPORT_SYMBOL(get_fault_addr);
20922 +void not_implemented(void)
20924 + printk(KERN_DEBUG "Something isn't implemented in here\n");
20927 +EXPORT_SYMBOL(not_implemented);
20929 +int user_context(unsigned long sp)
20931 + unsigned long stack;
20933 + stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
20934 + stack += 2 * PAGE_SIZE;
20935 + return(stack != current->thread.kernel_stack);
20938 +extern void remove_umid_dir(void);
20940 +__uml_exitcall(remove_umid_dir);
20942 +extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
20944 +void do_uml_exitcalls(void)
20946 + exitcall_t *call;
20948 + call = &__uml_exitcall_end;
20949 + while (--call >= &__uml_exitcall_begin)
20953 +char *uml_strdup(char *string)
20957 + new = kmalloc(strlen(string) + 1, GFP_KERNEL);
20958 + if(new == NULL) return(NULL);
20959 + strcpy(new, string);
20963 +void *get_init_task(void)
20965 + return(&init_task_union.task);
20968 +int copy_to_user_proc(void *to, void *from, int size)
20970 + return(copy_to_user(to, from, size));
20973 +int copy_from_user_proc(void *to, void *from, int size)
20975 + return(copy_from_user(to, from, size));
20978 +int clear_user_proc(void *buf, int size)
20980 + return(clear_user(buf, size));
20983 +int strlen_user_proc(char *str)
20985 + return(strlen_user(str));
20988 +int smp_sigio_handler(void)
20991 + int cpu = current->processor;
20993 + IPI_handler(cpu);
21000 +int um_in_interrupt(void)
21002 + return(in_interrupt());
21007 + return(current->processor);
21011 + * Overrides for Emacs so that we follow Linus's tabbing style.
21012 + * Emacs will notice this stuff at the end of the file and automatically
21013 + * adjust the settings for this buffer only. This must remain at the end
21015 + * ---------------------------------------------------------------------------
21016 + * Local variables:
21017 + * c-file-style: "linux"
21020 diff -Naur -X ../exclude-files orig/arch/um/kernel/ptrace.c um/arch/um/kernel/ptrace.c
21021 --- orig/arch/um/kernel/ptrace.c 1969-12-31 19:00:00.000000000 -0500
21022 +++ um/arch/um/kernel/ptrace.c 2002-12-28 22:50:21.000000000 -0500
21025 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
21026 + * Licensed under the GPL
21029 +#include "linux/sched.h"
21030 +#include "linux/mm.h"
21031 +#include "linux/errno.h"
21032 +#include "linux/smp_lock.h"
21033 +#ifdef CONFIG_PROC_MM
21034 +#include "linux/proc_mm.h"
21036 +#include "asm/ptrace.h"
21037 +#include "asm/uaccess.h"
21038 +#include "kern_util.h"
21039 +#include "ptrace_user.h"
21042 + * Called by kernel/ptrace.c when detaching..
21044 +void ptrace_disable(struct task_struct *child)
21048 +extern long do_mmap2(struct task_struct *task, unsigned long addr,
21049 + unsigned long len, unsigned long prot,
21050 + unsigned long flags, unsigned long fd,
21051 + unsigned long pgoff);
21053 +int sys_ptrace(long request, long pid, long addr, long data)
21055 + struct task_struct *child;
21060 + if (request == PTRACE_TRACEME) {
21061 + /* are we already being traced? */
21062 + if (current->ptrace & PT_PTRACED)
21064 + /* set the ptrace bit in the process flags. */
21065 + current->ptrace |= PT_PTRACED;
21070 + read_lock(&tasklist_lock);
21071 + child = find_task_by_pid(pid);
21073 + get_task_struct(child);
21074 + read_unlock(&tasklist_lock);
21079 + if (pid == 1) /* you may not mess with init */
21082 + if (request == PTRACE_ATTACH) {
21083 + ret = ptrace_attach(child);
21087 + ret = ptrace_check_attach(child, request == PTRACE_KILL);
21091 + switch (request) {
21092 + /* when I and D space are separate, these will need to be fixed. */
21093 + case PTRACE_PEEKTEXT: /* read word at location addr. */
21094 + case PTRACE_PEEKDATA: {
21095 + unsigned long tmp;
21099 + copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
21100 + if (copied != sizeof(tmp))
21102 + ret = put_user(tmp,(unsigned long *) data);
21106 + /* read the word at location addr in the USER area. */
21107 + case PTRACE_PEEKUSR: {
21108 + unsigned long tmp;
21111 + if ((addr & 3) || addr < 0)
21114 + tmp = 0; /* Default return condition */
21115 + if(addr < FRAME_SIZE_OFFSET){
21116 + tmp = getreg(child, addr);
21118 + else if((addr >= offsetof(struct user, u_debugreg[0])) &&
21119 + (addr <= offsetof(struct user, u_debugreg[7]))){
21120 + addr -= offsetof(struct user, u_debugreg[0]);
21121 + addr = addr >> 2;
21122 + tmp = child->thread.arch.debugregs[addr];
21124 + ret = put_user(tmp, (unsigned long *) data);
21128 + /* when I and D space are separate, this will have to be fixed. */
21129 + case PTRACE_POKETEXT: /* write the word at location addr. */
21130 + case PTRACE_POKEDATA:
21132 + if (access_process_vm(child, addr, &data, sizeof(data),
21133 + 1) != sizeof(data))
21138 + case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
21140 + if ((addr & 3) || addr < 0)
21143 + if (addr < FRAME_SIZE_OFFSET) {
21144 + ret = putreg(child, addr, data);
21147 + else if((addr >= offsetof(struct user, u_debugreg[0])) &&
21148 + (addr <= offsetof(struct user, u_debugreg[7]))){
21149 + addr -= offsetof(struct user, u_debugreg[0]);
21150 + addr = addr >> 2;
21151 + if((addr == 4) || (addr == 5)) break;
21152 + child->thread.arch.debugregs[addr] = data;
21158 + case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
21159 + case PTRACE_CONT: { /* restart after signal. */
21161 + if ((unsigned long) data > _NSIG)
21163 + if (request == PTRACE_SYSCALL)
21164 + child->ptrace |= PT_TRACESYS;
21166 + child->ptrace &= ~PT_TRACESYS;
21167 + child->exit_code = data;
21168 + wake_up_process(child);
21174 + * make the child exit. Best I can do is send it a sigkill.
21175 + * perhaps it should be put in the status that it wants to
21178 + case PTRACE_KILL: {
21180 + if (child->state == TASK_ZOMBIE) /* already dead */
21182 + child->exit_code = SIGKILL;
21183 + wake_up_process(child);
21187 + case PTRACE_SINGLESTEP: { /* set the trap flag. */
21189 + if ((unsigned long) data > _NSIG)
21191 + child->ptrace &= ~PT_TRACESYS;
21192 + child->ptrace |= PT_DTRACE;
21193 + child->exit_code = data;
21194 + /* give it a chance to run. */
21195 + wake_up_process(child);
21200 + case PTRACE_DETACH:
21201 + /* detach a process that was attached. */
21202 + ret = ptrace_detach(child, data);
21205 +#ifdef PTRACE_GETREGS
21206 + case PTRACE_GETREGS: { /* Get all gp regs from the child. */
21207 + if (!access_ok(VERIFY_WRITE, (unsigned long *)data,
21208 + FRAME_SIZE_OFFSET)) {
21212 + for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
21213 + __put_user(getreg(child, i), (unsigned long *) data);
21214 + data += sizeof(long);
21220 +#ifdef PTRACE_SETREGS
21221 + case PTRACE_SETREGS: { /* Set all gp regs in the child. */
21222 + unsigned long tmp = 0;
21223 + if (!access_ok(VERIFY_READ, (unsigned *)data,
21224 + FRAME_SIZE_OFFSET)) {
21228 + for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
21229 + __get_user(tmp, (unsigned long *) data);
21230 + putreg(child, i, tmp);
21231 + data += sizeof(long);
21237 +#ifdef PTRACE_GETFPREGS
21238 + case PTRACE_GETFPREGS: /* Get the child FPU state. */
21239 + ret = get_fpregs(data, child);
21242 +#ifdef PTRACE_SETFPREGS
21243 + case PTRACE_SETFPREGS: /* Set the child FPU state. */
21244 + ret = set_fpregs(data, child);
21247 +#ifdef PTRACE_GETFPXREGS
21248 + case PTRACE_GETFPXREGS: /* Get the child FPU state. */
21249 + ret = get_fpxregs(data, child);
21252 +#ifdef PTRACE_SETFPXREGS
21253 + case PTRACE_SETFPXREGS: /* Set the child FPU state. */
21254 + ret = set_fpxregs(data, child);
21257 + case PTRACE_FAULTINFO: {
21258 + struct ptrace_faultinfo fault;
21260 + fault = ((struct ptrace_faultinfo)
21261 + { .is_write = child->thread.err,
21262 + .addr = child->thread.cr2 });
21263 + ret = copy_to_user((unsigned long *) data, &fault,
21269 + case PTRACE_SIGPENDING:
21270 + ret = copy_to_user((unsigned long *) data,
21271 + &child->pending.signal,
21272 + sizeof(child->pending.signal));
21275 + case PTRACE_LDT: {
21276 + struct ptrace_ldt ldt;
21278 + if(copy_from_user(&ldt, (unsigned long *) data,
21284 + /* This one is confusing, so just punt and return -EIO for
21290 +#ifdef CONFIG_PROC_MM
21291 + case PTRACE_SWITCH_MM: {
21292 + struct mm_struct *old = child->mm;
21293 + struct mm_struct *new = proc_mm_get_mm(data);
21296 + ret = PTR_ERR(new);
21300 + atomic_inc(&new->mm_users);
21302 + child->active_mm = new;
21313 + free_task_struct(child);
21319 +void syscall_trace(void)
21321 + if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
21322 + != (PT_PTRACED|PT_TRACESYS))
21324 + current->exit_code = SIGTRAP;
21325 + current->state = TASK_STOPPED;
21326 + notify_parent(current, SIGCHLD);
21329 + * this isn't the same as continuing with a signal, but it will do
21330 + * for normal use. strace only continues with a signal if the
21331 + * stopping signal is not SIGTRAP. -brl
21333 + if (current->exit_code) {
21334 + send_sig(current->exit_code, current, 1);
21335 + current->exit_code = 0;
21340 + * Overrides for Emacs so that we follow Linus's tabbing style.
21341 + * Emacs will notice this stuff at the end of the file and automatically
21342 + * adjust the settings for this buffer only. This must remain at the end
21344 + * ---------------------------------------------------------------------------
21345 + * Local variables:
21346 + * c-file-style: "linux"
21349 diff -Naur -X ../exclude-files orig/arch/um/kernel/reboot.c um/arch/um/kernel/reboot.c
21350 --- orig/arch/um/kernel/reboot.c 1969-12-31 19:00:00.000000000 -0500
21351 +++ um/arch/um/kernel/reboot.c 2002-12-30 20:57:42.000000000 -0500
21354 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
21355 + * Licensed under the GPL
21358 +#include "linux/sched.h"
21359 +#include "user_util.h"
21360 +#include "kern_util.h"
21364 +#include "choose-mode.h"
21367 +static void kill_idlers(int me)
21369 + struct task_struct *p;
21372 + for(i = 0; i < sizeof(init_tasks)/sizeof(init_tasks[0]); i++){
21373 + p = init_tasks[i];
21374 + if((p != NULL) && (p->thread.mode.tt.extern_pid != me) &&
21375 + (p->thread.mode.tt.extern_pid != -1))
21376 + os_kill_process(p->thread.mode.tt.extern_pid, 0);
21381 +static void kill_off_processes(void)
21383 + CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas());
21385 + kill_idlers(os_getpid());
21389 +void uml_cleanup(void)
21391 + kill_off_processes();
21392 + do_uml_exitcalls();
21395 +void machine_restart(char * __unused)
21397 + do_uml_exitcalls();
21398 + kill_off_processes();
21399 + CHOOSE_MODE(reboot_tt(), reboot_skas());
21402 +void machine_power_off(void)
21404 + do_uml_exitcalls();
21405 + kill_off_processes();
21406 + CHOOSE_MODE(halt_tt(), halt_skas());
21409 +void machine_halt(void)
21411 + machine_power_off();
21415 + * Overrides for Emacs so that we follow Linus's tabbing style.
21416 + * Emacs will notice this stuff at the end of the file and automatically
21417 + * adjust the settings for this buffer only. This must remain at the end
21419 + * ---------------------------------------------------------------------------
21420 + * Local variables:
21421 + * c-file-style: "linux"
21424 diff -Naur -X ../exclude-files orig/arch/um/kernel/resource.c um/arch/um/kernel/resource.c
21425 --- orig/arch/um/kernel/resource.c 1969-12-31 19:00:00.000000000 -0500
21426 +++ um/arch/um/kernel/resource.c 2002-10-23 21:08:04.000000000 -0400
21429 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
21430 + * Licensed under the GPL
21433 +#include "linux/pci.h"
21435 +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
21436 + unsigned long start, unsigned long size)
21442 + * Overrides for Emacs so that we follow Linus's tabbing style.
21443 + * Emacs will notice this stuff at the end of the file and automatically
21444 + * adjust the settings for this buffer only. This must remain at the end
21446 + * ---------------------------------------------------------------------------
21447 + * Local variables:
21448 + * c-file-style: "linux"
21451 diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_kern.c um/arch/um/kernel/sigio_kern.c
21452 --- orig/arch/um/kernel/sigio_kern.c 1969-12-31 19:00:00.000000000 -0500
21453 +++ um/arch/um/kernel/sigio_kern.c 2003-05-11 18:34:01.000000000 -0400
21456 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
21457 + * Licensed under the GPL
21460 +#include "linux/kernel.h"
21461 +#include "linux/list.h"
21462 +#include "linux/slab.h"
21463 +#include "asm/irq.h"
21465 +#include "sigio.h"
21466 +#include "irq_user.h"
21467 +#include "irq_kern.h"
21469 +/* Protected by sigio_lock() called from write_sigio_workaround */
21470 +static int sigio_irq_fd = -1;
21472 +void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
21474 + read_sigio_fd(sigio_irq_fd);
21475 + reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
21478 +int write_sigio_irq(int fd)
21480 + if(um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
21481 + SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio",
21483 + printk("write_sigio_irq : um_request_irq failed\n");
21486 + sigio_irq_fd = fd;
21490 +static spinlock_t sigio_spinlock = SPIN_LOCK_UNLOCKED;
21492 +void sigio_lock(void)
21494 + spin_lock(&sigio_spinlock);
21497 +void sigio_unlock(void)
21499 + spin_unlock(&sigio_spinlock);
21503 + * Overrides for Emacs so that we follow Linus's tabbing style.
21504 + * Emacs will notice this stuff at the end of the file and automatically
21505 + * adjust the settings for this buffer only. This must remain at the end
21507 + * ---------------------------------------------------------------------------
21508 + * Local variables:
21509 + * c-file-style: "linux"
21512 diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_user.c um/arch/um/kernel/sigio_user.c
21513 --- orig/arch/um/kernel/sigio_user.c 1969-12-31 19:00:00.000000000 -0500
21514 +++ um/arch/um/kernel/sigio_user.c 2002-12-29 23:36:35.000000000 -0500
21517 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
21518 + * Licensed under the GPL
21521 +#include <unistd.h>
21522 +#include <stdlib.h>
21523 +#include <termios.h>
21525 +#include <fcntl.h>
21526 +#include <signal.h>
21527 +#include <errno.h>
21528 +#include <string.h>
21529 +#include <sched.h>
21530 +#include <sys/socket.h>
21531 +#include <sys/poll.h>
21534 +#include "kern_util.h"
21535 +#include "sigio.h"
21536 +#include "helper.h"
21539 +/* Changed during early boot */
21540 +int pty_output_sigio = 0;
21541 +int pty_close_sigio = 0;
21543 +/* Used as a flag during SIGIO testing early in boot */
21544 +static int got_sigio = 0;
21546 +void __init handler(int sig)
21551 +struct openpty_arg {
21557 +static void openpty_cb(void *arg)
21559 + struct openpty_arg *info = arg;
21562 + if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
21563 + info->err = errno;
21566 +void __init check_one_sigio(void (*proc)(int, int))
21568 + struct sigaction old, new;
21569 + struct termios tt;
21570 + struct openpty_arg pty = { .master = -1, .slave = -1 };
21571 + int master, slave, flags;
21573 + initial_thread_cb(openpty_cb, &pty);
21575 + printk("openpty failed, errno = %d\n", pty.err);
21579 + master = pty.master;
21580 + slave = pty.slave;
21582 + if((master == -1) || (slave == -1)){
21583 + printk("openpty failed to allocate a pty\n");
21587 + if(tcgetattr(master, &tt) < 0)
21588 + panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
21590 + if(tcsetattr(master, TCSADRAIN, &tt) < 0)
21591 + panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
21593 + if((flags = fcntl(master, F_GETFL)) < 0)
21594 + panic("tty_fds : fcntl F_GETFL failed, errno = %d\n", errno);
21596 + if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
21597 + (fcntl(master, F_SETOWN, os_getpid()) < 0))
21598 + panic("check_sigio : fcntl F_SETFL or F_SETOWN failed, "
21599 + "errno = %d\n", errno);
21601 + if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
21602 + panic("check_sigio : fcntl F_SETFL failed, errno = %d\n",
21605 + if(sigaction(SIGIO, NULL, &old) < 0)
21606 + panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
21608 + new.sa_handler = handler;
21609 + if(sigaction(SIGIO, &new, NULL) < 0)
21610 + panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
21613 + (*proc)(master, slave);
21618 + if(sigaction(SIGIO, &old, NULL) < 0)
21619 + panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
21622 +static void tty_output(int master, int slave)
21627 + printk("Checking that host ptys support output SIGIO...");
21629 + memset(buf, 0, sizeof(buf));
21630 + while(write(master, buf, sizeof(buf)) > 0) ;
21631 + if(errno != EAGAIN)
21632 + panic("check_sigio : write failed, errno = %d\n", errno);
21634 + while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
21638 + pty_output_sigio = 1;
21640 + else if(errno == EAGAIN) printk("No, enabling workaround\n");
21641 + else panic("check_sigio : read failed, errno = %d\n", errno);
21644 +static void tty_close(int master, int slave)
21646 + printk("Checking that host ptys support SIGIO on close...");
21651 + pty_close_sigio = 1;
21653 + else printk("No, enabling workaround\n");
21656 +void __init check_sigio(void)
21658 + if(access("/dev/ptmx", R_OK) && access("/dev/ptyp0", R_OK)){
21659 + printk("No pseudo-terminals available - skipping pty SIGIO "
21663 + check_one_sigio(tty_output);
21664 + check_one_sigio(tty_close);
21667 +/* Protected by sigio_lock(), also used by sigio_cleanup, which is an
21670 +static int write_sigio_pid = -1;
21672 +/* These arrays are initialized before the sigio thread is started, and
21673 + * the descriptors closed after it is killed. So, it can't see them change.
21674 + * On the UML side, they are changed under the sigio_lock.
21676 +static int write_sigio_fds[2] = { -1, -1 };
21677 +static int sigio_private[2] = { -1, -1 };
21680 + struct pollfd *poll;
21685 +/* Protected by sigio_lock(). Used by the sigio thread, but the UML thread
21686 + * synchronizes with it.
21688 +struct pollfds current_poll = {
21694 +struct pollfds next_poll = {
21700 +static int write_sigio_thread(void *unused)
21702 + struct pollfds *fds, tmp;
21703 + struct pollfd *p;
21704 + int i, n, respond_fd;
21707 + fds = ¤t_poll;
21709 + n = poll(fds->poll, fds->used, -1);
21711 + if(errno == EINTR) continue;
21712 + printk("write_sigio_thread : poll returned %d, "
21713 + "errno = %d\n", n, errno);
21715 + for(i = 0; i < fds->used; i++){
21716 + p = &fds->poll[i];
21717 + if(p->revents == 0) continue;
21718 + if(p->fd == sigio_private[1]){
21719 + n = read(sigio_private[1], &c, sizeof(c));
21720 + if(n != sizeof(c))
21721 + printk("write_sigio_thread : "
21722 + "read failed, errno = %d\n",
21724 + tmp = current_poll;
21725 + current_poll = next_poll;
21727 + respond_fd = sigio_private[1];
21730 + respond_fd = write_sigio_fds[1];
21732 + memmove(&fds->poll[i], &fds->poll[i + 1],
21733 + (fds->used - i) * sizeof(*fds->poll));
21736 + n = write(respond_fd, &c, sizeof(c));
21737 + if(n != sizeof(c))
21738 + printk("write_sigio_thread : write failed, "
21739 + "errno = %d\n", errno);
21744 +static int need_poll(int n)
21746 + if(n <= next_poll.size){
21747 + next_poll.used = n;
21750 + if(next_poll.poll != NULL) kfree(next_poll.poll);
21751 + next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
21752 + if(next_poll.poll == NULL){
21753 + printk("need_poll : failed to allocate new pollfds\n");
21754 + next_poll.size = 0;
21755 + next_poll.used = 0;
21758 + next_poll.size = n;
21759 + next_poll.used = n;
21763 +static void update_thread(void)
21765 + unsigned long flags;
21769 + flags = set_signals(0);
21770 + n = write(sigio_private[0], &c, sizeof(c));
21771 + if(n != sizeof(c)){
21772 + printk("update_thread : write failed, errno = %d\n", errno);
21776 + n = read(sigio_private[0], &c, sizeof(c));
21777 + if(n != sizeof(c)){
21778 + printk("update_thread : read failed, errno = %d\n", errno);
21782 + set_signals(flags);
21786 + if(write_sigio_pid != -1)
21787 + os_kill_process(write_sigio_pid, 1);
21788 + write_sigio_pid = -1;
21789 + close(sigio_private[0]);
21790 + close(sigio_private[1]);
21791 + close(write_sigio_fds[0]);
21792 + close(write_sigio_fds[1]);
21794 + set_signals(flags);
21797 +int add_sigio_fd(int fd, int read)
21799 + int err = 0, i, n, events;
21802 + for(i = 0; i < current_poll.used; i++){
21803 + if(current_poll.poll[i].fd == fd)
21807 + n = current_poll.used + 1;
21808 + err = need_poll(n);
21812 + for(i = 0; i < current_poll.used; i++)
21813 + next_poll.poll[i] = current_poll.poll[i];
21815 + if(read) events = POLLIN;
21816 + else events = POLLOUT;
21818 + next_poll.poll[n - 1] = ((struct pollfd) { .fd = fd,
21819 + .events = events,
21827 +int ignore_sigio_fd(int fd)
21829 + struct pollfd *p;
21830 + int err = 0, i, n = 0;
21833 + for(i = 0; i < current_poll.used; i++){
21834 + if(current_poll.poll[i].fd == fd) break;
21836 + if(i == current_poll.used)
21839 + err = need_poll(current_poll.used - 1);
21843 + for(i = 0; i < current_poll.used; i++){
21844 + p = ¤t_poll.poll[i];
21845 + if(p->fd != fd) next_poll.poll[n++] = current_poll.poll[i];
21848 + printk("ignore_sigio_fd : fd %d not found\n", fd);
21859 +static int setup_initial_poll(int fd)
21861 + struct pollfd *p;
21863 + p = um_kmalloc(sizeof(struct pollfd));
21865 + printk("setup_initial_poll : failed to allocate poll\n");
21868 + *p = ((struct pollfd) { .fd = fd,
21869 + .events = POLLIN,
21871 + current_poll = ((struct pollfds) { .poll = p,
21877 +void write_sigio_workaround(void)
21879 + unsigned long stack;
21883 + if(write_sigio_pid != -1)
21886 + err = os_pipe(write_sigio_fds, 1, 1);
21888 + printk("write_sigio_workaround - os_pipe 1 failed, "
21889 + "errno = %d\n", -err);
21892 + err = os_pipe(sigio_private, 1, 1);
21894 + printk("write_sigio_workaround - os_pipe 2 failed, "
21895 + "errno = %d\n", -err);
21898 + if(setup_initial_poll(sigio_private[1]))
21901 + write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
21902 + CLONE_FILES | CLONE_VM, &stack, 0);
21904 + if(write_sigio_pid < 0) goto out_close2;
21906 + if(write_sigio_irq(write_sigio_fds[0]))
21914 + os_kill_process(write_sigio_pid, 1);
21915 + write_sigio_pid = -1;
21917 + close(sigio_private[0]);
21918 + close(sigio_private[1]);
21920 + close(write_sigio_fds[0]);
21921 + close(write_sigio_fds[1]);
21925 +int read_sigio_fd(int fd)
21930 + n = read(fd, &c, sizeof(c));
21931 + if(n != sizeof(c)){
21932 + printk("read_sigio_fd - read failed, errno = %d\n", errno);
21938 +static void sigio_cleanup(void)
21940 + if(write_sigio_pid != -1)
21941 + os_kill_process(write_sigio_pid, 1);
21944 +__uml_exitcall(sigio_cleanup);
21947 + * Overrides for Emacs so that we follow Linus's tabbing style.
21948 + * Emacs will notice this stuff at the end of the file and automatically
21949 + * adjust the settings for this buffer only. This must remain at the end
21951 + * ---------------------------------------------------------------------------
21952 + * Local variables:
21953 + * c-file-style: "linux"
21956 diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_kern.c um/arch/um/kernel/signal_kern.c
21957 --- orig/arch/um/kernel/signal_kern.c 1969-12-31 19:00:00.000000000 -0500
21958 +++ um/arch/um/kernel/signal_kern.c 2002-12-08 19:44:13.000000000 -0500
21961 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
21962 + * Licensed under the GPL
21965 +#include "linux/config.h"
21966 +#include "linux/stddef.h"
21967 +#include "linux/sys.h"
21968 +#include "linux/sched.h"
21969 +#include "linux/wait.h"
21970 +#include "linux/kernel.h"
21971 +#include "linux/smp_lock.h"
21972 +#include "linux/module.h"
21973 +#include "linux/slab.h"
21974 +#include "asm/signal.h"
21975 +#include "asm/uaccess.h"
21976 +#include "asm/ucontext.h"
21977 +#include "user_util.h"
21978 +#include "kern_util.h"
21979 +#include "signal_kern.h"
21980 +#include "signal_user.h"
21982 +#include "frame_kern.h"
21983 +#include "sigcontext.h"
21986 +EXPORT_SYMBOL(block_signals);
21987 +EXPORT_SYMBOL(unblock_signals);
21989 +static void force_segv(int sig)
21991 + if(sig == SIGSEGV){
21992 + struct k_sigaction *ka;
21994 + ka = ¤t->sig->action[SIGSEGV - 1];
21995 + ka->sa.sa_handler = SIG_DFL;
21997 + force_sig(SIGSEGV, current);
22000 +#define _S(nr) (1<<((nr)-1))
22002 +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
22005 + * OK, we're invoking a handler
22007 +static int handle_signal(struct pt_regs *regs, unsigned long signr,
22008 + struct k_sigaction *ka, siginfo_t *info,
22009 + sigset_t *oldset, int error)
22011 + __sighandler_t handler;
22012 + void (*restorer)(void);
22013 + unsigned long sp;
22019 + case -ERESTARTNOHAND:
22023 + case -ERESTARTSYS:
22024 + if (!(ka->sa.sa_flags & SA_RESTART)) {
22028 + /* fallthrough */
22029 + case -ERESTARTNOINTR:
22030 + PT_REGS_RESTART_SYSCALL(regs);
22031 + PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
22033 + /* This is because of the UM_SET_SYSCALL_RETURN and the fact
22034 + * that on i386 the system call number and return value are
22035 + * in the same register. When the system call restarts, %eax
22036 + * had better have the system call number in it. Since the
22037 + * return value doesn't matter (except that it shouldn't be
22038 + * -ERESTART*), we'll stick the system call number there.
22040 + ret = PT_REGS_SYSCALL_NR(regs);
22044 + handler = ka->sa.sa_handler;
22047 + if (ka->sa.sa_flags & SA_ONESHOT)
22048 + ka->sa.sa_handler = SIG_DFL;
22050 + if (!(ka->sa.sa_flags & SA_NODEFER)) {
22051 + spin_lock_irq(¤t->sigmask_lock);
22052 + sigorsets(¤t->blocked, ¤t->blocked,
22053 + &ka->sa.sa_mask);
22054 + sigaddset(¤t->blocked, signr);
22055 + recalc_sigpending(current);
22056 + spin_unlock_irq(¤t->sigmask_lock);
22059 + sp = PT_REGS_SP(regs);
22061 + if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
22062 + sp = current->sas_ss_sp + current->sas_ss_size;
22064 + if(error != 0) PT_REGS_SET_SYSCALL_RETURN(regs, ret);
22066 + if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer;
22067 + else restorer = NULL;
22069 + if(ka->sa.sa_flags & SA_SIGINFO)
22070 + err = setup_signal_stack_si(sp, signr, (unsigned long) handler,
22071 + restorer, regs, info, &save);
22073 + err = setup_signal_stack_sc(sp, signr, (unsigned long) handler,
22074 + restorer, regs, &save);
22075 + if(err) goto segv;
22079 + force_segv(signr);
22084 + * Note that 'init' is a special process: it doesn't get signals it doesn't
22085 + * want to handle. Thus you cannot kill init even with a SIGKILL even by
22089 +static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error)
22092 + struct k_sigaction *ka;
22096 + oldset = ¤t->blocked;
22099 + unsigned long signr;
22101 + spin_lock_irq(¤t->sigmask_lock);
22102 + signr = dequeue_signal(¤t->blocked, &info);
22103 + spin_unlock_irq(¤t->sigmask_lock);
22108 + if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
22109 + /* Let the debugger run. */
22110 + current->exit_code = signr;
22111 + current->state = TASK_STOPPED;
22112 + notify_parent(current, SIGCHLD);
22115 + /* We're back. Did the debugger cancel the sig? */
22116 + if (!(signr = current->exit_code))
22118 + current->exit_code = 0;
22120 + /* The debugger continued. Ignore SIGSTOP. */
22121 + if (signr == SIGSTOP)
22124 + /* Update the siginfo structure. Is this good? */
22125 + if (signr != info.si_signo) {
22126 + info.si_signo = signr;
22127 + info.si_errno = 0;
22128 + info.si_code = SI_USER;
22129 + info.si_pid = current->p_pptr->pid;
22130 + info.si_uid = current->p_pptr->uid;
22133 + /* If the (new) signal is now blocked, requeue it. */
22134 + if (sigismember(¤t->blocked, signr)) {
22135 + send_sig_info(signr, &info, current);
22140 + ka = ¤t->sig->action[signr-1];
22141 + if (ka->sa.sa_handler == SIG_IGN) {
22142 + if (signr != SIGCHLD)
22144 + /* Check for SIGCHLD: it's special. */
22145 + while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
22150 + if (ka->sa.sa_handler == SIG_DFL) {
22151 + int exit_code = signr;
22153 + /* Init gets no signals it doesn't want. */
22154 + if (current->pid == 1)
22158 + case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
22161 + case SIGTSTP: case SIGTTIN: case SIGTTOU:
22162 + if (is_orphaned_pgrp(current->pgrp))
22167 + struct signal_struct *sig;
22168 + current->state = TASK_STOPPED;
22169 + current->exit_code = signr;
22170 + sig = current->p_pptr->sig;
22171 + if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
22172 + notify_parent(current, SIGCHLD);
22176 + case SIGQUIT: case SIGILL: case SIGTRAP:
22177 + case SIGABRT: case SIGFPE: case SIGSEGV:
22178 + case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
22179 + if (do_coredump(signr, ¤t->thread.regs))
22180 + exit_code |= 0x80;
22184 + sig_exit(signr, exit_code, &info);
22189 + /* Whee! Actually deliver the signal. */
22190 + err = handle_signal(regs, signr, ka, &info, oldset, error);
22191 + if(!err) return(1);
22194 + /* Did we come from a system call? */
22195 + if(PT_REGS_SYSCALL_NR(regs) >= 0){
22196 + /* Restart the system call - no handlers present */
22197 + if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND ||
22198 + PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS ||
22199 + PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOINTR){
22200 + PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
22201 + PT_REGS_RESTART_SYSCALL(regs);
22205 + /* This closes a way to execute a system call on the host. If
22206 + * you set a breakpoint on a system call instruction and singlestep
22207 + * from it, the tracing thread used to PTRACE_SINGLESTEP the process
22208 + * rather than PTRACE_SYSCALL it, allowing the system call to execute
22209 + * on the host. The tracing thread will check this flag and
22210 + * PTRACE_SYSCALL if necessary.
22212 + if((current->ptrace & PT_DTRACE) &&
22213 + is_syscall(PT_REGS_IP(¤t->thread.regs)))
22214 + (void) CHOOSE_MODE(current->thread.mode.tt.singlestep_syscall = 1, 0);
22219 +int do_signal(int error)
22221 + return(kern_do_signal(¤t->thread.regs, NULL, error));
22225 + * Atomically swap in the new signal mask, and wait for a signal.
22227 +int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
22229 + sigset_t saveset;
22231 + mask &= _BLOCKABLE;
22232 + spin_lock_irq(¤t->sigmask_lock);
22233 + saveset = current->blocked;
22234 + siginitset(¤t->blocked, mask);
22235 + recalc_sigpending(current);
22236 + spin_unlock_irq(¤t->sigmask_lock);
22239 + current->state = TASK_INTERRUPTIBLE;
22241 + if(kern_do_signal(¤t->thread.regs, &saveset, -EINTR))
22246 +int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
22248 + sigset_t saveset, newset;
22250 + /* XXX: Don't preclude handling different sized sigset_t's. */
22251 + if (sigsetsize != sizeof(sigset_t))
22254 + if (copy_from_user(&newset, unewset, sizeof(newset)))
22256 + sigdelsetmask(&newset, ~_BLOCKABLE);
22258 + spin_lock_irq(¤t->sigmask_lock);
22259 + saveset = current->blocked;
22260 + current->blocked = newset;
22261 + recalc_sigpending(current);
22262 + spin_unlock_irq(¤t->sigmask_lock);
22265 + current->state = TASK_INTERRUPTIBLE;
22267 + if (kern_do_signal(¤t->thread.regs, &saveset, -EINTR))
22272 +static int copy_sc_from_user(struct pt_regs *to, void *from,
22273 + struct arch_frame_data *arch)
22277 + ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
22278 + copy_sc_from_user_skas(&to->regs, from));
22282 +int sys_sigreturn(struct pt_regs regs)
22284 + void *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
22285 + void *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
22286 + int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
22288 + spin_lock_irq(¤t->sigmask_lock);
22289 + copy_from_user(¤t->blocked.sig[0], sc_sigmask(sc),
22290 + sizeof(current->blocked.sig[0]));
22291 + copy_from_user(¤t->blocked.sig[1], mask, sig_size);
22292 + sigdelsetmask(¤t->blocked, ~_BLOCKABLE);
22293 + recalc_sigpending(current);
22294 + spin_unlock_irq(¤t->sigmask_lock);
22295 + copy_sc_from_user(¤t->thread.regs, sc,
22296 + &signal_frame_sc.common.arch);
22297 + return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
22300 +int sys_rt_sigreturn(struct pt_regs regs)
22302 + struct ucontext *uc = sp_to_uc(PT_REGS_SP(¤t->thread.regs));
22304 + int sig_size = _NSIG_WORDS * sizeof(unsigned long);
22306 + spin_lock_irq(¤t->sigmask_lock);
22307 + copy_from_user(¤t->blocked, &uc->uc_sigmask, sig_size);
22308 + sigdelsetmask(¤t->blocked, ~_BLOCKABLE);
22309 + recalc_sigpending(current);
22310 + spin_unlock_irq(¤t->sigmask_lock);
22311 + fp = (void *) (((unsigned long) uc) + sizeof(struct ucontext));
22312 + copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext,
22313 + &signal_frame_si.common.arch);
22314 + return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
22318 + * Overrides for Emacs so that we follow Linus's tabbing style.
22319 + * Emacs will notice this stuff at the end of the file and automatically
22320 + * adjust the settings for this buffer only. This must remain at the end
22322 + * ---------------------------------------------------------------------------
22323 + * Local variables:
22324 + * c-file-style: "linux"
22327 diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_user.c um/arch/um/kernel/signal_user.c
22328 --- orig/arch/um/kernel/signal_user.c 1969-12-31 19:00:00.000000000 -0500
22329 +++ um/arch/um/kernel/signal_user.c 2002-10-23 21:08:04.000000000 -0400
22332 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
22333 + * Licensed under the GPL
22336 +#include <stdio.h>
22337 +#include <unistd.h>
22338 +#include <stdlib.h>
22339 +#include <signal.h>
22340 +#include <errno.h>
22341 +#include <stdarg.h>
22342 +#include <string.h>
22343 +#include <sys/mman.h>
22344 +#include "user_util.h"
22345 +#include "kern_util.h"
22347 +#include "signal_user.h"
22348 +#include "signal_kern.h"
22349 +#include "sysdep/sigcontext.h"
22350 +#include "sigcontext.h"
22352 +void set_sigstack(void *sig_stack, int size)
22354 + stack_t stack = ((stack_t) { .ss_flags = 0,
22355 + .ss_sp = (__ptr_t) sig_stack,
22356 + .ss_size = size - sizeof(void *) });
22358 + if(sigaltstack(&stack, NULL) != 0)
22359 + panic("enabling signal stack failed, errno = %d\n", errno);
22362 +void set_handler(int sig, void (*handler)(int), int flags, ...)
22364 + struct sigaction action;
22368 + va_start(ap, flags);
22369 + action.sa_handler = handler;
22370 + sigemptyset(&action.sa_mask);
22371 + while((mask = va_arg(ap, int)) != -1){
22372 + sigaddset(&action.sa_mask, mask);
22374 + action.sa_flags = flags;
22375 + action.sa_restorer = NULL;
22376 + if(sigaction(sig, &action, NULL) < 0)
22377 + panic("sigaction failed");
22380 +int change_sig(int signal, int on)
22382 + sigset_t sigset, old;
22384 + sigemptyset(&sigset);
22385 + sigaddset(&sigset, signal);
22386 + sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
22387 + return(!sigismember(&old, signal));
22390 +static void change_signals(int type)
22394 + sigemptyset(&mask);
22395 + sigaddset(&mask, SIGVTALRM);
22396 + sigaddset(&mask, SIGALRM);
22397 + sigaddset(&mask, SIGIO);
22398 + sigaddset(&mask, SIGPROF);
22399 + if(sigprocmask(type, &mask, NULL) < 0)
22400 + panic("Failed to change signal mask - errno = %d", errno);
22403 +void block_signals(void)
22405 + change_signals(SIG_BLOCK);
22408 +void unblock_signals(void)
22410 + change_signals(SIG_UNBLOCK);
22413 +#define SIGIO_BIT 0
22414 +#define SIGVTALRM_BIT 1
22416 +static int enable_mask(sigset_t *mask)
22420 + sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
22421 + sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
22422 + sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
22426 +int get_signals(void)
22430 + if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
22431 + panic("Failed to get signal mask");
22432 + return(enable_mask(&mask));
22435 +int set_signals(int enable)
22440 + sigemptyset(&mask);
22441 + if(enable & (1 << SIGIO_BIT))
22442 + sigaddset(&mask, SIGIO);
22443 + if(enable & (1 << SIGVTALRM_BIT)){
22444 + sigaddset(&mask, SIGVTALRM);
22445 + sigaddset(&mask, SIGALRM);
22447 + if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
22448 + panic("Failed to enable signals");
22449 + ret = enable_mask(&mask);
22450 + sigemptyset(&mask);
22451 + if((enable & (1 << SIGIO_BIT)) == 0)
22452 + sigaddset(&mask, SIGIO);
22453 + if((enable & (1 << SIGVTALRM_BIT)) == 0){
22454 + sigaddset(&mask, SIGVTALRM);
22455 + sigaddset(&mask, SIGALRM);
22457 + if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
22458 + panic("Failed to block signals");
22464 + * Overrides for Emacs so that we follow Linus's tabbing style.
22465 + * Emacs will notice this stuff at the end of the file and automatically
22466 + * adjust the settings for this buffer only. This must remain at the end
22468 + * ---------------------------------------------------------------------------
22469 + * Local variables:
22470 + * c-file-style: "linux"
22473 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_kern.c um/arch/um/kernel/skas/exec_kern.c
22474 --- orig/arch/um/kernel/skas/exec_kern.c 1969-12-31 19:00:00.000000000 -0500
22475 +++ um/arch/um/kernel/skas/exec_kern.c 2002-11-11 18:57:19.000000000 -0500
22478 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22479 + * Licensed under the GPL
22482 +#include "linux/kernel.h"
22483 +#include "asm/current.h"
22484 +#include "asm/page.h"
22485 +#include "asm/signal.h"
22486 +#include "asm/ptrace.h"
22487 +#include "asm/uaccess.h"
22488 +#include "asm/mmu_context.h"
22494 +void flush_thread_skas(void)
22496 + force_flush_all();
22497 + switch_mm_skas(current->mm->context.skas.mm_fd);
22500 +void start_thread_skas(struct pt_regs *regs, unsigned long eip,
22501 + unsigned long esp)
22504 + PT_REGS_IP(regs) = eip;
22505 + PT_REGS_SP(regs) = esp;
22509 + * Overrides for Emacs so that we follow Linus's tabbing style.
22510 + * Emacs will notice this stuff at the end of the file and automatically
22511 + * adjust the settings for this buffer only. This must remain at the end
22513 + * ---------------------------------------------------------------------------
22514 + * Local variables:
22515 + * c-file-style: "linux"
22518 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_user.c um/arch/um/kernel/skas/exec_user.c
22519 --- orig/arch/um/kernel/skas/exec_user.c 1969-12-31 19:00:00.000000000 -0500
22520 +++ um/arch/um/kernel/skas/exec_user.c 2002-11-03 19:23:01.000000000 -0500
22523 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22524 + * Licensed under the GPL
22527 +#include <stdlib.h>
22528 +#include <errno.h>
22529 +#include <signal.h>
22530 +#include <sched.h>
22531 +#include <sys/wait.h>
22532 +#include <sys/ptrace.h>
22534 +#include "kern_util.h"
22536 +#include "time_user.h"
22538 +static int user_thread_tramp(void *arg)
22540 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
22541 + panic("user_thread_tramp - PTRACE_TRACEME failed, "
22542 + "errno = %d\n", errno);
22544 + os_stop_process(os_getpid());
22548 +int user_thread(unsigned long stack, int flags)
22552 + pid = clone(user_thread_tramp, (void *) stack_sp(stack),
22553 + flags | CLONE_FILES | SIGCHLD, NULL);
22555 + printk("user_thread - clone failed, errno = %d\n", errno);
22559 + if(waitpid(pid, &status, WUNTRACED) < 0){
22560 + printk("user_thread - waitpid failed, errno = %d\n", errno);
22564 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
22565 + printk("user_thread - trampoline didn't stop, status = %d\n",
22574 + * Overrides for Emacs so that we follow Linus's tabbing style.
22575 + * Emacs will notice this stuff at the end of the file and automatically
22576 + * adjust the settings for this buffer only. This must remain at the end
22578 + * ---------------------------------------------------------------------------
22579 + * Local variables:
22580 + * c-file-style: "linux"
22583 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mmu.h um/arch/um/kernel/skas/include/mmu.h
22584 --- orig/arch/um/kernel/skas/include/mmu.h 1969-12-31 19:00:00.000000000 -0500
22585 +++ um/arch/um/kernel/skas/include/mmu.h 2002-11-10 21:21:50.000000000 -0500
22588 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22589 + * Licensed under the GPL
22592 +#ifndef __SKAS_MMU_H
22593 +#define __SKAS_MMU_H
22595 +#include "linux/list.h"
22596 +#include "linux/spinlock.h"
22598 +struct mmu_context_skas {
22605 + * Overrides for Emacs so that we follow Linus's tabbing style.
22606 + * Emacs will notice this stuff at the end of the file and automatically
22607 + * adjust the settings for this buffer only. This must remain at the end
22609 + * ---------------------------------------------------------------------------
22610 + * Local variables:
22611 + * c-file-style: "linux"
22614 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode.h um/arch/um/kernel/skas/include/mode.h
22615 --- orig/arch/um/kernel/skas/include/mode.h 1969-12-31 19:00:00.000000000 -0500
22616 +++ um/arch/um/kernel/skas/include/mode.h 2003-03-26 13:27:46.000000000 -0500
22619 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22620 + * Licensed under the GPL
22623 +#ifndef __MODE_SKAS_H__
22624 +#define __MODE_SKAS_H__
22626 +extern unsigned long exec_regs[];
22627 +extern unsigned long exec_fp_regs[];
22628 +extern unsigned long exec_fpx_regs[];
22629 +extern int have_fpx_regs;
22631 +extern void user_time_init_skas(void);
22632 +extern int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr);
22633 +extern int copy_sc_to_user_skas(void *to_ptr, void *fp,
22634 + union uml_pt_regs *regs,
22635 + unsigned long fault_addr, int fault_type);
22636 +extern void sig_handler_common_skas(int sig, void *sc_ptr);
22637 +extern void halt_skas(void);
22638 +extern void reboot_skas(void);
22639 +extern void kill_off_processes_skas(void);
22640 +extern int is_skas_winch(int pid, int fd, void *data);
22645 + * Overrides for Emacs so that we follow Linus's tabbing style.
22646 + * Emacs will notice this stuff at the end of the file and automatically
22647 + * adjust the settings for this buffer only. This must remain at the end
22649 + * ---------------------------------------------------------------------------
22650 + * Local variables:
22651 + * c-file-style: "linux"
22654 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode_kern.h um/arch/um/kernel/skas/include/mode_kern.h
22655 --- orig/arch/um/kernel/skas/include/mode_kern.h 1969-12-31 19:00:00.000000000 -0500
22656 +++ um/arch/um/kernel/skas/include/mode_kern.h 2002-12-16 21:49:11.000000000 -0500
22659 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22660 + * Licensed under the GPL
22663 +#ifndef __SKAS_MODE_KERN_H__
22664 +#define __SKAS_MODE_KERN_H__
22666 +#include "linux/sched.h"
22667 +#include "asm/page.h"
22668 +#include "asm/ptrace.h"
22670 +extern void flush_thread_skas(void);
22671 +extern void *_switch_to_skas(void *prev, void *next);
22672 +extern void start_thread_skas(struct pt_regs *regs, unsigned long eip,
22673 + unsigned long esp);
22674 +extern int copy_thread_skas(int nr, unsigned long clone_flags,
22675 + unsigned long sp, unsigned long stack_top,
22676 + struct task_struct *p, struct pt_regs *regs);
22677 +extern void release_thread_skas(struct task_struct *task);
22678 +extern void exit_thread_skas(void);
22679 +extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
22680 +extern void init_idle_skas(void);
22681 +extern void flush_tlb_kernel_vm_skas(void);
22682 +extern void __flush_tlb_one_skas(unsigned long addr);
22683 +extern void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start,
22684 + unsigned long end);
22685 +extern void flush_tlb_mm_skas(struct mm_struct *mm);
22686 +extern void force_flush_all_skas(void);
22687 +extern long execute_syscall_skas(void *r);
22688 +extern void before_mem_skas(unsigned long unused);
22689 +extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
22690 + unsigned long *task_size_out);
22691 +extern int start_uml_skas(void);
22692 +extern int external_pid_skas(struct task_struct *task);
22693 +extern int thread_pid_skas(struct thread_struct *thread);
22695 +#define kmem_end_skas (host_task_size - 1024 * 1024)
22700 + * Overrides for Emacs so that we follow Linus's tabbing style.
22701 + * Emacs will notice this stuff at the end of the file and automatically
22702 + * adjust the settings for this buffer only. This must remain at the end
22704 + * ---------------------------------------------------------------------------
22705 + * Local variables:
22706 + * c-file-style: "linux"
22709 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/proc_mm.h um/arch/um/kernel/skas/include/proc_mm.h
22710 --- orig/arch/um/kernel/skas/include/proc_mm.h 1969-12-31 19:00:00.000000000 -0500
22711 +++ um/arch/um/kernel/skas/include/proc_mm.h 2002-11-13 11:57:23.000000000 -0500
22714 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22715 + * Licensed under the GPL
22718 +#ifndef __SKAS_PROC_MM_H
22719 +#define __SKAS_PROC_MM_H
22721 +#define MM_MMAP 54
22722 +#define MM_MUNMAP 55
22723 +#define MM_MPROTECT 56
22724 +#define MM_COPY_SEGMENTS 57
22727 + unsigned long addr;
22728 + unsigned long len;
22729 + unsigned long prot;
22730 + unsigned long flags;
22731 + unsigned long fd;
22732 + unsigned long offset;
22735 +struct mm_munmap {
22736 + unsigned long addr;
22737 + unsigned long len;
22740 +struct mm_mprotect {
22741 + unsigned long addr;
22742 + unsigned long len;
22743 + unsigned int prot;
22746 +struct proc_mm_op {
22749 + struct mm_mmap mmap;
22750 + struct mm_munmap munmap;
22751 + struct mm_mprotect mprotect;
22752 + int copy_segments;
22759 + * Overrides for Emacs so that we follow Linus's tabbing style.
22760 + * Emacs will notice this stuff at the end of the file and automatically
22761 + * adjust the settings for this buffer only. This must remain at the end
22763 + * ---------------------------------------------------------------------------
22764 + * Local variables:
22765 + * c-file-style: "linux"
22768 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/ptrace-skas.h um/arch/um/kernel/skas/include/ptrace-skas.h
22769 --- orig/arch/um/kernel/skas/include/ptrace-skas.h 1969-12-31 19:00:00.000000000 -0500
22770 +++ um/arch/um/kernel/skas/include/ptrace-skas.h 2003-01-17 13:22:09.000000000 -0500
22773 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22774 + * Licensed under the GPL
22777 +#ifndef __PTRACE_SKAS_H
22778 +#define __PTRACE_SKAS_H
22780 +#include "uml-config.h"
22782 +#ifdef UML_CONFIG_MODE_SKAS
22784 +#include "skas_ptregs.h"
22786 +#define HOST_FRAME_SIZE 17
22788 +#define REGS_IP(r) ((r)[HOST_IP])
22789 +#define REGS_SP(r) ((r)[HOST_SP])
22790 +#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
22791 +#define REGS_EAX(r) ((r)[HOST_EAX])
22792 +#define REGS_EBX(r) ((r)[HOST_EBX])
22793 +#define REGS_ECX(r) ((r)[HOST_ECX])
22794 +#define REGS_EDX(r) ((r)[HOST_EDX])
22795 +#define REGS_ESI(r) ((r)[HOST_ESI])
22796 +#define REGS_EDI(r) ((r)[HOST_EDI])
22797 +#define REGS_EBP(r) ((r)[HOST_EBP])
22798 +#define REGS_CS(r) ((r)[HOST_CS])
22799 +#define REGS_SS(r) ((r)[HOST_SS])
22800 +#define REGS_DS(r) ((r)[HOST_DS])
22801 +#define REGS_ES(r) ((r)[HOST_ES])
22802 +#define REGS_FS(r) ((r)[HOST_FS])
22803 +#define REGS_GS(r) ((r)[HOST_GS])
22805 +#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res)
22807 +#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
22809 +#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
22811 +#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
22813 +#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
22820 + * Overrides for Emacs so that we follow Linus's tabbing style.
22821 + * Emacs will notice this stuff at the end of the file and automatically
22822 + * adjust the settings for this buffer only. This must remain at the end
22824 + * ---------------------------------------------------------------------------
22825 + * Local variables:
22826 + * c-file-style: "linux"
22829 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/skas.h um/arch/um/kernel/skas/include/skas.h
22830 --- orig/arch/um/kernel/skas/include/skas.h 1969-12-31 19:00:00.000000000 -0500
22831 +++ um/arch/um/kernel/skas/include/skas.h 2002-12-08 21:00:12.000000000 -0500
22834 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22835 + * Licensed under the GPL
22841 +#include "sysdep/ptrace.h"
22843 +extern int userspace_pid;
22845 +extern void switch_threads(void *me, void *next);
22846 +extern void thread_wait(void *sw, void *fb);
22847 +extern void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
22848 + void (*handler)(int));
22849 +extern int start_idle_thread(void *stack, void *switch_buf_ptr,
22850 + void **fork_buf_ptr);
22851 +extern int user_thread(unsigned long stack, int flags);
22852 +extern void userspace(union uml_pt_regs *regs);
22853 +extern void new_thread_proc(void *stack, void (*handler)(int sig));
22854 +extern void remove_sigstack(void);
22855 +extern void new_thread_handler(int sig);
22856 +extern void handle_syscall(union uml_pt_regs *regs);
22857 +extern void map(int fd, unsigned long virt, unsigned long phys,
22858 + unsigned long len, int r, int w, int x);
22859 +extern int unmap(int fd, void *addr, int len);
22860 +extern int protect(int fd, unsigned long addr, unsigned long len,
22861 + int r, int w, int x, int must_succeed);
22862 +extern void user_signal(int sig, union uml_pt_regs *regs);
22863 +extern int singlestepping_skas(void);
22864 +extern int new_mm(int from);
22865 +extern void save_registers(union uml_pt_regs *regs);
22866 +extern void restore_registers(union uml_pt_regs *regs);
22867 +extern void start_userspace(void);
22868 +extern void init_registers(int pid);
22873 + * Overrides for Emacs so that we follow Linus's tabbing style.
22874 + * Emacs will notice this stuff at the end of the file and automatically
22875 + * adjust the settings for this buffer only. This must remain at the end
22877 + * ---------------------------------------------------------------------------
22878 + * Local variables:
22879 + * c-file-style: "linux"
22882 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/uaccess.h um/arch/um/kernel/skas/include/uaccess.h
22883 --- orig/arch/um/kernel/skas/include/uaccess.h 1969-12-31 19:00:00.000000000 -0500
22884 +++ um/arch/um/kernel/skas/include/uaccess.h 2003-01-31 23:05:56.000000000 -0500
22887 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22888 + * Licensed under the GPL
22891 +#ifndef __SKAS_UACCESS_H
22892 +#define __SKAS_UACCESS_H
22894 +#include "linux/string.h"
22895 +#include "linux/sched.h"
22896 +#include "asm/processor.h"
22897 +#include "asm/pgtable.h"
22898 +#include "asm/errno.h"
22899 +#include "asm/current.h"
22900 +#include "asm/a.out.h"
22901 +#include "kern_util.h"
22903 +#define access_ok_skas(type, addr, size) \
22904 + ((segment_eq(get_fs(), KERNEL_DS)) || \
22905 + (((unsigned long) (addr) < TASK_SIZE) && \
22906 + ((unsigned long) (addr) + (size) <= TASK_SIZE)))
22908 +static inline int verify_area_skas(int type, const void * addr,
22909 + unsigned long size)
22911 + return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
22914 +static inline unsigned long maybe_map(unsigned long virt, int is_write)
22918 + void *phys = um_virt_to_phys(current, virt, &pte);
22921 + if(IS_ERR(phys) || (is_write && !pte_write(pte))){
22922 + if(!handle_page_fault(virt, 0, is_write, 0, &dummy_code))
22924 + phys = um_virt_to_phys(current, virt, NULL);
22926 + return((unsigned long) __va((unsigned long) phys));
22929 +static inline int buffer_op(unsigned long addr, int len,
22930 + int (*op)(unsigned long addr, int len, void *arg),
22933 + int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
22934 + int remain = len, n;
22936 + n = (*op)(addr, size, arg);
22938 + return(n < 0 ? remain : 0);
22945 + while(addr < ((addr + remain) & PAGE_MASK)){
22946 + n = (*op)(addr, PAGE_SIZE, arg);
22948 + return(n < 0 ? remain : 0);
22950 + addr += PAGE_SIZE;
22951 + remain -= PAGE_SIZE;
22956 + n = (*op)(addr, remain, arg);
22958 + return(n < 0 ? remain : 0);
22962 +static inline int copy_chunk_from_user(unsigned long from, int len, void *arg)
22964 + unsigned long *to_ptr = arg, to = *to_ptr;
22966 + from = maybe_map(from, 0);
22970 + memcpy((void *) to, (void *) from, len);
22975 +static inline int copy_from_user_skas(void *to, const void *from, int n)
22977 + if(segment_eq(get_fs(), KERNEL_DS)){
22978 + memcpy(to, from, n);
22982 + return(access_ok_skas(VERIFY_READ, from, n) ?
22983 + buffer_op((unsigned long) from, n, copy_chunk_from_user, &to) :
22987 +static inline int copy_chunk_to_user(unsigned long to, int len, void *arg)
22989 + unsigned long *from_ptr = arg, from = *from_ptr;
22991 + to = maybe_map(to, 1);
22995 + memcpy((void *) to, (void *) from, len);
22996 + *from_ptr += len;
23000 +static inline int copy_to_user_skas(void *to, const void *from, int n)
23002 + if(segment_eq(get_fs(), KERNEL_DS)){
23003 + memcpy(to, from, n);
23007 + return(access_ok_skas(VERIFY_WRITE, to, n) ?
23008 + buffer_op((unsigned long) to, n, copy_chunk_to_user, &from) :
23012 +static inline int strncpy_chunk_from_user(unsigned long from, int len,
23015 + char **to_ptr = arg, *to = *to_ptr;
23018 + from = maybe_map(from, 0);
23022 + strncpy(to, (void *) from, len);
23023 + n = strnlen(to, len);
23031 +static inline int strncpy_from_user_skas(char *dst, const char *src, int count)
23036 + if(segment_eq(get_fs(), KERNEL_DS)){
23037 + strncpy(dst, src, count);
23038 + return(strnlen(dst, count));
23041 + if(!access_ok_skas(VERIFY_READ, src, 1))
23044 + n = buffer_op((unsigned long) src, count, strncpy_chunk_from_user,
23048 + return(strnlen(dst, count));
23051 +static inline int clear_chunk(unsigned long addr, int len, void *unused)
23053 + addr = maybe_map(addr, 1);
23057 + memset((void *) addr, 0, len);
23061 +static inline int __clear_user_skas(void *mem, int len)
23063 + return(buffer_op((unsigned long) mem, len, clear_chunk, NULL));
23066 +static inline int clear_user_skas(void *mem, int len)
23068 + if(segment_eq(get_fs(), KERNEL_DS)){
23069 + memset(mem, 0, len);
23073 + return(access_ok_skas(VERIFY_WRITE, mem, len) ?
23074 + buffer_op((unsigned long) mem, len, clear_chunk, NULL) : len);
23077 +static inline int strnlen_chunk(unsigned long str, int len, void *arg)
23079 + int *len_ptr = arg, n;
23081 + str = maybe_map(str, 0);
23085 + n = strnlen((void *) str, len);
23093 +static inline int strnlen_user_skas(const void *str, int len)
23095 + int count = 0, n;
23097 + if(segment_eq(get_fs(), KERNEL_DS))
23098 + return(strnlen(str, len) + 1);
23100 + n = buffer_op((unsigned long) str, len, strnlen_chunk, &count);
23102 + return(count + 1);
23109 + * Overrides for Emacs so that we follow Linus's tabbing style.
23110 + * Emacs will notice this stuff at the end of the file and automatically
23111 + * adjust the settings for this buffer only. This must remain at the end
23113 + * ---------------------------------------------------------------------------
23114 + * Local variables:
23115 + * c-file-style: "linux"
23118 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/Makefile um/arch/um/kernel/skas/Makefile
23119 --- orig/arch/um/kernel/skas/Makefile 1969-12-31 19:00:00.000000000 -0500
23120 +++ um/arch/um/kernel/skas/Makefile 2002-11-01 16:05:44.000000000 -0500
23123 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23124 +# Licensed under the GPL
23129 +obj-y = exec_kern.o exec_user.o mem.o mem_user.o mmu.o process.o \
23130 + process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o
23132 +subdir-y = sys-$(SUBARCH)
23134 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
23136 +USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
23138 +include $(TOPDIR)/Rules.make
23140 +include/skas_ptregs.h : util/mk_ptregs
23141 + util/mk_ptregs > $@
23146 +$(USER_OBJS) : %.o: %.c
23147 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
23150 + $(MAKE) -C util clean
23151 + $(RM) -f include/skas_ptregs.h
23152 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mem.c um/arch/um/kernel/skas/mem.c
23153 --- orig/arch/um/kernel/skas/mem.c 1969-12-31 19:00:00.000000000 -0500
23154 +++ um/arch/um/kernel/skas/mem.c 2002-12-16 21:49:39.000000000 -0500
23157 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23158 + * Licensed under the GPL
23161 +#include "linux/config.h"
23162 +#include "linux/mm.h"
23163 +#include "mem_user.h"
23165 +unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
23166 + unsigned long *task_size_out)
23168 + /* Round up to the nearest 4M */
23169 + unsigned long top = ROUND_4M((unsigned long) &arg);
23171 + *host_size_out = top;
23172 + *task_size_out = top;
23173 + return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
23177 + * Overrides for Emacs so that we follow Linus's tabbing style.
23178 + * Emacs will notice this stuff at the end of the file and automatically
23179 + * adjust the settings for this buffer only. This must remain at the end
23181 + * ---------------------------------------------------------------------------
23182 + * Local variables:
23183 + * c-file-style: "linux"
23186 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mem_user.c um/arch/um/kernel/skas/mem_user.c
23187 --- orig/arch/um/kernel/skas/mem_user.c 1969-12-31 19:00:00.000000000 -0500
23188 +++ um/arch/um/kernel/skas/mem_user.c 2002-12-31 00:13:18.000000000 -0500
23191 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23192 + * Licensed under the GPL
23195 +#include <errno.h>
23196 +#include <sys/mman.h>
23197 +#include <sys/ptrace.h>
23198 +#include "mem_user.h"
23201 +#include "proc_mm.h"
23203 +void map(int fd, unsigned long virt, unsigned long phys, unsigned long len,
23204 + int r, int w, int x)
23206 + struct proc_mm_op map;
23207 + struct mem_region *region;
23210 + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
23211 + (x ? PROT_EXEC : 0);
23212 + region = phys_region(phys);
23214 + map = ((struct proc_mm_op) { .op = MM_MMAP,
23220 + .flags = MAP_SHARED |
23222 + .fd = region->fd,
23223 + .offset = phys_offset(phys)
23225 + n = os_write_file(fd, &map, sizeof(map));
23226 + if(n != sizeof(map))
23227 + printk("map : /proc/mm map failed, errno = %d\n", errno);
23230 +int unmap(int fd, void *addr, int len)
23232 + struct proc_mm_op unmap;
23235 + unmap = ((struct proc_mm_op) { .op = MM_MUNMAP,
23238 + { .addr = (unsigned long) addr,
23239 + .len = len } } } );
23240 + n = os_write_file(fd, &unmap, sizeof(unmap));
23241 + if((n != 0) && (n != sizeof(unmap)))
23246 +int protect(int fd, unsigned long addr, unsigned long len, int r, int w,
23247 + int x, int must_succeed)
23249 + struct proc_mm_op protect;
23252 + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
23253 + (x ? PROT_EXEC : 0);
23255 + protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
23258 + { .addr = (unsigned long) addr,
23260 + .prot = prot } } } );
23262 + n = os_write_file(fd, &protect, sizeof(protect));
23263 + if((n != 0) && (n != sizeof(protect))){
23265 + panic("protect failed, errno = %d", errno);
23271 +void before_mem_skas(unsigned long unused)
23276 + * Overrides for Emacs so that we follow Linus's tabbing style.
23277 + * Emacs will notice this stuff at the end of the file and automatically
23278 + * adjust the settings for this buffer only. This must remain at the end
23280 + * ---------------------------------------------------------------------------
23281 + * Local variables:
23282 + * c-file-style: "linux"
23285 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mmu.c um/arch/um/kernel/skas/mmu.c
23286 --- orig/arch/um/kernel/skas/mmu.c 1969-12-31 19:00:00.000000000 -0500
23287 +++ um/arch/um/kernel/skas/mmu.c 2002-11-13 13:09:57.000000000 -0500
23290 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23291 + * Licensed under the GPL
23294 +#include "linux/list.h"
23295 +#include "linux/spinlock.h"
23296 +#include "linux/slab.h"
23297 +#include "asm/segment.h"
23298 +#include "asm/mmu.h"
23302 +int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
23306 + if((current->mm != NULL) && (current->mm != &init_mm))
23307 + from = current->mm->context.skas.mm_fd;
23310 + mm->context.skas.mm_fd = new_mm(from);
23311 + if(mm->context.skas.mm_fd < 0)
23312 + panic("init_new_context_skas - new_mm failed, errno = %d\n",
23313 + mm->context.skas.mm_fd);
23318 +void destroy_context_skas(struct mm_struct *mm)
23320 + os_close_file(mm->context.skas.mm_fd);
23324 + * Overrides for Emacs so that we follow Linus's tabbing style.
23325 + * Emacs will notice this stuff at the end of the file and automatically
23326 + * adjust the settings for this buffer only. This must remain at the end
23328 + * ---------------------------------------------------------------------------
23329 + * Local variables:
23330 + * c-file-style: "linux"
23333 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process.c um/arch/um/kernel/skas/process.c
23334 --- orig/arch/um/kernel/skas/process.c 1969-12-31 19:00:00.000000000 -0500
23335 +++ um/arch/um/kernel/skas/process.c 2003-05-15 15:21:48.000000000 -0400
23338 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23339 + * Licensed under the GPL
23342 +#include <stdlib.h>
23343 +#include <unistd.h>
23344 +#include <errno.h>
23345 +#include <signal.h>
23346 +#include <setjmp.h>
23347 +#include <sched.h>
23348 +#include <sys/wait.h>
23349 +#include <sys/ptrace.h>
23350 +#include <sys/mman.h>
23351 +#include <sys/user.h>
23352 +#include <asm/unistd.h>
23354 +#include "ptrace_user.h"
23355 +#include "time_user.h"
23356 +#include "sysdep/ptrace.h"
23357 +#include "user_util.h"
23358 +#include "kern_util.h"
23360 +#include "sysdep/sigcontext.h"
23362 +#include "proc_mm.h"
23363 +#include "skas_ptrace.h"
23364 +#include "chan_user.h"
23366 +int is_skas_winch(int pid, int fd, void *data)
23368 + if(pid != getpid())
23371 + register_winch_irq(-1, fd, -1, data);
23375 +unsigned long exec_regs[FRAME_SIZE];
23376 +unsigned long exec_fp_regs[HOST_FP_SIZE];
23377 +unsigned long exec_fpx_regs[HOST_XFP_SIZE];
23378 +int have_fpx_regs = 1;
23380 +static void handle_segv(int pid)
23382 + struct ptrace_faultinfo fault;
23385 + err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault);
23387 + panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n",
23390 + segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
23393 +static void handle_trap(int pid, union uml_pt_regs *regs)
23395 + int err, syscall_nr, status;
23397 + syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
23398 + if(syscall_nr < 1){
23399 + relay_signal(SIGTRAP, regs);
23402 + UPT_SYSCALL_NR(regs) = syscall_nr;
23404 + err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
23406 + panic("handle_trap - nullifying syscall failed errno = %d\n",
23409 + err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
23411 + panic("handle_trap - continuing to end of syscall failed, "
23412 + "errno = %d\n", errno);
23414 + err = waitpid(pid, &status, WUNTRACED);
23415 + if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
23416 + panic("handle_trap - failed to wait at end of syscall, "
23417 + "errno = %d, status = %d\n", errno, status);
23419 + handle_syscall(regs);
23422 +static int userspace_tramp(void *arg)
23424 + init_new_thread_signals(0);
23426 + ptrace(PTRACE_TRACEME, 0, 0, 0);
23427 + os_stop_process(os_getpid());
23431 +int userspace_pid;
23433 +void start_userspace(void)
23436 + unsigned long sp;
23437 + int pid, status, n;
23439 + stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
23440 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
23441 + if(stack == MAP_FAILED)
23442 + panic("start_userspace : mmap failed, errno = %d", errno);
23443 + sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
23445 + pid = clone(userspace_tramp, (void *) sp,
23446 + CLONE_FILES | CLONE_VM | SIGCHLD, NULL);
23448 + panic("start_userspace : clone failed, errno = %d", errno);
23451 + n = waitpid(pid, &status, WUNTRACED);
23453 + panic("start_userspace : wait failed, errno = %d",
23455 + } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
23457 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
23458 + panic("start_userspace : expected SIGSTOP, got status = %d",
23461 + if(munmap(stack, PAGE_SIZE) < 0)
23462 + panic("start_userspace : munmap failed, errno = %d\n", errno);
23464 + userspace_pid = pid;
23467 +void userspace(union uml_pt_regs *regs)
23469 + int err, status, op;
23471 + restore_registers(regs);
23473 + err = ptrace(PTRACE_SYSCALL, userspace_pid, 0, 0);
23475 + panic("userspace - PTRACE_SYSCALL failed, errno = %d\n",
23478 + err = waitpid(userspace_pid, &status, WUNTRACED);
23480 + panic("userspace - waitpid failed, errno = %d\n",
23483 + regs->skas.is_user = 1;
23484 + save_registers(regs);
23486 + if(WIFSTOPPED(status)){
23487 + switch(WSTOPSIG(status)){
23489 + handle_segv(userspace_pid);
23492 + handle_trap(userspace_pid, regs);
23500 + user_signal(WSTOPSIG(status), regs);
23503 + printk("userspace - child stopped with signal "
23504 + "%d\n", WSTOPSIG(status));
23509 + restore_registers(regs);
23511 + op = singlestepping_skas() ? PTRACE_SINGLESTEP :
23513 + err = ptrace(op, userspace_pid, 0, 0);
23515 + panic("userspace - PTRACE_SYSCALL failed, "
23516 + "errno = %d\n", errno);
23520 +void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
23521 + void (*handler)(int))
23523 + jmp_buf switch_buf, fork_buf;
23525 + *switch_buf_ptr = &switch_buf;
23526 + *fork_buf_ptr = &fork_buf;
23528 + if(setjmp(fork_buf) == 0)
23529 + new_thread_proc(stack, handler);
23531 + remove_sigstack();
23534 +void thread_wait(void *sw, void *fb)
23536 + jmp_buf buf, **switch_buf = sw, *fork_buf;
23538 + *switch_buf = &buf;
23540 + if(setjmp(buf) == 0)
23541 + longjmp(*fork_buf, 1);
23544 +static int move_registers(int int_op, int fp_op, union uml_pt_regs *regs,
23545 + unsigned long *fp_regs)
23547 + if(ptrace(int_op, userspace_pid, 0, regs->skas.regs) < 0)
23549 + if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0)
23554 +void save_registers(union uml_pt_regs *regs)
23556 + unsigned long *fp_regs;
23559 + if(have_fpx_regs){
23560 + fp_op = PTRACE_GETFPXREGS;
23561 + fp_regs = regs->skas.xfp;
23564 + fp_op = PTRACE_GETFPREGS;
23565 + fp_regs = regs->skas.fp;
23568 + err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs);
23570 + panic("save_registers - saving registers failed, errno = %d\n",
23574 +void restore_registers(union uml_pt_regs *regs)
23576 + unsigned long *fp_regs;
23579 + if(have_fpx_regs){
23580 + fp_op = PTRACE_SETFPXREGS;
23581 + fp_regs = regs->skas.xfp;
23584 + fp_op = PTRACE_SETFPREGS;
23585 + fp_regs = regs->skas.fp;
23588 + err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs);
23590 + panic("restore_registers - saving registers failed, "
23591 + "errno = %d\n", err);
23594 +void switch_threads(void *me, void *next)
23596 + jmp_buf my_buf, **me_ptr = me, *next_buf = next;
23598 + *me_ptr = &my_buf;
23599 + if(setjmp(my_buf) == 0)
23600 + longjmp(*next_buf, 1);
23603 +static jmp_buf initial_jmpbuf;
23605 +/* XXX Make these percpu */
23606 +static void (*cb_proc)(void *arg);
23607 +static void *cb_arg;
23608 +static jmp_buf *cb_back;
23610 +int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
23612 + jmp_buf **switch_buf = switch_buf_ptr;
23615 + *fork_buf_ptr = &initial_jmpbuf;
23616 + n = setjmp(initial_jmpbuf);
23618 + new_thread_proc((void *) stack, new_thread_handler);
23620 + remove_sigstack();
23622 + (*cb_proc)(cb_arg);
23623 + longjmp(*cb_back, 1);
23633 + longjmp(**switch_buf, 1);
23636 +void remove_sigstack(void)
23638 + stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE,
23642 + if(sigaltstack(&stack, NULL) != 0)
23643 + panic("disabling signal stack failed, errno = %d\n", errno);
23646 +void initial_thread_cb_skas(void (*proc)(void *), void *arg)
23655 + if(setjmp(here) == 0)
23656 + longjmp(initial_jmpbuf, 2);
23657 + unblock_signals();
23664 +void halt_skas(void)
23667 + longjmp(initial_jmpbuf, 3);
23670 +void reboot_skas(void)
23673 + longjmp(initial_jmpbuf, 4);
23676 +int new_mm(int from)
23678 + struct proc_mm_op copy;
23679 + int n, fd = os_open_file("/proc/mm",
23680 + of_cloexec(of_write(OPENFLAGS())), 0);
23686 + copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS,
23688 + { .copy_segments = from } } );
23689 + n = os_write_file(fd, ©, sizeof(copy));
23690 + if(n != sizeof(copy))
23691 + printk("new_mm : /proc/mm copy_segments failed, "
23692 + "errno = %d\n", errno);
23698 +void switch_mm_skas(int mm_fd)
23702 + err = ptrace(PTRACE_SWITCH_MM, userspace_pid, 0, mm_fd);
23704 + panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
23708 +void kill_off_processes_skas(void)
23710 + os_kill_process(userspace_pid, 1);
23713 +void init_registers(int pid)
23717 + if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0)
23718 + panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
23721 + err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
23725 + have_fpx_regs = 0;
23727 + panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
23730 + err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
23732 + panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
23737 + * Overrides for Emacs so that we follow Linus's tabbing style.
23738 + * Emacs will notice this stuff at the end of the file and automatically
23739 + * adjust the settings for this buffer only. This must remain at the end
23741 + * ---------------------------------------------------------------------------
23742 + * Local variables:
23743 + * c-file-style: "linux"
23746 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process_kern.c um/arch/um/kernel/skas/process_kern.c
23747 --- orig/arch/um/kernel/skas/process_kern.c 1969-12-31 19:00:00.000000000 -0500
23748 +++ um/arch/um/kernel/skas/process_kern.c 2002-12-22 20:37:39.000000000 -0500
23751 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23752 + * Licensed under the GPL
23755 +#include "linux/sched.h"
23756 +#include "linux/slab.h"
23757 +#include "kern_util.h"
23758 +#include "time_user.h"
23759 +#include "signal_user.h"
23762 +#include "user_util.h"
23764 +#include "frame.h"
23768 +int singlestepping_skas(void)
23770 + int ret = current->ptrace & PT_DTRACE;
23772 + current->ptrace &= ~PT_DTRACE;
23776 +void *_switch_to_skas(void *prev, void *next)
23778 + struct task_struct *from, *to;
23783 + /* XXX need to check runqueues[cpu].idle */
23784 + if(current->pid == 0)
23785 + switch_timers(0);
23787 + to->thread.prev_sched = from;
23790 + switch_threads(&from->thread.mode.skas.switch_buf,
23791 + to->thread.mode.skas.switch_buf);
23793 + if(current->pid == 0)
23794 + switch_timers(1);
23796 + return(current->thread.prev_sched);
23799 +extern void schedule_tail(struct task_struct *prev);
23801 +void new_thread_handler(int sig)
23803 + int (*fn)(void *), n;
23806 + fn = current->thread.request.u.thread.proc;
23807 + arg = current->thread.request.u.thread.arg;
23808 + change_sig(SIGUSR1, 1);
23809 + thread_wait(¤t->thread.mode.skas.switch_buf,
23810 + current->thread.mode.skas.fork_buf);
23812 + if(current->thread.prev_sched != NULL)
23813 + schedule_tail(current->thread.prev_sched);
23814 + current->thread.prev_sched = NULL;
23816 + n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf);
23818 + userspace(¤t->thread.regs.regs);
23822 +void new_thread_proc(void *stack, void (*handler)(int sig))
23824 + init_new_thread_stack(stack, handler);
23825 + os_usr1_process(os_getpid());
23828 +void release_thread_skas(struct task_struct *task)
23832 +void exit_thread_skas(void)
23836 +void fork_handler(int sig)
23838 + change_sig(SIGUSR1, 1);
23839 + thread_wait(¤t->thread.mode.skas.switch_buf,
23840 + current->thread.mode.skas.fork_buf);
23842 + force_flush_all();
23843 + if(current->thread.prev_sched != NULL)
23844 + schedule_tail(current->thread.prev_sched);
23845 + current->thread.prev_sched = NULL;
23846 + unblock_signals();
23848 + userspace(¤t->thread.regs.regs);
23851 +int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
23852 + unsigned long stack_top, struct task_struct * p,
23853 + struct pt_regs *regs)
23855 + void (*handler)(int);
23857 + if(current->thread.forking){
23858 + memcpy(&p->thread.regs.regs.skas,
23859 + ¤t->thread.regs.regs.skas,
23860 + sizeof(p->thread.regs.regs.skas));
23861 + REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
23862 + if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
23864 + handler = fork_handler;
23867 + memcpy(p->thread.regs.regs.skas.regs, exec_regs,
23868 + sizeof(p->thread.regs.regs.skas.regs));
23869 + memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs,
23870 + sizeof(p->thread.regs.regs.skas.fp));
23871 + memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs,
23872 + sizeof(p->thread.regs.regs.skas.xfp));
23873 + p->thread.request.u.thread = current->thread.request.u.thread;
23874 + handler = new_thread_handler;
23877 + new_thread((void *) p->thread.kernel_stack,
23878 + &p->thread.mode.skas.switch_buf,
23879 + &p->thread.mode.skas.fork_buf, handler);
23883 +void init_idle_skas(void)
23885 + cpu_tasks[current->processor].pid = os_getpid();
23888 +extern void start_kernel(void);
23890 +static int start_kernel_proc(void *unused)
23895 + pid = os_getpid();
23897 + cpu_tasks[0].pid = pid;
23898 + cpu_tasks[0].task = current;
23900 + cpu_online_map = 1;
23906 +int start_uml_skas(void)
23908 + start_userspace();
23909 + capture_signal_stack();
23911 + init_new_thread_signals(1);
23914 + init_task.thread.request.u.thread.proc = start_kernel_proc;
23915 + init_task.thread.request.u.thread.arg = NULL;
23916 + return(start_idle_thread((void *) init_task.thread.kernel_stack,
23917 + &init_task.thread.mode.skas.switch_buf,
23918 + &init_task.thread.mode.skas.fork_buf));
23921 +int external_pid_skas(struct task_struct *task)
23923 + return(userspace_pid);
23926 +int thread_pid_skas(struct thread_struct *thread)
23928 + return(userspace_pid);
23932 + * Overrides for Emacs so that we follow Linus's tabbing style.
23933 + * Emacs will notice this stuff at the end of the file and automatically
23934 + * adjust the settings for this buffer only. This must remain at the end
23936 + * ---------------------------------------------------------------------------
23937 + * Local variables:
23938 + * c-file-style: "linux"
23941 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_kern.c um/arch/um/kernel/skas/syscall_kern.c
23942 --- orig/arch/um/kernel/skas/syscall_kern.c 1969-12-31 19:00:00.000000000 -0500
23943 +++ um/arch/um/kernel/skas/syscall_kern.c 2002-12-08 21:01:44.000000000 -0500
23946 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23947 + * Licensed under the GPL
23950 +#include "linux/sys.h"
23951 +#include "asm/errno.h"
23952 +#include "asm/unistd.h"
23953 +#include "asm/ptrace.h"
23954 +#include "asm/current.h"
23955 +#include "sysdep/syscalls.h"
23956 +#include "kern_util.h"
23958 +extern syscall_handler_t *sys_call_table[];
23960 +long execute_syscall_skas(void *r)
23962 + struct pt_regs *regs = r;
23966 + current->thread.nsyscalls++;
23968 + syscall = UPT_SYSCALL_NR(®s->regs);
23970 + if((syscall >= NR_syscalls) || (syscall < 0))
23972 + else res = EXECUTE_SYSCALL(syscall, regs);
23978 + * Overrides for Emacs so that we follow Linus's tabbing style.
23979 + * Emacs will notice this stuff at the end of the file and automatically
23980 + * adjust the settings for this buffer only. This must remain at the end
23982 + * ---------------------------------------------------------------------------
23983 + * Local variables:
23984 + * c-file-style: "linux"
23987 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_user.c um/arch/um/kernel/skas/syscall_user.c
23988 --- orig/arch/um/kernel/skas/syscall_user.c 1969-12-31 19:00:00.000000000 -0500
23989 +++ um/arch/um/kernel/skas/syscall_user.c 2002-12-08 21:00:12.000000000 -0500
23992 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23993 + * Licensed under the GPL
23996 +#include <stdlib.h>
23997 +#include <signal.h>
23998 +#include "kern_util.h"
23999 +#include "syscall_user.h"
24000 +#include "sysdep/ptrace.h"
24001 +#include "sysdep/sigcontext.h"
24004 +#define ERESTARTSYS 512
24005 +#define ERESTARTNOINTR 513
24006 +#define ERESTARTNOHAND 514
24008 +void handle_syscall(union uml_pt_regs *regs)
24013 + index = record_syscall_start(UPT_SYSCALL_NR(regs));
24016 + result = execute_syscall(regs);
24018 + REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
24019 + if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) ||
24020 + (result == -ERESTARTNOINTR))
24021 + do_signal(result);
24024 + record_syscall_end(index, result);
24028 + * Overrides for Emacs so that we follow Linus's tabbing style.
24029 + * Emacs will notice this stuff at the end of the file and automatically
24030 + * adjust the settings for this buffer only. This must remain at the end
24032 + * ---------------------------------------------------------------------------
24033 + * Local variables:
24034 + * c-file-style: "linux"
24037 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/Makefile um/arch/um/kernel/skas/sys-i386/Makefile
24038 --- orig/arch/um/kernel/skas/sys-i386/Makefile 1969-12-31 19:00:00.000000000 -0500
24039 +++ um/arch/um/kernel/skas/sys-i386/Makefile 2002-10-23 21:08:04.000000000 -0400
24042 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24043 +# Licensed under the GPL
24046 +O_TARGET = sys-i386.o
24048 +obj-y = sigcontext.o
24050 +USER_OBJS = sigcontext.o
24052 +include $(TOPDIR)/Rules.make
24054 +$(USER_OBJS) : %.o: %.c
24055 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
24058 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/sigcontext.c um/arch/um/kernel/skas/sys-i386/sigcontext.c
24059 --- orig/arch/um/kernel/skas/sys-i386/sigcontext.c 1969-12-31 19:00:00.000000000 -0500
24060 +++ um/arch/um/kernel/skas/sys-i386/sigcontext.c 2002-12-08 20:38:46.000000000 -0500
24063 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24064 + * Licensed under the GPL
24067 +#include <errno.h>
24068 +#include <asm/sigcontext.h>
24069 +#include <sys/ptrace.h>
24070 +#include <linux/ptrace.h>
24071 +#include "sysdep/ptrace.h"
24072 +#include "sysdep/ptrace_user.h"
24073 +#include "kern_util.h"
24075 +#include "sigcontext.h"
24077 +extern int userspace_pid;
24079 +int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr)
24081 + struct sigcontext sc, *from = from_ptr;
24082 + unsigned long fpregs[FP_FRAME_SIZE];
24085 + err = copy_from_user_proc(&sc, from, sizeof(sc));
24086 + err |= copy_from_user_proc(fpregs, sc.fpstate, sizeof(fpregs));
24090 + regs->skas.regs[GS] = sc.gs;
24091 + regs->skas.regs[FS] = sc.fs;
24092 + regs->skas.regs[ES] = sc.es;
24093 + regs->skas.regs[DS] = sc.ds;
24094 + regs->skas.regs[EDI] = sc.edi;
24095 + regs->skas.regs[ESI] = sc.esi;
24096 + regs->skas.regs[EBP] = sc.ebp;
24097 + regs->skas.regs[UESP] = sc.esp;
24098 + regs->skas.regs[EBX] = sc.ebx;
24099 + regs->skas.regs[EDX] = sc.edx;
24100 + regs->skas.regs[ECX] = sc.ecx;
24101 + regs->skas.regs[EAX] = sc.eax;
24102 + regs->skas.regs[EIP] = sc.eip;
24103 + regs->skas.regs[CS] = sc.cs;
24104 + regs->skas.regs[EFL] = sc.eflags;
24105 + regs->skas.regs[UESP] = sc.esp_at_signal;
24106 + regs->skas.regs[SS] = sc.ss;
24107 + regs->skas.fault_addr = sc.cr2;
24108 + regs->skas.fault_type = FAULT_WRITE(sc.err);
24109 + regs->skas.trap_type = sc.trapno;
24111 + err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs);
24113 + printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
24114 + "errno = %d\n", errno);
24121 +int copy_sc_to_user_skas(void *to_ptr, void *fp, union uml_pt_regs *regs,
24122 + unsigned long fault_addr, int fault_type)
24124 + struct sigcontext sc, *to = to_ptr;
24125 + struct _fpstate *to_fp;
24126 + unsigned long fpregs[FP_FRAME_SIZE];
24129 + sc.gs = regs->skas.regs[GS];
24130 + sc.fs = regs->skas.regs[FS];
24131 + sc.es = regs->skas.regs[ES];
24132 + sc.ds = regs->skas.regs[DS];
24133 + sc.edi = regs->skas.regs[EDI];
24134 + sc.esi = regs->skas.regs[ESI];
24135 + sc.ebp = regs->skas.regs[EBP];
24136 + sc.esp = regs->skas.regs[UESP];
24137 + sc.ebx = regs->skas.regs[EBX];
24138 + sc.edx = regs->skas.regs[EDX];
24139 + sc.ecx = regs->skas.regs[ECX];
24140 + sc.eax = regs->skas.regs[EAX];
24141 + sc.eip = regs->skas.regs[EIP];
24142 + sc.cs = regs->skas.regs[CS];
24143 + sc.eflags = regs->skas.regs[EFL];
24144 + sc.esp_at_signal = regs->skas.regs[UESP];
24145 + sc.ss = regs->skas.regs[SS];
24146 + sc.cr2 = fault_addr;
24147 + sc.err = TO_SC_ERR(fault_type);
24148 + sc.trapno = regs->skas.trap_type;
24150 + err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs);
24152 + printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
24153 + "errno = %d\n", errno);
24156 + to_fp = (struct _fpstate *)
24157 + (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
24158 + sc.fpstate = to_fp;
24163 + return(copy_to_user_proc(to, &sc, sizeof(sc)) ||
24164 + copy_to_user_proc(to_fp, fpregs, sizeof(fpregs)));
24168 + * Overrides for Emacs so that we follow Linus's tabbing style.
24169 + * Emacs will notice this stuff at the end of the file and automatically
24170 + * adjust the settings for this buffer only. This must remain at the end
24172 + * ---------------------------------------------------------------------------
24173 + * Local variables:
24174 + * c-file-style: "linux"
24177 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/time.c um/arch/um/kernel/skas/time.c
24178 --- orig/arch/um/kernel/skas/time.c 1969-12-31 19:00:00.000000000 -0500
24179 +++ um/arch/um/kernel/skas/time.c 2002-10-23 21:08:04.000000000 -0400
24182 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24183 + * Licensed under the GPL
24186 +#include <sys/signal.h>
24187 +#include <sys/time.h>
24188 +#include "time_user.h"
24189 +#include "process.h"
24192 +void user_time_init_skas(void)
24194 + if(signal(SIGALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
24195 + panic("Couldn't set SIGALRM handler");
24196 + if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
24197 + panic("Couldn't set SIGVTALRM handler");
24198 + set_interval(ITIMER_VIRTUAL);
24202 + * Overrides for Emacs so that we follow Linus's tabbing style.
24203 + * Emacs will notice this stuff at the end of the file and automatically
24204 + * adjust the settings for this buffer only. This must remain at the end
24206 + * ---------------------------------------------------------------------------
24207 + * Local variables:
24208 + * c-file-style: "linux"
24211 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/tlb.c um/arch/um/kernel/skas/tlb.c
24212 --- orig/arch/um/kernel/skas/tlb.c 1969-12-31 19:00:00.000000000 -0500
24213 +++ um/arch/um/kernel/skas/tlb.c 2002-12-22 18:30:35.000000000 -0500
24216 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24217 + * Licensed under the GPL
24220 +#include "linux/stddef.h"
24221 +#include "linux/sched.h"
24222 +#include "asm/page.h"
24223 +#include "asm/pgtable.h"
24224 +#include "asm/mmu.h"
24225 +#include "user_util.h"
24226 +#include "mem_user.h"
24230 +static void fix_range(struct mm_struct *mm, unsigned long start_addr,
24231 + unsigned long end_addr, int force)
24236 + unsigned long addr;
24237 + int r, w, x, err, fd;
24239 + if(mm == NULL) return;
24240 + fd = mm->context.skas.mm_fd;
24241 + for(addr = start_addr; addr < end_addr;){
24242 + npgd = pgd_offset(mm, addr);
24243 + npmd = pmd_offset(npgd, addr);
24244 + if(pmd_present(*npmd)){
24245 + npte = pte_offset(npmd, addr);
24246 + r = pte_read(*npte);
24247 + w = pte_write(*npte);
24248 + x = pte_exec(*npte);
24249 + if(!pte_dirty(*npte)) w = 0;
24250 + if(!pte_young(*npte)){
24254 + if(force || pte_newpage(*npte)){
24255 + err = unmap(fd, (void *) addr, PAGE_SIZE);
24257 + panic("munmap failed, errno = %d\n",
24259 + if(pte_present(*npte))
24261 + pte_val(*npte) & PAGE_MASK,
24262 + PAGE_SIZE, r, w, x);
24264 + else if(pte_newprot(*npte)){
24265 + protect(fd, addr, PAGE_SIZE, r, w, x, 1);
24267 + *npte = pte_mkuptodate(*npte);
24268 + addr += PAGE_SIZE;
24271 + if(force || pmd_newpage(*npmd)){
24272 + err = unmap(fd, (void *) addr, PMD_SIZE);
24274 + panic("munmap failed, errno = %d\n",
24276 + pmd_mkuptodate(*npmd);
24278 + addr += PMD_SIZE;
24283 +static void flush_kernel_vm_range(unsigned long start, unsigned long end)
24285 + struct mm_struct *mm;
24289 + unsigned long addr;
24290 + int updated = 0, err;
24293 + for(addr = start_vm; addr < end_vm;){
24294 + pgd = pgd_offset(mm, addr);
24295 + pmd = pmd_offset(pgd, addr);
24296 + if(pmd_present(*pmd)){
24297 + pte = pte_offset(pmd, addr);
24298 + if(!pte_present(*pte) || pte_newpage(*pte)){
24300 + err = os_unmap_memory((void *) addr,
24303 + panic("munmap failed, errno = %d\n",
24305 + if(pte_present(*pte))
24307 + pte_val(*pte) & PAGE_MASK,
24308 + PAGE_SIZE, 1, 1, 1);
24310 + else if(pte_newprot(*pte)){
24312 + protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
24314 + addr += PAGE_SIZE;
24317 + if(pmd_newpage(*pmd)){
24319 + err = os_unmap_memory((void *) addr, PMD_SIZE);
24321 + panic("munmap failed, errno = %d\n",
24324 + addr += PMD_SIZE;
24329 +void flush_tlb_kernel_vm_skas(void)
24331 + flush_kernel_vm_range(start_vm, end_vm);
24334 +void __flush_tlb_one_skas(unsigned long addr)
24336 + flush_kernel_vm_range(addr, addr + PAGE_SIZE);
24339 +void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start,
24340 + unsigned long end)
24343 + flush_kernel_vm_range(start, end);
24344 + else fix_range(mm, start, end, 0);
24347 +void flush_tlb_mm_skas(struct mm_struct *mm)
24349 + flush_tlb_kernel_vm_skas();
24350 + fix_range(mm, 0, host_task_size, 0);
24353 +void force_flush_all_skas(void)
24355 + fix_range(current->mm, 0, host_task_size, 1);
24359 + * Overrides for Emacs so that we follow Linus's tabbing style.
24360 + * Emacs will notice this stuff at the end of the file and automatically
24361 + * adjust the settings for this buffer only. This must remain at the end
24363 + * ---------------------------------------------------------------------------
24364 + * Local variables:
24365 + * c-file-style: "linux"
24368 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/trap_user.c um/arch/um/kernel/skas/trap_user.c
24369 --- orig/arch/um/kernel/skas/trap_user.c 1969-12-31 19:00:00.000000000 -0500
24370 +++ um/arch/um/kernel/skas/trap_user.c 2002-12-15 13:28:41.000000000 -0500
24373 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24374 + * Licensed under the GPL
24377 +#include <signal.h>
24378 +#include <errno.h>
24379 +#include <asm/sigcontext.h>
24380 +#include "sysdep/ptrace.h"
24381 +#include "signal_user.h"
24382 +#include "user_util.h"
24383 +#include "kern_util.h"
24385 +#include "sigcontext.h"
24387 +void sig_handler_common_skas(int sig, void *sc_ptr)
24389 + struct sigcontext *sc = sc_ptr;
24390 + struct skas_regs *r;
24391 + struct signal_info *info;
24392 + int save_errno = errno;
24394 + r = &TASK_REGS(get_current())->skas;
24396 + r->fault_addr = SC_FAULT_ADDR(sc);
24397 + r->fault_type = SC_FAULT_TYPE(sc);
24398 + r->trap_type = SC_TRAP_TYPE(sc);
24400 + change_sig(SIGUSR1, 1);
24401 + info = &sig_info[sig];
24402 + if(!info->is_irq) unblock_signals();
24404 + (*info->handler)(sig, (union uml_pt_regs *) r);
24406 + errno = save_errno;
24409 +extern int missed_ticks[];
24411 +void user_signal(int sig, union uml_pt_regs *regs)
24413 + struct signal_info *info;
24415 + if(sig == SIGVTALRM)
24416 + missed_ticks[cpu()]++;
24417 + regs->skas.is_user = 1;
24418 + regs->skas.fault_addr = 0;
24419 + regs->skas.fault_type = 0;
24420 + regs->skas.trap_type = 0;
24421 + info = &sig_info[sig];
24422 + (*info->handler)(sig, regs);
24424 + unblock_signals();
24428 + * Overrides for Emacs so that we follow Linus's tabbing style.
24429 + * Emacs will notice this stuff at the end of the file and automatically
24430 + * adjust the settings for this buffer only. This must remain at the end
24432 + * ---------------------------------------------------------------------------
24433 + * Local variables:
24434 + * c-file-style: "linux"
24437 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/Makefile um/arch/um/kernel/skas/util/Makefile
24438 --- orig/arch/um/kernel/skas/util/Makefile 1969-12-31 19:00:00.000000000 -0500
24439 +++ um/arch/um/kernel/skas/util/Makefile 2002-10-23 21:08:04.000000000 -0400
24443 +mk_ptregs : mk_ptregs.o
24444 + $(CC) -o mk_ptregs mk_ptregs.o
24446 +mk_ptregs.o : mk_ptregs.c
24450 + $(RM) -f mk_ptregs *.o *~
24451 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/mk_ptregs.c um/arch/um/kernel/skas/util/mk_ptregs.c
24452 --- orig/arch/um/kernel/skas/util/mk_ptregs.c 1969-12-31 19:00:00.000000000 -0500
24453 +++ um/arch/um/kernel/skas/util/mk_ptregs.c 2002-11-11 12:10:06.000000000 -0500
24455 +#include <asm/ptrace.h>
24456 +#include <asm/user.h>
24458 +#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val))
24460 +int main(int argc, char **argv)
24462 + printf("/* Automatically generated by "
24463 + "arch/um/kernel/skas/util/mk_ptregs */\n");
24465 + printf("#ifndef __SKAS_PT_REGS_\n");
24466 + printf("#define __SKAS_PT_REGS_\n");
24468 + printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE);
24469 + printf("#define HOST_FP_SIZE %d\n",
24470 + sizeof(struct user_i387_struct) / sizeof(unsigned long));
24471 + printf("#define HOST_XFP_SIZE %d\n",
24472 + sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
24474 + PRINT_REG("IP", EIP);
24475 + PRINT_REG("SP", UESP);
24476 + PRINT_REG("EFLAGS", EFL);
24477 + PRINT_REG("EAX", EAX);
24478 + PRINT_REG("EBX", EBX);
24479 + PRINT_REG("ECX", ECX);
24480 + PRINT_REG("EDX", EDX);
24481 + PRINT_REG("ESI", ESI);
24482 + PRINT_REG("EDI", EDI);
24483 + PRINT_REG("EBP", EBP);
24484 + PRINT_REG("CS", CS);
24485 + PRINT_REG("SS", SS);
24486 + PRINT_REG("DS", DS);
24487 + PRINT_REG("FS", FS);
24488 + PRINT_REG("ES", ES);
24489 + PRINT_REG("GS", GS);
24491 + printf("#endif\n");
24496 + * Overrides for Emacs so that we follow Linus's tabbing style.
24497 + * Emacs will notice this stuff at the end of the file and automatically
24498 + * adjust the settings for this buffer only. This must remain at the end
24500 + * ---------------------------------------------------------------------------
24501 + * Local variables:
24502 + * c-file-style: "linux"
24505 diff -Naur -X ../exclude-files orig/arch/um/kernel/smp.c um/arch/um/kernel/smp.c
24506 --- orig/arch/um/kernel/smp.c 1969-12-31 19:00:00.000000000 -0500
24507 +++ um/arch/um/kernel/smp.c 2003-02-22 14:28:45.000000000 -0500
24510 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
24511 + * Licensed under the GPL
24514 +#include "linux/config.h"
24519 +#include "linux/sched.h"
24520 +#include "linux/threads.h"
24521 +#include "linux/interrupt.h"
24522 +#include "asm/smp.h"
24523 +#include "asm/processor.h"
24524 +#include "asm/spinlock.h"
24525 +#include "asm/softirq.h"
24526 +#include "asm/hardirq.h"
24527 +#include "user_util.h"
24528 +#include "kern_util.h"
24529 +#include "irq_user.h"
24533 +/* Total count of live CPUs, set by smp_boot_cpus */
24534 +int smp_num_cpus = 1;
24536 +/* The 'big kernel lock' */
24537 +spinlock_cacheline_t kernel_flag_cacheline = {SPIN_LOCK_UNLOCKED};
24539 +/* Per CPU bogomips and other parameters */
24541 +/* The only piece used here is the ipi pipe, which is set before SMP is
24542 + * started and never changed.
24544 +struct cpuinfo_um cpu_data[NR_CPUS];
24546 +/* CPU online map, set by smp_boot_cpus */
24547 +unsigned long cpu_online_map;
24549 +atomic_t global_bh_count;
24551 +/* Set when the idlers are all forked */
24552 +int smp_threads_ready = 0;
24554 +/* Not used by UML */
24555 +unsigned char global_irq_holder = 0;
24556 +unsigned volatile long global_irq_lock;
24558 +/* A statistic, can be a little off */
24559 +static int num_reschedules_sent = 0;
24561 +void smp_send_reschedule(int cpu)
24563 + write(cpu_data[cpu].ipi_pipe[1], "R", 1);
24564 + num_reschedules_sent++;
24567 +static void show(char * str)
24569 + int cpu = smp_processor_id();
24571 + printk(KERN_INFO "\n%s, CPU %d:\n", str, cpu);
24574 +#define MAXCOUNT 100000000
24576 +static inline void wait_on_bh(void)
24578 + int count = MAXCOUNT;
24581 + show("wait_on_bh");
24584 + /* nothing .. wait for the other bh's to go away */
24585 + } while (atomic_read(&global_bh_count) != 0);
24589 + * This is called when we want to synchronize with
24590 + * bottom half handlers. We need to wait until
24591 + * no other CPU is executing any bottom half handler.
24593 + * Don't wait if we're already running in an interrupt
24594 + * context or are inside a bh handler.
24596 +void synchronize_bh(void)
24598 + if (atomic_read(&global_bh_count) && !in_interrupt())
24602 +void smp_send_stop(void)
24606 + printk(KERN_INFO "Stopping all CPUs...");
24607 + for(i = 0; i < ncpus; i++){
24608 + if(i == current->processor)
24610 + write(cpu_data[i].ipi_pipe[1], "S", 1);
24612 + printk("done\n");
24616 +static atomic_t smp_commenced = ATOMIC_INIT(0);
24617 +static volatile unsigned long smp_callin_map = 0;
24619 +void smp_commence(void)
24621 + printk("All CPUs are go!\n");
24624 + atomic_set(&smp_commenced, 1);
24627 +static int idle_proc(void *unused)
24631 + set_current(current);
24632 + del_from_runqueue(current);
24633 + unhash_process(current);
24635 + cpu = current->processor;
24636 + err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
24638 + panic("CPU#%d failed to create IPI pipe, errno = %d", cpu,
24641 + activate_ipi(cpu_data[cpu].ipi_pipe[0],
24642 + current->thread.mode.tt.extern_pid);
24645 + if (test_and_set_bit(current->processor, &smp_callin_map)) {
24646 + printk("huh, CPU#%d already present??\n", current->processor);
24650 + while (!atomic_read(&smp_commenced))
24658 +static int idle_thread(int (*fn)(void *), int cpu)
24660 + struct task_struct *new_task;
24664 + current->thread.request.u.thread.proc = fn;
24665 + current->thread.request.u.thread.arg = NULL;
24666 + pid = do_fork(CLONE_VM | CLONE_PID, 0, NULL, 0);
24667 + if(pid < 0) panic("do_fork failed in idle_thread");
24668 + new_task = get_task(pid, 1);
24670 + cpu_tasks[cpu].pid = new_task->thread.mode.tt.extern_pid;
24671 + cpu_tasks[cpu].task = new_task;
24672 + init_tasks[cpu] = new_task;
24673 + new_task->processor = cpu;
24674 + new_task->cpus_allowed = 1 << cpu;
24675 + new_task->cpus_runnable = new_task->cpus_allowed;
24676 + CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c,
24678 + ({ panic("skas mode doesn't support SMP"); }));
24679 + return(new_task->thread.mode.tt.extern_pid);
24682 +void smp_boot_cpus(void)
24686 + set_bit(0, &cpu_online_map);
24687 + set_bit(0, &smp_callin_map);
24689 + err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
24690 + if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
24692 + activate_ipi(cpu_data[0].ipi_pipe[0],
24693 + current->thread.mode.tt.extern_pid);
24696 + printk(KERN_INFO "ncpus set to 1\n");
24699 + else if(ncpus > NR_CPUS){
24701 + "ncpus can't be greater than NR_CPUS, set to %d\n",
24709 + printk(KERN_INFO "Starting up other processors:\n");
24710 + for(i=1;i<ncpus;i++){
24713 + /* Do this early, for hard_smp_processor_id() */
24714 + cpu_tasks[i].pid = -1;
24715 + set_bit(i, &cpu_online_map);
24718 + pid = idle_thread(idle_proc, i);
24719 + printk(KERN_INFO "\t#%d - idle thread pid = %d.. ",
24722 + waittime = 200000000;
24723 + while (waittime-- && !test_bit(i, &smp_callin_map))
24726 + if (test_bit(i, &smp_callin_map))
24727 + printk("online\n");
24729 + printk("failed\n");
24730 + clear_bit(i, &cpu_online_map);
24736 +int setup_profiling_timer(unsigned int multiplier)
24738 + printk(KERN_INFO "setup_profiling_timer\n");
24742 +void smp_call_function_slave(int cpu);
24744 +void IPI_handler(int cpu)
24749 + fd = cpu_data[cpu].ipi_pipe[0];
24750 + while (read(fd, &c, 1) == 1) {
24753 + smp_call_function_slave(cpu);
24757 + current->need_resched = 1;
24761 + printk("CPU#%d stopping\n", cpu);
24767 + printk("CPU#%d received unknown IPI [%c]!\n", cpu, c);
24773 +int hard_smp_processor_id(void)
24775 + return(pid_to_processor_id(os_getpid()));
24778 +static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
24779 +static atomic_t scf_started;
24780 +static atomic_t scf_finished;
24781 +static void (*func)(void *info);
24782 +static void *info;
24784 +void smp_call_function_slave(int cpu)
24786 + atomic_inc(&scf_started);
24788 + atomic_inc(&scf_finished);
24791 +int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic,
24794 + int cpus = smp_num_cpus - 1;
24800 + spin_lock_bh(&call_lock);
24801 + atomic_set(&scf_started, 0);
24802 + atomic_set(&scf_finished, 0);
24806 + for (i=0;i<NR_CPUS;i++)
24807 + if (i != current->processor && test_bit(i, &cpu_online_map))
24808 + write(cpu_data[i].ipi_pipe[1], "C", 1);
24810 + while (atomic_read(&scf_started) != cpus)
24814 + while (atomic_read(&scf_finished) != cpus)
24817 + spin_unlock_bh(&call_lock);
24824 + * Overrides for Emacs so that we follow Linus's tabbing style.
24825 + * Emacs will notice this stuff at the end of the file and automatically
24826 + * adjust the settings for this buffer only. This must remain at the end
24828 + * ---------------------------------------------------------------------------
24829 + * Local variables:
24830 + * c-file-style: "linux"
24833 diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_kern.c um/arch/um/kernel/syscall_kern.c
24834 --- orig/arch/um/kernel/syscall_kern.c 1969-12-31 19:00:00.000000000 -0500
24835 +++ um/arch/um/kernel/syscall_kern.c 2002-11-08 14:04:10.000000000 -0500
24838 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
24839 + * Licensed under the GPL
24842 +#include "linux/sched.h"
24843 +#include "linux/file.h"
24844 +#include "linux/smp_lock.h"
24845 +#include "linux/mm.h"
24846 +#include "linux/utsname.h"
24847 +#include "linux/msg.h"
24848 +#include "linux/shm.h"
24849 +#include "linux/sys.h"
24850 +#include "linux/unistd.h"
24851 +#include "linux/slab.h"
24852 +#include "linux/utime.h"
24853 +#include "asm/mman.h"
24854 +#include "asm/uaccess.h"
24855 +#include "asm/ipc.h"
24856 +#include "kern_util.h"
24857 +#include "user_util.h"
24858 +#include "sysdep/syscalls.h"
24859 +#include "mode_kern.h"
24860 +#include "choose-mode.h"
24862 +/* Unlocked, I don't care if this is a bit off */
24863 +int nsyscalls = 0;
24865 +long um_mount(char * dev_name, char * dir_name, char * type,
24866 + unsigned long new_flags, void * data)
24868 + if(type == NULL) type = "";
24869 + return(sys_mount(dev_name, dir_name, type, new_flags, data));
24872 +long sys_fork(void)
24876 + current->thread.forking = 1;
24877 + ret = do_fork(SIGCHLD, 0, NULL, 0);
24878 + current->thread.forking = 0;
24882 +long sys_clone(unsigned long clone_flags, unsigned long newsp)
24886 + current->thread.forking = 1;
24887 + ret = do_fork(clone_flags, newsp, NULL, 0);
24888 + current->thread.forking = 0;
24892 +long sys_vfork(void)
24896 + current->thread.forking = 1;
24897 + ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0);
24898 + current->thread.forking = 0;
24902 +/* common code for old and new mmaps */
24903 +long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
24904 + unsigned long prot, unsigned long flags, unsigned long fd,
24905 + unsigned long pgoff)
24907 + int error = -EBADF;
24908 + struct file * file = NULL;
24910 + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
24911 + if (!(flags & MAP_ANONYMOUS)) {
24917 + down_write(&mm->mmap_sem);
24918 + error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
24919 + up_write(&mm->mmap_sem);
24927 +long sys_mmap2(unsigned long addr, unsigned long len,
24928 + unsigned long prot, unsigned long flags,
24929 + unsigned long fd, unsigned long pgoff)
24931 + return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
24935 + * Perform the select(nd, in, out, ex, tv) and mmap() system
24936 + * calls. Linux/i386 didn't use to be able to handle more than
24937 + * 4 system call parameters, so these system calls used a memory
24938 + * block for parameter passing..
24941 +struct mmap_arg_struct {
24942 + unsigned long addr;
24943 + unsigned long len;
24944 + unsigned long prot;
24945 + unsigned long flags;
24946 + unsigned long fd;
24947 + unsigned long offset;
24950 +int old_mmap(unsigned long addr, unsigned long len,
24951 + unsigned long prot, unsigned long flags,
24952 + unsigned long fd, unsigned long offset)
24954 + int err = -EINVAL;
24955 + if (offset & ~PAGE_MASK)
24958 + err = do_mmap2(current->mm, addr, len, prot, flags, fd,
24959 + offset >> PAGE_SHIFT);
24964 + * sys_pipe() is the normal C calling standard for creating
24965 + * a pipe. It's not the way unix traditionally does this, though.
24967 +int sys_pipe(unsigned long * fildes)
24972 + error = do_pipe(fd);
24974 + if (copy_to_user(fildes, fd, 2*sizeof(int)))
24980 +int sys_pause(void)
24982 + current->state = TASK_INTERRUPTIBLE;
24984 + return -ERESTARTNOHAND;
24987 +int sys_sigaction(int sig, const struct old_sigaction *act,
24988 + struct old_sigaction *oact)
24990 + struct k_sigaction new_ka, old_ka;
24994 + old_sigset_t mask;
24995 + if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
24996 + __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
24997 + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
24999 + __get_user(new_ka.sa.sa_flags, &act->sa_flags);
25000 + __get_user(mask, &act->sa_mask);
25001 + siginitset(&new_ka.sa.sa_mask, mask);
25004 + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
25006 + if (!ret && oact) {
25007 + if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
25008 + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
25009 + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
25011 + __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
25012 + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
25019 + * sys_ipc() is the de-multiplexer for the SysV IPC calls..
25021 + * This is really horribly ugly.
25023 +int sys_ipc (uint call, int first, int second,
25024 + int third, void *ptr, long fifth)
25026 + int version, ret;
25028 + version = call >> 16; /* hack for backward compatibility */
25033 + return sys_semop (first, (struct sembuf *)ptr, second);
25035 + return sys_semget (first, second, third);
25037 + union semun fourth;
25040 + if (get_user(fourth.__pad, (void **) ptr))
25042 + return sys_semctl (first, second, third, fourth);
25046 + return sys_msgsnd (first, (struct msgbuf *) ptr,
25049 + switch (version) {
25051 + struct ipc_kludge tmp;
25055 + if (copy_from_user(&tmp,
25056 + (struct ipc_kludge *) ptr,
25059 + return sys_msgrcv (first, tmp.msgp, second,
25060 + tmp.msgtyp, third);
25063 + panic("msgrcv with version != 0");
25064 + return sys_msgrcv (first,
25065 + (struct msgbuf *) ptr,
25066 + second, fifth, third);
25069 + return sys_msgget ((key_t) first, second);
25071 + return sys_msgctl (first, second, (struct msqid_ds *) ptr);
25074 + switch (version) {
25077 + ret = sys_shmat (first, (char *) ptr, second, &raddr);
25080 + return put_user (raddr, (ulong *) third);
25082 + case 1: /* iBCS2 emulator entry point */
25083 + if (!segment_eq(get_fs(), get_ds()))
25085 + return sys_shmat (first, (char *) ptr, second, (ulong *) third);
25088 + return sys_shmdt ((char *)ptr);
25090 + return sys_shmget (first, second, third);
25092 + return sys_shmctl (first, second,
25093 + (struct shmid_ds *) ptr);
25099 +int sys_uname(struct old_utsname * name)
25104 + down_read(&uts_sem);
25105 + err=copy_to_user(name, &system_utsname, sizeof (*name));
25106 + up_read(&uts_sem);
25107 + return err?-EFAULT:0;
25110 +int sys_olduname(struct oldold_utsname * name)
25116 + if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
25119 + down_read(&uts_sem);
25121 + error = __copy_to_user(&name->sysname,&system_utsname.sysname,
25123 + error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
25124 + error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
25126 + error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
25127 + error |= __copy_to_user(&name->release,&system_utsname.release,
25129 + error |= __put_user(0,name->release+__OLD_UTS_LEN);
25130 + error |= __copy_to_user(&name->version,&system_utsname.version,
25132 + error |= __put_user(0,name->version+__OLD_UTS_LEN);
25133 + error |= __copy_to_user(&name->machine,&system_utsname.machine,
25135 + error |= __put_user(0,name->machine+__OLD_UTS_LEN);
25137 + up_read(&uts_sem);
25139 + error = error ? -EFAULT : 0;
25144 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
25146 + return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
25149 +long execute_syscall(void *r)
25151 + return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
25154 +spinlock_t syscall_lock = SPIN_LOCK_UNLOCKED;
25156 +static int syscall_index = 0;
25158 +int next_syscall_index(int limit)
25162 + spin_lock(&syscall_lock);
25163 + ret = syscall_index;
25164 + if(++syscall_index == limit)
25165 + syscall_index = 0;
25166 + spin_unlock(&syscall_lock);
25171 + * Overrides for Emacs so that we follow Linus's tabbing style.
25172 + * Emacs will notice this stuff at the end of the file and automatically
25173 + * adjust the settings for this buffer only. This must remain at the end
25175 + * ---------------------------------------------------------------------------
25176 + * Local variables:
25177 + * c-file-style: "linux"
25180 diff -Naur -X ../exclude-files orig/arch/um/kernel/sys_call_table.c um/arch/um/kernel/sys_call_table.c
25181 --- orig/arch/um/kernel/sys_call_table.c 1969-12-31 19:00:00.000000000 -0500
25182 +++ um/arch/um/kernel/sys_call_table.c 2003-02-27 13:33:23.000000000 -0500
25185 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
25186 + * Licensed under the GPL
25189 +#include "linux/unistd.h"
25190 +#include "linux/version.h"
25191 +#include "linux/sys.h"
25192 +#include "asm/signal.h"
25193 +#include "sysdep/syscalls.h"
25194 +#include "kern_util.h"
25196 +extern syscall_handler_t sys_ni_syscall;
25197 +extern syscall_handler_t sys_exit;
25198 +extern syscall_handler_t sys_fork;
25199 +extern syscall_handler_t sys_creat;
25200 +extern syscall_handler_t sys_link;
25201 +extern syscall_handler_t sys_unlink;
25202 +extern syscall_handler_t sys_chdir;
25203 +extern syscall_handler_t sys_mknod;
25204 +extern syscall_handler_t sys_chmod;
25205 +extern syscall_handler_t sys_lchown16;
25206 +extern syscall_handler_t sys_ni_syscall;
25207 +extern syscall_handler_t sys_stat;
25208 +extern syscall_handler_t sys_getpid;
25209 +extern syscall_handler_t sys_oldumount;
25210 +extern syscall_handler_t sys_setuid16;
25211 +extern syscall_handler_t sys_getuid16;
25212 +extern syscall_handler_t sys_ptrace;
25213 +extern syscall_handler_t sys_alarm;
25214 +extern syscall_handler_t sys_fstat;
25215 +extern syscall_handler_t sys_pause;
25216 +extern syscall_handler_t sys_utime;
25217 +extern syscall_handler_t sys_ni_syscall;
25218 +extern syscall_handler_t sys_ni_syscall;
25219 +extern syscall_handler_t sys_access;
25220 +extern syscall_handler_t sys_nice;
25221 +extern syscall_handler_t sys_ni_syscall;
25222 +extern syscall_handler_t sys_sync;
25223 +extern syscall_handler_t sys_kill;
25224 +extern syscall_handler_t sys_rename;
25225 +extern syscall_handler_t sys_mkdir;
25226 +extern syscall_handler_t sys_rmdir;
25227 +extern syscall_handler_t sys_pipe;
25228 +extern syscall_handler_t sys_times;
25229 +extern syscall_handler_t sys_ni_syscall;
25230 +extern syscall_handler_t sys_brk;
25231 +extern syscall_handler_t sys_setgid16;
25232 +extern syscall_handler_t sys_getgid16;
25233 +extern syscall_handler_t sys_signal;
25234 +extern syscall_handler_t sys_geteuid16;
25235 +extern syscall_handler_t sys_getegid16;
25236 +extern syscall_handler_t sys_acct;
25237 +extern syscall_handler_t sys_umount;
25238 +extern syscall_handler_t sys_ni_syscall;
25239 +extern syscall_handler_t sys_ioctl;
25240 +extern syscall_handler_t sys_fcntl;
25241 +extern syscall_handler_t sys_ni_syscall;
25242 +extern syscall_handler_t sys_setpgid;
25243 +extern syscall_handler_t sys_ni_syscall;
25244 +extern syscall_handler_t sys_olduname;
25245 +extern syscall_handler_t sys_umask;
25246 +extern syscall_handler_t sys_chroot;
25247 +extern syscall_handler_t sys_ustat;
25248 +extern syscall_handler_t sys_dup2;
25249 +extern syscall_handler_t sys_getppid;
25250 +extern syscall_handler_t sys_getpgrp;
25251 +extern syscall_handler_t sys_sigaction;
25252 +extern syscall_handler_t sys_sgetmask;
25253 +extern syscall_handler_t sys_ssetmask;
25254 +extern syscall_handler_t sys_setreuid16;
25255 +extern syscall_handler_t sys_setregid16;
25256 +extern syscall_handler_t sys_sigsuspend;
25257 +extern syscall_handler_t sys_sigpending;
25258 +extern syscall_handler_t sys_sethostname;
25259 +extern syscall_handler_t sys_setrlimit;
25260 +extern syscall_handler_t sys_old_getrlimit;
25261 +extern syscall_handler_t sys_getrusage;
25262 +extern syscall_handler_t sys_gettimeofday;
25263 +extern syscall_handler_t sys_settimeofday;
25264 +extern syscall_handler_t sys_getgroups16;
25265 +extern syscall_handler_t sys_setgroups16;
25266 +extern syscall_handler_t sys_symlink;
25267 +extern syscall_handler_t sys_lstat;
25268 +extern syscall_handler_t sys_readlink;
25269 +extern syscall_handler_t sys_uselib;
25270 +extern syscall_handler_t sys_swapon;
25271 +extern syscall_handler_t sys_reboot;
25272 +extern syscall_handler_t old_readdir;
25273 +extern syscall_handler_t sys_munmap;
25274 +extern syscall_handler_t sys_truncate;
25275 +extern syscall_handler_t sys_ftruncate;
25276 +extern syscall_handler_t sys_fchmod;
25277 +extern syscall_handler_t sys_fchown16;
25278 +extern syscall_handler_t sys_getpriority;
25279 +extern syscall_handler_t sys_setpriority;
25280 +extern syscall_handler_t sys_ni_syscall;
25281 +extern syscall_handler_t sys_statfs;
25282 +extern syscall_handler_t sys_fstatfs;
25283 +extern syscall_handler_t sys_ni_syscall;
25284 +extern syscall_handler_t sys_socketcall;
25285 +extern syscall_handler_t sys_syslog;
25286 +extern syscall_handler_t sys_setitimer;
25287 +extern syscall_handler_t sys_getitimer;
25288 +extern syscall_handler_t sys_newstat;
25289 +extern syscall_handler_t sys_newlstat;
25290 +extern syscall_handler_t sys_newfstat;
25291 +extern syscall_handler_t sys_uname;
25292 +extern syscall_handler_t sys_ni_syscall;
25293 +extern syscall_handler_t sys_vhangup;
25294 +extern syscall_handler_t sys_ni_syscall;
25295 +extern syscall_handler_t sys_ni_syscall;
25296 +extern syscall_handler_t sys_swapoff;
25297 +extern syscall_handler_t sys_sysinfo;
25298 +extern syscall_handler_t sys_ipc;
25299 +extern syscall_handler_t sys_fsync;
25300 +extern syscall_handler_t sys_sigreturn;
25301 +extern syscall_handler_t sys_rt_sigreturn;
25302 +extern syscall_handler_t sys_clone;
25303 +extern syscall_handler_t sys_setdomainname;
25304 +extern syscall_handler_t sys_newuname;
25305 +extern syscall_handler_t sys_ni_syscall;
25306 +extern syscall_handler_t sys_adjtimex;
25307 +extern syscall_handler_t sys_mprotect;
25308 +extern syscall_handler_t sys_sigprocmask;
25309 +extern syscall_handler_t sys_create_module;
25310 +extern syscall_handler_t sys_init_module;
25311 +extern syscall_handler_t sys_delete_module;
25312 +extern syscall_handler_t sys_get_kernel_syms;
25313 +extern syscall_handler_t sys_quotactl;
25314 +extern syscall_handler_t sys_getpgid;
25315 +extern syscall_handler_t sys_fchdir;
25316 +extern syscall_handler_t sys_bdflush;
25317 +extern syscall_handler_t sys_sysfs;
25318 +extern syscall_handler_t sys_personality;
25319 +extern syscall_handler_t sys_ni_syscall;
25320 +extern syscall_handler_t sys_setfsuid16;
25321 +extern syscall_handler_t sys_setfsgid16;
25322 +extern syscall_handler_t sys_llseek;
25323 +extern syscall_handler_t sys_getdents;
25324 +extern syscall_handler_t sys_flock;
25325 +extern syscall_handler_t sys_msync;
25326 +extern syscall_handler_t sys_readv;
25327 +extern syscall_handler_t sys_writev;
25328 +extern syscall_handler_t sys_getsid;
25329 +extern syscall_handler_t sys_fdatasync;
25330 +extern syscall_handler_t sys_sysctl;
25331 +extern syscall_handler_t sys_mlock;
25332 +extern syscall_handler_t sys_munlock;
25333 +extern syscall_handler_t sys_mlockall;
25334 +extern syscall_handler_t sys_munlockall;
25335 +extern syscall_handler_t sys_sched_setparam;
25336 +extern syscall_handler_t sys_sched_getparam;
25337 +extern syscall_handler_t sys_sched_setscheduler;
25338 +extern syscall_handler_t sys_sched_getscheduler;
25339 +extern syscall_handler_t sys_sched_get_priority_max;
25340 +extern syscall_handler_t sys_sched_get_priority_min;
25341 +extern syscall_handler_t sys_sched_rr_get_interval;
25342 +extern syscall_handler_t sys_nanosleep;
25343 +extern syscall_handler_t sys_mremap;
25344 +extern syscall_handler_t sys_setresuid16;
25345 +extern syscall_handler_t sys_getresuid16;
25346 +extern syscall_handler_t sys_ni_syscall;
25347 +extern syscall_handler_t sys_query_module;
25348 +extern syscall_handler_t sys_poll;
25349 +extern syscall_handler_t sys_nfsservctl;
25350 +extern syscall_handler_t sys_setresgid16;
25351 +extern syscall_handler_t sys_getresgid16;
25352 +extern syscall_handler_t sys_prctl;
25353 +extern syscall_handler_t sys_ni_syscall;
25354 +extern syscall_handler_t sys_rt_sigaction;
25355 +extern syscall_handler_t sys_rt_sigprocmask;
25356 +extern syscall_handler_t sys_rt_sigpending;
25357 +extern syscall_handler_t sys_rt_sigtimedwait;
25358 +extern syscall_handler_t sys_rt_sigqueueinfo;
25359 +extern syscall_handler_t sys_rt_sigsuspend;
25360 +extern syscall_handler_t sys_pread;
25361 +extern syscall_handler_t sys_pwrite;
25362 +extern syscall_handler_t sys_chown16;
25363 +extern syscall_handler_t sys_getcwd;
25364 +extern syscall_handler_t sys_capget;
25365 +extern syscall_handler_t sys_capset;
25366 +extern syscall_handler_t sys_sigaltstack;
25367 +extern syscall_handler_t sys_sendfile;
25368 +extern syscall_handler_t sys_ni_syscall;
25369 +extern syscall_handler_t sys_ni_syscall;
25370 +extern syscall_handler_t sys_vfork;
25371 +extern syscall_handler_t sys_getrlimit;
25372 +extern syscall_handler_t sys_mmap2;
25373 +extern syscall_handler_t sys_truncate64;
25374 +extern syscall_handler_t sys_ftruncate64;
25375 +extern syscall_handler_t sys_stat64;
25376 +extern syscall_handler_t sys_lstat64;
25377 +extern syscall_handler_t sys_fstat64;
25378 +extern syscall_handler_t sys_lchown;
25379 +extern syscall_handler_t sys_getuid;
25380 +extern syscall_handler_t sys_getgid;
25381 +extern syscall_handler_t sys_geteuid;
25382 +extern syscall_handler_t sys_getegid;
25383 +extern syscall_handler_t sys_setreuid;
25384 +extern syscall_handler_t sys_setregid;
25385 +extern syscall_handler_t sys_getgroups;
25386 +extern syscall_handler_t sys_setgroups;
25387 +extern syscall_handler_t sys_fchown;
25388 +extern syscall_handler_t sys_setresuid;
25389 +extern syscall_handler_t sys_getresuid;
25390 +extern syscall_handler_t sys_setresgid;
25391 +extern syscall_handler_t sys_getresgid;
25392 +extern syscall_handler_t sys_chown;
25393 +extern syscall_handler_t sys_setuid;
25394 +extern syscall_handler_t sys_setgid;
25395 +extern syscall_handler_t sys_setfsuid;
25396 +extern syscall_handler_t sys_setfsgid;
25397 +extern syscall_handler_t sys_pivot_root;
25398 +extern syscall_handler_t sys_mincore;
25399 +extern syscall_handler_t sys_madvise;
25400 +extern syscall_handler_t sys_fcntl64;
25401 +extern syscall_handler_t sys_getdents64;
25402 +extern syscall_handler_t sys_gettid;
25403 +extern syscall_handler_t sys_readahead;
25404 +extern syscall_handler_t sys_tkill;
25405 +extern syscall_handler_t sys_setxattr;
25406 +extern syscall_handler_t sys_lsetxattr;
25407 +extern syscall_handler_t sys_fsetxattr;
25408 +extern syscall_handler_t sys_getxattr;
25409 +extern syscall_handler_t sys_lgetxattr;
25410 +extern syscall_handler_t sys_fgetxattr;
25411 +extern syscall_handler_t sys_listxattr;
25412 +extern syscall_handler_t sys_llistxattr;
25413 +extern syscall_handler_t sys_flistxattr;
25414 +extern syscall_handler_t sys_removexattr;
25415 +extern syscall_handler_t sys_lremovexattr;
25416 +extern syscall_handler_t sys_fremovexattr;
25418 +extern syscall_handler_t um_mount;
25419 +extern syscall_handler_t um_time;
25420 +extern syscall_handler_t um_stime;
25422 +#define LAST_GENERIC_SYSCALL __NR_sched_getaffinity
25424 +#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
25425 +#define LAST_SYSCALL LAST_GENERIC_SYSCALL
25427 +#define LAST_SYSCALL LAST_ARCH_SYSCALL
25430 +syscall_handler_t *sys_call_table[] = {
25431 + [ 0 ] = sys_ni_syscall,
25432 + [ __NR_exit ] = sys_exit,
25433 + [ __NR_fork ] = sys_fork,
25434 + [ __NR_read ] = (syscall_handler_t *) sys_read,
25435 + [ __NR_write ] = (syscall_handler_t *) sys_write,
25437 + /* These three are declared differently in asm/unistd.h */
25438 + [ __NR_open ] = (syscall_handler_t *) sys_open,
25439 + [ __NR_close ] = (syscall_handler_t *) sys_close,
25440 + [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid,
25441 + [ __NR_creat ] = sys_creat,
25442 + [ __NR_link ] = sys_link,
25443 + [ __NR_unlink ] = sys_unlink,
25445 + /* declared differently in kern_util.h */
25446 + [ __NR_execve ] = (syscall_handler_t *) sys_execve,
25447 + [ __NR_chdir ] = sys_chdir,
25448 + [ __NR_time ] = um_time,
25449 + [ __NR_mknod ] = sys_mknod,
25450 + [ __NR_chmod ] = sys_chmod,
25451 + [ __NR_lchown ] = sys_lchown16,
25452 + [ __NR_break ] = sys_ni_syscall,
25453 + [ __NR_oldstat ] = sys_stat,
25454 + [ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
25455 + [ __NR_getpid ] = sys_getpid,
25456 + [ __NR_mount ] = um_mount,
25457 + [ __NR_umount ] = sys_oldumount,
25458 + [ __NR_setuid ] = sys_setuid16,
25459 + [ __NR_getuid ] = sys_getuid16,
25460 + [ __NR_stime ] = um_stime,
25461 + [ __NR_ptrace ] = sys_ptrace,
25462 + [ __NR_alarm ] = sys_alarm,
25463 + [ __NR_oldfstat ] = sys_fstat,
25464 + [ __NR_pause ] = sys_pause,
25465 + [ __NR_utime ] = sys_utime,
25466 + [ __NR_stty ] = sys_ni_syscall,
25467 + [ __NR_gtty ] = sys_ni_syscall,
25468 + [ __NR_access ] = sys_access,
25469 + [ __NR_nice ] = sys_nice,
25470 + [ __NR_ftime ] = sys_ni_syscall,
25471 + [ __NR_sync ] = sys_sync,
25472 + [ __NR_kill ] = sys_kill,
25473 + [ __NR_rename ] = sys_rename,
25474 + [ __NR_mkdir ] = sys_mkdir,
25475 + [ __NR_rmdir ] = sys_rmdir,
25477 + /* Declared differently in asm/unistd.h */
25478 + [ __NR_dup ] = (syscall_handler_t *) sys_dup,
25479 + [ __NR_pipe ] = sys_pipe,
25480 + [ __NR_times ] = sys_times,
25481 + [ __NR_prof ] = sys_ni_syscall,
25482 + [ __NR_brk ] = sys_brk,
25483 + [ __NR_setgid ] = sys_setgid16,
25484 + [ __NR_getgid ] = sys_getgid16,
25485 + [ __NR_signal ] = sys_signal,
25486 + [ __NR_geteuid ] = sys_geteuid16,
25487 + [ __NR_getegid ] = sys_getegid16,
25488 + [ __NR_acct ] = sys_acct,
25489 + [ __NR_umount2 ] = sys_umount,
25490 + [ __NR_lock ] = sys_ni_syscall,
25491 + [ __NR_ioctl ] = sys_ioctl,
25492 + [ __NR_fcntl ] = sys_fcntl,
25493 + [ __NR_mpx ] = sys_ni_syscall,
25494 + [ __NR_setpgid ] = sys_setpgid,
25495 + [ __NR_ulimit ] = sys_ni_syscall,
25496 + [ __NR_oldolduname ] = sys_olduname,
25497 + [ __NR_umask ] = sys_umask,
25498 + [ __NR_chroot ] = sys_chroot,
25499 + [ __NR_ustat ] = sys_ustat,
25500 + [ __NR_dup2 ] = sys_dup2,
25501 + [ __NR_getppid ] = sys_getppid,
25502 + [ __NR_getpgrp ] = sys_getpgrp,
25503 + [ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
25504 + [ __NR_sigaction ] = sys_sigaction,
25505 + [ __NR_sgetmask ] = sys_sgetmask,
25506 + [ __NR_ssetmask ] = sys_ssetmask,
25507 + [ __NR_setreuid ] = sys_setreuid16,
25508 + [ __NR_setregid ] = sys_setregid16,
25509 + [ __NR_sigsuspend ] = sys_sigsuspend,
25510 + [ __NR_sigpending ] = sys_sigpending,
25511 + [ __NR_sethostname ] = sys_sethostname,
25512 + [ __NR_setrlimit ] = sys_setrlimit,
25513 + [ __NR_getrlimit ] = sys_old_getrlimit,
25514 + [ __NR_getrusage ] = sys_getrusage,
25515 + [ __NR_gettimeofday ] = sys_gettimeofday,
25516 + [ __NR_settimeofday ] = sys_settimeofday,
25517 + [ __NR_getgroups ] = sys_getgroups16,
25518 + [ __NR_setgroups ] = sys_setgroups16,
25519 + [ __NR_symlink ] = sys_symlink,
25520 + [ __NR_oldlstat ] = sys_lstat,
25521 + [ __NR_readlink ] = sys_readlink,
25522 + [ __NR_uselib ] = sys_uselib,
25523 + [ __NR_swapon ] = sys_swapon,
25524 + [ __NR_reboot ] = sys_reboot,
25525 + [ __NR_readdir ] = old_readdir,
25526 + [ __NR_munmap ] = sys_munmap,
25527 + [ __NR_truncate ] = sys_truncate,
25528 + [ __NR_ftruncate ] = sys_ftruncate,
25529 + [ __NR_fchmod ] = sys_fchmod,
25530 + [ __NR_fchown ] = sys_fchown16,
25531 + [ __NR_getpriority ] = sys_getpriority,
25532 + [ __NR_setpriority ] = sys_setpriority,
25533 + [ __NR_profil ] = sys_ni_syscall,
25534 + [ __NR_statfs ] = sys_statfs,
25535 + [ __NR_fstatfs ] = sys_fstatfs,
25536 + [ __NR_ioperm ] = sys_ni_syscall,
25537 + [ __NR_socketcall ] = sys_socketcall,
25538 + [ __NR_syslog ] = sys_syslog,
25539 + [ __NR_setitimer ] = sys_setitimer,
25540 + [ __NR_getitimer ] = sys_getitimer,
25541 + [ __NR_stat ] = sys_newstat,
25542 + [ __NR_lstat ] = sys_newlstat,
25543 + [ __NR_fstat ] = sys_newfstat,
25544 + [ __NR_olduname ] = sys_uname,
25545 + [ __NR_iopl ] = sys_ni_syscall,
25546 + [ __NR_vhangup ] = sys_vhangup,
25547 + [ __NR_idle ] = sys_ni_syscall,
25548 + [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
25549 + [ __NR_swapoff ] = sys_swapoff,
25550 + [ __NR_sysinfo ] = sys_sysinfo,
25551 + [ __NR_ipc ] = sys_ipc,
25552 + [ __NR_fsync ] = sys_fsync,
25553 + [ __NR_sigreturn ] = sys_sigreturn,
25554 + [ __NR_clone ] = sys_clone,
25555 + [ __NR_setdomainname ] = sys_setdomainname,
25556 + [ __NR_uname ] = sys_newuname,
25557 + [ __NR_adjtimex ] = sys_adjtimex,
25558 + [ __NR_mprotect ] = sys_mprotect,
25559 + [ __NR_sigprocmask ] = sys_sigprocmask,
25560 + [ __NR_create_module ] = sys_create_module,
25561 + [ __NR_init_module ] = sys_init_module,
25562 + [ __NR_delete_module ] = sys_delete_module,
25563 + [ __NR_get_kernel_syms ] = sys_get_kernel_syms,
25564 + [ __NR_quotactl ] = sys_quotactl,
25565 + [ __NR_getpgid ] = sys_getpgid,
25566 + [ __NR_fchdir ] = sys_fchdir,
25567 + [ __NR_bdflush ] = sys_bdflush,
25568 + [ __NR_sysfs ] = sys_sysfs,
25569 + [ __NR_personality ] = sys_personality,
25570 + [ __NR_afs_syscall ] = sys_ni_syscall,
25571 + [ __NR_setfsuid ] = sys_setfsuid16,
25572 + [ __NR_setfsgid ] = sys_setfsgid16,
25573 + [ __NR__llseek ] = sys_llseek,
25574 + [ __NR_getdents ] = sys_getdents,
25575 + [ __NR__newselect ] = (syscall_handler_t *) sys_select,
25576 + [ __NR_flock ] = sys_flock,
25577 + [ __NR_msync ] = sys_msync,
25578 + [ __NR_readv ] = sys_readv,
25579 + [ __NR_writev ] = sys_writev,
25580 + [ __NR_getsid ] = sys_getsid,
25581 + [ __NR_fdatasync ] = sys_fdatasync,
25582 + [ __NR__sysctl ] = sys_sysctl,
25583 + [ __NR_mlock ] = sys_mlock,
25584 + [ __NR_munlock ] = sys_munlock,
25585 + [ __NR_mlockall ] = sys_mlockall,
25586 + [ __NR_munlockall ] = sys_munlockall,
25587 + [ __NR_sched_setparam ] = sys_sched_setparam,
25588 + [ __NR_sched_getparam ] = sys_sched_getparam,
25589 + [ __NR_sched_setscheduler ] = sys_sched_setscheduler,
25590 + [ __NR_sched_getscheduler ] = sys_sched_getscheduler,
25591 + [ __NR_sched_yield ] = (syscall_handler_t *) yield,
25592 + [ __NR_sched_get_priority_max ] = sys_sched_get_priority_max,
25593 + [ __NR_sched_get_priority_min ] = sys_sched_get_priority_min,
25594 + [ __NR_sched_rr_get_interval ] = sys_sched_rr_get_interval,
25595 + [ __NR_nanosleep ] = sys_nanosleep,
25596 + [ __NR_mremap ] = sys_mremap,
25597 + [ __NR_setresuid ] = sys_setresuid16,
25598 + [ __NR_getresuid ] = sys_getresuid16,
25599 + [ __NR_vm86 ] = sys_ni_syscall,
25600 + [ __NR_query_module ] = sys_query_module,
25601 + [ __NR_poll ] = sys_poll,
25602 + [ __NR_nfsservctl ] = sys_nfsservctl,
25603 + [ __NR_setresgid ] = sys_setresgid16,
25604 + [ __NR_getresgid ] = sys_getresgid16,
25605 + [ __NR_prctl ] = sys_prctl,
25606 + [ __NR_rt_sigreturn ] = sys_rt_sigreturn,
25607 + [ __NR_rt_sigaction ] = sys_rt_sigaction,
25608 + [ __NR_rt_sigprocmask ] = sys_rt_sigprocmask,
25609 + [ __NR_rt_sigpending ] = sys_rt_sigpending,
25610 + [ __NR_rt_sigtimedwait ] = sys_rt_sigtimedwait,
25611 + [ __NR_rt_sigqueueinfo ] = sys_rt_sigqueueinfo,
25612 + [ __NR_rt_sigsuspend ] = sys_rt_sigsuspend,
25613 + [ __NR_pread ] = sys_pread,
25614 + [ __NR_pwrite ] = sys_pwrite,
25615 + [ __NR_chown ] = sys_chown16,
25616 + [ __NR_getcwd ] = sys_getcwd,
25617 + [ __NR_capget ] = sys_capget,
25618 + [ __NR_capset ] = sys_capset,
25619 + [ __NR_sigaltstack ] = sys_sigaltstack,
25620 + [ __NR_sendfile ] = sys_sendfile,
25621 + [ __NR_getpmsg ] = sys_ni_syscall,
25622 + [ __NR_putpmsg ] = sys_ni_syscall,
25623 + [ __NR_vfork ] = sys_vfork,
25624 + [ __NR_ugetrlimit ] = sys_getrlimit,
25625 + [ __NR_mmap2 ] = sys_mmap2,
25626 + [ __NR_truncate64 ] = sys_truncate64,
25627 + [ __NR_ftruncate64 ] = sys_ftruncate64,
25628 + [ __NR_stat64 ] = sys_stat64,
25629 + [ __NR_lstat64 ] = sys_lstat64,
25630 + [ __NR_fstat64 ] = sys_fstat64,
25631 + [ __NR_fcntl64 ] = sys_fcntl64,
25632 + [ __NR_getdents64 ] = sys_getdents64,
25633 + [ __NR_security ] = sys_ni_syscall,
25634 + [ __NR_gettid ] = sys_gettid,
25635 + [ __NR_readahead ] = sys_readahead,
25636 + [ __NR_setxattr ] = sys_setxattr,
25637 + [ __NR_lsetxattr ] = sys_lsetxattr,
25638 + [ __NR_fsetxattr ] = sys_fsetxattr,
25639 + [ __NR_getxattr ] = sys_getxattr,
25640 + [ __NR_lgetxattr ] = sys_lgetxattr,
25641 + [ __NR_fgetxattr ] = sys_fgetxattr,
25642 + [ __NR_listxattr ] = sys_listxattr,
25643 + [ __NR_llistxattr ] = sys_llistxattr,
25644 + [ __NR_flistxattr ] = sys_flistxattr,
25645 + [ __NR_removexattr ] = sys_removexattr,
25646 + [ __NR_lremovexattr ] = sys_lremovexattr,
25647 + [ __NR_fremovexattr ] = sys_fremovexattr,
25648 + [ __NR_tkill ] = sys_tkill,
25649 + [ __NR_sendfile64 ] = sys_ni_syscall,
25650 + [ __NR_futex ] = sys_ni_syscall,
25651 + [ __NR_sched_setaffinity ] = sys_ni_syscall,
25652 + [ __NR_sched_getaffinity ] = sys_ni_syscall,
25655 + [ LAST_SYSCALL + 1 ... NR_syscalls ] =
25656 + (syscall_handler_t *) sys_ni_syscall
25660 + * Overrides for Emacs so that we follow Linus's tabbing style.
25661 + * Emacs will notice this stuff at the end of the file and automatically
25662 + * adjust the settings for this buffer only. This must remain at the end
25664 + * ---------------------------------------------------------------------------
25665 + * Local variables:
25666 + * c-file-style: "linux"
25669 diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_user.c um/arch/um/kernel/syscall_user.c
25670 --- orig/arch/um/kernel/syscall_user.c 1969-12-31 19:00:00.000000000 -0500
25671 +++ um/arch/um/kernel/syscall_user.c 2002-10-23 21:08:04.000000000 -0400
25674 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25675 + * Licensed under the GPL
25678 +#include <stdlib.h>
25679 +#include <sys/time.h>
25680 +#include "kern_util.h"
25681 +#include "syscall_user.h"
25687 + struct timeval start;
25688 + struct timeval end;
25689 +} syscall_record[1024];
25691 +int record_syscall_start(int syscall)
25695 + max = sizeof(syscall_record)/sizeof(syscall_record[0]);
25696 + index = next_syscall_index(max);
25698 + syscall_record[index].syscall = syscall;
25699 + syscall_record[index].pid = current_pid();
25700 + syscall_record[index].result = 0xdeadbeef;
25701 + gettimeofday(&syscall_record[index].start, NULL);
25705 +void record_syscall_end(int index, int result)
25707 + syscall_record[index].result = result;
25708 + gettimeofday(&syscall_record[index].end, NULL);
25712 + * Overrides for Emacs so that we follow Linus's tabbing style.
25713 + * Emacs will notice this stuff at the end of the file and automatically
25714 + * adjust the settings for this buffer only. This must remain at the end
25716 + * ---------------------------------------------------------------------------
25717 + * Local variables:
25718 + * c-file-style: "linux"
25721 diff -Naur -X ../exclude-files orig/arch/um/kernel/sysrq.c um/arch/um/kernel/sysrq.c
25722 --- orig/arch/um/kernel/sysrq.c 1969-12-31 19:00:00.000000000 -0500
25723 +++ um/arch/um/kernel/sysrq.c 2002-10-23 21:08:04.000000000 -0400
25726 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
25727 + * Licensed under the GPL
25730 +#include "linux/sched.h"
25731 +#include "linux/kernel.h"
25732 +#include "linux/module.h"
25733 +#include "asm/page.h"
25734 +#include "asm/processor.h"
25735 +#include "sysrq.h"
25736 +#include "user_util.h"
25739 + * If the address is either in the .text section of the
25740 + * kernel, or in the vmalloc'ed module regions, it *may*
25741 + * be the address of a calling routine
25744 +#ifdef CONFIG_MODULES
25746 +extern struct module *module_list;
25747 +extern struct module kernel_module;
25749 +static inline int kernel_text_address(unsigned long addr)
25752 + struct module *mod;
25754 + if (addr >= (unsigned long) &_stext &&
25755 + addr <= (unsigned long) &_etext)
25758 + for (mod = module_list; mod != &kernel_module; mod = mod->next) {
25759 + /* mod_bound tests for addr being inside the vmalloc'ed
25760 + * module area. Of course it'd be better to test only
25761 + * for the .text subset... */
25762 + if (mod_bound(addr, 0, mod)) {
25773 +static inline int kernel_text_address(unsigned long addr)
25775 + return (addr >= (unsigned long) &_stext &&
25776 + addr <= (unsigned long) &_etext);
25781 +void show_trace(unsigned long * stack)
25784 + unsigned long addr;
25787 + stack = (unsigned long*) &stack;
25789 + printk("Call Trace: ");
25791 + while (((long) stack & (THREAD_SIZE-1)) != 0) {
25793 + if (kernel_text_address(addr)) {
25794 + if (i && ((i % 6) == 0))
25796 + printk("[<%08lx>] ", addr);
25803 +void show_trace_task(struct task_struct *tsk)
25805 + unsigned long esp = PT_REGS_SP(&tsk->thread.regs);
25807 + /* User space on another CPU? */
25808 + if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
25810 + show_trace((unsigned long *)esp);
25814 + * Overrides for Emacs so that we follow Linus's tabbing style.
25815 + * Emacs will notice this stuff at the end of the file and automatically
25816 + * adjust the settings for this buffer only. This must remain at the end
25818 + * ---------------------------------------------------------------------------
25819 + * Local variables:
25820 + * c-file-style: "linux"
25823 diff -Naur -X ../exclude-files orig/arch/um/kernel/tempfile.c um/arch/um/kernel/tempfile.c
25824 --- orig/arch/um/kernel/tempfile.c 1969-12-31 19:00:00.000000000 -0500
25825 +++ um/arch/um/kernel/tempfile.c 2003-01-17 23:16:19.000000000 -0500
25828 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25829 + * Licensed under the GPL
25832 +#include <stdio.h>
25833 +#include <stdlib.h>
25834 +#include <unistd.h>
25835 +#include <string.h>
25836 +#include <errno.h>
25837 +#include <sys/param.h>
25840 +/* Modified from create_mem_file and start_debugger */
25841 +static char *tempdir = NULL;
25843 +static void __init find_tempdir(void)
25845 + char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
25847 + char *dir = NULL;
25849 + if(tempdir != NULL) return; /* We've already been called */
25850 + for(i = 0; dirs[i]; i++){
25851 + dir = getenv(dirs[i]);
25852 + if((dir != NULL) && (*dir != '\0'))
25855 + if((dir == NULL) || (*dir == '\0'))
25858 + tempdir = malloc(strlen(dir) + 2);
25859 + if(tempdir == NULL){
25860 + fprintf(stderr, "Failed to malloc tempdir, "
25861 + "errno = %d\n", errno);
25864 + strcpy(tempdir, dir);
25865 + strcat(tempdir, "/");
25868 +int make_tempfile(const char *template, char **out_tempname, int do_unlink)
25870 + char tempname[MAXPATHLEN];
25874 + if (*template != '/')
25875 + strcpy(tempname, tempdir);
25878 + strcat(tempname, template);
25879 + if((fd = mkstemp(tempname)) < 0){
25880 + fprintf(stderr, "open - cannot create %s: %s\n", tempname,
25881 + strerror(errno));
25884 + if(do_unlink && (unlink(tempname) < 0)){
25885 + perror("unlink");
25888 + if(out_tempname){
25889 + if((*out_tempname = strdup(tempname)) == NULL){
25890 + perror("strdup");
25898 + * Overrides for Emacs so that we follow Linus's tabbing style.
25899 + * Emacs will notice this stuff at the end of the file and automatically
25900 + * adjust the settings for this buffer only. This must remain at the end
25902 + * ---------------------------------------------------------------------------
25903 + * Local variables:
25904 + * c-file-style: "linux"
25907 diff -Naur -X ../exclude-files orig/arch/um/kernel/time.c um/arch/um/kernel/time.c
25908 --- orig/arch/um/kernel/time.c 1969-12-31 19:00:00.000000000 -0500
25909 +++ um/arch/um/kernel/time.c 2003-04-23 20:45:19.000000000 -0400
25912 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
25913 + * Licensed under the GPL
25916 +#include <stdio.h>
25917 +#include <unistd.h>
25919 +#include <sys/time.h>
25920 +#include <signal.h>
25921 +#include <errno.h>
25922 +#include "user_util.h"
25923 +#include "kern_util.h"
25925 +#include "process.h"
25926 +#include "signal_user.h"
25927 +#include "time_user.h"
25929 +extern struct timeval xtime;
25931 +struct timeval local_offset = { 0, 0 };
25935 + gettimeofday(&xtime, NULL);
25936 + timeradd(&xtime, &local_offset, &xtime);
25939 +void set_interval(int timer_type)
25941 + int usec = 1000000/hz();
25942 + struct itimerval interval = ((struct itimerval) { { 0, usec },
25945 + if(setitimer(timer_type, &interval, NULL) == -1)
25946 + panic("setitimer failed - errno = %d\n", errno);
25949 +void enable_timer(void)
25951 + int usec = 1000000/hz();
25952 + struct itimerval enable = ((struct itimerval) { { 0, usec },
25954 + if(setitimer(ITIMER_VIRTUAL, &enable, NULL))
25955 + printk("enable_timer - setitimer failed, errno = %d\n",
25959 +void switch_timers(int to_real)
25961 + struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
25962 + struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
25963 + { 0, 1000000/hz() }});
25967 + old = ITIMER_VIRTUAL;
25968 + new = ITIMER_REAL;
25971 + old = ITIMER_REAL;
25972 + new = ITIMER_VIRTUAL;
25975 + if((setitimer(old, &disable, NULL) < 0) ||
25976 + (setitimer(new, &enable, NULL)))
25977 + printk("switch_timers - setitimer failed, errno = %d\n",
25981 +void idle_timer(void)
25983 + if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
25984 + panic("Couldn't unset SIGVTALRM handler");
25986 + set_handler(SIGALRM, (__sighandler_t) alarm_handler,
25987 + SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
25988 + set_interval(ITIMER_REAL);
25991 +void time_init(void)
25993 + if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
25994 + panic("Couldn't set SIGVTALRM handler");
25995 + set_interval(ITIMER_VIRTUAL);
25998 +void do_gettimeofday(struct timeval *tv)
26000 + unsigned long flags;
26002 + flags = time_lock();
26003 + gettimeofday(tv, NULL);
26004 + timeradd(tv, &local_offset, tv);
26005 + time_unlock(flags);
26008 +void do_settimeofday(struct timeval *tv)
26010 + struct timeval now;
26011 + unsigned long flags;
26013 + flags = time_lock();
26014 + gettimeofday(&now, NULL);
26015 + timersub(tv, &now, &local_offset);
26016 + time_unlock(flags);
26019 +void idle_sleep(int secs)
26021 + struct timespec ts;
26023 + ts.tv_sec = secs;
26025 + nanosleep(&ts, NULL);
26029 + * Overrides for Emacs so that we follow Linus's tabbing style.
26030 + * Emacs will notice this stuff at the end of the file and automatically
26031 + * adjust the settings for this buffer only. This must remain at the end
26033 + * ---------------------------------------------------------------------------
26034 + * Local variables:
26035 + * c-file-style: "linux"
26038 diff -Naur -X ../exclude-files orig/arch/um/kernel/time_kern.c um/arch/um/kernel/time_kern.c
26039 --- orig/arch/um/kernel/time_kern.c 1969-12-31 19:00:00.000000000 -0500
26040 +++ um/arch/um/kernel/time_kern.c 2003-04-23 22:19:08.000000000 -0400
26043 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
26044 + * Licensed under the GPL
26047 +#include "linux/kernel.h"
26048 +#include "linux/unistd.h"
26049 +#include "linux/stddef.h"
26050 +#include "linux/spinlock.h"
26051 +#include "linux/sched.h"
26052 +#include "linux/interrupt.h"
26053 +#include "linux/init.h"
26054 +#include "linux/delay.h"
26055 +#include "asm/irq.h"
26056 +#include "asm/param.h"
26057 +#include "asm/current.h"
26058 +#include "kern_util.h"
26059 +#include "user_util.h"
26060 +#include "time_user.h"
26063 +extern rwlock_t xtime_lock;
26070 +/* Changed at early boot */
26071 +int timer_irq_inited = 0;
26073 +/* missed_ticks will be modified after kernel memory has been
26074 + * write-protected, so this puts it in a section which will be left
26077 +int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
26079 +void timer_irq(union uml_pt_regs *regs)
26081 + int cpu = current->processor, ticks = missed_ticks[cpu];
26083 + if(!timer_irq_inited) return;
26084 + missed_ticks[cpu] = 0;
26085 + while(ticks--) do_IRQ(TIMER_IRQ, regs);
26088 +void boot_timer_handler(int sig)
26090 + struct pt_regs regs;
26092 + CHOOSE_MODE((void)
26093 + (UPT_SC(®s.regs) = (struct sigcontext *) (&sig + 1)),
26094 + (void) (regs.regs.skas.is_user = 0));
26098 +void um_timer(int irq, void *dev, struct pt_regs *regs)
26101 + write_lock(&xtime_lock);
26105 + write_unlock(&xtime_lock);
26108 +long um_time(int * tloc)
26110 + struct timeval now;
26112 + do_gettimeofday(&now);
26114 + if (put_user(now.tv_sec,tloc))
26115 + now.tv_sec = -EFAULT;
26117 + return now.tv_sec;
26120 +long um_stime(int * tptr)
26123 + struct timeval new;
26125 + if (get_user(value, tptr))
26127 + new.tv_sec = value;
26129 + do_settimeofday(&new);
26133 +/* XXX Needs to be moved under sys-i386 */
26134 +void __delay(um_udelay_t time)
26136 + /* Stolen from the i386 __loop_delay */
26138 + __asm__ __volatile__(
26143 + "2:\tdecl %0\n\tjns 2b"
26148 +void __udelay(um_udelay_t usecs)
26152 + n = (loops_per_jiffy * HZ * usecs) / 1000000;
26153 + for(i=0;i<n;i++) ;
26156 +void __const_udelay(um_udelay_t usecs)
26160 + n = (loops_per_jiffy * HZ * usecs) / 1000000;
26161 + for(i=0;i<n;i++) ;
26164 +void timer_handler(int sig, union uml_pt_regs *regs)
26167 + update_process_times(user_context(UPT_SP(regs)));
26169 + if(current->processor == 0)
26173 +static spinlock_t timer_spinlock = SPIN_LOCK_UNLOCKED;
26175 +unsigned long time_lock(void)
26177 + unsigned long flags;
26179 + spin_lock_irqsave(&timer_spinlock, flags);
26183 +void time_unlock(unsigned long flags)
26185 + spin_unlock_irqrestore(&timer_spinlock, flags);
26188 +int __init timer_init(void)
26192 + CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
26193 + if((err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer",
26195 + printk(KERN_ERR "timer_init : request_irq failed - "
26196 + "errno = %d\n", -err);
26197 + timer_irq_inited = 1;
26201 +__initcall(timer_init);
26205 + * Overrides for Emacs so that we follow Linus's tabbing style.
26206 + * Emacs will notice this stuff at the end of the file and automatically
26207 + * adjust the settings for this buffer only. This must remain at the end
26209 + * ---------------------------------------------------------------------------
26210 + * Local variables:
26211 + * c-file-style: "linux"
26214 diff -Naur -X ../exclude-files orig/arch/um/kernel/tlb.c um/arch/um/kernel/tlb.c
26215 --- orig/arch/um/kernel/tlb.c 1969-12-31 19:00:00.000000000 -0500
26216 +++ um/arch/um/kernel/tlb.c 2002-10-23 22:15:51.000000000 -0400
26219 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
26220 + * Licensed under the GPL
26223 +#include "linux/mm.h"
26224 +#include "asm/page.h"
26225 +#include "asm/pgalloc.h"
26226 +#include "choose-mode.h"
26227 +#include "mode_kern.h"
26229 +void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
26231 + address &= PAGE_MASK;
26232 + flush_tlb_range(vma->vm_mm, address, address + PAGE_SIZE);
26235 +void flush_tlb_all(void)
26237 + flush_tlb_mm(current->mm);
26240 +void flush_tlb_kernel_vm(void)
26242 + CHOOSE_MODE(flush_tlb_kernel_vm_tt(), flush_tlb_kernel_vm_skas());
26245 +void __flush_tlb_one(unsigned long addr)
26247 + CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
26250 +void flush_tlb_range(struct mm_struct *mm, unsigned long start,
26251 + unsigned long end)
26253 + CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, mm, start,
26257 +void flush_tlb_mm(struct mm_struct *mm)
26259 + CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
26262 +void force_flush_all(void)
26264 + CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
26268 +pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
26270 + return(pgd_offset(mm, address));
26273 +pmd_t *pmd_offset_proc(pgd_t *pgd, unsigned long address)
26275 + return(pmd_offset(pgd, address));
26278 +pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
26280 + return(pte_offset(pmd, address));
26283 +pte_t *addr_pte(struct task_struct *task, unsigned long addr)
26285 + return(pte_offset(pmd_offset(pgd_offset(task->mm, addr), addr), addr));
26289 + * Overrides for Emacs so that we follow Linus's tabbing style.
26290 + * Emacs will notice this stuff at the end of the file and automatically
26291 + * adjust the settings for this buffer only. This must remain at the end
26293 + * ---------------------------------------------------------------------------
26294 + * Local variables:
26295 + * c-file-style: "linux"
26298 diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_kern.c um/arch/um/kernel/trap_kern.c
26299 --- orig/arch/um/kernel/trap_kern.c 1969-12-31 19:00:00.000000000 -0500
26300 +++ um/arch/um/kernel/trap_kern.c 2003-03-26 13:26:00.000000000 -0500
26303 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
26304 + * Licensed under the GPL
26307 +#include "linux/kernel.h"
26308 +#include "linux/sched.h"
26309 +#include "linux/mm.h"
26310 +#include "linux/spinlock.h"
26311 +#include "linux/config.h"
26312 +#include "linux/init.h"
26313 +#include "asm/semaphore.h"
26314 +#include "asm/pgtable.h"
26315 +#include "asm/pgalloc.h"
26316 +#include "asm/a.out.h"
26317 +#include "asm/current.h"
26318 +#include "asm/irq.h"
26319 +#include "user_util.h"
26320 +#include "kern_util.h"
26322 +#include "chan_kern.h"
26323 +#include "mconsole_kern.h"
26324 +#include "2_5compat.h"
26326 +unsigned long handle_page_fault(unsigned long address, unsigned long ip,
26327 + int is_write, int is_user, int *code_out)
26329 + struct mm_struct *mm = current->mm;
26330 + struct vm_area_struct *vma;
26334 + unsigned long page;
26337 + *code_out = SEGV_MAPERR;
26338 + down_read(&mm->mmap_sem);
26339 + vma = find_vma(mm, address);
26342 + else if(vma->vm_start <= address)
26344 + else if(!(vma->vm_flags & VM_GROWSDOWN))
26346 + else if(expand_stack(vma, address))
26350 + *code_out = SEGV_ACCERR;
26351 + if(is_write && !(vma->vm_flags & VM_WRITE))
26353 + page = address & PAGE_MASK;
26354 + if(page == (unsigned long) current + PAGE_SIZE)
26355 + panic("Kernel stack overflow");
26356 + pgd = pgd_offset(mm, page);
26357 + pmd = pmd_offset(pgd, page);
26360 + switch (handle_mm_fault(mm, vma, address, is_write)) {
26362 + current->min_flt++;
26365 + current->maj_flt++;
26368 + if (current->pid == 1) {
26369 + up_read(&mm->mmap_sem);
26371 + down_read(&mm->mmap_sem);
26374 + /* Fall through to bad area case */
26378 + pte = pte_offset(pmd, page);
26379 + } while(!pte_present(*pte));
26381 + *pte = pte_mkyoung(*pte);
26382 + if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
26383 + flush_tlb_page(vma, page);
26385 + up_read(&mm->mmap_sem);
26389 +unsigned long segv(unsigned long address, unsigned long ip, int is_write,
26390 + int is_user, void *sc)
26392 + struct siginfo si;
26396 + if(!is_user && (address >= start_vm) && (address < end_vm)){
26397 + flush_tlb_kernel_vm();
26400 + if(current->mm == NULL)
26401 + panic("Segfault with no mm");
26403 + handled = handle_page_fault(address, ip, is_write, is_user,
26406 + catcher = current->thread.fault_catcher;
26409 + else if(catcher != NULL){
26410 + current->thread.fault_addr = (void *) address;
26411 + do_longjmp(catcher, 1);
26413 + else if(current->thread.fault_addr != NULL){
26414 + panic("fault_addr set but no fault catcher");
26416 + else if(arch_fixup(ip, sc))
26420 + panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
26422 + si.si_signo = SIGSEGV;
26423 + si.si_addr = (void *) address;
26424 + current->thread.cr2 = address;
26425 + current->thread.err = is_write;
26426 + force_sig_info(SIGSEGV, &si, current);
26430 +void bad_segv(unsigned long address, unsigned long ip, int is_write)
26432 + struct siginfo si;
26434 + printk(KERN_ERR "Unfixable SEGV in '%s' (pid %d) at 0x%lx "
26435 + "(ip 0x%lx)\n", current->comm, current->pid, address, ip);
26436 + si.si_signo = SIGSEGV;
26437 + si.si_code = SEGV_ACCERR;
26438 + si.si_addr = (void *) address;
26439 + current->thread.cr2 = address;
26440 + current->thread.err = is_write;
26441 + force_sig_info(SIGSEGV, &si, current);
26444 +void relay_signal(int sig, union uml_pt_regs *regs)
26446 + if(arch_handle_signal(sig, regs)) return;
26447 + if(!UPT_IS_USER(regs))
26448 + panic("Kernel mode signal %d", sig);
26449 + force_sig(sig, current);
26452 +void bus_handler(int sig, union uml_pt_regs *regs)
26454 + if(current->thread.fault_catcher != NULL)
26455 + do_longjmp(current->thread.fault_catcher, 1);
26456 + else relay_signal(sig, regs);
26459 +void winch(int sig, union uml_pt_regs *regs)
26461 + do_IRQ(WINCH_IRQ, regs);
26464 +void trap_init(void)
26468 +spinlock_t trap_lock = SPIN_LOCK_UNLOCKED;
26470 +static int trap_index = 0;
26472 +int next_trap_index(int limit)
26476 + spin_lock(&trap_lock);
26477 + ret = trap_index;
26478 + if(++trap_index == limit)
26480 + spin_unlock(&trap_lock);
26485 + * Overrides for Emacs so that we follow Linus's tabbing style.
26486 + * Emacs will notice this stuff at the end of the file and automatically
26487 + * adjust the settings for this buffer only. This must remain at the end
26489 + * ---------------------------------------------------------------------------
26490 + * Local variables:
26491 + * c-file-style: "linux"
26494 diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_user.c um/arch/um/kernel/trap_user.c
26495 --- orig/arch/um/kernel/trap_user.c 1969-12-31 19:00:00.000000000 -0500
26496 +++ um/arch/um/kernel/trap_user.c 2003-03-26 13:25:50.000000000 -0500
26499 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
26500 + * Licensed under the GPL
26503 +#include <stdlib.h>
26504 +#include <errno.h>
26505 +#include <fcntl.h>
26506 +#include <setjmp.h>
26507 +#include <signal.h>
26508 +#include <sys/time.h>
26509 +#include <sys/ioctl.h>
26510 +#include <sys/ptrace.h>
26511 +#include <sys/wait.h>
26512 +#include <asm/page.h>
26513 +#include <asm/unistd.h>
26514 +#include <asm/ptrace.h>
26516 +#include "sysdep/ptrace.h"
26517 +#include "sigcontext.h"
26518 +#include "sysdep/sigcontext.h"
26519 +#include "irq_user.h"
26520 +#include "frame_user.h"
26521 +#include "signal_user.h"
26522 +#include "time_user.h"
26525 +#include "choose-mode.h"
26526 +#include "kern_util.h"
26527 +#include "user_util.h"
26530 +void kill_child_dead(int pid)
26532 + kill(pid, SIGKILL);
26533 + kill(pid, SIGCONT);
26534 + while(waitpid(pid, NULL, 0) > 0) kill(pid, SIGCONT);
26537 +/* Unlocked - don't care if this is a bit off */
26538 +int nsegfaults = 0;
26541 + unsigned long address;
26544 + unsigned long sp;
26546 +} segfault_record[1024];
26548 +void segv_handler(int sig, union uml_pt_regs *regs)
26552 + if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){
26553 + bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs),
26554 + UPT_FAULT_WRITE(regs));
26557 + max = sizeof(segfault_record)/sizeof(segfault_record[0]);
26558 + index = next_trap_index(max);
26561 + segfault_record[index].address = UPT_FAULT_ADDR(regs);
26562 + segfault_record[index].pid = os_getpid();
26563 + segfault_record[index].is_write = UPT_FAULT_WRITE(regs);
26564 + segfault_record[index].sp = UPT_SP(regs);
26565 + segfault_record[index].is_user = UPT_IS_USER(regs);
26566 + segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs),
26567 + UPT_IS_USER(regs), regs);
26570 +void usr2_handler(int sig, union uml_pt_regs *regs)
26572 + CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
26575 +struct signal_info sig_info[] = {
26576 + [ SIGTRAP ] { .handler = relay_signal,
26578 + [ SIGFPE ] { .handler = relay_signal,
26580 + [ SIGILL ] { .handler = relay_signal,
26582 + [ SIGWINCH ] { .handler = winch,
26584 + [ SIGBUS ] { .handler = bus_handler,
26586 + [ SIGSEGV] { .handler = segv_handler,
26588 + [ SIGIO ] { .handler = sigio_handler,
26590 + [ SIGVTALRM ] { .handler = timer_handler,
26592 + [ SIGALRM ] { .handler = timer_handler,
26594 + [ SIGUSR2 ] { .handler = usr2_handler,
26598 +void sig_handler(int sig, struct sigcontext sc)
26600 + CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
26604 +extern int timer_irq_inited, missed_ticks[];
26606 +void alarm_handler(int sig, struct sigcontext sc)
26608 + if(!timer_irq_inited) return;
26609 + missed_ticks[cpu()]++;
26611 + if(sig == SIGALRM)
26612 + switch_timers(0);
26614 + CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
26617 + if(sig == SIGALRM)
26618 + switch_timers(1);
26621 +void do_longjmp(void *b, int val)
26623 + jmp_buf *buf = b;
26625 + longjmp(*buf, val);
26629 + * Overrides for Emacs so that we follow Linus's tabbing style.
26630 + * Emacs will notice this stuff at the end of the file and automatically
26631 + * adjust the settings for this buffer only. This must remain at the end
26633 + * ---------------------------------------------------------------------------
26634 + * Local variables:
26635 + * c-file-style: "linux"
26638 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_kern.c um/arch/um/kernel/tt/exec_kern.c
26639 --- orig/arch/um/kernel/tt/exec_kern.c 1969-12-31 19:00:00.000000000 -0500
26640 +++ um/arch/um/kernel/tt/exec_kern.c 2002-10-24 19:22:17.000000000 -0400
26643 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
26644 + * Licensed under the GPL
26647 +#include "linux/kernel.h"
26648 +#include "linux/mm.h"
26649 +#include "asm/signal.h"
26650 +#include "asm/ptrace.h"
26651 +#include "asm/uaccess.h"
26652 +#include "asm/pgalloc.h"
26653 +#include "user_util.h"
26654 +#include "kern_util.h"
26655 +#include "irq_user.h"
26656 +#include "time_user.h"
26657 +#include "mem_user.h"
26661 +static int exec_tramp(void *sig_stack)
26663 + init_new_thread_stack(sig_stack, NULL);
26664 + init_new_thread_signals(1);
26665 + os_stop_process(os_getpid());
26669 +void flush_thread_tt(void)
26671 + unsigned long stack;
26674 + stack = alloc_stack(0, 0);
26677 + "flush_thread : failed to allocate temporary stack\n");
26678 + do_exit(SIGKILL);
26681 + new_pid = start_fork_tramp((void *) current->thread.kernel_stack,
26682 + stack, 0, exec_tramp);
26685 + "flush_thread : new thread failed, errno = %d\n",
26687 + do_exit(SIGKILL);
26690 + if(current->processor == 0)
26691 + forward_interrupts(new_pid);
26692 + current->thread.request.op = OP_EXEC;
26693 + current->thread.request.u.exec.pid = new_pid;
26694 + unprotect_stack((unsigned long) current);
26695 + os_usr1_process(os_getpid());
26698 + free_page(stack);
26699 + protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
26700 + task_protections((unsigned long) current);
26701 + force_flush_all();
26702 + unblock_signals();
26705 +void start_thread_tt(struct pt_regs *regs, unsigned long eip,
26706 + unsigned long esp)
26709 + flush_tlb_mm(current->mm);
26710 + PT_REGS_IP(regs) = eip;
26711 + PT_REGS_SP(regs) = esp;
26712 + PT_FIX_EXEC_STACK(esp);
26716 + * Overrides for Emacs so that we follow Linus's tabbing style.
26717 + * Emacs will notice this stuff at the end of the file and automatically
26718 + * adjust the settings for this buffer only. This must remain at the end
26720 + * ---------------------------------------------------------------------------
26721 + * Local variables:
26722 + * c-file-style: "linux"
26725 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_user.c um/arch/um/kernel/tt/exec_user.c
26726 --- orig/arch/um/kernel/tt/exec_user.c 1969-12-31 19:00:00.000000000 -0500
26727 +++ um/arch/um/kernel/tt/exec_user.c 2002-12-05 19:36:57.000000000 -0500
26730 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
26731 + * Licensed under the GPL
26734 +#include <stdio.h>
26735 +#include <unistd.h>
26736 +#include <stdlib.h>
26737 +#include <sched.h>
26738 +#include <errno.h>
26739 +#include <sys/wait.h>
26740 +#include <sys/ptrace.h>
26741 +#include <signal.h>
26742 +#include "user_util.h"
26743 +#include "kern_util.h"
26745 +#include "ptrace_user.h"
26747 +void do_exec(int old_pid, int new_pid)
26749 + unsigned long regs[FRAME_SIZE];
26751 + if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) ||
26752 + (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0) ||
26753 + (waitpid(new_pid, 0, WUNTRACED) < 0))
26754 + tracer_panic("do_exec failed to attach proc - errno = %d",
26757 + if(ptrace_getregs(old_pid, regs) < 0)
26758 + tracer_panic("do_exec failed to get registers - errno = %d",
26761 + kill(old_pid, SIGKILL);
26763 + if(ptrace_setregs(new_pid, regs) < 0)
26764 + tracer_panic("do_exec failed to start new proc - errno = %d",
26769 + * Overrides for Emacs so that we follow Linus's tabbing style.
26770 + * Emacs will notice this stuff at the end of the file and automatically
26771 + * adjust the settings for this buffer only. This must remain at the end
26773 + * ---------------------------------------------------------------------------
26774 + * Local variables:
26775 + * c-file-style: "linux"
26778 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb.c um/arch/um/kernel/tt/gdb.c
26779 --- orig/arch/um/kernel/tt/gdb.c 1969-12-31 19:00:00.000000000 -0500
26780 +++ um/arch/um/kernel/tt/gdb.c 2003-01-17 13:23:31.000000000 -0500
26783 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
26784 + * Licensed under the GPL
26787 +#include <stdio.h>
26788 +#include <stdlib.h>
26789 +#include <errno.h>
26790 +#include <string.h>
26791 +#include <signal.h>
26792 +#include <sys/ptrace.h>
26793 +#include <sys/types.h>
26794 +#include "uml-config.h"
26795 +#include "kern_constants.h"
26796 +#include "chan_user.h"
26799 +#include "debug.h"
26800 +#include "kern_util.h"
26801 +#include "user_util.h"
26803 +#include "sysdep/thread.h"
26805 +extern int debugger_pid;
26806 +extern int debugger_fd;
26807 +extern int debugger_parent;
26809 +int detach(int pid, int sig)
26811 + return(ptrace(PTRACE_DETACH, pid, 0, sig));
26814 +int attach(int pid)
26818 + err = ptrace(PTRACE_ATTACH, pid, 0, 0);
26819 + if(err < 0) return(-errno);
26820 + else return(err);
26825 + return(ptrace(PTRACE_CONT, pid, 0, 0));
26828 +#ifdef UML_CONFIG_PT_PROXY
26830 +int debugger_signal(int status, pid_t pid)
26832 + return(debugger_proxy(status, pid));
26835 +void child_signal(pid_t pid, int status)
26837 + child_proxy(pid, status);
26840 +static void gdb_announce(char *dev_name, int dev)
26842 + printf("gdb assigned device '%s'\n", dev_name);
26845 +static struct chan_opts opts = {
26846 + .announce = gdb_announce,
26847 + .xterm_title = "UML kernel debugger",
26849 + .tramp_stack = 0,
26853 +/* Accessed by the tracing thread, which automatically serializes access */
26854 +static void *xterm_data;
26855 +static int xterm_fd;
26857 +extern void *xterm_init(char *, int, struct chan_opts *);
26858 +extern int xterm_open(int, int, int, void *, char **);
26859 +extern void xterm_close(int, void *);
26861 +int open_gdb_chan(void)
26863 + char stack[UM_KERN_PAGE_SIZE], *dummy;
26865 + opts.tramp_stack = (unsigned long) stack;
26866 + xterm_data = xterm_init("", 0, &opts);
26867 + xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy);
26868 + return(xterm_fd);
26871 +static void exit_debugger_cb(void *unused)
26873 + if(debugger_pid != -1){
26874 + if(gdb_pid != -1){
26875 + fake_child_exit();
26878 + else kill_child_dead(debugger_pid);
26879 + debugger_pid = -1;
26880 + if(debugger_parent != -1)
26881 + detach(debugger_parent, SIGINT);
26883 + if(xterm_data != NULL) xterm_close(xterm_fd, xterm_data);
26886 +static void exit_debugger(void)
26888 + initial_thread_cb(exit_debugger_cb, NULL);
26891 +__uml_exitcall(exit_debugger);
26898 +static void config_gdb_cb(void *arg)
26900 + struct gdb_data *data = arg;
26905 + if(debugger_pid != -1) exit_debugger_cb(NULL);
26906 + if(!strncmp(data->str, "pid,", strlen("pid,"))){
26907 + data->str += strlen("pid,");
26908 + pid = strtoul(data->str, NULL, 0);
26909 + task = cpu_tasks[0].task;
26910 + debugger_pid = attach_debugger(TASK_EXTERN_PID(task), pid, 0);
26911 + if(debugger_pid != -1){
26918 + debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
26919 + init_proxy(debugger_pid, 0, 0);
26922 +int gdb_config(char *str)
26924 + struct gdb_data data;
26926 + if(*str++ != '=') return(-1);
26928 + initial_thread_cb(config_gdb_cb, &data);
26929 + return(data.err);
26932 +void remove_gdb_cb(void *unused)
26934 + exit_debugger_cb(NULL);
26937 +int gdb_remove(char *unused)
26939 + initial_thread_cb(remove_gdb_cb, NULL);
26943 +void signal_usr1(int sig)
26945 + if(debugger_pid != -1){
26946 + printk(UM_KERN_ERR "The debugger is already running\n");
26949 + debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
26950 + init_proxy(debugger_pid, 0, 0);
26953 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
26957 + pid = start_debugger(linux_prog, startup, stop, &debugger_fd);
26958 + status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
26963 + init_proxy(pid, 1, status);
26967 +int attach_debugger(int idle_pid, int pid, int stop)
26969 + int status = 0, err;
26971 + err = attach(pid);
26973 + printf("Failed to attach pid %d, errno = %d\n", pid, -err);
26976 + if(stop) status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
26977 + init_proxy(pid, 1, status);
26981 +#ifdef notdef /* Put this back in when it does something useful */
26982 +static int __init uml_gdb_init_setup(char *line, int *add)
26984 + gdb_init = uml_strdup(line);
26988 +__uml_setup("gdb=", uml_gdb_init_setup,
26989 +"gdb=<channel description>\n\n"
26993 +static int __init uml_gdb_pid_setup(char *line, int *add)
26995 + gdb_pid = strtoul(line, NULL, 0);
27000 +__uml_setup("gdb-pid=", uml_gdb_pid_setup,
27002 +" gdb-pid is used to attach an external debugger to UML. This may be\n"
27003 +" an already-running gdb or a debugger-like process like strace.\n\n"
27008 +int debugger_signal(int status, pid_t pid){ return(0); }
27009 +void child_signal(pid_t pid, int status){ }
27010 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
27012 + printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
27013 + kill_child_dead(idle_pid);
27017 +void signal_usr1(int sig)
27019 + printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
27022 +int attach_debugger(int idle_pid, int pid, int stop)
27024 + printk(UM_KERN_ERR "attach_debugger called when CONFIG_PT_PROXY "
27029 +int config_gdb(char *str)
27034 +int remove_gdb(void)
27039 +int init_parent_proxy(int pid)
27044 +void debugger_parent_signal(int status, int pid)
27051 + * Overrides for Emacs so that we follow Linus's tabbing style.
27052 + * Emacs will notice this stuff at the end of the file and automatically
27053 + * adjust the settings for this buffer only. This must remain at the end
27055 + * ---------------------------------------------------------------------------
27056 + * Local variables:
27057 + * c-file-style: "linux"
27060 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb_kern.c um/arch/um/kernel/tt/gdb_kern.c
27061 --- orig/arch/um/kernel/tt/gdb_kern.c 1969-12-31 19:00:00.000000000 -0500
27062 +++ um/arch/um/kernel/tt/gdb_kern.c 2002-12-15 21:16:17.000000000 -0500
27065 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27066 + * Licensed under the GPL
27069 +#include "linux/init.h"
27070 +#include "linux/config.h"
27071 +#include "mconsole_kern.h"
27073 +#ifdef CONFIG_MCONSOLE
27075 +extern int gdb_config(char *str);
27076 +extern int gdb_remove(char *unused);
27078 +static struct mc_device gdb_mc = {
27080 + .config = gdb_config,
27081 + .remove = gdb_remove,
27084 +int gdb_mc_init(void)
27086 + mconsole_register_dev(&gdb_mc);
27090 +__initcall(gdb_mc_init);
27095 + * Overrides for Emacs so that we follow Linus's tabbing style.
27096 + * Emacs will notice this stuff at the end of the file and automatically
27097 + * adjust the settings for this buffer only. This must remain at the end
27099 + * ---------------------------------------------------------------------------
27100 + * Local variables:
27101 + * c-file-style: "linux"
27104 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/debug.h um/arch/um/kernel/tt/include/debug.h
27105 --- orig/arch/um/kernel/tt/include/debug.h 1969-12-31 19:00:00.000000000 -0500
27106 +++ um/arch/um/kernel/tt/include/debug.h 2002-10-23 21:08:04.000000000 -0400
27109 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) and
27110 + * Lars Brinkhoff.
27111 + * Licensed under the GPL
27117 +extern int debugger_proxy(int status, pid_t pid);
27118 +extern void child_proxy(pid_t pid, int status);
27119 +extern void init_proxy (pid_t pid, int waiting, int status);
27120 +extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
27121 +extern void fake_child_exit(void);
27122 +extern int gdb_config(char *str);
27123 +extern int gdb_remove(char *unused);
27128 + * Overrides for Emacs so that we follow Linus's tabbing style.
27129 + * Emacs will notice this stuff at the end of the file and automatically
27130 + * adjust the settings for this buffer only. This must remain at the end
27132 + * ---------------------------------------------------------------------------
27133 + * Local variables:
27134 + * c-file-style: "linux"
27137 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mmu.h um/arch/um/kernel/tt/include/mmu.h
27138 --- orig/arch/um/kernel/tt/include/mmu.h 1969-12-31 19:00:00.000000000 -0500
27139 +++ um/arch/um/kernel/tt/include/mmu.h 2002-11-09 12:51:32.000000000 -0500
27142 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27143 + * Licensed under the GPL
27146 +#ifndef __TT_MMU_H
27147 +#define __TT_MMU_H
27149 +struct mmu_context_tt {
27155 + * Overrides for Emacs so that we follow Linus's tabbing style.
27156 + * Emacs will notice this stuff at the end of the file and automatically
27157 + * adjust the settings for this buffer only. This must remain at the end
27159 + * ---------------------------------------------------------------------------
27160 + * Local variables:
27161 + * c-file-style: "linux"
27164 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode.h um/arch/um/kernel/tt/include/mode.h
27165 --- orig/arch/um/kernel/tt/include/mode.h 1969-12-31 19:00:00.000000000 -0500
27166 +++ um/arch/um/kernel/tt/include/mode.h 2002-12-09 00:34:40.000000000 -0500
27169 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27170 + * Licensed under the GPL
27173 +#ifndef __MODE_TT_H__
27174 +#define __MODE_TT_H__
27176 +#include "sysdep/ptrace.h"
27178 +extern int tracing_pid;
27180 +extern int tracer(int (*init_proc)(void *), void *sp);
27181 +extern void user_time_init_tt(void);
27182 +extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data);
27183 +extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr,
27185 +extern void sig_handler_common_tt(int sig, void *sc);
27186 +extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
27187 +extern void reboot_tt(void);
27188 +extern void halt_tt(void);
27189 +extern int is_tracer_winch(int pid, int fd, void *data);
27190 +extern void kill_off_processes_tt(void);
27195 + * Overrides for Emacs so that we follow Linus's tabbing style.
27196 + * Emacs will notice this stuff at the end of the file and automatically
27197 + * adjust the settings for this buffer only. This must remain at the end
27199 + * ---------------------------------------------------------------------------
27200 + * Local variables:
27201 + * c-file-style: "linux"
27204 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode_kern.h um/arch/um/kernel/tt/include/mode_kern.h
27205 --- orig/arch/um/kernel/tt/include/mode_kern.h 1969-12-31 19:00:00.000000000 -0500
27206 +++ um/arch/um/kernel/tt/include/mode_kern.h 2002-12-16 21:49:18.000000000 -0500
27209 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27210 + * Licensed under the GPL
27213 +#ifndef __TT_MODE_KERN_H__
27214 +#define __TT_MODE_KERN_H__
27216 +#include "linux/sched.h"
27217 +#include "asm/page.h"
27218 +#include "asm/ptrace.h"
27219 +#include "asm/uaccess.h"
27221 +extern void *_switch_to_tt(void *prev, void *next);
27222 +extern void flush_thread_tt(void);
27223 +extern void start_thread_tt(struct pt_regs *regs, unsigned long eip,
27224 + unsigned long esp);
27225 +extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
27226 + unsigned long stack_top, struct task_struct *p,
27227 + struct pt_regs *regs);
27228 +extern void release_thread_tt(struct task_struct *task);
27229 +extern void exit_thread_tt(void);
27230 +extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
27231 +extern void init_idle_tt(void);
27232 +extern void flush_tlb_kernel_vm_tt(void);
27233 +extern void __flush_tlb_one_tt(unsigned long addr);
27234 +extern void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start,
27235 + unsigned long end);
27236 +extern void flush_tlb_mm_tt(struct mm_struct *mm);
27237 +extern void force_flush_all_tt(void);
27238 +extern long execute_syscall_tt(void *r);
27239 +extern void before_mem_tt(unsigned long brk_start);
27240 +extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
27241 + unsigned long *task_size_out);
27242 +extern int start_uml_tt(void);
27243 +extern int external_pid_tt(struct task_struct *task);
27244 +extern int thread_pid_tt(struct thread_struct *thread);
27246 +#define kmem_end_tt (host_task_size - ABOVE_KMEM)
27251 + * Overrides for Emacs so that we follow Linus's tabbing style.
27252 + * Emacs will notice this stuff at the end of the file and automatically
27253 + * adjust the settings for this buffer only. This must remain at the end
27255 + * ---------------------------------------------------------------------------
27256 + * Local variables:
27257 + * c-file-style: "linux"
27260 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/ptrace-tt.h um/arch/um/kernel/tt/include/ptrace-tt.h
27261 --- orig/arch/um/kernel/tt/include/ptrace-tt.h 1969-12-31 19:00:00.000000000 -0500
27262 +++ um/arch/um/kernel/tt/include/ptrace-tt.h 2003-01-17 13:23:30.000000000 -0500
27265 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
27266 + * Licensed under the GPL
27269 +#ifndef __PTRACE_TT_H
27270 +#define __PTRACE_TT_H
27272 +#include "uml-config.h"
27274 +#ifdef UML_CONFIG_MODE_TT
27275 +#include "sysdep/sc.h"
27281 + * Overrides for Emacs so that we follow Linus's tabbing style.
27282 + * Emacs will notice this stuff at the end of the file and automatically
27283 + * adjust the settings for this buffer only. This must remain at the end
27285 + * ---------------------------------------------------------------------------
27286 + * Local variables:
27287 + * c-file-style: "linux"
27290 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/tt.h um/arch/um/kernel/tt/include/tt.h
27291 --- orig/arch/um/kernel/tt/include/tt.h 1969-12-31 19:00:00.000000000 -0500
27292 +++ um/arch/um/kernel/tt/include/tt.h 2002-12-20 23:29:11.000000000 -0500
27295 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27296 + * Licensed under the GPL
27302 +#include "sysdep/ptrace.h"
27304 +extern int gdb_pid;
27306 +extern int debug_stop;
27307 +extern int debug_trace;
27309 +extern int honeypot;
27311 +extern int fork_tramp(void *sig_stack);
27312 +extern int do_proc_op(void *t, int proc_id);
27313 +extern int tracer(int (*init_proc)(void *), void *sp);
27314 +extern void attach_process(int pid);
27315 +extern void tracer_panic(char *format, ...);
27316 +extern void set_init_pid(int pid);
27317 +extern int set_user_mode(void *task);
27318 +extern void set_tracing(void *t, int tracing);
27319 +extern int is_tracing(void *task);
27320 +extern int singlestepping_tt(void *t);
27321 +extern void clear_singlestep(void *t);
27322 +extern void syscall_handler(int sig, union uml_pt_regs *regs);
27323 +extern void exit_kernel(int pid, void *task);
27324 +extern int do_syscall(void *task, int pid);
27325 +extern int is_valid_pid(int pid);
27326 +extern void remap_data(void *segment_start, void *segment_end, int w);
27331 + * Overrides for Emacs so that we follow Linus's tabbing style.
27332 + * Emacs will notice this stuff at the end of the file and automatically
27333 + * adjust the settings for this buffer only. This must remain at the end
27335 + * ---------------------------------------------------------------------------
27336 + * Local variables:
27337 + * c-file-style: "linux"
27340 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/uaccess.h um/arch/um/kernel/tt/include/uaccess.h
27341 --- orig/arch/um/kernel/tt/include/uaccess.h 1969-12-31 19:00:00.000000000 -0500
27342 +++ um/arch/um/kernel/tt/include/uaccess.h 2003-03-25 16:58:42.000000000 -0500
27345 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
27346 + * Licensed under the GPL
27349 +#ifndef __TT_UACCESS_H
27350 +#define __TT_UACCESS_H
27352 +#include "linux/string.h"
27353 +#include "linux/sched.h"
27354 +#include "asm/processor.h"
27355 +#include "asm/errno.h"
27356 +#include "asm/current.h"
27357 +#include "asm/a.out.h"
27358 +#include "uml_uaccess.h"
27360 +#define ABOVE_KMEM (16 * 1024 * 1024)
27362 +extern unsigned long end_vm;
27363 +extern unsigned long uml_physmem;
27365 +#define under_task_size(addr, size) \
27366 + (((unsigned long) (addr) < TASK_SIZE) && \
27367 + (((unsigned long) (addr) + (size)) < TASK_SIZE))
27369 +#define is_stack(addr, size) \
27370 + (((unsigned long) (addr) < STACK_TOP) && \
27371 + ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
27372 + (((unsigned long) (addr) + (size)) <= STACK_TOP))
27374 +#define access_ok_tt(type, addr, size) \
27375 + ((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \
27376 + (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
27377 + (under_task_size(addr, size) || is_stack(addr, size))))
27379 +static inline int verify_area_tt(int type, const void * addr,
27380 + unsigned long size)
27382 + return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
27385 +extern unsigned long get_fault_addr(void);
27387 +extern int __do_copy_from_user(void *to, const void *from, int n,
27388 + void **fault_addr, void **fault_catcher);
27390 +static inline int copy_from_user_tt(void *to, const void *from, int n)
27392 + if(!access_ok_tt(VERIFY_READ, from, n))
27395 + return(__do_copy_from_user(to, from, n, ¤t->thread.fault_addr,
27396 + ¤t->thread.fault_catcher));
27399 +static inline int copy_to_user_tt(void *to, const void *from, int n)
27401 + if(!access_ok_tt(VERIFY_WRITE, to, n))
27404 + return(__do_copy_to_user(to, from, n, ¤t->thread.fault_addr,
27405 + ¤t->thread.fault_catcher));
27408 +extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
27409 + void **fault_addr, void **fault_catcher);
27411 +static inline int strncpy_from_user_tt(char *dst, const char *src, int count)
27415 + if(!access_ok_tt(VERIFY_READ, src, 1))
27418 + n = __do_strncpy_from_user(dst, src, count,
27419 + ¤t->thread.fault_addr,
27420 + ¤t->thread.fault_catcher);
27421 + if(n < 0) return(-EFAULT);
27425 +extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
27426 + void **fault_catcher);
27428 +static inline int __clear_user_tt(void *mem, int len)
27430 + return(__do_clear_user(mem, len,
27431 + ¤t->thread.fault_addr,
27432 + ¤t->thread.fault_catcher));
27435 +static inline int clear_user_tt(void *mem, int len)
27437 + if(!access_ok_tt(VERIFY_WRITE, mem, len))
27440 + return(__do_clear_user(mem, len, ¤t->thread.fault_addr,
27441 + ¤t->thread.fault_catcher));
27444 +extern int __do_strnlen_user(const char *str, unsigned long n,
27445 + void **fault_addr, void **fault_catcher);
27447 +static inline int strnlen_user_tt(const void *str, int len)
27449 + return(__do_strnlen_user(str, len,
27450 + ¤t->thread.fault_addr,
27451 + ¤t->thread.fault_catcher));
27457 + * Overrides for Emacs so that we follow Linus's tabbing style.
27458 + * Emacs will notice this stuff at the end of the file and automatically
27459 + * adjust the settings for this buffer only. This must remain at the end
27461 + * ---------------------------------------------------------------------------
27462 + * Local variables:
27463 + * c-file-style: "linux"
27466 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ksyms.c um/arch/um/kernel/tt/ksyms.c
27467 --- orig/arch/um/kernel/tt/ksyms.c 1969-12-31 19:00:00.000000000 -0500
27468 +++ um/arch/um/kernel/tt/ksyms.c 2002-10-27 17:01:56.000000000 -0500
27471 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
27472 + * Licensed under the GPL
27475 +#include "linux/module.h"
27476 +#include "asm/uaccess.h"
27479 +EXPORT_SYMBOL(__do_copy_from_user);
27480 +EXPORT_SYMBOL(__do_copy_to_user);
27481 +EXPORT_SYMBOL(__do_strncpy_from_user);
27482 +EXPORT_SYMBOL(__do_strnlen_user);
27483 +EXPORT_SYMBOL(__do_clear_user);
27485 +EXPORT_SYMBOL(tracing_pid);
27486 +EXPORT_SYMBOL(honeypot);
27489 + * Overrides for Emacs so that we follow Linus's tabbing style.
27490 + * Emacs will notice this stuff at the end of the file and automatically
27491 + * adjust the settings for this buffer only. This must remain at the end
27493 + * ---------------------------------------------------------------------------
27494 + * Local variables:
27495 + * c-file-style: "linux"
27498 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/Makefile um/arch/um/kernel/tt/Makefile
27499 --- orig/arch/um/kernel/tt/Makefile 1969-12-31 19:00:00.000000000 -0500
27500 +++ um/arch/um/kernel/tt/Makefile 2002-12-20 23:29:42.000000000 -0500
27503 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27504 +# Licensed under the GPL
27509 +obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
27510 + syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
27513 +obj-$(CONFIG_PT_PROXY) += gdb_kern.o
27515 +subdir-y = sys-$(SUBARCH)
27516 +subdir-$(CONFIG_PT_PROXY) += ptproxy
27518 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
27520 +export-objs = ksyms.o
27522 +USER_OBJS = $(filter %_user.o,$(obj-y)) gdb.o time.o tracer.o
27524 +UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS))
27525 +UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS))
27527 +include $(TOPDIR)/Rules.make
27529 +$(USER_OBJS) : %.o: %.c
27530 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
27532 +$(O_TARGET) : unmap_fin.o
27535 + $(CC) $(UNMAP_CFLAGS) -c -o $@ $<
27537 +unmap_fin.o : unmap.o
27538 + ld -r -o $@ $< -lc -L/usr/lib
27541 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem.c um/arch/um/kernel/tt/mem.c
27542 --- orig/arch/um/kernel/tt/mem.c 1969-12-31 19:00:00.000000000 -0500
27543 +++ um/arch/um/kernel/tt/mem.c 2002-12-16 21:49:51.000000000 -0500
27546 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27547 + * Licensed under the GPL
27550 +#include "linux/stddef.h"
27551 +#include "linux/config.h"
27552 +#include "linux/mm.h"
27553 +#include "asm/uaccess.h"
27554 +#include "mem_user.h"
27555 +#include "kern_util.h"
27556 +#include "user_util.h"
27560 +void before_mem_tt(unsigned long brk_start)
27562 + if(!jail || debug)
27563 + remap_data(UML_ROUND_DOWN(&_stext), UML_ROUND_UP(&_etext), 1);
27564 + remap_data(UML_ROUND_DOWN(&_sdata), UML_ROUND_UP(&_edata), 1);
27565 + remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(brk_start), 1);
27568 +#ifdef CONFIG_HOST_2G_2G
27569 +#define TOP 0x80000000
27571 +#define TOP 0xc0000000
27574 +#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
27575 +#define START (TOP - SIZE)
27577 +unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
27578 + unsigned long *task_size_out)
27580 + /* Round up to the nearest 4M */
27581 + *host_size_out = ROUND_4M((unsigned long) &arg);
27582 + *task_size_out = START;
27587 + * Overrides for Emacs so that we follow Linus's tabbing style.
27588 + * Emacs will notice this stuff at the end of the file and automatically
27589 + * adjust the settings for this buffer only. This must remain at the end
27591 + * ---------------------------------------------------------------------------
27592 + * Local variables:
27593 + * c-file-style: "linux"
27596 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem_user.c um/arch/um/kernel/tt/mem_user.c
27597 --- orig/arch/um/kernel/tt/mem_user.c 1969-12-31 19:00:00.000000000 -0500
27598 +++ um/arch/um/kernel/tt/mem_user.c 2003-01-17 22:07:31.000000000 -0500
27601 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27602 + * Licensed under the GPL
27605 +#include <stdlib.h>
27606 +#include <stdio.h>
27607 +#include <unistd.h>
27608 +#include <string.h>
27609 +#include <errno.h>
27610 +#include <sys/mman.h>
27612 +#include "mem_user.h"
27613 +#include "user_util.h"
27615 +void remap_data(void *segment_start, void *segment_end, int w)
27618 + unsigned long size;
27621 + if(w) prot = PROT_WRITE;
27623 + prot |= PROT_READ | PROT_EXEC;
27624 + size = (unsigned long) segment_end -
27625 + (unsigned long) segment_start;
27626 + data = create_mem_file(size);
27627 + if((addr = mmap(NULL, size, PROT_WRITE | PROT_READ,
27628 + MAP_SHARED, data, 0)) == MAP_FAILED){
27629 + perror("mapping new data segment");
27632 + memcpy(addr, segment_start, size);
27633 + if(switcheroo(data, prot, addr, segment_start,
27635 + printf("switcheroo failed\n");
27641 + * Overrides for Emacs so that we follow Linus's tabbing style.
27642 + * Emacs will notice this stuff at the end of the file and automatically
27643 + * adjust the settings for this buffer only. This must remain at the end
27645 + * ---------------------------------------------------------------------------
27646 + * Local variables:
27647 + * c-file-style: "linux"
27650 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/process_kern.c um/arch/um/kernel/tt/process_kern.c
27651 --- orig/arch/um/kernel/tt/process_kern.c 1969-12-31 19:00:00.000000000 -0500
27652 +++ um/arch/um/kernel/tt/process_kern.c 2003-05-29 13:46:00.000000000 -0400
27655 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27656 + * Licensed under the GPL
27659 +#include "linux/sched.h"
27660 +#include "linux/signal.h"
27661 +#include "linux/kernel.h"
27662 +#include "asm/system.h"
27663 +#include "asm/pgalloc.h"
27664 +#include "asm/ptrace.h"
27665 +#include "irq_user.h"
27666 +#include "signal_user.h"
27667 +#include "kern_util.h"
27668 +#include "user_util.h"
27671 +#include "sigcontext.h"
27672 +#include "time_user.h"
27673 +#include "mem_user.h"
27679 +void *_switch_to_tt(void *prev, void *next)
27681 + struct task_struct *from, *to;
27682 + unsigned long flags;
27683 + int err, vtalrm, alrm, prof, cpu;
27685 + /* jailing and SMP are incompatible, so this doesn't need to be
27688 + static int reading;
27693 + to->thread.prev_sched = from;
27695 + cpu = from->processor;
27697 + forward_interrupts(to->thread.mode.tt.extern_pid);
27699 + forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid);
27701 + local_irq_save(flags);
27703 + vtalrm = change_sig(SIGVTALRM, 0);
27704 + alrm = change_sig(SIGALRM, 0);
27705 + prof = change_sig(SIGPROF, 0);
27711 + err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
27712 + if(err != sizeof(c))
27713 + panic("write of switch_pipe failed, errno = %d", -err);
27716 + if(from->state == TASK_ZOMBIE)
27717 + os_kill_process(os_getpid(), 0);
27719 + err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
27720 + if(err != sizeof(c))
27721 + panic("read of switch_pipe failed, errno = %d", -err);
27723 + /* This works around a nasty race with 'jail'. If we are switching
27724 + * between two threads of a threaded app and the incoming process
27725 + * runs before the outgoing process reaches the read, and it makes
27726 + * it all the way out to userspace, then it will have write-protected
27727 + * the outgoing process stack. Then, when the outgoing process
27728 + * returns from the write, it will segfault because it can no longer
27729 + * write its own stack. So, in order to avoid that, the incoming
27730 + * thread sits in a loop yielding until 'reading' is set. This
27731 + * isn't entirely safe, since there may be a reschedule from a timer
27732 + * happening between setting 'reading' and sleeping in read. But,
27733 + * it should get a whole quantum in which to reach the read and sleep,
27734 + * which should be enough.
27738 + while(!reading) sched_yield();
27741 + change_sig(SIGVTALRM, vtalrm);
27742 + change_sig(SIGALRM, alrm);
27743 + change_sig(SIGPROF, prof);
27748 + local_irq_restore(flags);
27750 + return(current->thread.prev_sched);
27753 +void release_thread_tt(struct task_struct *task)
27755 + os_kill_process(task->thread.mode.tt.extern_pid, 0);
27758 +void exit_thread_tt(void)
27760 + close(current->thread.mode.tt.switch_pipe[0]);
27761 + close(current->thread.mode.tt.switch_pipe[1]);
27764 +extern void schedule_tail(struct task_struct *prev);
27766 +static void new_thread_handler(int sig)
27768 + int (*fn)(void *);
27771 + fn = current->thread.request.u.thread.proc;
27772 + arg = current->thread.request.u.thread.arg;
27773 + UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
27774 + suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
27776 + init_new_thread_signals(1);
27778 + free_page(current->thread.temp_stack);
27779 + set_cmdline("(kernel thread)");
27780 + force_flush_all();
27782 + if(current->thread.prev_sched != NULL)
27783 + schedule_tail(current->thread.prev_sched);
27784 + current->thread.prev_sched = NULL;
27786 + change_sig(SIGUSR1, 1);
27787 + change_sig(SIGVTALRM, 1);
27788 + change_sig(SIGPROF, 1);
27790 + if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf))
27794 +static int new_thread_proc(void *stack)
27797 + init_new_thread_stack(stack, new_thread_handler);
27798 + os_usr1_process(os_getpid());
27802 +/* Signal masking - signals are blocked at the start of fork_tramp. They
27803 + * are re-enabled when finish_fork_handler is entered by fork_tramp hitting
27804 + * itself with a SIGUSR1. set_user_mode has to be run with SIGUSR1 off,
27805 + * so it is blocked before it's called. They are re-enabled on sigreturn
27806 + * despite the fact that they were blocked when the SIGUSR1 was issued because
27807 + * copy_thread copies the parent's signcontext, including the signal mask
27808 + * onto the signal frame.
27811 +static void finish_fork_handler(int sig)
27813 + UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
27814 + suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
27816 + init_new_thread_signals(1);
27819 + force_flush_all();
27820 + if(current->mm != current->p_pptr->mm)
27821 + protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
27823 + task_protections((unsigned long) current);
27825 + if(current->thread.prev_sched != NULL)
27826 + schedule_tail(current->thread.prev_sched);
27827 + current->thread.prev_sched = NULL;
27829 + free_page(current->thread.temp_stack);
27831 + change_sig(SIGUSR1, 0);
27832 + set_user_mode(current);
27835 +int fork_tramp(void *stack)
27838 + arch_init_thread();
27839 + init_new_thread_stack(stack, finish_fork_handler);
27840 + os_usr1_process(os_getpid());
27844 +int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
27845 + unsigned long stack_top, struct task_struct * p,
27846 + struct pt_regs *regs)
27848 + int (*tramp)(void *);
27849 + int new_pid, err;
27850 + unsigned long stack;
27852 + if(current->thread.forking)
27853 + tramp = fork_tramp;
27855 + tramp = new_thread_proc;
27856 + p->thread.request.u.thread = current->thread.request.u.thread;
27859 + err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
27861 + printk("copy_thread : pipe failed, errno = %d\n", -err);
27865 + stack = alloc_stack(0, 0);
27867 + printk(KERN_ERR "copy_thread : failed to allocate "
27868 + "temporary stack\n");
27872 + clone_flags &= CLONE_VM;
27873 + p->thread.temp_stack = stack;
27874 + new_pid = start_fork_tramp((void *) p->thread.kernel_stack, stack,
27875 + clone_flags, tramp);
27877 + printk(KERN_ERR "copy_thread : clone failed - errno = %d\n",
27882 + if(current->thread.forking){
27883 + sc_to_sc(UPT_SC(&p->thread.regs.regs),
27884 + UPT_SC(¤t->thread.regs.regs));
27885 + SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
27886 + if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
27888 + p->thread.mode.tt.extern_pid = new_pid;
27890 + current->thread.request.op = OP_FORK;
27891 + current->thread.request.u.fork.pid = new_pid;
27892 + os_usr1_process(os_getpid());
27896 +void reboot_tt(void)
27898 + current->thread.request.op = OP_REBOOT;
27899 + os_usr1_process(os_getpid());
27900 + os_kill_process(os_getpid(), 0);
27903 +void halt_tt(void)
27905 + current->thread.request.op = OP_HALT;
27906 + os_usr1_process(os_getpid());
27907 + os_kill_process(os_getpid(), 0);
27910 +void kill_off_processes_tt(void)
27912 + struct task_struct *p;
27915 + me = os_getpid();
27916 + for_each_task(p){
27917 + int pid = p->thread.mode.tt.extern_pid;
27918 + if((pid != me) && (pid != -1))
27919 + os_kill_process(p->thread.mode.tt.extern_pid, 0);
27921 + if((init_task.thread.mode.tt.extern_pid != me) &&
27922 + (init_task.thread.mode.tt.extern_pid != -1))
27923 + os_kill_process(init_task.thread.mode.tt.extern_pid, 0);
27926 +void initial_thread_cb_tt(void (*proc)(void *), void *arg)
27928 + if(os_getpid() == tracing_pid){
27932 + current->thread.request.op = OP_CB;
27933 + current->thread.request.u.cb.proc = proc;
27934 + current->thread.request.u.cb.arg = arg;
27935 + os_usr1_process(os_getpid());
27939 +int do_proc_op(void *t, int proc_id)
27941 + struct task_struct *task;
27942 + struct thread_struct *thread;
27946 + thread = &task->thread;
27947 + op = thread->request.op;
27950 + case OP_TRACE_ON:
27953 + pid = thread->request.u.exec.pid;
27954 + do_exec(thread->mode.tt.extern_pid, pid);
27955 + thread->mode.tt.extern_pid = pid;
27956 + cpu_tasks[task->processor].pid = pid;
27959 + attach_process(thread->request.u.fork.pid);
27962 + (*thread->request.u.cb.proc)(thread->request.u.cb.arg);
27968 + tracer_panic("Bad op in do_proc_op");
27971 + thread->request.op = OP_NONE;
27975 +void init_idle_tt(void)
27980 +/* Changed by jail_setup, which is a setup */
27983 +int __init jail_setup(char *line, int *add)
27987 + if(jail) return(0);
27989 + printf("'jail' may not used used in a kernel with CONFIG_SMP "
27993 +#ifdef CONFIG_HOSTFS
27994 + printf("'jail' may not used used in a kernel with CONFIG_HOSTFS "
27998 +#ifdef CONFIG_MODULES
27999 + printf("'jail' may not used used in a kernel with CONFIG_MODULES "
28005 + /* CAP_SYS_RAWIO controls the ability to open /dev/mem and /dev/kmem.
28006 + * Removing it from the bounding set eliminates the ability of anything
28007 + * to acquire it, and thus read or write kernel memory.
28009 + cap_lower(cap_bset, CAP_SYS_RAWIO);
28014 +__uml_setup("jail", jail_setup,
28016 +" Enables the protection of kernel memory from processes.\n\n"
28019 +static void mprotect_kernel_mem(int w)
28021 + unsigned long start, end;
28024 + if(!jail || (current == &init_task)) return;
28026 + pages = (1 << CONFIG_KERNEL_STACK_ORDER);
28028 + start = (unsigned long) current + PAGE_SIZE;
28029 + end = (unsigned long) current + PAGE_SIZE * pages;
28030 + protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
28031 + protect_memory(end, high_physmem - end, 1, w, 1, 1);
28033 + start = (unsigned long) UML_ROUND_DOWN(&_stext);
28034 + end = (unsigned long) UML_ROUND_UP(&_etext);
28035 + protect_memory(start, end - start, 1, w, 1, 1);
28037 + start = (unsigned long) UML_ROUND_DOWN(&_unprotected_end);
28038 + end = (unsigned long) UML_ROUND_UP(&_edata);
28039 + protect_memory(start, end - start, 1, w, 1, 1);
28041 + start = (unsigned long) UML_ROUND_DOWN(&__bss_start);
28042 + end = (unsigned long) UML_ROUND_UP(brk_start);
28043 + protect_memory(start, end - start, 1, w, 1, 1);
28045 + mprotect_kernel_vm(w);
28048 +void unprotect_kernel_mem(void)
28050 + mprotect_kernel_mem(1);
28053 +void protect_kernel_mem(void)
28055 + mprotect_kernel_mem(0);
28058 +extern void start_kernel(void);
28060 +static int start_kernel_proc(void *unused)
28065 + pid = os_getpid();
28067 + cpu_tasks[0].pid = pid;
28068 + cpu_tasks[0].task = current;
28070 + cpu_online_map = 1;
28072 + if(debug) os_stop_process(pid);
28077 +void set_tracing(void *task, int tracing)
28079 + ((struct task_struct *) task)->thread.mode.tt.tracing = tracing;
28082 +int is_tracing(void *t)
28084 + return (((struct task_struct *) t)->thread.mode.tt.tracing);
28087 +int set_user_mode(void *t)
28089 + struct task_struct *task;
28091 + task = t ? t : current;
28092 + if(task->thread.mode.tt.tracing)
28094 + task->thread.request.op = OP_TRACE_ON;
28095 + os_usr1_process(os_getpid());
28099 +void set_init_pid(int pid)
28103 + init_task.thread.mode.tt.extern_pid = pid;
28104 + err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
28105 + if(err) panic("Can't create switch pipe for init_task, errno = %d",
28109 +int singlestepping_tt(void *t)
28111 + struct task_struct *task = t;
28113 + if(task->thread.mode.tt.singlestep_syscall)
28115 + return(task->ptrace & PT_DTRACE);
28118 +void clear_singlestep(void *t)
28120 + struct task_struct *task = t;
28122 + task->ptrace &= ~PT_DTRACE;
28125 +int start_uml_tt(void)
28130 + pages = (1 << CONFIG_KERNEL_STACK_ORDER) - 2;
28131 + sp = (void *) init_task.thread.kernel_stack + pages * PAGE_SIZE -
28132 + sizeof(unsigned long);
28133 + return(tracer(start_kernel_proc, sp));
28136 +int external_pid_tt(struct task_struct *task)
28138 + return(task->thread.mode.tt.extern_pid);
28141 +int thread_pid_tt(struct thread_struct *thread)
28143 + return(thread->mode.tt.extern_pid);
28146 +int is_valid_pid(int pid)
28148 + struct task_struct *task;
28150 + read_lock(&tasklist_lock);
28151 + for_each_task(task){
28152 + if(task->thread.mode.tt.extern_pid == pid){
28153 + read_unlock(&tasklist_lock);
28157 + read_unlock(&tasklist_lock);
28162 + * Overrides for Emacs so that we follow Linus's tabbing style.
28163 + * Emacs will notice this stuff at the end of the file and automatically
28164 + * adjust the settings for this buffer only. This must remain at the end
28166 + * ---------------------------------------------------------------------------
28167 + * Local variables:
28168 + * c-file-style: "linux"
28171 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/Makefile um/arch/um/kernel/tt/ptproxy/Makefile
28172 --- orig/arch/um/kernel/tt/ptproxy/Makefile 1969-12-31 19:00:00.000000000 -0500
28173 +++ um/arch/um/kernel/tt/ptproxy/Makefile 2002-10-23 21:08:04.000000000 -0400
28175 +O_TARGET = ptproxy.o
28177 +obj-y = proxy.o ptrace.o sysdep.o wait.o
28179 +USER_OBJS = $(obj-y)
28181 +include $(TOPDIR)/Rules.make
28183 +$(USER_OBJS) : %.o: %.c
28184 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
28187 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/proxy.c um/arch/um/kernel/tt/ptproxy/proxy.c
28188 --- orig/arch/um/kernel/tt/ptproxy/proxy.c 1969-12-31 19:00:00.000000000 -0500
28189 +++ um/arch/um/kernel/tt/ptproxy/proxy.c 2003-04-16 14:01:03.000000000 -0400
28191 +/**********************************************************************
28194 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
28195 +terms and conditions.
28197 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
28198 +**********************************************************************/
28200 +/* XXX This file shouldn't refer to CONFIG_* */
28202 +#include <errno.h>
28203 +#include <stdio.h>
28204 +#include <stdlib.h>
28205 +#include <unistd.h>
28206 +#include <signal.h>
28207 +#include <string.h>
28208 +#include <fcntl.h>
28209 +#include <termios.h>
28210 +#include <sys/wait.h>
28211 +#include <sys/types.h>
28212 +#include <sys/ptrace.h>
28213 +#include <sys/ioctl.h>
28214 +#include <asm/unistd.h>
28216 +#include "ptproxy.h"
28217 +#include "sysdep.h"
28220 +#include "user_util.h"
28223 +#include "tempfile.h"
28225 +static int debugger_wait(debugger_state *debugger, int *status, int options,
28226 + int (*syscall)(debugger_state *debugger, pid_t child),
28227 + int (*normal_return)(debugger_state *debugger,
28229 + int (*wait_return)(debugger_state *debugger,
28232 + if(debugger->real_wait){
28233 + debugger->handle_trace = normal_return;
28234 + syscall_continue(debugger->pid);
28235 + debugger->real_wait = 0;
28238 + debugger->wait_status_ptr = status;
28239 + debugger->wait_options = options;
28240 + if((debugger->debugee != NULL) && debugger->debugee->event){
28241 + syscall_continue(debugger->pid);
28242 + wait_for_stop(debugger->pid, SIGTRAP, PTRACE_SYSCALL,
28244 + (*wait_return)(debugger, -1);
28247 + else if(debugger->wait_options & WNOHANG){
28248 + syscall_cancel(debugger->pid, 0);
28249 + debugger->handle_trace = syscall;
28253 + syscall_pause(debugger->pid);
28254 + debugger->handle_trace = wait_return;
28255 + debugger->waiting = 1;
28261 + * Handle debugger trap, i.e. syscall.
28264 +int debugger_syscall(debugger_state *debugger, pid_t child)
28266 + long arg1, arg2, arg3, arg4, arg5, result;
28267 + int syscall, ret = 0;
28269 + syscall = get_syscall(debugger->pid, &arg1, &arg2, &arg3, &arg4,
28273 + case __NR_execve:
28274 + /* execve never returns */
28275 + debugger->handle_trace = debugger_syscall;
28278 + case __NR_ptrace:
28279 + if(debugger->debugee->pid != 0) arg2 = debugger->debugee->pid;
28280 + if(!debugger->debugee->in_context)
28281 + child = debugger->debugee->pid;
28282 + result = proxy_ptrace(debugger, arg1, arg2, arg3, arg4, child,
28284 + syscall_cancel(debugger->pid, result);
28285 + debugger->handle_trace = debugger_syscall;
28288 + case __NR_waitpid:
28290 + if(!debugger_wait(debugger, (int *) arg2, arg3,
28291 + debugger_syscall, debugger_normal_return,
28292 + proxy_wait_return))
28297 + if(!debugger->debugee->in_context)
28298 + child = debugger->debugee->pid;
28299 + if(arg1 == debugger->debugee->pid){
28300 + result = kill(child, arg2);
28301 + syscall_cancel(debugger->pid, result);
28302 + debugger->handle_trace = debugger_syscall;
28305 + else debugger->handle_trace = debugger_normal_return;
28309 + debugger->handle_trace = debugger_normal_return;
28312 + syscall_continue(debugger->pid);
28316 +/* Used by the tracing thread */
28317 +static debugger_state parent;
28318 +static int parent_syscall(debugger_state *debugger, int pid);
28320 +int init_parent_proxy(int pid)
28322 + parent = ((debugger_state) { .pid = pid,
28323 + .wait_options = 0,
28324 + .wait_status_ptr = NULL,
28327 + .expecting_child = 0,
28328 + .handle_trace = parent_syscall,
28329 + .debugee = NULL } );
28333 +int parent_normal_return(debugger_state *debugger, pid_t unused)
28335 + debugger->handle_trace = parent_syscall;
28336 + syscall_continue(debugger->pid);
28340 +static int parent_syscall(debugger_state *debugger, int pid)
28342 + long arg1, arg2, arg3, arg4, arg5;
28345 + syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5);
28347 + if((syscall == __NR_waitpid) || (syscall == __NR_wait4)){
28348 + debugger_wait(&parent, (int *) arg2, arg3, parent_syscall,
28349 + parent_normal_return, parent_wait_return);
28351 + else ptrace(PTRACE_SYSCALL, pid, 0, 0);
28355 +int debugger_normal_return(debugger_state *debugger, pid_t unused)
28357 + debugger->handle_trace = debugger_syscall;
28358 + syscall_continue(debugger->pid);
28362 +void debugger_cancelled_return(debugger_state *debugger, int result)
28364 + debugger->handle_trace = debugger_syscall;
28365 + syscall_set_result(debugger->pid, result);
28366 + syscall_continue(debugger->pid);
28369 +/* Used by the tracing thread */
28370 +static debugger_state debugger;
28371 +static debugee_state debugee;
28373 +void init_proxy (pid_t debugger_pid, int stopped, int status)
28375 + debugger.pid = debugger_pid;
28376 + debugger.handle_trace = debugger_syscall;
28377 + debugger.debugee = &debugee;
28378 + debugger.waiting = 0;
28379 + debugger.real_wait = 0;
28380 + debugger.expecting_child = 0;
28383 + debugee.traced = 0;
28384 + debugee.stopped = stopped;
28385 + debugee.event = 0;
28386 + debugee.zombie = 0;
28387 + debugee.died = 0;
28388 + debugee.wait_status = status;
28389 + debugee.in_context = 1;
28392 +int debugger_proxy(int status, int pid)
28394 + int ret = 0, sig;
28396 + if(WIFSTOPPED(status)){
28397 + sig = WSTOPSIG(status);
28398 + if (sig == SIGTRAP)
28399 + ret = (*debugger.handle_trace)(&debugger, pid);
28401 + else if(sig == SIGCHLD){
28402 + if(debugger.expecting_child){
28403 + ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
28404 + debugger.expecting_child = 0;
28406 + else if(debugger.waiting)
28407 + real_wait_return(&debugger);
28409 + ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
28410 + debugger.real_wait = 1;
28413 + else ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
28415 + else if(WIFEXITED(status)){
28416 + tracer_panic("debugger (pid %d) exited with status %d",
28417 + debugger.pid, WEXITSTATUS(status));
28419 + else if(WIFSIGNALED(status)){
28420 + tracer_panic("debugger (pid %d) exited with signal %d",
28421 + debugger.pid, WTERMSIG(status));
28424 + tracer_panic("proxy got unknown status (0x%x) on debugger "
28425 + "(pid %d)", status, debugger.pid);
28430 +void child_proxy(pid_t pid, int status)
28432 + debugee.event = 1;
28433 + debugee.wait_status = status;
28435 + if(WIFSTOPPED(status)){
28436 + debugee.stopped = 1;
28437 + debugger.expecting_child = 1;
28438 + kill(debugger.pid, SIGCHLD);
28440 + else if(WIFEXITED(status) || WIFSIGNALED(status)){
28441 + debugee.zombie = 1;
28442 + debugger.expecting_child = 1;
28443 + kill(debugger.pid, SIGCHLD);
28445 + else panic("proxy got unknown status (0x%x) on child (pid %d)",
28449 +void debugger_parent_signal(int status, int pid)
28453 + if(WIFSTOPPED(status)){
28454 + sig = WSTOPSIG(status);
28455 + if(sig == SIGTRAP) (*parent.handle_trace)(&parent, pid);
28456 + else ptrace(PTRACE_SYSCALL, pid, 0, sig);
28460 +void fake_child_exit(void)
28464 + child_proxy(1, W_EXITCODE(0, 0));
28465 + while(debugger.waiting == 1){
28466 + pid = waitpid(debugger.pid, &status, WUNTRACED);
28467 + if(pid != debugger.pid){
28468 + printk("fake_child_exit - waitpid failed, "
28469 + "errno = %d\n", errno);
28472 + debugger_proxy(status, debugger.pid);
28474 + pid = waitpid(debugger.pid, &status, WUNTRACED);
28475 + if(pid != debugger.pid){
28476 + printk("fake_child_exit - waitpid failed, "
28477 + "errno = %d\n", errno);
28480 + if(ptrace(PTRACE_DETACH, debugger.pid, 0, SIGCONT) < 0)
28481 + printk("fake_child_exit - PTRACE_DETACH failed, errno = %d\n",
28485 +char gdb_init_string[] =
28489 +handle SIGWINCH nostop noprint pass \n\
28492 +int start_debugger(char *prog, int startup, int stop, int *fd_out)
28494 + int slave, child;
28496 + slave = open_gdb_chan();
28497 + if((child = fork()) == 0){
28498 + char *tempname = NULL;
28501 + if(setsid() < 0) perror("setsid");
28502 + if((dup2(slave, 0) < 0) || (dup2(slave, 1) < 0) ||
28503 + (dup2(slave, 2) < 0)){
28504 + printk("start_debugger : dup2 failed, errno = %d\n",
28508 + if(ioctl(0, TIOCSCTTY, 0) < 0){
28509 + printk("start_debugger : TIOCSCTTY failed, "
28510 + "errno = %d\n", errno);
28513 + if(tcsetpgrp (1, os_getpid()) < 0){
28514 + printk("start_debugger : tcsetpgrp failed, "
28515 + "errno = %d\n", errno);
28520 + if((fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0)) < 0){
28521 + printk("start_debugger : make_tempfile failed, errno = %d\n",
28525 + write(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
28528 + write(fd, "b start_kernel\n",
28529 + strlen("b start_kernel\n"));
28531 + write(fd, "c\n", strlen("c\n"));
28533 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
28534 + printk("start_debugger : PTRACE_TRACEME failed, "
28535 + "errno = %d\n", errno);
28538 + execlp("gdb", "gdb", "--command", tempname, prog, NULL);
28539 + printk("start_debugger : exec of gdb failed, errno = %d\n",
28543 + printk("start_debugger : fork for gdb failed, errno = %d\n",
28552 + * Overrides for Emacs so that we follow Linus's tabbing style.
28553 + * Emacs will notice this stuff at the end of the file and automatically
28554 + * adjust the settings for this buffer only. This must remain at the end
28556 + * ---------------------------------------------------------------------------
28557 + * Local variables:
28558 + * c-file-style: "linux"
28561 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptproxy.h um/arch/um/kernel/tt/ptproxy/ptproxy.h
28562 --- orig/arch/um/kernel/tt/ptproxy/ptproxy.h 1969-12-31 19:00:00.000000000 -0500
28563 +++ um/arch/um/kernel/tt/ptproxy/ptproxy.h 2002-10-23 21:08:04.000000000 -0400
28565 +/**********************************************************************
28568 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
28569 +terms and conditions.
28570 +**********************************************************************/
28572 +#ifndef __PTPROXY_H
28573 +#define __PTPROXY_H
28575 +#include <sys/types.h>
28577 +typedef struct debugger debugger_state;
28578 +typedef struct debugee debugee_state;
28583 + int wait_options;
28584 + int *wait_status_ptr;
28585 + unsigned int waiting : 1;
28586 + unsigned int real_wait : 1;
28587 + unsigned int expecting_child : 1;
28588 + int (*handle_trace) (debugger_state *, pid_t);
28590 + debugee_state *debugee;
28597 + unsigned int died : 1;
28598 + unsigned int event : 1;
28599 + unsigned int stopped : 1;
28600 + unsigned int trace_singlestep : 1;
28601 + unsigned int trace_syscall : 1;
28602 + unsigned int traced : 1;
28603 + unsigned int zombie : 1;
28604 + unsigned int in_context : 1;
28607 +extern int debugger_syscall(debugger_state *debugger, pid_t pid);
28608 +extern int debugger_normal_return (debugger_state *debugger, pid_t unused);
28610 +extern long proxy_ptrace (struct debugger *, int, pid_t, long, long, pid_t,
28611 + int *strace_out);
28612 +extern void debugger_cancelled_return(debugger_state *debugger, int result);
28617 + * Overrides for Emacs so that we follow Linus's tabbing style.
28618 + * Emacs will notice this stuff at the end of the file and automatically
28619 + * adjust the settings for this buffer only. This must remain at the end
28621 + * ---------------------------------------------------------------------------
28622 + * Local variables:
28623 + * c-file-style: "linux"
28626 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptrace.c um/arch/um/kernel/tt/ptproxy/ptrace.c
28627 --- orig/arch/um/kernel/tt/ptproxy/ptrace.c 1969-12-31 19:00:00.000000000 -0500
28628 +++ um/arch/um/kernel/tt/ptproxy/ptrace.c 2002-11-11 13:06:03.000000000 -0500
28630 +/**********************************************************************
28633 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
28634 +terms and conditions.
28636 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
28637 +**********************************************************************/
28639 +#include <errno.h>
28640 +#include <unistd.h>
28641 +#include <signal.h>
28642 +#include <sys/types.h>
28643 +#include <sys/time.h>
28644 +#include <sys/ptrace.h>
28645 +#include <sys/wait.h>
28646 +#include <asm/ptrace.h>
28648 +#include "ptproxy.h"
28649 +#include "debug.h"
28650 +#include "user_util.h"
28651 +#include "kern_util.h"
28652 +#include "ptrace_user.h"
28655 +long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
28656 + long arg3, long arg4, pid_t child, int *ret)
28663 + if(debugger->debugee->died) return(-ESRCH);
28666 + case PTRACE_ATTACH:
28667 + if(debugger->debugee->traced) return(-EPERM);
28669 + debugger->debugee->pid = arg2;
28670 + debugger->debugee->traced = 1;
28672 + if(is_valid_pid(arg2) && (arg2 != child)){
28673 + debugger->debugee->in_context = 0;
28674 + kill(arg2, SIGSTOP);
28675 + debugger->debugee->event = 1;
28676 + debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);
28679 + debugger->debugee->in_context = 1;
28680 + if(debugger->debugee->stopped)
28681 + child_proxy(child, W_STOPCODE(SIGSTOP));
28682 + else kill(child, SIGSTOP);
28687 + case PTRACE_DETACH:
28688 + if(!debugger->debugee->traced) return(-EPERM);
28690 + debugger->debugee->traced = 0;
28691 + debugger->debugee->pid = 0;
28692 + if(!debugger->debugee->in_context)
28693 + kill(child, SIGCONT);
28697 + case PTRACE_CONT:
28698 + if(!debugger->debugee->in_context) return(-EPERM);
28699 + *ret = PTRACE_CONT;
28700 + return(ptrace(PTRACE_CONT, child, arg3, arg4));
28702 +#ifdef UM_HAVE_GETFPREGS
28703 + case PTRACE_GETFPREGS:
28705 + long regs[FP_FRAME_SIZE];
28708 + result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
28709 + if(result == -1) return(-errno);
28711 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
28712 + ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
28718 +#ifdef UM_HAVE_GETFPXREGS
28719 + case PTRACE_GETFPXREGS:
28721 + long regs[FPX_FRAME_SIZE];
28724 + result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
28725 + if(result == -1) return(-errno);
28727 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
28728 + ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
28734 +#ifdef UM_HAVE_GETREGS
28735 + case PTRACE_GETREGS:
28737 + long regs[FRAME_SIZE];
28740 + result = ptrace(PTRACE_GETREGS, child, 0, regs);
28741 + if(result == -1) return(-errno);
28743 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
28744 + ptrace (PTRACE_POKEDATA, debugger->pid,
28745 + arg4 + 4 * i, regs[i]);
28751 + case PTRACE_KILL:
28752 + result = ptrace(PTRACE_KILL, child, arg3, arg4);
28753 + if(result == -1) return(-errno);
28757 + case PTRACE_PEEKDATA:
28758 + case PTRACE_PEEKTEXT:
28759 + case PTRACE_PEEKUSER:
28760 + /* The value being read out could be -1, so we have to
28761 + * check errno to see if there's an error, and zero it
28762 + * beforehand so we're not faked out by an old error
28766 + result = ptrace(arg1, child, arg3, 0);
28767 + if((result == -1) && (errno != 0)) return(-errno);
28769 + result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
28770 + if(result == -1) return(-errno);
28774 + case PTRACE_POKEDATA:
28775 + case PTRACE_POKETEXT:
28776 + case PTRACE_POKEUSER:
28777 + result = ptrace(arg1, child, arg3, arg4);
28778 + if(result == -1) return(-errno);
28780 + if(arg1 == PTRACE_POKEUSER) ptrace_pokeuser(arg3, arg4);
28783 +#ifdef UM_HAVE_SETFPREGS
28784 + case PTRACE_SETFPREGS:
28786 + long regs[FP_FRAME_SIZE];
28789 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
28790 + regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
28791 + arg4 + 4 * i, 0);
28792 + result = ptrace(PTRACE_SETFPREGS, child, 0, regs);
28793 + if(result == -1) return(-errno);
28799 +#ifdef UM_HAVE_SETFPXREGS
28800 + case PTRACE_SETFPXREGS:
28802 + long regs[FPX_FRAME_SIZE];
28805 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
28806 + regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
28807 + arg4 + 4 * i, 0);
28808 + result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);
28809 + if(result == -1) return(-errno);
28815 +#ifdef UM_HAVE_SETREGS
28816 + case PTRACE_SETREGS:
28818 + long regs[FRAME_SIZE];
28821 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
28822 + regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,
28823 + arg4 + 4 * i, 0);
28824 + result = ptrace(PTRACE_SETREGS, child, 0, regs);
28825 + if(result == -1) return(-errno);
28831 + case PTRACE_SINGLESTEP:
28832 + if(!debugger->debugee->in_context) return(-EPERM);
28833 + sigemptyset(&relay);
28834 + sigaddset(&relay, SIGSEGV);
28835 + sigaddset(&relay, SIGILL);
28836 + sigaddset(&relay, SIGBUS);
28837 + result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4);
28838 + if(result == -1) return(-errno);
28840 + status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
28842 + child_proxy(child, status);
28845 + case PTRACE_SYSCALL:
28846 + if(!debugger->debugee->in_context) return(-EPERM);
28847 + result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);
28848 + if(result == -1) return(-errno);
28850 + *ret = PTRACE_SYSCALL;
28853 + case PTRACE_TRACEME:
28860 + * Overrides for Emacs so that we follow Linus's tabbing style.
28861 + * Emacs will notice this stuff at the end of the file and automatically
28862 + * adjust the settings for this buffer only. This must remain at the end
28864 + * ---------------------------------------------------------------------------
28865 + * Local variables:
28866 + * c-file-style: "linux"
28869 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.c um/arch/um/kernel/tt/ptproxy/sysdep.c
28870 --- orig/arch/um/kernel/tt/ptproxy/sysdep.c 1969-12-31 19:00:00.000000000 -0500
28871 +++ um/arch/um/kernel/tt/ptproxy/sysdep.c 2002-10-23 21:08:04.000000000 -0400
28873 +/**********************************************************************
28876 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
28877 +terms and conditions.
28878 +**********************************************************************/
28880 +#include <stdio.h>
28881 +#include <string.h>
28882 +#include <stdlib.h>
28883 +#include <signal.h>
28884 +#include <sys/types.h>
28885 +#include <sys/ptrace.h>
28886 +#include <asm/ptrace.h>
28887 +#include <linux/unistd.h>
28888 +#include "ptrace_user.h"
28889 +#include "user_util.h"
28892 +int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4,
28895 + *arg1 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG1_OFFSET, 0);
28896 + *arg2 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG2_OFFSET, 0);
28897 + *arg3 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG3_OFFSET, 0);
28898 + *arg4 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG4_OFFSET, 0);
28899 + *arg5 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG5_OFFSET, 0);
28900 + return(ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET, 0));
28903 +void syscall_cancel(pid_t pid, int result)
28905 + if((ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
28906 + __NR_getpid) < 0) ||
28907 + (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) ||
28908 + (wait_for_stop(pid, SIGTRAP, PTRACE_SYSCALL, NULL) < 0) ||
28909 + (ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result) < 0) ||
28910 + (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0))
28911 + printk("ptproxy: couldn't cancel syscall: errno = %d\n",
28915 +void syscall_set_result(pid_t pid, long result)
28917 + ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result);
28920 +void syscall_continue(pid_t pid)
28922 + ptrace(PTRACE_SYSCALL, pid, 0, 0);
28925 +int syscall_pause(pid_t pid)
28927 + if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_pause) < 0){
28928 + printk("syscall_change - ptrace failed, errno = %d\n", errno);
28935 + * Overrides for Emacs so that we follow Linus's tabbing style.
28936 + * Emacs will notice this stuff at the end of the file and automatically
28937 + * adjust the settings for this buffer only. This must remain at the end
28939 + * ---------------------------------------------------------------------------
28940 + * Local variables:
28941 + * c-file-style: "linux"
28944 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.h um/arch/um/kernel/tt/ptproxy/sysdep.h
28945 --- orig/arch/um/kernel/tt/ptproxy/sysdep.h 1969-12-31 19:00:00.000000000 -0500
28946 +++ um/arch/um/kernel/tt/ptproxy/sysdep.h 2002-10-23 21:08:04.000000000 -0400
28948 +/**********************************************************************
28951 +Copyright (C) 1999 Lars Brinkhoff.
28952 +Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
28953 +See the file COPYING for licensing terms and conditions.
28954 +**********************************************************************/
28956 +extern int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3,
28957 + long *arg4, long *arg5);
28958 +extern void syscall_cancel (pid_t pid, long result);
28959 +extern void syscall_set_result (pid_t pid, long result);
28960 +extern void syscall_continue (pid_t pid);
28961 +extern int syscall_pause(pid_t pid);
28964 + * Overrides for Emacs so that we follow Linus's tabbing style.
28965 + * Emacs will notice this stuff at the end of the file and automatically
28966 + * adjust the settings for this buffer only. This must remain at the end
28968 + * ---------------------------------------------------------------------------
28969 + * Local variables:
28970 + * c-file-style: "linux"
28973 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.c um/arch/um/kernel/tt/ptproxy/wait.c
28974 --- orig/arch/um/kernel/tt/ptproxy/wait.c 1969-12-31 19:00:00.000000000 -0500
28975 +++ um/arch/um/kernel/tt/ptproxy/wait.c 2002-10-23 21:08:04.000000000 -0400
28977 +/**********************************************************************
28980 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
28981 +terms and conditions.
28983 +**********************************************************************/
28985 +#include <errno.h>
28986 +#include <signal.h>
28987 +#include <sys/wait.h>
28988 +#include <sys/ptrace.h>
28989 +#include <asm/ptrace.h>
28991 +#include "ptproxy.h"
28992 +#include "sysdep.h"
28994 +#include "user_util.h"
28995 +#include "sysdep/ptrace.h"
28996 +#include "sysdep/ptrace_user.h"
28997 +#include "sysdep/sigcontext.h"
28999 +int proxy_wait_return(struct debugger *debugger, pid_t unused)
29001 + debugger->waiting = 0;
29003 + if(debugger->debugee->died || (debugger->wait_options & __WCLONE)){
29004 + debugger_cancelled_return(debugger, -ECHILD);
29008 + if(debugger->debugee->zombie && debugger->debugee->event)
29009 + debugger->debugee->died = 1;
29011 + if(debugger->debugee->event){
29012 + debugger->debugee->event = 0;
29013 + ptrace(PTRACE_POKEDATA, debugger->pid,
29014 + debugger->wait_status_ptr,
29015 + debugger->debugee->wait_status);
29017 + ptrace (PTRACE_POKEDATA, pid, rusage_ptr, ...); */
29018 + debugger_cancelled_return(debugger, debugger->debugee->pid);
29022 + /* pause will return -EINTR, which happens to be right for wait */
29023 + debugger_normal_return(debugger, -1);
29027 +int parent_wait_return(struct debugger *debugger, pid_t unused)
29029 + return(debugger_normal_return(debugger, -1));
29032 +int real_wait_return(struct debugger *debugger)
29034 + unsigned long ip;
29037 + pid = debugger->pid;
29038 + ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
29039 + ip = IP_RESTART_SYSCALL(ip);
29040 + err = ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip);
29041 + if(ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip) < 0)
29042 + tracer_panic("real_wait_return : Failed to restart system "
29043 + "call, errno = %d\n");
29044 + if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
29045 + (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
29046 + (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
29047 + debugger_normal_return(debugger, -1))
29048 + tracer_panic("real_wait_return : gdb failed to wait, "
29054 + * Overrides for Emacs so that we follow Linus's tabbing style.
29055 + * Emacs will notice this stuff at the end of the file and automatically
29056 + * adjust the settings for this buffer only. This must remain at the end
29058 + * ---------------------------------------------------------------------------
29059 + * Local variables:
29060 + * c-file-style: "linux"
29063 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.h um/arch/um/kernel/tt/ptproxy/wait.h
29064 --- orig/arch/um/kernel/tt/ptproxy/wait.h 1969-12-31 19:00:00.000000000 -0500
29065 +++ um/arch/um/kernel/tt/ptproxy/wait.h 2002-10-23 21:08:04.000000000 -0400
29067 +/**********************************************************************
29070 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
29071 +terms and conditions.
29072 +**********************************************************************/
29074 +#ifndef __PTPROXY_WAIT_H
29075 +#define __PTPROXY_WAIT_H
29077 +extern int proxy_wait_return(struct debugger *debugger, pid_t unused);
29078 +extern int real_wait_return(struct debugger *debugger);
29079 +extern int parent_wait_return(struct debugger *debugger, pid_t unused);
29082 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_kern.c um/arch/um/kernel/tt/syscall_kern.c
29083 --- orig/arch/um/kernel/tt/syscall_kern.c 1969-12-31 19:00:00.000000000 -0500
29084 +++ um/arch/um/kernel/tt/syscall_kern.c 2002-12-08 19:32:53.000000000 -0500
29087 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
29088 + * Licensed under the GPL
29091 +#include "linux/types.h"
29092 +#include "linux/utime.h"
29093 +#include "linux/sys.h"
29094 +#include "asm/unistd.h"
29095 +#include "asm/ptrace.h"
29096 +#include "asm/uaccess.h"
29097 +#include "sysdep/syscalls.h"
29098 +#include "kern_util.h"
29100 +static inline int check_area(void *ptr, int size)
29102 + return(verify_area(VERIFY_WRITE, ptr, size));
29105 +static int check_readlink(struct pt_regs *regs)
29107 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
29108 + UPT_SYSCALL_ARG2(®s->regs)));
29111 +static int check_utime(struct pt_regs *regs)
29113 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
29114 + sizeof(struct utimbuf)));
29117 +static int check_oldstat(struct pt_regs *regs)
29119 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
29120 + sizeof(struct __old_kernel_stat)));
29123 +static int check_stat(struct pt_regs *regs)
29125 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
29126 + sizeof(struct stat)));
29129 +static int check_stat64(struct pt_regs *regs)
29131 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
29132 + sizeof(struct stat64)));
29137 + int (*check_params)(struct pt_regs *);
29140 +struct bogus this_is_bogus[256] = {
29141 + [ __NR_mknod ] = { 1, NULL },
29142 + [ __NR_mkdir ] = { 1, NULL },
29143 + [ __NR_rmdir ] = { 1, NULL },
29144 + [ __NR_unlink ] = { 1, NULL },
29145 + [ __NR_symlink ] = { 1, NULL },
29146 + [ __NR_link ] = { 1, NULL },
29147 + [ __NR_rename ] = { 1, NULL },
29148 + [ __NR_umount ] = { 1, NULL },
29149 + [ __NR_mount ] = { 1, NULL },
29150 + [ __NR_pivot_root ] = { 1, NULL },
29151 + [ __NR_chdir ] = { 1, NULL },
29152 + [ __NR_chroot ] = { 1, NULL },
29153 + [ __NR_open ] = { 1, NULL },
29154 + [ __NR_quotactl ] = { 1, NULL },
29155 + [ __NR_sysfs ] = { 1, NULL },
29156 + [ __NR_readlink ] = { 1, check_readlink },
29157 + [ __NR_acct ] = { 1, NULL },
29158 + [ __NR_execve ] = { 1, NULL },
29159 + [ __NR_uselib ] = { 1, NULL },
29160 + [ __NR_statfs ] = { 1, NULL },
29161 + [ __NR_truncate ] = { 1, NULL },
29162 + [ __NR_access ] = { 1, NULL },
29163 + [ __NR_chmod ] = { 1, NULL },
29164 + [ __NR_chown ] = { 1, NULL },
29165 + [ __NR_lchown ] = { 1, NULL },
29166 + [ __NR_utime ] = { 1, check_utime },
29167 + [ __NR_oldlstat ] = { 1, check_oldstat },
29168 + [ __NR_oldstat ] = { 1, check_oldstat },
29169 + [ __NR_stat ] = { 1, check_stat },
29170 + [ __NR_lstat ] = { 1, check_stat },
29171 + [ __NR_stat64 ] = { 1, check_stat64 },
29172 + [ __NR_lstat64 ] = { 1, check_stat64 },
29173 + [ __NR_chown32 ] = { 1, NULL },
29178 +static int check_bogosity(struct pt_regs *regs)
29180 + struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(®s->regs)];
29182 + if(!bogon->kernel_ds) return(0);
29183 + if(bogon->check_params && (*bogon->check_params)(regs))
29185 + set_fs(KERNEL_DS);
29189 +extern syscall_handler_t *sys_call_table[];
29191 +long execute_syscall_tt(void *r)
29193 + struct pt_regs *regs = r;
29197 + current->thread.nsyscalls++;
29199 + syscall = UPT_SYSCALL_NR(®s->regs);
29201 + if((syscall >= NR_syscalls) || (syscall < 0))
29203 + else if(honeypot && check_bogosity(regs))
29205 + else res = EXECUTE_SYSCALL(syscall, regs);
29209 + if(current->thread.mode.tt.singlestep_syscall){
29210 + current->thread.mode.tt.singlestep_syscall = 0;
29211 + current->ptrace &= ~PT_DTRACE;
29212 + force_sig(SIGTRAP, current);
29219 + * Overrides for Emacs so that we follow Linus's tabbing style.
29220 + * Emacs will notice this stuff at the end of the file and automatically
29221 + * adjust the settings for this buffer only. This must remain at the end
29223 + * ---------------------------------------------------------------------------
29224 + * Local variables:
29225 + * c-file-style: "linux"
29228 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_user.c um/arch/um/kernel/tt/syscall_user.c
29229 --- orig/arch/um/kernel/tt/syscall_user.c 1969-12-31 19:00:00.000000000 -0500
29230 +++ um/arch/um/kernel/tt/syscall_user.c 2002-12-08 21:00:11.000000000 -0500
29233 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
29234 + * Licensed under the GPL
29237 +#include <unistd.h>
29238 +#include <signal.h>
29239 +#include <errno.h>
29240 +#include <sys/ptrace.h>
29241 +#include <asm/unistd.h>
29242 +#include "sysdep/ptrace.h"
29243 +#include "sigcontext.h"
29244 +#include "ptrace_user.h"
29246 +#include "user_util.h"
29247 +#include "kern_util.h"
29248 +#include "syscall_user.h"
29252 +#define ERESTARTSYS 512
29253 +#define ERESTARTNOINTR 513
29254 +#define ERESTARTNOHAND 514
29256 +void syscall_handler_tt(int sig, union uml_pt_regs *regs)
29260 + int index, syscall;
29262 + syscall = UPT_SYSCALL_NR(regs);
29263 + sc = UPT_SC(regs);
29264 + SC_START_SYSCALL(sc);
29266 + index = record_syscall_start(syscall);
29268 + result = execute_syscall(regs);
29270 + /* regs->sc may have changed while the system call ran (there may
29271 + * have been an interrupt or segfault), so it needs to be refreshed.
29273 + UPT_SC(regs) = sc;
29275 + SC_SET_SYSCALL_RETURN(sc, result);
29276 + if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) ||
29277 + (result == -ERESTARTNOINTR))
29278 + do_signal(result);
29281 + record_syscall_end(index, result);
29284 +int do_syscall(void *task, int pid)
29286 + unsigned long proc_regs[FRAME_SIZE];
29287 + union uml_pt_regs *regs;
29290 + if(ptrace_getregs(pid, proc_regs) < 0)
29291 + tracer_panic("Couldn't read registers");
29292 + syscall = PT_SYSCALL_NR(proc_regs);
29294 + regs = TASK_REGS(task);
29295 + UPT_SYSCALL_NR(regs) = syscall;
29297 + if(syscall < 1) return(0);
29299 + if((syscall != __NR_sigreturn) &&
29300 + ((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
29301 + ((unsigned long *) PT_IP(proc_regs) <= &_etext))
29302 + tracer_panic("I'm tracing myself and I can't get out");
29304 + if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
29305 + __NR_getpid) < 0)
29306 + tracer_panic("do_syscall : Nullifying syscall failed, "
29307 + "errno = %d", errno);
29312 + * Overrides for Emacs so that we follow Linus's tabbing style.
29313 + * Emacs will notice this stuff at the end of the file and automatically
29314 + * adjust the settings for this buffer only. This must remain at the end
29316 + * ---------------------------------------------------------------------------
29317 + * Local variables:
29318 + * c-file-style: "linux"
29321 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/Makefile um/arch/um/kernel/tt/sys-i386/Makefile
29322 --- orig/arch/um/kernel/tt/sys-i386/Makefile 1969-12-31 19:00:00.000000000 -0500
29323 +++ um/arch/um/kernel/tt/sys-i386/Makefile 2002-10-23 21:08:04.000000000 -0400
29326 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29327 +# Licensed under the GPL
29330 +O_TARGET = sys-i386.o
29332 +obj-y = sigcontext.o
29334 +USER_OBJS = sigcontext.o
29336 +include $(TOPDIR)/Rules.make
29338 +$(USER_OBJS) : %.o: %.c
29339 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
29342 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/sigcontext.c um/arch/um/kernel/tt/sys-i386/sigcontext.c
29343 --- orig/arch/um/kernel/tt/sys-i386/sigcontext.c 1969-12-31 19:00:00.000000000 -0500
29344 +++ um/arch/um/kernel/tt/sys-i386/sigcontext.c 2002-12-01 23:33:52.000000000 -0500
29347 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29348 + * Licensed under the GPL
29351 +#include <stdlib.h>
29352 +#include <asm/sigcontext.h>
29353 +#include "kern_util.h"
29354 +#include "sysdep/frame.h"
29356 +int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data)
29358 + struct arch_frame_data *arch = data;
29359 + struct sigcontext *to = to_ptr, *from = from_ptr;
29360 + struct _fpstate *to_fp, *from_fp;
29361 + unsigned long sigs;
29364 + to_fp = to->fpstate;
29365 + from_fp = from->fpstate;
29366 + sigs = to->oldmask;
29367 + err = copy_from_user_proc(to, from, sizeof(*to));
29368 + to->oldmask = sigs;
29369 + if(to_fp != NULL){
29370 + err |= copy_from_user_proc(&to->fpstate, &to_fp,
29371 + sizeof(to->fpstate));
29372 + err |= copy_from_user_proc(to_fp, from_fp, arch->fpstate_size);
29377 +int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data)
29379 + struct arch_frame_data *arch = data;
29380 + struct sigcontext *to = to_ptr, *from = from_ptr;
29381 + struct _fpstate *to_fp, *from_fp;
29384 + to_fp = (struct _fpstate *)
29385 + (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
29386 + from_fp = from->fpstate;
29387 + err = copy_to_user_proc(to, from, sizeof(*to));
29388 + if(from_fp != NULL){
29389 + err |= copy_to_user_proc(&to->fpstate, &to_fp,
29390 + sizeof(to->fpstate));
29391 + err |= copy_to_user_proc(to_fp, from_fp, arch->fpstate_size);
29397 + * Overrides for Emacs so that we follow Linus's tabbing style.
29398 + * Emacs will notice this stuff at the end of the file and automatically
29399 + * adjust the settings for this buffer only. This must remain at the end
29401 + * ---------------------------------------------------------------------------
29402 + * Local variables:
29403 + * c-file-style: "linux"
29406 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/time.c um/arch/um/kernel/tt/time.c
29407 --- orig/arch/um/kernel/tt/time.c 1969-12-31 19:00:00.000000000 -0500
29408 +++ um/arch/um/kernel/tt/time.c 2002-10-23 21:08:04.000000000 -0400
29411 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
29412 + * Licensed under the GPL
29415 +#include <signal.h>
29416 +#include <sys/time.h>
29417 +#include <time_user.h>
29418 +#include "process.h"
29421 +void user_time_init_tt(void)
29423 + if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
29424 + panic("Couldn't set SIGVTALRM handler");
29425 + set_interval(ITIMER_VIRTUAL);
29429 + * Overrides for Emacs so that we follow Linus's tabbing style.
29430 + * Emacs will notice this stuff at the end of the file and automatically
29431 + * adjust the settings for this buffer only. This must remain at the end
29433 + * ---------------------------------------------------------------------------
29434 + * Local variables:
29435 + * c-file-style: "linux"
29438 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tlb.c um/arch/um/kernel/tt/tlb.c
29439 --- orig/arch/um/kernel/tt/tlb.c 1969-12-31 19:00:00.000000000 -0500
29440 +++ um/arch/um/kernel/tt/tlb.c 2002-12-19 13:03:11.000000000 -0500
29443 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29444 + * Licensed under the GPL
29447 +#include "linux/stddef.h"
29448 +#include "linux/kernel.h"
29449 +#include "linux/sched.h"
29450 +#include "asm/page.h"
29451 +#include "asm/pgtable.h"
29452 +#include "asm/uaccess.h"
29453 +#include "user_util.h"
29454 +#include "mem_user.h"
29457 +static void fix_range(struct mm_struct *mm, unsigned long start_addr,
29458 + unsigned long end_addr, int force)
29463 + unsigned long addr;
29464 + int r, w, x, err;
29466 + if((current->thread.mode.tt.extern_pid != -1) &&
29467 + (current->thread.mode.tt.extern_pid != os_getpid()))
29468 + panic("fix_range fixing wrong address space, current = 0x%p",
29470 + if(mm == NULL) return;
29471 + for(addr=start_addr;addr<end_addr;){
29472 + if(addr == TASK_SIZE){
29473 + /* Skip over kernel text, kernel data, and physical
29474 + * memory, which don't have ptes, plus kernel virtual
29475 + * memory, which is flushed separately, and remap
29476 + * the process stack. The only way to get here is
29477 + * if (end_addr == STACK_TOP) > TASK_SIZE, which is
29478 + * only true in the honeypot case.
29480 + addr = STACK_TOP - ABOVE_KMEM;
29483 + npgd = pgd_offset(mm, addr);
29484 + npmd = pmd_offset(npgd, addr);
29485 + if(pmd_present(*npmd)){
29486 + npte = pte_offset(npmd, addr);
29487 + r = pte_read(*npte);
29488 + w = pte_write(*npte);
29489 + x = pte_exec(*npte);
29490 + if(!pte_dirty(*npte)) w = 0;
29491 + if(!pte_young(*npte)){
29495 + if(force || pte_newpage(*npte)){
29496 + err = os_unmap_memory((void *) addr,
29499 + panic("munmap failed, errno = %d\n",
29501 + if(pte_present(*npte))
29503 + pte_val(*npte) & PAGE_MASK,
29504 + PAGE_SIZE, r, w, x);
29506 + else if(pte_newprot(*npte)){
29507 + protect_memory(addr, PAGE_SIZE, r, w, x, 1);
29509 + *npte = pte_mkuptodate(*npte);
29510 + addr += PAGE_SIZE;
29513 + if(force || pmd_newpage(*npmd)){
29514 + err = os_unmap_memory((void *) addr, PMD_SIZE);
29516 + panic("munmap failed, errno = %d\n",
29518 + pmd_mkuptodate(*npmd);
29520 + addr += PMD_SIZE;
29525 +atomic_t vmchange_seq = ATOMIC_INIT(1);
29527 +static void flush_kernel_vm_range(unsigned long start, unsigned long end,
29530 + struct mm_struct *mm;
29534 + unsigned long addr;
29535 + int updated = 0, err;
29538 + for(addr = start; addr < end;){
29539 + pgd = pgd_offset(mm, addr);
29540 + pmd = pmd_offset(pgd, addr);
29541 + if(pmd_present(*pmd)){
29542 + pte = pte_offset(pmd, addr);
29543 + if(!pte_present(*pte) || pte_newpage(*pte)){
29545 + err = os_unmap_memory((void *) addr,
29548 + panic("munmap failed, errno = %d\n",
29550 + if(pte_present(*pte))
29552 + pte_val(*pte) & PAGE_MASK,
29553 + PAGE_SIZE, 1, 1, 1);
29555 + else if(pte_newprot(*pte)){
29557 + protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
29559 + addr += PAGE_SIZE;
29562 + if(pmd_newpage(*pmd)){
29564 + err = os_unmap_memory((void *) addr, PMD_SIZE);
29566 + panic("munmap failed, errno = %d\n",
29569 + addr += PMD_SIZE;
29572 + if(updated && update_seq) atomic_inc(&vmchange_seq);
29575 +static void protect_vm_page(unsigned long addr, int w, int must_succeed)
29579 + err = protect_memory(addr, PAGE_SIZE, 1, w, 1, must_succeed);
29580 + if(err == 0) return;
29581 + else if((err == -EFAULT) || (err == -ENOMEM)){
29582 + flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
29583 + protect_vm_page(addr, w, 1);
29585 + else panic("protect_vm_page : protect failed, errno = %d\n", err);
29588 +void mprotect_kernel_vm(int w)
29590 + struct mm_struct *mm;
29594 + unsigned long addr;
29597 + for(addr = start_vm; addr < end_vm;){
29598 + pgd = pgd_offset(mm, addr);
29599 + pmd = pmd_offset(pgd, addr);
29600 + if(pmd_present(*pmd)){
29601 + pte = pte_offset(pmd, addr);
29602 + if(pte_present(*pte)) protect_vm_page(addr, w, 0);
29603 + addr += PAGE_SIZE;
29605 + else addr += PMD_SIZE;
29609 +void flush_tlb_kernel_vm_tt(void)
29611 + flush_kernel_vm_range(start_vm, end_vm, 1);
29614 +void __flush_tlb_one_tt(unsigned long addr)
29616 + flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
29619 +void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start,
29620 + unsigned long end)
29622 + if(mm != current->mm) return;
29624 + /* Assumes that the range start ... end is entirely within
29625 + * either process memory or kernel vm
29627 + if((start >= start_vm) && (start < end_vm))
29628 + flush_kernel_vm_range(start, end, 1);
29629 + else fix_range(mm, start, end, 0);
29632 +void flush_tlb_mm_tt(struct mm_struct *mm)
29634 + unsigned long seq;
29636 + if(mm != current->mm) return;
29638 + fix_range(mm, 0, STACK_TOP, 0);
29640 + seq = atomic_read(&vmchange_seq);
29641 + if(current->thread.mode.tt.vm_seq == seq) return;
29642 + current->thread.mode.tt.vm_seq = seq;
29643 + flush_kernel_vm_range(start_vm, end_vm, 0);
29646 +void force_flush_all_tt(void)
29648 + fix_range(current->mm, 0, STACK_TOP, 1);
29649 + flush_kernel_vm_range(start_vm, end_vm, 0);
29653 + * Overrides for Emacs so that we follow Linus's tabbing style.
29654 + * Emacs will notice this stuff at the end of the file and automatically
29655 + * adjust the settings for this buffer only. This must remain at the end
29657 + * ---------------------------------------------------------------------------
29658 + * Local variables:
29659 + * c-file-style: "linux"
29662 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tracer.c um/arch/um/kernel/tt/tracer.c
29663 --- orig/arch/um/kernel/tt/tracer.c 1969-12-31 19:00:00.000000000 -0500
29664 +++ um/arch/um/kernel/tt/tracer.c 2003-03-26 10:01:33.000000000 -0500
29667 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29668 + * Licensed under the GPL
29671 +#include <stdio.h>
29672 +#include <stdlib.h>
29673 +#include <stdarg.h>
29674 +#include <unistd.h>
29675 +#include <signal.h>
29676 +#include <errno.h>
29677 +#include <sched.h>
29678 +#include <string.h>
29679 +#include <sys/mman.h>
29680 +#include <sys/ptrace.h>
29681 +#include <sys/time.h>
29682 +#include <sys/wait.h>
29684 +#include "sysdep/ptrace.h"
29685 +#include "sigcontext.h"
29686 +#include "sysdep/sigcontext.h"
29688 +#include "signal_user.h"
29689 +#include "user_util.h"
29690 +#include "mem_user.h"
29691 +#include "process.h"
29692 +#include "kern_util.h"
29693 +#include "frame.h"
29694 +#include "chan_user.h"
29695 +#include "ptrace_user.h"
29699 +static int tracer_winch[2];
29701 +int is_tracer_winch(int pid, int fd, void *data)
29703 + if(pid != tracing_pid)
29706 + register_winch_irq(tracer_winch[0], fd, -1, data);
29710 +static void tracer_winch_handler(int sig)
29714 + if(write(tracer_winch[1], &c, sizeof(c)) != sizeof(c))
29715 + printk("tracer_winch_handler - write failed, errno = %d\n",
29719 +/* Called only by the tracing thread during initialization */
29721 +static void setup_tracer_winch(void)
29725 + err = os_pipe(tracer_winch, 1, 1);
29727 + printk("setup_tracer_winch : os_pipe failed, errno = %d\n",
29731 + signal(SIGWINCH, tracer_winch_handler);
29734 +void attach_process(int pid)
29736 + if((ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) ||
29737 + (ptrace(PTRACE_CONT, pid, 0, 0) < 0))
29738 + tracer_panic("OP_FORK failed to attach pid");
29739 + wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
29740 + if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
29741 + tracer_panic("OP_FORK failed to continue process");
29744 +void tracer_panic(char *format, ...)
29748 + va_start(ap, format);
29749 + vprintf(format, ap);
29751 + while(1) pause();
29754 +static void tracer_segv(int sig, struct sigcontext sc)
29756 + printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
29757 + SC_FAULT_ADDR(&sc), SC_IP(&sc));
29762 +/* Changed early in boot, and then only read */
29764 +int debug_stop = 1;
29765 +int debug_parent = 0;
29768 +static int signal_tramp(void *arg)
29770 + int (*proc)(void *);
29772 + if(honeypot && munmap((void *) (host_task_size - 0x10000000),
29774 + panic("Unmapping stack failed");
29775 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
29776 + panic("ptrace PTRACE_TRACEME failed");
29777 + os_stop_process(os_getpid());
29778 + change_sig(SIGWINCH, 0);
29779 + signal(SIGUSR1, SIG_IGN);
29780 + change_sig(SIGCHLD, 0);
29781 + signal(SIGSEGV, (__sighandler_t) sig_handler);
29782 + set_cmdline("(idle thread)");
29783 + set_init_pid(os_getpid());
29785 + return((*proc)(NULL));
29788 +static void sleeping_process_signal(int pid, int sig)
29791 + /* These two result from UML being ^Z-ed and bg-ed. PTRACE_CONT is
29792 + * right because the process must be in the kernel already.
29796 + if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
29797 + tracer_panic("sleeping_process_signal : Failed to "
29798 + "continue pid %d, errno = %d\n", pid,
29802 + /* This happens when the debugger (e.g. strace) is doing system call
29803 + * tracing on the kernel. During a context switch, the current task
29804 + * will be set to the incoming process and the outgoing process will
29805 + * hop into write and then read. Since it's not the current process
29806 + * any more, the trace of those will land here. So, we need to just
29807 + * PTRACE_SYSCALL it.
29810 + if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
29811 + tracer_panic("sleeping_process_signal : Failed to "
29812 + "PTRACE_SYSCALL pid %d, errno = %d\n",
29818 + tracer_panic("sleeping process %d got unexpected "
29819 + "signal : %d\n", pid, sig);
29824 +/* Accessed only by the tracing thread */
29825 +int debugger_pid = -1;
29826 +int debugger_parent = -1;
29827 +int debugger_fd = -1;
29833 + unsigned long addr;
29834 + struct timeval time;
29835 +} signal_record[1024][32];
29837 +int signal_index[32];
29839 +int debug_trace = 0;
29840 +extern int io_nsignals, io_count, intr_count;
29842 +extern void signal_usr1(int sig);
29844 +int tracing_pid = -1;
29846 +int tracer(int (*init_proc)(void *), void *sp)
29848 + void *task = NULL;
29849 + unsigned long eip = 0;
29850 + int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
29851 + int last_index, proc_id = 0, n, err, old_tracing = 0, strace = 0;
29853 + capture_signal_stack();
29854 + signal(SIGPIPE, SIG_IGN);
29855 + setup_tracer_winch();
29856 + tracing_pid = os_getpid();
29857 + printf("tracing thread pid = %d\n", tracing_pid);
29859 + pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
29860 + n = waitpid(pid, &status, WUNTRACED);
29862 + printf("waitpid on idle thread failed, errno = %d\n", errno);
29865 + if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
29866 + printf("Failed to continue idle thread, errno = %d\n", errno);
29870 + signal(SIGSEGV, (sighandler_t) tracer_segv);
29871 + signal(SIGUSR1, signal_usr1);
29873 + printf("Tracing thread pausing to be attached\n");
29877 + if(gdb_pid != -1)
29878 + debugger_pid = attach_debugger(pid, gdb_pid, 1);
29879 + else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop);
29880 + if(debug_parent){
29881 + debugger_parent = os_process_parent(debugger_pid);
29882 + init_parent_proxy(debugger_parent);
29883 + err = attach(debugger_parent);
29885 + printf("Failed to attach debugger parent %d, "
29886 + "errno = %d\n", debugger_parent, err);
29887 + debugger_parent = -1;
29890 + if(ptrace(PTRACE_SYSCALL, debugger_parent,
29892 + printf("Failed to continue debugger "
29893 + "parent, errno = %d\n", errno);
29894 + debugger_parent = -1;
29899 + set_cmdline("(tracing thread)");
29901 + if((pid = waitpid(-1, &status, WUNTRACED)) <= 0){
29902 + if(errno != ECHILD){
29903 + printf("wait failed - errno = %d\n", errno);
29907 + if(pid == debugger_pid){
29910 + if(WIFEXITED(status) || WIFSIGNALED(status))
29911 + debugger_pid = -1;
29912 + /* XXX Figure out how to deal with gdb and SMP */
29913 + else cont = debugger_signal(status, cpu_tasks[0].pid);
29914 + if(cont == PTRACE_SYSCALL) strace = 1;
29917 + else if(pid == debugger_parent){
29918 + debugger_parent_signal(status, pid);
29922 + if(WIFEXITED(status)) ;
29925 + printf("Child %d exited with status %d\n", pid,
29926 + WEXITSTATUS(status));
29929 + else if(WIFSIGNALED(status)){
29930 + sig = WTERMSIG(status);
29932 + printf("Child %d exited with signal %d\n", pid,
29936 + else if(WIFSTOPPED(status)){
29937 + proc_id = pid_to_processor_id(pid);
29938 + sig = WSTOPSIG(status);
29939 + if(signal_index[proc_id] == 1024){
29940 + signal_index[proc_id] = 0;
29941 + last_index = 1023;
29943 + else last_index = signal_index[proc_id] - 1;
29944 + if(((sig == SIGPROF) || (sig == SIGVTALRM) ||
29945 + (sig == SIGALRM)) &&
29946 + (signal_record[proc_id][last_index].signal == sig)&&
29947 + (signal_record[proc_id][last_index].pid == pid))
29948 + signal_index[proc_id] = last_index;
29949 + signal_record[proc_id][signal_index[proc_id]].pid = pid;
29950 + gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL);
29951 + eip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
29952 + signal_record[proc_id][signal_index[proc_id]].addr = eip;
29953 + signal_record[proc_id][signal_index[proc_id]++].signal = sig;
29955 + if(proc_id == -1){
29956 + sleeping_process_signal(pid, sig);
29960 + task = cpu_tasks[proc_id].task;
29961 + tracing = is_tracing(task);
29962 + old_tracing = tracing;
29967 + op = do_proc_op(task, proc_id);
29969 + case OP_TRACE_ON:
29970 + arch_leave_kernel(task, pid);
29977 + ptrace(PTRACE_KILL, pid, 0, 0);
29978 + return(op == OP_REBOOT);
29980 + printf("Detaching pid %d\n", pid);
29981 + detach(pid, SIGSTOP);
29986 + /* OP_EXEC switches host processes on us,
29987 + * we want to continue the new one.
29989 + pid = cpu_tasks[proc_id].pid;
29992 + if(!tracing && (debugger_pid != -1)){
29993 + child_signal(pid, status);
29997 + if(do_syscall(task, pid)) sig = SIGUSR2;
29998 + else clear_singlestep(task);
30001 + if(tracing) sig = 0;
30019 + set_tracing(task, tracing);
30021 + if(!tracing && old_tracing)
30022 + arch_enter_kernel(task, pid);
30024 + if(!tracing && (debugger_pid != -1) && (sig != 0) &&
30025 + (sig != SIGALRM) && (sig != SIGVTALRM) &&
30026 + (sig != SIGSEGV) && (sig != SIGTRAP) &&
30027 + (sig != SIGUSR2) && (sig != SIGIO) &&
30028 + (sig != SIGFPE)){
30029 + child_signal(pid, status);
30034 + if(singlestepping_tt(task))
30035 + cont_type = PTRACE_SINGLESTEP;
30036 + else cont_type = PTRACE_SYSCALL;
30038 + else cont_type = PTRACE_CONT;
30040 + if((cont_type == PTRACE_CONT) &&
30041 + (debugger_pid != -1) && strace)
30042 + cont_type = PTRACE_SYSCALL;
30044 + if(ptrace(cont_type, pid, 0, sig) != 0){
30045 + tracer_panic("ptrace failed to continue "
30046 + "process - errno = %d\n",
30054 +static int __init uml_debug_setup(char *line, int *add)
30060 + if(*line != '=') return(0);
30063 + while(line != NULL){
30064 + next = strchr(line, ',');
30065 + if(next) *next++ = '\0';
30067 + if(!strcmp(line, "go")) debug_stop = 0;
30068 + else if(!strcmp(line, "parent")) debug_parent = 1;
30069 + else printf("Unknown debug option : '%s'\n", line);
30076 +__uml_setup("debug", uml_debug_setup,
30078 +" Starts up the kernel under the control of gdb. See the \n"
30079 +" kernel debugging tutorial and the debugging session pages\n"
30080 +" at http://user-mode-linux.sourceforge.net/ for more information.\n\n"
30083 +static int __init uml_debugtrace_setup(char *line, int *add)
30088 +__uml_setup("debugtrace", uml_debugtrace_setup,
30090 +" Causes the tracing thread to pause until it is attached by a\n"
30091 +" debugger and continued. This is mostly for debugging crashes\n"
30092 +" early during boot, and should be pretty much obsoleted by\n"
30093 +" the debug switch.\n\n"
30096 +static int __init uml_honeypot_setup(char *line, int *add)
30098 + jail_setup("", add);
30102 +__uml_setup("honeypot", uml_honeypot_setup,
30104 +" This makes UML put process stacks in the same location as they are\n"
30105 +" on the host, allowing expoits such as stack smashes to work against\n"
30106 +" UML. This implies 'jail'.\n\n"
30110 + * Overrides for Emacs so that we follow Linus's tabbing style.
30111 + * Emacs will notice this stuff at the end of the file and automatically
30112 + * adjust the settings for this buffer only. This must remain at the end
30114 + * ---------------------------------------------------------------------------
30115 + * Local variables:
30116 + * c-file-style: "linux"
30119 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/trap_user.c um/arch/um/kernel/tt/trap_user.c
30120 --- orig/arch/um/kernel/tt/trap_user.c 1969-12-31 19:00:00.000000000 -0500
30121 +++ um/arch/um/kernel/tt/trap_user.c 2002-12-09 13:14:42.000000000 -0500
30124 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
30125 + * Licensed under the GPL
30128 +#include <stdlib.h>
30129 +#include <errno.h>
30130 +#include <signal.h>
30131 +#include <asm/sigcontext.h>
30132 +#include "sysdep/ptrace.h"
30133 +#include "signal_user.h"
30134 +#include "user_util.h"
30135 +#include "kern_util.h"
30139 +void sig_handler_common_tt(int sig, void *sc_ptr)
30141 + struct sigcontext *sc = sc_ptr;
30142 + struct tt_regs save_regs, *r;
30143 + struct signal_info *info;
30144 + int save_errno = errno, is_user;
30146 + unprotect_kernel_mem();
30148 + r = &TASK_REGS(get_current())->tt;
30150 + is_user = user_context(SC_SP(sc));
30152 + if(sig != SIGUSR2)
30155 + change_sig(SIGUSR1, 1);
30156 + info = &sig_info[sig];
30157 + if(!info->is_irq) unblock_signals();
30159 + (*info->handler)(sig, (union uml_pt_regs *) r);
30164 + change_sig(SIGUSR1, 0);
30165 + set_user_mode(NULL);
30168 + errno = save_errno;
30169 + if(is_user) protect_kernel_mem();
30173 + * Overrides for Emacs so that we follow Linus's tabbing style.
30174 + * Emacs will notice this stuff at the end of the file and automatically
30175 + * adjust the settings for this buffer only. This must remain at the end
30177 + * ---------------------------------------------------------------------------
30178 + * Local variables:
30179 + * c-file-style: "linux"
30182 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/uaccess_user.c um/arch/um/kernel/tt/uaccess_user.c
30183 --- orig/arch/um/kernel/tt/uaccess_user.c 1969-12-31 19:00:00.000000000 -0500
30184 +++ um/arch/um/kernel/tt/uaccess_user.c 2003-03-25 17:10:54.000000000 -0500
30187 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
30188 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
30189 + * Licensed under the GPL
30192 +#include <setjmp.h>
30193 +#include <string.h>
30194 +#include "user_util.h"
30195 +#include "uml_uaccess.h"
30197 +#include "kern_util.h"
30199 +int __do_copy_from_user(void *to, const void *from, int n,
30200 + void **fault_addr, void **fault_catcher)
30202 + struct tt_regs save = TASK_REGS(get_current())->tt;
30203 + unsigned long fault;
30206 + fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
30207 + __do_copy, &faulted);
30208 + TASK_REGS(get_current())->tt = save;
30210 + if(!faulted) return(0);
30211 + else return(n - (fault - (unsigned long) from));
30214 +static void __do_strncpy(void *dst, const void *src, int count)
30216 + strncpy(dst, src, count);
30219 +int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
30220 + void **fault_addr, void **fault_catcher)
30222 + struct tt_regs save = TASK_REGS(get_current())->tt;
30223 + unsigned long fault;
30226 + fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
30227 + __do_strncpy, &faulted);
30228 + TASK_REGS(get_current())->tt = save;
30230 + if(!faulted) return(strlen(dst));
30234 +static void __do_clear(void *to, const void *from, int n)
30236 + memset(to, 0, n);
30239 +int __do_clear_user(void *mem, unsigned long len,
30240 + void **fault_addr, void **fault_catcher)
30242 + struct tt_regs save = TASK_REGS(get_current())->tt;
30243 + unsigned long fault;
30246 + fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
30247 + __do_clear, &faulted);
30248 + TASK_REGS(get_current())->tt = save;
30250 + if(!faulted) return(0);
30251 + else return(len - (fault - (unsigned long) mem));
30254 +int __do_strnlen_user(const char *str, unsigned long n,
30255 + void **fault_addr, void **fault_catcher)
30257 + struct tt_regs save = TASK_REGS(get_current())->tt;
30259 + unsigned long *faddrp = (unsigned long *)fault_addr;
30262 + *fault_catcher = &jbuf;
30263 + if(setjmp(jbuf) == 0){
30264 + ret = strlen(str) + 1;
30267 + ret = *faddrp - (unsigned long) str;
30269 + *fault_addr = NULL;
30270 + *fault_catcher = NULL;
30272 + TASK_REGS(get_current())->tt = save;
30277 + * Overrides for Emacs so that we follow Linus's tabbing style.
30278 + * Emacs will notice this stuff at the end of the file and automatically
30279 + * adjust the settings for this buffer only. This must remain at the end
30281 + * ---------------------------------------------------------------------------
30282 + * Local variables:
30283 + * c-file-style: "linux"
30286 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/unmap.c um/arch/um/kernel/tt/unmap.c
30287 --- orig/arch/um/kernel/tt/unmap.c 1969-12-31 19:00:00.000000000 -0500
30288 +++ um/arch/um/kernel/tt/unmap.c 2002-12-11 10:42:21.000000000 -0500
30291 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
30292 + * Licensed under the GPL
30295 +#include <sys/mman.h>
30297 +int switcheroo(int fd, int prot, void *from, void *to, int size)
30299 + if(munmap(to, size) < 0){
30302 + if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
30305 + if(munmap(from, size) < 0){
30312 + * Overrides for Emacs so that we follow Linus's tabbing style.
30313 + * Emacs will notice this stuff at the end of the file and automatically
30314 + * adjust the settings for this buffer only. This must remain at the end
30316 + * ---------------------------------------------------------------------------
30317 + * Local variables:
30318 + * c-file-style: "linux"
30321 diff -Naur -X ../exclude-files orig/arch/um/kernel/tty_log.c um/arch/um/kernel/tty_log.c
30322 --- orig/arch/um/kernel/tty_log.c 1969-12-31 19:00:00.000000000 -0500
30323 +++ um/arch/um/kernel/tty_log.c 2003-04-16 16:35:20.000000000 -0400
30326 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and
30327 + * geoffrey hing <ghing@net.ohio-state.edu>
30328 + * Licensed under the GPL
30331 +#include <errno.h>
30332 +#include <string.h>
30333 +#include <stdio.h>
30334 +#include <stdlib.h>
30335 +#include <unistd.h>
30336 +#include <fcntl.h>
30337 +#include <sys/time.h>
30340 +#include "kern_util.h"
30343 +#define TTY_LOG_DIR "./"
30345 +/* Set early in boot and then unchanged */
30346 +static char *tty_log_dir = TTY_LOG_DIR;
30347 +static int tty_log_fd = -1;
30349 +#define TTY_LOG_OPEN 1
30350 +#define TTY_LOG_CLOSE 2
30351 +#define TTY_LOG_WRITE 3
30352 +#define TTY_LOG_EXEC 4
30354 +#define TTY_READ 1
30355 +#define TTY_WRITE 2
30357 +struct tty_log_buf {
30359 + unsigned long tty;
30362 + unsigned long sec;
30363 + unsigned long usec;
30366 +int open_tty_log(void *tty, void *current_tty)
30368 + struct timeval tv;
30369 + struct tty_log_buf data;
30370 + char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
30373 + gettimeofday(&tv, NULL);
30374 + if(tty_log_fd != -1){
30375 + data = ((struct tty_log_buf) { .what = TTY_LOG_OPEN,
30376 + .tty = (unsigned long) tty,
30377 + .len = sizeof(current_tty),
30379 + .sec = tv.tv_sec,
30380 + .usec = tv.tv_usec } );
30381 + write(tty_log_fd, &data, sizeof(data));
30382 + write(tty_log_fd, ¤t_tty, data.len);
30383 + return(tty_log_fd);
30386 + sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
30387 + (unsigned int) tv.tv_usec);
30389 + fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
30392 + printk("open_tty_log : couldn't open '%s', errno = %d\n",
30398 +void close_tty_log(int fd, void *tty)
30400 + struct tty_log_buf data;
30401 + struct timeval tv;
30403 + if(tty_log_fd != -1){
30404 + gettimeofday(&tv, NULL);
30405 + data = ((struct tty_log_buf) { .what = TTY_LOG_CLOSE,
30406 + .tty = (unsigned long) tty,
30409 + .sec = tv.tv_sec,
30410 + .usec = tv.tv_usec } );
30411 + write(tty_log_fd, &data, sizeof(data));
30417 +static int log_chunk(int fd, char *buf, int len)
30419 + int total = 0, try, missed, n;
30423 + try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
30424 + missed = copy_from_user_proc(chunk, buf, try);
30426 + n = write(fd, chunk, try);
30440 +int write_tty_log(int fd, char *buf, int len, void *tty, int is_read)
30442 + struct timeval tv;
30443 + struct tty_log_buf data;
30446 + if(fd == tty_log_fd){
30447 + gettimeofday(&tv, NULL);
30448 + direction = is_read ? TTY_READ : TTY_WRITE;
30449 + data = ((struct tty_log_buf) { .what = TTY_LOG_WRITE,
30450 + .tty = (unsigned long) tty,
30452 + .direction = direction,
30453 + .sec = tv.tv_sec,
30454 + .usec = tv.tv_usec } );
30455 + write(tty_log_fd, &data, sizeof(data));
30458 + return(log_chunk(fd, buf, len));
30461 +void log_exec(char **argv, void *tty)
30463 + struct timeval tv;
30464 + struct tty_log_buf data;
30468 + if(tty_log_fd == -1) return;
30470 + gettimeofday(&tv, NULL);
30473 + for(ptr = argv; ; ptr++){
30474 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
30476 + if(arg == NULL) break;
30477 + len += strlen_user_proc(arg);
30480 + data = ((struct tty_log_buf) { .what = TTY_LOG_EXEC,
30481 + .tty = (unsigned long) tty,
30484 + .sec = tv.tv_sec,
30485 + .usec = tv.tv_usec } );
30486 + write(tty_log_fd, &data, sizeof(data));
30488 + for(ptr = argv; ; ptr++){
30489 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
30491 + if(arg == NULL) break;
30492 + log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
30496 +static int __init set_tty_log_dir(char *name, int *add)
30498 + tty_log_dir = name;
30502 +__uml_setup("tty_log_dir=", set_tty_log_dir,
30503 +"tty_log_dir=<directory>\n"
30504 +" This is used to specify the directory where the logs of all pty\n"
30505 +" data from this UML machine will be written.\n\n"
30508 +static int __init set_tty_log_fd(char *name, int *add)
30512 + tty_log_fd = strtoul(name, &end, 0);
30513 + if((*end != '\0') || (end == name)){
30514 + printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
30520 +__uml_setup("tty_log_fd=", set_tty_log_fd,
30521 +"tty_log_fd=<fd>\n"
30522 +" This is used to specify a preconfigured file descriptor to which all\n"
30523 +" tty data will be written. Preconfigure the descriptor with something\n"
30524 +" like '10>tty_log tty_log_fd=10'.\n\n"
30529 + * Overrides for Emacs so that we follow Linus's tabbing style.
30530 + * Emacs will notice this stuff at the end of the file and automatically
30531 + * adjust the settings for this buffer only. This must remain at the end
30533 + * ---------------------------------------------------------------------------
30534 + * Local variables:
30535 + * c-file-style: "linux"
30538 diff -Naur -X ../exclude-files orig/arch/um/kernel/uaccess_user.c um/arch/um/kernel/uaccess_user.c
30539 --- orig/arch/um/kernel/uaccess_user.c 1969-12-31 19:00:00.000000000 -0500
30540 +++ um/arch/um/kernel/uaccess_user.c 2003-03-25 17:06:05.000000000 -0500
30543 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
30544 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
30545 + * Licensed under the GPL
30548 +#include <setjmp.h>
30549 +#include <string.h>
30551 +/* These are here rather than tt/uaccess.c because skas mode needs them in
30552 + * order to do SIGBUS recovery when a tmpfs mount runs out of room.
30555 +unsigned long __do_user_copy(void *to, const void *from, int n,
30556 + void **fault_addr, void **fault_catcher,
30557 + void (*op)(void *to, const void *from,
30558 + int n), int *faulted_out)
30560 + unsigned long *faddrp = (unsigned long *) fault_addr, ret;
30563 + *fault_catcher = &jbuf;
30564 + if(setjmp(jbuf) == 0){
30565 + (*op)(to, from, n);
30567 + *faulted_out = 0;
30571 + *faulted_out = 1;
30573 + *fault_addr = NULL;
30574 + *fault_catcher = NULL;
30578 +void __do_copy(void *to, const void *from, int n)
30580 + memcpy(to, from, n);
30584 +int __do_copy_to_user(void *to, const void *from, int n,
30585 + void **fault_addr, void **fault_catcher)
30587 + unsigned long fault;
30590 + fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
30591 + __do_copy, &faulted);
30592 + if(!faulted) return(0);
30593 + else return(n - (fault - (unsigned long) to));
30597 + * Overrides for Emacs so that we follow Linus's tabbing style.
30598 + * Emacs will notice this stuff at the end of the file and automatically
30599 + * adjust the settings for this buffer only. This must remain at the end
30601 + * ---------------------------------------------------------------------------
30602 + * Local variables:
30603 + * c-file-style: "linux"
30606 diff -Naur -X ../exclude-files orig/arch/um/kernel/um_arch.c um/arch/um/kernel/um_arch.c
30607 --- orig/arch/um/kernel/um_arch.c 1969-12-31 19:00:00.000000000 -0500
30608 +++ um/arch/um/kernel/um_arch.c 2003-03-06 19:06:09.000000000 -0500
30611 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
30612 + * Licensed under the GPL
30615 +#include "linux/config.h"
30616 +#include "linux/kernel.h"
30617 +#include "linux/sched.h"
30618 +#include "linux/notifier.h"
30619 +#include "linux/mm.h"
30620 +#include "linux/types.h"
30621 +#include "linux/tty.h"
30622 +#include "linux/init.h"
30623 +#include "linux/bootmem.h"
30624 +#include "linux/spinlock.h"
30625 +#include "linux/utsname.h"
30626 +#include "linux/sysrq.h"
30627 +#include "linux/seq_file.h"
30628 +#include "linux/delay.h"
30629 +#include "asm/page.h"
30630 +#include "asm/pgtable.h"
30631 +#include "asm/ptrace.h"
30632 +#include "asm/elf.h"
30633 +#include "asm/user.h"
30634 +#include "ubd_user.h"
30635 +#include "asm/current.h"
30636 +#include "user_util.h"
30637 +#include "kern_util.h"
30639 +#include "mprot.h"
30640 +#include "mem_user.h"
30643 +#include "initrd.h"
30646 +#include "choose-mode.h"
30647 +#include "mode_kern.h"
30650 +#define DEFAULT_COMMAND_LINE "root=/dev/ubd0"
30652 +struct cpuinfo_um boot_cpu_data = {
30653 + .loops_per_jiffy = 0,
30654 + .pgd_quick = NULL,
30655 + .pmd_quick = NULL,
30656 + .pte_quick = NULL,
30657 + .pgtable_cache_sz = 0,
30658 + .ipi_pipe = { -1, -1 }
30661 +unsigned long thread_saved_pc(struct thread_struct *thread)
30663 + return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
30667 +static int show_cpuinfo(struct seq_file *m, void *v)
30671 + index = (struct cpuinfo_um *)v - cpu_data;
30673 + if (!(cpu_online_map & (1 << index)))
30677 + seq_printf(m, "processor\t: %d\n", index);
30678 + seq_printf(m, "vendor_id\t: User Mode Linux\n");
30679 + seq_printf(m, "model name\t: UML\n");
30680 + seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
30681 + seq_printf(m, "host\t\t: %s\n", host_info);
30682 + seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
30683 + loops_per_jiffy/(500000/HZ),
30684 + (loops_per_jiffy/(5000/HZ)) % 100);
30689 +static void *c_start(struct seq_file *m, loff_t *pos)
30691 + return *pos < NR_CPUS ? cpu_data + *pos : NULL;
30694 +static void *c_next(struct seq_file *m, void *v, loff_t *pos)
30697 + return c_start(m, pos);
30700 +static void c_stop(struct seq_file *m, void *v)
30704 +struct seq_operations cpuinfo_op = {
30705 + .start = c_start,
30708 + .show = show_cpuinfo,
30711 +pte_t * __bad_pagetable(void)
30713 + panic("Someone should implement __bad_pagetable");
30717 +/* Set in linux_main */
30718 +unsigned long host_task_size;
30719 +unsigned long task_size;
30720 +unsigned long uml_start;
30722 +/* Set in early boot */
30723 +unsigned long uml_physmem;
30724 +unsigned long uml_reserved;
30725 +unsigned long start_vm;
30726 +unsigned long end_vm;
30729 +#ifdef CONFIG_MODE_TT
30730 +/* Pointer set in linux_main, the array itself is private to each thread,
30731 + * and changed at address space creation time so this poses no concurrency
30734 +static char *argv1_begin = NULL;
30735 +static char *argv1_end = NULL;
30738 +/* Set in early boot */
30739 +static int have_root __initdata = 0;
30740 +long physmem_size = 32 * 1024 * 1024;
30742 +void set_cmdline(char *cmd)
30744 +#ifdef CONFIG_MODE_TT
30745 + char *umid, *ptr;
30747 + if(CHOOSE_MODE(honeypot, 0)) return;
30749 + umid = get_umid(1);
30750 + if(umid != NULL){
30751 + snprintf(argv1_begin,
30752 + (argv1_end - argv1_begin) * sizeof(*ptr),
30754 + ptr = &argv1_begin[strlen(argv1_begin)];
30756 + else ptr = argv1_begin;
30758 + snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
30759 + memset(argv1_begin + strlen(argv1_begin), '\0',
30760 + argv1_end - argv1_begin - strlen(argv1_begin));
30764 +static char *usage_string =
30765 +"User Mode Linux v%s\n"
30766 +" available at http://user-mode-linux.sourceforge.net/\n\n";
30768 +static int __init uml_version_setup(char *line, int *add)
30770 + printf("%s\n", system_utsname.release);
30774 +__uml_setup("--version", uml_version_setup,
30776 +" Prints the version number of the kernel.\n\n"
30779 +static int __init uml_root_setup(char *line, int *add)
30785 +__uml_setup("root=", uml_root_setup,
30786 +"root=<file containing the root fs>\n"
30787 +" This is actually used by the generic kernel in exactly the same\n"
30788 +" way as in any other kernel. If you configure a number of block\n"
30789 +" devices and want to boot off something other than ubd0, you \n"
30790 +" would use something like:\n"
30791 +" root=/dev/ubd5\n\n"
30795 +static int __init uml_ncpus_setup(char *line, int *add)
30797 + if (!sscanf(line, "%d", &ncpus)) {
30798 + printf("Couldn't parse [%s]\n", line);
30805 +__uml_setup("ncpus=", uml_ncpus_setup,
30806 +"ncpus=<# of desired CPUs>\n"
30807 +" This tells an SMP kernel how many virtual processors to start.\n\n"
30813 +#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
30814 +#define DEFAULT_TT 0
30816 +static int __init mode_tt_setup(char *line, int *add)
30823 +#ifdef CONFIG_MODE_SKAS
30825 +#define DEFAULT_TT 0
30827 +static int __init mode_tt_setup(char *line, int *add)
30829 + printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
30834 +#ifdef CONFIG_MODE_TT
30836 +#define DEFAULT_TT 1
30838 +static int __init mode_tt_setup(char *line, int *add)
30840 + printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
30846 +#error Either CONFIG_MODE_TT or CONFIG_MODE_SKAS must be enabled
30852 +__uml_setup("mode=tt", mode_tt_setup,
30854 +" When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n"
30855 +" forces UML to run in tt (tracing thread) mode. It is not the default\n"
30856 +" because it's slower and less secure than skas mode.\n\n"
30859 +int mode_tt = DEFAULT_TT;
30861 +static int __init Usage(char *line, int *add)
30865 + printf(usage_string, system_utsname.release);
30866 + p = &__uml_help_start;
30867 + while (p < &__uml_help_end) {
30868 + printf("%s", *p);
30874 +__uml_setup("--help", Usage,
30876 +" Prints this message.\n\n"
30879 +static int __init uml_checksetup(char *line, int *add)
30881 + struct uml_param *p;
30883 + p = &__uml_setup_start;
30884 + while(p < &__uml_setup_end) {
30887 + n = strlen(p->str);
30888 + if(!strncmp(line, p->str, n)){
30889 + if (p->setup_func(line + n, add)) return 1;
30896 +static void __init uml_postsetup(void)
30900 + p = &__uml_postsetup_start;
30901 + while(p < &__uml_postsetup_end){
30908 +/* Set during early boot */
30909 +unsigned long brk_start;
30910 +static struct vm_reserved kernel_vm_reserved;
30912 +#define MIN_VMALLOC (32 * 1024 * 1024)
30914 +int linux_main(int argc, char **argv)
30916 + unsigned long avail;
30917 + unsigned long virtmem_size, max_physmem;
30918 + unsigned int i, add, err;
30920 + for (i = 1; i < argc; i++){
30921 + if((i == 1) && (argv[i][0] == ' ')) continue;
30923 + uml_checksetup(argv[i], &add);
30924 + if(add) add_arg(saved_command_line, argv[i]);
30926 + if(have_root == 0) add_arg(saved_command_line, DEFAULT_COMMAND_LINE);
30928 + mode_tt = force_tt ? 1 : !can_do_skas();
30929 + uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
30930 + &host_task_size, &task_size);
30932 + brk_start = (unsigned long) sbrk(0);
30933 + CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
30935 + uml_physmem = uml_start;
30937 + /* Reserve up to 4M after the current brk */
30938 + uml_reserved = ROUND_4M(brk_start) + (1 << 22);
30940 + setup_machinename(system_utsname.machine);
30942 +#ifdef CONFIG_MODE_TT
30943 + argv1_begin = argv[1];
30944 + argv1_end = &argv[1][strlen(argv[1])];
30947 + set_usable_vm(uml_physmem, get_kmem_end());
30950 + max_physmem = get_kmem_end() - uml_physmem - MIN_VMALLOC;
30951 + if(physmem_size > max_physmem){
30952 + highmem = physmem_size - max_physmem;
30953 + physmem_size -= highmem;
30954 +#ifndef CONFIG_HIGHMEM
30956 + printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
30957 + "to %ld bytes\n", physmem_size);
30961 + high_physmem = uml_physmem + physmem_size;
30962 + high_memory = (void *) high_physmem;
30964 + start_vm = VMALLOC_START;
30966 + setup_physmem(uml_physmem, uml_reserved, physmem_size);
30967 + virtmem_size = physmem_size;
30968 + avail = get_kmem_end() - start_vm;
30969 + if(physmem_size > avail) virtmem_size = avail;
30970 + end_vm = start_vm + virtmem_size;
30972 + if(virtmem_size < physmem_size)
30973 + printf("Kernel virtual memory size shrunk to %ld bytes\n",
30976 + err = reserve_vm(high_physmem, end_vm, &kernel_vm_reserved);
30978 + printf("Failed to reserve VM area for kernel VM\n");
30984 + init_task.thread.kernel_stack = (unsigned long) &init_task +
30987 + task_protections((unsigned long) &init_task);
30988 + os_flush_stdout();
30990 + return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
30993 +static int panic_exit(struct notifier_block *self, unsigned long unused1,
30996 +#ifdef CONFIG_SYSRQ
30997 + handle_sysrq('p', ¤t->thread.regs, NULL, NULL);
31003 +static struct notifier_block panic_exit_notifier = {
31004 + .notifier_call = panic_exit,
31009 +void __init setup_arch(char **cmdline_p)
31011 + notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
31013 + strcpy(command_line, saved_command_line);
31014 + *cmdline_p = command_line;
31015 + setup_hostinfo();
31018 +void __init check_bugs(void)
31020 + arch_check_bugs();
31026 + * Overrides for Emacs so that we follow Linus's tabbing style.
31027 + * Emacs will notice this stuff at the end of the file and automatically
31028 + * adjust the settings for this buffer only. This must remain at the end
31030 + * ---------------------------------------------------------------------------
31031 + * Local variables:
31032 + * c-file-style: "linux"
31035 diff -Naur -X ../exclude-files orig/arch/um/kernel/umid.c um/arch/um/kernel/umid.c
31036 --- orig/arch/um/kernel/umid.c 1969-12-31 19:00:00.000000000 -0500
31037 +++ um/arch/um/kernel/umid.c 2003-02-24 23:11:23.000000000 -0500
31040 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
31041 + * Licensed under the GPL
31044 +#include <stdio.h>
31045 +#include <unistd.h>
31046 +#include <fcntl.h>
31047 +#include <errno.h>
31048 +#include <string.h>
31049 +#include <stdlib.h>
31050 +#include <dirent.h>
31051 +#include <signal.h>
31052 +#include <sys/stat.h>
31053 +#include <sys/param.h>
31058 +#include "user_util.h"
31059 +#include "choose-mode.h"
31061 +#define UMID_LEN 64
31062 +#define UML_DIR "~/.uml/"
31064 +/* Changed by set_umid and make_umid, which are run early in boot */
31065 +static char umid[UMID_LEN] = { 0 };
31067 +/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
31068 +static char *uml_dir = UML_DIR;
31070 +/* Changed by set_umid */
31071 +static int umid_is_random = 1;
31072 +static int umid_inited = 0;
31074 +static int make_umid(int (*printer)(const char *fmt, ...));
31076 +static int __init set_umid(char *name, int is_random,
31077 + int (*printer)(const char *fmt, ...))
31080 + (*printer)("Unique machine name can't be set twice\n");
31084 + if(strlen(name) > UMID_LEN - 1)
31085 + (*printer)("Unique machine name is being truncated to %s "
31086 + "characters\n", UMID_LEN);
31087 + strncpy(umid, name, UMID_LEN - 1);
31088 + umid[UMID_LEN - 1] = '\0';
31090 + umid_is_random = is_random;
31095 +static int __init set_umid_arg(char *name, int *add)
31097 + return(set_umid(name, 0, printf));
31100 +__uml_setup("umid=", set_umid_arg,
31102 +" This is used to assign a unique identity to this UML machine and\n"
31103 +" is used for naming the pid file and management console socket.\n\n"
31106 +int __init umid_file_name(char *name, char *buf, int len)
31110 + if(!umid_inited && make_umid(printk)) return(-1);
31112 + n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
31114 + printk("umid_file_name : buffer too short\n");
31118 + sprintf(buf, "%s%s/%s", uml_dir, umid, name);
31122 +extern int tracing_pid;
31124 +static int __init create_pid_file(void)
31126 + char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
31127 + char pid[sizeof("nnnnn\0")];
31130 + if(umid_file_name("pid", file, sizeof(file))) return 0;
31132 + fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
31135 + printf("Open of machine pid file \"%s\" failed - "
31136 + "errno = %d\n", file, -fd);
31140 + sprintf(pid, "%d\n", os_getpid());
31141 + if(write(fd, pid, strlen(pid)) != strlen(pid))
31142 + printf("Write of pid file failed - errno = %d\n", errno);
31147 +static int actually_do_remove(char *dir)
31150 + struct dirent *ent;
31154 + if((directory = opendir(dir)) == NULL){
31155 + printk("actually_do_remove : couldn't open directory '%s', "
31156 + "errno = %d\n", dir, errno);
31159 + while((ent = readdir(directory)) != NULL){
31160 + if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
31162 + len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
31163 + if(len > sizeof(file)){
31164 + printk("Not deleting '%s' from '%s' - name too long\n",
31165 + ent->d_name, dir);
31168 + sprintf(file, "%s/%s", dir, ent->d_name);
31169 + if(unlink(file) < 0){
31170 + printk("actually_do_remove : couldn't remove '%s' "
31171 + "from '%s', errno = %d\n", ent->d_name, dir,
31176 + if(rmdir(dir) < 0){
31177 + printk("actually_do_remove : couldn't rmdir '%s', "
31178 + "errno = %d\n", dir, errno);
31184 +void remove_umid_dir(void)
31186 + char dir[strlen(uml_dir) + UMID_LEN + 1];
31187 + if(!umid_inited) return;
31189 + sprintf(dir, "%s%s", uml_dir, umid);
31190 + actually_do_remove(dir);
31193 +char *get_umid(int only_if_set)
31195 + if(only_if_set && umid_is_random) return(NULL);
31199 +int not_dead_yet(char *dir)
31201 + char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
31202 + char pid[sizeof("nnnnn\0")], *end;
31205 + sprintf(file, "%s/pid", dir);
31207 + if((fd = os_open_file(file, of_read(OPENFLAGS()), 0)) < 0){
31208 + if(fd != -ENOENT){
31209 + printk("not_dead_yet : couldn't open pid file '%s', "
31210 + "errno = %d\n", file, -fd);
31216 + if(read(fd, pid, sizeof(pid)) < 0){
31217 + printk("not_dead_yet : couldn't read pid file '%s', "
31218 + "errno = %d\n", file, errno);
31221 + p = strtoul(pid, &end, 0);
31223 + printk("not_dead_yet : couldn't parse pid file '%s', "
31224 + "errno = %d\n", file, errno);
31227 + if(((kill(p, 0) < 0) && (errno == ESRCH)) ||
31228 + (p == CHOOSE_MODE(tracing_pid, os_getpid())))
31231 + if(!dead) return(1);
31232 + return(actually_do_remove(dir));
31235 +static int __init set_uml_dir(char *name, int *add)
31237 + if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
31238 + uml_dir = malloc(strlen(name) + 1);
31239 + if(uml_dir == NULL){
31240 + printf("Failed to malloc uml_dir - error = %d\n",
31245 + sprintf(uml_dir, "%s/", name);
31247 + else uml_dir = name;
31251 +static int __init make_uml_dir(void)
31253 + char dir[MAXPATHLEN + 1] = { '\0' };
31256 + if(*uml_dir == '~'){
31257 + char *home = getenv("HOME");
31259 + if(home == NULL){
31260 + printf("make_uml_dir : no value in environment for "
31264 + strncpy(dir, home, sizeof(dir));
31267 + len = strlen(dir);
31268 + strncat(dir, uml_dir, sizeof(dir) - len);
31269 + len = strlen(dir);
31270 + if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){
31272 + dir[len + 1] = '\0';
31275 + if((uml_dir = malloc(strlen(dir) + 1)) == NULL){
31276 + printf("make_uml_dir : malloc failed, errno = %d\n", errno);
31279 + strcpy(uml_dir, dir);
31281 + if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
31282 + printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
31288 +static int __init make_umid(int (*printer)(const char *fmt, ...))
31291 + char tmp[strlen(uml_dir) + UMID_LEN + 1];
31293 + strncpy(tmp, uml_dir, sizeof(tmp) - 1);
31294 + tmp[sizeof(tmp) - 1] = '\0';
31296 + if(!umid_inited){
31297 + strcat(tmp, "XXXXXX");
31298 + fd = mkstemp(tmp);
31300 + (*printer)("make_umid - mkstemp failed, errno = %d\n",
31306 + /* There's a nice tiny little race between this unlink and
31307 + * the mkdir below. It'd be nice if there were a mkstemp
31308 + * for directories.
31311 + set_umid(&tmp[strlen(uml_dir)], 1, printer);
31314 + sprintf(tmp, "%s%s", uml_dir, umid);
31316 + if((err = mkdir(tmp, 0777)) < 0){
31317 + if(errno == EEXIST){
31318 + if(not_dead_yet(tmp)){
31319 + (*printer)("umid '%s' is in use\n", umid);
31322 + err = mkdir(tmp, 0777);
31326 + (*printer)("Failed to create %s - errno = %d\n", umid, errno);
31333 +__uml_setup("uml_dir=", set_uml_dir,
31334 +"uml_dir=<directory>\n"
31335 +" The location to place the pid and umid files.\n\n"
31338 +__uml_postsetup(make_uml_dir);
31340 +static int __init make_umid_setup(void)
31342 + return(make_umid(printf));
31345 +__uml_postsetup(make_umid_setup);
31346 +__uml_postsetup(create_pid_file);
31349 + * Overrides for Emacs so that we follow Linus's tabbing style.
31350 + * Emacs will notice this stuff at the end of the file and automatically
31351 + * adjust the settings for this buffer only. This must remain at the end
31353 + * ---------------------------------------------------------------------------
31354 + * Local variables:
31355 + * c-file-style: "linux"
31358 diff -Naur -X ../exclude-files orig/arch/um/kernel/user_syms.c um/arch/um/kernel/user_syms.c
31359 --- orig/arch/um/kernel/user_syms.c 1969-12-31 19:00:00.000000000 -0500
31360 +++ um/arch/um/kernel/user_syms.c 2002-10-23 21:08:04.000000000 -0400
31362 +#include <stdio.h>
31363 +#include <unistd.h>
31364 +#include <fcntl.h>
31365 +#include <dirent.h>
31366 +#include <errno.h>
31367 +#include <utime.h>
31368 +#include <string.h>
31369 +#include <sys/stat.h>
31370 +#include <sys/vfs.h>
31371 +#include <sys/ioctl.h>
31372 +#include "user_util.h"
31373 +#include "mem_user.h"
31375 +/* XXX All the __CONFIG_* stuff is broken because this file can't include
31379 +/* Had to steal this from linux/module.h because that file can't be included
31380 + * since this includes various user-level headers.
31383 +struct module_symbol
31385 + unsigned long value;
31386 + const char *name;
31389 +/* Indirect stringification. */
31391 +#define __MODULE_STRING_1(x) #x
31392 +#define __MODULE_STRING(x) __MODULE_STRING_1(x)
31394 +#if !defined(__AUTOCONF_INCLUDED__)
31396 +#define __EXPORT_SYMBOL(sym,str) error config_must_be_included_before_module
31397 +#define EXPORT_SYMBOL(var) error config_must_be_included_before_module
31398 +#define EXPORT_SYMBOL_NOVERS(var) error config_must_be_included_before_module
31400 +#elif !defined(__CONFIG_MODULES__)
31402 +#define __EXPORT_SYMBOL(sym,str)
31403 +#define EXPORT_SYMBOL(var)
31404 +#define EXPORT_SYMBOL_NOVERS(var)
31408 +#define __EXPORT_SYMBOL(sym, str) \
31409 +const char __kstrtab_##sym[] \
31410 +__attribute__((section(".kstrtab"))) = str; \
31411 +const struct module_symbol __ksymtab_##sym \
31412 +__attribute__((section("__ksymtab"))) = \
31413 +{ (unsigned long)&sym, __kstrtab_##sym }
31415 +#if defined(__MODVERSIONS__) || !defined(__CONFIG_MODVERSIONS__)
31416 +#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var))
31418 +#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var)))
31421 +#define EXPORT_SYMBOL_NOVERS(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var))
31425 +EXPORT_SYMBOL(__errno_location);
31427 +EXPORT_SYMBOL(access);
31428 +EXPORT_SYMBOL(open);
31429 +EXPORT_SYMBOL(open64);
31430 +EXPORT_SYMBOL(close);
31431 +EXPORT_SYMBOL(read);
31432 +EXPORT_SYMBOL(write);
31433 +EXPORT_SYMBOL(dup2);
31434 +EXPORT_SYMBOL(__xstat);
31435 +EXPORT_SYMBOL(__lxstat);
31436 +EXPORT_SYMBOL(__lxstat64);
31437 +EXPORT_SYMBOL(lseek);
31438 +EXPORT_SYMBOL(lseek64);
31439 +EXPORT_SYMBOL(chown);
31440 +EXPORT_SYMBOL(truncate);
31441 +EXPORT_SYMBOL(utime);
31442 +EXPORT_SYMBOL(chmod);
31443 +EXPORT_SYMBOL(rename);
31444 +EXPORT_SYMBOL(__xmknod);
31446 +EXPORT_SYMBOL(symlink);
31447 +EXPORT_SYMBOL(link);
31448 +EXPORT_SYMBOL(unlink);
31449 +EXPORT_SYMBOL(readlink);
31451 +EXPORT_SYMBOL(mkdir);
31452 +EXPORT_SYMBOL(rmdir);
31453 +EXPORT_SYMBOL(opendir);
31454 +EXPORT_SYMBOL(readdir);
31455 +EXPORT_SYMBOL(closedir);
31456 +EXPORT_SYMBOL(seekdir);
31457 +EXPORT_SYMBOL(telldir);
31459 +EXPORT_SYMBOL(ioctl);
31461 +extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes,
31462 + __off64_t __offset);
31463 +extern ssize_t pwrite64 (int __fd, __const void *__buf, size_t __n,
31464 + __off64_t __offset);
31465 +EXPORT_SYMBOL(pread64);
31466 +EXPORT_SYMBOL(pwrite64);
31468 +EXPORT_SYMBOL(statfs);
31469 +EXPORT_SYMBOL(statfs64);
31471 +EXPORT_SYMBOL(memcpy);
31472 +EXPORT_SYMBOL(getuid);
31474 +EXPORT_SYMBOL(memset);
31475 +EXPORT_SYMBOL(strstr);
31477 +EXPORT_SYMBOL(find_iomem);
31478 diff -Naur -X ../exclude-files orig/arch/um/kernel/user_util.c um/arch/um/kernel/user_util.c
31479 --- orig/arch/um/kernel/user_util.c 1969-12-31 19:00:00.000000000 -0500
31480 +++ um/arch/um/kernel/user_util.c 2003-04-23 20:41:54.000000000 -0400
31483 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
31484 + * Licensed under the GPL
31487 +#include <stdio.h>
31488 +#include <stdlib.h>
31489 +#include <fcntl.h>
31490 +#include <unistd.h>
31491 +#include <limits.h>
31492 +#include <sys/mman.h>
31493 +#include <sys/stat.h>
31494 +#include <sys/ptrace.h>
31495 +#include <sys/utsname.h>
31496 +#include <sys/param.h>
31497 +#include <sys/time.h>
31498 +#include "asm/types.h"
31499 +#include <ctype.h>
31500 +#include <signal.h>
31502 +#include <errno.h>
31503 +#include <stdarg.h>
31504 +#include <sched.h>
31505 +#include <termios.h>
31506 +#include <string.h>
31507 +#include "user_util.h"
31508 +#include "kern_util.h"
31510 +#include "mem_user.h"
31512 +#include "helper.h"
31513 +#include "uml-config.h"
31515 +#define COMMAND_LINE_SIZE _POSIX_ARG_MAX
31517 +/* Changed in linux_main and setup_arch, which run before SMP is started */
31518 +char saved_command_line[COMMAND_LINE_SIZE] = { 0 };
31519 +char command_line[COMMAND_LINE_SIZE] = { 0 };
31521 +void add_arg(char *cmd_line, char *arg)
31523 + if (strlen(cmd_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
31524 + printf("add_arg: Too much command line!\n");
31527 + if(strlen(cmd_line) > 0) strcat(cmd_line, " ");
31528 + strcat(cmd_line, arg);
31533 + while(1) sleep(1000000);
31536 +void stack_protections(unsigned long address)
31538 + int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
31540 + if(mprotect((void *) address, page_size(), prot) < 0)
31541 + panic("protecting stack failed, errno = %d", errno);
31544 +void task_protections(unsigned long address)
31546 + unsigned long guard = address + page_size();
31547 + unsigned long stack = guard + page_size();
31548 + int prot = 0, pages;
31550 + if(mprotect((void *) guard, page_size(), prot) < 0)
31551 + panic("protecting guard page failed, errno = %d", errno);
31553 + pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
31554 + prot = PROT_READ | PROT_WRITE | PROT_EXEC;
31555 + if(mprotect((void *) stack, pages * page_size(), prot) < 0)
31556 + panic("protecting stack failed, errno = %d", errno);
31559 +int wait_for_stop(int pid, int sig, int cont_type, void *relay)
31561 + sigset_t *relay_signals = relay;
31565 + if(((ret = waitpid(pid, &status, WUNTRACED)) < 0) ||
31566 + !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
31568 + if(errno == EINTR) continue;
31569 + printk("wait failed, errno = %d\n",
31572 + else if(WIFEXITED(status))
31573 + printk("process exited with status %d\n",
31574 + WEXITSTATUS(status));
31575 + else if(WIFSIGNALED(status))
31576 + printk("process exited with signal %d\n",
31577 + WTERMSIG(status));
31578 + else if((WSTOPSIG(status) == SIGVTALRM) ||
31579 + (WSTOPSIG(status) == SIGALRM) ||
31580 + (WSTOPSIG(status) == SIGIO) ||
31581 + (WSTOPSIG(status) == SIGPROF) ||
31582 + (WSTOPSIG(status) == SIGCHLD) ||
31583 + (WSTOPSIG(status) == SIGWINCH) ||
31584 + (WSTOPSIG(status) == SIGINT)){
31585 + ptrace(cont_type, pid, 0, WSTOPSIG(status));
31588 + else if((relay_signals != NULL) &&
31589 + sigismember(relay_signals, WSTOPSIG(status))){
31590 + ptrace(cont_type, pid, 0, WSTOPSIG(status));
31593 + else printk("process stopped with signal %d\n",
31594 + WSTOPSIG(status));
31595 + panic("wait_for_stop failed to wait for %d to stop "
31596 + "with %d\n", pid, sig);
31602 +int raw(int fd, int complain)
31604 + struct termios tt;
31607 + tcgetattr(fd, &tt);
31609 + err = tcsetattr(fd, TCSANOW, &tt);
31610 + if((err < 0) && complain){
31611 + printk("tcsetattr failed, errno = %d\n", errno);
31617 +void setup_machinename(char *machine_out)
31619 + struct utsname host;
31622 + strcpy(machine_out, host.machine);
31625 +char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1];
31627 +void setup_hostinfo(void)
31629 + struct utsname host;
31632 + sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename,
31633 + host.release, host.version, host.machine);
31637 + * Overrides for Emacs so that we follow Linus's tabbing style.
31638 + * Emacs will notice this stuff at the end of the file and automatically
31639 + * adjust the settings for this buffer only. This must remain at the end
31641 + * ---------------------------------------------------------------------------
31642 + * Local variables:
31643 + * c-file-style: "linux"
31646 diff -Naur -X ../exclude-files orig/arch/um/link.ld.in um/arch/um/link.ld.in
31647 --- orig/arch/um/link.ld.in 1969-12-31 19:00:00.000000000 -0500
31648 +++ um/arch/um/link.ld.in 2003-01-17 23:11:30.000000000 -0500
31650 +OUTPUT_FORMAT("ELF_FORMAT")
31651 +OUTPUT_ARCH(ELF_ARCH)
31656 + . = START() + SIZEOF_HEADERS;
31659 + __binary_start = .;
31660 +ifdef(`MODE_TT', `
31661 + .thread_private : {
31662 + __start_thread_private = .;
31665 + arch/um/kernel/tt/unmap_fin.o (.data)
31666 + __end_thread_private = .;
31669 + .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
31671 + . = ALIGN(4096); /* Init code and data */
31673 + __init_begin = .;
31674 + .text.init : { *(.text.init) }
31679 + /* .gnu.warning sections are handled specially by elf32.em. */
31681 + *(.gnu.linkonce.t*)
31683 + .fini : { *(.fini) } =0x9090
31684 + .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
31685 + .rodata1 : { *(.rodata1) }
31687 + PROVIDE (etext = .);
31690 + PROVIDE (_sdata = .);
31692 +include(`arch/um/common.ld.in')
31696 + . = ALIGN(KERNEL_STACK_SIZE); /* init_task */
31697 + *(.data.init_task)
31699 + *(.gnu.linkonce.d*)
31702 + .data1 : { *(.data1) }
31712 + .got : { *(.got.plt) *(.got) }
31713 + .dynamic : { *(.dynamic) }
31714 + /* We want the small data sections together, so single-instruction offsets
31715 + can access them all, and initialized data all before uninitialized, so
31716 + we can shorten the on-disk segment size. */
31717 + .sdata : { *(.sdata) }
31719 + PROVIDE (edata = .);
31720 + . = ALIGN(0x1000);
31724 + PROVIDE(_bss_start = .);
31735 + PROVIDE (end = .);
31736 + /* Stabs debugging sections. */
31737 + .stab 0 : { *(.stab) }
31738 + .stabstr 0 : { *(.stabstr) }
31739 + .stab.excl 0 : { *(.stab.excl) }
31740 + .stab.exclstr 0 : { *(.stab.exclstr) }
31741 + .stab.index 0 : { *(.stab.index) }
31742 + .stab.indexstr 0 : { *(.stab.indexstr) }
31743 + .comment 0 : { *(.comment) }
31745 diff -Naur -X ../exclude-files orig/arch/um/main.c um/arch/um/main.c
31746 --- orig/arch/um/main.c 1969-12-31 19:00:00.000000000 -0500
31747 +++ um/arch/um/main.c 2003-01-17 13:22:40.000000000 -0500
31750 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
31751 + * Licensed under the GPL
31754 +#include <unistd.h>
31755 +#include <stdio.h>
31756 +#include <stdlib.h>
31757 +#include <string.h>
31758 +#include <signal.h>
31759 +#include <sys/resource.h>
31760 +#include <sys/mman.h>
31761 +#include <sys/user.h>
31762 +#include <asm/page.h>
31763 +#include "user_util.h"
31764 +#include "kern_util.h"
31765 +#include "mem_user.h"
31766 +#include "signal_user.h"
31770 +#include "choose-mode.h"
31771 +#include "uml-config.h"
31773 +/* Set in set_stklim, which is called from main and __wrap_malloc.
31774 + * __wrap_malloc only calls it if main hasn't started.
31776 +unsigned long stacksizelim;
31781 +#define PGD_BOUND (4 * 1024 * 1024)
31782 +#define STACKSIZE (8 * 1024 * 1024)
31783 +#define THREAD_NAME_LEN (256)
31785 +static void set_stklim(void)
31787 + struct rlimit lim;
31789 + if(getrlimit(RLIMIT_STACK, &lim) < 0){
31790 + perror("getrlimit");
31793 + if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){
31794 + lim.rlim_cur = STACKSIZE;
31795 + if(setrlimit(RLIMIT_STACK, &lim) < 0){
31796 + perror("setrlimit");
31800 + stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1);
31803 +static __init void do_uml_initcalls(void)
31805 + initcall_t *call;
31807 + call = &__uml_initcall_start;
31808 + while (call < &__uml_initcall_end){;
31814 +static void last_ditch_exit(int sig)
31816 + CHOOSE_MODE(kmalloc_ok = 0, (void) 0);
31817 + signal(SIGINT, SIG_DFL);
31818 + signal(SIGTERM, SIG_DFL);
31819 + signal(SIGHUP, SIG_DFL);
31824 +extern int uml_exitcode;
31826 +int main(int argc, char **argv, char **envp)
31832 + /* Enable all signals except SIGIO - in some environments, we can
31833 + * enter with some signals blocked
31836 + sigemptyset(&mask);
31837 + sigaddset(&mask, SIGIO);
31838 + if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){
31839 + perror("sigprocmask");
31843 +#ifdef UML_CONFIG_MODE_TT
31844 + /* Allocate memory for thread command lines */
31845 + if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
31847 + char padding[THREAD_NAME_LEN] = {
31848 + [ 0 ... THREAD_NAME_LEN - 2] = ' ', '\0'
31851 + new_argv = malloc((argc + 2) * sizeof(char*));
31853 + perror("Allocating extended argv");
31857 + new_argv[0] = argv[0];
31858 + new_argv[1] = padding;
31860 + for(i = 2; i <= argc; i++)
31861 + new_argv[i] = argv[i - 1];
31862 + new_argv[argc + 1] = NULL;
31864 + execvp(new_argv[0], new_argv);
31865 + perror("execing with extended args");
31870 + linux_prog = argv[0];
31874 + if((new_argv = malloc((argc + 1) * sizeof(char *))) == NULL){
31875 + perror("Mallocing argv");
31878 + for(i=0;i<argc;i++){
31879 + if((new_argv[i] = strdup(argv[i])) == NULL){
31880 + perror("Mallocing an arg");
31884 + new_argv[argc] = NULL;
31886 + set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
31887 + set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
31888 + set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
31890 + do_uml_initcalls();
31891 + ret = linux_main(argc, argv);
31896 + execvp(new_argv[0], new_argv);
31897 + perror("Failed to exec kernel");
31901 + return(uml_exitcode);
31904 +#define CAN_KMALLOC() \
31905 + (kmalloc_ok && CHOOSE_MODE((getpid() != tracing_pid), 1))
31907 +extern void *__real_malloc(int);
31909 +void *__wrap_malloc(int size)
31911 + if(CAN_KMALLOC())
31912 + return(um_kmalloc(size));
31914 + return(__real_malloc(size));
31917 +void *__wrap_calloc(int n, int size)
31919 + void *ptr = __wrap_malloc(n * size);
31921 + if(ptr == NULL) return(NULL);
31922 + memset(ptr, 0, n * size);
31926 +extern void __real_free(void *);
31928 +void __wrap_free(void *ptr)
31930 + if(CAN_KMALLOC()) kfree(ptr);
31931 + else __real_free(ptr);
31935 + * Overrides for Emacs so that we follow Linus's tabbing style.
31936 + * Emacs will notice this stuff at the end of the file and automatically
31937 + * adjust the settings for this buffer only. This must remain at the end
31939 + * ---------------------------------------------------------------------------
31940 + * Local variables:
31941 + * c-file-style: "linux"
31944 diff -Naur -X ../exclude-files orig/arch/um/Makefile um/arch/um/Makefile
31945 --- orig/arch/um/Makefile 1969-12-31 19:00:00.000000000 -0500
31946 +++ um/arch/um/Makefile 2003-06-05 15:42:11.000000000 -0400
31949 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
31950 +# Licensed under the GPL
31953 +OS := $(shell uname -s)
31955 +ARCH_DIR = arch/um
31957 +core-y := kernel sys-$(SUBARCH) os-$(OS)
31958 +drivers-y := fs drivers
31959 +subdir-y := $(core-y) $(drivers-y)
31960 +SUBDIRS += $(foreach dir,$(subdir-y),$(ARCH_DIR)/$(dir))
31962 +CORE_FILES += $(foreach dir,$(core-y),$(ARCH_DIR)/$(dir)/built-in.o)
31963 +DRIVERS += $(foreach dir,$(drivers-y),$(ARCH_DIR)/$(dir)/built-in.o)
31965 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
31966 +include $(ARCH_DIR)/Makefile-os-$(OS)
31968 +MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
31969 +MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
31971 +ifneq ($(MAKEFILE-y),)
31972 + include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
31975 +EXTRAVERSION := $(EXTRAVERSION)-6um
31977 +include/linux/version.h: arch/$(ARCH)/Makefile
31979 +# Recalculate MODLIB to reflect the EXTRAVERSION changes (via KERNELRELEASE)
31980 +# The way the toplevel Makefile is written EXTRAVERSION is not supposed
31981 +# to be changed outside the toplevel Makefile, but recalculating MODLIB is
31982 +# a sufficient workaround until we no longer need architecture dependent
31984 +MODLIB := $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
31986 +ifeq ($(CONFIG_DEBUGSYM),y)
31987 +CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS))
31990 +CFLAGS-$(CONFIG_DEBUGSYM) += -g
31992 +ARCH_INCLUDE = -I$(TOPDIR)/$(ARCH_DIR)/include
31994 +# -Derrno=kernel_errno - This turns all kernel references to errno into
31995 +# kernel_errno to separate them from the libc errno. This allows -fno-common
31996 +# in CFLAGS. Otherwise, it would cause ld to complain about the two different
31999 +CFLAGS += $(ARCH_CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
32000 + -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
32005 +LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
32007 +SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
32009 +# These aren't in Makefile-tt because they are needed in the !CONFIG_MODE_TT +
32010 +# CONFIG_MODE_SKAS + CONFIG_STATIC_LINK case.
32013 +LD_SCRIPT_TT := link.ld
32015 +ifeq ($(CONFIG_STATIC_LINK),y)
32016 + LINK-y += $(LINK_TT)
32017 + LD_SCRIPT-y := $(LD_SCRIPT_TT)
32019 +ifeq ($(CONFIG_MODE_TT),y)
32020 + LINK-y += $(LINK_TT)
32021 + LD_SCRIPT-y := $(LD_SCRIPT_TT)
32023 +ifeq ($(CONFIG_MODE_SKAS),y)
32024 + LINK-y += $(LINK_SKAS)
32025 + LD_SCRIPT-y := $(LD_SCRIPT_SKAS)
32030 +LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
32031 +M4_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT)
32033 +$(LD_SCRIPT-y): $(LD_SCRIPT-y).in
32034 + pages=$$(( 1 << $(CONFIG_KERNEL_STACK_ORDER) )) ; \
32035 + m4 -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
32036 + -DELF_FORMAT=$(ELF_FORMAT) $(M4_MODE_TT) \
32037 + -DKERNEL_STACK_SIZE=$$(( 4096 * $$pages )) $< > $@
32039 +SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
32040 + include/asm-um/sigcontext.h include/asm-um/processor.h \
32041 + include/asm-um/ptrace.h include/asm-um/arch-signal.h
32043 +ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \
32044 + $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
32046 +ifeq ($(CONFIG_MODE_SKAS), y)
32047 +$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
32050 +GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
32052 +setup: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS)
32054 +linux: setup $(ARCH_DIR)/main.o vmlinux $(LD_SCRIPT-y)
32055 + mv vmlinux vmlinux.o
32056 + $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
32057 + -o linux $(ARCH_DIR)/main.o vmlinux.o -L/usr/lib -lutil
32059 +USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
32060 +USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
32061 +USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
32064 +# To get a definition of F_SETSIG
32065 +USER_CFLAGS += -D_GNU_SOURCE
32067 +CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/link.ld $(ARCH_DIR)/dyn_link.ld \
32068 + $(GEN_HEADERS) $(ARCH_DIR)/include/uml-config.h
32070 +$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
32071 + $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
32074 + rm -f $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
32075 + $(LD_SCRIPT) $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
32077 +archclean: sysclean
32078 + find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
32079 + -o -name '*.gcov' \) -type f -print | xargs rm -f
32080 + cd $(ARCH_DIR) ; \
32081 + for dir in $(subdir-y) util ; do $(MAKE) -C $$dir clean; done
32085 +$(SYMLINK_HEADERS):
32086 + cd $(TOPDIR)/$(dir $@) ; \
32087 + ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
32089 +include/asm-um/arch:
32090 + cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
32092 +arch/um/include/sysdep:
32093 + cd $(TOPDIR)/arch/um/include && ln -sf sysdep-$(SUBARCH) sysdep
32096 + cd $(ARCH_DIR) && ln -sf os-$(OS) os
32098 +$(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
32101 +$(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
32104 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
32105 + sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
32107 +$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/util/mk_task_user.c \
32108 + $(ARCH_DIR)/util/mk_task_kern.c $(SYS_HEADERS)
32109 + $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_task
32111 +$(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util/mk_constants_user.c \
32112 + $(ARCH_DIR)/util/mk_constants_kern.c
32113 + $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_constants
32115 +export SUBARCH USER_CFLAGS OS
32116 diff -Naur -X ../exclude-files orig/arch/um/Makefile-i386 um/arch/um/Makefile-i386
32117 --- orig/arch/um/Makefile-i386 1969-12-31 19:00:00.000000000 -0500
32118 +++ um/arch/um/Makefile-i386 2002-10-23 21:08:04.000000000 -0400
32120 +ifeq ($(CONFIG_HOST_2G_2G), y)
32121 +TOP_ADDR = 0x80000000
32123 +TOP_ADDR = 0xc0000000
32126 +ARCH_CFLAGS = -U__$(SUBARCH)__ -U$(SUBARCH) -DUM_FASTCALL
32127 +ELF_ARCH = $(SUBARCH)
32128 +ELF_FORMAT = elf32-$(SUBARCH)
32130 +I386_H = $(ARCH_DIR)/include/sysdep-i386
32131 +SYS = $(ARCH_DIR)/sys-i386
32132 +UTIL = $(SYS)/util
32133 +SUBDIRS += $(UTIL)
32135 +SYS_HEADERS = $(I386_H)/sc.h $(I386_H)/thread.h
32137 +$(I386_H)/sc.h : $(UTIL)/mk_sc
32138 + $(UTIL)/mk_sc > $@
32140 +$(I386_H)/thread.h : $(UTIL)/mk_thread
32141 + $(UTIL)/mk_thread > $@
32143 +$(UTIL)/mk_sc : $(UTIL)/mk_sc.c
32144 + $(MAKE) -C $(UTIL) mk_sc
32146 +$(UTIL)/mk_thread : $(UTIL)/mk_thread_user.c $(UTIL)/mk_thread_kern.c \
32148 + $(MAKE) -C $(UTIL) mk_thread
32151 + rm -f $(SYS_HEADERS)
32152 + $(MAKE) -C $(UTIL) clean
32153 + $(MAKE) -C $(SYS) clean
32155 diff -Naur -X ../exclude-files orig/arch/um/Makefile-ia64 um/arch/um/Makefile-ia64
32156 --- orig/arch/um/Makefile-ia64 1969-12-31 19:00:00.000000000 -0500
32157 +++ um/arch/um/Makefile-ia64 2002-10-23 21:08:04.000000000 -0400
32159 +START_ADDR = 0x1000000000000000
32160 diff -Naur -X ../exclude-files orig/arch/um/Makefile-os-Linux um/arch/um/Makefile-os-Linux
32161 --- orig/arch/um/Makefile-os-Linux 1969-12-31 19:00:00.000000000 -0500
32162 +++ um/arch/um/Makefile-os-Linux 2002-12-09 14:21:51.000000000 -0500
32165 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
32166 +# Licensed under the GPL
32169 +SUBDIRS += $(ARCH_DIR)/os-$(OS)/drivers
32170 +DRIVERS += $(ARCH_DIR)/os-$(OS)/drivers/drivers.o
32171 diff -Naur -X ../exclude-files orig/arch/um/Makefile-ppc um/arch/um/Makefile-ppc
32172 --- orig/arch/um/Makefile-ppc 1969-12-31 19:00:00.000000000 -0500
32173 +++ um/arch/um/Makefile-ppc 2002-10-23 21:08:04.000000000 -0400
32175 +ifeq ($(CONFIG_HOST_2G_2G), y)
32176 +START_ADDR = 0x80000000
32178 +START_ADDR = 0xc0000000
32180 +ARCH_CFLAGS = -U__powerpc__ -D__UM_PPC__
32182 +# The arch is ppc, but the elf32 name is powerpc
32183 +ELF_SUBARCH = powerpc
32184 diff -Naur -X ../exclude-files orig/arch/um/Makefile-skas um/arch/um/Makefile-skas
32185 --- orig/arch/um/Makefile-skas 1969-12-31 19:00:00.000000000 -0500
32186 +++ um/arch/um/Makefile-skas 2002-12-15 22:02:57.000000000 -0500
32189 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32190 +# Licensed under the GPL
32195 +CFLAGS-$(CONFIG_GCOV) += -fprofile-arcs -ftest-coverage
32196 +CFLAGS-$(CONFIG_GPROF) += $(PROFILE)
32197 +LINK-$(CONFIG_GPROF) += $(PROFILE)
32199 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/skas/include
32201 +LINK_SKAS = -Wl,-rpath,/lib
32202 +LD_SCRIPT_SKAS = dyn_link.ld
32204 +GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
32206 +$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
32207 + $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
32208 diff -Naur -X ../exclude-files orig/arch/um/Makefile-tt um/arch/um/Makefile-tt
32209 --- orig/arch/um/Makefile-tt 1969-12-31 19:00:00.000000000 -0500
32210 +++ um/arch/um/Makefile-tt 2002-12-16 20:22:23.000000000 -0500
32213 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32214 +# Licensed under the GPL
32217 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/tt/include
32219 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/etap.h um/arch/um/os-Linux/drivers/etap.h
32220 --- orig/arch/um/os-Linux/drivers/etap.h 1969-12-31 19:00:00.000000000 -0500
32221 +++ um/arch/um/os-Linux/drivers/etap.h 2002-10-23 21:08:04.000000000 -0400
32224 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
32225 + * Licensed under the GPL
32228 +#include "net_user.h"
32230 +struct ethertap_data {
32238 +extern struct net_user_info ethertap_user_info;
32241 + * Overrides for Emacs so that we follow Linus's tabbing style.
32242 + * Emacs will notice this stuff at the end of the file and automatically
32243 + * adjust the settings for this buffer only. This must remain at the end
32245 + * ---------------------------------------------------------------------------
32246 + * Local variables:
32247 + * c-file-style: "linux"
32250 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_kern.c um/arch/um/os-Linux/drivers/ethertap_kern.c
32251 --- orig/arch/um/os-Linux/drivers/ethertap_kern.c 1969-12-31 19:00:00.000000000 -0500
32252 +++ um/arch/um/os-Linux/drivers/ethertap_kern.c 2002-12-15 21:17:37.000000000 -0500
32255 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
32256 + * James Leu (jleu@mindspring.net).
32257 + * Copyright (C) 2001 by various other people who didn't put their name here.
32258 + * Licensed under the GPL.
32261 +#include "linux/init.h"
32262 +#include "linux/netdevice.h"
32263 +#include "linux/etherdevice.h"
32264 +#include "linux/init.h"
32265 +#include "net_kern.h"
32266 +#include "net_user.h"
32269 +struct ethertap_init {
32274 +static void etap_init(struct net_device *dev, void *data)
32276 + struct uml_net_private *pri;
32277 + struct ethertap_data *epri;
32278 + struct ethertap_init *init = data;
32280 + init_etherdev(dev, 0);
32282 + epri = (struct ethertap_data *) pri->user;
32283 + *epri = ((struct ethertap_data)
32284 + { .dev_name = init->dev_name,
32285 + .gate_addr = init->gate_addr,
32287 + .control_fd = -1,
32290 + printk("ethertap backend - %s", epri->dev_name);
32291 + if(epri->gate_addr != NULL)
32292 + printk(", IP = %s", epri->gate_addr);
32296 +static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
32300 + *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
32301 + if(*skb == NULL) return(-ENOMEM);
32302 + len = net_recvfrom(fd, (*skb)->mac.raw,
32303 + (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
32304 + if(len <= 0) return(len);
32305 + skb_pull(*skb, 2);
32310 +static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
32312 + if(skb_headroom(*skb) < 2){
32313 + struct sk_buff *skb2;
32315 + skb2 = skb_realloc_headroom(*skb, 2);
32316 + dev_kfree_skb(*skb);
32317 + if (skb2 == NULL) return(-ENOMEM);
32320 + skb_push(*skb, 2);
32321 + return(net_send(fd, (*skb)->data, (*skb)->len));
32324 +struct net_kern_info ethertap_kern_info = {
32325 + .init = etap_init,
32326 + .protocol = eth_protocol,
32327 + .read = etap_read,
32328 + .write = etap_write,
32331 +int ethertap_setup(char *str, char **mac_out, void *data)
32333 + struct ethertap_init *init = data;
32335 + *init = ((struct ethertap_init)
32336 + { .dev_name = NULL,
32337 + .gate_addr = NULL });
32338 + if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
32339 + &init->gate_addr))
32341 + if(init->dev_name == NULL){
32342 + printk("ethertap_setup : Missing tap device name\n");
32349 +static struct transport ethertap_transport = {
32350 + .list = LIST_HEAD_INIT(ethertap_transport.list),
32351 + .name = "ethertap",
32352 + .setup = ethertap_setup,
32353 + .user = ðertap_user_info,
32354 + .kern = ðertap_kern_info,
32355 + .private_size = sizeof(struct ethertap_data),
32358 +static int register_ethertap(void)
32360 + register_transport(ðertap_transport);
32364 +__initcall(register_ethertap);
32367 + * Overrides for Emacs so that we follow Linus's tabbing style.
32368 + * Emacs will notice this stuff at the end of the file and automatically
32369 + * adjust the settings for this buffer only. This must remain at the end
32371 + * ---------------------------------------------------------------------------
32372 + * Local variables:
32373 + * c-file-style: "linux"
32376 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_user.c um/arch/um/os-Linux/drivers/ethertap_user.c
32377 --- orig/arch/um/os-Linux/drivers/ethertap_user.c 1969-12-31 19:00:00.000000000 -0500
32378 +++ um/arch/um/os-Linux/drivers/ethertap_user.c 2002-12-15 21:17:52.000000000 -0500
32381 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
32382 + * James Leu (jleu@mindspring.net).
32383 + * Copyright (C) 2001 by various other people who didn't put their name here.
32384 + * Licensed under the GPL.
32387 +#include <stdio.h>
32388 +#include <unistd.h>
32389 +#include <stddef.h>
32390 +#include <fcntl.h>
32391 +#include <stdlib.h>
32392 +#include <sys/errno.h>
32393 +#include <sys/socket.h>
32394 +#include <sys/wait.h>
32395 +#include <sys/un.h>
32396 +#include <net/if.h>
32398 +#include "kern_util.h"
32399 +#include "net_user.h"
32401 +#include "helper.h"
32404 +#define MAX_PACKET ETH_MAX_PACKET
32406 +void etap_user_init(void *data, void *dev)
32408 + struct ethertap_data *pri = data;
32413 +struct addr_change {
32414 + enum { ADD_ADDR, DEL_ADDR } what;
32415 + unsigned char addr[4];
32416 + unsigned char netmask[4];
32419 +static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
32422 + struct addr_change change;
32425 + change.what = op;
32426 + memcpy(change.addr, addr, sizeof(change.addr));
32427 + memcpy(change.netmask, netmask, sizeof(change.netmask));
32428 + if(write(fd, &change, sizeof(change)) != sizeof(change))
32429 + printk("etap_change - request failed, errno = %d\n",
32431 + output = um_kmalloc(page_size());
32432 + if(output == NULL)
32433 + printk("etap_change : Failed to allocate output buffer\n");
32434 + read_output(fd, output, page_size());
32435 + if(output != NULL){
32436 + printk("%s", output);
32441 +static void etap_open_addr(unsigned char *addr, unsigned char *netmask,
32444 + etap_change(ADD_ADDR, addr, netmask, *((int *) arg));
32447 +static void etap_close_addr(unsigned char *addr, unsigned char *netmask,
32450 + etap_change(DEL_ADDR, addr, netmask, *((int *) arg));
32453 +struct etap_pre_exec_data {
32454 + int control_remote;
32459 +static void etap_pre_exec(void *arg)
32461 + struct etap_pre_exec_data *data = arg;
32463 + dup2(data->control_remote, 1);
32464 + close(data->data_me);
32465 + close(data->control_me);
32468 +static int etap_tramp(char *dev, char *gate, int control_me,
32469 + int control_remote, int data_me, int data_remote)
32471 + struct etap_pre_exec_data pe_data;
32472 + int pid, status, err;
32473 + char version_buf[sizeof("nnnnn\0")];
32474 + char data_fd_buf[sizeof("nnnnnn\0")];
32475 + char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
32476 + char *setup_args[] = { "uml_net", version_buf, "ethertap", dev,
32477 + data_fd_buf, gate_buf, NULL };
32478 + char *nosetup_args[] = { "uml_net", version_buf, "ethertap",
32479 + dev, data_fd_buf, NULL };
32482 + sprintf(data_fd_buf, "%d", data_remote);
32483 + sprintf(version_buf, "%d", UML_NET_VERSION);
32484 + if(gate != NULL){
32485 + strcpy(gate_buf, gate);
32486 + args = setup_args;
32488 + else args = nosetup_args;
32491 + pe_data.control_remote = control_remote;
32492 + pe_data.control_me = control_me;
32493 + pe_data.data_me = data_me;
32494 + pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
32496 + if(pid < 0) err = errno;
32497 + close(data_remote);
32498 + close(control_remote);
32499 + if(read(control_me, &c, sizeof(c)) != sizeof(c)){
32500 + printk("etap_tramp : read of status failed, errno = %d\n",
32505 + printk("etap_tramp : uml_net failed\n");
32507 + if(waitpid(pid, &status, 0) < 0) err = errno;
32508 + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)){
32509 + printk("uml_net didn't exit with status 1\n");
32515 +static int etap_open(void *data)
32517 + struct ethertap_data *pri = data;
32519 + int data_fds[2], control_fds[2], err, output_len;
32521 + err = tap_open_common(pri->dev, pri->gate_addr);
32522 + if(err) return(err);
32524 + err = os_pipe(data_fds, 0, 0);
32526 + printk("data os_pipe failed - errno = %d\n", -err);
32530 + err = os_pipe(control_fds, 1, 0);
32532 + printk("control os_pipe failed - errno = %d\n", -err);
32536 + err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
32537 + control_fds[1], data_fds[0], data_fds[1]);
32538 + output_len = page_size();
32539 + output = um_kmalloc(output_len);
32540 + read_output(control_fds[0], output, output_len);
32542 + if(output == NULL)
32543 + printk("etap_open : failed to allocate output buffer\n");
32545 + printk("%s", output);
32550 + printk("etap_tramp failed - errno = %d\n", err);
32554 + pri->data_fd = data_fds[0];
32555 + pri->control_fd = control_fds[0];
32556 + iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
32557 + return(data_fds[0]);
32560 +static void etap_close(int fd, void *data)
32562 + struct ethertap_data *pri = data;
32564 + iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
32566 + os_shutdown_socket(pri->data_fd, 1, 1);
32567 + close(pri->data_fd);
32568 + pri->data_fd = -1;
32569 + close(pri->control_fd);
32570 + pri->control_fd = -1;
32573 +static int etap_set_mtu(int mtu, void *data)
32578 +static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
32581 + struct ethertap_data *pri = data;
32583 + tap_check_ips(pri->gate_addr, addr);
32584 + if(pri->control_fd == -1) return;
32585 + etap_open_addr(addr, netmask, &pri->control_fd);
32588 +static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
32591 + struct ethertap_data *pri = data;
32593 + if(pri->control_fd == -1) return;
32594 + etap_close_addr(addr, netmask, &pri->control_fd);
32597 +struct net_user_info ethertap_user_info = {
32598 + .init = etap_user_init,
32599 + .open = etap_open,
32600 + .close = etap_close,
32602 + .set_mtu = etap_set_mtu,
32603 + .add_address = etap_add_addr,
32604 + .delete_address = etap_del_addr,
32605 + .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP
32609 + * Overrides for Emacs so that we follow Linus's tabbing style.
32610 + * Emacs will notice this stuff at the end of the file and automatically
32611 + * adjust the settings for this buffer only. This must remain at the end
32613 + * ---------------------------------------------------------------------------
32614 + * Local variables:
32615 + * c-file-style: "linux"
32618 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/Makefile um/arch/um/os-Linux/drivers/Makefile
32619 --- orig/arch/um/os-Linux/drivers/Makefile 1969-12-31 19:00:00.000000000 -0500
32620 +++ um/arch/um/os-Linux/drivers/Makefile 2002-10-23 21:08:04.000000000 -0400
32623 +# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
32624 +# Licensed under the GPL
32627 +O_TARGET := drivers.o
32629 +list-multi := tuntap.o ethertap.o
32631 +ethertap-objs := ethertap_kern.o ethertap_user.o
32632 +tuntap-objs := tuntap_kern.o tuntap_user.o
32635 +obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap.o
32636 +obj-$(CONFIG_UML_NET_TUNTAP) += tuntap.o
32638 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y)),$($(f)-objs))
32640 +USER_OBJS = $(filter %_user.o,$(obj-y) $(USER_SINGLE_OBJS))
32642 +include $(TOPDIR)/Rules.make
32644 +$(USER_OBJS) : %.o: %.c
32645 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
32647 +ethertap.o : $(ethertap-objs)
32649 +tuntap.o : $(tuntap-objs)
32651 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
32652 + $(LD) $(LD_RFLAG) -r -o $@ $($(patsubst %.o,%,$@)-objs)
32653 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap.h um/arch/um/os-Linux/drivers/tuntap.h
32654 --- orig/arch/um/os-Linux/drivers/tuntap.h 1969-12-31 19:00:00.000000000 -0500
32655 +++ um/arch/um/os-Linux/drivers/tuntap.h 2002-10-23 21:08:04.000000000 -0400
32658 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32659 + * Licensed under the GPL
32662 +#ifndef __UM_TUNTAP_H
32663 +#define __UM_TUNTAP_H
32665 +#include "net_user.h"
32667 +struct tuntap_data {
32669 + int fixed_config;
32675 +extern struct net_user_info tuntap_user_info;
32680 + * Overrides for Emacs so that we follow Linus's tabbing style.
32681 + * Emacs will notice this stuff at the end of the file and automatically
32682 + * adjust the settings for this buffer only. This must remain at the end
32684 + * ---------------------------------------------------------------------------
32685 + * Local variables:
32686 + * c-file-style: "linux"
32689 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_kern.c um/arch/um/os-Linux/drivers/tuntap_kern.c
32690 --- orig/arch/um/os-Linux/drivers/tuntap_kern.c 1969-12-31 19:00:00.000000000 -0500
32691 +++ um/arch/um/os-Linux/drivers/tuntap_kern.c 2002-12-15 21:18:16.000000000 -0500
32694 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
32695 + * Licensed under the GPL
32698 +#include "linux/stddef.h"
32699 +#include "linux/netdevice.h"
32700 +#include "linux/etherdevice.h"
32701 +#include "linux/skbuff.h"
32702 +#include "linux/init.h"
32703 +#include "asm/errno.h"
32704 +#include "net_kern.h"
32705 +#include "net_user.h"
32706 +#include "tuntap.h"
32708 +struct tuntap_init {
32713 +static void tuntap_init(struct net_device *dev, void *data)
32715 + struct uml_net_private *pri;
32716 + struct tuntap_data *tpri;
32717 + struct tuntap_init *init = data;
32719 + init_etherdev(dev, 0);
32721 + tpri = (struct tuntap_data *) pri->user;
32722 + *tpri = ((struct tuntap_data)
32723 + { .dev_name = init->dev_name,
32724 + .fixed_config = (init->dev_name != NULL),
32725 + .gate_addr = init->gate_addr,
32728 + printk("TUN/TAP backend - ");
32729 + if(tpri->gate_addr != NULL)
32730 + printk("IP = %s", tpri->gate_addr);
32734 +static int tuntap_read(int fd, struct sk_buff **skb,
32735 + struct uml_net_private *lp)
32737 + *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
32738 + if(*skb == NULL) return(-ENOMEM);
32739 + return(net_read(fd, (*skb)->mac.raw,
32740 + (*skb)->dev->mtu + ETH_HEADER_OTHER));
32743 +static int tuntap_write(int fd, struct sk_buff **skb,
32744 + struct uml_net_private *lp)
32746 + return(net_write(fd, (*skb)->data, (*skb)->len));
32749 +struct net_kern_info tuntap_kern_info = {
32750 + .init = tuntap_init,
32751 + .protocol = eth_protocol,
32752 + .read = tuntap_read,
32753 + .write = tuntap_write,
32756 +int tuntap_setup(char *str, char **mac_out, void *data)
32758 + struct tuntap_init *init = data;
32760 + *init = ((struct tuntap_init)
32761 + { .dev_name = NULL,
32762 + .gate_addr = NULL });
32763 + if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
32764 + &init->gate_addr))
32770 +static struct transport tuntap_transport = {
32771 + .list = LIST_HEAD_INIT(tuntap_transport.list),
32772 + .name = "tuntap",
32773 + .setup = tuntap_setup,
32774 + .user = &tuntap_user_info,
32775 + .kern = &tuntap_kern_info,
32776 + .private_size = sizeof(struct tuntap_data),
32777 + .setup_size = sizeof(struct tuntap_init),
32780 +static int register_tuntap(void)
32782 + register_transport(&tuntap_transport);
32786 +__initcall(register_tuntap);
32789 + * Overrides for Emacs so that we follow Linus's tabbing style.
32790 + * Emacs will notice this stuff at the end of the file and automatically
32791 + * adjust the settings for this buffer only. This must remain at the end
32793 + * ---------------------------------------------------------------------------
32794 + * Local variables:
32795 + * c-file-style: "linux"
32798 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_user.c um/arch/um/os-Linux/drivers/tuntap_user.c
32799 --- orig/arch/um/os-Linux/drivers/tuntap_user.c 1969-12-31 19:00:00.000000000 -0500
32800 +++ um/arch/um/os-Linux/drivers/tuntap_user.c 2002-12-15 21:18:25.000000000 -0500
32803 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32804 + * Licensed under the GPL
32807 +#include <stdio.h>
32808 +#include <stddef.h>
32809 +#include <stdlib.h>
32810 +#include <unistd.h>
32811 +#include <errno.h>
32812 +#include <fcntl.h>
32813 +#include <sys/wait.h>
32814 +#include <sys/socket.h>
32815 +#include <sys/un.h>
32816 +#include <sys/uio.h>
32817 +#include <sys/ioctl.h>
32818 +#include <net/if.h>
32819 +#include <linux/if_tun.h>
32820 +#include "net_user.h"
32821 +#include "tuntap.h"
32822 +#include "kern_util.h"
32824 +#include "helper.h"
32827 +#define MAX_PACKET ETH_MAX_PACKET
32829 +void tuntap_user_init(void *data, void *dev)
32831 + struct tuntap_data *pri = data;
32836 +static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
32839 + struct tuntap_data *pri = data;
32841 + tap_check_ips(pri->gate_addr, addr);
32842 + if((pri->fd == -1) || pri->fixed_config) return;
32843 + open_addr(addr, netmask, pri->dev_name);
32846 +static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
32849 + struct tuntap_data *pri = data;
32851 + if((pri->fd == -1) || pri->fixed_config) return;
32852 + close_addr(addr, netmask, pri->dev_name);
32855 +struct tuntap_pre_exec_data {
32860 +static void tuntap_pre_exec(void *arg)
32862 + struct tuntap_pre_exec_data *data = arg;
32864 + dup2(data->stdout, 1);
32865 + close(data->close_me);
32868 +static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
32869 + char *buffer, int buffer_len, int *used_out)
32871 + struct tuntap_pre_exec_data data;
32872 + char version_buf[sizeof("nnnnn\0")];
32873 + char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate,
32875 + char buf[CMSG_SPACE(sizeof(*fd_out))];
32876 + struct msghdr msg;
32877 + struct cmsghdr *cmsg;
32878 + struct iovec iov;
32881 + sprintf(version_buf, "%d", UML_NET_VERSION);
32883 + data.stdout = remote;
32884 + data.close_me = me;
32886 + pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
32888 + if(pid < 0) return(-pid);
32892 + msg.msg_name = NULL;
32893 + msg.msg_namelen = 0;
32894 + if(buffer != NULL){
32895 + iov = ((struct iovec) { buffer, buffer_len });
32896 + msg.msg_iov = &iov;
32897 + msg.msg_iovlen = 1;
32900 + msg.msg_iov = NULL;
32901 + msg.msg_iovlen = 0;
32903 + msg.msg_control = buf;
32904 + msg.msg_controllen = sizeof(buf);
32905 + msg.msg_flags = 0;
32906 + n = recvmsg(me, &msg, 0);
32909 + printk("tuntap_open_tramp : recvmsg failed - errno = %d\n",
32913 + waitpid(pid, NULL, 0);
32915 + cmsg = CMSG_FIRSTHDR(&msg);
32916 + if(cmsg == NULL){
32917 + printk("tuntap_open_tramp : didn't receive a message\n");
32920 + if((cmsg->cmsg_level != SOL_SOCKET) ||
32921 + (cmsg->cmsg_type != SCM_RIGHTS)){
32922 + printk("tuntap_open_tramp : didn't receive a descriptor\n");
32925 + *fd_out = ((int *) CMSG_DATA(cmsg))[0];
32929 +static int tuntap_open(void *data)
32931 + struct ifreq ifr;
32932 + struct tuntap_data *pri = data;
32933 + char *output, *buffer;
32934 + int err, fds[2], len, used;
32936 + err = tap_open_common(pri->dev, pri->gate_addr);
32937 + if(err) return(err);
32939 + if(pri->fixed_config){
32940 + if((pri->fd = open("/dev/net/tun", O_RDWR)) < 0){
32941 + printk("Failed to open /dev/net/tun, errno = %d\n",
32945 + memset(&ifr, 0, sizeof(ifr));
32946 + ifr.ifr_flags = IFF_TAP;
32947 + strncpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name) - 1);
32948 + if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
32949 + printk("TUNSETIFF failed, errno = %d", errno);
32955 + err = os_pipe(fds, 0, 0);
32957 + printk("tuntap_open : os_pipe failed - errno = %d\n",
32962 + buffer = get_output_buffer(&len);
32963 + if(buffer != NULL) len--;
32966 + err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
32967 + fds[1], buffer, len, &used);
32971 + pri->dev_name = uml_strdup(buffer);
32972 + output += IFNAMSIZ;
32974 + free_output_buffer(buffer);
32978 + free_output_buffer(buffer);
32979 + printk("tuntap_open_tramp failed - errno = %d\n", err);
32983 + iter_addresses(pri->dev, open_addr, pri->dev_name);
32989 +static void tuntap_close(int fd, void *data)
32991 + struct tuntap_data *pri = data;
32993 + if(!pri->fixed_config)
32994 + iter_addresses(pri->dev, close_addr, pri->dev_name);
32999 +static int tuntap_set_mtu(int mtu, void *data)
33004 +struct net_user_info tuntap_user_info = {
33005 + .init = tuntap_user_init,
33006 + .open = tuntap_open,
33007 + .close = tuntap_close,
33009 + .set_mtu = tuntap_set_mtu,
33010 + .add_address = tuntap_add_addr,
33011 + .delete_address = tuntap_del_addr,
33012 + .max_packet = MAX_PACKET
33016 + * Overrides for Emacs so that we follow Linus's tabbing style.
33017 + * Emacs will notice this stuff at the end of the file and automatically
33018 + * adjust the settings for this buffer only. This must remain at the end
33020 + * ---------------------------------------------------------------------------
33021 + * Local variables:
33022 + * c-file-style: "linux"
33025 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/file.c um/arch/um/os-Linux/file.c
33026 --- orig/arch/um/os-Linux/file.c 1969-12-31 19:00:00.000000000 -0500
33027 +++ um/arch/um/os-Linux/file.c 2003-02-04 19:32:10.000000000 -0500
33030 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33031 + * Licensed under the GPL
33034 +#include <stdio.h>
33035 +#include <unistd.h>
33036 +#include <errno.h>
33037 +#include <fcntl.h>
33038 +#include <signal.h>
33039 +#include <sys/socket.h>
33040 +#include <sys/un.h>
33041 +#include <sys/ioctl.h>
33042 +#include <sys/mount.h>
33043 +#include <sys/uio.h>
33046 +#include "kern_util.h"
33048 +int os_file_type(char *file)
33050 + struct stat64 buf;
33052 + if(stat64(file, &buf) == -1)
33055 + if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
33056 + else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
33057 + else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
33058 + else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
33059 + else if(S_ISFIFO(buf.st_mode)) return(OS_TYPE_FIFO);
33060 + else if(S_ISSOCK(buf.st_mode)) return(OS_TYPE_SOCK);
33061 + else return(OS_TYPE_FILE);
33064 +int os_file_mode(char *file, struct openflags *mode_out)
33066 + *mode_out = OPENFLAGS();
33068 + if(!access(file, W_OK)) *mode_out = of_write(*mode_out);
33069 + else if(errno != EACCES)
33072 + if(!access(file, R_OK)) *mode_out = of_read(*mode_out);
33073 + else if(errno != EACCES)
33079 +int os_open_file(char *file, struct openflags flags, int mode)
33083 + if(flags.r && flags.w) f = O_RDWR;
33084 + else if(flags.r) f = O_RDONLY;
33085 + else if(flags.w) f = O_WRONLY;
33088 + if(flags.s) f |= O_SYNC;
33089 + if(flags.c) f |= O_CREAT;
33090 + if(flags.t) f |= O_TRUNC;
33091 + if(flags.e) f |= O_EXCL;
33093 + fd = open64(file, f, mode);
33094 + if(fd < 0) return(-errno);
33097 + if(fcntl(fd, F_SETFD, 1)){
33106 +int os_connect_socket(char *name)
33108 + struct sockaddr_un sock;
33111 + sock.sun_family = AF_UNIX;
33112 + snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
33114 + fd = socket(AF_UNIX, SOCK_STREAM, 0);
33118 + err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
33125 +void os_close_file(int fd)
33130 +int os_seek_file(int fd, __u64 offset)
33134 + actual = lseek64(fd, offset, SEEK_SET);
33135 + if(actual != offset) return(-errno);
33139 +int os_read_file(int fd, void *buf, int len)
33143 + /* Force buf into memory if it's not already. */
33145 + /* XXX This fails if buf is kernel memory */
33147 + if(copy_to_user_proc(buf, &c, sizeof(c)))
33151 + n = read(fd, buf, len);
33157 +int os_write_file(int fd, void *buf, int count)
33161 + /* Force buf into memory if it's not already. */
33163 + /* XXX This fails if buf is kernel memory */
33165 + if(copy_to_user_proc(buf, buf, buf[0]))
33169 + n = write(fd, buf, count);
33175 +int os_file_size(char *file, long long *size_out)
33177 + struct stat64 buf;
33179 + if(stat64(file, &buf) == -1){
33180 + printk("Couldn't stat \"%s\" : errno = %d\n", file, errno);
33183 + if(S_ISBLK(buf.st_mode)){
33186 + if((fd = open64(file, O_RDONLY)) < 0){
33187 + printk("Couldn't open \"%s\", errno = %d\n", file,
33191 + if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
33192 + printk("Couldn't get the block size of \"%s\", "
33193 + "errno = %d\n", file, errno);
33197 + *size_out = ((long long) blocks) * 512;
33201 + *size_out = buf.st_size;
33205 +int os_pipe(int *fds, int stream, int close_on_exec)
33207 + int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
33209 + err = socketpair(AF_UNIX, type, 0, fds);
33213 + if(!close_on_exec)
33216 + if((fcntl(fds[0], F_SETFD, 1) < 0) || (fcntl(fds[1], F_SETFD, 1) < 0))
33217 + printk("os_pipe : Setting FD_CLOEXEC failed, errno = %d",
33223 +int os_set_fd_async(int fd, int owner)
33225 + /* XXX This should do F_GETFL first */
33226 + if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){
33227 + printk("os_set_fd_async : failed to set O_ASYNC and "
33228 + "O_NONBLOCK on fd # %d, errno = %d\n", fd, errno);
33232 + if(fcntl(fd, F_SETFD, 1) < 0){
33233 + printk("os_set_fd_async : Setting FD_CLOEXEC failed, "
33234 + "errno = %d\n", errno);
33238 + if((fcntl(fd, F_SETSIG, SIGIO) < 0) ||
33239 + (fcntl(fd, F_SETOWN, owner) < 0)){
33240 + printk("os_set_fd_async : Failed to fcntl F_SETOWN "
33241 + "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd,
33249 +int os_set_fd_block(int fd, int blocking)
33253 + flags = fcntl(fd, F_GETFL);
33255 + if(blocking) flags &= ~O_NONBLOCK;
33256 + else flags |= O_NONBLOCK;
33258 + if(fcntl(fd, F_SETFL, flags) < 0){
33259 + printk("Failed to change blocking on fd # %d, errno = %d\n",
33266 +int os_accept_connection(int fd)
33270 + new = accept(fd, NULL, 0);
33285 +#define SHUT_RDWR 2
33288 +int os_shutdown_socket(int fd, int r, int w)
33292 + if(r && w) what = SHUT_RDWR;
33293 + else if(r) what = SHUT_RD;
33294 + else if(w) what = SHUT_WR;
33296 + printk("os_shutdown_socket : neither r or w was set\n");
33299 + err = shutdown(fd, what);
33305 +int os_rcv_fd(int fd, int *helper_pid_out)
33308 + char buf[CMSG_SPACE(sizeof(new))];
33309 + struct msghdr msg;
33310 + struct cmsghdr *cmsg;
33311 + struct iovec iov;
33313 + msg.msg_name = NULL;
33314 + msg.msg_namelen = 0;
33315 + iov = ((struct iovec) { .iov_base = helper_pid_out,
33316 + .iov_len = sizeof(*helper_pid_out) });
33317 + msg.msg_iov = &iov;
33318 + msg.msg_iovlen = 1;
33319 + msg.msg_control = buf;
33320 + msg.msg_controllen = sizeof(buf);
33321 + msg.msg_flags = 0;
33323 + n = recvmsg(fd, &msg, 0);
33327 + else if(n != sizeof(iov.iov_len))
33328 + *helper_pid_out = -1;
33330 + cmsg = CMSG_FIRSTHDR(&msg);
33331 + if(cmsg == NULL){
33332 + printk("rcv_fd didn't receive anything, error = %d\n", errno);
33335 + if((cmsg->cmsg_level != SOL_SOCKET) ||
33336 + (cmsg->cmsg_type != SCM_RIGHTS)){
33337 + printk("rcv_fd didn't receive a descriptor\n");
33341 + new = ((int *) CMSG_DATA(cmsg))[0];
33345 +int create_unix_socket(char *file, int len)
33347 + struct sockaddr_un addr;
33350 + sock = socket(PF_UNIX, SOCK_DGRAM, 0);
33352 + printk("create_unix_socket - socket failed, errno = %d\n",
33357 + addr.sun_family = AF_UNIX;
33359 + /* XXX Be more careful about overflow */
33360 + snprintf(addr.sun_path, len, "%s", file);
33362 + err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
33364 + printk("create_listening_socket - bind failed, errno = %d\n",
33372 +void os_flush_stdout(void)
33377 +int os_lock_file(int fd, int excl)
33379 + int type = excl ? F_WRLCK : F_RDLCK;
33380 + struct flock lock = ((struct flock) { .l_type = type,
33381 + .l_whence = SEEK_SET,
33386 + err = fcntl(fd, F_SETLK, &lock);
33391 + err = fcntl(fd, F_GETLK, &lock);
33397 + printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
33404 + * Overrides for Emacs so that we follow Linus's tabbing style.
33405 + * Emacs will notice this stuff at the end of the file and automatically
33406 + * adjust the settings for this buffer only. This must remain at the end
33408 + * ---------------------------------------------------------------------------
33409 + * Local variables:
33410 + * c-file-style: "linux"
33413 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/include/file.h um/arch/um/os-Linux/include/file.h
33414 --- orig/arch/um/os-Linux/include/file.h 1969-12-31 19:00:00.000000000 -0500
33415 +++ um/arch/um/os-Linux/include/file.h 2002-10-23 21:08:04.000000000 -0400
33418 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33419 + * Licensed under the GPL
33422 +#ifndef __OS_FILE_H__
33423 +#define __OS_FILE_H__
33425 +#define DEV_NULL "/dev/null"
33430 + * Overrides for Emacs so that we follow Linus's tabbing style.
33431 + * Emacs will notice this stuff at the end of the file and automatically
33432 + * adjust the settings for this buffer only. This must remain at the end
33434 + * ---------------------------------------------------------------------------
33435 + * Local variables:
33436 + * c-file-style: "linux"
33439 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/Makefile um/arch/um/os-Linux/Makefile
33440 --- orig/arch/um/os-Linux/Makefile 1969-12-31 19:00:00.000000000 -0500
33441 +++ um/arch/um/os-Linux/Makefile 2002-10-23 21:08:04.000000000 -0400
33444 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
33445 +# Licensed under the GPL
33448 +O_TARGET = built-in.o
33450 +obj-y = file.o process.o tty.o
33452 +include $(TOPDIR)/Rules.make
33454 +$(obj-y) : %.o: %.c
33455 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
33460 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/process.c um/arch/um/os-Linux/process.c
33461 --- orig/arch/um/os-Linux/process.c 1969-12-31 19:00:00.000000000 -0500
33462 +++ um/arch/um/os-Linux/process.c 2003-01-08 14:19:00.000000000 -0500
33465 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33466 + * Licensed under the GPL
33469 +#include <unistd.h>
33470 +#include <stdio.h>
33471 +#include <errno.h>
33472 +#include <signal.h>
33473 +#include <sys/mman.h>
33474 +#include <sys/wait.h>
33478 +unsigned long os_process_pc(int pid)
33480 + char proc_stat[sizeof("/proc/#####/stat\0")], buf[256];
33481 + unsigned long pc;
33484 + sprintf(proc_stat, "/proc/%d/stat", pid);
33485 + fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
33487 + printk("os_process_pc - couldn't open '%s', errno = %d\n",
33488 + proc_stat, errno);
33491 + if(read(fd, buf, sizeof(buf)) < 0){
33492 + printk("os_process_pc - couldn't read '%s', errno = %d\n",
33493 + proc_stat, errno);
33499 + if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d "
33500 + "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
33501 + "%*d %*d %*d %*d %ld", &pc) != 1){
33502 + printk("os_process_pc - couldn't find pc in '%s'\n", buf);
33507 +int os_process_parent(int pid)
33509 + char stat[sizeof("/proc/nnnnn/stat\0")];
33511 + int parent, n, fd;
33513 + if(pid == -1) return(-1);
33515 + snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
33516 + fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
33518 + printk("Couldn't open '%s', errno = %d\n", stat, -fd);
33522 + n = read(fd, data, sizeof(data));
33526 + printk("Couldn't read '%s', errno = %d\n", stat);
33531 + /* XXX This will break if there is a space in the command */
33532 + n = sscanf(data, "%*d %*s %*c %d", &parent);
33533 + if(n != 1) printk("Failed to scan '%s'\n", data);
33538 +void os_stop_process(int pid)
33540 + kill(pid, SIGSTOP);
33543 +void os_kill_process(int pid, int reap_child)
33545 + kill(pid, SIGKILL);
33547 + waitpid(pid, NULL, 0);
33551 +void os_usr1_process(int pid)
33553 + kill(pid, SIGUSR1);
33556 +int os_getpid(void)
33558 + return(getpid());
33561 +int os_map_memory(void *virt, int fd, unsigned long off, unsigned long len,
33562 + int r, int w, int x)
33567 + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
33568 + (x ? PROT_EXEC : 0);
33570 + loc = mmap((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
33572 + if(loc == MAP_FAILED)
33577 +int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
33579 + int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
33580 + (x ? PROT_EXEC : 0));
33582 + if(mprotect(addr, len, prot) < 0)
33587 +int os_unmap_memory(void *addr, int len)
33591 + err = munmap(addr, len);
33592 + if(err < 0) return(-errno);
33597 + * Overrides for Emacs so that we follow Linus's tabbing style.
33598 + * Emacs will notice this stuff at the end of the file and automatically
33599 + * adjust the settings for this buffer only. This must remain at the end
33601 + * ---------------------------------------------------------------------------
33602 + * Local variables:
33603 + * c-file-style: "linux"
33606 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/tty.c um/arch/um/os-Linux/tty.c
33607 --- orig/arch/um/os-Linux/tty.c 1969-12-31 19:00:00.000000000 -0500
33608 +++ um/arch/um/os-Linux/tty.c 2002-10-23 21:08:04.000000000 -0400
33611 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33612 + * Licensed under the GPL
33615 +#include <stdlib.h>
33616 +#include <errno.h>
33619 +#include "kern_util.h"
33621 +struct grantpt_info {
33627 +static void grantpt_cb(void *arg)
33629 + struct grantpt_info *info = arg;
33631 + info->res = grantpt(info->fd);
33632 + info->err = errno;
33637 + struct grantpt_info info;
33640 + if((fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0)) < 0){
33641 + printk("get_pty : Couldn't open /dev/ptmx - errno = %d\n",
33647 + initial_thread_cb(grantpt_cb, &info);
33649 + if(info.res < 0){
33650 + printk("get_pty : Couldn't grant pty - errno = %d\n",
33654 + if(unlockpt(fd) < 0){
33655 + printk("get_pty : Couldn't unlock pty - errno = %d\n", errno);
33662 + * Overrides for Emacs so that we follow Linus's tabbing style.
33663 + * Emacs will notice this stuff at the end of the file and automatically
33664 + * adjust the settings for this buffer only. This must remain at the end
33666 + * ---------------------------------------------------------------------------
33667 + * Local variables:
33668 + * c-file-style: "linux"
33671 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/bugs.c um/arch/um/sys-i386/bugs.c
33672 --- orig/arch/um/sys-i386/bugs.c 1969-12-31 19:00:00.000000000 -0500
33673 +++ um/arch/um/sys-i386/bugs.c 2003-05-29 13:46:50.000000000 -0400
33676 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33677 + * Licensed under the GPL
33680 +#include <unistd.h>
33681 +#include <fcntl.h>
33682 +#include <errno.h>
33683 +#include <string.h>
33684 +#include <sys/signal.h>
33685 +#include <asm/ldt.h>
33686 +#include "kern_util.h"
33688 +#include "sysdep/ptrace.h"
33691 +#define MAXTOKEN 64
33693 +/* Set during early boot */
33694 +int cpu_has_cmov = 1;
33695 +int cpu_has_xmm = 0;
33697 +static char token(int fd, char *buf, int len, char stop)
33700 + char *ptr, *end, c;
33705 + n = read(fd, ptr, sizeof(*ptr));
33707 + if(n == 0) return(0);
33708 + else if(n != sizeof(*ptr)){
33709 + printk("Reading /proc/cpuinfo failed, "
33710 + "errno = %d\n", errno);
33713 + } while((c != '\n') && (c != stop) && (ptr < end));
33716 + printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
33719 + *(ptr - 1) = '\0';
33723 +static int check_cpu_feature(char *feature, int *have_it)
33725 + char buf[MAXTOKEN], c;
33726 + int fd, len = sizeof(buf)/sizeof(buf[0]), n;
33728 + printk("Checking for host processor %s support...", feature);
33729 + fd = open("/proc/cpuinfo", O_RDONLY);
33731 + printk("Couldn't open /proc/cpuinfo, errno = %d\n", errno);
33736 + buf[len - 1] = '\0';
33738 + c = token(fd, buf, len - 1, ':');
33739 + if(c <= 0) goto out;
33740 + else if(c != ':'){
33741 + printk("Failed to find ':' in /proc/cpuinfo\n");
33745 + if(!strncmp(buf, "flags", strlen("flags"))) break;
33748 + n = read(fd, &c, sizeof(c));
33749 + if(n != sizeof(c)){
33750 + printk("Failed to find newline in "
33751 + "/proc/cpuinfo, n = %d, errno = %d\n",
33755 + } while(c != '\n');
33758 + c = token(fd, buf, len - 1, ' ');
33759 + if(c < 0) goto out;
33760 + else if(c != ' '){
33761 + printk("Failed to find ':' in /proc/cpuinfo\n");
33766 + c = token(fd, buf, len - 1, ' ');
33767 + if(c < 0) goto out;
33768 + else if(c == '\n') break;
33770 + if(!strcmp(buf, feature)){
33776 + if(*have_it == 0) printk("No\n");
33777 + else if(*have_it == 1) printk("Yes\n");
33782 +static void disable_lcall(void)
33784 + struct modify_ldt_ldt_s ldt;
33787 + bzero(&ldt, sizeof(ldt));
33788 + ldt.entry_number = 7;
33789 + ldt.base_addr = 0;
33791 + err = modify_ldt(1, &ldt, sizeof(ldt));
33793 + printk("Failed to disable lcall7 - errno = %d\n", errno);
33796 +void arch_init_thread(void)
33801 +void arch_check_bugs(void)
33805 + if(access("/proc/cpuinfo", R_OK)){
33806 + printk("/proc/cpuinfo not available - skipping CPU capability "
33810 + if(check_cpu_feature("cmov", &have_it)) cpu_has_cmov = have_it;
33811 + if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
33814 +int arch_handle_signal(int sig, union uml_pt_regs *regs)
33816 + unsigned long ip;
33818 + /* This is testing for a cmov (0x0f 0x4x) instruction causing a
33819 + * SIGILL in init.
33821 + if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0);
33823 + ip = UPT_IP(regs);
33824 + if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
33827 + if(cpu_has_cmov == 0)
33828 + panic("SIGILL caused by cmov, which this processor doesn't "
33829 + "implement, boot a filesystem compiled for older "
33831 + else if(cpu_has_cmov == 1)
33832 + panic("SIGILL caused by cmov, which this processor claims to "
33834 + else if(cpu_has_cmov == -1)
33835 + panic("SIGILL caused by cmov, couldn't tell if this processor "
33836 + "implements it, boot a filesystem compiled for older "
33838 + else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
33843 + * Overrides for Emacs so that we follow Linus's tabbing style.
33844 + * Emacs will notice this stuff at the end of the file and automatically
33845 + * adjust the settings for this buffer only. This must remain at the end
33847 + * ---------------------------------------------------------------------------
33848 + * Local variables:
33849 + * c-file-style: "linux"
33852 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/checksum.S um/arch/um/sys-i386/checksum.S
33853 --- orig/arch/um/sys-i386/checksum.S 1969-12-31 19:00:00.000000000 -0500
33854 +++ um/arch/um/sys-i386/checksum.S 2002-10-31 20:17:50.000000000 -0500
33857 + * INET An implementation of the TCP/IP protocol suite for the LINUX
33858 + * operating system. INET is implemented using the BSD Socket
33859 + * interface as the means of communication with the user level.
33861 + * IP/TCP/UDP checksumming routines
33863 + * Authors: Jorge Cwik, <jorge@laser.satlink.net>
33864 + * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
33865 + * Tom May, <ftom@netcom.com>
33866 + * Pentium Pro/II routines:
33867 + * Alexander Kjeldaas <astor@guardian.no>
33868 + * Finn Arne Gangstad <finnag@guardian.no>
33869 + * Lots of code moved from tcp.c and ip.c; see those files
33870 + * for more names.
33872 + * Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception
33874 + * Andi Kleen, add zeroing on error
33875 + * converted to pure assembler
33877 + * This program is free software; you can redistribute it and/or
33878 + * modify it under the terms of the GNU General Public License
33879 + * as published by the Free Software Foundation; either version
33880 + * 2 of the License, or (at your option) any later version.
33883 +#include <linux/config.h>
33884 +#include <asm/errno.h>
33887 + * computes a partial checksum, e.g. for TCP/UDP fragments
33891 +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
33896 +.globl arch_csum_partial
33898 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
33901 + * Experiments with Ethernet and SLIP connections show that buff
33902 + * is aligned on either a 2-byte or 4-byte boundary. We get at
33903 + * least a twofold speedup on 486 and Pentium if it is 4-byte aligned.
33904 + * Fortunately, it is easy to convert 2-byte alignment to 4-byte
33905 + * alignment for the unrolled loop.
33907 +arch_csum_partial:
33910 + movl 20(%esp),%eax # Function arg: unsigned int sum
33911 + movl 16(%esp),%ecx # Function arg: int len
33912 + movl 12(%esp),%esi # Function arg: unsigned char *buff
33913 + testl $2, %esi # Check alignment.
33914 + jz 2f # Jump if alignment is ok.
33915 + subl $2, %ecx # Alignment uses up two bytes.
33916 + jae 1f # Jump if we had at least two bytes.
33917 + addl $2, %ecx # ecx was < 2. Deal with it.
33919 +1: movw (%esi), %bx
33928 +1: movl (%esi), %ebx
33930 + movl 4(%esi), %ebx
33932 + movl 8(%esi), %ebx
33934 + movl 12(%esi), %ebx
33936 + movl 16(%esi), %ebx
33938 + movl 20(%esi), %ebx
33940 + movl 24(%esi), %ebx
33942 + movl 28(%esi), %ebx
33944 + lea 32(%esi), %esi
33948 +2: movl %edx, %ecx
33951 + shrl $2, %edx # This clears CF
33952 +3: adcl (%esi), %eax
33953 + lea 4(%esi), %esi
33962 + leal 2(%esi),%esi
33965 +5: movb (%esi),%cl
33975 +/* Version for PentiumII/PPro */
33977 +arch_csum_partial:
33980 + movl 20(%esp),%eax # Function arg: unsigned int sum
33981 + movl 16(%esp),%ecx # Function arg: int len
33982 + movl 12(%esp),%esi # Function arg: const unsigned char *buf
33994 + lea 45f(%ebx,%ebx,2), %ebx
33998 + # Handle 2-byte-aligned regions
33999 +20: addw (%esi), %ax
34000 + lea 2(%esi), %esi
34007 + movzbl (%esi),%ebx # csumming 1 byte, 2-aligned
34012 + addw (%esi), %ax # csumming 2 bytes, 2-aligned
34017 + addl -128(%esi), %eax
34018 + adcl -124(%esi), %eax
34019 + adcl -120(%esi), %eax
34020 + adcl -116(%esi), %eax
34021 + adcl -112(%esi), %eax
34022 + adcl -108(%esi), %eax
34023 + adcl -104(%esi), %eax
34024 + adcl -100(%esi), %eax
34025 + adcl -96(%esi), %eax
34026 + adcl -92(%esi), %eax
34027 + adcl -88(%esi), %eax
34028 + adcl -84(%esi), %eax
34029 + adcl -80(%esi), %eax
34030 + adcl -76(%esi), %eax
34031 + adcl -72(%esi), %eax
34032 + adcl -68(%esi), %eax
34033 + adcl -64(%esi), %eax
34034 + adcl -60(%esi), %eax
34035 + adcl -56(%esi), %eax
34036 + adcl -52(%esi), %eax
34037 + adcl -48(%esi), %eax
34038 + adcl -44(%esi), %eax
34039 + adcl -40(%esi), %eax
34040 + adcl -36(%esi), %eax
34041 + adcl -32(%esi), %eax
34042 + adcl -28(%esi), %eax
34043 + adcl -24(%esi), %eax
34044 + adcl -20(%esi), %eax
34045 + adcl -16(%esi), %eax
34046 + adcl -12(%esi), %eax
34047 + adcl -8(%esi), %eax
34048 + adcl -4(%esi), %eax
34050 + lea 128(%esi), %esi
34058 + # Handle the last 1-3 bytes without jumping
34059 + notl %ecx # 1->2, 2->1, 3->0, higher bits are masked
34060 + movl $0xffffff,%ebx # by the shll and shrl instructions
34063 + andl -128(%esi),%ebx # esi is 4-aligned so should be ok
34074 +unsigned int csum_partial_copy_generic (const char *src, char *dst,
34075 + int len, int sum, int *src_err_ptr, int *dst_err_ptr)
34079 + * Copy from ds while checksumming, otherwise like csum_partial
34081 + * The macros SRC and DST specify the type of access for the instruction.
34082 + * thus we can call a custom exception handler for all access types.
34084 + * FIXME: could someone double-check whether I haven't mixed up some SRC and
34085 + * DST definitions? It's damn hard to trigger all cases. I hope I got
34086 + * them all but there's no guarantee.
34089 +#define SRC(y...) \
34091 + .section __ex_table, "a"; \
34092 + .long 9999b, 6001f ; \
34095 +#define DST(y...) \
34097 + .section __ex_table, "a"; \
34098 + .long 9999b, 6002f ; \
34102 +.globl csum_partial_copy_generic_i386
34104 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
34106 +#define ARGBASE 16
34109 +csum_partial_copy_generic_i386:
34114 + movl ARGBASE+16(%esp),%eax # sum
34115 + movl ARGBASE+12(%esp),%ecx # len
34116 + movl ARGBASE+4(%esp),%esi # src
34117 + movl ARGBASE+8(%esp),%edi # dst
34119 + testl $2, %edi # Check alignment.
34120 + jz 2f # Jump if alignment is ok.
34121 + subl $2, %ecx # Alignment uses up two bytes.
34122 + jae 1f # Jump if we had at least two bytes.
34123 + addl $2, %ecx # ecx was < 2. Deal with it.
34125 +SRC(1: movw (%esi), %bx )
34127 +DST( movw %bx, (%edi) )
34132 + movl %ecx, FP(%esp)
34136 +SRC(1: movl (%esi), %ebx )
34137 +SRC( movl 4(%esi), %edx )
34139 +DST( movl %ebx, (%edi) )
34141 +DST( movl %edx, 4(%edi) )
34143 +SRC( movl 8(%esi), %ebx )
34144 +SRC( movl 12(%esi), %edx )
34146 +DST( movl %ebx, 8(%edi) )
34148 +DST( movl %edx, 12(%edi) )
34150 +SRC( movl 16(%esi), %ebx )
34151 +SRC( movl 20(%esi), %edx )
34153 +DST( movl %ebx, 16(%edi) )
34155 +DST( movl %edx, 20(%edi) )
34157 +SRC( movl 24(%esi), %ebx )
34158 +SRC( movl 28(%esi), %edx )
34160 +DST( movl %ebx, 24(%edi) )
34162 +DST( movl %edx, 28(%edi) )
34164 + lea 32(%esi), %esi
34165 + lea 32(%edi), %edi
34169 +2: movl FP(%esp), %edx
34173 + shrl $2, %edx # This clears CF
34174 +SRC(3: movl (%esi), %ebx )
34176 +DST( movl %ebx, (%edi) )
34177 + lea 4(%esi), %esi
34178 + lea 4(%edi), %edi
34186 +SRC( movw (%esi), %cx )
34187 + leal 2(%esi), %esi
34188 +DST( movw %cx, (%edi) )
34189 + leal 2(%edi), %edi
34192 +SRC(5: movb (%esi), %cl )
34193 +DST( movb %cl, (%edi) )
34194 +6: addl %ecx, %eax
34199 +# Exception handler:
34200 +.section .fixup, "ax"
34203 + movl ARGBASE+20(%esp), %ebx # src_err_ptr
34204 + movl $-EFAULT, (%ebx)
34206 + # zero the complete destination - computing the rest
34207 + # is too much work
34208 + movl ARGBASE+8(%esp), %edi # dst
34209 + movl ARGBASE+12(%esp), %ecx # len
34216 + movl ARGBASE+24(%esp), %ebx # dst_err_ptr
34217 + movl $-EFAULT,(%ebx)
34225 + popl %ecx # equivalent to addl $4,%esp
34230 +/* Version for PentiumII/PPro */
34232 +#define ROUND1(x) \
34233 + SRC(movl x(%esi), %ebx ) ; \
34234 + addl %ebx, %eax ; \
34235 + DST(movl %ebx, x(%edi) ) ;
34237 +#define ROUND(x) \
34238 + SRC(movl x(%esi), %ebx ) ; \
34239 + adcl %ebx, %eax ; \
34240 + DST(movl %ebx, x(%edi) ) ;
34242 +#define ARGBASE 12
34244 +csum_partial_copy_generic_i386:
34248 + movl ARGBASE+4(%esp),%esi #src
34249 + movl ARGBASE+8(%esp),%edi #dst
34250 + movl ARGBASE+12(%esp),%ecx #len
34251 + movl ARGBASE+16(%esp),%eax #sum
34260 + lea -1(%esi),%edx
34262 + lea 3f(%ebx,%ebx), %ebx
34267 + SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl)
34268 + ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52)
34269 + ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36)
34270 + ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20)
34271 + ROUND (-16) ROUND(-12) ROUND(-8) ROUND(-4)
34276 +4: movl ARGBASE+12(%esp),%edx #len
34281 +SRC( movw (%esi), %dx )
34282 + leal 2(%esi), %esi
34283 +DST( movw %dx, (%edi) )
34284 + leal 2(%edi), %edi
34288 +SRC( movb (%esi), %dl )
34289 +DST( movb %dl, (%edi) )
34290 +6: addl %edx, %eax
34293 +.section .fixup, "ax"
34294 +6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
34295 + movl $-EFAULT, (%ebx)
34296 + # zero the complete destination (computing the rest is too much work)
34297 + movl ARGBASE+8(%esp),%edi # dst
34298 + movl ARGBASE+12(%esp),%ecx # len
34302 +6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
34303 + movl $-EFAULT, (%ebx)
34316 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/fault.c um/arch/um/sys-i386/fault.c
34317 --- orig/arch/um/sys-i386/fault.c 1969-12-31 19:00:00.000000000 -0500
34318 +++ um/arch/um/sys-i386/fault.c 2002-10-27 16:49:35.000000000 -0500
34321 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34322 + * Licensed under the GPL
34325 +#include <signal.h>
34326 +#include "sysdep/ptrace.h"
34327 +#include "sysdep/sigcontext.h"
34329 +extern unsigned long search_exception_table(unsigned long addr);
34331 +int arch_fixup(unsigned long address, void *sc_ptr)
34333 + struct sigcontext *sc = sc_ptr;
34334 + unsigned long fixup;
34336 + fixup = search_exception_table(address);
34345 + * Overrides for Emacs so that we follow Linus's tabbing style.
34346 + * Emacs will notice this stuff at the end of the file and automatically
34347 + * adjust the settings for this buffer only. This must remain at the end
34349 + * ---------------------------------------------------------------------------
34350 + * Local variables:
34351 + * c-file-style: "linux"
34354 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ksyms.c um/arch/um/sys-i386/ksyms.c
34355 --- orig/arch/um/sys-i386/ksyms.c 1969-12-31 19:00:00.000000000 -0500
34356 +++ um/arch/um/sys-i386/ksyms.c 2002-10-29 21:01:45.000000000 -0500
34358 +#include "linux/module.h"
34359 +#include "linux/in6.h"
34360 +#include "linux/rwsem.h"
34361 +#include "asm/byteorder.h"
34362 +#include "asm/semaphore.h"
34363 +#include "asm/uaccess.h"
34364 +#include "asm/checksum.h"
34365 +#include "asm/errno.h"
34367 +EXPORT_SYMBOL(__down_failed);
34368 +EXPORT_SYMBOL(__down_failed_interruptible);
34369 +EXPORT_SYMBOL(__down_failed_trylock);
34370 +EXPORT_SYMBOL(__up_wakeup);
34372 +/* Networking helper routines. */
34373 +EXPORT_SYMBOL(csum_partial_copy_from);
34374 +EXPORT_SYMBOL(csum_partial_copy_to);
34375 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ldt.c um/arch/um/sys-i386/ldt.c
34376 --- orig/arch/um/sys-i386/ldt.c 1969-12-31 19:00:00.000000000 -0500
34377 +++ um/arch/um/sys-i386/ldt.c 2002-11-13 12:43:04.000000000 -0500
34380 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
34381 + * Licensed under the GPL
34384 +#include "linux/config.h"
34385 +#include "linux/slab.h"
34386 +#include "asm/uaccess.h"
34387 +#include "asm/ptrace.h"
34388 +#include "choose-mode.h"
34391 +#ifdef CONFIG_MODE_TT
34392 +extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
34394 +int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
34396 + if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT);
34397 + return(modify_ldt(func, ptr, bytecount));
34401 +#ifdef CONFIG_MODE_SKAS
34402 +extern int userspace_pid;
34404 +int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
34406 + struct ptrace_ldt ldt;
34410 + buf = kmalloc(bytecount, GFP_KERNEL);
34419 + res = copy_from_user(buf, ptr, bytecount);
34428 + ldt = ((struct ptrace_ldt) { .func = func,
34430 + .bytecount = bytecount });
34431 + res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt);
34439 + res = copy_to_user(ptr, buf, n);
34453 +int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
34455 + return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
34456 + ptr, bytecount));
34462 + * Overrides for Emacs so that we follow Linus's tabbing style.
34463 + * Emacs will notice this stuff at the end of the file and automatically
34464 + * adjust the settings for this buffer only. This must remain at the end
34466 + * ---------------------------------------------------------------------------
34467 + * Local variables:
34468 + * c-file-style: "linux"
34471 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/Makefile um/arch/um/sys-i386/Makefile
34472 --- orig/arch/um/sys-i386/Makefile 1969-12-31 19:00:00.000000000 -0500
34473 +++ um/arch/um/sys-i386/Makefile 2002-11-23 23:34:24.000000000 -0500
34476 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34477 +# Licensed under the GPL
34480 +O_TARGET = built-in.o
34482 +obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \
34483 + ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
34484 +export-objs = ksyms.o
34486 +USER_OBJS = bugs.o ptrace_user.o sigcontext.o fault.o
34488 +SYMLINKS = semaphore.c extable.c
34490 +semaphore.c-dir = kernel
34491 +extable.c-dir = mm
34493 +include $(TOPDIR)/Rules.make
34495 +$(USER_OBJS) : %.o: %.c
34496 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
34500 + ln -sf $(TOPDIR)/arch/i386/$($1-dir)/$1 $1
34504 + $(call make_link,$@)
34507 + $(MAKE) -C util clean
34508 + rm -f $(SYMLINKS)
34521 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace.c um/arch/um/sys-i386/ptrace.c
34522 --- orig/arch/um/sys-i386/ptrace.c 1969-12-31 19:00:00.000000000 -0500
34523 +++ um/arch/um/sys-i386/ptrace.c 2002-10-27 16:49:35.000000000 -0500
34526 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
34527 + * Licensed under the GPL
34530 +#include "linux/sched.h"
34531 +#include "asm/elf.h"
34532 +#include "asm/ptrace.h"
34533 +#include "asm/uaccess.h"
34534 +#include "ptrace_user.h"
34535 +#include "sysdep/sigcontext.h"
34536 +#include "sysdep/sc.h"
34538 +void arch_switch(void)
34540 + update_debugregs(current->thread.arch.debugregs_seq);
34543 +int is_syscall(unsigned long addr)
34545 + unsigned short instr;
34548 + n = copy_from_user(&instr, (void *) addr, sizeof(instr));
34550 + printk("is_syscall : failed to read instruction from 0x%lu\n",
34554 + return(instr == 0x80cd);
34557 +/* determines which flags the user has access to. */
34558 +/* 1 = access 0 = no access */
34559 +#define FLAG_MASK 0x00044dd5
34561 +int putreg(struct task_struct *child, int regno, unsigned long value)
34566 + if (value && (value & 3) != 3)
34568 + PT_REGS_FS(&child->thread.regs) = value;
34571 + if (value && (value & 3) != 3)
34573 + PT_REGS_GS(&child->thread.regs) = value;
34577 + if (value && (value & 3) != 3)
34583 + if ((value & 3) != 3)
34588 + value &= FLAG_MASK;
34589 + value |= PT_REGS_EFLAGS(&child->thread.regs);
34592 + PT_REGS_SET(&child->thread.regs, regno, value);
34596 +unsigned long getreg(struct task_struct *child, int regno)
34598 + unsigned long retval = ~0UL;
34609 + /* fall through */
34611 + retval &= PT_REG(&child->thread.regs, regno);
34616 +struct i387_fxsave_struct {
34617 + unsigned short cwd;
34618 + unsigned short swd;
34619 + unsigned short twd;
34620 + unsigned short fop;
34627 + long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
34628 + long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
34629 + long padding[56];
34633 + * FPU tag word conversions.
34636 +static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
34638 + unsigned int tmp; /* to avoid 16 bit prefixes in the code */
34640 + /* Transform each pair of bits into 01 (valid) or 00 (empty) */
34642 + tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
34643 + /* and move the valid bits to the lower byte. */
34644 + tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
34645 + tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
34646 + tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
34650 +static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
34652 + struct _fpxreg *st = NULL;
34653 + unsigned long twd = (unsigned long) fxsave->twd;
34654 + unsigned long tag;
34655 + unsigned long ret = 0xffff0000;
34658 +#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
34660 + for ( i = 0 ; i < 8 ; i++ ) {
34661 + if ( twd & 0x1 ) {
34662 + st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
34664 + switch ( st->exponent & 0x7fff ) {
34666 + tag = 2; /* Special */
34669 + if ( !st->significand[0] &&
34670 + !st->significand[1] &&
34671 + !st->significand[2] &&
34672 + !st->significand[3] ) {
34673 + tag = 1; /* Zero */
34675 + tag = 2; /* Special */
34679 + if ( st->significand[3] & 0x8000 ) {
34680 + tag = 0; /* Valid */
34682 + tag = 2; /* Special */
34687 + tag = 3; /* Empty */
34689 + ret |= (tag << (2 * i));
34696 + * FXSR floating point environment conversions.
34699 +#ifdef CONFIG_MODE_TT
34700 +static inline int convert_fxsr_to_user_tt(struct _fpstate *buf,
34701 + struct pt_regs *regs)
34703 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
34704 + unsigned long env[7];
34705 + struct _fpreg *to;
34706 + struct _fpxreg *from;
34709 + env[0] = (unsigned long)fxsave->cwd | 0xffff0000;
34710 + env[1] = (unsigned long)fxsave->swd | 0xffff0000;
34711 + env[2] = twd_fxsr_to_i387(fxsave);
34712 + env[3] = fxsave->fip;
34713 + env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
34714 + env[5] = fxsave->foo;
34715 + env[6] = fxsave->fos;
34717 + if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
34720 + to = &buf->_st[0];
34721 + from = (struct _fpxreg *) &fxsave->st_space[0];
34722 + for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
34723 + if ( __copy_to_user( to, from, sizeof(*to) ) )
34730 +static inline int convert_fxsr_to_user(struct _fpstate *buf,
34731 + struct pt_regs *regs)
34733 + return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0));
34736 +#ifdef CONFIG_MODE_TT
34737 +static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
34738 + struct _fpstate *buf)
34740 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
34741 + unsigned long env[7];
34742 + struct _fpxreg *to;
34743 + struct _fpreg *from;
34746 + if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
34749 + fxsave->cwd = (unsigned short)(env[0] & 0xffff);
34750 + fxsave->swd = (unsigned short)(env[1] & 0xffff);
34751 + fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
34752 + fxsave->fip = env[3];
34753 + fxsave->fop = (unsigned short)((env[4] & 0xffff0000) >> 16);
34754 + fxsave->fcs = (env[4] & 0xffff);
34755 + fxsave->foo = env[5];
34756 + fxsave->fos = env[6];
34758 + to = (struct _fpxreg *) &fxsave->st_space[0];
34759 + from = &buf->_st[0];
34760 + for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
34761 + if ( __copy_from_user( to, from, sizeof(*from) ) )
34768 +static inline int convert_fxsr_from_user(struct pt_regs *regs,
34769 + struct _fpstate *buf)
34771 + return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0));
34774 +int get_fpregs(unsigned long buf, struct task_struct *child)
34778 + err = convert_fxsr_to_user((struct _fpstate *) buf,
34779 + &child->thread.regs);
34780 + if(err) return(-EFAULT);
34784 +int set_fpregs(unsigned long buf, struct task_struct *child)
34788 + err = convert_fxsr_from_user(&child->thread.regs,
34789 + (struct _fpstate *) buf);
34790 + if(err) return(-EFAULT);
34794 +#ifdef CONFIG_MODE_TT
34795 +int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
34797 + struct pt_regs *regs = &tsk->thread.regs;
34798 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
34801 + err = __copy_to_user((void *) buf, fxsave,
34802 + sizeof(struct user_fxsr_struct));
34803 + if(err) return -EFAULT;
34808 +int get_fpxregs(unsigned long buf, struct task_struct *tsk)
34810 + return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0));
34813 +#ifdef CONFIG_MODE_TT
34814 +int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
34816 + struct pt_regs *regs = &tsk->thread.regs;
34817 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
34820 + err = __copy_from_user(fxsave, (void *) buf,
34821 + sizeof(struct user_fxsr_struct) );
34822 + if(err) return -EFAULT;
34827 +int set_fpxregs(unsigned long buf, struct task_struct *tsk)
34829 + return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0));
34833 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
34835 + fpu->cwd = (((SC_FP_CW(PT_REGS_SC(regs)) & 0xffff) << 16) |
34836 + (SC_FP_SW(PT_REGS_SC(regs)) & 0xffff));
34837 + fpu->swd = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
34838 + fpu->twd = SC_FP_IPOFF(PT_REGS_SC(regs));
34839 + fpu->fip = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
34840 + fpu->fcs = SC_FP_DATAOFF(PT_REGS_SC(regs));
34841 + fpu->foo = SC_FP_DATASEL(PT_REGS_SC(regs));
34843 + memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)),
34844 + sizeof(fpu->st_space));
34849 +#ifdef CONFIG_MODE_TT
34850 +static inline void copy_fpu_fxsave_tt(struct pt_regs *regs,
34851 + struct user_i387_struct *buf)
34853 + struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs));
34854 + unsigned short *to;
34855 + unsigned short *from;
34858 + memcpy( buf, fpu, 7 * sizeof(long) );
34860 + to = (unsigned short *) &buf->st_space[0];
34861 + from = (unsigned short *) &fpu->st_space[0];
34862 + for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) {
34863 + memcpy( to, from, 5 * sizeof(unsigned short) );
34868 +static inline void copy_fpu_fxsave(struct pt_regs *regs,
34869 + struct user_i387_struct *buf)
34871 + (void) CHOOSE_MODE(copy_fpu_fxsave_tt(regs, buf), 0);
34874 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
34876 + copy_fpu_fxsave(regs, (struct user_i387_struct *) fpu);
34881 + * Overrides for Emacs so that we follow Linus's tabbing style.
34882 + * Emacs will notice this stuff at the end of the file and automatically
34883 + * adjust the settings for this buffer only. This must remain at the end
34885 + * ---------------------------------------------------------------------------
34886 + * Local variables:
34887 + * c-file-style: "linux"
34890 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace_user.c um/arch/um/sys-i386/ptrace_user.c
34891 --- orig/arch/um/sys-i386/ptrace_user.c 1969-12-31 19:00:00.000000000 -0500
34892 +++ um/arch/um/sys-i386/ptrace_user.c 2002-10-23 21:08:04.000000000 -0400
34895 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34896 + * Licensed under the GPL
34899 +#include <stdio.h>
34900 +#include <errno.h>
34901 +#include <unistd.h>
34902 +#include <linux/stddef.h>
34903 +#include <sys/ptrace.h>
34904 +#include <asm/ptrace.h>
34905 +#include <asm/user.h>
34906 +#include "kern_util.h"
34907 +#include "sysdep/thread.h"
34911 +int ptrace_getregs(long pid, unsigned long *regs_out)
34913 + return(ptrace(PTRACE_GETREGS, pid, 0, regs_out));
34916 +int ptrace_setregs(long pid, unsigned long *regs)
34918 + return(ptrace(PTRACE_SETREGS, pid, 0, regs));
34921 +int ptrace_getfpregs(long pid, unsigned long *regs)
34923 + return(ptrace(PTRACE_GETFPREGS, pid, 0, regs));
34926 +static void write_debugregs(int pid, unsigned long *regs)
34928 + struct user *dummy;
34932 + nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
34933 + for(i = 0; i < nregs; i++){
34934 + if((i == 4) || (i == 5)) continue;
34935 + if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
34937 + printk("write_debugregs - ptrace failed, "
34938 + "errno = %d\n", errno);
34942 +static void read_debugregs(int pid, unsigned long *regs)
34944 + struct user *dummy;
34948 + nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
34949 + for(i = 0; i < nregs; i++){
34950 + regs[i] = ptrace(PTRACE_PEEKUSR, pid,
34951 + &dummy->u_debugreg[i], 0);
34955 +/* Accessed only by the tracing thread */
34956 +static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
34957 +static int debugregs_seq = 0;
34959 +void arch_enter_kernel(void *task, int pid)
34961 + read_debugregs(pid, TASK_DEBUGREGS(task));
34962 + write_debugregs(pid, kernel_debugregs);
34965 +void arch_leave_kernel(void *task, int pid)
34967 + read_debugregs(pid, kernel_debugregs);
34968 + write_debugregs(pid, TASK_DEBUGREGS(task));
34971 +void ptrace_pokeuser(unsigned long addr, unsigned long data)
34973 + if((addr < offsetof(struct user, u_debugreg[0])) ||
34974 + (addr > offsetof(struct user, u_debugreg[7])))
34976 + addr -= offsetof(struct user, u_debugreg[0]);
34977 + addr = addr >> 2;
34978 + if(kernel_debugregs[addr] == data) return;
34980 + kernel_debugregs[addr] = data;
34984 +static void update_debugregs_cb(void *arg)
34986 + int pid = *((int *) arg);
34988 + write_debugregs(pid, kernel_debugregs);
34991 +void update_debugregs(int seq)
34995 + if(seq == debugregs_seq) return;
34997 + me = os_getpid();
34998 + initial_thread_cb(update_debugregs_cb, &me);
35002 + * Overrides for Emacs so that we follow Linus's tabbing style.
35003 + * Emacs will notice this stuff at the end of the file and automatically
35004 + * adjust the settings for this buffer only. This must remain at the end
35006 + * ---------------------------------------------------------------------------
35007 + * Local variables:
35008 + * c-file-style: "linux"
35011 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sigcontext.c um/arch/um/sys-i386/sigcontext.c
35012 --- orig/arch/um/sys-i386/sigcontext.c 1969-12-31 19:00:00.000000000 -0500
35013 +++ um/arch/um/sys-i386/sigcontext.c 2002-12-02 23:20:13.000000000 -0500
35016 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
35017 + * Licensed under the GPL
35020 +#include <stddef.h>
35021 +#include <string.h>
35022 +#include <asm/ptrace.h>
35023 +#include <asm/sigcontext.h>
35024 +#include "sysdep/ptrace.h"
35025 +#include "kern_util.h"
35026 +#include "frame_user.h"
35028 +int sc_size(void *data)
35030 + struct arch_frame_data *arch = data;
35032 + return(sizeof(struct sigcontext) + arch->fpstate_size);
35035 +void sc_to_sc(void *to_ptr, void *from_ptr)
35037 + struct sigcontext *to = to_ptr, *from = from_ptr;
35038 + int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size;
35040 + memcpy(to, from, size);
35041 + if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1);
35044 +unsigned long *sc_sigmask(void *sc_ptr)
35046 + struct sigcontext *sc = sc_ptr;
35048 + return(&sc->oldmask);
35051 +int sc_get_fpregs(unsigned long buf, void *sc_ptr)
35053 + struct sigcontext *sc = sc_ptr;
35054 + struct _fpstate *from = sc->fpstate, *to = (struct _fpstate *) buf;
35057 + if(from == NULL){
35058 + err |= clear_user_proc(&to->cw, sizeof(to->cw));
35059 + err |= clear_user_proc(&to->sw, sizeof(to->sw));
35060 + err |= clear_user_proc(&to->tag, sizeof(to->tag));
35061 + err |= clear_user_proc(&to->ipoff, sizeof(to->ipoff));
35062 + err |= clear_user_proc(&to->cssel, sizeof(to->cssel));
35063 + err |= clear_user_proc(&to->dataoff, sizeof(to->dataoff));
35064 + err |= clear_user_proc(&to->datasel, sizeof(to->datasel));
35065 + err |= clear_user_proc(&to->_st, sizeof(to->_st));
35068 + err |= copy_to_user_proc(&to->cw, &from->cw, sizeof(to->cw));
35069 + err |= copy_to_user_proc(&to->sw, &from->sw, sizeof(to->sw));
35070 + err |= copy_to_user_proc(&to->tag, &from->tag,
35071 + sizeof(to->tag));
35072 + err |= copy_to_user_proc(&to->ipoff, &from->ipoff,
35073 + sizeof(to->ipoff));
35074 + err |= copy_to_user_proc(&to->cssel,& from->cssel,
35075 + sizeof(to->cssel));
35076 + err |= copy_to_user_proc(&to->dataoff, &from->dataoff,
35077 + sizeof(to->dataoff));
35078 + err |= copy_to_user_proc(&to->datasel, &from->datasel,
35079 + sizeof(to->datasel));
35080 + err |= copy_to_user_proc(to->_st, from->_st, sizeof(to->_st));
35086 + * Overrides for Emacs so that we follow Linus's tabbing style.
35087 + * Emacs will notice this stuff at the end of the file and automatically
35088 + * adjust the settings for this buffer only. This must remain at the end
35090 + * ---------------------------------------------------------------------------
35091 + * Local variables:
35092 + * c-file-style: "linux"
35095 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/syscalls.c um/arch/um/sys-i386/syscalls.c
35096 --- orig/arch/um/sys-i386/syscalls.c 1969-12-31 19:00:00.000000000 -0500
35097 +++ um/arch/um/sys-i386/syscalls.c 2002-10-23 21:08:04.000000000 -0400
35100 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
35101 + * Licensed under the GPL
35104 +#include "asm/mman.h"
35105 +#include "asm/uaccess.h"
35106 +#include "asm/unistd.h"
35109 + * Perform the select(nd, in, out, ex, tv) and mmap() system
35110 + * calls. Linux/i386 didn't use to be able to handle more than
35111 + * 4 system call parameters, so these system calls used a memory
35112 + * block for parameter passing..
35115 +struct mmap_arg_struct {
35116 + unsigned long addr;
35117 + unsigned long len;
35118 + unsigned long prot;
35119 + unsigned long flags;
35120 + unsigned long fd;
35121 + unsigned long offset;
35124 +extern int old_mmap(unsigned long addr, unsigned long len,
35125 + unsigned long prot, unsigned long flags,
35126 + unsigned long fd, unsigned long offset);
35128 +int old_mmap_i386(struct mmap_arg_struct *arg)
35130 + struct mmap_arg_struct a;
35131 + int err = -EFAULT;
35133 + if (copy_from_user(&a, arg, sizeof(a)))
35136 + err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
35141 +struct sel_arg_struct {
35143 + fd_set *inp, *outp, *exp;
35144 + struct timeval *tvp;
35147 +int old_select(struct sel_arg_struct *arg)
35149 + struct sel_arg_struct a;
35151 + if (copy_from_user(&a, arg, sizeof(a)))
35153 + /* sys_select() does the appropriate kernel locking */
35154 + return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
35158 + * Overrides for Emacs so that we follow Linus's tabbing style.
35159 + * Emacs will notice this stuff at the end of the file and automatically
35160 + * adjust the settings for this buffer only. This must remain at the end
35162 + * ---------------------------------------------------------------------------
35163 + * Local variables:
35164 + * c-file-style: "linux"
35167 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sysrq.c um/arch/um/sys-i386/sysrq.c
35168 --- orig/arch/um/sys-i386/sysrq.c 1969-12-31 19:00:00.000000000 -0500
35169 +++ um/arch/um/sys-i386/sysrq.c 2002-10-23 21:08:04.000000000 -0400
35171 +#include "linux/kernel.h"
35172 +#include "linux/smp.h"
35173 +#include "linux/sched.h"
35174 +#include "asm/ptrace.h"
35175 +#include "sysrq.h"
35177 +void show_regs(struct pt_regs *regs)
35180 + printk("EIP: %04lx:[<%08lx>] CPU: %d %s",
35181 + 0xffff & PT_REGS_CS(regs), PT_REGS_IP(regs),
35182 + smp_processor_id(), print_tainted());
35183 + if (PT_REGS_CS(regs) & 3)
35184 + printk(" ESP: %04lx:%08lx", 0xffff & PT_REGS_SS(regs),
35185 + PT_REGS_SP(regs));
35186 + printk(" EFLAGS: %08lx\n %s\n", PT_REGS_EFLAGS(regs),
35187 + print_tainted());
35188 + printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
35189 + PT_REGS_EAX(regs), PT_REGS_EBX(regs),
35190 + PT_REGS_ECX(regs),
35191 + PT_REGS_EDX(regs));
35192 + printk("ESI: %08lx EDI: %08lx EBP: %08lx",
35193 + PT_REGS_ESI(regs), PT_REGS_EDI(regs),
35194 + PT_REGS_EBP(regs));
35195 + printk(" DS: %04lx ES: %04lx\n",
35196 + 0xffff & PT_REGS_DS(regs),
35197 + 0xffff & PT_REGS_ES(regs));
35199 + show_trace((unsigned long *) ®s);
35201 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/Makefile um/arch/um/sys-i386/util/Makefile
35202 --- orig/arch/um/sys-i386/util/Makefile 1969-12-31 19:00:00.000000000 -0500
35203 +++ um/arch/um/sys-i386/util/Makefile 2002-10-23 21:08:04.000000000 -0400
35205 +EXE = mk_sc mk_thread
35207 +include $(TOPDIR)/Rules.make
35212 + $(CC) -o mk_sc mk_sc.o
35217 +mk_thread : mk_thread_user.o mk_thread_kern.o
35218 + $(CC) -o mk_thread mk_thread_user.o mk_thread_kern.o
35220 +mk_thread_user.o : mk_thread_user.c
35223 +mk_thread_kern.o : mk_thread_kern.c
35224 + $(CC) $(CFLAGS) -c $<
35229 +archmrproper : clean
35233 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/mk_sc.c um/arch/um/sys-i386/util/mk_sc.c
35234 --- orig/arch/um/sys-i386/util/mk_sc.c 1969-12-31 19:00:00.000000000 -0500
35235 +++ um/arch/um/sys-i386/util/mk_sc.c 2002-10-23 21:08:04.000000000 -0400
35237 +#include <stdio.h>
35238 +#include <signal.h>
35239 +#include <linux/stddef.h>
35241 +#define SC_OFFSET(name, field) \
35242 + printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
35243 + offsetof(struct sigcontext, field))
35245 +#define SC_FP_OFFSET(name, field) \
35246 + printf("#define " name \
35247 + "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
35248 + offsetof(struct _fpstate, field))
35250 +#define SC_FP_OFFSET_PTR(name, field, type) \
35251 + printf("#define " name \
35252 + "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
35253 + offsetof(struct _fpstate, field))
35255 +int main(int argc, char **argv)
35257 + SC_OFFSET("SC_IP", eip);
35258 + SC_OFFSET("SC_SP", esp);
35259 + SC_OFFSET("SC_FS", fs);
35260 + SC_OFFSET("SC_GS", gs);
35261 + SC_OFFSET("SC_DS", ds);
35262 + SC_OFFSET("SC_ES", es);
35263 + SC_OFFSET("SC_SS", ss);
35264 + SC_OFFSET("SC_CS", cs);
35265 + SC_OFFSET("SC_EFLAGS", eflags);
35266 + SC_OFFSET("SC_EAX", eax);
35267 + SC_OFFSET("SC_EBX", ebx);
35268 + SC_OFFSET("SC_ECX", ecx);
35269 + SC_OFFSET("SC_EDX", edx);
35270 + SC_OFFSET("SC_EDI", edi);
35271 + SC_OFFSET("SC_ESI", esi);
35272 + SC_OFFSET("SC_EBP", ebp);
35273 + SC_OFFSET("SC_TRAPNO", trapno);
35274 + SC_OFFSET("SC_ERR", err);
35275 + SC_OFFSET("SC_CR2", cr2);
35276 + SC_OFFSET("SC_FPSTATE", fpstate);
35277 + SC_FP_OFFSET("SC_FP_CW", cw);
35278 + SC_FP_OFFSET("SC_FP_SW", sw);
35279 + SC_FP_OFFSET("SC_FP_TAG", tag);
35280 + SC_FP_OFFSET("SC_FP_IPOFF", ipoff);
35281 + SC_FP_OFFSET("SC_FP_CSSEL", cssel);
35282 + SC_FP_OFFSET("SC_FP_DATAOFF", dataoff);
35283 + SC_FP_OFFSET("SC_FP_DATASEL", datasel);
35284 + SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate");
35285 + SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void");
35288 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
35289 --- orig/arch/um/sys-i386/util/mk_thread_kern.c 1969-12-31 19:00:00.000000000 -0500
35290 +++ um/arch/um/sys-i386/util/mk_thread_kern.c 2002-12-09 23:24:38.000000000 -0500
35292 +#include "linux/config.h"
35293 +#include "linux/stddef.h"
35294 +#include "linux/sched.h"
35296 +extern void print_head(void);
35297 +extern void print_constant_ptr(char *name, int value);
35298 +extern void print_constant(char *name, char *type, int value);
35299 +extern void print_tail(void);
35301 +#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
35303 +int main(int argc, char **argv)
35306 + print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs));
35307 +#ifdef CONFIG_MODE_TT
35308 + print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
35314 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
35315 --- orig/arch/um/sys-i386/util/mk_thread_user.c 1969-12-31 19:00:00.000000000 -0500
35316 +++ um/arch/um/sys-i386/util/mk_thread_user.c 2002-10-23 21:08:04.000000000 -0400
35318 +#include <stdio.h>
35320 +void print_head(void)
35323 + printf(" * Generated by mk_thread\n");
35326 + printf("#ifndef __UM_THREAD_H\n");
35327 + printf("#define __UM_THREAD_H\n");
35331 +void print_constant_ptr(char *name, int value)
35333 + printf("#define %s(task) ((unsigned long *) "
35334 + "&(((char *) (task))[%d]))\n", name, value);
35337 +void print_constant(char *name, char *type, int value)
35339 + printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
35343 +void print_tail(void)
35346 + printf("#endif\n");
35348 diff -Naur -X ../exclude-files orig/arch/um/sys-ia64/Makefile um/arch/um/sys-ia64/Makefile
35349 --- orig/arch/um/sys-ia64/Makefile 1969-12-31 19:00:00.000000000 -0500
35350 +++ um/arch/um/sys-ia64/Makefile 2002-10-23 21:08:04.000000000 -0400
35360 + $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
35370 + @$(MAKEBOOT) clean
35377 +include $(TOPDIR)/Rules.make
35378 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/Makefile um/arch/um/sys-ppc/Makefile
35379 --- orig/arch/um/sys-ppc/Makefile 1969-12-31 19:00:00.000000000 -0500
35380 +++ um/arch/um/sys-ppc/Makefile 2002-10-23 21:08:04.000000000 -0400
35385 + $(CC) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
35387 +OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \
35388 + ptrace_user.o sysrq.o
35390 +EXTRA_AFLAGS := -DCONFIG_ALL_PPC -I. -I$(TOPDIR)/arch/ppc/kernel
35396 + $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
35398 +ptrace_user.o: ptrace_user.c
35399 + $(CC) -D__KERNEL__ $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
35401 +sigcontext.o: sigcontext.c
35402 + $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
35406 + ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
35410 + ln -s $(TOPDIR)/arch/ppc/lib/$@ $@
35414 + ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
35418 + ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
35420 +ppc_defs.h: mk_defs.c ppc_defs.head \
35421 + $(TOPDIR)/include/asm-ppc/mmu.h \
35422 + $(TOPDIR)/include/asm-ppc/processor.h \
35423 + $(TOPDIR)/include/asm-ppc/pgtable.h \
35424 + $(TOPDIR)/include/asm-ppc/ptrace.h
35425 +# $(CC) $(CFLAGS) -S mk_defs.c
35426 + cp ppc_defs.head ppc_defs.h
35427 +# for bk, this way we can write to the file even if it's not checked out
35428 + echo '#define THREAD 608' >> ppc_defs.h
35429 + echo '#define PT_REGS 8' >> ppc_defs.h
35430 + echo '#define CLONE_VM 256' >> ppc_defs.h
35431 +# chmod u+w ppc_defs.h
35432 +# grep '^#define' mk_defs.s >> ppc_defs.h
35435 +# the asm link is horrible, and breaks the other targets. This is also
35436 +# not going to work with parallel makes.
35438 +checksum.o: checksum.S
35440 + ln -s $(TOPDIR)/include/asm-ppc asm
35441 + $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
35444 +misc.o: misc.S ppc_defs.h
35446 + ln -s $(TOPDIR)/include/asm-ppc asm
35447 + $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
35453 + rm -f checksum.S semaphore.c mk_defs.c
35461 +include $(TOPDIR)/Rules.make
35462 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/misc.S um/arch/um/sys-ppc/misc.S
35463 --- orig/arch/um/sys-ppc/misc.S 1969-12-31 19:00:00.000000000 -0500
35464 +++ um/arch/um/sys-ppc/misc.S 2002-10-23 21:08:04.000000000 -0400
35467 + * This file contains miscellaneous low-level functions.
35468 + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
35470 + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
35471 + * and Paul Mackerras.
35473 + * A couple of functions stolen from arch/ppc/kernel/misc.S for UML
35474 + * by Chris Emerson.
35476 + * This program is free software; you can redistribute it and/or
35477 + * modify it under the terms of the GNU General Public License
35478 + * as published by the Free Software Foundation; either version
35479 + * 2 of the License, or (at your option) any later version.
35483 +#include <linux/config.h>
35484 +#include <asm/processor.h>
35485 +#include "ppc_asm.h"
35487 +#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
35488 +#define CACHE_LINE_SIZE 16
35489 +#define LG_CACHE_LINE_SIZE 4
35490 +#define MAX_COPY_PREFETCH 1
35491 +#elif !defined(CONFIG_PPC64BRIDGE)
35492 +#define CACHE_LINE_SIZE 32
35493 +#define LG_CACHE_LINE_SIZE 5
35494 +#define MAX_COPY_PREFETCH 4
35496 +#define CACHE_LINE_SIZE 128
35497 +#define LG_CACHE_LINE_SIZE 7
35498 +#define MAX_COPY_PREFETCH 1
35499 +#endif /* CONFIG_4xx || CONFIG_8xx */
35504 + * Clear a page using the dcbz instruction, which doesn't cause any
35505 + * memory traffic (except to write out any cache lines which get
35506 + * displaced). This only works on cacheable memory.
35508 +_GLOBAL(clear_page)
35509 + li r0,4096/CACHE_LINE_SIZE
35520 + addi r3,r3,CACHE_LINE_SIZE
35525 + * Copy a whole page. We use the dcbz instruction on the destination
35526 + * to reduce memory traffic (it eliminates the unnecessary reads of
35527 + * the destination into cache). This requires that the destination
35530 +#define COPY_16_BYTES \
35534 + lwzu r9,16(r4); \
35540 +_GLOBAL(copy_page)
35545 +#ifndef CONFIG_8xx
35546 +#if MAX_COPY_PREFETCH > 1
35547 + li r0,MAX_COPY_PREFETCH
35551 + addi r11,r11,CACHE_LINE_SIZE
35553 +#else /* MAX_COPY_PREFETCH == 1 */
35555 + li r11,CACHE_LINE_SIZE+4
35556 +#endif /* MAX_COPY_PREFETCH */
35557 +#endif /* CONFIG_8xx */
35559 + li r0,4096/CACHE_LINE_SIZE
35562 +#ifndef CONFIG_8xx
35567 +#if CACHE_LINE_SIZE >= 32
35569 +#if CACHE_LINE_SIZE >= 64
35572 +#if CACHE_LINE_SIZE >= 128
35582 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/miscthings.c um/arch/um/sys-ppc/miscthings.c
35583 --- orig/arch/um/sys-ppc/miscthings.c 1969-12-31 19:00:00.000000000 -0500
35584 +++ um/arch/um/sys-ppc/miscthings.c 2002-10-23 21:08:04.000000000 -0400
35586 +#include "linux/threads.h"
35587 +#include "linux/stddef.h" // for NULL
35588 +#include "linux/elf.h" // for AT_NULL
35590 +/* The following function nicked from arch/ppc/kernel/process.c and
35591 + * adapted slightly */
35593 + * XXX ld.so expects the auxiliary table to start on
35594 + * a 16-byte boundary, so we have to find it and
35595 + * move it up. :-(
35597 +void shove_aux_table(unsigned long sp)
35602 + unsigned long aux_start, offset;
35604 + argc = *(int *)sp;
35605 + sp += sizeof(int) + (argc + 1) * sizeof(char *);
35606 + /* skip over the environment pointers */
35608 + p = *(char **)sp;
35609 + sp += sizeof(char *);
35610 + } while (p != NULL);
35612 + /* skip to the end of the auxiliary table */
35614 + e = *(unsigned long *)sp;
35615 + sp += 2 * sizeof(unsigned long);
35616 + } while (e != AT_NULL);
35617 + offset = ((aux_start + 15) & ~15) - aux_start;
35618 + if (offset != 0) {
35620 + sp -= sizeof(unsigned long);
35621 + e = *(unsigned long *)sp;
35622 + *(unsigned long *)(sp + offset) = e;
35623 + } while (sp > aux_start);
35626 +/* END stuff taken from arch/ppc/kernel/process.c */
35630 + * Overrides for Emacs so that we follow Linus's tabbing style.
35631 + * Emacs will notice this stuff at the end of the file and automatically
35632 + * adjust the settings for this buffer only. This must remain at the end
35634 + * ---------------------------------------------------------------------------
35635 + * Local variables:
35636 + * c-file-style: "linux"
35639 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace.c um/arch/um/sys-ppc/ptrace.c
35640 --- orig/arch/um/sys-ppc/ptrace.c 1969-12-31 19:00:00.000000000 -0500
35641 +++ um/arch/um/sys-ppc/ptrace.c 2002-10-23 21:08:04.000000000 -0400
35643 +#include "linux/sched.h"
35644 +#include "asm/ptrace.h"
35646 +int putreg(struct task_struct *child, unsigned long regno,
35647 + unsigned long value)
35649 + child->thread.process_regs.regs[regno >> 2] = value;
35653 +unsigned long getreg(struct task_struct *child, unsigned long regno)
35655 + unsigned long retval = ~0UL;
35657 + retval &= child->thread.process_regs.regs[regno >> 2];
35662 + * Overrides for Emacs so that we follow Linus's tabbing style.
35663 + * Emacs will notice this stuff at the end of the file and automatically
35664 + * adjust the settings for this buffer only. This must remain at the end
35666 + * ---------------------------------------------------------------------------
35667 + * Local variables:
35668 + * c-file-style: "linux"
35671 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace_user.c um/arch/um/sys-ppc/ptrace_user.c
35672 --- orig/arch/um/sys-ppc/ptrace_user.c 1969-12-31 19:00:00.000000000 -0500
35673 +++ um/arch/um/sys-ppc/ptrace_user.c 2002-10-23 21:08:04.000000000 -0400
35675 +#include <sys/ptrace.h>
35676 +#include <errno.h>
35677 +#include <asm/ptrace.h>
35678 +#include "sysdep/ptrace.h"
35680 +int ptrace_getregs(long pid, unsigned long *regs_out)
35683 + for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
35685 + regs_out->regs[i] = ptrace(PTRACE_PEEKUSER, pid, i*4, 0);
35693 +int ptrace_setregs(long pid, unsigned long *regs_in)
35696 + for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
35697 + if (i != 34 /* FIXME: PT_ORIG_R3 */ && i <= PT_MQ) {
35698 + if (ptrace(PTRACE_POKEUSER, pid, i*4, regs_in->regs[i]) < 0) {
35706 + * Overrides for Emacs so that we follow Linus's tabbing style.
35707 + * Emacs will notice this stuff at the end of the file and automatically
35708 + * adjust the settings for this buffer only. This must remain at the end
35710 + * ---------------------------------------------------------------------------
35711 + * Local variables:
35712 + * c-file-style: "linux"
35715 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sigcontext.c um/arch/um/sys-ppc/sigcontext.c
35716 --- orig/arch/um/sys-ppc/sigcontext.c 1969-12-31 19:00:00.000000000 -0500
35717 +++ um/arch/um/sys-ppc/sigcontext.c 2002-10-23 21:08:04.000000000 -0400
35719 +#include "asm/ptrace.h"
35720 +#include "asm/sigcontext.h"
35721 +#include "sysdep/ptrace.h"
35722 +#include "user_util.h"
35725 + * Overrides for Emacs so that we follow Linus's tabbing style.
35726 + * Emacs will notice this stuff at the end of the file and automatically
35727 + * adjust the settings for this buffer only. This must remain at the end
35729 + * ---------------------------------------------------------------------------
35730 + * Local variables:
35731 + * c-file-style: "linux"
35734 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sysrq.c um/arch/um/sys-ppc/sysrq.c
35735 --- orig/arch/um/sys-ppc/sysrq.c 1969-12-31 19:00:00.000000000 -0500
35736 +++ um/arch/um/sys-ppc/sysrq.c 2002-10-23 21:08:04.000000000 -0400
35739 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
35740 + * Licensed under the GPL
35743 +#include "linux/kernel.h"
35744 +#include "linux/smp.h"
35745 +#include "asm/ptrace.h"
35746 +#include "sysrq.h"
35748 +void show_regs(struct pt_regs_subarch *regs)
35751 + printk("show_regs(): insert regs here.\n");
35754 + printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs, regs->eip,
35755 + smp_processor_id());
35756 + if (regs->xcs & 3)
35757 + printk(" ESP: %04x:%08lx",0xffff & regs->xss, regs->esp);
35758 + printk(" EFLAGS: %08lx\n", regs->eflags);
35759 + printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
35760 + regs->eax, regs->ebx, regs->ecx, regs->edx);
35761 + printk("ESI: %08lx EDI: %08lx EBP: %08lx",
35762 + regs->esi, regs->edi, regs->ebp);
35763 + printk(" DS: %04x ES: %04x\n",
35764 + 0xffff & regs->xds, 0xffff & regs->xes);
35767 + show_trace(®s->gpr[1]);
35772 + * Overrides for Emacs so that we follow Linus's tabbing style.
35773 + * Emacs will notice this stuff at the end of the file and automatically
35774 + * adjust the settings for this buffer only. This must remain at the end
35776 + * ---------------------------------------------------------------------------
35777 + * Local variables:
35778 + * c-file-style: "linux"
35781 diff -Naur -X ../exclude-files orig/arch/um/util/Makefile um/arch/um/util/Makefile
35782 --- orig/arch/um/util/Makefile 1969-12-31 19:00:00.000000000 -0500
35783 +++ um/arch/um/util/Makefile 2002-10-23 21:09:14.000000000 -0400
35785 +ALL = mk_task mk_constants
35789 +mk_task : mk_task_user.o mk_task_kern.o
35790 + $(CC) -o mk_task mk_task_user.o mk_task_kern.o
35792 +mk_task_user.o : mk_task_user.c
35795 +mk_task_kern.o : mk_task_kern.c
35796 + $(CC) $(CFLAGS) -c $<
35798 +mk_constants : mk_constants_user.o mk_constants_kern.o
35799 + $(CC) -o mk_constants mk_constants_user.o mk_constants_kern.o
35801 +mk_constants_user.o : mk_constants_user.c
35804 +mk_constants_kern.o : mk_constants_kern.c
35805 + $(CC) $(CFLAGS) -c $<
35808 + $(RM) $(ALL) *.o *~
35810 +archmrproper : clean
35811 diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_kern.c um/arch/um/util/mk_constants_kern.c
35812 --- orig/arch/um/util/mk_constants_kern.c 1969-12-31 19:00:00.000000000 -0500
35813 +++ um/arch/um/util/mk_constants_kern.c 2002-10-23 21:08:04.000000000 -0400
35815 +#include "linux/kernel.h"
35816 +#include "linux/stringify.h"
35817 +#include "asm/page.h"
35819 +extern void print_head(void);
35820 +extern void print_constant_str(char *name, char *value);
35821 +extern void print_constant_int(char *name, int value);
35822 +extern void print_tail(void);
35824 +int main(int argc, char **argv)
35827 + print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
35828 + print_constant_str("UM_KERN_EMERG", KERN_EMERG);
35829 + print_constant_str("UM_KERN_ALERT", KERN_ALERT);
35830 + print_constant_str("UM_KERN_CRIT", KERN_CRIT);
35831 + print_constant_str("UM_KERN_ERR", KERN_ERR);
35832 + print_constant_str("UM_KERN_WARNING", KERN_WARNING);
35833 + print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
35834 + print_constant_str("UM_KERN_INFO", KERN_INFO);
35835 + print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
35839 diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_user.c um/arch/um/util/mk_constants_user.c
35840 --- orig/arch/um/util/mk_constants_user.c 1969-12-31 19:00:00.000000000 -0500
35841 +++ um/arch/um/util/mk_constants_user.c 2002-10-23 21:08:04.000000000 -0400
35843 +#include <stdio.h>
35845 +void print_head(void)
35848 + printf(" * Generated by mk_constants\n");
35851 + printf("#ifndef __UM_CONSTANTS_H\n");
35852 + printf("#define __UM_CONSTANTS_H\n");
35856 +void print_constant_str(char *name, char *value)
35858 + printf("#define %s \"%s\"\n", name, value);
35861 +void print_constant_int(char *name, int value)
35863 + printf("#define %s %d\n", name, value);
35866 +void print_tail(void)
35869 + printf("#endif\n");
35871 diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_kern.c um/arch/um/util/mk_task_kern.c
35872 --- orig/arch/um/util/mk_task_kern.c 1969-12-31 19:00:00.000000000 -0500
35873 +++ um/arch/um/util/mk_task_kern.c 2002-12-08 21:03:34.000000000 -0500
35875 +#include "linux/sched.h"
35876 +#include "linux/stddef.h"
35878 +extern void print(char *name, char *type, int offset);
35879 +extern void print_ptr(char *name, char *type, int offset);
35880 +extern void print_head(void);
35881 +extern void print_tail(void);
35883 +int main(int argc, char **argv)
35886 + print_ptr("TASK_REGS", "union uml_pt_regs",
35887 + offsetof(struct task_struct, thread.regs));
35888 + print("TASK_PID", "int", offsetof(struct task_struct, pid));
35892 diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_user.c um/arch/um/util/mk_task_user.c
35893 --- orig/arch/um/util/mk_task_user.c 1969-12-31 19:00:00.000000000 -0500
35894 +++ um/arch/um/util/mk_task_user.c 2002-10-23 21:08:04.000000000 -0400
35896 +#include <stdio.h>
35898 +void print(char *name, char *type, int offset)
35900 + printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
35904 +void print_ptr(char *name, char *type, int offset)
35906 + printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
35910 +void print_head(void)
35913 + printf(" * Generated by mk_task\n");
35916 + printf("#ifndef __TASK_H\n");
35917 + printf("#define __TASK_H\n");
35921 +void print_tail(void)
35924 + printf("#endif\n");
35926 diff -Naur -X ../exclude-files orig/CREDITS um/CREDITS
35927 --- orig/CREDITS 2003-02-27 13:04:11.000000000 -0500
35928 +++ um/CREDITS 2003-02-27 13:05:17.000000000 -0500
35929 @@ -432,6 +432,7 @@
35931 W: http://lars.nocrew.org/
35932 D: dsp56k device driver
35933 +D: ptrace proxy in user mode kernel port
35937 @@ -721,7 +722,7 @@
35938 E: jdike@karaya.com
35939 W: http://user-mode-linux.sourceforge.net
35940 D: User mode kernel port
35942 +S: 375 Tubbs Hill Rd
35943 S: Deering NH 03244
35946 diff -Naur -X ../exclude-files orig/Documentation/Configure.help um/Documentation/Configure.help
35947 --- orig/Documentation/Configure.help 2003-02-27 13:04:11.000000000 -0500
35948 +++ um/Documentation/Configure.help 2003-02-27 13:05:17.000000000 -0500
35949 @@ -14690,19 +14690,23 @@
35950 The module will be called dsbr100.o. If you want to compile it as a
35951 module, say M here and read <file:Documentation/modules.txt>.
35953 -Always do synchronous disk IO for UBD
35954 -CONFIG_BLK_DEV_UBD_SYNC
35955 +CONFIG_BLK_DEV_UBD
35956 The User-Mode Linux port includes a driver called UBD which will let
35957 you access arbitrary files on the host computer as block devices.
35958 - Writes to such a block device are not immediately written to the
35959 - host's disk; this may cause problems if, for example, the User-Mode
35960 - Linux 'Virtual Machine' uses a journalling file system and the host
35961 - computer crashes.
35962 + Unless you know that you do not need such virtual block devices say
35965 +Always do synchronous disk IO for UBD
35966 +CONFIG_BLK_DEV_UBD_SYNC
35967 + Writes to the virtual block device are not immediately written to the host's
35968 + disk; this may cause problems if, for example, the User-Mode Linux
35969 + 'Virtual Machine' uses a journalling filesystem and the host computer
35972 Synchronous operation (i.e. always writing data to the host's disk
35973 immediately) is configurable on a per-UBD basis by using a special
35974 kernel command line option. Alternatively, you can say Y here to
35975 - turn on synchronous operation by default for all block.
35976 + turn on synchronous operation by default for all block devices.
35978 If you're running a journalling file system (like reiserfs, for
35979 example) in your virtual machine, you will want to say Y here. If
35980 @@ -14714,6 +14718,7 @@
35982 This option enables a debugging interface which allows gdb to debug
35983 the kernel without needing to actually attach to kernel threads.
35984 + CONFIG_XTERM_CHAN must be enabled in order to enable CONFIG_PT_PROXY.
35985 If you want to do kernel debugging, say Y here; otherwise say N.
35988 @@ -14908,26 +14913,174 @@
35991 CONFIG_UML_NET_SLIP
35992 - The Slip User-Mode Linux network transport allows a running UML to
35993 + The slip User-Mode Linux network transport allows a running UML to
35994 network with its host over a point-to-point link. Unlike Ethertap,
35995 which can carry any Ethernet frame (and hence even non-IP packets),
35996 - the Slip transport can only carry IP packets.
35997 + the slip transport can only carry IP packets.
35999 - To use this, your host must support Slip devices.
36000 + To use this, your host must support slip devices.
36002 For more information, see
36003 <http://user-mode-linux.sourceforge.net/networking.html>. That site
36004 - has examples of the UML command line to use to enable Slip
36005 + has examples of the UML command line to use to enable slip
36006 networking, and details of a few quirks with it.
36008 - The Ethertap Transport is preferred over Slip because of its
36009 - limitation. If you prefer Slip, however, say Y here. Otherwise
36010 + The Ethertap Transport is preferred over slip because of its
36011 + limitations. If you prefer slip, however, say Y here. Otherwise
36012 choose the Multicast transport (to network multiple UMLs on
36013 multiple hosts), Ethertap (to network with the host and the
36014 outside world), and/or the Daemon transport (to network multiple
36015 UMLs on a single host). You may choose more than one without
36016 conflict. If you don't need UML networking, say N.
36019 +CONFIG_UML_NET_SLIRP
36020 + The SLiRP User-Mode Linux network transport allows a running UML
36021 + to network by invoking a program that can handle SLIP encapsulated
36022 + packets. This is commonly (but not limited to) the application
36023 + known as SLiRP, a program that can re-socket IP packets back onto
36024 + the host on which it is run. Only IP packets are supported,
36025 + unlike other network transports that can handle all Ethernet
36026 + frames. In general, slirp allows the UML the same IP connectivity
36027 + to the outside world that the host user is permitted, and unlike
36028 + other transports, SLiRP works without the need of root level
36029 + privleges, setuid binaries, or SLIP devices on the host. This
36030 + also means not every type of connection is possible, but most
36031 + situations can be accomodated with carefully crafted slirp
36032 + commands that can be passed along as part of the network device's
36033 + setup string. The effect of this transport on the UML is similar
36034 + that of a host behind a firewall that masquerades all network
36035 + connections passing through it (but is less secure).
36037 + To use this you should first have slirp compiled somewhere
36038 + accessible on the host, and have read its documentation. If you
36039 + don't need UML networking, say N.
36041 + Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
36043 +Default main console channel initialization
36044 +CONFIG_CON_ZERO_CHAN
36045 + This is the string describing the channel to which the main console
36046 + will be attached by default. This value can be overridden from the
36047 + command line. The default value is "fd:0,fd:1", which attaches the
36048 + main console to stdin and stdout.
36049 + It is safe to leave this unchanged.
36051 +Default console channel initialization
36053 + This is the string describing the channel to which all consoles
36054 + except the main console will be attached by default. This value can
36055 + be overridden from the command line. The default value is "xterm",
36056 + which brings them up in xterms.
36057 + It is safe to leave this unchanged, although you may wish to change
36058 + this if you expect the UML that you build to be run in environments
36059 + which don't have X or xterm available.
36061 +Default serial line channel initialization
36063 + This is the string describing the channel to which the serial lines
36064 + will be attached by default. This value can be overridden from the
36065 + command line. The default value is "pty", which attaches them to
36066 + traditional pseudo-terminals.
36067 + It is safe to leave this unchanged, although you may wish to change
36068 + this if you expect the UML that you build to be run in environments
36069 + which don't have a set of /dev/pty* devices.
36073 + This is set to the number of layers of UMLs that this UML will be run
36074 + in. Normally, this is zero, meaning that it will run directly on the
36075 + host. Setting it to one will build a UML that can run inside a UML
36076 + that is running on the host. Generally, if you intend this UML to run
36077 + inside another UML, set CONFIG_NEST_LEVEL to one more than the host UML.
36078 + Note that if the hosting UML has its CONFIG_KERNEL_HALF_GIGS set to
36079 + greater than one, then the guest UML should have its CONFIG_NEST_LEVEL
36080 + set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
36081 + Only change this if you are running nested UMLs.
36083 +Kernel address space size (in .5G units)
36084 +CONFIG_KERNEL_HALF_GIGS
36085 + This determines the amount of address space that UML will allocate for
36086 + its own, measured in half Gigabyte units. The default is 1.
36087 + Change this only if you need to boot UML with an unusually large amount
36088 + of physical memory.
36092 + This option enables UML sound support. If enabled, it will pull in
36093 + soundcore and the UML hostaudio relay, which acts as a intermediary
36094 + between the host's dsp and mixer devices and the UML sound system.
36095 + It is safe to say 'Y' here.
36099 + This option enables UML SMP support. UML implements virtual SMP by
36100 + allowing as many processes to run simultaneously on the host as
36101 + there are virtual processors configured. Obviously, if the host is
36102 + a uniprocessor, those processes will timeshare, but, inside UML,
36103 + will appear to be running simultaneously. If the host is a
36104 + multiprocessor, then UML processes may run simultaneously, depending
36105 + on the host scheduler.
36106 + CONFIG_SMP will be set to whatever this option is set to.
36107 + It is safe to leave this unchanged.
36109 +file descriptor channel support
36111 + This option enables support for attaching UML consoles and serial
36112 + lines to already set up file descriptors. Generally, the main
36113 + console is attached to file descriptors 0 and 1 (stdin and stdout),
36114 + so it would be wise to leave this enabled unless you intend to
36115 + attach it to some other host device.
36117 +null device channel support
36119 + This option enables support for attaching UML consoles and serial
36120 + lines to a device similar to /dev/null. Data written to it disappears
36121 + and there is never any data to be read.
36123 +port channel support
36125 + This option enables support for attaching UML consoles and serial
36126 + lines to host portals. They may be accessed with 'telnet <host>
36127 + <port number>'. Any number of consoles and serial lines may be
36128 + attached to a single portal, although what UML device you get when
36129 + you telnet to that portal will be unpredictable.
36130 + It is safe to say 'Y' here.
36132 +pty channel support
36134 + This option enables support for attaching UML consoles and serial
36135 + lines to host pseudo-terminals. Access to both traditional
36136 + pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled
36137 + with this option. The assignment of UML devices to host devices
36138 + will be announced in the kernel message log.
36139 + It is safe to say 'Y' here.
36141 +tty channel support
36143 + This option enables support for attaching UML consoles and serial
36144 + lines to host terminals. Access to both virtual consoles
36145 + (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and
36146 + /dev/pts/*) are controlled by this option.
36147 + It is safe to say 'Y' here.
36149 +xterm channel support
36151 + This option enables support for attaching UML consoles and serial
36152 + lines to xterms. Each UML device so assigned will be brought up in
36154 + If you disable this option, then CONFIG_PT_PROXY will be disabled as
36155 + well, since UML's gdb currently requires an xterm.
36156 + It is safe to say 'Y' here.
36160 + This option enables logging of all data going through pseudo-terminals
36161 + to the host. This is primarily useful for honeypots, where you want
36162 + secure keystroke logging that can't be detected or disabled by root.
36163 + Say 'N' unless you are setting up a UML honeypot or otherwise know that
36164 + you want this option.
36166 Microtek USB scanner support
36167 CONFIG_USB_MICROTEK
36168 Say Y here if you want support for the Microtek X6USB and
36169 diff -Naur -X ../exclude-files orig/drivers/char/Makefile um/drivers/char/Makefile
36170 --- orig/drivers/char/Makefile 2003-02-27 13:04:15.000000000 -0500
36171 +++ um/drivers/char/Makefile 2003-02-27 13:05:21.000000000 -0500
36185 diff -Naur -X ../exclude-files orig/drivers/char/tty_io.c um/drivers/char/tty_io.c
36186 --- orig/drivers/char/tty_io.c 2003-02-27 13:04:15.000000000 -0500
36187 +++ um/drivers/char/tty_io.c 2003-02-27 13:05:21.000000000 -0500
36188 @@ -637,6 +637,9 @@
36189 wake_up_interruptible(&tty->write_wait);
36192 +extern int write_tty_log(int fd, const unsigned char *buf, int len, void *tty,
36195 static ssize_t tty_read(struct file * file, char * buf, size_t count,
36198 @@ -677,8 +680,13 @@
36204 inode->i_atime = CURRENT_TIME;
36205 +#ifdef CONFIG_TTY_LOG
36206 + if(tty->log_fd >= 0)
36207 + write_tty_log(tty->log_fd, buf, i, tty, 1);
36213 @@ -732,6 +740,10 @@
36215 file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
36217 +#ifdef CONFIG_TTY_LOG
36218 + if(tty->log_fd >= 0)
36219 + write_tty_log(tty->log_fd, buf - ret, ret, tty, 0);
36222 up(&tty->atomic_write);
36224 @@ -945,6 +957,9 @@
36225 goto release_mem_out;
36228 +#ifdef CONFIG_TTY_LOG
36229 + tty->log_fd = -1;
36234 @@ -1039,6 +1054,8 @@
36235 free_tty_struct(tty);
36238 +extern int close_tty_log(int fd, void *tty);
36241 * Even releasing the tty structures is a tricky business.. We have
36242 * to be very careful that the structures are all released at the
36243 @@ -1267,6 +1284,10 @@
36244 run_task_queue(&tq_timer);
36245 flush_scheduled_tasks();
36247 +#ifdef CONFIG_TTY_LOG
36248 + if(tty->log_fd >= 0) close_tty_log(tty->log_fd, tty);
36252 * The release_mem function takes care of the details of clearing
36253 * the slots and preserving the termios structure.
36254 @@ -1274,6 +1295,8 @@
36255 release_mem(tty, idx);
36258 +extern int open_tty_log(void *tty, void *current_tty);
36261 * tty_open and tty_release keep up the tty count that contains the
36262 * number of opens done on a tty. We cannot use the inode-count, as
36263 @@ -1425,6 +1448,11 @@
36268 +#ifdef CONFIG_TTY_LOG
36269 + if(tty->log_fd < 0)
36270 + tty->log_fd = open_tty_log(tty, current->tty);
36275 diff -Naur -X ../exclude-files orig/drivers/net/setup.c um/drivers/net/setup.c
36276 --- orig/drivers/net/setup.c 2002-09-15 12:13:19.000000000 -0400
36277 +++ um/drivers/net/setup.c 2002-10-23 21:08:05.000000000 -0400
36279 extern int lmc_setup(void);
36281 extern int madgemc_probe(void);
36282 -extern int uml_net_probe(void);
36284 /* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is string of 9 zeros. */
36285 #define __PAD6 "\0\0\0\0\0\0\0\0\0"
36286 @@ -103,9 +102,6 @@
36287 #ifdef CONFIG_MADGEMC
36288 {madgemc_probe, 0},
36290 -#ifdef CONFIG_UML_NET
36291 - {uml_net_probe, 0},
36296 diff -Naur -X ../exclude-files orig/include/asm-i386/hardirq.h um/include/asm-i386/hardirq.h
36297 --- orig/include/asm-i386/hardirq.h 2002-09-15 12:13:19.000000000 -0400
36298 +++ um/include/asm-i386/hardirq.h 2003-05-28 11:02:07.000000000 -0400
36300 #include <linux/config.h>
36301 #include <linux/threads.h>
36302 #include <linux/irq.h>
36303 +#include <asm/processor.h> /* for cpu_relax */
36305 /* assembly code in softirq.h is sensitive to the offsets of these fields */
36307 diff -Naur -X ../exclude-files orig/include/asm-um/a.out.h um/include/asm-um/a.out.h
36308 --- orig/include/asm-um/a.out.h 1969-12-31 19:00:00.000000000 -0500
36309 +++ um/include/asm-um/a.out.h 2002-10-27 11:54:50.000000000 -0500
36311 +#ifndef __UM_A_OUT_H
36312 +#define __UM_A_OUT_H
36314 +#include "linux/config.h"
36315 +#include "asm/arch/a.out.h"
36316 +#include "choose-mode.h"
36320 +extern unsigned long stacksizelim;
36322 +extern unsigned long host_task_size;
36324 +#define STACK_ROOM (stacksizelim)
36326 +extern int honeypot;
36327 +#define STACK_TOP \
36328 + CHOOSE_MODE((honeypot ? host_task_size : task_size), task_size)
36331 diff -Naur -X ../exclude-files orig/include/asm-um/archparam-i386.h um/include/asm-um/archparam-i386.h
36332 --- orig/include/asm-um/archparam-i386.h 1969-12-31 19:00:00.000000000 -0500
36333 +++ um/include/asm-um/archparam-i386.h 2002-12-08 20:09:11.000000000 -0500
36336 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
36337 + * Licensed under the GPL
36340 +#ifndef __UM_ARCHPARAM_I386_H
36341 +#define __UM_ARCHPARAM_I386_H
36343 +/********* Bits for asm-um/elf.h ************/
36347 +#define ELF_PLATFORM "i586"
36349 +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
36351 +typedef struct user_i387_struct elf_fpregset_t;
36352 +typedef unsigned long elf_greg_t;
36354 +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
36355 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
36357 +#define ELF_DATA ELFDATA2LSB
36358 +#define ELF_ARCH EM_386
36360 +#define ELF_PLAT_INIT(regs) do { \
36361 + PT_REGS_EBX(regs) = 0; \
36362 + PT_REGS_ECX(regs) = 0; \
36363 + PT_REGS_EDX(regs) = 0; \
36364 + PT_REGS_ESI(regs) = 0; \
36365 + PT_REGS_EDI(regs) = 0; \
36366 + PT_REGS_EBP(regs) = 0; \
36367 + PT_REGS_EAX(regs) = 0; \
36370 +/* Shamelessly stolen from include/asm-i386/elf.h */
36372 +#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \
36373 + pr_reg[0] = PT_REGS_EBX(regs); \
36374 + pr_reg[1] = PT_REGS_ECX(regs); \
36375 + pr_reg[2] = PT_REGS_EDX(regs); \
36376 + pr_reg[3] = PT_REGS_ESI(regs); \
36377 + pr_reg[4] = PT_REGS_EDI(regs); \
36378 + pr_reg[5] = PT_REGS_EBP(regs); \
36379 + pr_reg[6] = PT_REGS_EAX(regs); \
36380 + pr_reg[7] = PT_REGS_DS(regs); \
36381 + pr_reg[8] = PT_REGS_ES(regs); \
36382 + /* fake once used fs and gs selectors? */ \
36383 + pr_reg[9] = PT_REGS_DS(regs); \
36384 + pr_reg[10] = PT_REGS_DS(regs); \
36385 + pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \
36386 + pr_reg[12] = PT_REGS_IP(regs); \
36387 + pr_reg[13] = PT_REGS_CS(regs); \
36388 + pr_reg[14] = PT_REGS_EFLAGS(regs); \
36389 + pr_reg[15] = PT_REGS_SP(regs); \
36390 + pr_reg[16] = PT_REGS_SS(regs); \
36393 +/********* Bits for asm-um/delay.h **********/
36395 +typedef unsigned long um_udelay_t;
36397 +/********* Nothing for asm-um/hardirq.h **********/
36399 +/********* Nothing for asm-um/hw_irq.h **********/
36401 +/********* Nothing for asm-um/string.h **********/
36406 + * Overrides for Emacs so that we follow Linus's tabbing style.
36407 + * Emacs will notice this stuff at the end of the file and automatically
36408 + * adjust the settings for this buffer only. This must remain at the end
36410 + * ---------------------------------------------------------------------------
36411 + * Local variables:
36412 + * c-file-style: "linux"
36415 diff -Naur -X ../exclude-files orig/include/asm-um/archparam-ppc.h um/include/asm-um/archparam-ppc.h
36416 --- orig/include/asm-um/archparam-ppc.h 1969-12-31 19:00:00.000000000 -0500
36417 +++ um/include/asm-um/archparam-ppc.h 2002-10-23 21:08:05.000000000 -0400
36419 +#ifndef __UM_ARCHPARAM_PPC_H
36420 +#define __UM_ARCHPARAM_PPC_H
36422 +/********* Bits for asm-um/elf.h ************/
36424 +#define ELF_PLATFORM (0)
36426 +#define ELF_ET_DYN_BASE (0x08000000)
36428 +/* the following stolen from asm-ppc/elf.h */
36429 +#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
36430 +#define ELF_NFPREG 33 /* includes fpscr */
36431 +/* General registers */
36432 +typedef unsigned long elf_greg_t;
36433 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
36435 +/* Floating point registers */
36436 +typedef double elf_fpreg_t;
36437 +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
36439 +#define ELF_DATA ELFDATA2MSB
36440 +#define ELF_ARCH EM_PPC
36442 +/********* Bits for asm-um/delay.h **********/
36444 +typedef unsigned int um_udelay_t;
36446 +/********* Bits for asm-um/hw_irq.h **********/
36448 +struct hw_interrupt_type;
36450 +/********* Bits for asm-um/hardirq.h **********/
36452 +#define irq_enter(cpu, irq) hardirq_enter(cpu)
36453 +#define irq_exit(cpu, irq) hardirq_exit(cpu)
36455 +/********* Bits for asm-um/string.h **********/
36457 +#define __HAVE_ARCH_STRRCHR
36460 diff -Naur -X ../exclude-files orig/include/asm-um/arch-signal-i386.h um/include/asm-um/arch-signal-i386.h
36461 --- orig/include/asm-um/arch-signal-i386.h 1969-12-31 19:00:00.000000000 -0500
36462 +++ um/include/asm-um/arch-signal-i386.h 2002-10-23 21:08:05.000000000 -0400
36465 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36466 + * Licensed under the GPL
36469 +#ifndef __UM_ARCH_SIGNAL_I386_H
36470 +#define __UM_ARCH_SIGNAL_I386_H
36472 +struct arch_signal_context {
36473 + unsigned long extrasigs[_NSIG_WORDS];
36479 + * Overrides for Emacs so that we follow Linus's tabbing style.
36480 + * Emacs will notice this stuff at the end of the file and automatically
36481 + * adjust the settings for this buffer only. This must remain at the end
36483 + * ---------------------------------------------------------------------------
36484 + * Local variables:
36485 + * c-file-style: "linux"
36488 diff -Naur -X ../exclude-files orig/include/asm-um/atomic.h um/include/asm-um/atomic.h
36489 --- orig/include/asm-um/atomic.h 1969-12-31 19:00:00.000000000 -0500
36490 +++ um/include/asm-um/atomic.h 2003-05-28 11:02:07.000000000 -0400
36492 +#ifndef __UM_ATOMIC_H
36493 +#define __UM_ATOMIC_H
36495 +#include "asm/arch/atomic.h"
36498 diff -Naur -X ../exclude-files orig/include/asm-um/bitops.h um/include/asm-um/bitops.h
36499 --- orig/include/asm-um/bitops.h 1969-12-31 19:00:00.000000000 -0500
36500 +++ um/include/asm-um/bitops.h 2003-05-28 11:02:07.000000000 -0400
36502 +#ifndef __UM_BITOPS_H
36503 +#define __UM_BITOPS_H
36505 +#include "asm/arch/bitops.h"
36508 diff -Naur -X ../exclude-files orig/include/asm-um/boot.h um/include/asm-um/boot.h
36509 --- orig/include/asm-um/boot.h 1969-12-31 19:00:00.000000000 -0500
36510 +++ um/include/asm-um/boot.h 2002-10-23 21:08:05.000000000 -0400
36512 +#ifndef __UM_BOOT_H
36513 +#define __UM_BOOT_H
36515 +#include "asm/arch/boot.h"
36518 diff -Naur -X ../exclude-files orig/include/asm-um/bugs.h um/include/asm-um/bugs.h
36519 --- orig/include/asm-um/bugs.h 1969-12-31 19:00:00.000000000 -0500
36520 +++ um/include/asm-um/bugs.h 2002-10-23 21:08:05.000000000 -0400
36522 +#ifndef __UM_BUGS_H
36523 +#define __UM_BUGS_H
36525 +void check_bugs(void);
36528 diff -Naur -X ../exclude-files orig/include/asm-um/byteorder.h um/include/asm-um/byteorder.h
36529 --- orig/include/asm-um/byteorder.h 1969-12-31 19:00:00.000000000 -0500
36530 +++ um/include/asm-um/byteorder.h 2003-02-27 13:20:12.000000000 -0500
36532 +#ifndef __UM_BYTEORDER_H
36533 +#define __UM_BYTEORDER_H
36535 +#include "asm/arch/byteorder.h"
36538 diff -Naur -X ../exclude-files orig/include/asm-um/cache.h um/include/asm-um/cache.h
36539 --- orig/include/asm-um/cache.h 1969-12-31 19:00:00.000000000 -0500
36540 +++ um/include/asm-um/cache.h 2002-10-23 21:08:05.000000000 -0400
36542 +#ifndef __UM_CACHE_H
36543 +#define __UM_CACHE_H
36545 +#define L1_CACHE_BYTES 32
36548 diff -Naur -X ../exclude-files orig/include/asm-um/checksum.h um/include/asm-um/checksum.h
36549 --- orig/include/asm-um/checksum.h 1969-12-31 19:00:00.000000000 -0500
36550 +++ um/include/asm-um/checksum.h 2002-10-29 17:25:12.000000000 -0500
36552 +#ifndef __UM_CHECKSUM_H
36553 +#define __UM_CHECKSUM_H
36555 +#include "sysdep/checksum.h"
36558 diff -Naur -X ../exclude-files orig/include/asm-um/cobalt.h um/include/asm-um/cobalt.h
36559 --- orig/include/asm-um/cobalt.h 1969-12-31 19:00:00.000000000 -0500
36560 +++ um/include/asm-um/cobalt.h 2002-10-23 21:08:05.000000000 -0400
36562 +#ifndef __UM_COBALT_H
36563 +#define __UM_COBALT_H
36565 +#include "asm/arch/cobalt.h"
36568 diff -Naur -X ../exclude-files orig/include/asm-um/current.h um/include/asm-um/current.h
36569 --- orig/include/asm-um/current.h 1969-12-31 19:00:00.000000000 -0500
36570 +++ um/include/asm-um/current.h 2003-05-28 11:02:07.000000000 -0400
36573 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
36574 + * Licensed under the GPL
36577 +#ifndef __UM_CURRENT_H
36578 +#define __UM_CURRENT_H
36580 +#ifndef __ASSEMBLY__
36582 +#include "linux/config.h"
36583 +#include "asm/page.h"
36585 +struct task_struct;
36587 +#define CURRENT_TASK(dummy) (((unsigned long) &dummy) & \
36588 + (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
36590 +#define current ({ int dummy; (struct task_struct *) CURRENT_TASK(dummy); })
36592 +#endif /* __ASSEMBLY__ */
36597 + * Overrides for Emacs so that we follow Linus's tabbing style.
36598 + * Emacs will notice this stuff at the end of the file and automatically
36599 + * adjust the settings for this buffer only. This must remain at the end
36601 + * ---------------------------------------------------------------------------
36602 + * Local variables:
36603 + * c-file-style: "linux"
36606 diff -Naur -X ../exclude-files orig/include/asm-um/delay.h um/include/asm-um/delay.h
36607 --- orig/include/asm-um/delay.h 1969-12-31 19:00:00.000000000 -0500
36608 +++ um/include/asm-um/delay.h 2002-12-08 20:09:15.000000000 -0500
36610 +#ifndef __UM_DELAY_H
36611 +#define __UM_DELAY_H
36613 +#include "asm/arch/delay.h"
36614 +#include "asm/archparam.h"
36617 diff -Naur -X ../exclude-files orig/include/asm-um/desc.h um/include/asm-um/desc.h
36618 --- orig/include/asm-um/desc.h 1969-12-31 19:00:00.000000000 -0500
36619 +++ um/include/asm-um/desc.h 2002-10-23 21:08:05.000000000 -0400
36621 +#ifndef __UM_DESC_H
36622 +#define __UM_DESC_H
36624 +#include "asm/arch/desc.h"
36627 diff -Naur -X ../exclude-files orig/include/asm-um/div64.h um/include/asm-um/div64.h
36628 --- orig/include/asm-um/div64.h 1969-12-31 19:00:00.000000000 -0500
36629 +++ um/include/asm-um/div64.h 2002-10-23 21:08:05.000000000 -0400
36631 +#ifndef _UM_DIV64_H
36632 +#define _UM_DIV64_H
36634 +#include "asm/arch/div64.h"
36637 diff -Naur -X ../exclude-files orig/include/asm-um/dma.h um/include/asm-um/dma.h
36638 --- orig/include/asm-um/dma.h 1969-12-31 19:00:00.000000000 -0500
36639 +++ um/include/asm-um/dma.h 2002-10-27 16:53:42.000000000 -0500
36641 +#ifndef __UM_DMA_H
36642 +#define __UM_DMA_H
36644 +#include "asm/io.h"
36646 +extern unsigned long uml_physmem;
36648 +#define MAX_DMA_ADDRESS (uml_physmem)
36651 diff -Naur -X ../exclude-files orig/include/asm-um/elf.h um/include/asm-um/elf.h
36652 --- orig/include/asm-um/elf.h 1969-12-31 19:00:00.000000000 -0500
36653 +++ um/include/asm-um/elf.h 2002-12-08 20:13:07.000000000 -0500
36655 +#ifndef __UM_ELF_H
36656 +#define __UM_ELF_H
36658 +#include "asm/archparam.h"
36660 +#define ELF_HWCAP (0)
36662 +#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
36664 +#define ELF_EXEC_PAGESIZE 4096
36666 +#define elf_check_arch(x) (1)
36668 +#define ELF_CLASS ELFCLASS32
36670 +#define USE_ELF_CORE_DUMP
36673 diff -Naur -X ../exclude-files orig/include/asm-um/errno.h um/include/asm-um/errno.h
36674 --- orig/include/asm-um/errno.h 1969-12-31 19:00:00.000000000 -0500
36675 +++ um/include/asm-um/errno.h 2002-10-23 21:08:05.000000000 -0400
36677 +#ifndef __UM_ERRNO_H
36678 +#define __UM_ERRNO_H
36680 +#include "asm/arch/errno.h"
36683 diff -Naur -X ../exclude-files orig/include/asm-um/fcntl.h um/include/asm-um/fcntl.h
36684 --- orig/include/asm-um/fcntl.h 1969-12-31 19:00:00.000000000 -0500
36685 +++ um/include/asm-um/fcntl.h 2002-10-23 21:08:05.000000000 -0400
36687 +#ifndef __UM_FCNTL_H
36688 +#define __UM_FCNTL_H
36690 +#include "asm/arch/fcntl.h"
36693 diff -Naur -X ../exclude-files orig/include/asm-um/fixmap.h um/include/asm-um/fixmap.h
36694 --- orig/include/asm-um/fixmap.h 1969-12-31 19:00:00.000000000 -0500
36695 +++ um/include/asm-um/fixmap.h 2003-05-28 11:02:08.000000000 -0400
36697 +#ifndef __UM_FIXMAP_H
36698 +#define __UM_FIXMAP_H
36700 +#include <linux/config.h>
36701 +#include <asm/kmap_types.h>
36704 + * Here we define all the compile-time 'special' virtual
36705 + * addresses. The point is to have a constant address at
36706 + * compile time, but to set the physical address only
36707 + * in the boot process. We allocate these special addresses
36708 + * from the end of virtual memory (0xfffff000) backwards.
36709 + * Also this lets us do fail-safe vmalloc(), we
36710 + * can guarantee that these special addresses and
36711 + * vmalloc()-ed addresses never overlap.
36713 + * these 'compile-time allocated' memory buffers are
36714 + * fixed-size 4k pages. (or larger if used with an increment
36715 + * highger than 1) use fixmap_set(idx,phys) to associate
36716 + * physical memory with fixmap indices.
36718 + * TLB entries of such buffers will not be flushed across
36723 + * on UP currently we will have no trace of the fixmap mechanizm,
36724 + * no page table allocations, etc. This might change in the
36725 + * future, say framebuffers for the console driver(s) could be
36728 +enum fixed_addresses {
36729 +#ifdef CONFIG_HIGHMEM
36730 + FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
36731 + FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
36733 + __end_of_fixed_addresses
36736 +extern void __set_fixmap (enum fixed_addresses idx,
36737 + unsigned long phys, pgprot_t flags);
36739 +#define set_fixmap(idx, phys) \
36740 + __set_fixmap(idx, phys, PAGE_KERNEL)
36742 + * Some hardware wants to get fixmapped without caching.
36744 +#define set_fixmap_nocache(idx, phys) \
36745 + __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
36747 + * used by vmalloc.c.
36749 + * Leave one empty page between vmalloc'ed areas and
36750 + * the start of the fixmap, and leave one page empty
36751 + * at the top of mem..
36753 +extern unsigned long get_kmem_end(void);
36755 +#define FIXADDR_TOP (get_kmem_end() - 0x2000)
36756 +#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
36757 +#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
36759 +#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
36761 +extern void __this_fixmap_does_not_exist(void);
36764 + * 'index to address' translation. If anyone tries to use the idx
36765 + * directly without tranlation, we catch the bug with a NULL-deference
36766 + * kernel oops. Illegal ranges of incoming indices are caught too.
36768 +static inline unsigned long fix_to_virt(const unsigned int idx)
36771 + * this branch gets completely eliminated after inlining,
36772 + * except when someone tries to use fixaddr indices in an
36773 + * illegal way. (such as mixing up address types or using
36774 + * out-of-range indices).
36776 + * If it doesn't get removed, the linker will complain
36777 + * loudly with a reasonably clear error message..
36779 + if (idx >= __end_of_fixed_addresses)
36780 + __this_fixmap_does_not_exist();
36782 + return __fix_to_virt(idx);
36786 diff -Naur -X ../exclude-files orig/include/asm-um/floppy.h um/include/asm-um/floppy.h
36787 --- orig/include/asm-um/floppy.h 1969-12-31 19:00:00.000000000 -0500
36788 +++ um/include/asm-um/floppy.h 2002-10-23 21:08:05.000000000 -0400
36790 +#ifndef __UM_FLOPPY_H
36791 +#define __UM_FLOPPY_H
36793 +#include "asm/arch/floppy.h"
36796 diff -Naur -X ../exclude-files orig/include/asm-um/hardirq.h um/include/asm-um/hardirq.h
36797 --- orig/include/asm-um/hardirq.h 1969-12-31 19:00:00.000000000 -0500
36798 +++ um/include/asm-um/hardirq.h 2003-05-28 11:02:07.000000000 -0400
36800 +#ifndef __UM_HARDIRQ_H
36801 +#define __UM_HARDIRQ_H
36803 +#include "asm/arch/hardirq.h"
36806 diff -Naur -X ../exclude-files orig/include/asm-um/hdreg.h um/include/asm-um/hdreg.h
36807 --- orig/include/asm-um/hdreg.h 1969-12-31 19:00:00.000000000 -0500
36808 +++ um/include/asm-um/hdreg.h 2002-10-23 21:08:05.000000000 -0400
36810 +#ifndef __UM_HDREG_H
36811 +#define __UM_HDREG_H
36813 +#include "asm/arch/hdreg.h"
36816 diff -Naur -X ../exclude-files orig/include/asm-um/highmem.h um/include/asm-um/highmem.h
36817 --- orig/include/asm-um/highmem.h 1969-12-31 19:00:00.000000000 -0500
36818 +++ um/include/asm-um/highmem.h 2003-05-28 11:02:08.000000000 -0400
36820 +#ifndef __UM_HIGHMEM_H
36821 +#define __UM_HIGHMEM_H
36823 +#include "asm/page.h"
36824 +#include "asm/fixmap.h"
36825 +#include "asm/arch/highmem.h"
36829 +#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK)
36832 diff -Naur -X ../exclude-files orig/include/asm-um/hw_irq.h um/include/asm-um/hw_irq.h
36833 --- orig/include/asm-um/hw_irq.h 1969-12-31 19:00:00.000000000 -0500
36834 +++ um/include/asm-um/hw_irq.h 2003-05-11 18:31:58.000000000 -0400
36836 +#ifndef _ASM_UM_HW_IRQ_H
36837 +#define _ASM_UM_HW_IRQ_H
36839 +#include "asm/irq.h"
36840 +#include "asm/archparam.h"
36842 +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
36846 diff -Naur -X ../exclude-files orig/include/asm-um/ide.h um/include/asm-um/ide.h
36847 --- orig/include/asm-um/ide.h 1969-12-31 19:00:00.000000000 -0500
36848 +++ um/include/asm-um/ide.h 2002-10-23 21:08:05.000000000 -0400
36850 +#ifndef __UM_IDE_H
36851 +#define __UM_IDE_H
36853 +#include "asm/arch/ide.h"
36856 diff -Naur -X ../exclude-files orig/include/asm-um/init.h um/include/asm-um/init.h
36857 --- orig/include/asm-um/init.h 1969-12-31 19:00:00.000000000 -0500
36858 +++ um/include/asm-um/init.h 2002-10-23 21:08:05.000000000 -0400
36860 +#ifndef _UM_INIT_H
36861 +#define _UM_INIT_H
36865 +#define __initdata
36866 +#define __initfunc(__arginit) __arginit
36867 +#define __cacheline_aligned
36871 diff -Naur -X ../exclude-files orig/include/asm-um/ioctl.h um/include/asm-um/ioctl.h
36872 --- orig/include/asm-um/ioctl.h 1969-12-31 19:00:00.000000000 -0500
36873 +++ um/include/asm-um/ioctl.h 2002-10-23 21:08:05.000000000 -0400
36875 +#ifndef __UM_IOCTL_H
36876 +#define __UM_IOCTL_H
36878 +#include "asm/arch/ioctl.h"
36881 diff -Naur -X ../exclude-files orig/include/asm-um/ioctls.h um/include/asm-um/ioctls.h
36882 --- orig/include/asm-um/ioctls.h 1969-12-31 19:00:00.000000000 -0500
36883 +++ um/include/asm-um/ioctls.h 2002-10-23 21:11:14.000000000 -0400
36885 +#ifndef __UM_IOCTLS_H
36886 +#define __UM_IOCTLS_H
36888 +#include "asm/arch/ioctls.h"
36891 diff -Naur -X ../exclude-files orig/include/asm-um/io.h um/include/asm-um/io.h
36892 --- orig/include/asm-um/io.h 1969-12-31 19:00:00.000000000 -0500
36893 +++ um/include/asm-um/io.h 2002-10-27 16:53:42.000000000 -0500
36898 +#include "asm/page.h"
36900 +#define IO_SPACE_LIMIT 0xdeadbeef /* Sure hope nothing uses this */
36902 +static inline int inb(unsigned long i) { return(0); }
36903 +static inline void outb(char c, unsigned long i) { }
36906 + * Change virtual addresses to physical addresses and vv.
36907 + * These are pretty trivial
36909 +static inline unsigned long virt_to_phys(volatile void * address)
36911 + return __pa((void *) address);
36914 +static inline void * phys_to_virt(unsigned long address)
36916 + return __va(address);
36920 diff -Naur -X ../exclude-files orig/include/asm-um/ipcbuf.h um/include/asm-um/ipcbuf.h
36921 --- orig/include/asm-um/ipcbuf.h 1969-12-31 19:00:00.000000000 -0500
36922 +++ um/include/asm-um/ipcbuf.h 2002-10-23 21:08:05.000000000 -0400
36924 +#ifndef __UM_IPCBUF_H
36925 +#define __UM_IPCBUF_H
36927 +#include "asm/arch/ipcbuf.h"
36930 diff -Naur -X ../exclude-files orig/include/asm-um/ipc.h um/include/asm-um/ipc.h
36931 --- orig/include/asm-um/ipc.h 1969-12-31 19:00:00.000000000 -0500
36932 +++ um/include/asm-um/ipc.h 2002-10-23 21:08:05.000000000 -0400
36934 +#ifndef __UM_IPC_H
36935 +#define __UM_IPC_H
36937 +#include "asm/arch/ipc.h"
36940 diff -Naur -X ../exclude-files orig/include/asm-um/irq.h um/include/asm-um/irq.h
36941 --- orig/include/asm-um/irq.h 1969-12-31 19:00:00.000000000 -0500
36942 +++ um/include/asm-um/irq.h 2003-05-03 11:03:52.000000000 -0400
36944 +#ifndef __UM_IRQ_H
36945 +#define __UM_IRQ_H
36947 +#define TIMER_IRQ 0
36949 +#define CONSOLE_IRQ 2
36950 +#define CONSOLE_WRITE_IRQ 3
36952 +#define UM_ETH_IRQ 5
36954 +#define SSL_WRITE_IRQ 7
36955 +#define ACCEPT_IRQ 8
36956 +#define MCONSOLE_IRQ 9
36957 +#define WINCH_IRQ 10
36958 +#define SIGIO_WRITE_IRQ 11
36959 +#define TELNETD_IRQ 12
36960 +#define XTERM_IRQ 13
36962 +#define LAST_IRQ XTERM_IRQ
36963 +#define NR_IRQS (LAST_IRQ + 1)
36966 diff -Naur -X ../exclude-files orig/include/asm-um/keyboard.h um/include/asm-um/keyboard.h
36967 --- orig/include/asm-um/keyboard.h 1969-12-31 19:00:00.000000000 -0500
36968 +++ um/include/asm-um/keyboard.h 2002-10-23 21:08:05.000000000 -0400
36970 +#ifndef __UM_KEYBOARD_H
36971 +#define __UM_KEYBOARD_H
36973 +#include "asm/arch/keyboard.h"
36976 diff -Naur -X ../exclude-files orig/include/asm-um/kmap_types.h um/include/asm-um/kmap_types.h
36977 --- orig/include/asm-um/kmap_types.h 1969-12-31 19:00:00.000000000 -0500
36978 +++ um/include/asm-um/kmap_types.h 2003-02-27 13:20:14.000000000 -0500
36981 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36982 + * Licensed under the GPL
36985 +#ifndef __UM_KMAP_TYPES_H
36986 +#define __UM_KMAP_TYPES_H
36988 +#include "asm/arch/kmap_types.h"
36991 diff -Naur -X ../exclude-files orig/include/asm-um/linux_logo.h um/include/asm-um/linux_logo.h
36992 --- orig/include/asm-um/linux_logo.h 1969-12-31 19:00:00.000000000 -0500
36993 +++ um/include/asm-um/linux_logo.h 2002-10-23 21:08:05.000000000 -0400
36995 +#ifndef __UM_LINUX_LOGO_H
36996 +#define __UM_LINUX_LOGO_H
36998 +#include "asm/arch/linux_logo.h"
37001 diff -Naur -X ../exclude-files orig/include/asm-um/locks.h um/include/asm-um/locks.h
37002 --- orig/include/asm-um/locks.h 1969-12-31 19:00:00.000000000 -0500
37003 +++ um/include/asm-um/locks.h 2002-10-23 21:08:05.000000000 -0400
37005 +#ifndef __UM_LOCKS_H
37006 +#define __UM_LOCKS_H
37008 +#include "asm/arch/locks.h"
37011 diff -Naur -X ../exclude-files orig/include/asm-um/mca_dma.h um/include/asm-um/mca_dma.h
37012 --- orig/include/asm-um/mca_dma.h 1969-12-31 19:00:00.000000000 -0500
37013 +++ um/include/asm-um/mca_dma.h 2002-10-23 21:08:05.000000000 -0400
37015 +#ifndef mca___UM_DMA_H
37016 +#define mca___UM_DMA_H
37018 +#include "asm/arch/mca_dma.h"
37021 diff -Naur -X ../exclude-files orig/include/asm-um/mman.h um/include/asm-um/mman.h
37022 --- orig/include/asm-um/mman.h 1969-12-31 19:00:00.000000000 -0500
37023 +++ um/include/asm-um/mman.h 2002-10-23 21:08:05.000000000 -0400
37025 +#ifndef __UM_MMAN_H
37026 +#define __UM_MMAN_H
37028 +#include "asm/arch/mman.h"
37031 diff -Naur -X ../exclude-files orig/include/asm-um/mmu_context.h um/include/asm-um/mmu_context.h
37032 --- orig/include/asm-um/mmu_context.h 1969-12-31 19:00:00.000000000 -0500
37033 +++ um/include/asm-um/mmu_context.h 2003-05-28 11:02:07.000000000 -0400
37036 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
37037 + * Licensed under the GPL
37040 +#ifndef __UM_MMU_CONTEXT_H
37041 +#define __UM_MMU_CONTEXT_H
37043 +#include "linux/sched.h"
37044 +#include "choose-mode.h"
37046 +#define get_mmu_context(task) do ; while(0)
37047 +#define activate_context(tsk) do ; while(0)
37049 +static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
37053 +extern void switch_mm_skas(int mm_fd);
37055 +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
37056 + struct task_struct *tsk, unsigned cpu)
37058 + if(prev != next){
37059 + clear_bit(cpu, &prev->cpu_vm_mask);
37060 + set_bit(cpu, &next->cpu_vm_mask);
37061 + if(next != &init_mm)
37062 + CHOOSE_MODE((void) 0,
37063 + switch_mm_skas(next->context.skas.mm_fd));
37067 +static inline void enter_lazy_tlb(struct mm_struct *mm,
37068 + struct task_struct *tsk, unsigned cpu)
37072 +extern int init_new_context_skas(struct task_struct *task,
37073 + struct mm_struct *mm);
37075 +static inline int init_new_context_tt(struct task_struct *task,
37076 + struct mm_struct *mm)
37081 +static inline int init_new_context(struct task_struct *task,
37082 + struct mm_struct *mm)
37084 + return(CHOOSE_MODE_PROC(init_new_context_tt, init_new_context_skas,
37088 +extern void destroy_context_skas(struct mm_struct *mm);
37090 +static inline void destroy_context(struct mm_struct *mm)
37092 + CHOOSE_MODE((void) 0, destroy_context_skas(mm));
37098 + * Overrides for Emacs so that we follow Linus's tabbing style.
37099 + * Emacs will notice this stuff at the end of the file and automatically
37100 + * adjust the settings for this buffer only. This must remain at the end
37102 + * ---------------------------------------------------------------------------
37103 + * Local variables:
37104 + * c-file-style: "linux"
37107 diff -Naur -X ../exclude-files orig/include/asm-um/mmu.h um/include/asm-um/mmu.h
37108 --- orig/include/asm-um/mmu.h 1969-12-31 19:00:00.000000000 -0500
37109 +++ um/include/asm-um/mmu.h 2002-11-09 12:51:11.000000000 -0500
37112 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
37113 + * Licensed under the GPL
37119 +#include "um_mmu.h"
37124 + * Overrides for Emacs so that we follow Linus's tabbing style.
37125 + * Emacs will notice this stuff at the end of the file and automatically
37126 + * adjust the settings for this buffer only. This must remain at the end
37128 + * ---------------------------------------------------------------------------
37129 + * Local variables:
37130 + * c-file-style: "linux"
37133 diff -Naur -X ../exclude-files orig/include/asm-um/module.h um/include/asm-um/module.h
37134 --- orig/include/asm-um/module.h 1969-12-31 19:00:00.000000000 -0500
37135 +++ um/include/asm-um/module.h 2002-10-23 21:08:05.000000000 -0400
37137 +#ifndef __UM_MODULE_H
37138 +#define __UM_MODULE_H
37140 +#include "asm/arch/module.h"
37143 diff -Naur -X ../exclude-files orig/include/asm-um/msgbuf.h um/include/asm-um/msgbuf.h
37144 --- orig/include/asm-um/msgbuf.h 1969-12-31 19:00:00.000000000 -0500
37145 +++ um/include/asm-um/msgbuf.h 2002-10-23 21:08:05.000000000 -0400
37147 +#ifndef __UM_MSGBUF_H
37148 +#define __UM_MSGBUF_H
37150 +#include "asm/arch/msgbuf.h"
37153 diff -Naur -X ../exclude-files orig/include/asm-um/mtrr.h um/include/asm-um/mtrr.h
37154 --- orig/include/asm-um/mtrr.h 1969-12-31 19:00:00.000000000 -0500
37155 +++ um/include/asm-um/mtrr.h 2003-05-29 13:46:27.000000000 -0400
37157 +#ifndef __UM_MTRR_H
37158 +#define __UM_MTRR_H
37160 +#include "asm/arch/mtrr.h"
37163 diff -Naur -X ../exclude-files orig/include/asm-um/namei.h um/include/asm-um/namei.h
37164 --- orig/include/asm-um/namei.h 1969-12-31 19:00:00.000000000 -0500
37165 +++ um/include/asm-um/namei.h 2002-10-23 21:08:05.000000000 -0400
37167 +#ifndef __UM_NAMEI_H
37168 +#define __UM_NAMEI_H
37170 +#include "asm/arch/namei.h"
37173 diff -Naur -X ../exclude-files orig/include/asm-um/page.h um/include/asm-um/page.h
37174 --- orig/include/asm-um/page.h 1969-12-31 19:00:00.000000000 -0500
37175 +++ um/include/asm-um/page.h 2002-10-27 16:49:35.000000000 -0500
37177 +#ifndef __UM_PAGE_H
37178 +#define __UM_PAGE_H
37182 +#include "asm/arch/page.h"
37188 +#undef virt_to_page
37190 +#undef PAGE_OFFSET
37193 +extern unsigned long uml_physmem;
37195 +#define PAGE_OFFSET (uml_physmem)
37196 +#define KERNELBASE PAGE_OFFSET
37198 +#ifndef __ASSEMBLY__
37200 +extern void stop(void);
37202 +#define BUG() do { \
37203 + panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
37206 +#define PAGE_BUG(page) do { \
37210 +#endif /* __ASSEMBLY__ */
37212 +#define __va_space (8*1024*1024)
37214 +extern unsigned long region_pa(void *virt);
37215 +extern void *region_va(unsigned long phys);
37217 +#define __pa(virt) region_pa((void *) (virt))
37218 +#define __va(phys) region_va((unsigned long) (phys))
37220 +extern struct page *page_mem_map(struct page *page);
37222 +extern struct page *pfn_to_page(unsigned long pfn);
37224 +#define VALID_PAGE(page) (page_mem_map(page) != NULL)
37226 +extern struct page *arch_validate(struct page *page, int mask, int order);
37227 +#define HAVE_ARCH_VALIDATE
37230 diff -Naur -X ../exclude-files orig/include/asm-um/page_offset.h um/include/asm-um/page_offset.h
37231 --- orig/include/asm-um/page_offset.h 1969-12-31 19:00:00.000000000 -0500
37232 +++ um/include/asm-um/page_offset.h 2002-10-23 21:08:05.000000000 -0400
37234 +#define PAGE_OFFSET_RAW (uml_physmem)
37235 diff -Naur -X ../exclude-files orig/include/asm-um/param.h um/include/asm-um/param.h
37236 --- orig/include/asm-um/param.h 1969-12-31 19:00:00.000000000 -0500
37237 +++ um/include/asm-um/param.h 2002-10-23 21:08:05.000000000 -0400
37239 +#ifndef _UM_PARAM_H
37240 +#define _UM_PARAM_H
37246 +#define EXEC_PAGESIZE 4096
37249 +#define NGROUPS 32
37253 +#define NOGROUP (-1)
37256 +#define MAXHOSTNAMELEN 64 /* max length of hostname */
37259 +# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */
37263 diff -Naur -X ../exclude-files orig/include/asm-um/pci.h um/include/asm-um/pci.h
37264 --- orig/include/asm-um/pci.h 1969-12-31 19:00:00.000000000 -0500
37265 +++ um/include/asm-um/pci.h 2002-10-23 21:08:05.000000000 -0400
37267 +#ifndef __UM_PCI_H
37268 +#define __UM_PCI_H
37270 +#define PCI_DMA_BUS_IS_PHYS (1)
37273 diff -Naur -X ../exclude-files orig/include/asm-um/pgalloc.h um/include/asm-um/pgalloc.h
37274 --- orig/include/asm-um/pgalloc.h 1969-12-31 19:00:00.000000000 -0500
37275 +++ um/include/asm-um/pgalloc.h 2003-05-28 11:02:08.000000000 -0400
37278 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
37279 + * Derived from include/asm-i386/pgalloc.h and include/asm-i386/pgtable.h
37280 + * Licensed under the GPL
37283 +#ifndef __UM_PGALLOC_H
37284 +#define __UM_PGALLOC_H
37286 +#include "linux/config.h"
37287 +#include "linux/mm.h"
37288 +#include "asm/fixmap.h"
37289 +#include "choose-mode.h"
37291 +#define pgd_quicklist (current_cpu_data.pgd_quick)
37292 +#define pmd_quicklist (current_cpu_data.pmd_quick)
37293 +#define pte_quicklist (current_cpu_data.pte_quick)
37294 +#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
37296 +#define pmd_populate(mm, pmd, pte) set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
37299 + * Allocate and free page tables.
37302 +static inline pgd_t *get_pgd_slow_tt(void)
37304 + pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
37307 + memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
37308 + memcpy(pgd + USER_PTRS_PER_PGD,
37309 + swapper_pg_dir + USER_PTRS_PER_PGD,
37310 + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
37315 +static inline pgd_t *get_pgd_slow_skas(void)
37317 + pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
37320 + memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
37324 +static inline pgd_t *get_pgd_slow(void)
37326 + return(CHOOSE_MODE(get_pgd_slow_tt(), get_pgd_slow_skas()));
37329 +static inline pgd_t *get_pgd_fast(void)
37331 + unsigned long *ret;
37333 + if ((ret = pgd_quicklist) != NULL) {
37334 + pgd_quicklist = (unsigned long *)(*ret);
37336 + pgtable_cache_size--;
37338 + ret = (unsigned long *)get_pgd_slow();
37339 + return (pgd_t *)ret;
37342 +static inline void free_pgd_fast(pgd_t *pgd)
37344 + *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
37345 + pgd_quicklist = (unsigned long *) pgd;
37346 + pgtable_cache_size++;
37349 +static inline void free_pgd_slow(pgd_t *pgd)
37351 + free_page((unsigned long)pgd);
37354 +static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
37358 + pte = (pte_t *) __get_free_page(GFP_KERNEL);
37364 +static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
37366 + unsigned long *ret;
37368 + if ((ret = (unsigned long *)pte_quicklist) != NULL) {
37369 + pte_quicklist = (unsigned long *)(*ret);
37371 + pgtable_cache_size--;
37373 + return (pte_t *)ret;
37376 +static inline void pte_free_fast(pte_t *pte)
37378 + *(unsigned long *)pte = (unsigned long) pte_quicklist;
37379 + pte_quicklist = (unsigned long *) pte;
37380 + pgtable_cache_size++;
37383 +static inline void pte_free_slow(pte_t *pte)
37385 + free_page((unsigned long)pte);
37388 +#define pte_free(pte) pte_free_fast(pte)
37389 +#define pgd_free(pgd) free_pgd_slow(pgd)
37390 +#define pgd_alloc(mm) get_pgd_fast()
37393 + * allocating and freeing a pmd is trivial: the 1-entry pmd is
37394 + * inside the pgd, so has no extra memory associated with it.
37397 +#define pmd_alloc_one_fast(mm, addr) ({ BUG(); ((pmd_t *)1); })
37398 +#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
37399 +#define pmd_free_slow(x) do { } while (0)
37400 +#define pmd_free_fast(x) do { } while (0)
37401 +#define pmd_free(x) do { } while (0)
37402 +#define pgd_populate(mm, pmd, pte) BUG()
37407 + * - flush_tlb() flushes the current mm struct TLBs
37408 + * - flush_tlb_all() flushes all processes TLBs
37409 + * - flush_tlb_mm(mm) flushes the specified mm context TLB's
37410 + * - flush_tlb_page(vma, vmaddr) flushes one page
37411 + * - flush_tlb_kernel_vm() flushes the kernel vm area
37412 + * - flush_tlb_range(mm, start, end) flushes a range of pages
37413 + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
37416 +extern void flush_tlb_all(void);
37417 +extern void flush_tlb_mm(struct mm_struct *mm);
37418 +extern void flush_tlb_range(struct mm_struct *mm, unsigned long start,
37419 + unsigned long end);
37420 +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
37421 +extern void flush_tlb_kernel_vm(void);
37423 +static inline void flush_tlb_pgtables(struct mm_struct *mm,
37424 + unsigned long start, unsigned long end)
37430 + * Overrides for Emacs so that we follow Linus's tabbing style.
37431 + * Emacs will notice this stuff at the end of the file and automatically
37432 + * adjust the settings for this buffer only. This must remain at the end
37434 + * ---------------------------------------------------------------------------
37435 + * Local variables:
37436 + * c-file-style: "linux"
37439 diff -Naur -X ../exclude-files orig/include/asm-um/pgtable.h um/include/asm-um/pgtable.h
37440 --- orig/include/asm-um/pgtable.h 1969-12-31 19:00:00.000000000 -0500
37441 +++ um/include/asm-um/pgtable.h 2003-05-28 11:02:07.000000000 -0400
37444 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
37445 + * Derived from include/asm-i386/pgtable.h
37446 + * Licensed under the GPL
37449 +#ifndef __UM_PGTABLE_H
37450 +#define __UM_PGTABLE_H
37452 +#include "linux/sched.h"
37453 +#include "asm/processor.h"
37454 +#include "asm/page.h"
37456 +extern pgd_t swapper_pg_dir[1024];
37458 +#define flush_cache_all() do ; while (0)
37459 +#define flush_cache_mm(mm) do ; while (0)
37460 +#define flush_cache_range(vma, start, end) do ; while (0)
37461 +#define flush_cache_page(vma, vmaddr) do ; while (0)
37462 +#define flush_page_to_ram(page) do ; while (0)
37463 +#define flush_dcache_page(page) do ; while (0)
37464 +#define flush_icache_range(from, to) do ; while (0)
37465 +#define flush_icache_page(vma,pg) do ; while (0)
37466 +#define flush_icache_user_range(vma,pg,adr,len) do ; while (0)
37468 +extern void __flush_tlb_one(unsigned long addr);
37470 +extern void pte_free(pte_t *pte);
37472 +extern void pgd_free(pgd_t *pgd);
37474 +extern int do_check_pgt_cache(int, int);
37476 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
37479 +/* zero page used for uninitialized stuff */
37480 +extern unsigned long *empty_zero_page;
37482 +#define pgtable_cache_init() do ; while (0)
37484 +/* PMD_SHIFT determines the size of the area a second-level page table can map */
37485 +#define PMD_SHIFT 22
37486 +#define PMD_SIZE (1UL << PMD_SHIFT)
37487 +#define PMD_MASK (~(PMD_SIZE-1))
37489 +/* PGDIR_SHIFT determines what a third-level page table entry can map */
37490 +#define PGDIR_SHIFT 22
37491 +#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
37492 +#define PGDIR_MASK (~(PGDIR_SIZE-1))
37495 + * entries per page directory level: the i386 is two-level, so
37496 + * we don't really have any PMD directory physically.
37498 +#define PTRS_PER_PTE 1024
37499 +#define PTRS_PER_PMD 1
37500 +#define PTRS_PER_PGD 1024
37501 +#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
37502 +#define FIRST_USER_PGD_NR 0
37504 +#define pte_ERROR(e) \
37505 + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
37506 +#define pmd_ERROR(e) \
37507 + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
37508 +#define pgd_ERROR(e) \
37509 + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
37512 + * pgd entries used up by user/kernel:
37515 +#define USER_PGD_PTRS (TASK_SIZE >> PGDIR_SHIFT)
37516 +#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
37518 +#ifndef __ASSEMBLY__
37519 +/* Just any arbitrary offset to the start of the vmalloc VM area: the
37520 + * current 8MB value just means that there will be a 8MB "hole" after the
37521 + * physical memory until the kernel virtual memory starts. That means that
37522 + * any out-of-bounds memory accesses will hopefully be caught.
37523 + * The vmalloc() routines leaves a hole of 4kB between each vmalloced
37524 + * area for the same reason. ;)
37527 +extern unsigned long high_physmem;
37529 +#define VMALLOC_OFFSET (__va_space)
37530 +#define VMALLOC_START (((unsigned long) high_physmem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
37531 +#define VMALLOC_VMADDR(x) ((unsigned long)(x))
37533 +#if CONFIG_HIGHMEM
37534 +# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
37536 +# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
37539 +#define _PAGE_PRESENT 0x001
37540 +#define _PAGE_NEWPAGE 0x002
37541 +#define _PAGE_PROTNONE 0x004 /* If not present */
37542 +#define _PAGE_RW 0x008
37543 +#define _PAGE_USER 0x010
37544 +#define _PAGE_ACCESSED 0x020
37545 +#define _PAGE_DIRTY 0x040
37546 +#define _PAGE_NEWPROT 0x080
37548 +#define REGION_MASK 0xf0000000
37549 +#define REGION_SHIFT 28
37551 +#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
37552 +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
37553 +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
37555 +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
37556 +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
37557 +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
37558 +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
37559 +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
37560 +#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
37563 + * The i386 can't do page protection for execute, and considers that the same are read.
37564 + * Also, write permissions imply read permissions. This is the closest we can get..
37566 +#define __P000 PAGE_NONE
37567 +#define __P001 PAGE_READONLY
37568 +#define __P010 PAGE_COPY
37569 +#define __P011 PAGE_COPY
37570 +#define __P100 PAGE_READONLY
37571 +#define __P101 PAGE_READONLY
37572 +#define __P110 PAGE_COPY
37573 +#define __P111 PAGE_COPY
37575 +#define __S000 PAGE_NONE
37576 +#define __S001 PAGE_READONLY
37577 +#define __S010 PAGE_SHARED
37578 +#define __S011 PAGE_SHARED
37579 +#define __S100 PAGE_READONLY
37580 +#define __S101 PAGE_READONLY
37581 +#define __S110 PAGE_SHARED
37582 +#define __S111 PAGE_SHARED
37585 + * Define this if things work differently on an i386 and an i486:
37586 + * it will (on an i486) warn about kernel memory accesses that are
37587 + * done without a 'verify_area(VERIFY_WRITE,..)'
37589 +#undef TEST_VERIFY_AREA
37591 +/* page table for 0-4MB for everybody */
37592 +extern unsigned long pg0[1024];
37595 + * BAD_PAGETABLE is used when we need a bogus page-table, while
37596 + * BAD_PAGE is used for a bogus page.
37598 + * ZERO_PAGE is a global shared page that is always zero: used
37599 + * for zero-mapped memory areas etc..
37601 +extern pte_t __bad_page(void);
37602 +extern pte_t * __bad_pagetable(void);
37604 +#define BAD_PAGETABLE __bad_pagetable()
37605 +#define BAD_PAGE __bad_page()
37606 +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
37608 +/* number of bits that fit into a memory pointer */
37609 +#define BITS_PER_PTR (8*sizeof(unsigned long))
37611 +/* to align the pointer to a pointer address */
37612 +#define PTR_MASK (~(sizeof(void*)-1))
37614 +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
37615 +/* 64-bit machines, beware! SRB. */
37616 +#define SIZEOF_PTR_LOG2 2
37618 +/* to find an entry in a page-table */
37619 +#define PAGE_PTR(address) \
37620 +((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
37622 +#define pte_none(x) !(pte_val(x) & ~_PAGE_NEWPAGE)
37623 +#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
37625 +#define pte_clear(xp) do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
37627 +#define phys_region_index(x) (((x) & REGION_MASK) >> REGION_SHIFT)
37628 +#define pte_region_index(x) phys_region_index(pte_val(x))
37630 +#define pmd_none(x) (!(pmd_val(x) & ~_PAGE_NEWPAGE))
37631 +#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
37632 +#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
37633 +#define pmd_clear(xp) do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
37635 +#define pmd_newpage(x) (pmd_val(x) & _PAGE_NEWPAGE)
37636 +#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE)
37639 + * The "pgd_xxx()" functions here are trivial for a folded two-level
37640 + * setup: the pgd is never bad, and a pmd always exists (as it's folded
37641 + * into the pgd entry)
37643 +static inline int pgd_none(pgd_t pgd) { return 0; }
37644 +static inline int pgd_bad(pgd_t pgd) { return 0; }
37645 +static inline int pgd_present(pgd_t pgd) { return 1; }
37646 +static inline void pgd_clear(pgd_t * pgdp) { }
37648 +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
37650 +extern struct page *pte_mem_map(pte_t pte);
37651 +extern struct page *phys_mem_map(unsigned long phys);
37652 +extern unsigned long phys_to_pfn(unsigned long p);
37654 +#define pte_page(x) pfn_to_page(pte_pfn(x))
37655 +#define pte_address(x) (__va(pte_val(x) & PAGE_MASK))
37656 +#define mk_phys(a, r) ((a) + (r << REGION_SHIFT))
37657 +#define phys_addr(p) ((p) & ~REGION_MASK)
37658 +#define phys_page(p) (phys_mem_map(p) + ((phys_addr(p)) >> PAGE_SHIFT))
37659 +#define virt_to_page(kaddr) \
37660 + (phys_mem_map(__pa(kaddr)) + (phys_addr(__pa(kaddr)) >> PAGE_SHIFT))
37661 +#define pte_pfn(x) phys_to_pfn(pte_val(x))
37663 +static inline pte_t pte_mknewprot(pte_t pte)
37665 + pte_val(pte) |= _PAGE_NEWPROT;
37669 +static inline pte_t pte_mknewpage(pte_t pte)
37671 + pte_val(pte) |= _PAGE_NEWPAGE;
37675 +static inline void set_pte(pte_t *pteptr, pte_t pteval)
37677 + /* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so
37678 + * fix_range knows to unmap it. _PAGE_NEWPROT is specific to
37681 + *pteptr = pte_mknewpage(pteval);
37682 + if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr);
37686 + * (pmds are folded into pgds so this doesnt get actually called,
37687 + * but the define is needed for a generic inline function.)
37689 +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
37690 +#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
37693 + * The following only work if pte_present() is true.
37694 + * Undefined behaviour if not..
37696 +static inline int pte_read(pte_t pte)
37698 + return((pte_val(pte) & _PAGE_USER) &&
37699 + !(pte_val(pte) & _PAGE_PROTNONE));
37702 +static inline int pte_exec(pte_t pte){
37703 + return((pte_val(pte) & _PAGE_USER) &&
37704 + !(pte_val(pte) & _PAGE_PROTNONE));
37707 +static inline int pte_write(pte_t pte)
37709 + return((pte_val(pte) & _PAGE_RW) &&
37710 + !(pte_val(pte) & _PAGE_PROTNONE));
37713 +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
37714 +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
37715 +static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
37716 +static inline int pte_newprot(pte_t pte)
37718 + return(pte_present(pte) && (pte_val(pte) & _PAGE_NEWPROT));
37721 +static inline pte_t pte_rdprotect(pte_t pte)
37723 + pte_val(pte) &= ~_PAGE_USER;
37724 + return(pte_mknewprot(pte));
37727 +static inline pte_t pte_exprotect(pte_t pte)
37729 + pte_val(pte) &= ~_PAGE_USER;
37730 + return(pte_mknewprot(pte));
37733 +static inline pte_t pte_mkclean(pte_t pte)
37735 + pte_val(pte) &= ~_PAGE_DIRTY;
37739 +static inline pte_t pte_mkold(pte_t pte)
37741 + pte_val(pte) &= ~_PAGE_ACCESSED;
37745 +static inline pte_t pte_wrprotect(pte_t pte)
37747 + pte_val(pte) &= ~_PAGE_RW;
37748 + return(pte_mknewprot(pte));
37751 +static inline pte_t pte_mkread(pte_t pte)
37753 + pte_val(pte) |= _PAGE_USER;
37754 + return(pte_mknewprot(pte));
37757 +static inline pte_t pte_mkexec(pte_t pte)
37759 + pte_val(pte) |= _PAGE_USER;
37760 + return(pte_mknewprot(pte));
37763 +static inline pte_t pte_mkdirty(pte_t pte)
37765 + pte_val(pte) |= _PAGE_DIRTY;
37769 +static inline pte_t pte_mkyoung(pte_t pte)
37771 + pte_val(pte) |= _PAGE_ACCESSED;
37775 +static inline pte_t pte_mkwrite(pte_t pte)
37777 + pte_val(pte) |= _PAGE_RW;
37778 + return(pte_mknewprot(pte));
37781 +static inline pte_t pte_mkuptodate(pte_t pte)
37783 + pte_val(pte) &= ~_PAGE_NEWPAGE;
37784 + if(pte_present(pte)) pte_val(pte) &= ~_PAGE_NEWPROT;
37788 +extern unsigned long page_to_phys(struct page *page);
37791 + * Conversion functions: convert a page and protection to a page entry,
37792 + * and a page entry and page directory to the page they refer to.
37795 +#define mk_pte(page, pgprot) \
37799 + pte_val(__pte) = page_to_phys(page) + pgprot_val(pgprot);\
37800 + if(pte_present(__pte)) pte_mknewprot(pte_mknewpage(__pte)); \
37804 +/* This takes a physical page address that is used by the remapping functions */
37805 +#define mk_pte_phys(physpage, pgprot) \
37806 + pte_mknewpage(mk_pte(phys_page(physpage), pgprot))
37808 +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
37810 + pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
37811 + if(pte_present(pte)) pte = pte_mknewpage(pte_mknewprot(pte));
37815 +#define pmd_page(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
37817 +/* to find an entry in a page-table-directory. */
37818 +#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
37819 +#define __pgd_offset(address) pgd_index(address)
37821 +/* to find an entry in a page-table-directory */
37822 +#define pgd_offset(mm, address) \
37823 +((mm)->pgd + ((address) >> PGDIR_SHIFT))
37825 +/* to find an entry in a kernel page-table-directory */
37826 +#define pgd_offset_k(address) pgd_offset(&init_mm, address)
37828 +#define __pmd_offset(address) \
37829 + (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
37831 +/* Find an entry in the second-level page table.. */
37832 +static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
37834 + return (pmd_t *) dir;
37837 +/* Find an entry in the third-level page table.. */
37838 +#define pte_offset(pmd, address) \
37839 +((pte_t *) (pmd_page(*pmd) + ((address>>10) & ((PTRS_PER_PTE-1)<<2))))
37841 +#define update_mmu_cache(vma,address,pte) do ; while (0)
37843 +/* Encode and de-code a swap entry */
37844 +#define SWP_TYPE(x) (((x).val >> 3) & 0x7f)
37845 +#define SWP_OFFSET(x) ((x).val >> 10)
37847 +#define SWP_ENTRY(type, offset) \
37848 + ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
37849 +#define pte_to_swp_entry(pte) \
37850 + ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
37851 +#define swp_entry_to_pte(x) ((pte_t) { (x).val })
37853 +#define PageSkip(x) (0)
37854 +#define kern_addr_valid(addr) (1)
37856 +#include <asm-generic/pgtable.h>
37862 + * Overrides for Emacs so that we follow Linus's tabbing style.
37863 + * Emacs will notice this stuff at the end of the file and automatically
37864 + * adjust the settings for this buffer only. This must remain at the end
37866 + * ---------------------------------------------------------------------------
37867 + * Local variables:
37868 + * c-file-style: "linux"
37871 diff -Naur -X ../exclude-files orig/include/asm-um/poll.h um/include/asm-um/poll.h
37872 --- orig/include/asm-um/poll.h 1969-12-31 19:00:00.000000000 -0500
37873 +++ um/include/asm-um/poll.h 2002-10-23 21:08:05.000000000 -0400
37875 +#ifndef __UM_POLL_H
37876 +#define __UM_POLL_H
37878 +#include "asm/arch/poll.h"
37881 diff -Naur -X ../exclude-files orig/include/asm-um/posix_types.h um/include/asm-um/posix_types.h
37882 --- orig/include/asm-um/posix_types.h 1969-12-31 19:00:00.000000000 -0500
37883 +++ um/include/asm-um/posix_types.h 2002-10-23 21:08:05.000000000 -0400
37885 +#ifndef __UM_POSIX_TYPES_H
37886 +#define __UM_POSIX_TYPES_H
37888 +#include "asm/arch/posix_types.h"
37891 diff -Naur -X ../exclude-files orig/include/asm-um/processor-generic.h um/include/asm-um/processor-generic.h
37892 --- orig/include/asm-um/processor-generic.h 1969-12-31 19:00:00.000000000 -0500
37893 +++ um/include/asm-um/processor-generic.h 2003-05-28 11:02:07.000000000 -0400
37896 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
37897 + * Licensed under the GPL
37900 +#ifndef __UM_PROCESSOR_GENERIC_H
37901 +#define __UM_PROCESSOR_GENERIC_H
37905 +struct task_struct;
37907 +#include "linux/config.h"
37908 +#include "linux/signal.h"
37909 +#include "asm/ptrace.h"
37910 +#include "asm/siginfo.h"
37911 +#include "choose-mode.h"
37915 +#define current_text_addr() ((void *) 0)
37917 +#define cpu_relax() do ; while (0)
37919 +#ifdef CONFIG_MODE_TT
37920 +struct proc_tt_mode {
37923 + int switch_pipe[2];
37924 + int singlestep_syscall;
37929 +#ifdef CONFIG_MODE_SKAS
37930 +struct proc_skas_mode {
37931 + void *switch_buf;
37936 +struct thread_struct {
37938 + unsigned long kernel_stack;
37940 + struct pt_regs regs;
37941 + unsigned long cr2;
37943 + void *fault_addr;
37944 + void *fault_catcher;
37945 + struct task_struct *prev_sched;
37946 + unsigned long temp_stack;
37948 + struct arch_thread arch;
37950 +#ifdef CONFIG_MODE_TT
37951 + struct proc_tt_mode tt;
37953 +#ifdef CONFIG_MODE_SKAS
37954 + struct proc_skas_mode skas;
37964 + int (*proc)(void *);
37968 + void (*proc)(void *);
37975 +#define INIT_THREAD \
37978 + .kernel_stack = 0, \
37979 + .nsyscalls = 0, \
37980 + .regs = EMPTY_REGS, \
37983 + .fault_addr = NULL, \
37984 + .prev_sched = NULL, \
37985 + .temp_stack = 0, \
37986 + .exec_buf = NULL, \
37987 + .arch = INIT_ARCH_THREAD, \
37988 + .request = { 0 } \
37991 +#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
37994 + unsigned long seg;
37997 +extern struct task_struct *alloc_task_struct(void);
37998 +extern void free_task_struct(struct task_struct *task);
38000 +#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count)
38002 +extern void release_thread(struct task_struct *);
38003 +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
38004 +extern void dump_thread(struct pt_regs *regs, struct user *u);
38006 +extern unsigned long thread_saved_pc(struct thread_struct *t);
38008 +static inline void mm_copy_segments(struct mm_struct *from_mm,
38009 + struct mm_struct *new_mm)
38013 +static inline void copy_segments(struct task_struct *p,
38014 + struct mm_struct *new_mm)
38018 +static inline void release_segments(struct mm_struct *mm)
38022 +#define init_task (init_task_union.task)
38023 +#define init_stack (init_task_union.stack)
38026 + * User space process size: 3GB (default).
38028 +extern unsigned long task_size;
38030 +#define TASK_SIZE (task_size)
38032 +/* This decides where the kernel will search for a free chunk of vm
38033 + * space during mmap's.
38035 +#define TASK_UNMAPPED_BASE (0x40000000)
38037 +extern void start_thread(struct pt_regs *regs, unsigned long entry,
38038 + unsigned long stack);
38040 +struct cpuinfo_um {
38041 + unsigned long loops_per_jiffy;
38042 + unsigned long *pgd_quick;
38043 + unsigned long *pmd_quick;
38044 + unsigned long *pte_quick;
38045 + unsigned long pgtable_cache_sz;
38049 +extern struct cpuinfo_um boot_cpu_data;
38051 +#define my_cpu_data cpu_data[smp_processor_id()]
38054 +extern struct cpuinfo_um cpu_data[];
38055 +#define current_cpu_data cpu_data[smp_processor_id()]
38057 +#define cpu_data (&boot_cpu_data)
38058 +#define current_cpu_data boot_cpu_data
38061 +#define KSTK_EIP(tsk) (PT_REGS_IP(&tsk->thread.regs))
38062 +#define KSTK_ESP(tsk) (PT_REGS_SP(&tsk->thread.regs))
38063 +#define get_wchan(p) (0)
38068 + * Overrides for Emacs so that we follow Linus's tabbing style.
38069 + * Emacs will notice this stuff at the end of the file and automatically
38070 + * adjust the settings for this buffer only. This must remain at the end
38072 + * ---------------------------------------------------------------------------
38073 + * Local variables:
38074 + * c-file-style: "linux"
38077 diff -Naur -X ../exclude-files orig/include/asm-um/processor-i386.h um/include/asm-um/processor-i386.h
38078 --- orig/include/asm-um/processor-i386.h 1969-12-31 19:00:00.000000000 -0500
38079 +++ um/include/asm-um/processor-i386.h 2003-05-28 11:02:07.000000000 -0400
38082 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38083 + * Licensed under the GPL
38086 +#ifndef __UM_PROCESSOR_I386_H
38087 +#define __UM_PROCESSOR_I386_H
38089 +extern int cpu_has_xmm;
38090 +extern int cpu_has_cmov;
38092 +struct arch_thread {
38093 + unsigned long debugregs[8];
38094 + int debugregs_seq;
38097 +#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \
38098 + .debugregs_seq = 0 }
38100 +#include "asm/arch/user.h"
38102 +#include "asm/processor-generic.h"
38107 + * Overrides for Emacs so that we follow Linus's tabbing style.
38108 + * Emacs will notice this stuff at the end of the file and automatically
38109 + * adjust the settings for this buffer only. This must remain at the end
38111 + * ---------------------------------------------------------------------------
38112 + * Local variables:
38113 + * c-file-style: "linux"
38116 diff -Naur -X ../exclude-files orig/include/asm-um/processor-ppc.h um/include/asm-um/processor-ppc.h
38117 --- orig/include/asm-um/processor-ppc.h 1969-12-31 19:00:00.000000000 -0500
38118 +++ um/include/asm-um/processor-ppc.h 2002-10-23 21:08:05.000000000 -0400
38120 +#ifndef __UM_PROCESSOR_PPC_H
38121 +#define __UM_PROCESSOR_PPC_H
38123 +#if defined(__ASSEMBLY__)
38125 +#define CONFIG_ALL_PPC
38126 +#include "arch/processor.h"
38130 +#include "asm/processor-generic.h"
38135 diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-generic.h um/include/asm-um/ptrace-generic.h
38136 --- orig/include/asm-um/ptrace-generic.h 1969-12-31 19:00:00.000000000 -0500
38137 +++ um/include/asm-um/ptrace-generic.h 2003-05-28 11:02:07.000000000 -0400
38140 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
38141 + * Licensed under the GPL
38144 +#ifndef __UM_PTRACE_GENERIC_H
38145 +#define __UM_PTRACE_GENERIC_H
38147 +#ifndef __ASSEMBLY__
38149 +#include "linux/config.h"
38151 +#include "asm/current.h"
38153 +#define pt_regs pt_regs_subarch
38154 +#define show_regs show_regs_subarch
38156 +#include "asm/arch/ptrace.h"
38161 +#undef instruction_pointer
38163 +#include "sysdep/ptrace.h"
38164 +#include "skas_ptrace.h"
38167 + union uml_pt_regs regs;
38170 +#define EMPTY_REGS { regs : EMPTY_UML_PT_REGS }
38172 +#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
38173 +#define PT_REGS_SP(r) UPT_SP(&(r)->regs)
38175 +#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg)
38176 +#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val)
38178 +#define PT_REGS_SET_SYSCALL_RETURN(r, res) \
38179 + UPT_SET_SYSCALL_RETURN(&(r)->regs, res)
38180 +#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs)
38182 +#define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs)
38184 +#define PT_REGS_SC(r) UPT_SC(&(r)->regs)
38186 +struct task_struct;
38188 +extern unsigned long getreg(struct task_struct *child, int regno);
38189 +extern int putreg(struct task_struct *child, int regno, unsigned long value);
38190 +extern int get_fpregs(unsigned long buf, struct task_struct *child);
38191 +extern int set_fpregs(unsigned long buf, struct task_struct *child);
38192 +extern int get_fpxregs(unsigned long buf, struct task_struct *child);
38193 +extern int set_fpxregs(unsigned long buf, struct task_struct *tsk);
38195 +extern void show_regs(struct pt_regs *regs);
38197 +#define INIT_TASK_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
38204 + * Overrides for Emacs so that we follow Linus's tabbing style.
38205 + * Emacs will notice this stuff at the end of the file and automatically
38206 + * adjust the settings for this buffer only. This must remain at the end
38208 + * ---------------------------------------------------------------------------
38209 + * Local variables:
38210 + * c-file-style: "linux"
38213 diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-i386.h um/include/asm-um/ptrace-i386.h
38214 --- orig/include/asm-um/ptrace-i386.h 1969-12-31 19:00:00.000000000 -0500
38215 +++ um/include/asm-um/ptrace-i386.h 2003-05-28 11:02:07.000000000 -0400
38218 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
38219 + * Licensed under the GPL
38222 +#ifndef __UM_PTRACE_I386_H
38223 +#define __UM_PTRACE_I386_H
38225 +#include "sysdep/ptrace.h"
38226 +#include "asm/ptrace-generic.h"
38228 +#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
38229 +#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs)
38230 +#define PT_REGS_ECX(r) UPT_ECX(&(r)->regs)
38231 +#define PT_REGS_EDX(r) UPT_EDX(&(r)->regs)
38232 +#define PT_REGS_ESI(r) UPT_ESI(&(r)->regs)
38233 +#define PT_REGS_EDI(r) UPT_EDI(&(r)->regs)
38234 +#define PT_REGS_EBP(r) UPT_EBP(&(r)->regs)
38236 +#define PT_REGS_CS(r) UPT_CS(&(r)->regs)
38237 +#define PT_REGS_SS(r) UPT_SS(&(r)->regs)
38238 +#define PT_REGS_DS(r) UPT_DS(&(r)->regs)
38239 +#define PT_REGS_ES(r) UPT_ES(&(r)->regs)
38240 +#define PT_REGS_FS(r) UPT_FS(&(r)->regs)
38241 +#define PT_REGS_GS(r) UPT_GS(&(r)->regs)
38243 +#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs)
38245 +#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_EAX(r)
38246 +#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r)
38247 +#define PT_FIX_EXEC_STACK(sp) do ; while(0)
38249 +#define user_mode(r) UPT_IS_USER(&(r)->regs)
38254 + * Overrides for Emacs so that we follow Linus's tabbing style.
38255 + * Emacs will notice this stuff at the end of the file and automatically
38256 + * adjust the settings for this buffer only. This must remain at the end
38258 + * ---------------------------------------------------------------------------
38259 + * Local variables:
38260 + * c-file-style: "linux"
38263 diff -Naur -X ../exclude-files orig/include/asm-um/resource.h um/include/asm-um/resource.h
38264 --- orig/include/asm-um/resource.h 1969-12-31 19:00:00.000000000 -0500
38265 +++ um/include/asm-um/resource.h 2002-10-23 21:08:05.000000000 -0400
38267 +#ifndef __UM_RESOURCE_H
38268 +#define __UM_RESOURCE_H
38270 +#include "asm/arch/resource.h"
38273 diff -Naur -X ../exclude-files orig/include/asm-um/rwlock.h um/include/asm-um/rwlock.h
38274 --- orig/include/asm-um/rwlock.h 1969-12-31 19:00:00.000000000 -0500
38275 +++ um/include/asm-um/rwlock.h 2002-10-23 21:08:05.000000000 -0400
38277 +#ifndef __UM_RWLOCK_H
38278 +#define __UM_RWLOCK_H
38280 +#include "asm/arch/rwlock.h"
38283 diff -Naur -X ../exclude-files orig/include/asm-um/rwsem.h um/include/asm-um/rwsem.h
38284 --- orig/include/asm-um/rwsem.h 1969-12-31 19:00:00.000000000 -0500
38285 +++ um/include/asm-um/rwsem.h 2003-05-28 11:02:07.000000000 -0400
38287 +#ifndef __UM_RWSEM_H__
38288 +#define __UM_RWSEM_H__
38290 +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
38291 +#define __builtin_expect(exp,c) (exp)
38294 +#include "asm/arch/rwsem.h"
38297 diff -Naur -X ../exclude-files orig/include/asm-um/scatterlist.h um/include/asm-um/scatterlist.h
38298 --- orig/include/asm-um/scatterlist.h 1969-12-31 19:00:00.000000000 -0500
38299 +++ um/include/asm-um/scatterlist.h 2003-02-27 13:21:49.000000000 -0500
38301 +#ifndef __UM_SCATTERLIST_H
38302 +#define __UM_SCATTERLIST_H
38304 +#include "asm/arch/scatterlist.h"
38307 diff -Naur -X ../exclude-files orig/include/asm-um/segment.h um/include/asm-um/segment.h
38308 --- orig/include/asm-um/segment.h 1969-12-31 19:00:00.000000000 -0500
38309 +++ um/include/asm-um/segment.h 2002-11-01 19:45:34.000000000 -0500
38311 +#ifndef __UM_SEGMENT_H
38312 +#define __UM_SEGMENT_H
38315 diff -Naur -X ../exclude-files orig/include/asm-um/semaphore.h um/include/asm-um/semaphore.h
38316 --- orig/include/asm-um/semaphore.h 1969-12-31 19:00:00.000000000 -0500
38317 +++ um/include/asm-um/semaphore.h 2003-05-28 11:02:07.000000000 -0400
38319 +#ifndef __UM_SEMAPHORE_H
38320 +#define __UM_SEMAPHORE_H
38322 +#include "asm/arch/semaphore.h"
38325 diff -Naur -X ../exclude-files orig/include/asm-um/sembuf.h um/include/asm-um/sembuf.h
38326 --- orig/include/asm-um/sembuf.h 1969-12-31 19:00:00.000000000 -0500
38327 +++ um/include/asm-um/sembuf.h 2002-10-23 21:08:05.000000000 -0400
38329 +#ifndef __UM_SEMBUF_H
38330 +#define __UM_SEMBUF_H
38332 +#include "asm/arch/sembuf.h"
38335 diff -Naur -X ../exclude-files orig/include/asm-um/serial.h um/include/asm-um/serial.h
38336 --- orig/include/asm-um/serial.h 1969-12-31 19:00:00.000000000 -0500
38337 +++ um/include/asm-um/serial.h 2002-10-23 21:08:05.000000000 -0400
38339 +#ifndef __UM_SERIAL_H
38340 +#define __UM_SERIAL_H
38342 +#include "asm/arch/serial.h"
38345 diff -Naur -X ../exclude-files orig/include/asm-um/shmbuf.h um/include/asm-um/shmbuf.h
38346 --- orig/include/asm-um/shmbuf.h 1969-12-31 19:00:00.000000000 -0500
38347 +++ um/include/asm-um/shmbuf.h 2002-10-23 21:08:05.000000000 -0400
38349 +#ifndef __UM_SHMBUF_H
38350 +#define __UM_SHMBUF_H
38352 +#include "asm/arch/shmbuf.h"
38355 diff -Naur -X ../exclude-files orig/include/asm-um/shmparam.h um/include/asm-um/shmparam.h
38356 --- orig/include/asm-um/shmparam.h 1969-12-31 19:00:00.000000000 -0500
38357 +++ um/include/asm-um/shmparam.h 2002-10-23 21:08:05.000000000 -0400
38359 +#ifndef __UM_SHMPARAM_H
38360 +#define __UM_SHMPARAM_H
38362 +#include "asm/arch/shmparam.h"
38365 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-generic.h um/include/asm-um/sigcontext-generic.h
38366 --- orig/include/asm-um/sigcontext-generic.h 1969-12-31 19:00:00.000000000 -0500
38367 +++ um/include/asm-um/sigcontext-generic.h 2002-10-23 21:08:05.000000000 -0400
38369 +#ifndef __UM_SIGCONTEXT_GENERIC_H
38370 +#define __UM_SIGCONTEXT_GENERIC_H
38372 +#include "asm/arch/sigcontext.h"
38375 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-i386.h um/include/asm-um/sigcontext-i386.h
38376 --- orig/include/asm-um/sigcontext-i386.h 1969-12-31 19:00:00.000000000 -0500
38377 +++ um/include/asm-um/sigcontext-i386.h 2002-10-23 21:08:05.000000000 -0400
38379 +#ifndef __UM_SIGCONTEXT_I386_H
38380 +#define __UM_SIGCONTEXT_I386_H
38382 +#include "asm/sigcontext-generic.h"
38385 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-ppc.h um/include/asm-um/sigcontext-ppc.h
38386 --- orig/include/asm-um/sigcontext-ppc.h 1969-12-31 19:00:00.000000000 -0500
38387 +++ um/include/asm-um/sigcontext-ppc.h 2002-10-23 21:08:05.000000000 -0400
38389 +#ifndef __UM_SIGCONTEXT_PPC_H
38390 +#define __UM_SIGCONTEXT_PPC_H
38392 +#define pt_regs sys_pt_regs
38394 +#include "asm/sigcontext-generic.h"
38399 diff -Naur -X ../exclude-files orig/include/asm-um/siginfo.h um/include/asm-um/siginfo.h
38400 --- orig/include/asm-um/siginfo.h 1969-12-31 19:00:00.000000000 -0500
38401 +++ um/include/asm-um/siginfo.h 2003-05-28 11:02:07.000000000 -0400
38403 +#ifndef __UM_SIGINFO_H
38404 +#define __UM_SIGINFO_H
38406 +#include "asm/arch/siginfo.h"
38409 diff -Naur -X ../exclude-files orig/include/asm-um/signal.h um/include/asm-um/signal.h
38410 --- orig/include/asm-um/signal.h 1969-12-31 19:00:00.000000000 -0500
38411 +++ um/include/asm-um/signal.h 2003-05-28 11:02:07.000000000 -0400
38414 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38415 + * Licensed under the GPL
38418 +#ifndef __UM_SIGNAL_H
38419 +#define __UM_SIGNAL_H
38421 +#include "asm/arch/signal.h"
38426 + * Overrides for Emacs so that we follow Linus's tabbing style.
38427 + * Emacs will notice this stuff at the end of the file and automatically
38428 + * adjust the settings for this buffer only. This must remain at the end
38430 + * ---------------------------------------------------------------------------
38431 + * Local variables:
38432 + * c-file-style: "linux"
38435 diff -Naur -X ../exclude-files orig/include/asm-um/smp.h um/include/asm-um/smp.h
38436 --- orig/include/asm-um/smp.h 1969-12-31 19:00:00.000000000 -0500
38437 +++ um/include/asm-um/smp.h 2003-05-28 11:02:07.000000000 -0400
38439 +#ifndef __UM_SMP_H
38440 +#define __UM_SMP_H
38444 +#include "linux/config.h"
38445 +#include "asm/current.h"
38447 +#define smp_processor_id() (current->processor)
38448 +#define cpu_logical_map(n) (n)
38449 +#define cpu_number_map(n) (n)
38450 +#define PROC_CHANGE_PENALTY 15 /* Pick a number, any number */
38451 +extern int hard_smp_processor_id(void);
38452 +extern unsigned long cpu_online_map;
38453 +#define NO_PROC_ID -1
38458 diff -Naur -X ../exclude-files orig/include/asm-um/smplock.h um/include/asm-um/smplock.h
38459 --- orig/include/asm-um/smplock.h 1969-12-31 19:00:00.000000000 -0500
38460 +++ um/include/asm-um/smplock.h 2003-05-28 11:02:07.000000000 -0400
38462 +#ifndef __UM_SMPLOCK_H
38463 +#define __UM_SMPLOCK_H
38465 +#include "asm/arch/smplock.h"
38468 diff -Naur -X ../exclude-files orig/include/asm-um/socket.h um/include/asm-um/socket.h
38469 --- orig/include/asm-um/socket.h 1969-12-31 19:00:00.000000000 -0500
38470 +++ um/include/asm-um/socket.h 2003-02-27 13:20:13.000000000 -0500
38472 +#ifndef __UM_SOCKET_H
38473 +#define __UM_SOCKET_H
38475 +#include "asm/arch/socket.h"
38478 diff -Naur -X ../exclude-files orig/include/asm-um/sockios.h um/include/asm-um/sockios.h
38479 --- orig/include/asm-um/sockios.h 1969-12-31 19:00:00.000000000 -0500
38480 +++ um/include/asm-um/sockios.h 2002-10-23 21:08:05.000000000 -0400
38482 +#ifndef __UM_SOCKIOS_H
38483 +#define __UM_SOCKIOS_H
38485 +#include "asm/arch/sockios.h"
38488 diff -Naur -X ../exclude-files orig/include/asm-um/softirq.h um/include/asm-um/softirq.h
38489 --- orig/include/asm-um/softirq.h 1969-12-31 19:00:00.000000000 -0500
38490 +++ um/include/asm-um/softirq.h 2003-05-28 11:02:07.000000000 -0400
38492 +#ifndef __UM_SOFTIRQ_H
38493 +#define __UM_SOFTIRQ_H
38495 +#include "linux/smp.h"
38496 +#include "asm/system.h"
38497 +#include "asm/processor.h"
38499 +/* A gratuitous name change */
38500 +#define i386_bh_lock um_bh_lock
38501 +#include "asm/arch/softirq.h"
38502 +#undef i386_bh_lock
38505 diff -Naur -X ../exclude-files orig/include/asm-um/spinlock.h um/include/asm-um/spinlock.h
38506 --- orig/include/asm-um/spinlock.h 1969-12-31 19:00:00.000000000 -0500
38507 +++ um/include/asm-um/spinlock.h 2003-05-28 11:02:07.000000000 -0400
38509 +#ifndef __UM_SPINLOCK_H
38510 +#define __UM_SPINLOCK_H
38512 +#include "linux/config.h"
38515 +#include "asm/arch/spinlock.h"
38519 diff -Naur -X ../exclude-files orig/include/asm-um/statfs.h um/include/asm-um/statfs.h
38520 --- orig/include/asm-um/statfs.h 1969-12-31 19:00:00.000000000 -0500
38521 +++ um/include/asm-um/statfs.h 2003-05-28 11:02:07.000000000 -0400
38523 +#ifndef _UM_STATFS_H
38524 +#define _UM_STATFS_H
38526 +#include "asm/arch/statfs.h"
38529 diff -Naur -X ../exclude-files orig/include/asm-um/stat.h um/include/asm-um/stat.h
38530 --- orig/include/asm-um/stat.h 1969-12-31 19:00:00.000000000 -0500
38531 +++ um/include/asm-um/stat.h 2002-10-23 21:08:05.000000000 -0400
38533 +#ifndef __UM_STAT_H
38534 +#define __UM_STAT_H
38536 +#include "asm/arch/stat.h"
38539 diff -Naur -X ../exclude-files orig/include/asm-um/string.h um/include/asm-um/string.h
38540 --- orig/include/asm-um/string.h 1969-12-31 19:00:00.000000000 -0500
38541 +++ um/include/asm-um/string.h 2003-02-24 22:52:09.000000000 -0500
38543 +#ifndef __UM_STRING_H
38544 +#define __UM_STRING_H
38546 +#include "asm/arch/string.h"
38547 +#include "asm/archparam.h"
38550 diff -Naur -X ../exclude-files orig/include/asm-um/system-generic.h um/include/asm-um/system-generic.h
38551 --- orig/include/asm-um/system-generic.h 1969-12-31 19:00:00.000000000 -0500
38552 +++ um/include/asm-um/system-generic.h 2003-05-28 11:02:07.000000000 -0400
38554 +#ifndef __UM_SYSTEM_GENERIC_H
38555 +#define __UM_SYSTEM_GENERIC_H
38557 +#include "asm/arch/system.h"
38559 +#undef prepare_to_switch
38561 +#undef __save_flags
38563 +#undef __restore_flags
38564 +#undef restore_flags
38569 +#undef local_irq_save
38570 +#undef local_irq_restore
38571 +#undef local_irq_disable
38572 +#undef local_irq_enable
38574 +#define prepare_to_switch() do ; while(0)
38576 +void *_switch_to(void *prev, void *next);
38578 +#define switch_to(prev, next, last) prev = _switch_to(prev, next)
38580 +extern int get_signals(void);
38581 +extern int set_signals(int enable);
38582 +extern void block_signals(void);
38583 +extern void unblock_signals(void);
38585 +#define local_irq_save(flags) do { (flags) = set_signals(0); } while(0)
38587 +#define local_irq_restore(flags) do { set_signals(flags); } while(0)
38589 +#define local_irq_enable() unblock_signals()
38590 +#define local_irq_disable() block_signals()
38592 +#define __sti() unblock_signals()
38593 +#define sti() unblock_signals()
38594 +#define __cli() block_signals()
38595 +#define cli() block_signals()
38597 +#define __save_flags(x) do { (flags) = get_signals(); } while(0)
38598 +#define save_flags(x) __save_flags(x)
38600 +#define __restore_flags(x) local_irq_restore(x)
38601 +#define restore_flags(x) __restore_flags(x)
38604 diff -Naur -X ../exclude-files orig/include/asm-um/system-i386.h um/include/asm-um/system-i386.h
38605 --- orig/include/asm-um/system-i386.h 1969-12-31 19:00:00.000000000 -0500
38606 +++ um/include/asm-um/system-i386.h 2003-05-28 11:02:07.000000000 -0400
38608 +#ifndef __UM_SYSTEM_I386_H
38609 +#define __UM_SYSTEM_I386_H
38611 +#include "asm/system-generic.h"
38613 +#define __HAVE_ARCH_CMPXCHG 1
38615 +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
38616 + unsigned long new, int size)
38618 + unsigned long prev;
38621 + __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
38623 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
38627 + __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
38629 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
38633 + __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
38635 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
38642 +#define cmpxchg(ptr,o,n)\
38643 + ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
38644 + (unsigned long)(n),sizeof(*(ptr))))
38647 diff -Naur -X ../exclude-files orig/include/asm-um/system-ppc.h um/include/asm-um/system-ppc.h
38648 --- orig/include/asm-um/system-ppc.h 1969-12-31 19:00:00.000000000 -0500
38649 +++ um/include/asm-um/system-ppc.h 2002-10-23 21:08:05.000000000 -0400
38651 +#ifndef __UM_SYSTEM_PPC_H
38652 +#define __UM_SYSTEM_PPC_H
38654 +#define _switch_to _ppc_switch_to
38656 +#include "asm/arch/system.h"
38660 +#include "asm/system-generic.h"
38663 diff -Naur -X ../exclude-files orig/include/asm-um/termbits.h um/include/asm-um/termbits.h
38664 --- orig/include/asm-um/termbits.h 1969-12-31 19:00:00.000000000 -0500
38665 +++ um/include/asm-um/termbits.h 2002-10-23 21:11:14.000000000 -0400
38667 +#ifndef __UM_TERMBITS_H
38668 +#define __UM_TERMBITS_H
38670 +#include "asm/arch/termbits.h"
38673 diff -Naur -X ../exclude-files orig/include/asm-um/termios.h um/include/asm-um/termios.h
38674 --- orig/include/asm-um/termios.h 1969-12-31 19:00:00.000000000 -0500
38675 +++ um/include/asm-um/termios.h 2003-02-27 13:20:13.000000000 -0500
38677 +#ifndef __UM_TERMIOS_H
38678 +#define __UM_TERMIOS_H
38680 +#include "asm/arch/termios.h"
38683 diff -Naur -X ../exclude-files orig/include/asm-um/timex.h um/include/asm-um/timex.h
38684 --- orig/include/asm-um/timex.h 1969-12-31 19:00:00.000000000 -0500
38685 +++ um/include/asm-um/timex.h 2003-05-28 11:02:07.000000000 -0400
38687 +#ifndef __UM_TIMEX_H
38688 +#define __UM_TIMEX_H
38690 +#include "linux/time.h"
38692 +typedef unsigned long cycles_t;
38694 +#define cacheflush_time (0)
38696 +static inline cycles_t get_cycles (void)
38701 +#define vxtime_lock() do ; while (0)
38702 +#define vxtime_unlock() do ; while (0)
38705 diff -Naur -X ../exclude-files orig/include/asm-um/tlb.h um/include/asm-um/tlb.h
38706 --- orig/include/asm-um/tlb.h 1969-12-31 19:00:00.000000000 -0500
38707 +++ um/include/asm-um/tlb.h 2002-10-23 21:08:05.000000000 -0400
38709 +#include <asm-generic/tlb.h>
38710 diff -Naur -X ../exclude-files orig/include/asm-um/types.h um/include/asm-um/types.h
38711 --- orig/include/asm-um/types.h 1969-12-31 19:00:00.000000000 -0500
38712 +++ um/include/asm-um/types.h 2002-10-23 21:08:05.000000000 -0400
38714 +#ifndef __UM_TYPES_H
38715 +#define __UM_TYPES_H
38717 +#include "asm/arch/types.h"
38720 diff -Naur -X ../exclude-files orig/include/asm-um/uaccess.h um/include/asm-um/uaccess.h
38721 --- orig/include/asm-um/uaccess.h 1969-12-31 19:00:00.000000000 -0500
38722 +++ um/include/asm-um/uaccess.h 2002-10-23 21:08:05.000000000 -0400
38725 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38726 + * Licensed under the GPL
38729 +#ifndef __UM_UACCESS_H
38730 +#define __UM_UACCESS_H
38732 +#define VERIFY_READ 0
38733 +#define VERIFY_WRITE 1
38736 + * The fs value determines whether argument validity checking should be
38737 + * performed or not. If get_fs() == USER_DS, checking is performed, with
38738 + * get_fs() == KERNEL_DS, checking is bypassed.
38740 + * For historical reasons, these macros are grossly misnamed.
38743 +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
38745 +#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
38746 +#define USER_DS MAKE_MM_SEG(TASK_SIZE)
38748 +#define get_ds() (KERNEL_DS)
38749 +#define get_fs() (current->addr_limit)
38750 +#define set_fs(x) (current->addr_limit = (x))
38752 +#define segment_eq(a, b) ((a).seg == (b).seg)
38754 +#include "um_uaccess.h"
38756 +#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
38758 +#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
38760 +#define __get_user(x, ptr) \
38762 + const __typeof__(ptr) __private_ptr = ptr; \
38763 + __typeof__(*(__private_ptr)) __private_val; \
38764 + int __private_ret = -EFAULT; \
38766 + if (__copy_from_user(&__private_val, (__private_ptr), \
38767 + sizeof(*(__private_ptr))) == 0) {\
38768 + (x) = (__typeof__(*(__private_ptr))) __private_val; \
38769 + __private_ret = 0; \
38774 +#define get_user(x, ptr) \
38776 + const __typeof__((*ptr)) *private_ptr = (ptr); \
38777 + (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \
38778 + __get_user(x, private_ptr) : ((x) = 0, -EFAULT)); \
38781 +#define __put_user(x, ptr) \
38783 + __typeof__(ptr) __private_ptr = ptr; \
38784 + __typeof__(*(__private_ptr)) __private_val; \
38785 + int __private_ret = -EFAULT; \
38786 + __private_val = (__typeof__(*(__private_ptr))) (x); \
38787 + if (__copy_to_user((__private_ptr), &__private_val, \
38788 + sizeof(*(__private_ptr))) == 0) { \
38789 + __private_ret = 0; \
38794 +#define put_user(x, ptr) \
38796 + __typeof__(*(ptr)) *private_ptr = (ptr); \
38797 + (access_ok(VERIFY_WRITE, private_ptr, sizeof(*private_ptr)) ? \
38798 + __put_user(x, private_ptr) : -EFAULT); \
38801 +#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
38803 +struct exception_table_entry
38805 + unsigned long insn;
38806 + unsigned long fixup;
38812 + * Overrides for Emacs so that we follow Linus's tabbing style.
38813 + * Emacs will notice this stuff at the end of the file and automatically
38814 + * adjust the settings for this buffer only. This must remain at the end
38816 + * ---------------------------------------------------------------------------
38817 + * Local variables:
38818 + * c-file-style: "linux"
38821 diff -Naur -X ../exclude-files orig/include/asm-um/ucontext.h um/include/asm-um/ucontext.h
38822 --- orig/include/asm-um/ucontext.h 1969-12-31 19:00:00.000000000 -0500
38823 +++ um/include/asm-um/ucontext.h 2002-12-01 13:20:58.000000000 -0500
38825 +#ifndef _ASM_UM_UCONTEXT_H
38826 +#define _ASM_UM_UCONTEXT_H
38828 +#include "asm/arch/ucontext.h"
38831 diff -Naur -X ../exclude-files orig/include/asm-um/unaligned.h um/include/asm-um/unaligned.h
38832 --- orig/include/asm-um/unaligned.h 1969-12-31 19:00:00.000000000 -0500
38833 +++ um/include/asm-um/unaligned.h 2002-10-23 21:08:05.000000000 -0400
38835 +#ifndef __UM_UNALIGNED_H
38836 +#define __UM_UNALIGNED_H
38838 +#include "asm/arch/unaligned.h"
38841 diff -Naur -X ../exclude-files orig/include/asm-um/unistd.h um/include/asm-um/unistd.h
38842 --- orig/include/asm-um/unistd.h 1969-12-31 19:00:00.000000000 -0500
38843 +++ um/include/asm-um/unistd.h 2003-05-28 11:02:08.000000000 -0400
38846 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
38847 + * Licensed under the GPL
38850 +#ifndef _UM_UNISTD_H_
38851 +#define _UM_UNISTD_H_
38853 +#include "linux/resource.h"
38854 +#include "asm/uaccess.h"
38856 +extern long sys_open(const char *filename, int flags, int mode);
38857 +extern long sys_dup(unsigned int fildes);
38858 +extern long sys_close(unsigned int fd);
38859 +extern int um_execve(const char *file, char *const argv[], char *const env[]);
38860 +extern long sys_setsid(void);
38861 +extern long sys_waitpid(pid_t pid, unsigned int * stat_addr, int options);
38862 +extern long sys_wait4(pid_t pid,unsigned int *stat_addr, int options,
38863 + struct rusage *ru);
38864 +extern long sys_mount(char *dev_name, char *dir_name, char *type,
38865 + unsigned long flags, void *data);
38866 +extern long sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp,
38867 + struct timeval *tvp);
38868 +extern long sys_lseek(unsigned int fildes, unsigned long offset, int whence);
38869 +extern long sys_read(unsigned int fildes, char *buf, int len);
38870 +extern long sys_write(unsigned int fildes, char *buf, int len);
38872 +#ifdef __KERNEL_SYSCALLS__
38874 +#define KERNEL_CALL(ret_t, sys, args...) \
38875 + mm_segment_t fs = get_fs(); \
38877 + set_fs(KERNEL_DS); \
38878 + ret = sys(args); \
38882 +static inline long open(const char *pathname, int flags, int mode)
38884 + KERNEL_CALL(int, sys_open, pathname, flags, mode)
38887 +static inline long dup(unsigned int fd)
38889 + KERNEL_CALL(int, sys_dup, fd);
38892 +static inline long close(unsigned int fd)
38894 + KERNEL_CALL(int, sys_close, fd);
38897 +static inline int execve(const char *filename, char *const argv[],
38898 + char *const envp[])
38900 + KERNEL_CALL(int, um_execve, filename, argv, envp);
38903 +static inline long waitpid(pid_t pid, unsigned int *status, int options)
38905 + KERNEL_CALL(pid_t, sys_wait4, pid, status, options, NULL)
38908 +static inline pid_t wait(int *status)
38910 + KERNEL_CALL(pid_t, sys_wait4, -1, status, 0, NULL)
38913 +static inline pid_t setsid(void)
38915 + KERNEL_CALL(pid_t, sys_setsid)
38918 +static inline long lseek(unsigned int fd, off_t offset, unsigned int whence)
38920 + KERNEL_CALL(long, sys_lseek, fd, offset, whence)
38923 +static inline int read(unsigned int fd, char * buf, int len)
38925 + KERNEL_CALL(int, sys_read, fd, buf, len)
38928 +static inline int write(unsigned int fd, char * buf, int len)
38930 + KERNEL_CALL(int, sys_write, fd, buf, len)
38935 +/* Save the value of __KERNEL_SYSCALLS__, undefine it, include the underlying
38936 + * arch's unistd.h for the system call numbers, and restore the old
38937 + * __KERNEL_SYSCALLS__.
38940 +#ifdef __KERNEL_SYSCALLS__
38941 +#define __SAVE_KERNEL_SYSCALLS__ __KERNEL_SYSCALLS__
38944 +#undef __KERNEL_SYSCALLS__
38945 +#include "asm/arch/unistd.h"
38947 +#ifdef __KERNEL_SYSCALLS__
38948 +#define __KERNEL_SYSCALLS__ __SAVE_KERNEL_SYSCALLS__
38954 + * Overrides for Emacs so that we follow Linus's tabbing style.
38955 + * Emacs will notice this stuff at the end of the file and automatically
38956 + * adjust the settings for this buffer only. This must remain at the end
38958 + * ---------------------------------------------------------------------------
38959 + * Local variables:
38960 + * c-file-style: "linux"
38963 diff -Naur -X ../exclude-files orig/include/asm-um/user.h um/include/asm-um/user.h
38964 --- orig/include/asm-um/user.h 1969-12-31 19:00:00.000000000 -0500
38965 +++ um/include/asm-um/user.h 2003-05-28 11:04:47.000000000 -0400
38967 +#ifndef __UM_USER_H
38968 +#define __UM_USER_H
38970 +#include "asm/arch/user.h"
38973 diff -Naur -X ../exclude-files orig/include/asm-um/vga.h um/include/asm-um/vga.h
38974 --- orig/include/asm-um/vga.h 1969-12-31 19:00:00.000000000 -0500
38975 +++ um/include/asm-um/vga.h 2002-10-23 21:08:05.000000000 -0400
38977 +#ifndef __UM_VGA_H
38978 +#define __UM_VGA_H
38980 +#include "asm/arch/vga.h"
38983 diff -Naur -X ../exclude-files orig/include/asm-um/xor.h um/include/asm-um/xor.h
38984 --- orig/include/asm-um/xor.h 1969-12-31 19:00:00.000000000 -0500
38985 +++ um/include/asm-um/xor.h 2002-10-23 21:08:05.000000000 -0400
38987 +#ifndef __UM_XOR_H
38988 +#define __UM_XOR_H
38990 +#include "asm-generic/xor.h"
38993 diff -Naur -X ../exclude-files orig/include/linux/blk.h um/include/linux/blk.h
38994 --- orig/include/linux/blk.h 2002-09-15 12:13:19.000000000 -0400
38995 +++ um/include/linux/blk.h 2003-05-28 11:02:34.000000000 -0400
38996 @@ -320,6 +320,15 @@
38997 #define DEVICE_REQUEST do_ida_request
38998 #define DEVICE_NR(device) (MINOR(device) >> 4)
39000 +#elif (MAJOR_NR == UBD_MAJOR)
39002 +#define DEVICE_NAME "User-mode block device"
39003 +#define DEVICE_INTR do_ubd
39004 +#define DEVICE_REQUEST do_ubd_request
39005 +#define DEVICE_NR(device) (MINOR(device) >> UBD_SHIFT)
39006 +#define DEVICE_ON(device)
39007 +#define DEVICE_OFF(device)
39009 #endif /* MAJOR_NR == whatever */
39011 /* provide DEVICE_xxx defaults, if not explicitly defined
39012 diff -Naur -X ../exclude-files orig/include/linux/fs.h um/include/linux/fs.h
39013 --- orig/include/linux/fs.h 2003-02-27 13:04:27.000000000 -0500
39014 +++ um/include/linux/fs.h 2003-05-28 11:02:07.000000000 -0400
39015 @@ -318,6 +318,8 @@
39016 #include <linux/ncp_fs_i.h>
39017 #include <linux/proc_fs_i.h>
39018 #include <linux/usbdev_fs_i.h>
39019 +#include <linux/hostfs_fs_i.h>
39020 +#include <linux/hppfs_fs_i.h>
39021 #include <linux/jffs2_fs_i.h>
39022 #include <linux/cramfs_fs_sb.h>
39024 @@ -509,7 +511,9 @@
39025 struct proc_inode_info proc_i;
39026 struct socket socket_i;
39027 struct usbdev_inode_info usbdev_i;
39028 - struct jffs2_inode_info jffs2_i;
39029 + struct hostfs_inode_info hostfs_i;
39030 + struct hppfs_inode_info hppfs_i;
39031 + struct jffs2_inode_info jffs2_i;
39035 diff -Naur -X ../exclude-files orig/include/linux/hostfs_fs_i.h um/include/linux/hostfs_fs_i.h
39036 --- orig/include/linux/hostfs_fs_i.h 1969-12-31 19:00:00.000000000 -0500
39037 +++ um/include/linux/hostfs_fs_i.h 2002-10-23 21:08:05.000000000 -0400
39039 +#ifndef _HOSTFS_FS_I
39040 +#define _HOSTFS_FS_I
39042 +struct hostfs_inode_info {
39043 + char *host_filename;
39051 + * Overrides for Emacs so that we follow Linus's tabbing style.
39052 + * Emacs will notice this stuff at the end of the file and automatically
39053 + * adjust the settings for this buffer only. This must remain at the end
39055 + * ---------------------------------------------------------------------------
39056 + * Local variables:
39057 + * c-file-style: "linux"
39060 diff -Naur -X ../exclude-files orig/include/linux/hppfs_fs_i.h um/include/linux/hppfs_fs_i.h
39061 --- orig/include/linux/hppfs_fs_i.h 1969-12-31 19:00:00.000000000 -0500
39062 +++ um/include/linux/hppfs_fs_i.h 2002-10-23 21:08:05.000000000 -0400
39064 +#ifndef _HPPFS_FS_I
39065 +#define _HPPFS_FS_I
39067 +struct hppfs_inode_info {
39068 + struct dentry *proc_dentry;
39074 + * Overrides for Emacs so that we follow Linus's tabbing style.
39075 + * Emacs will notice this stuff at the end of the file and automatically
39076 + * adjust the settings for this buffer only. This must remain at the end
39078 + * ---------------------------------------------------------------------------
39079 + * Local variables:
39080 + * c-file-style: "linux"
39083 diff -Naur -X ../exclude-files orig/include/linux/kernel.h um/include/linux/kernel.h
39084 --- orig/include/linux/kernel.h 2003-02-27 13:04:27.000000000 -0500
39085 +++ um/include/linux/kernel.h 2003-05-28 11:02:07.000000000 -0400
39087 # define ATTRIB_NORET __attribute__((noreturn))
39088 # define NORET_AND noreturn,
39091 +#if defined(__i386__) || defined(UM_FASTCALL)
39092 #define FASTCALL(x) x __attribute__((regparm(3)))
39094 #define FASTCALL(x) x
39095 diff -Naur -X ../exclude-files orig/include/linux/kernel_stat.h um/include/linux/kernel_stat.h
39096 --- orig/include/linux/kernel_stat.h 2003-02-27 13:04:27.000000000 -0500
39097 +++ um/include/linux/kernel_stat.h 2003-05-28 11:02:07.000000000 -0400
39099 * used by rstatd/perfmeter
39102 -#define DK_MAX_MAJOR 16
39103 +#define DK_MAX_MAJOR 99
39104 #define DK_MAX_DISK 16
39106 struct kernel_stat {
39107 diff -Naur -X ../exclude-files orig/include/linux/mm.h um/include/linux/mm.h
39108 --- orig/include/linux/mm.h 2002-09-15 12:13:19.000000000 -0400
39109 +++ um/include/linux/mm.h 2003-05-28 11:02:07.000000000 -0400
39110 @@ -425,6 +425,14 @@
39111 extern struct page * FASTCALL(__alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist));
39112 extern struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order);
39114 +#ifndef HAVE_ARCH_VALIDATE
39115 +static inline struct page *arch_validate(struct page *page,
39116 + unsigned int gfp_mask, int order)
39122 static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
39125 @@ -432,7 +440,7 @@
39127 if (order >= MAX_ORDER)
39129 - return _alloc_pages(gfp_mask, order);
39130 + return arch_validate(_alloc_pages(gfp_mask, order), gfp_mask, order);
39133 #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
39134 @@ -492,6 +500,9 @@
39135 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
39136 int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
39138 +extern long do_mprotect(struct mm_struct *mm, unsigned long start,
39139 + size_t len, unsigned long prot);
39142 * On a two-level page table, this ends up being trivial. Thus the
39143 * inlining and the symmetry break with pte_alloc() that does all
39144 @@ -539,9 +550,10 @@
39146 extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
39148 -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
39149 - unsigned long len, unsigned long prot,
39150 - unsigned long flag, unsigned long pgoff);
39151 +extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file,
39152 + unsigned long addr, unsigned long len,
39153 + unsigned long prot, unsigned long flag,
39154 + unsigned long pgoff);
39156 static inline unsigned long do_mmap(struct file *file, unsigned long addr,
39157 unsigned long len, unsigned long prot,
39158 @@ -551,7 +563,8 @@
39159 if ((offset + PAGE_ALIGN(len)) < offset)
39161 if (!(offset & ~PAGE_MASK))
39162 - ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
39163 + ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag,
39164 + offset >> PAGE_SHIFT);
39168 diff -Naur -X ../exclude-files orig/include/linux/proc_mm.h um/include/linux/proc_mm.h
39169 --- orig/include/linux/proc_mm.h 1969-12-31 19:00:00.000000000 -0500
39170 +++ um/include/linux/proc_mm.h 2003-05-28 11:03:43.000000000 -0400
39173 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39174 + * Licensed under the GPL
39177 +#ifndef __PROC_MM_H
39178 +#define __PROC_MM_H
39180 +#include "linux/sched.h"
39182 +#define MM_MMAP 54
39183 +#define MM_MUNMAP 55
39184 +#define MM_MPROTECT 56
39185 +#define MM_COPY_SEGMENTS 57
39188 + unsigned long addr;
39189 + unsigned long len;
39190 + unsigned long prot;
39191 + unsigned long flags;
39192 + unsigned long fd;
39193 + unsigned long offset;
39196 +struct mm_munmap {
39197 + unsigned long addr;
39198 + unsigned long len;
39201 +struct mm_mprotect {
39202 + unsigned long addr;
39203 + unsigned long len;
39204 + unsigned int prot;
39207 +struct proc_mm_op {
39210 + struct mm_mmap mmap;
39211 + struct mm_munmap munmap;
39212 + struct mm_mprotect mprotect;
39213 + int copy_segments;
39217 +extern struct mm_struct *proc_mm_get_mm(int fd);
39220 diff -Naur -X ../exclude-files orig/include/linux/tty.h um/include/linux/tty.h
39221 --- orig/include/linux/tty.h 2003-02-27 13:04:28.000000000 -0500
39222 +++ um/include/linux/tty.h 2003-05-28 11:02:07.000000000 -0400
39223 @@ -309,6 +309,9 @@
39224 spinlock_t read_lock;
39225 /* If the tty has a pending do_SAK, queue it here - akpm */
39226 struct tq_struct SAK_tq;
39227 +#ifdef CONFIG_TTY_LOG
39232 /* tty magic number */
39233 @@ -366,6 +369,7 @@
39234 extern int specialix_init(void);
39235 extern int espserial_init(void);
39236 extern int macserial_init(void);
39237 +extern int stdio_init(void);
39238 extern int a2232board_init(void);
39240 extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
39241 @@ -421,5 +425,7 @@
39242 extern int vt_ioctl(struct tty_struct *tty, struct file * file,
39243 unsigned int cmd, unsigned long arg);
39245 +extern void stdio_console_init(void);
39247 #endif /* __KERNEL__ */
39249 diff -Naur -X ../exclude-files orig/init/do_mounts.c um/init/do_mounts.c
39250 --- orig/init/do_mounts.c 2003-02-27 13:04:28.000000000 -0500
39251 +++ um/init/do_mounts.c 2003-02-27 13:05:27.000000000 -0500
39252 @@ -153,6 +153,22 @@
39254 { "apblock", APBLOCK_MAJOR << 8},
39255 { "ddv", DDV_MAJOR << 8},
39256 + { "ubd0", UBD_MAJOR << 8 | 0 << 4},
39257 + { "ubda", UBD_MAJOR << 8 | 0 << 4},
39258 + { "ubd1", UBD_MAJOR << 8 | 1 << 4},
39259 + { "ubdb", UBD_MAJOR << 8 | 1 << 4},
39260 + { "ubd2", UBD_MAJOR << 8 | 2 << 4},
39261 + { "ubdc", UBD_MAJOR << 8 | 2 << 4},
39262 + { "ubd3", UBD_MAJOR << 8 | 3 << 4},
39263 + { "ubdd", UBD_MAJOR << 8 | 3 << 4},
39264 + { "ubd4", UBD_MAJOR << 8 | 4 << 4},
39265 + { "ubde", UBD_MAJOR << 8 | 4 << 4},
39266 + { "ubd5", UBD_MAJOR << 8 | 5 << 4},
39267 + { "ubdf", UBD_MAJOR << 8 | 5 << 4},
39268 + { "ubd6", UBD_MAJOR << 8 | 6 << 4},
39269 + { "ubdg", UBD_MAJOR << 8 | 6 << 4},
39270 + { "ubd7", UBD_MAJOR << 8 | 7 << 4},
39271 + { "ubdh", UBD_MAJOR << 8 | 7 << 4},
39272 { "jsfd", JSFD_MAJOR << 8},
39273 #if defined(CONFIG_ARCH_S390)
39274 { "dasda", (DASD_MAJOR << MINORBITS) },
39275 diff -Naur -X ../exclude-files orig/kernel/panic.c um/kernel/panic.c
39276 --- orig/kernel/panic.c 2003-02-27 13:04:29.000000000 -0500
39277 +++ um/kernel/panic.c 2003-02-27 13:05:27.000000000 -0500
39282 - notifier_call_chain(&panic_notifier_list, 0, NULL);
39283 + notifier_call_chain(&panic_notifier_list, 0, buf);
39285 if (panic_timeout > 0)
39287 diff -Naur -X ../exclude-files orig/MAINTAINERS um/MAINTAINERS
39288 --- orig/MAINTAINERS 2003-02-27 13:04:12.000000000 -0500
39289 +++ um/MAINTAINERS 2003-02-27 13:05:17.000000000 -0500
39290 @@ -1841,6 +1841,14 @@
39291 L: linux-usb-devel@lists.sourceforge.net
39292 W: http://usb.in.tum.de
39297 +M: jdike@karaya.com
39298 +L: user-mode-linux-devel@lists.sourceforge.net
39299 +L: user-mode-linux-user@lists.sourceforge.net
39300 +W: http://user-mode-linux.sourceforge.net
39303 USB "USBNET" DRIVER
39305 diff -Naur -X ../exclude-files orig/Makefile um/Makefile
39306 --- orig/Makefile 2003-02-27 13:04:12.000000000 -0500
39307 +++ um/Makefile 2003-02-27 13:05:17.000000000 -0500
39310 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
39312 -ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
39313 +# SUBARCH tells the usermode build what the underlying arch is. That is set
39314 +# first, and if a usermode build is happening, the "ARCH=um" on the command
39315 +# line overrides the setting of ARCH below. If a native build is happening,
39316 +# then ARCH is assigned, getting whatever value it gets normally, and
39317 +# SUBARCH is subsequently ignored.
39319 +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
39320 +ARCH := $(SUBARCH)
39322 KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
39324 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
39325 diff -Naur -X ../exclude-files orig/mm/Makefile um/mm/Makefile
39326 --- orig/mm/Makefile 2002-08-21 11:47:43.000000000 -0400
39327 +++ um/mm/Makefile 2002-11-08 14:21:36.000000000 -0500
39331 obj-$(CONFIG_HIGHMEM) += highmem.o
39332 +obj-$(CONFIG_PROC_MM) += proc_mm.o
39334 include $(TOPDIR)/Rules.make
39335 diff -Naur -X ../exclude-files orig/mm/mmap.c um/mm/mmap.c
39336 --- orig/mm/mmap.c 2003-02-27 13:04:29.000000000 -0500
39337 +++ um/mm/mmap.c 2003-02-27 13:05:27.000000000 -0500
39338 @@ -390,10 +390,11 @@
39342 -unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned long len,
39343 - unsigned long prot, unsigned long flags, unsigned long pgoff)
39344 +unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file,
39345 + unsigned long addr, unsigned long len,
39346 + unsigned long prot, unsigned long flags,
39347 + unsigned long pgoff)
39349 - struct mm_struct * mm = current->mm;
39350 struct vm_area_struct * vma, * prev;
39351 unsigned int vm_flags;
39352 int correct_wcount = 0;
39353 diff -Naur -X ../exclude-files orig/mm/mprotect.c um/mm/mprotect.c
39354 --- orig/mm/mprotect.c 2002-08-21 11:47:43.000000000 -0400
39355 +++ um/mm/mprotect.c 2002-11-10 20:24:32.000000000 -0500
39356 @@ -264,7 +264,8 @@
39360 -asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
39361 +long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
39362 + unsigned long prot)
39364 unsigned long nstart, end, tmp;
39365 struct vm_area_struct * vma, * next, * prev;
39366 @@ -281,9 +282,9 @@
39370 - down_write(¤t->mm->mmap_sem);
39371 + down_write(&mm->mmap_sem);
39373 - vma = find_vma_prev(current->mm, start, &prev);
39374 + vma = find_vma_prev(mm, start, &prev);
39376 if (!vma || vma->vm_start > start)
39378 @@ -332,6 +333,11 @@
39379 prev->vm_mm->map_count--;
39382 - up_write(¤t->mm->mmap_sem);
39383 + up_write(&mm->mmap_sem);
39387 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
39389 + return(do_mprotect(current->mm, start, len, prot));
39391 diff -Naur -X ../exclude-files orig/mm/proc_mm.c um/mm/proc_mm.c
39392 --- orig/mm/proc_mm.c 1969-12-31 19:00:00.000000000 -0500
39393 +++ um/mm/proc_mm.c 2002-11-19 14:20:26.000000000 -0500
39396 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39397 + * Licensed under the GPL
39400 +#include "linux/init.h"
39401 +#include "linux/proc_fs.h"
39402 +#include "linux/proc_mm.h"
39403 +#include "linux/file.h"
39404 +#include "asm/uaccess.h"
39405 +#include "asm/mmu_context.h"
39407 +static struct file_operations proc_mm_fops;
39409 +struct mm_struct *proc_mm_get_mm(int fd)
39411 + struct mm_struct *ret = ERR_PTR(-EBADF);
39412 + struct file *file;
39418 + ret = ERR_PTR(-EINVAL);
39419 + if(file->f_op != &proc_mm_fops)
39422 + ret = file->private_data;
39429 +extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
39430 + unsigned long len, unsigned long prot,
39431 + unsigned long flags, unsigned long fd,
39432 + unsigned long pgoff);
39434 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
39435 + size_t count, loff_t *ppos)
39437 + struct mm_struct *mm = file->private_data;
39438 + struct proc_mm_op req;
39441 + if(count > sizeof(req))
39444 + n = copy_from_user(&req, buffer, count);
39451 + struct mm_mmap *map = &req.u.mmap;
39453 + ret = do_mmap2(mm, map->addr, map->len, map->prot,
39454 + map->flags, map->fd, map->offset >> PAGE_SHIFT);
39455 + if((ret & ~PAGE_MASK) == 0)
39460 + case MM_MUNMAP: {
39461 + struct mm_munmap *unmap = &req.u.munmap;
39463 + down_write(&mm->mmap_sem);
39464 + ret = do_munmap(mm, unmap->addr, unmap->len);
39465 + up_write(&mm->mmap_sem);
39471 + case MM_MPROTECT: {
39472 + struct mm_mprotect *protect = &req.u.mprotect;
39474 + ret = do_mprotect(mm, protect->addr, protect->len,
39481 + case MM_COPY_SEGMENTS: {
39482 + struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
39484 + if(IS_ERR(from)){
39485 + ret = PTR_ERR(from);
39489 + mm_copy_segments(from, mm);
39500 +static int open_proc_mm(struct inode *inode, struct file *file)
39502 + struct mm_struct *mm = mm_alloc();
39509 + ret = init_new_context(current, mm);
39513 + spin_lock(&mmlist_lock);
39514 + list_add(&mm->mmlist, ¤t->mm->mmlist);
39516 + spin_unlock(&mmlist_lock);
39518 + file->private_data = mm;
39528 +static int release_proc_mm(struct inode *inode, struct file *file)
39530 + struct mm_struct *mm = file->private_data;
39536 +static struct file_operations proc_mm_fops = {
39537 + .open = open_proc_mm,
39538 + .release = release_proc_mm,
39539 + .write = write_proc_mm,
39542 +static int make_proc_mm(void)
39544 + struct proc_dir_entry *ent;
39546 + ent = create_proc_entry("mm", 0222, &proc_root);
39548 + printk("make_proc_mm : Failed to register /proc/mm\n");
39551 + ent->proc_fops = &proc_mm_fops;
39556 +__initcall(make_proc_mm);
39559 + * Overrides for Emacs so that we follow Linus's tabbing style.
39560 + * Emacs will notice this stuff at the end of the file and automatically
39561 + * adjust the settings for this buffer only. This must remain at the end
39563 + * ---------------------------------------------------------------------------
39564 + * Local variables:
39565 + * c-file-style: "linux"
39568 diff -Naur -X ../exclude-files orig/mm/slab.c um/mm/slab.c
39569 --- orig/mm/slab.c 2003-02-27 13:04:29.000000000 -0500
39570 +++ um/mm/slab.c 2003-02-27 13:05:27.000000000 -0500
39571 @@ -1946,10 +1946,14 @@
39573 name = cachep->name;
39578 + set_fs(KERNEL_DS);
39579 if (__get_user(tmp, name))
39585 seq_printf(m, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
39586 name, active_objs, num_objs, cachep->objsize,