1 diff -Naur -X ../exclude-files orig/CREDITS um/CREDITS
2 --- orig/CREDITS Thu Feb 27 13:04:11 2003
3 +++ um/CREDITS Thu Feb 27 13:05:17 2003
6 W: http://lars.nocrew.org/
7 D: dsp56k device driver
8 +D: ptrace proxy in user mode kernel port
14 W: http://user-mode-linux.sourceforge.net
15 D: User mode kernel port
21 diff -Naur -X ../exclude-files orig/Documentation/Configure.help um/Documentation/Configure.help
22 --- orig/Documentation/Configure.help Thu Feb 27 13:04:11 2003
23 +++ um/Documentation/Configure.help Thu Feb 27 13:05:17 2003
24 @@ -14690,19 +14690,23 @@
25 The module will be called dsbr100.o. If you want to compile it as a
26 module, say M here and read <file:Documentation/modules.txt>.
28 -Always do synchronous disk IO for UBD
29 -CONFIG_BLK_DEV_UBD_SYNC
31 The User-Mode Linux port includes a driver called UBD which will let
32 you access arbitrary files on the host computer as block devices.
33 - Writes to such a block device are not immediately written to the
34 - host's disk; this may cause problems if, for example, the User-Mode
35 - Linux 'Virtual Machine' uses a journalling file system and the host
37 + Unless you know that you do not need such virtual block devices say
40 +Always do synchronous disk IO for UBD
41 +CONFIG_BLK_DEV_UBD_SYNC
42 + Writes to the virtual block device are not immediately written to the host's
43 + disk; this may cause problems if, for example, the User-Mode Linux
44 + 'Virtual Machine' uses a journalling filesystem and the host computer
47 Synchronous operation (i.e. always writing data to the host's disk
48 immediately) is configurable on a per-UBD basis by using a special
49 kernel command line option. Alternatively, you can say Y here to
50 - turn on synchronous operation by default for all block.
51 + turn on synchronous operation by default for all block devices.
53 If you're running a journalling file system (like reiserfs, for
54 example) in your virtual machine, you will want to say Y here. If
55 @@ -14714,6 +14718,7 @@
57 This option enables a debugging interface which allows gdb to debug
58 the kernel without needing to actually attach to kernel threads.
59 + CONFIG_XTERM_CHAN must be enabled in order to enable CONFIG_PT_PROXY.
60 If you want to do kernel debugging, say Y here; otherwise say N.
63 @@ -14908,25 +14913,173 @@
67 - The Slip User-Mode Linux network transport allows a running UML to
68 + The slip User-Mode Linux network transport allows a running UML to
69 network with its host over a point-to-point link. Unlike Ethertap,
70 which can carry any Ethernet frame (and hence even non-IP packets),
71 - the Slip transport can only carry IP packets.
72 + the slip transport can only carry IP packets.
74 - To use this, your host must support Slip devices.
75 + To use this, your host must support slip devices.
77 For more information, see
78 <http://user-mode-linux.sourceforge.net/networking.html>. That site
79 - has examples of the UML command line to use to enable Slip
80 + has examples of the UML command line to use to enable slip
81 networking, and details of a few quirks with it.
83 - The Ethertap Transport is preferred over Slip because of its
84 - limitation. If you prefer Slip, however, say Y here. Otherwise
85 + The Ethertap Transport is preferred over slip because of its
86 + limitations. If you prefer slip, however, say Y here. Otherwise
87 choose the Multicast transport (to network multiple UMLs on
88 multiple hosts), Ethertap (to network with the host and the
89 outside world), and/or the Daemon transport (to network multiple
90 UMLs on a single host). You may choose more than one without
91 conflict. If you don't need UML networking, say N.
95 + The SLiRP User-Mode Linux network transport allows a running UML
96 + to network by invoking a program that can handle SLIP encapsulated
97 + packets. This is commonly (but not limited to) the application
98 + known as SLiRP, a program that can re-socket IP packets back onto
99 + the host on which it is run. Only IP packets are supported,
100 + unlike other network transports that can handle all Ethernet
101 + frames. In general, slirp allows the UML the same IP connectivity
102 + to the outside world that the host user is permitted, and unlike
103 + other transports, SLiRP works without the need of root level
104 + privleges, setuid binaries, or SLIP devices on the host. This
105 + also means not every type of connection is possible, but most
106 + situations can be accomodated with carefully crafted slirp
107 + commands that can be passed along as part of the network device's
108 + setup string. The effect of this transport on the UML is similar
109 + that of a host behind a firewall that masquerades all network
110 + connections passing through it (but is less secure).
112 + To use this you should first have slirp compiled somewhere
113 + accessible on the host, and have read its documentation. If you
114 + don't need UML networking, say N.
116 + Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
118 +Default main console channel initialization
119 +CONFIG_CON_ZERO_CHAN
120 + This is the string describing the channel to which the main console
121 + will be attached by default. This value can be overridden from the
122 + command line. The default value is "fd:0,fd:1", which attaches the
123 + main console to stdin and stdout.
124 + It is safe to leave this unchanged.
126 +Default console channel initialization
128 + This is the string describing the channel to which all consoles
129 + except the main console will be attached by default. This value can
130 + be overridden from the command line. The default value is "xterm",
131 + which brings them up in xterms.
132 + It is safe to leave this unchanged, although you may wish to change
133 + this if you expect the UML that you build to be run in environments
134 + which don't have X or xterm available.
136 +Default serial line channel initialization
138 + This is the string describing the channel to which the serial lines
139 + will be attached by default. This value can be overridden from the
140 + command line. The default value is "pty", which attaches them to
141 + traditional pseudo-terminals.
142 + It is safe to leave this unchanged, although you may wish to change
143 + this if you expect the UML that you build to be run in environments
144 + which don't have a set of /dev/pty* devices.
148 + This is set to the number of layers of UMLs that this UML will be run
149 + in. Normally, this is zero, meaning that it will run directly on the
150 + host. Setting it to one will build a UML that can run inside a UML
151 + that is running on the host. Generally, if you intend this UML to run
152 + inside another UML, set CONFIG_NEST_LEVEL to one more than the host UML.
153 + Note that if the hosting UML has its CONFIG_KERNEL_HALF_GIGS set to
154 + greater than one, then the guest UML should have its CONFIG_NEST_LEVEL
155 + set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
156 + Only change this if you are running nested UMLs.
158 +Kernel address space size (in .5G units)
159 +CONFIG_KERNEL_HALF_GIGS
160 + This determines the amount of address space that UML will allocate for
161 + its own, measured in half Gigabyte units. The default is 1.
162 + Change this only if you need to boot UML with an unusually large amount
163 + of physical memory.
167 + This option enables UML sound support. If enabled, it will pull in
168 + soundcore and the UML hostaudio relay, which acts as a intermediary
169 + between the host's dsp and mixer devices and the UML sound system.
170 + It is safe to say 'Y' here.
174 + This option enables UML SMP support. UML implements virtual SMP by
175 + allowing as many processes to run simultaneously on the host as
176 + there are virtual processors configured. Obviously, if the host is
177 + a uniprocessor, those processes will timeshare, but, inside UML,
178 + will appear to be running simultaneously. If the host is a
179 + multiprocessor, then UML processes may run simultaneously, depending
180 + on the host scheduler.
181 + CONFIG_SMP will be set to whatever this option is set to.
182 + It is safe to leave this unchanged.
184 +file descriptor channel support
186 + This option enables support for attaching UML consoles and serial
187 + lines to already set up file descriptors. Generally, the main
188 + console is attached to file descriptors 0 and 1 (stdin and stdout),
189 + so it would be wise to leave this enabled unless you intend to
190 + attach it to some other host device.
192 +null device channel support
194 + This option enables support for attaching UML consoles and serial
195 + lines to a device similar to /dev/null. Data written to it disappears
196 + and there is never any data to be read.
198 +port channel support
200 + This option enables support for attaching UML consoles and serial
201 + lines to host portals. They may be accessed with 'telnet <host>
202 + <port number>'. Any number of consoles and serial lines may be
203 + attached to a single portal, although what UML device you get when
204 + you telnet to that portal will be unpredictable.
205 + It is safe to say 'Y' here.
209 + This option enables support for attaching UML consoles and serial
210 + lines to host pseudo-terminals. Access to both traditional
211 + pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled
212 + with this option. The assignment of UML devices to host devices
213 + will be announced in the kernel message log.
214 + It is safe to say 'Y' here.
218 + This option enables support for attaching UML consoles and serial
219 + lines to host terminals. Access to both virtual consoles
220 + (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and
221 + /dev/pts/*) are controlled by this option.
222 + It is safe to say 'Y' here.
224 +xterm channel support
226 + This option enables support for attaching UML consoles and serial
227 + lines to xterms. Each UML device so assigned will be brought up in
229 + If you disable this option, then CONFIG_PT_PROXY will be disabled as
230 + well, since UML's gdb currently requires an xterm.
231 + It is safe to say 'Y' here.
235 + This option enables logging of all data going through pseudo-terminals
236 + to the host. This is primarily useful for honeypots, where you want
237 + secure keystroke logging that can't be detected or disabled by root.
238 + Say 'N' unless you are setting up a UML honeypot or otherwise know that
239 + you want this option.
241 Microtek USB scanner support
243 diff -Naur -X ../exclude-files orig/MAINTAINERS um/MAINTAINERS
244 --- orig/MAINTAINERS Thu Feb 27 13:04:12 2003
245 +++ um/MAINTAINERS Thu Feb 27 13:05:17 2003
246 @@ -1841,6 +1841,14 @@
247 L: linux-usb-devel@lists.sourceforge.net
248 W: http://usb.in.tum.de
254 +L: user-mode-linux-devel@lists.sourceforge.net
255 +L: user-mode-linux-user@lists.sourceforge.net
256 +W: http://user-mode-linux.sourceforge.net
261 diff -Naur -X ../exclude-files orig/Makefile um/Makefile
262 --- orig/Makefile Thu Feb 27 13:04:12 2003
263 +++ um/Makefile Thu Feb 27 13:05:17 2003
266 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
268 -ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
269 +# SUBARCH tells the usermode build what the underlying arch is. That is set
270 +# first, and if a usermode build is happening, the "ARCH=um" on the command
271 +# line overrides the setting of ARCH below. If a native build is happening,
272 +# then ARCH is assigned, getting whatever value it gets normally, and
273 +# SUBARCH is subsequently ignored.
275 +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
278 KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
280 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
281 diff -Naur -X ../exclude-files orig/arch/um/Makefile um/arch/um/Makefile
282 --- orig/arch/um/Makefile Wed Dec 31 19:00:00 1969
283 +++ um/arch/um/Makefile Fri Mar 28 21:46:54 2003
286 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
287 +# Licensed under the GPL
290 +OS := $(shell uname -s)
294 +core-y := kernel sys-$(SUBARCH) os-$(OS)
295 +drivers-y := fs drivers
296 +subdir-y := $(core-y) $(drivers-y)
297 +SUBDIRS += $(foreach dir,$(subdir-y),$(ARCH_DIR)/$(dir))
299 +CORE_FILES += $(foreach dir,$(core-y),$(ARCH_DIR)/$(dir)/built-in.o)
300 +DRIVERS += $(foreach dir,$(drivers-y),$(ARCH_DIR)/$(dir)/built-in.o)
302 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
303 +include $(ARCH_DIR)/Makefile-os-$(OS)
305 +MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
306 +MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
308 +ifneq ($(MAKEFILE-y),)
309 + include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
312 +EXTRAVERSION := $(EXTRAVERSION)-4um
314 +include/linux/version.h: arch/$(ARCH)/Makefile
316 +# Recalculate MODLIB to reflect the EXTRAVERSION changes (via KERNELRELEASE)
317 +# The way the toplevel Makefile is written EXTRAVERSION is not supposed
318 +# to be changed outside the toplevel Makefile, but recalculating MODLIB is
319 +# a sufficient workaround until we no longer need architecture dependent
321 +MODLIB := $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
323 +ifeq ($(CONFIG_DEBUGSYM),y)
324 +CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS))
327 +CFLAGS-$(CONFIG_DEBUGSYM) += -g
329 +ARCH_INCLUDE = -I$(TOPDIR)/$(ARCH_DIR)/include
331 +# -Derrno=kernel_errno - This turns all kernel references to errno into
332 +# kernel_errno to separate them from the libc errno. This allows -fno-common
333 +# in CFLAGS. Otherwise, it would cause ld to complain about the two different
336 +CFLAGS += $(ARCH_CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
337 + -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
342 +LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
344 +SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
346 +# These aren't in Makefile-tt because they are needed in the !CONFIG_MODE_TT +
347 +# CONFIG_MODE_SKAS + CONFIG_STATIC_LINK case.
350 +LD_SCRIPT_TT := link.ld
352 +ifeq ($(CONFIG_STATIC_LINK),y)
353 + LINK-y += $(LINK_TT)
354 + LD_SCRIPT-y := $(LD_SCRIPT_TT)
356 +ifeq ($(CONFIG_MODE_TT),y)
357 + LINK-y += $(LINK_TT)
358 + LD_SCRIPT-y := $(LD_SCRIPT_TT)
360 +ifeq ($(CONFIG_MODE_SKAS),y)
361 + LINK-y += $(LINK_SKAS)
362 + LD_SCRIPT-y := $(LD_SCRIPT_SKAS)
367 +LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
368 +M4_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT)
370 +$(LD_SCRIPT-y): $(LD_SCRIPT-y).in
371 + pages=$$(( 1 << $(CONFIG_KERNEL_STACK_ORDER) )) ; \
372 + m4 -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
373 + -DELF_FORMAT=$(ELF_FORMAT) $(M4_MODE_TT) \
374 + -DKERNEL_STACK_SIZE=$$(( 4096 * $$pages )) $< > $@
376 +SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
377 + include/asm-um/sigcontext.h include/asm-um/processor.h \
378 + include/asm-um/ptrace.h include/asm-um/arch-signal.h
380 +ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \
381 + $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
383 +ifeq ($(CONFIG_MODE_SKAS), y)
384 +$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
387 +GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
389 +setup: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS)
391 +linux: setup $(ARCH_DIR)/main.o vmlinux $(LD_SCRIPT-y)
392 + mv vmlinux vmlinux.o
393 + $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
394 + -o linux $(ARCH_DIR)/main.o vmlinux.o -L/usr/lib -lutil
396 +USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
397 +USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
398 +USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
401 +# To get a definition of F_SETSIG
402 +USER_CFLAGS += -D_GNU_SOURCE
404 +CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/link.ld $(ARCH_DIR)/dyn_link.ld \
405 + $(GEN_HEADERS) $(ARCH_DIR)/include/uml-config.h
407 +$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
408 + $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
411 + rm -f $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
412 + $(LD_SCRIPT) $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
415 + find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
416 + -o -name '*.gcov' \) -type f -print | xargs rm -f
418 + for dir in $(subdir-y) util ; do $(MAKE) -C $$dir clean; done
423 + cd $(TOPDIR)/$(dir $@) ; \
424 + ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
426 +include/asm-um/arch:
427 + cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
429 +arch/um/include/sysdep:
430 + cd $(TOPDIR)/arch/um/include && ln -sf sysdep-$(SUBARCH) sysdep
433 + cd $(ARCH_DIR) && ln -sf os-$(OS) os
435 +$(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
438 +$(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
441 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
442 + sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
444 +$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/util/mk_task_user.c \
445 + $(ARCH_DIR)/util/mk_task_kern.c $(SYS_HEADERS)
446 + $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_task
448 +$(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util/mk_constants_user.c \
449 + $(ARCH_DIR)/util/mk_constants_kern.c
450 + $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_constants
452 +export SUBARCH USER_CFLAGS OS
453 diff -Naur -X ../exclude-files orig/arch/um/Makefile-i386 um/arch/um/Makefile-i386
454 --- orig/arch/um/Makefile-i386 Wed Dec 31 19:00:00 1969
455 +++ um/arch/um/Makefile-i386 Wed Oct 23 21:08:04 2002
457 +ifeq ($(CONFIG_HOST_2G_2G), y)
458 +TOP_ADDR = 0x80000000
460 +TOP_ADDR = 0xc0000000
463 +ARCH_CFLAGS = -U__$(SUBARCH)__ -U$(SUBARCH) -DUM_FASTCALL
464 +ELF_ARCH = $(SUBARCH)
465 +ELF_FORMAT = elf32-$(SUBARCH)
467 +I386_H = $(ARCH_DIR)/include/sysdep-i386
468 +SYS = $(ARCH_DIR)/sys-i386
472 +SYS_HEADERS = $(I386_H)/sc.h $(I386_H)/thread.h
474 +$(I386_H)/sc.h : $(UTIL)/mk_sc
477 +$(I386_H)/thread.h : $(UTIL)/mk_thread
478 + $(UTIL)/mk_thread > $@
480 +$(UTIL)/mk_sc : $(UTIL)/mk_sc.c
481 + $(MAKE) -C $(UTIL) mk_sc
483 +$(UTIL)/mk_thread : $(UTIL)/mk_thread_user.c $(UTIL)/mk_thread_kern.c \
485 + $(MAKE) -C $(UTIL) mk_thread
488 + rm -f $(SYS_HEADERS)
489 + $(MAKE) -C $(UTIL) clean
490 + $(MAKE) -C $(SYS) clean
492 diff -Naur -X ../exclude-files orig/arch/um/Makefile-ia64 um/arch/um/Makefile-ia64
493 --- orig/arch/um/Makefile-ia64 Wed Dec 31 19:00:00 1969
494 +++ um/arch/um/Makefile-ia64 Wed Oct 23 21:08:04 2002
496 +START_ADDR = 0x1000000000000000
497 diff -Naur -X ../exclude-files orig/arch/um/Makefile-os-Linux um/arch/um/Makefile-os-Linux
498 --- orig/arch/um/Makefile-os-Linux Wed Dec 31 19:00:00 1969
499 +++ um/arch/um/Makefile-os-Linux Mon Dec 9 14:21:51 2002
502 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
503 +# Licensed under the GPL
506 +SUBDIRS += $(ARCH_DIR)/os-$(OS)/drivers
507 +DRIVERS += $(ARCH_DIR)/os-$(OS)/drivers/drivers.o
508 diff -Naur -X ../exclude-files orig/arch/um/Makefile-ppc um/arch/um/Makefile-ppc
509 --- orig/arch/um/Makefile-ppc Wed Dec 31 19:00:00 1969
510 +++ um/arch/um/Makefile-ppc Wed Oct 23 21:08:04 2002
512 +ifeq ($(CONFIG_HOST_2G_2G), y)
513 +START_ADDR = 0x80000000
515 +START_ADDR = 0xc0000000
517 +ARCH_CFLAGS = -U__powerpc__ -D__UM_PPC__
519 +# The arch is ppc, but the elf32 name is powerpc
520 +ELF_SUBARCH = powerpc
521 diff -Naur -X ../exclude-files orig/arch/um/Makefile-skas um/arch/um/Makefile-skas
522 --- orig/arch/um/Makefile-skas Wed Dec 31 19:00:00 1969
523 +++ um/arch/um/Makefile-skas Sun Dec 15 22:02:57 2002
526 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
527 +# Licensed under the GPL
532 +CFLAGS-$(CONFIG_GCOV) += -fprofile-arcs -ftest-coverage
533 +CFLAGS-$(CONFIG_GPROF) += $(PROFILE)
534 +LINK-$(CONFIG_GPROF) += $(PROFILE)
536 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/skas/include
538 +LINK_SKAS = -Wl,-rpath,/lib
539 +LD_SCRIPT_SKAS = dyn_link.ld
541 +GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
543 +$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
544 + $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
545 diff -Naur -X ../exclude-files orig/arch/um/Makefile-tt um/arch/um/Makefile-tt
546 --- orig/arch/um/Makefile-tt Wed Dec 31 19:00:00 1969
547 +++ um/arch/um/Makefile-tt Mon Dec 16 20:22:23 2002
550 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
551 +# Licensed under the GPL
554 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/tt/include
556 diff -Naur -X ../exclude-files orig/arch/um/common.ld.in um/arch/um/common.ld.in
557 --- orig/arch/um/common.ld.in Wed Dec 31 19:00:00 1969
558 +++ um/arch/um/common.ld.in Tue Feb 4 19:35:13 2003
560 + .kstrtab : { *(.kstrtab) }
562 + . = ALIGN(16); /* Exception table */
563 + __start___ex_table = .;
564 + __ex_table : { *(__ex_table) }
565 + __stop___ex_table = .;
567 + __start___ksymtab = .; /* Kernel symbol table */
568 + __ksymtab : { *(__ksymtab) }
569 + __stop___ksymtab = .;
571 + .unprotected : { *(.unprotected) }
573 + PROVIDE (_unprotected_end = .);
576 + __uml_setup_start = .;
577 + .uml.setup.init : { *(.uml.setup.init) }
578 + __uml_setup_end = .;
579 + __uml_help_start = .;
580 + .uml.help.init : { *(.uml.help.init) }
581 + __uml_help_end = .;
582 + __uml_postsetup_start = .;
583 + .uml.postsetup.init : { *(.uml.postsetup.init) }
584 + __uml_postsetup_end = .;
586 + .setup.init : { *(.setup.init) }
588 + __initcall_start = .;
589 + .initcall.init : { *(.initcall.init) }
590 + __initcall_end = .;
591 + __uml_initcall_start = .;
592 + .uml.initcall.init : { *(.uml.initcall.init) }
593 + __uml_initcall_end = .;
595 + __exitcall_begin = .;
596 + .exitcall : { *(.exitcall.exit) }
597 + __exitcall_end = .;
598 + __uml_exitcall_begin = .;
599 + .uml.exitcall : { *(.uml.exitcall.exit) }
600 + __uml_exitcall_end = .;
602 + __preinit_array_start = .;
603 + .preinit_array : { *(.preinit_array) }
604 + __preinit_array_end = .;
605 + __init_array_start = .;
606 + .init_array : { *(.init_array) }
607 + __init_array_end = .;
608 + __fini_array_start = .;
609 + .fini_array : { *(.fini_array) }
610 + __fini_array_end = .;
612 + .data.init : { *(.data.init) }
613 diff -Naur -X ../exclude-files orig/arch/um/config.in um/arch/um/config.in
614 --- orig/arch/um/config.in Wed Dec 31 19:00:00 1969
615 +++ um/arch/um/config.in Thu Feb 27 13:12:39 2003
617 +define_bool CONFIG_USERMODE y
619 +mainmenu_name "Linux/Usermode Kernel Configuration"
621 +define_bool CONFIG_ISA n
622 +define_bool CONFIG_SBUS n
623 +define_bool CONFIG_PCI n
625 +define_bool CONFIG_UID16 y
627 +define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
629 +mainmenu_option next_comment
630 +comment 'Code maturity level options'
631 +bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
634 +mainmenu_option next_comment
635 +comment 'General Setup'
637 +bool 'Separate kernel address space support' CONFIG_MODE_SKAS
639 +# This is to ensure that at least one of the modes is enabled. When neither
640 +# is present in defconfig, they default to N, which is bad.
641 +if [ "$CONFIG_MODE_SKAS" != "y" ]; then
642 + define_bool CONFIG_MODE_TT y
645 +bool 'Tracing thread support' CONFIG_MODE_TT
646 +if [ "$CONFIG_MODE_TT" != "y" ]; then
647 + bool 'Statically linked binary when CONFIG_MODE_TT is disabled' CONFIG_STATIC_LINK
649 +bool 'Networking support' CONFIG_NET
650 +bool 'System V IPC' CONFIG_SYSVIPC
651 +bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
652 +bool 'Sysctl support' CONFIG_SYSCTL
653 +tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
654 +tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
655 +tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
656 +tristate 'Host filesystem' CONFIG_HOSTFS
657 +tristate 'Honeypot proc filesystem' CONFIG_HPPFS
658 +bool 'Management console' CONFIG_MCONSOLE
659 +dep_bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ $CONFIG_MCONSOLE
660 +bool '2G/2G host address space split' CONFIG_HOST_2G_2G
661 +bool 'Symmetric multi-processing support' CONFIG_UML_SMP
662 +define_bool CONFIG_SMP $CONFIG_UML_SMP
663 +int 'Nesting level' CONFIG_NEST_LEVEL 0
664 +int 'Kernel address space size (in .5G units)' CONFIG_KERNEL_HALF_GIGS 1
665 +bool 'Highmem support' CONFIG_HIGHMEM
666 +bool '/proc/mm' CONFIG_PROC_MM
667 +int 'Kernel stack size order' CONFIG_KERNEL_STACK_ORDER 2
670 +mainmenu_option next_comment
671 +comment 'Loadable module support'
672 +bool 'Enable loadable module support' CONFIG_MODULES
673 +if [ "$CONFIG_MODULES" = "y" ]; then
674 +# MODVERSIONS does not yet work in this architecture
675 +# bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
676 + bool ' Kernel module loader' CONFIG_KMOD
680 +source arch/um/config_char.in
682 +source arch/um/config_block.in
684 +define_bool CONFIG_NETDEVICES $CONFIG_NET
686 +if [ "$CONFIG_NET" = "y" ]; then
687 + source arch/um/config_net.in
688 + source net/Config.in
693 +mainmenu_option next_comment
694 +comment 'SCSI support'
696 +tristate 'SCSI support' CONFIG_SCSI
698 +if [ "$CONFIG_SCSI" != "n" ]; then
699 + source arch/um/config_scsi.in
703 +source drivers/md/Config.in
705 +source drivers/mtd/Config.in
707 +source lib/Config.in
709 +mainmenu_option next_comment
710 +comment 'Kernel hacking'
711 +bool 'Debug memory allocations' CONFIG_DEBUG_SLAB
712 +bool 'Enable kernel debugging symbols' CONFIG_DEBUGSYM
713 +if [ "$CONFIG_XTERM_CHAN" = "y" ]; then
714 + dep_bool 'Enable ptrace proxy' CONFIG_PT_PROXY $CONFIG_DEBUGSYM
716 + define_bool CONFIG_PT_PROXY n
718 +dep_bool 'Enable gprof support' CONFIG_GPROF $CONFIG_DEBUGSYM
719 +dep_bool 'Enable gcov support' CONFIG_GCOV $CONFIG_DEBUGSYM
721 diff -Naur -X ../exclude-files orig/arch/um/config.release um/arch/um/config.release
722 --- orig/arch/um/config.release Wed Dec 31 19:00:00 1969
723 +++ um/arch/um/config.release Wed Oct 23 21:08:04 2002
726 +# Automatically generated make config: don't edit
729 +# CONFIG_ISA is not set
730 +# CONFIG_SBUS is not set
731 +# CONFIG_PCI is not set
733 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
736 +# Code maturity level options
738 +CONFIG_EXPERIMENTAL=y
745 +CONFIG_BSD_PROCESS_ACCT=y
747 +CONFIG_BINFMT_AOUT=y
749 +CONFIG_BINFMT_MISC=y
751 +# CONFIG_HPPFS is not set
753 +CONFIG_MAGIC_SYSRQ=y
754 +# CONFIG_HOST_2G_2G is not set
755 +# CONFIG_UML_SMP is not set
756 +# CONFIG_SMP is not set
758 +CONFIG_KERNEL_HALF_GIGS=1
761 +# Loadable module support
769 +CONFIG_STDIO_CONSOLE=y
772 +# CONFIG_NULL_CHAN is not set
777 +CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
778 +CONFIG_CON_CHAN="xterm"
779 +CONFIG_SSL_CHAN="pty"
780 +CONFIG_UNIX98_PTYS=y
781 +CONFIG_UNIX98_PTY_COUNT=256
782 +# CONFIG_WATCHDOG is not set
786 +# CONFIG_TTY_LOG is not set
791 +CONFIG_BLK_DEV_UBD=y
792 +# CONFIG_BLK_DEV_UBD_SYNC is not set
793 +CONFIG_BLK_DEV_LOOP=y
794 +CONFIG_BLK_DEV_NBD=y
795 +CONFIG_BLK_DEV_RAM=y
796 +CONFIG_BLK_DEV_RAM_SIZE=4096
797 +CONFIG_BLK_DEV_INITRD=y
798 +# CONFIG_MMAPPER is not set
805 +CONFIG_UML_NET_ETHERTAP=y
806 +CONFIG_UML_NET_TUNTAP=y
807 +CONFIG_UML_NET_SLIP=y
808 +CONFIG_UML_NET_DAEMON=y
809 +CONFIG_UML_NET_MCAST=y
815 +CONFIG_PPP_MULTILINK=y
816 +# CONFIG_PPP_ASYNC is not set
817 +CONFIG_PPP_SYNC_TTY=m
818 +CONFIG_PPP_DEFLATE=m
819 +CONFIG_PPP_BSDCOMP=m
824 +# Networking options
827 +CONFIG_PACKET_MMAP=y
828 +# CONFIG_NETLINK_DEV is not set
829 +# CONFIG_NETFILTER is not set
830 +# CONFIG_FILTER is not set
833 +# CONFIG_IP_MULTICAST is not set
834 +# CONFIG_IP_ADVANCED_ROUTER is not set
835 +# CONFIG_IP_PNP is not set
836 +# CONFIG_NET_IPIP is not set
837 +# CONFIG_NET_IPGRE is not set
838 +# CONFIG_ARPD is not set
839 +# CONFIG_INET_ECN is not set
840 +# CONFIG_SYN_COOKIES is not set
841 +# CONFIG_IPV6 is not set
842 +# CONFIG_KHTTPD is not set
843 +# CONFIG_ATM is not set
844 +# CONFIG_VLAN_8021Q is not set
849 +# CONFIG_IPX is not set
850 +# CONFIG_ATALK is not set
855 +# CONFIG_DECNET is not set
856 +# CONFIG_BRIDGE is not set
857 +# CONFIG_X25 is not set
858 +# CONFIG_LAPB is not set
859 +# CONFIG_LLC is not set
860 +# CONFIG_NET_DIVERT is not set
861 +# CONFIG_ECONET is not set
862 +# CONFIG_WAN_ROUTER is not set
863 +# CONFIG_NET_FASTROUTE is not set
864 +# CONFIG_NET_HW_FLOWCONTROL is not set
867 +# QoS and/or fair queueing
869 +# CONFIG_NET_SCHED is not set
874 +# CONFIG_NET_PKTGEN is not set
882 +CONFIG_REISERFS_FS=m
883 +# CONFIG_REISERFS_CHECK is not set
884 +# CONFIG_REISERFS_PROC_INFO is not set
886 +# CONFIG_ADFS_FS_RW is not set
892 +# CONFIG_JBD_DEBUG is not set
902 +# CONFIG_JOLIET is not set
903 +# CONFIG_ZISOFS is not set
906 +# CONFIG_NTFS_FS is not set
910 +CONFIG_DEVFS_MOUNT=y
911 +# CONFIG_DEVFS_DEBUG is not set
914 +# CONFIG_QNX4FS_RW is not set
919 +# CONFIG_UDF_RW is not set
921 +# CONFIG_UFS_FS_WRITE is not set
924 +# Network File Systems
926 +# CONFIG_CODA_FS is not set
927 +# CONFIG_INTERMEZZO_FS is not set
935 +# CONFIG_SMB_FS is not set
936 +# CONFIG_NCP_FS is not set
937 +# CONFIG_ZISOFS_FS is not set
938 +CONFIG_ZLIB_FS_INFLATE=m
943 +# CONFIG_PARTITION_ADVANCED is not set
944 +CONFIG_MSDOS_PARTITION=y
945 +# CONFIG_SMB_NLS is not set
949 +# Native Language Support
951 +CONFIG_NLS_DEFAULT="iso8859-1"
952 +# CONFIG_NLS_CODEPAGE_437 is not set
953 +# CONFIG_NLS_CODEPAGE_737 is not set
954 +# CONFIG_NLS_CODEPAGE_775 is not set
955 +# CONFIG_NLS_CODEPAGE_850 is not set
956 +# CONFIG_NLS_CODEPAGE_852 is not set
957 +# CONFIG_NLS_CODEPAGE_855 is not set
958 +# CONFIG_NLS_CODEPAGE_857 is not set
959 +# CONFIG_NLS_CODEPAGE_860 is not set
960 +# CONFIG_NLS_CODEPAGE_861 is not set
961 +# CONFIG_NLS_CODEPAGE_862 is not set
962 +# CONFIG_NLS_CODEPAGE_863 is not set
963 +# CONFIG_NLS_CODEPAGE_864 is not set
964 +# CONFIG_NLS_CODEPAGE_865 is not set
965 +# CONFIG_NLS_CODEPAGE_866 is not set
966 +# CONFIG_NLS_CODEPAGE_869 is not set
967 +# CONFIG_NLS_CODEPAGE_936 is not set
968 +# CONFIG_NLS_CODEPAGE_950 is not set
969 +# CONFIG_NLS_CODEPAGE_932 is not set
970 +# CONFIG_NLS_CODEPAGE_949 is not set
971 +# CONFIG_NLS_CODEPAGE_874 is not set
972 +# CONFIG_NLS_ISO8859_8 is not set
973 +# CONFIG_NLS_CODEPAGE_1250 is not set
974 +# CONFIG_NLS_CODEPAGE_1251 is not set
975 +# CONFIG_NLS_ISO8859_1 is not set
976 +# CONFIG_NLS_ISO8859_2 is not set
977 +# CONFIG_NLS_ISO8859_3 is not set
978 +# CONFIG_NLS_ISO8859_4 is not set
979 +# CONFIG_NLS_ISO8859_5 is not set
980 +# CONFIG_NLS_ISO8859_6 is not set
981 +# CONFIG_NLS_ISO8859_7 is not set
982 +# CONFIG_NLS_ISO8859_9 is not set
983 +# CONFIG_NLS_ISO8859_13 is not set
984 +# CONFIG_NLS_ISO8859_14 is not set
985 +# CONFIG_NLS_ISO8859_15 is not set
986 +# CONFIG_NLS_KOI8_R is not set
987 +# CONFIG_NLS_KOI8_U is not set
988 +# CONFIG_NLS_UTF8 is not set
996 +# SCSI support type (disk, tape, CD-ROM)
998 +# CONFIG_BLK_DEV_SD is not set
999 +# CONFIG_CHR_DEV_ST is not set
1000 +# CONFIG_BLK_DEV_SR is not set
1001 +# CONFIG_CHR_DEV_SG is not set
1004 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
1006 +# CONFIG_SCSI_DEBUG_QUEUES is not set
1007 +# CONFIG_SCSI_MULTI_LUN is not set
1008 +# CONFIG_SCSI_CONSTANTS is not set
1009 +# CONFIG_SCSI_LOGGING is not set
1010 +CONFIG_SCSI_DEBUG=m
1013 +# Multi-device support (RAID and LVM)
1015 +# CONFIG_MD is not set
1018 +# Memory Technology Devices (MTD)
1020 +# CONFIG_MTD is not set
1025 +# CONFIG_DEBUG_SLAB is not set
1026 +# CONFIG_DEBUGSYM is not set
1027 diff -Naur -X ../exclude-files orig/arch/um/config_block.in um/arch/um/config_block.in
1028 --- orig/arch/um/config_block.in Wed Dec 31 19:00:00 1969
1029 +++ um/arch/um/config_block.in Wed Oct 23 21:08:04 2002
1031 +mainmenu_option next_comment
1032 +comment 'Block Devices'
1034 +bool 'Virtual block device' CONFIG_BLK_DEV_UBD
1035 +dep_bool ' Always do synchronous disk IO for UBD' CONFIG_BLK_DEV_UBD_SYNC $CONFIG_BLK_DEV_UBD
1036 +tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
1037 +dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
1038 +tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
1039 +if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
1040 + int ' Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
1042 +dep_bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM
1044 +tristate 'Example IO memory driver' CONFIG_MMAPPER
1047 diff -Naur -X ../exclude-files orig/arch/um/config_char.in um/arch/um/config_char.in
1048 --- orig/arch/um/config_char.in Wed Dec 31 19:00:00 1969
1049 +++ um/arch/um/config_char.in Wed Oct 23 21:08:04 2002
1051 +mainmenu_option next_comment
1052 +comment 'Character Devices'
1054 +define_bool CONFIG_STDIO_CONSOLE y
1056 +bool 'Virtual serial line' CONFIG_SSL
1058 +bool 'file descriptor channel support' CONFIG_FD_CHAN
1059 +bool 'null channel support' CONFIG_NULL_CHAN
1060 +bool 'port channel support' CONFIG_PORT_CHAN
1061 +bool 'pty channel support' CONFIG_PTY_CHAN
1062 +bool 'tty channel support' CONFIG_TTY_CHAN
1063 +bool 'xterm channel support' CONFIG_XTERM_CHAN
1064 +string 'Default main console channel initialization' CONFIG_CON_ZERO_CHAN \
1066 +string 'Default console channel initialization' CONFIG_CON_CHAN "xterm"
1067 +string 'Default serial line channel initialization' CONFIG_SSL_CHAN "pty"
1070 +bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
1071 +if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
1072 + int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
1075 +bool 'Watchdog Timer Support' CONFIG_WATCHDOG
1076 +dep_bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT \
1078 +dep_tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG $CONFIG_WATCHDOG
1079 +dep_tristate ' UML watchdog' CONFIG_UML_WATCHDOG $CONFIG_WATCHDOG
1081 +tristate 'Sound support' CONFIG_UML_SOUND
1082 +define_tristate CONFIG_SOUND $CONFIG_UML_SOUND
1083 +define_tristate CONFIG_HOSTAUDIO $CONFIG_UML_SOUND
1085 +bool 'Enable tty logging' CONFIG_TTY_LOG
1088 diff -Naur -X ../exclude-files orig/arch/um/config_net.in um/arch/um/config_net.in
1089 --- orig/arch/um/config_net.in Wed Dec 31 19:00:00 1969
1090 +++ um/arch/um/config_net.in Wed Oct 23 21:08:04 2002
1092 +mainmenu_option next_comment
1093 +comment 'Network Devices'
1095 +# UML virtual driver
1096 +bool 'Virtual network device' CONFIG_UML_NET
1098 +dep_bool ' Ethertap transport' CONFIG_UML_NET_ETHERTAP $CONFIG_UML_NET
1099 +dep_bool ' TUN/TAP transport' CONFIG_UML_NET_TUNTAP $CONFIG_UML_NET
1100 +dep_bool ' SLIP transport' CONFIG_UML_NET_SLIP $CONFIG_UML_NET
1101 +dep_bool ' SLiRP transport' CONFIG_UML_NET_SLIRP $CONFIG_UML_NET
1102 +dep_bool ' Daemon transport' CONFIG_UML_NET_DAEMON $CONFIG_UML_NET
1103 +dep_bool ' Multicast transport' CONFIG_UML_NET_MCAST $CONFIG_UML_NET
1104 +dep_bool ' pcap transport' CONFIG_UML_NET_PCAP $CONFIG_UML_NET
1106 +# Below are hardware-independent drivers mirrored from
1107 +# drivers/net/Config.in. It would be nice if Linux
1108 +# had HW independent drivers separated from the other
1109 +# but it does not. Until then each non-ISA/PCI arch
1110 +# needs to provide it's own menu of network drivers
1112 +tristate 'Dummy net driver support' CONFIG_DUMMY
1113 +tristate 'Bonding driver support' CONFIG_BONDING
1114 +tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
1115 +tristate 'Universal TUN/TAP device driver support' CONFIG_TUN
1116 +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
1117 + if [ "$CONFIG_NETLINK" = "y" ]; then
1118 + tristate 'Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP
1122 +tristate 'PPP (point-to-point protocol) support' CONFIG_PPP
1123 +if [ ! "$CONFIG_PPP" = "n" ]; then
1124 + dep_bool ' PPP multilink support (EXPERIMENTAL)' CONFIG_PPP_MULTILINK $CONFIG_EXPERIMENTAL
1125 + dep_bool ' PPP filtering' CONFIG_PPP_FILTER $CONFIG_FILTER
1126 + dep_tristate ' PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP
1127 + dep_tristate ' PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
1128 + dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
1129 + dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP
1130 + dep_tristate ' PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP $CONFIG_EXPERIMENTAL
1133 +tristate 'SLIP (serial line) support' CONFIG_SLIP
1134 +dep_bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED $CONFIG_SLIP
1135 +dep_bool ' Keepalive and linefill' CONFIG_SLIP_SMART $CONFIG_SLIP
1136 +dep_bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 $CONFIG_SLIP
1139 diff -Naur -X ../exclude-files orig/arch/um/config_scsi.in um/arch/um/config_scsi.in
1140 --- orig/arch/um/config_scsi.in Wed Dec 31 19:00:00 1969
1141 +++ um/arch/um/config_scsi.in Wed Oct 23 21:08:04 2002
1143 +comment 'SCSI support type (disk, tape, CD-ROM)'
1145 +dep_tristate ' SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
1147 +if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then
1148 + int 'Maximum number of SCSI disks that can be loaded as modules' CONFIG_SD_EXTRA_DEVS 40
1151 +dep_tristate ' SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
1153 +dep_tristate ' SCSI CD-ROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
1155 +if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
1156 + bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
1157 + int 'Maximum number of CDROM devices that can be loaded as modules' CONFIG_SR_EXTRA_DEVS 2
1159 +dep_tristate ' SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
1161 +comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
1163 +#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
1164 + bool ' Enable extra checks in new queueing code' CONFIG_SCSI_DEBUG_QUEUES
1167 +bool ' Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
1169 +bool ' Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
1170 +bool ' SCSI logging facility' CONFIG_SCSI_LOGGING
1172 +dep_tristate 'SCSI debugging host simulator (EXPERIMENTAL)' CONFIG_SCSI_DEBUG $CONFIG_SCSI
1173 diff -Naur -X ../exclude-files orig/arch/um/defconfig um/arch/um/defconfig
1174 --- orig/arch/um/defconfig Wed Dec 31 19:00:00 1969
1175 +++ um/arch/um/defconfig Mon Jan 20 11:26:54 2003
1178 +# Automatically generated make config: don't edit
1181 +# CONFIG_ISA is not set
1182 +# CONFIG_SBUS is not set
1183 +# CONFIG_PCI is not set
1185 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
1188 +# Code maturity level options
1190 +CONFIG_EXPERIMENTAL=y
1199 +CONFIG_BSD_PROCESS_ACCT=y
1201 +CONFIG_BINFMT_AOUT=y
1202 +CONFIG_BINFMT_ELF=y
1203 +CONFIG_BINFMT_MISC=y
1207 +CONFIG_MAGIC_SYSRQ=y
1208 +# CONFIG_HOST_2G_2G is not set
1209 +# CONFIG_UML_SMP is not set
1210 +# CONFIG_SMP is not set
1211 +CONFIG_NEST_LEVEL=0
1212 +CONFIG_KERNEL_HALF_GIGS=1
1213 +# CONFIG_HIGHMEM is not set
1215 +CONFIG_KERNEL_STACK_ORDER=2
1218 +# Loadable module support
1221 +# CONFIG_KMOD is not set
1224 +# Character Devices
1226 +CONFIG_STDIO_CONSOLE=y
1233 +CONFIG_XTERM_CHAN=y
1234 +CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
1235 +CONFIG_CON_CHAN="xterm"
1236 +CONFIG_SSL_CHAN="pty"
1237 +CONFIG_UNIX98_PTYS=y
1238 +CONFIG_UNIX98_PTY_COUNT=256
1239 +# CONFIG_WATCHDOG is not set
1240 +# CONFIG_WATCHDOG_NOWAYOUT is not set
1241 +# CONFIG_SOFT_WATCHDOG is not set
1242 +# CONFIG_UML_WATCHDOG is not set
1246 +# CONFIG_TTY_LOG is not set
1251 +CONFIG_BLK_DEV_UBD=y
1252 +# CONFIG_BLK_DEV_UBD_SYNC is not set
1253 +CONFIG_BLK_DEV_LOOP=y
1254 +CONFIG_BLK_DEV_NBD=y
1255 +CONFIG_BLK_DEV_RAM=y
1256 +CONFIG_BLK_DEV_RAM_SIZE=4096
1257 +CONFIG_BLK_DEV_INITRD=y
1258 +# CONFIG_MMAPPER is not set
1259 +CONFIG_NETDEVICES=y
1265 +CONFIG_UML_NET_ETHERTAP=y
1266 +CONFIG_UML_NET_TUNTAP=y
1267 +CONFIG_UML_NET_SLIP=y
1268 +CONFIG_UML_NET_SLIRP=y
1269 +CONFIG_UML_NET_DAEMON=y
1270 +CONFIG_UML_NET_MCAST=y
1271 +# CONFIG_UML_NET_PCAP is not set
1273 +# CONFIG_BONDING is not set
1274 +# CONFIG_EQUALIZER is not set
1277 +# CONFIG_PPP_MULTILINK is not set
1278 +# CONFIG_PPP_FILTER is not set
1279 +# CONFIG_PPP_ASYNC is not set
1280 +# CONFIG_PPP_SYNC_TTY is not set
1281 +# CONFIG_PPP_DEFLATE is not set
1282 +# CONFIG_PPP_BSDCOMP is not set
1283 +# CONFIG_PPPOE is not set
1285 +# CONFIG_SLIP_COMPRESSED is not set
1286 +# CONFIG_SLIP_SMART is not set
1287 +# CONFIG_SLIP_MODE_SLIP6 is not set
1290 +# Networking options
1293 +CONFIG_PACKET_MMAP=y
1294 +# CONFIG_NETLINK_DEV is not set
1295 +# CONFIG_NETFILTER is not set
1296 +# CONFIG_FILTER is not set
1299 +# CONFIG_IP_MULTICAST is not set
1300 +# CONFIG_IP_ADVANCED_ROUTER is not set
1301 +# CONFIG_IP_PNP is not set
1302 +# CONFIG_NET_IPIP is not set
1303 +# CONFIG_NET_IPGRE is not set
1304 +# CONFIG_ARPD is not set
1305 +# CONFIG_INET_ECN is not set
1306 +# CONFIG_SYN_COOKIES is not set
1307 +# CONFIG_IPV6 is not set
1308 +# CONFIG_KHTTPD is not set
1309 +# CONFIG_ATM is not set
1310 +# CONFIG_VLAN_8021Q is not set
1315 +# CONFIG_IPX is not set
1316 +# CONFIG_ATALK is not set
1319 +# Appletalk devices
1321 +# CONFIG_DEV_APPLETALK is not set
1322 +# CONFIG_DECNET is not set
1323 +# CONFIG_BRIDGE is not set
1324 +# CONFIG_X25 is not set
1325 +# CONFIG_LAPB is not set
1326 +# CONFIG_LLC is not set
1327 +# CONFIG_NET_DIVERT is not set
1328 +# CONFIG_ECONET is not set
1329 +# CONFIG_WAN_ROUTER is not set
1330 +# CONFIG_NET_FASTROUTE is not set
1331 +# CONFIG_NET_HW_FLOWCONTROL is not set
1334 +# QoS and/or fair queueing
1336 +# CONFIG_NET_SCHED is not set
1341 +# CONFIG_NET_PKTGEN is not set
1348 +CONFIG_AUTOFS4_FS=y
1349 +CONFIG_REISERFS_FS=y
1350 +# CONFIG_REISERFS_CHECK is not set
1351 +# CONFIG_REISERFS_PROC_INFO is not set
1352 +# CONFIG_ADFS_FS is not set
1353 +# CONFIG_ADFS_FS_RW is not set
1354 +# CONFIG_AFFS_FS is not set
1355 +# CONFIG_HFS_FS is not set
1356 +# CONFIG_BFS_FS is not set
1357 +# CONFIG_EXT3_FS is not set
1358 +# CONFIG_JBD is not set
1359 +# CONFIG_JBD_DEBUG is not set
1364 +# CONFIG_EFS_FS is not set
1366 +CONFIG_JFFS_FS_VERBOSE=0
1367 +CONFIG_JFFS_PROC_FS=y
1369 +CONFIG_JFFS2_FS_DEBUG=0
1370 +# CONFIG_CRAMFS is not set
1371 +# CONFIG_TMPFS is not set
1373 +CONFIG_ISO9660_FS=y
1374 +# CONFIG_JOLIET is not set
1375 +# CONFIG_ZISOFS is not set
1377 +# CONFIG_VXFS_FS is not set
1378 +# CONFIG_NTFS_FS is not set
1379 +# CONFIG_NTFS_RW is not set
1380 +# CONFIG_HPFS_FS is not set
1383 +CONFIG_DEVFS_MOUNT=y
1384 +# CONFIG_DEVFS_DEBUG is not set
1386 +# CONFIG_QNX4FS_FS is not set
1387 +# CONFIG_QNX4FS_RW is not set
1388 +# CONFIG_ROMFS_FS is not set
1390 +# CONFIG_SYSV_FS is not set
1391 +# CONFIG_UDF_FS is not set
1392 +# CONFIG_UDF_RW is not set
1393 +# CONFIG_UFS_FS is not set
1394 +# CONFIG_UFS_FS_WRITE is not set
1397 +# Network File Systems
1399 +# CONFIG_CODA_FS is not set
1400 +# CONFIG_INTERMEZZO_FS is not set
1401 +# CONFIG_NFS_FS is not set
1402 +# CONFIG_NFS_V3 is not set
1403 +# CONFIG_ROOT_NFS is not set
1404 +# CONFIG_NFSD is not set
1405 +# CONFIG_NFSD_V3 is not set
1406 +# CONFIG_SUNRPC is not set
1407 +# CONFIG_LOCKD is not set
1408 +# CONFIG_SMB_FS is not set
1409 +# CONFIG_NCP_FS is not set
1410 +# CONFIG_NCPFS_PACKET_SIGNING is not set
1411 +# CONFIG_NCPFS_IOCTL_LOCKING is not set
1412 +# CONFIG_NCPFS_STRONG is not set
1413 +# CONFIG_NCPFS_NFS_NS is not set
1414 +# CONFIG_NCPFS_OS2_NS is not set
1415 +# CONFIG_NCPFS_SMALLDOS is not set
1416 +# CONFIG_NCPFS_NLS is not set
1417 +# CONFIG_NCPFS_EXTRAS is not set
1418 +# CONFIG_ZISOFS_FS is not set
1419 +# CONFIG_ZLIB_FS_INFLATE is not set
1424 +# CONFIG_PARTITION_ADVANCED is not set
1425 +CONFIG_MSDOS_PARTITION=y
1426 +# CONFIG_SMB_NLS is not set
1430 +# Native Language Support
1432 +CONFIG_NLS_DEFAULT="iso8859-1"
1433 +# CONFIG_NLS_CODEPAGE_437 is not set
1434 +# CONFIG_NLS_CODEPAGE_737 is not set
1435 +# CONFIG_NLS_CODEPAGE_775 is not set
1436 +# CONFIG_NLS_CODEPAGE_850 is not set
1437 +# CONFIG_NLS_CODEPAGE_852 is not set
1438 +# CONFIG_NLS_CODEPAGE_855 is not set
1439 +# CONFIG_NLS_CODEPAGE_857 is not set
1440 +# CONFIG_NLS_CODEPAGE_860 is not set
1441 +# CONFIG_NLS_CODEPAGE_861 is not set
1442 +# CONFIG_NLS_CODEPAGE_862 is not set
1443 +# CONFIG_NLS_CODEPAGE_863 is not set
1444 +# CONFIG_NLS_CODEPAGE_864 is not set
1445 +# CONFIG_NLS_CODEPAGE_865 is not set
1446 +# CONFIG_NLS_CODEPAGE_866 is not set
1447 +# CONFIG_NLS_CODEPAGE_869 is not set
1448 +# CONFIG_NLS_CODEPAGE_936 is not set
1449 +# CONFIG_NLS_CODEPAGE_950 is not set
1450 +# CONFIG_NLS_CODEPAGE_932 is not set
1451 +# CONFIG_NLS_CODEPAGE_949 is not set
1452 +# CONFIG_NLS_CODEPAGE_874 is not set
1453 +# CONFIG_NLS_ISO8859_8 is not set
1454 +# CONFIG_NLS_CODEPAGE_1250 is not set
1455 +# CONFIG_NLS_CODEPAGE_1251 is not set
1456 +# CONFIG_NLS_ISO8859_1 is not set
1457 +# CONFIG_NLS_ISO8859_2 is not set
1458 +# CONFIG_NLS_ISO8859_3 is not set
1459 +# CONFIG_NLS_ISO8859_4 is not set
1460 +# CONFIG_NLS_ISO8859_5 is not set
1461 +# CONFIG_NLS_ISO8859_6 is not set
1462 +# CONFIG_NLS_ISO8859_7 is not set
1463 +# CONFIG_NLS_ISO8859_9 is not set
1464 +# CONFIG_NLS_ISO8859_13 is not set
1465 +# CONFIG_NLS_ISO8859_14 is not set
1466 +# CONFIG_NLS_ISO8859_15 is not set
1467 +# CONFIG_NLS_KOI8_R is not set
1468 +# CONFIG_NLS_KOI8_U is not set
1469 +# CONFIG_NLS_UTF8 is not set
1477 +# SCSI support type (disk, tape, CD-ROM)
1479 +# CONFIG_BLK_DEV_SD is not set
1480 +# CONFIG_CHR_DEV_ST is not set
1481 +# CONFIG_BLK_DEV_SR is not set
1482 +# CONFIG_CHR_DEV_SG is not set
1485 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
1487 +# CONFIG_SCSI_DEBUG_QUEUES is not set
1488 +# CONFIG_SCSI_MULTI_LUN is not set
1489 +# CONFIG_SCSI_CONSTANTS is not set
1490 +# CONFIG_SCSI_LOGGING is not set
1491 +CONFIG_SCSI_DEBUG=y
1494 +# Multi-device support (RAID and LVM)
1496 +# CONFIG_MD is not set
1497 +# CONFIG_BLK_DEV_MD is not set
1498 +# CONFIG_MD_LINEAR is not set
1499 +# CONFIG_MD_RAID0 is not set
1500 +# CONFIG_MD_RAID1 is not set
1501 +# CONFIG_MD_RAID5 is not set
1502 +# CONFIG_MD_MULTIPATH is not set
1503 +# CONFIG_BLK_DEV_LVM is not set
1506 +# Memory Technology Devices (MTD)
1509 +# CONFIG_MTD_DEBUG is not set
1510 +# CONFIG_MTD_PARTITIONS is not set
1511 +# CONFIG_MTD_CONCAT is not set
1512 +# CONFIG_MTD_REDBOOT_PARTS is not set
1515 +# User Modules And Translation Layers
1519 +# CONFIG_FTL is not set
1520 +# CONFIG_NFTL is not set
1523 +# RAM/ROM/Flash chip drivers
1525 +# CONFIG_MTD_CFI is not set
1526 +# CONFIG_MTD_JEDECPROBE is not set
1527 +# CONFIG_MTD_GEN_PROBE is not set
1528 +# CONFIG_MTD_CFI_INTELEXT is not set
1529 +# CONFIG_MTD_CFI_AMDSTD is not set
1530 +# CONFIG_MTD_RAM is not set
1531 +# CONFIG_MTD_ROM is not set
1532 +# CONFIG_MTD_ABSENT is not set
1533 +# CONFIG_MTD_OBSOLETE_CHIPS is not set
1534 +# CONFIG_MTD_AMDSTD is not set
1535 +# CONFIG_MTD_SHARP is not set
1536 +# CONFIG_MTD_JEDEC is not set
1539 +# Mapping drivers for chip access
1541 +# CONFIG_MTD_PHYSMAP is not set
1542 +# CONFIG_MTD_PCI is not set
1545 +# Self-contained MTD device drivers
1547 +# CONFIG_MTD_PMC551 is not set
1548 +# CONFIG_MTD_SLRAM is not set
1549 +# CONFIG_MTD_MTDRAM is not set
1550 +CONFIG_MTD_BLKMTD=y
1553 +# Disk-On-Chip Device Drivers
1555 +# CONFIG_MTD_DOC1000 is not set
1556 +# CONFIG_MTD_DOC2000 is not set
1557 +# CONFIG_MTD_DOC2001 is not set
1558 +# CONFIG_MTD_DOCPROBE is not set
1561 +# NAND Flash Device Drivers
1563 +# CONFIG_MTD_NAND is not set
1568 +# CONFIG_DEBUG_SLAB is not set
1571 +# CONFIG_GPROF is not set
1572 +# CONFIG_GCOV is not set
1573 diff -Naur -X ../exclude-files orig/arch/um/drivers/Makefile um/arch/um/drivers/Makefile
1574 --- orig/arch/um/drivers/Makefile Wed Dec 31 19:00:00 1969
1575 +++ um/arch/um/drivers/Makefile Wed Oct 23 21:08:04 2002
1578 +# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
1579 +# Licensed under the GPL
1582 +O_TARGET := built-in.o
1584 +CHAN_OBJS := chan_kern.o chan_user.o line.o
1586 +list-multi := slip.o slirp.o daemon.o mcast.o mconsole.o net.o ubd.o \
1587 + hostaudio.o pcap.o port.o harddog.o
1589 +slip-objs := slip_kern.o slip_user.o
1590 +slirp-objs := slirp_kern.o slirp_user.o
1591 +daemon-objs := daemon_kern.o daemon_user.o
1592 +mcast-objs := mcast_kern.o mcast_user.o
1593 +pcap-objs := pcap_kern.o pcap_user.o -lpcap -L/usr/lib
1594 +net-objs := net_kern.o net_user.o
1595 +mconsole-objs := mconsole_kern.o mconsole_user.o
1596 +hostaudio-objs := hostaudio_kern.o hostaudio_user.o
1597 +ubd-objs := ubd_kern.o ubd_user.o
1598 +port-objs := port_kern.o port_user.o
1599 +harddog-objs := harddog_kern.o harddog_user.o
1601 +export-objs := mconsole_kern.o
1604 +obj-$(CONFIG_SSL) += ssl.o
1605 +obj-$(CONFIG_UML_NET_SLIP) += slip.o
1606 +obj-$(CONFIG_UML_NET_SLIRP) += slirp.o
1607 +obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
1608 +obj-$(CONFIG_UML_NET_MCAST) += mcast.o
1609 +obj-$(CONFIG_UML_NET_PCAP) += pcap.o
1610 +obj-$(CONFIG_UML_NET) += net.o
1611 +obj-$(CONFIG_MCONSOLE) += mconsole.o
1612 +obj-$(CONFIG_MMAPPER) += mmapper_kern.o
1613 +obj-$(CONFIG_BLK_DEV_UBD) += ubd.o
1614 +obj-$(CONFIG_HOSTAUDIO) += hostaudio.o
1615 +obj-$(CONFIG_FD_CHAN) += fd.o
1616 +obj-$(CONFIG_NULL_CHAN) += null.o
1617 +obj-$(CONFIG_PORT_CHAN) += port.o
1618 +obj-$(CONFIG_PTY_CHAN) += pty.o
1619 +obj-$(CONFIG_TTY_CHAN) += tty.o
1620 +obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
1621 +obj-$(CONFIG_UML_WATCHDOG) += harddog.o
1623 +CFLAGS_pcap_user.o = -I/usr/include/pcap
1625 +obj-y += stdio_console.o $(CHAN_OBJS)
1627 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
1629 +USER_OBJS = $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
1630 + null.o pty.o tty.o xterm.o
1632 +include $(TOPDIR)/Rules.make
1634 +$(USER_OBJS) : %.o: %.c
1635 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
1647 +daemon.o : $(daemon-objs)
1649 +slip.o : $(slip-objs)
1651 +slirp.o : $(slirp-objs)
1653 +mcast.o : $(mcast-objs)
1655 +pcap.o : $(pcap-objs)
1657 +mconsole.o : $(mconsole-objs)
1659 +net.o : $(net-objs)
1661 +hostaudio.o : $(hostaudio-objs)
1663 +ubd.o : $(ubd-objs)
1665 +port.o : $(port-objs)
1667 +harddog.o : $(harddog-objs)
1669 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
1670 + $(LD) $(LD_RFLAG) -r -o $@ $($(patsubst %.o,%,$@)-objs)
1671 diff -Naur -X ../exclude-files orig/arch/um/drivers/chan_kern.c um/arch/um/drivers/chan_kern.c
1672 --- orig/arch/um/drivers/chan_kern.c Wed Dec 31 19:00:00 1969
1673 +++ um/arch/um/drivers/chan_kern.c Thu Mar 6 19:25:16 2003
1676 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
1677 + * Licensed under the GPL
1680 +#include <linux/stddef.h>
1681 +#include <linux/kernel.h>
1682 +#include <linux/list.h>
1683 +#include <linux/slab.h>
1684 +#include <linux/tty.h>
1685 +#include <linux/string.h>
1686 +#include <linux/tty_flip.h>
1687 +#include <asm/irq.h>
1688 +#include "chan_kern.h"
1689 +#include "user_util.h"
1691 +#include "irq_user.h"
1695 +static void *not_configged_init(char *str, int device, struct chan_opts *opts)
1697 + printk(KERN_ERR "Using a channel type which is configured out of "
1702 +static int not_configged_open(int input, int output, int primary, void *data,
1705 + printk(KERN_ERR "Using a channel type which is configured out of "
1710 +static void not_configged_close(int fd, void *data)
1712 + printk(KERN_ERR "Using a channel type which is configured out of "
1716 +static int not_configged_read(int fd, char *c_out, void *data)
1718 + printk(KERN_ERR "Using a channel type which is configured out of "
1723 +static int not_configged_write(int fd, const char *buf, int len, void *data)
1725 + printk(KERN_ERR "Using a channel type which is configured out of "
1730 +static int not_configged_console_write(int fd, const char *buf, int len,
1733 + printk(KERN_ERR "Using a channel type which is configured out of "
1738 +static int not_configged_window_size(int fd, void *data, unsigned short *rows,
1739 + unsigned short *cols)
1741 + printk(KERN_ERR "Using a channel type which is configured out of "
1746 +static void not_configged_free(void *data)
1748 + printk(KERN_ERR "Using a channel type which is configured out of "
1752 +static struct chan_ops not_configged_ops = {
1753 + .init = not_configged_init,
1754 + .open = not_configged_open,
1755 + .close = not_configged_close,
1756 + .read = not_configged_read,
1757 + .write = not_configged_write,
1758 + .console_write = not_configged_console_write,
1759 + .window_size = not_configged_window_size,
1760 + .free = not_configged_free,
1764 +static void tty_receive_char(struct tty_struct *tty, char ch)
1766 + if(tty == NULL) return;
1768 + if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
1769 + if(ch == STOP_CHAR(tty)){
1773 + else if(ch == START_CHAR(tty)){
1779 + if((tty->flip.flag_buf_ptr == NULL) ||
1780 + (tty->flip.char_buf_ptr == NULL))
1782 + tty_insert_flip_char(tty, ch, TTY_NORMAL);
1785 +static int open_one_chan(struct chan *chan, int input, int output, int primary)
1789 + if(chan->opened) return(0);
1790 + if(chan->ops->open == NULL) fd = 0;
1791 + else fd = (*chan->ops->open)(input, output, primary, chan->data,
1793 + if(fd < 0) return(fd);
1800 +int open_chan(struct list_head *chans)
1802 + struct list_head *ele;
1803 + struct chan *chan;
1806 + list_for_each(ele, chans){
1807 + chan = list_entry(ele, struct chan, list);
1808 + ret = open_one_chan(chan, chan->input, chan->output,
1810 + if(chan->primary) err = ret;
1815 +void chan_enable_winch(struct list_head *chans, void *line)
1817 + struct list_head *ele;
1818 + struct chan *chan;
1820 + list_for_each(ele, chans){
1821 + chan = list_entry(ele, struct chan, list);
1822 + if(chan->primary && chan->output && chan->ops->winch){
1823 + register_winch(chan->fd, line);
1829 +void enable_chan(struct list_head *chans, void *data)
1831 + struct list_head *ele;
1832 + struct chan *chan;
1834 + list_for_each(ele, chans){
1835 + chan = list_entry(ele, struct chan, list);
1836 + if(!chan->opened) continue;
1838 + line_setup_irq(chan->fd, chan->input, chan->output, data);
1842 +void close_chan(struct list_head *chans)
1844 + struct list_head *ele;
1845 + struct chan *chan;
1847 + /* Close in reverse order as open in case more than one of them
1848 + * refers to the same device and they save and restore that device's
1849 + * state. Then, the first one opened will have the original state,
1850 + * so it must be the last closed.
1852 + for(ele = chans->prev; ele != chans; ele = ele->prev){
1853 + chan = list_entry(ele, struct chan, list);
1854 + if(!chan->opened) continue;
1855 + if(chan->ops->close != NULL)
1856 + (*chan->ops->close)(chan->fd, chan->data);
1862 +int write_chan(struct list_head *chans, const char *buf, int len,
1865 + struct list_head *ele;
1866 + struct chan *chan;
1869 + list_for_each(ele, chans){
1870 + chan = list_entry(ele, struct chan, list);
1871 + if(!chan->output || (chan->ops->write == NULL)) continue;
1872 + n = chan->ops->write(chan->fd, buf, len, chan->data);
1873 + if(chan->primary){
1875 + if((ret == -EAGAIN) || ((ret >= 0) && (ret < len))){
1876 + reactivate_fd(chan->fd, write_irq);
1877 + if(ret == -EAGAIN) ret = 0;
1884 +int console_write_chan(struct list_head *chans, const char *buf, int len)
1886 + struct list_head *ele;
1887 + struct chan *chan;
1890 + list_for_each(ele, chans){
1891 + chan = list_entry(ele, struct chan, list);
1892 + if(!chan->output || (chan->ops->console_write == NULL))
1894 + n = chan->ops->console_write(chan->fd, buf, len, chan->data);
1895 + if(chan->primary) ret = n;
1900 +int chan_window_size(struct list_head *chans, unsigned short *rows_out,
1901 + unsigned short *cols_out)
1903 + struct list_head *ele;
1904 + struct chan *chan;
1906 + list_for_each(ele, chans){
1907 + chan = list_entry(ele, struct chan, list);
1908 + if(chan->primary){
1909 + if(chan->ops->window_size == NULL) return(0);
1910 + return(chan->ops->window_size(chan->fd, chan->data,
1911 + rows_out, cols_out));
1917 +void free_one_chan(struct chan *chan)
1919 + list_del(&chan->list);
1920 + if(chan->ops->free != NULL)
1921 + (*chan->ops->free)(chan->data);
1922 + free_irq_by_fd(chan->fd);
1923 + if(chan->primary && chan->output) ignore_sigio_fd(chan->fd);
1927 +void free_chan(struct list_head *chans)
1929 + struct list_head *ele, *next;
1930 + struct chan *chan;
1932 + list_for_each_safe(ele, next, chans){
1933 + chan = list_entry(ele, struct chan, list);
1934 + free_one_chan(chan);
1938 +static int one_chan_config_string(struct chan *chan, char *str, int size,
1943 + CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
1945 + if(chan->dev == NULL){
1946 + CONFIG_CHUNK(str, size, n, "", 1);
1950 + CONFIG_CHUNK(str, size, n, ":", 0);
1951 + CONFIG_CHUNK(str, size, n, chan->dev, 0);
1956 +static int chan_pair_config_string(struct chan *in, struct chan *out,
1957 + char *str, int size, char **error_out)
1961 + n = one_chan_config_string(in, str, size, error_out);
1966 + CONFIG_CHUNK(str, size, n, "", 1);
1970 + CONFIG_CHUNK(str, size, n, ",", 1);
1971 + n = one_chan_config_string(out, str, size, error_out);
1974 + CONFIG_CHUNK(str, size, n, "", 1);
1979 +int chan_config_string(struct list_head *chans, char *str, int size,
1982 + struct list_head *ele;
1983 + struct chan *chan, *in = NULL, *out = NULL;
1985 + list_for_each(ele, chans){
1986 + chan = list_entry(ele, struct chan, list);
1987 + if(!chan->primary)
1995 + return(chan_pair_config_string(in, out, str, size, error_out));
2000 + struct chan_ops *ops;
2003 +struct chan_type chan_table[] = {
2004 +#ifdef CONFIG_FD_CHAN
2005 + { "fd", &fd_ops },
2007 + { "fd", ¬_configged_ops },
2010 +#ifdef CONFIG_NULL_CHAN
2011 + { "null", &null_ops },
2013 + { "null", ¬_configged_ops },
2016 +#ifdef CONFIG_PORT_CHAN
2017 + { "port", &port_ops },
2019 + { "port", ¬_configged_ops },
2022 +#ifdef CONFIG_PTY_CHAN
2023 + { "pty", &pty_ops },
2024 + { "pts", &pts_ops },
2026 + { "pty", ¬_configged_ops },
2027 + { "pts", ¬_configged_ops },
2030 +#ifdef CONFIG_TTY_CHAN
2031 + { "tty", &tty_ops },
2033 + { "tty", ¬_configged_ops },
2036 +#ifdef CONFIG_XTERM_CHAN
2037 + { "xterm", &xterm_ops },
2039 + { "xterm", ¬_configged_ops },
2043 +static struct chan *parse_chan(char *str, int pri, int device,
2044 + struct chan_opts *opts)
2046 + struct chan_type *entry;
2047 + struct chan_ops *ops;
2048 + struct chan *chan;
2054 + for(i = 0; i < sizeof(chan_table)/sizeof(chan_table[0]); i++){
2055 + entry = &chan_table[i];
2056 + if(!strncmp(str, entry->key, strlen(entry->key))){
2058 + str += strlen(entry->key);
2063 + printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n",
2067 + if(ops->init == NULL) return(NULL);
2068 + data = (*ops->init)(str, device, opts);
2069 + if(data == NULL) return(NULL);
2071 + chan = kmalloc(sizeof(*chan), GFP_KERNEL);
2072 + if(chan == NULL) return(NULL);
2073 + *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list),
2085 +int parse_chan_pair(char *str, struct list_head *chans, int pri, int device,
2086 + struct chan_opts *opts)
2088 + struct chan *new, *chan;
2091 + if(!list_empty(chans)){
2092 + chan = list_entry(chans->next, struct chan, list);
2093 + if(chan->pri >= pri) return(0);
2095 + INIT_LIST_HEAD(chans);
2098 + if((out = strchr(str, ',')) != NULL){
2102 + new = parse_chan(in, pri, device, opts);
2103 + if(new == NULL) return(-1);
2105 + list_add(&new->list, chans);
2107 + new = parse_chan(out, pri, device, opts);
2108 + if(new == NULL) return(-1);
2109 + list_add(&new->list, chans);
2113 + new = parse_chan(str, pri, device, opts);
2114 + if(new == NULL) return(-1);
2115 + list_add(&new->list, chans);
2122 +int chan_out_fd(struct list_head *chans)
2124 + struct list_head *ele;
2125 + struct chan *chan;
2127 + list_for_each(ele, chans){
2128 + chan = list_entry(ele, struct chan, list);
2129 + if(chan->primary && chan->output)
2135 +void chan_interrupt(struct list_head *chans, struct tq_struct *task,
2136 + struct tty_struct *tty, int irq, void *dev)
2138 + struct list_head *ele, *next;
2139 + struct chan *chan;
2143 + list_for_each_safe(ele, next, chans){
2144 + chan = list_entry(ele, struct chan, list);
2145 + if(!chan->input || (chan->ops->read == NULL)) continue;
2147 + if((tty != NULL) &&
2148 + (tty->flip.count >= TTY_FLIPBUF_SIZE)){
2149 + queue_task(task, &tq_timer);
2152 + err = chan->ops->read(chan->fd, &c, chan->data);
2153 + if(err > 0) tty_receive_char(tty, c);
2155 + if(err == 0) reactivate_fd(chan->fd, irq);
2157 + if(chan->primary){
2158 + if(tty != NULL) tty_hangup(tty);
2159 + line_disable(dev, irq);
2160 + close_chan(chans);
2165 + if(chan->ops->close != NULL)
2166 + chan->ops->close(chan->fd, chan->data);
2167 + free_one_chan(chan);
2172 + if(tty) tty_flip_buffer_push(tty);
2176 + * Overrides for Emacs so that we follow Linus's tabbing style.
2177 + * Emacs will notice this stuff at the end of the file and automatically
2178 + * adjust the settings for this buffer only. This must remain at the end
2180 + * ---------------------------------------------------------------------------
2181 + * Local variables:
2182 + * c-file-style: "linux"
2185 diff -Naur -X ../exclude-files orig/arch/um/drivers/chan_user.c um/arch/um/drivers/chan_user.c
2186 --- orig/arch/um/drivers/chan_user.c Wed Dec 31 19:00:00 1969
2187 +++ um/arch/um/drivers/chan_user.c Wed Mar 26 13:23:48 2003
2190 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
2191 + * Licensed under the GPL
2194 +#include <unistd.h>
2195 +#include <stdlib.h>
2197 +#include <termios.h>
2199 +#include <string.h>
2200 +#include <signal.h>
2201 +#include <sys/stat.h>
2202 +#include <sys/ioctl.h>
2203 +#include <sys/socket.h>
2204 +#include "kern_util.h"
2205 +#include "user_util.h"
2206 +#include "chan_user.h"
2208 +#include "helper.h"
2210 +#include "choose-mode.h"
2213 +void generic_close(int fd, void *unused)
2218 +int generic_read(int fd, char *c_out, void *unused)
2222 + n = read(fd, c_out, sizeof(*c_out));
2224 + if(errno == EAGAIN) return(0);
2227 + else if(n == 0) return(-EIO);
2231 +int generic_write(int fd, const char *buf, int n, void *unused)
2235 + count = write(fd, buf, n);
2236 + if(count < 0) return(-errno);
2240 +int generic_console_write(int fd, const char *buf, int n, void *unused)
2242 + struct termios save, new;
2246 + tcgetattr(fd, &save);
2248 + new.c_oflag |= OPOST;
2249 + tcsetattr(fd, TCSAFLUSH, &new);
2251 + err = generic_write(fd, buf, n, NULL);
2252 + if(isatty(fd)) tcsetattr(fd, TCSAFLUSH, &save);
2256 +int generic_window_size(int fd, void *unused, unsigned short *rows_out,
2257 + unsigned short *cols_out)
2259 + struct winsize size;
2262 + if(ioctl(fd, TIOCGWINSZ, &size) == 0){
2263 + ret = ((*rows_out != size.ws_row) ||
2264 + (*cols_out != size.ws_col));
2265 + *rows_out = size.ws_row;
2266 + *cols_out = size.ws_col;
2271 +void generic_free(void *data)
2276 +static void winch_handler(int sig)
2280 +struct winch_data {
2286 +static int winch_thread(void *arg)
2288 + struct winch_data *data = arg;
2290 + int pty_fd, pipe_fd;
2293 + close(data->close_me);
2294 + pty_fd = data->pty_fd;
2295 + pipe_fd = data->pipe_fd;
2296 + if(write(pipe_fd, &c, sizeof(c)) != sizeof(c))
2297 + printk("winch_thread : failed to write synchronization "
2298 + "byte, errno = %d\n", errno);
2300 + signal(SIGWINCH, winch_handler);
2301 + sigfillset(&sigs);
2302 + sigdelset(&sigs, SIGWINCH);
2303 + if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
2304 + printk("winch_thread : sigprocmask failed, errno = %d\n",
2310 + printk("winch_thread : setsid failed, errno = %d\n", errno);
2314 + if(ioctl(pty_fd, TIOCSCTTY, 0) < 0){
2315 + printk("winch_thread : TIOCSCTTY failed, errno = %d\n", errno);
2318 + if(tcsetpgrp(pty_fd, os_getpid()) < 0){
2319 + printk("winch_thread : tcsetpgrp failed, errno = %d\n", errno);
2323 + if(read(pipe_fd, &c, sizeof(c)) != sizeof(c))
2324 + printk("winch_thread : failed to read synchronization byte, "
2325 + "errno = %d\n", errno);
2330 + if(write(pipe_fd, &c, sizeof(c)) != sizeof(c)){
2331 + printk("winch_thread : write failed, errno = %d\n",
2337 +static int winch_tramp(int fd, void *device_data, int *fd_out)
2339 + struct winch_data data;
2340 + unsigned long stack;
2341 + int fds[2], pid, n, err;
2344 + err = os_pipe(fds, 1, 1);
2346 + printk("winch_tramp : os_pipe failed, errno = %d\n", -err);
2350 + data = ((struct winch_data) { .pty_fd = fd,
2351 + .pipe_fd = fds[1],
2352 + .close_me = fds[0] } );
2353 + pid = run_helper_thread(winch_thread, &data, 0, &stack, 0);
2355 + printk("fork of winch_thread failed - errno = %d\n", errno);
2361 + n = read(fds[0], &c, sizeof(c));
2362 + if(n != sizeof(c)){
2363 + printk("winch_tramp : failed to read synchronization byte\n");
2364 + printk("read returned %d, errno = %d\n", n, errno);
2365 + printk("fd %d will not support SIGWINCH\n", fd);
2371 +void register_winch(int fd, void *device_data)
2373 + int pid, thread, thread_fd;
2376 + if(!isatty(fd)) return;
2378 + pid = tcgetpgrp(fd);
2379 + if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd,
2380 + device_data) && (pid == -1)){
2381 + thread = winch_tramp(fd, device_data, &thread_fd);
2383 + register_winch_irq(thread_fd, fd, thread, device_data);
2385 + if(write(thread_fd, &c, sizeof(c)) != sizeof(c))
2386 + printk("register_winch : failed to write "
2387 + "synchronization byte\n");
2393 + * Overrides for Emacs so that we follow Linus's tabbing style.
2394 + * Emacs will notice this stuff at the end of the file and automatically
2395 + * adjust the settings for this buffer only. This must remain at the end
2397 + * ---------------------------------------------------------------------------
2398 + * Local variables:
2399 + * c-file-style: "linux"
2402 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon.h um/arch/um/drivers/daemon.h
2403 --- orig/arch/um/drivers/daemon.h Wed Dec 31 19:00:00 1969
2404 +++ um/arch/um/drivers/daemon.h Wed Oct 23 21:08:04 2002
2407 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
2408 + * Licensed under the GPL
2411 +#include "net_user.h"
2413 +#define SWITCH_VERSION 3
2415 +struct daemon_data {
2426 +extern struct net_user_info daemon_user_info;
2428 +extern int daemon_user_write(int fd, void *buf, int len,
2429 + struct daemon_data *pri);
2432 + * Overrides for Emacs so that we follow Linus's tabbing style.
2433 + * Emacs will notice this stuff at the end of the file and automatically
2434 + * adjust the settings for this buffer only. This must remain at the end
2436 + * ---------------------------------------------------------------------------
2437 + * Local variables:
2438 + * c-file-style: "linux"
2441 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon_kern.c um/arch/um/drivers/daemon_kern.c
2442 --- orig/arch/um/drivers/daemon_kern.c Wed Dec 31 19:00:00 1969
2443 +++ um/arch/um/drivers/daemon_kern.c Sun Dec 15 21:19:17 2002
2446 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
2447 + * James Leu (jleu@mindspring.net).
2448 + * Copyright (C) 2001 by various other people who didn't put their name here.
2449 + * Licensed under the GPL.
2452 +#include "linux/kernel.h"
2453 +#include "linux/init.h"
2454 +#include "linux/netdevice.h"
2455 +#include "linux/etherdevice.h"
2456 +#include "net_kern.h"
2457 +#include "net_user.h"
2458 +#include "daemon.h"
2460 +struct daemon_init {
2465 +void daemon_init(struct net_device *dev, void *data)
2467 + struct uml_net_private *pri;
2468 + struct daemon_data *dpri;
2469 + struct daemon_init *init = data;
2471 + init_etherdev(dev, 0);
2473 + dpri = (struct daemon_data *) pri->user;
2474 + *dpri = ((struct daemon_data)
2475 + { .sock_type = init->sock_type,
2476 + .ctl_sock = init->ctl_sock,
2478 + .data_addr = NULL,
2479 + .local_addr = NULL,
2484 + printk("daemon backend (uml_switch version %d) - %s:%s",
2485 + SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
2489 +static int daemon_read(int fd, struct sk_buff **skb,
2490 + struct uml_net_private *lp)
2492 + *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
2493 + if(*skb == NULL) return(-ENOMEM);
2494 + return(net_recvfrom(fd, (*skb)->mac.raw,
2495 + (*skb)->dev->mtu + ETH_HEADER_OTHER));
2498 +static int daemon_write(int fd, struct sk_buff **skb,
2499 + struct uml_net_private *lp)
2501 + return(daemon_user_write(fd, (*skb)->data, (*skb)->len,
2502 + (struct daemon_data *) &lp->user));
2505 +static struct net_kern_info daemon_kern_info = {
2506 + .init = daemon_init,
2507 + .protocol = eth_protocol,
2508 + .read = daemon_read,
2509 + .write = daemon_write,
2512 +int daemon_setup(char *str, char **mac_out, void *data)
2514 + struct daemon_init *init = data;
2517 + *init = ((struct daemon_init)
2518 + { .sock_type = "unix",
2519 + .ctl_sock = "/tmp/uml.ctl" });
2521 + remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
2523 + if(remain != NULL)
2524 + printk(KERN_WARNING "daemon_setup : Ignoring data socket "
2525 + "specification\n");
2530 +static struct transport daemon_transport = {
2531 + .list = LIST_HEAD_INIT(daemon_transport.list),
2533 + .setup = daemon_setup,
2534 + .user = &daemon_user_info,
2535 + .kern = &daemon_kern_info,
2536 + .private_size = sizeof(struct daemon_data),
2537 + .setup_size = sizeof(struct daemon_init),
2540 +static int register_daemon(void)
2542 + register_transport(&daemon_transport);
2546 +__initcall(register_daemon);
2549 + * Overrides for Emacs so that we follow Linus's tabbing style.
2550 + * Emacs will notice this stuff at the end of the file and automatically
2551 + * adjust the settings for this buffer only. This must remain at the end
2553 + * ---------------------------------------------------------------------------
2554 + * Local variables:
2555 + * c-file-style: "linux"
2558 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon_user.c um/arch/um/drivers/daemon_user.c
2559 --- orig/arch/um/drivers/daemon_user.c Wed Dec 31 19:00:00 1969
2560 +++ um/arch/um/drivers/daemon_user.c Fri Jan 17 13:48:59 2003
2563 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
2564 + * James Leu (jleu@mindspring.net).
2565 + * Copyright (C) 2001 by various other people who didn't put their name here.
2566 + * Licensed under the GPL.
2570 +#include <unistd.h>
2571 +#include <stdint.h>
2572 +#include <sys/socket.h>
2573 +#include <sys/un.h>
2574 +#include <sys/time.h>
2575 +#include "net_user.h"
2576 +#include "daemon.h"
2577 +#include "kern_util.h"
2578 +#include "user_util.h"
2582 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
2584 +enum request_type { REQ_NEW_CONTROL };
2586 +#define SWITCH_MAGIC 0xfeedface
2588 +struct request_v3 {
2591 + enum request_type type;
2592 + struct sockaddr_un sock;
2595 +static struct sockaddr_un *new_addr(void *name, int len)
2597 + struct sockaddr_un *sun;
2599 + sun = um_kmalloc(sizeof(struct sockaddr_un));
2601 + printk("new_addr: allocation of sockaddr_un failed\n");
2604 + sun->sun_family = AF_UNIX;
2605 + memcpy(sun->sun_path, name, len);
2609 +static int connect_to_switch(struct daemon_data *pri)
2611 + struct sockaddr_un *ctl_addr = pri->ctl_addr;
2612 + struct sockaddr_un *local_addr = pri->local_addr;
2613 + struct sockaddr_un *sun;
2614 + struct request_v3 req;
2617 + if((pri->control = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
2618 + printk("daemon_open : control socket failed, errno = %d\n",
2623 + if(connect(pri->control, (struct sockaddr *) ctl_addr,
2624 + sizeof(*ctl_addr)) < 0){
2625 + printk("daemon_open : control connect failed, errno = %d\n",
2631 + if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0){
2632 + printk("daemon_open : data socket failed, errno = %d\n",
2637 + if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){
2638 + printk("daemon_open : data bind failed, errno = %d\n",
2644 + sun = um_kmalloc(sizeof(struct sockaddr_un));
2646 + printk("new_addr: allocation of sockaddr_un failed\n");
2651 + req.magic = SWITCH_MAGIC;
2652 + req.version = SWITCH_VERSION;
2653 + req.type = REQ_NEW_CONTROL;
2654 + req.sock = *local_addr;
2655 + n = write(pri->control, &req, sizeof(req));
2656 + if(n != sizeof(req)){
2657 + printk("daemon_open : control setup request returned %d, "
2658 + "errno = %d\n", n, errno);
2663 + n = read(pri->control, sun, sizeof(*sun));
2664 + if(n != sizeof(*sun)){
2665 + printk("daemon_open : read of data socket returned %d, "
2666 + "errno = %d\n", n, errno);
2671 + pri->data_addr = sun;
2677 + close(pri->control);
2681 +static void daemon_user_init(void *data, void *dev)
2683 + struct daemon_data *pri = data;
2684 + struct timeval tv;
2691 + if(!strcmp(pri->sock_type, "unix"))
2692 + pri->ctl_addr = new_addr(pri->ctl_sock,
2693 + strlen(pri->ctl_sock) + 1);
2695 + name.pid = os_getpid();
2696 + gettimeofday(&tv, NULL);
2697 + name.usecs = tv.tv_usec;
2698 + pri->local_addr = new_addr(&name, sizeof(name));
2700 + pri->fd = connect_to_switch(pri);
2702 + kfree(pri->local_addr);
2703 + pri->local_addr = NULL;
2707 +static int daemon_open(void *data)
2709 + struct daemon_data *pri = data;
2713 +static void daemon_remove(void *data)
2715 + struct daemon_data *pri = data;
2718 + close(pri->control);
2719 + if(pri->data_addr != NULL) kfree(pri->data_addr);
2720 + if(pri->ctl_addr != NULL) kfree(pri->ctl_addr);
2721 + if(pri->local_addr != NULL) kfree(pri->local_addr);
2724 +int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
2726 + struct sockaddr_un *data_addr = pri->data_addr;
2728 + return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
2731 +static int daemon_set_mtu(int mtu, void *data)
2736 +struct net_user_info daemon_user_info = {
2737 + .init = daemon_user_init,
2738 + .open = daemon_open,
2740 + .remove = daemon_remove,
2741 + .set_mtu = daemon_set_mtu,
2742 + .add_address = NULL,
2743 + .delete_address = NULL,
2744 + .max_packet = MAX_PACKET - ETH_HEADER_OTHER
2748 + * Overrides for Emacs so that we follow Linus's tabbing style.
2749 + * Emacs will notice this stuff at the end of the file and automatically
2750 + * adjust the settings for this buffer only. This must remain at the end
2752 + * ---------------------------------------------------------------------------
2753 + * Local variables:
2754 + * c-file-style: "linux"
2757 diff -Naur -X ../exclude-files orig/arch/um/drivers/fd.c um/arch/um/drivers/fd.c
2758 --- orig/arch/um/drivers/fd.c Wed Dec 31 19:00:00 1969
2759 +++ um/arch/um/drivers/fd.c Sun Dec 15 20:57:25 2002
2762 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
2763 + * Licensed under the GPL
2767 +#include <stdlib.h>
2768 +#include <unistd.h>
2769 +#include <termios.h>
2771 +#include "user_util.h"
2772 +#include "chan_user.h"
2777 + struct termios tt;
2778 + char str[sizeof("1234567890\0")];
2781 +void *fd_init(char *str, int device, struct chan_opts *opts)
2783 + struct fd_chan *data;
2788 + printk("fd_init : channel type 'fd' must specify a file "
2793 + n = strtoul(str, &end, 0);
2794 + if((*end != '\0') || (end == str)){
2795 + printk("fd_init : couldn't parse file descriptor '%s'\n", str);
2798 + if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
2799 + *data = ((struct fd_chan) { .fd = n,
2800 + .raw = opts->raw });
2804 +int fd_open(int input, int output, int primary, void *d, char **dev_out)
2806 + struct fd_chan *data = d;
2808 + if(data->raw && isatty(data->fd)){
2809 + tcgetattr(data->fd, &data->tt);
2812 + sprintf(data->str, "%d", data->fd);
2813 + *dev_out = data->str;
2817 +void fd_close(int fd, void *d)
2819 + struct fd_chan *data = d;
2821 + if(data->raw && isatty(fd)){
2822 + tcsetattr(fd, TCSAFLUSH, &data->tt);
2827 +int fd_console_write(int fd, const char *buf, int n, void *d)
2829 + struct fd_chan *data = d;
2831 + return(generic_console_write(fd, buf, n, &data->tt));
2834 +struct chan_ops fd_ops = {
2838 + .close = fd_close,
2839 + .read = generic_read,
2840 + .write = generic_write,
2841 + .console_write = fd_console_write,
2842 + .window_size = generic_window_size,
2843 + .free = generic_free,
2848 + * Overrides for Emacs so that we follow Linus's tabbing style.
2849 + * Emacs will notice this stuff at the end of the file and automatically
2850 + * adjust the settings for this buffer only. This must remain at the end
2852 + * ---------------------------------------------------------------------------
2853 + * Local variables:
2854 + * c-file-style: "linux"
2857 diff -Naur -X ../exclude-files orig/arch/um/drivers/harddog_kern.c um/arch/um/drivers/harddog_kern.c
2858 --- orig/arch/um/drivers/harddog_kern.c Wed Dec 31 19:00:00 1969
2859 +++ um/arch/um/drivers/harddog_kern.c Sun Dec 15 20:57:42 2002
2861 +/* UML hardware watchdog, shamelessly stolen from:
2863 + * SoftDog 0.05: A Software Watchdog Device
2865 + * (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
2866 + * http://www.redhat.com
2868 + * This program is free software; you can redistribute it and/or
2869 + * modify it under the terms of the GNU General Public License
2870 + * as published by the Free Software Foundation; either version
2871 + * 2 of the License, or (at your option) any later version.
2873 + * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
2874 + * warranty for any of this software. This material is provided
2875 + * "AS-IS" and at no charge.
2877 + * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
2879 + * Software only watchdog driver. Unlike its big brother the WDT501P
2880 + * driver this won't always recover a failed machine.
2882 + * 03/96: Angelo Haritsis <ah@doc.ic.ac.uk> :
2884 + * Added soft_margin; use upon insmod to change the timer delay.
2885 + * NB: uses same minor as wdt (WATCHDOG_MINOR); we could use separate
2888 + * 19980911 Alan Cox
2889 + * Made SMP safe for 2.3.x
2891 + * 20011127 Joel Becker (jlbec@evilplan.org>
2892 + * Added soft_noboot; Allows testing the softdog trigger without
2893 + * requiring a recompile.
2894 + * Added WDIOC_GETTIMEOUT and WDIOC_SETTIMOUT.
2897 +#include <linux/module.h>
2898 +#include <linux/config.h>
2899 +#include <linux/types.h>
2900 +#include <linux/kernel.h>
2901 +#include <linux/fs.h>
2902 +#include <linux/mm.h>
2903 +#include <linux/miscdevice.h>
2904 +#include <linux/watchdog.h>
2905 +#include <linux/reboot.h>
2906 +#include <linux/smp_lock.h>
2907 +#include <linux/init.h>
2908 +#include <asm/uaccess.h>
2909 +#include "helper.h"
2910 +#include "mconsole.h"
2912 +MODULE_LICENSE("GPL");
2914 +/* Locked by the BKL in harddog_open and harddog_release */
2915 +static int timer_alive;
2916 +static int harddog_in_fd = -1;
2917 +static int harddog_out_fd = -1;
2920 + * Allow only one person to hold it open
2923 +extern int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock);
2925 +static int harddog_open(struct inode *inode, struct file *file)
2928 + char *sock = NULL;
2933 +#ifdef CONFIG_HARDDOG_NOWAYOUT
2934 + MOD_INC_USE_COUNT;
2937 +#ifdef CONFIG_MCONSOLE
2938 + sock = mconsole_notify_socket();
2940 + err = start_watchdog(&harddog_in_fd, &harddog_out_fd, sock);
2941 + if(err) return(err);
2948 +extern void stop_watchdog(int in_fd, int out_fd);
2950 +static int harddog_release(struct inode *inode, struct file *file)
2953 + * Shut off the timer.
2957 + stop_watchdog(harddog_in_fd, harddog_out_fd);
2958 + harddog_in_fd = -1;
2959 + harddog_out_fd = -1;
2966 +extern int ping_watchdog(int fd);
2968 +static ssize_t harddog_write(struct file *file, const char *data, size_t len,
2971 + /* Can't seek (pwrite) on this device */
2972 + if (ppos != &file->f_pos)
2976 + * Refresh the timer.
2979 + return(ping_watchdog(harddog_out_fd));
2983 +static int harddog_ioctl(struct inode *inode, struct file *file,
2984 + unsigned int cmd, unsigned long arg)
2986 + static struct watchdog_info ident = {
2989 + "UML Hardware Watchdog"
2994 + case WDIOC_GETSUPPORT:
2995 + if(copy_to_user((struct harddog_info *)arg, &ident,
2999 + case WDIOC_GETSTATUS:
3000 + case WDIOC_GETBOOTSTATUS:
3001 + return put_user(0,(int *)arg);
3002 + case WDIOC_KEEPALIVE:
3003 + return(ping_watchdog(harddog_out_fd));
3007 +static struct file_operations harddog_fops = {
3008 + .owner = THIS_MODULE,
3009 + .write = harddog_write,
3010 + .ioctl = harddog_ioctl,
3011 + .open = harddog_open,
3012 + .release = harddog_release,
3015 +static struct miscdevice harddog_miscdev = {
3016 + .minor = WATCHDOG_MINOR,
3017 + .name = "watchdog",
3018 + .fops = &harddog_fops,
3021 +static char banner[] __initdata = KERN_INFO "UML Watchdog Timer\n";
3023 +static int __init harddog_init(void)
3027 + ret = misc_register(&harddog_miscdev);
3037 +static void __exit harddog_exit(void)
3039 + misc_deregister(&harddog_miscdev);
3042 +module_init(harddog_init);
3043 +module_exit(harddog_exit);
3046 + * Overrides for Emacs so that we follow Linus's tabbing style.
3047 + * Emacs will notice this stuff at the end of the file and automatically
3048 + * adjust the settings for this buffer only. This must remain at the end
3050 + * ---------------------------------------------------------------------------
3051 + * Local variables:
3052 + * c-file-style: "linux"
3055 diff -Naur -X ../exclude-files orig/arch/um/drivers/harddog_user.c um/arch/um/drivers/harddog_user.c
3056 --- orig/arch/um/drivers/harddog_user.c Wed Dec 31 19:00:00 1969
3057 +++ um/arch/um/drivers/harddog_user.c Wed Dec 4 16:38:05 2002
3060 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3061 + * Licensed under the GPL
3065 +#include <unistd.h>
3067 +#include "user_util.h"
3069 +#include "helper.h"
3070 +#include "mconsole.h"
3072 +#include "choose-mode.h"
3081 +static void pre_exec(void *d)
3083 + struct dog_data *data = d;
3085 + dup2(data->stdin, 0);
3086 + dup2(data->stdout, 1);
3087 + dup2(data->stdout, 2);
3088 + close(data->stdin);
3089 + close(data->stdout);
3090 + close(data->close_me[0]);
3091 + close(data->close_me[1]);
3094 +int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
3096 + struct dog_data data;
3097 + int in_fds[2], out_fds[2], pid, n, err;
3098 + char pid_buf[sizeof("nnnnn\0")], c;
3099 + char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL };
3100 + char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL,
3102 + char **args = NULL;
3104 + err = os_pipe(in_fds, 1, 0);
3106 + printk("harddog_open - os_pipe failed, errno = %d\n", -err);
3110 + err = os_pipe(out_fds, 1, 0);
3112 + printk("harddog_open - os_pipe failed, errno = %d\n", -err);
3116 + data.stdin = out_fds[0];
3117 + data.stdout = in_fds[1];
3118 + data.close_me[0] = out_fds[1];
3119 + data.close_me[1] = in_fds[0];
3122 + mconsole_args[2] = sock;
3123 + args = mconsole_args;
3126 + /* XXX The os_getpid() is not SMP correct */
3127 + sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid()));
3131 + pid = run_helper(pre_exec, &data, args, NULL);
3133 + close(out_fds[0]);
3138 + printk("harddog_open - run_helper failed, errno = %d\n", err);
3142 + n = read(in_fds[0], &c, sizeof(c));
3144 + printk("harddog_open - EOF on watchdog pipe\n");
3150 + printk("harddog_open - read of watchdog pipe failed, "
3151 + "errno = %d\n", errno);
3156 + *in_fd_ret = in_fds[0];
3157 + *out_fd_ret = out_fds[1];
3160 + close(out_fds[1]);
3165 +void stop_watchdog(int in_fd, int out_fd)
3171 +int ping_watchdog(int fd)
3176 + n = write(fd, &c, sizeof(c));
3177 + if(n < sizeof(c)){
3178 + printk("ping_watchdog - write failed, errno = %d\n",
3187 + * Overrides for Emacs so that we follow Linus's tabbing style.
3188 + * Emacs will notice this stuff at the end of the file and automatically
3189 + * adjust the settings for this buffer only. This must remain at the end
3191 + * ---------------------------------------------------------------------------
3192 + * Local variables:
3193 + * c-file-style: "linux"
3196 diff -Naur -X ../exclude-files orig/arch/um/drivers/hostaudio_kern.c um/arch/um/drivers/hostaudio_kern.c
3197 --- orig/arch/um/drivers/hostaudio_kern.c Wed Dec 31 19:00:00 1969
3198 +++ um/arch/um/drivers/hostaudio_kern.c Fri Mar 28 21:57:16 2003
3201 + * Copyright (C) 2002 Steve Schmidtke
3202 + * Licensed under the GPL
3205 +#include "linux/config.h"
3206 +#include "linux/module.h"
3207 +#include "linux/version.h"
3208 +#include "linux/init.h"
3209 +#include "linux/slab.h"
3210 +#include "linux/fs.h"
3211 +#include "linux/sound.h"
3212 +#include "linux/soundcard.h"
3213 +#include "asm/uaccess.h"
3214 +#include "kern_util.h"
3216 +#include "hostaudio.h"
3218 +/* Only changed from linux_main at boot time */
3219 +char *dsp = HOSTAUDIO_DEV_DSP;
3220 +char *mixer = HOSTAUDIO_DEV_MIXER;
3223 +static int set_dsp(char *name, int *add)
3229 +__uml_setup("dsp=", set_dsp,
3230 +"dsp=<dsp device>\n"
3231 +" This is used to specify the host dsp device to the hostaudio driver.\n"
3232 +" The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
3235 +static int set_mixer(char *name, int *add)
3241 +__uml_setup("mixer=", set_mixer,
3242 +"mixer=<mixer device>\n"
3243 +" This is used to specify the host mixer device to the hostaudio driver.\n"
3244 +" The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
3248 +/* /dev/dsp file operations */
3250 +static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count,
3253 + struct hostaudio_state *state = file->private_data;
3258 + printk("hostaudio: read called, count = %d\n", count);
3261 + kbuf = kmalloc(count, GFP_KERNEL);
3265 + err = hostaudio_read_user(state, kbuf, count, ppos);
3269 + if(copy_to_user(buffer, kbuf, err))
3277 +static ssize_t hostaudio_write(struct file *file, const char *buffer,
3278 + size_t count, loff_t *ppos)
3280 + struct hostaudio_state *state = file->private_data;
3285 + printk("hostaudio: write called, count = %d\n", count);
3288 + kbuf = kmalloc(count, GFP_KERNEL);
3293 + if(copy_from_user(kbuf, buffer, count))
3296 + err = hostaudio_write_user(state, kbuf, count, ppos);
3305 +static unsigned int hostaudio_poll(struct file *file,
3306 + struct poll_table_struct *wait)
3308 + unsigned int mask = 0;
3311 + printk("hostaudio: poll called (unimplemented)\n");
3317 +static int hostaudio_ioctl(struct inode *inode, struct file *file,
3318 + unsigned int cmd, unsigned long arg)
3320 + struct hostaudio_state *state = file->private_data;
3321 + unsigned long data = 0;
3325 + printk("hostaudio: ioctl called, cmd = %u\n", cmd);
3328 + case SNDCTL_DSP_SPEED:
3329 + case SNDCTL_DSP_STEREO:
3330 + case SNDCTL_DSP_GETBLKSIZE:
3331 + case SNDCTL_DSP_CHANNELS:
3332 + case SNDCTL_DSP_SUBDIVIDE:
3333 + case SNDCTL_DSP_SETFRAGMENT:
3334 + if(get_user(data, (int *) arg))
3341 + err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
3344 + case SNDCTL_DSP_SPEED:
3345 + case SNDCTL_DSP_STEREO:
3346 + case SNDCTL_DSP_GETBLKSIZE:
3347 + case SNDCTL_DSP_CHANNELS:
3348 + case SNDCTL_DSP_SUBDIVIDE:
3349 + case SNDCTL_DSP_SETFRAGMENT:
3350 + if(put_user(data, (int *) arg))
3360 +static int hostaudio_open(struct inode *inode, struct file *file)
3362 + struct hostaudio_state *state;
3367 + printk("hostaudio: open called (host: %s)\n", dsp);
3370 + state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
3371 + if(state == NULL) return(-ENOMEM);
3373 + if(file->f_mode & FMODE_READ) r = 1;
3374 + if(file->f_mode & FMODE_WRITE) w = 1;
3376 + ret = hostaudio_open_user(state, r, w, dsp);
3382 + file->private_data = state;
3386 +static int hostaudio_release(struct inode *inode, struct file *file)
3388 + struct hostaudio_state *state = file->private_data;
3392 + printk("hostaudio: release called\n");
3395 + ret = hostaudio_release_user(state);
3401 +/* /dev/mixer file operations */
3403 +static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file,
3404 + unsigned int cmd, unsigned long arg)
3406 + struct hostmixer_state *state = file->private_data;
3409 + printk("hostmixer: ioctl called\n");
3412 + return(hostmixer_ioctl_mixdev_user(state, cmd, arg));
3415 +static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
3417 + struct hostmixer_state *state;
3422 + printk("hostmixer: open called (host: %s)\n", mixer);
3425 + state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL);
3426 + if(state == NULL) return(-ENOMEM);
3428 + if(file->f_mode & FMODE_READ) r = 1;
3429 + if(file->f_mode & FMODE_WRITE) w = 1;
3431 + ret = hostmixer_open_mixdev_user(state, r, w, mixer);
3438 + file->private_data = state;
3442 +static int hostmixer_release(struct inode *inode, struct file *file)
3444 + struct hostmixer_state *state = file->private_data;
3448 + printk("hostmixer: release called\n");
3451 + ret = hostmixer_release_mixdev_user(state);
3458 +/* kernel module operations */
3460 +static struct file_operations hostaudio_fops = {
3461 + .owner = THIS_MODULE,
3462 + .llseek = no_llseek,
3463 + .read = hostaudio_read,
3464 + .write = hostaudio_write,
3465 + .poll = hostaudio_poll,
3466 + .ioctl = hostaudio_ioctl,
3468 + .open = hostaudio_open,
3469 + .release = hostaudio_release,
3472 +static struct file_operations hostmixer_fops = {
3473 + .owner = THIS_MODULE,
3474 + .llseek = no_llseek,
3475 + .ioctl = hostmixer_ioctl_mixdev,
3476 + .open = hostmixer_open_mixdev,
3477 + .release = hostmixer_release,
3485 +MODULE_AUTHOR("Steve Schmidtke");
3486 +MODULE_DESCRIPTION("UML Audio Relay");
3487 +MODULE_LICENSE("GPL");
3489 +static int __init hostaudio_init_module(void)
3491 + printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
3494 + module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
3495 + if(module_data.dev_audio < 0){
3496 + printk(KERN_ERR "hostaudio: couldn't register DSP device!\n");
3500 + module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1);
3501 + if(module_data.dev_mixer < 0){
3502 + printk(KERN_ERR "hostmixer: couldn't register mixer "
3504 + unregister_sound_dsp(module_data.dev_audio);
3511 +static void __exit hostaudio_cleanup_module (void)
3513 + unregister_sound_mixer(module_data.dev_mixer);
3514 + unregister_sound_dsp(module_data.dev_audio);
3517 +module_init(hostaudio_init_module);
3518 +module_exit(hostaudio_cleanup_module);
3521 + * Overrides for Emacs so that we follow Linus's tabbing style.
3522 + * Emacs will notice this stuff at the end of the file and automatically
3523 + * adjust the settings for this buffer only. This must remain at the end
3525 + * ---------------------------------------------------------------------------
3526 + * Local variables:
3527 + * c-file-style: "linux"
3530 diff -Naur -X ../exclude-files orig/arch/um/drivers/hostaudio_user.c um/arch/um/drivers/hostaudio_user.c
3531 --- orig/arch/um/drivers/hostaudio_user.c Wed Dec 31 19:00:00 1969
3532 +++ um/arch/um/drivers/hostaudio_user.c Wed Oct 23 21:08:04 2002
3535 + * Copyright (C) 2002 Steve Schmidtke
3536 + * Licensed under the GPL
3539 +#include <sys/types.h>
3540 +#include <sys/stat.h>
3541 +#include <sys/ioctl.h>
3543 +#include <unistd.h>
3545 +#include "hostaudio.h"
3546 +#include "user_util.h"
3547 +#include "kern_util.h"
3551 +/* /dev/dsp file operations */
3553 +ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer,
3554 + size_t count, loff_t *ppos)
3559 + printk("hostaudio: read_user called, count = %d\n", count);
3562 + ret = read(state->fd, buffer, count);
3564 + if(ret < 0) return(-errno);
3568 +ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer,
3569 + size_t count, loff_t *ppos)
3574 + printk("hostaudio: write_user called, count = %d\n", count);
3577 + ret = write(state->fd, buffer, count);
3579 + if(ret < 0) return(-errno);
3583 +int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd,
3584 + unsigned long arg)
3588 + printk("hostaudio: ioctl_user called, cmd = %u\n", cmd);
3591 + ret = ioctl(state->fd, cmd, arg);
3593 + if(ret < 0) return(-errno);
3597 +int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp)
3600 + printk("hostaudio: open_user called\n");
3603 + state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
3605 + if(state->fd >= 0) return(0);
3607 + printk("hostaudio_open_user failed to open '%s', errno = %d\n",
3613 +int hostaudio_release_user(struct hostaudio_state *state)
3616 + printk("hostaudio: release called\n");
3618 + if(state->fd >= 0){
3626 +/* /dev/mixer file operations */
3628 +int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state,
3629 + unsigned int cmd, unsigned long arg)
3633 + printk("hostmixer: ioctl_user called cmd = %u\n",cmd);
3636 + ret = ioctl(state->fd, cmd, arg);
3642 +int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w,
3646 + printk("hostmixer: open_user called\n");
3649 + state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
3651 + if(state->fd >= 0) return(0);
3653 + printk("hostaudio_open_mixdev_user failed to open '%s', errno = %d\n",
3659 +int hostmixer_release_mixdev_user(struct hostmixer_state *state)
3662 + printk("hostmixer: release_user called\n");
3665 + if(state->fd >= 0){
3674 + * Overrides for Emacs so that we follow Linus's tabbing style.
3675 + * Emacs will notice this stuff at the end of the file and automatically
3676 + * adjust the settings for this buffer only. This must remain at the end
3678 + * ---------------------------------------------------------------------------
3679 + * Local variables:
3680 + * c-file-style: "linux"
3683 diff -Naur -X ../exclude-files orig/arch/um/drivers/line.c um/arch/um/drivers/line.c
3684 --- orig/arch/um/drivers/line.c Wed Dec 31 19:00:00 1969
3685 +++ um/arch/um/drivers/line.c Wed Mar 26 15:09:44 2003
3688 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3689 + * Licensed under the GPL
3692 +#include "linux/sched.h"
3693 +#include "linux/slab.h"
3694 +#include "linux/list.h"
3695 +#include "linux/devfs_fs_kernel.h"
3696 +#include "asm/irq.h"
3697 +#include "asm/uaccess.h"
3698 +#include "chan_kern.h"
3699 +#include "irq_user.h"
3702 +#include "user_util.h"
3703 +#include "kern_util.h"
3706 +#define LINE_BUFSIZE 4096
3708 +void line_interrupt(int irq, void *data, struct pt_regs *unused)
3710 + struct line *dev = data;
3712 + if(dev->count > 0)
3713 + chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq,
3717 +void line_timer_cb(void *arg)
3719 + struct line *dev = arg;
3721 + line_interrupt(dev->driver->read_irq, dev, NULL);
3724 +static void buffer_data(struct line *line, const char *buf, int len)
3728 + if(line->buffer == NULL){
3729 + line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
3730 + if(line->buffer == NULL){
3731 + printk("buffer_data - atomic allocation failed\n");
3734 + line->head = line->buffer;
3735 + line->tail = line->buffer;
3737 + end = line->buffer + LINE_BUFSIZE - line->tail;
3739 + memcpy(line->tail, buf, len);
3740 + line->tail += len;
3743 + memcpy(line->tail, buf, end);
3746 + memcpy(line->buffer, buf, len);
3747 + line->tail = line->buffer + len;
3751 +static int flush_buffer(struct line *line)
3755 + if((line->buffer == NULL) || (line->head == line->tail)) return(1);
3757 + if(line->tail < line->head){
3758 + count = line->buffer + LINE_BUFSIZE - line->head;
3759 + n = write_chan(&line->chan_list, line->head, count,
3760 + line->driver->write_irq);
3761 + if(n < 0) return(n);
3762 + if(n == count) line->head = line->buffer;
3769 + count = line->tail - line->head;
3770 + n = write_chan(&line->chan_list, line->head, count,
3771 + line->driver->write_irq);
3772 + if(n < 0) return(n);
3775 + return(line->head == line->tail);
3778 +int line_write(struct line *lines, struct tty_struct *tty, int from_user,
3779 + const char *buf, int len)
3781 + struct line *line;
3783 + unsigned long flags;
3786 + if(tty->stopped) return 0;
3789 + new = kmalloc(len, GFP_KERNEL);
3792 + n = copy_from_user(new, buf, len);
3798 + i = minor(tty->device) - tty->driver.minor_start;
3802 + if(line->head != line->tail){
3803 + local_irq_save(flags);
3804 + buffer_data(line, buf, len);
3805 + err = flush_buffer(line);
3806 + local_irq_restore(flags);
3811 + n = write_chan(&line->chan_list, buf, len,
3812 + line->driver->write_irq);
3818 + buffer_data(line, buf + n, len - n);
3828 +void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
3830 + struct line *dev = data;
3831 + struct tty_struct *tty = dev->tty;
3834 + err = flush_buffer(dev);
3835 + if(err == 0) return;
3837 + dev->head = dev->buffer;
3838 + dev->tail = dev->buffer;
3841 + if(tty == NULL) return;
3843 + if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
3844 + (tty->ldisc.write_wakeup != NULL))
3845 + (tty->ldisc.write_wakeup)(tty);
3848 + * In blocking mode, everything sleeps on tty->write_wait.
3849 + * Sleeping in the console driver would break non-blocking
3853 + if (waitqueue_active(&tty->write_wait))
3854 + wake_up_interruptible(&tty->write_wait);
3858 +int line_write_room(struct tty_struct *tty)
3860 + struct line *dev = tty->driver_data;
3863 + if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
3865 + n = dev->head - dev->tail;
3866 + if(n <= 0) n = LINE_BUFSIZE + n;
3870 +int line_setup_irq(int fd, int input, int output, void *data)
3872 + struct line *line = data;
3873 + struct line_driver *driver = line->driver;
3874 + int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
3876 + if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ,
3877 + line_interrupt, flags,
3878 + driver->read_irq_name, line);
3879 + if(err) return(err);
3880 + if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
3881 + line_write_interrupt, flags,
3882 + driver->write_irq_name, line);
3883 + line->have_irq = 1;
3887 +void line_disable(struct line *line, int current_irq)
3889 + if(!line->have_irq) return;
3891 + if(line->driver->read_irq == current_irq)
3892 + free_irq_later(line->driver->read_irq, line);
3894 + free_irq(line->driver->read_irq, line);
3896 + if(line->driver->write_irq == current_irq)
3897 + free_irq_later(line->driver->write_irq, line);
3899 + free_irq(line->driver->write_irq, line);
3901 + line->have_irq = 0;
3904 +int line_open(struct line *lines, struct tty_struct *tty,
3905 + struct chan_opts *opts)
3907 + struct line *line;
3910 + if(tty == NULL) n = 0;
3911 + else n = minor(tty->device) - tty->driver.minor_start;
3915 + if(line->count == 0){
3920 + if(list_empty(&line->chan_list)){
3921 + err = parse_chan_pair(line->init_str, &line->chan_list,
3922 + line->init_pri, n, opts);
3924 + err = open_chan(&line->chan_list);
3927 + enable_chan(&line->chan_list, line);
3928 + INIT_TQUEUE(&line->task, line_timer_cb, line);
3932 + chan_enable_winch(&line->chan_list, line);
3936 + /* This is outside the if because the initial console is opened
3937 + * with tty == NULL
3942 + tty->driver_data = line;
3943 + chan_window_size(&line->chan_list, &tty->winsize.ws_row,
3944 + &tty->winsize.ws_col);
3953 +void line_close(struct line *lines, struct tty_struct *tty)
3955 + struct line *line;
3958 + if(tty == NULL) n = 0;
3959 + else n = minor(tty->device) - tty->driver.minor_start;
3965 + /* I don't like this, but I can't think of anything better. What's
3966 + * going on is that the tty is in the process of being closed for
3967 + * the last time. Its count hasn't been dropped yet, so it's still
3968 + * at 1. This may happen when line->count != 0 because of the initial
3969 + * console open (without a tty) bumping it up to 1.
3971 + if((line->tty != NULL) && (line->tty->count == 1))
3973 + if(line->count == 0)
3974 + line_disable(line, -1);
3978 +void close_lines(struct line *lines, int nlines)
3982 + for(i = 0; i < nlines; i++)
3983 + close_chan(&lines[i].chan_list);
3986 +int line_setup(struct line *lines, int num, char *init, int all_allowed)
3991 + if(*init == '=') n = -1;
3993 + n = simple_strtoul(init, &end, 0);
3995 + printk(KERN_ERR "line_setup failed to parse \"%s\"\n",
4002 + if((n >= 0) && (n >= num)){
4003 + printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
4008 + if(lines[n].count > 0){
4009 + printk("line_setup - device %d is open\n", n);
4012 + if(lines[n].init_pri <= INIT_ONE){
4013 + lines[n].init_pri = INIT_ONE;
4014 + if(!strcmp(init, "none")) lines[n].valid = 0;
4016 + lines[n].init_str = init;
4017 + lines[n].valid = 1;
4021 + else if(!all_allowed){
4022 + printk("line_setup - can't configure all devices from "
4027 + for(i = 0; i < num; i++){
4028 + if(lines[i].init_pri <= INIT_ALL){
4029 + lines[i].init_pri = INIT_ALL;
4030 + if(!strcmp(init, "none")) lines[i].valid = 0;
4032 + lines[i].init_str = init;
4033 + lines[i].valid = 1;
4041 +int line_config(struct line *lines, int num, char *str)
4043 + char *new = uml_strdup(str);
4046 + printk("line_config - uml_strdup failed\n");
4049 + return(line_setup(lines, num, new, 0));
4052 +int line_get_config(char *name, struct line *lines, int num, char *str,
4053 + int size, char **error_out)
4055 + struct line *line;
4059 + dev = simple_strtoul(name, &end, 0);
4060 + if((*end != '\0') || (end == name)){
4061 + *error_out = "line_get_config failed to parse device number";
4065 + if((dev < 0) || (dev >= num)){
4066 + *error_out = "device number of of range";
4070 + line = &lines[dev];
4074 + CONFIG_CHUNK(str, size, n, "none", 1);
4075 + else if(line->count == 0)
4076 + CONFIG_CHUNK(str, size, n, line->init_str, 1);
4077 + else n = chan_config_string(&line->chan_list, str, size, error_out);
4083 +int line_remove(struct line *lines, int num, char *str)
4085 + char config[sizeof("conxxxx=none\0")];
4087 + sprintf(config, "%s=none", str);
4088 + return(line_setup(lines, num, config, 0));
4091 +void line_register_devfs(struct lines *set, struct line_driver *line_driver,
4092 + struct tty_driver *driver, struct line *lines,
4098 + driver->driver_name = line_driver->name;
4099 + driver->name = line_driver->devfs_name;
4100 + driver->major = line_driver->major;
4101 + driver->minor_start = line_driver->minor_start;
4102 + driver->type = line_driver->type;
4103 + driver->subtype = line_driver->subtype;
4104 + driver->magic = TTY_DRIVER_MAGIC;
4105 + driver->flags = TTY_DRIVER_REAL_RAW;
4109 + driver->table = kmalloc(n * sizeof(driver->table[0]), GFP_KERNEL);
4110 + driver->termios = kmalloc(n * sizeof(driver->termios[0]), GFP_KERNEL);
4111 + driver->termios_locked = kmalloc(n * sizeof(driver->termios_locked[0]),
4113 + if((driver->table == NULL) || (driver->termios == NULL) ||
4114 + (driver->termios_locked == NULL))
4115 + panic("Failed to allocate driver table");
4117 + memset(driver->table, 0, n * sizeof(driver->table[0]));
4118 + memset(driver->termios, 0, n * sizeof(driver->termios[0]));
4119 + memset(driver->termios_locked, 0,
4120 + n * sizeof(driver->termios_locked[0]));
4122 + driver->write_room = line_write_room;
4123 + driver->init_termios = tty_std_termios;
4125 + if (tty_register_driver(driver))
4126 + panic("line_register_devfs : Couldn't register driver\n");
4128 + from = line_driver->symlink_from;
4129 + to = line_driver->symlink_to;
4130 + err = devfs_mk_symlink(NULL, from, 0, to, NULL, NULL);
4131 + if(err) printk("Symlink creation from /dev/%s to /dev/%s "
4132 + "returned %d\n", from, to, err);
4134 + for(i = 0; i < nlines; i++){
4135 + if(!lines[i].valid)
4136 + tty_unregister_devfs(driver, driver->minor_start + i);
4139 + mconsole_register_dev(&line_driver->mc);
4142 +void lines_init(struct line *lines, int nlines)
4144 + struct line *line;
4147 + for(i = 0; i < nlines; i++){
4149 + INIT_LIST_HEAD(&line->chan_list);
4150 + sema_init(&line->sem, 1);
4151 + if(line->init_str != NULL){
4152 + line->init_str = uml_strdup(line->init_str);
4153 + if(line->init_str == NULL)
4154 + printk("lines_init - uml_strdup returned "
4161 + struct list_head list;
4165 + struct line *line;
4168 +void winch_interrupt(int irq, void *data, struct pt_regs *unused)
4170 + struct winch *winch = data;
4171 + struct tty_struct *tty;
4175 + if(winch->fd != -1){
4176 + err = generic_read(winch->fd, &c, NULL);
4178 + if(err != -EAGAIN){
4179 + printk("winch_interrupt : read failed, "
4180 + "errno = %d\n", -err);
4181 + printk("fd %d is losing SIGWINCH support\n",
4188 + tty = winch->line->tty;
4190 + chan_window_size(&winch->line->chan_list,
4191 + &tty->winsize.ws_row,
4192 + &tty->winsize.ws_col);
4193 + kill_pg(tty->pgrp, SIGWINCH, 1);
4196 + if(winch->fd != -1)
4197 + reactivate_fd(winch->fd, WINCH_IRQ);
4200 +DECLARE_MUTEX(winch_handler_sem);
4201 +LIST_HEAD(winch_handlers);
4203 +void register_winch_irq(int fd, int tty_fd, int pid, void *line)
4205 + struct winch *winch;
4207 + down(&winch_handler_sem);
4208 + winch = kmalloc(sizeof(*winch), GFP_KERNEL);
4209 + if(winch == NULL){
4210 + printk("register_winch_irq - kmalloc failed\n");
4213 + *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list),
4218 + list_add(&winch->list, &winch_handlers);
4219 + if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
4220 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
4221 + "winch", winch) < 0)
4222 + printk("register_winch_irq - failed to register IRQ\n");
4224 + up(&winch_handler_sem);
4227 +static void winch_cleanup(void)
4229 + struct list_head *ele;
4230 + struct winch *winch;
4232 + list_for_each(ele, &winch_handlers){
4233 + winch = list_entry(ele, struct winch, list);
4234 + if(winch->fd != -1){
4235 + deactivate_fd(winch->fd, WINCH_IRQ);
4238 + if(winch->pid != -1)
4239 + os_kill_process(winch->pid, 1);
4243 +__uml_exitcall(winch_cleanup);
4245 +char *add_xterm_umid(char *base)
4247 + char *umid, *title;
4250 + umid = get_umid(1);
4251 + if(umid == NULL) return(base);
4253 + len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
4254 + title = kmalloc(len, GFP_KERNEL);
4255 + if(title == NULL){
4256 + printk("Failed to allocate buffer for xterm title\n");
4260 + strncpy(title, base, len);
4261 + len -= strlen(title);
4262 + snprintf(&title[strlen(title)], len, " (%s)", umid);
4267 + * Overrides for Emacs so that we follow Linus's tabbing style.
4268 + * Emacs will notice this stuff at the end of the file and automatically
4269 + * adjust the settings for this buffer only. This must remain at the end
4271 + * ---------------------------------------------------------------------------
4272 + * Local variables:
4273 + * c-file-style: "linux"
4276 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast.h um/arch/um/drivers/mcast.h
4277 --- orig/arch/um/drivers/mcast.h Wed Dec 31 19:00:00 1969
4278 +++ um/arch/um/drivers/mcast.h Wed Oct 23 21:08:04 2002
4281 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
4282 + * Licensed under the GPL
4285 +#include "net_user.h"
4287 +struct mcast_data {
4289 + unsigned short port;
4295 +extern struct net_user_info mcast_user_info;
4297 +extern int mcast_user_write(int fd, void *buf, int len,
4298 + struct mcast_data *pri);
4301 + * Overrides for Emacs so that we follow Linus's tabbing style.
4302 + * Emacs will notice this stuff at the end of the file and automatically
4303 + * adjust the settings for this buffer only. This must remain at the end
4305 + * ---------------------------------------------------------------------------
4306 + * Local variables:
4307 + * c-file-style: "linux"
4310 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_kern.c um/arch/um/drivers/mcast_kern.c
4311 --- orig/arch/um/drivers/mcast_kern.c Wed Dec 31 19:00:00 1969
4312 +++ um/arch/um/drivers/mcast_kern.c Sun Dec 15 20:58:55 2002
4315 + * user-mode-linux networking multicast transport
4316 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4318 + * based on the existing uml-networking code, which is
4319 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
4320 + * James Leu (jleu@mindspring.net).
4321 + * Copyright (C) 2001 by various other people who didn't put their name here.
4323 + * Licensed under the GPL.
4326 +#include "linux/kernel.h"
4327 +#include "linux/init.h"
4328 +#include "linux/netdevice.h"
4329 +#include "linux/etherdevice.h"
4330 +#include "linux/in.h"
4331 +#include "linux/inet.h"
4332 +#include "net_kern.h"
4333 +#include "net_user.h"
4336 +struct mcast_init {
4342 +void mcast_init(struct net_device *dev, void *data)
4344 + struct uml_net_private *pri;
4345 + struct mcast_data *dpri;
4346 + struct mcast_init *init = data;
4348 + init_etherdev(dev, 0);
4350 + dpri = (struct mcast_data *) pri->user;
4351 + *dpri = ((struct mcast_data)
4352 + { .addr = init->addr,
4353 + .port = init->port,
4355 + .mcast_addr = NULL,
4357 + printk("mcast backend ");
4358 + printk("multicast adddress: %s:%u, TTL:%u ",
4359 + dpri->addr, dpri->port, dpri->ttl);
4364 +static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
4366 + *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
4367 + if(*skb == NULL) return(-ENOMEM);
4368 + return(net_recvfrom(fd, (*skb)->mac.raw,
4369 + (*skb)->dev->mtu + ETH_HEADER_OTHER));
4372 +static int mcast_write(int fd, struct sk_buff **skb,
4373 + struct uml_net_private *lp)
4375 + return mcast_user_write(fd, (*skb)->data, (*skb)->len,
4376 + (struct mcast_data *) &lp->user);
4379 +static struct net_kern_info mcast_kern_info = {
4380 + .init = mcast_init,
4381 + .protocol = eth_protocol,
4382 + .read = mcast_read,
4383 + .write = mcast_write,
4386 +int mcast_setup(char *str, char **mac_out, void *data)
4388 + struct mcast_init *init = data;
4389 + char *port_str = NULL, *ttl_str = NULL, *remain;
4393 + *init = ((struct mcast_init)
4394 + { .addr = "239.192.168.1",
4398 + remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
4400 + if(remain != NULL){
4401 + printk(KERN_ERR "mcast_setup - Extra garbage on "
4402 + "specification : '%s'\n", remain);
4406 + if(port_str != NULL){
4407 + n = simple_strtoul(port_str, &last, 10);
4408 + if((*last != '\0') || (last == port_str)){
4409 + printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
4413 + init->port = htons(n);
4416 + if(ttl_str != NULL){
4417 + init->ttl = simple_strtoul(ttl_str, &last, 10);
4418 + if((*last != '\0') || (last == ttl_str)){
4419 + printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
4425 + printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
4426 + init->port, init->ttl);
4431 +static struct transport mcast_transport = {
4432 + .list = LIST_HEAD_INIT(mcast_transport.list),
4434 + .setup = mcast_setup,
4435 + .user = &mcast_user_info,
4436 + .kern = &mcast_kern_info,
4437 + .private_size = sizeof(struct mcast_data),
4438 + .setup_size = sizeof(struct mcast_init),
4441 +static int register_mcast(void)
4443 + register_transport(&mcast_transport);
4447 +__initcall(register_mcast);
4450 + * Overrides for Emacs so that we follow Linus's tabbing style.
4451 + * Emacs will notice this stuff at the end of the file and automatically
4452 + * adjust the settings for this buffer only. This must remain at the end
4454 + * ---------------------------------------------------------------------------
4455 + * Local variables:
4456 + * c-file-style: "linux"
4459 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_user.c um/arch/um/drivers/mcast_user.c
4460 --- orig/arch/um/drivers/mcast_user.c Wed Dec 31 19:00:00 1969
4461 +++ um/arch/um/drivers/mcast_user.c Sun Dec 15 21:19:16 2002
4464 + * user-mode-linux networking multicast transport
4465 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4467 + * based on the existing uml-networking code, which is
4468 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
4469 + * James Leu (jleu@mindspring.net).
4470 + * Copyright (C) 2001 by various other people who didn't put their name here.
4472 + * Licensed under the GPL.
4477 +#include <unistd.h>
4478 +#include <linux/inet.h>
4479 +#include <sys/socket.h>
4480 +#include <sys/un.h>
4481 +#include <sys/time.h>
4482 +#include <netinet/in.h>
4483 +#include "net_user.h"
4485 +#include "kern_util.h"
4486 +#include "user_util.h"
4489 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
4491 +static struct sockaddr_in *new_addr(char *addr, unsigned short port)
4493 + struct sockaddr_in *sin;
4495 + sin = um_kmalloc(sizeof(struct sockaddr_in));
4497 + printk("new_addr: allocation of sockaddr_in failed\n");
4500 + sin->sin_family = AF_INET;
4501 + sin->sin_addr.s_addr = in_aton(addr);
4502 + sin->sin_port = port;
4506 +static void mcast_user_init(void *data, void *dev)
4508 + struct mcast_data *pri = data;
4510 + pri->mcast_addr = new_addr(pri->addr, pri->port);
4514 +static int mcast_open(void *data)
4516 + struct mcast_data *pri = data;
4517 + struct sockaddr_in *sin = pri->mcast_addr;
4518 + struct ip_mreq mreq;
4522 + if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) {
4527 + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
4528 + printk("mcast_open : data socket failed, errno = %d\n",
4534 + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
4535 + printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
4542 + /* set ttl according to config */
4543 + if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
4544 + sizeof(pri->ttl)) < 0) {
4545 + printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
4552 + /* set LOOP, so data does get fed back to local sockets */
4553 + if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
4554 + printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
4561 + /* bind socket to mcast address */
4562 + if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
4563 + printk("mcast_open : data bind failed, errno = %d\n", errno);
4569 + /* subscribe to the multicast group */
4570 + mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
4571 + mreq.imr_interface.s_addr = 0;
4572 + if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
4573 + &mreq, sizeof(mreq)) < 0) {
4574 + printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n",
4576 + printk("There appears not to be a multicast-capable network "
4577 + "interface on the host.\n");
4578 + printk("eth0 should be configured in order to use the "
4579 + "multicast transport.\n");
4588 +static void mcast_close(int fd, void *data)
4590 + struct ip_mreq mreq;
4591 + struct mcast_data *pri = data;
4592 + struct sockaddr_in *sin = pri->mcast_addr;
4594 + mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
4595 + mreq.imr_interface.s_addr = 0;
4596 + if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
4597 + &mreq, sizeof(mreq)) < 0) {
4598 + printk("mcast_open: IP_DROP_MEMBERSHIP failed, error = %d\n",
4605 +int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
4607 + struct sockaddr_in *data_addr = pri->mcast_addr;
4609 + return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
4612 +static int mcast_set_mtu(int mtu, void *data)
4617 +struct net_user_info mcast_user_info = {
4618 + .init = mcast_user_init,
4619 + .open = mcast_open,
4620 + .close = mcast_close,
4622 + .set_mtu = mcast_set_mtu,
4623 + .add_address = NULL,
4624 + .delete_address = NULL,
4625 + .max_packet = MAX_PACKET - ETH_HEADER_OTHER
4629 + * Overrides for Emacs so that we follow Linus's tabbing style.
4630 + * Emacs will notice this stuff at the end of the file and automatically
4631 + * adjust the settings for this buffer only. This must remain at the end
4633 + * ---------------------------------------------------------------------------
4634 + * Local variables:
4635 + * c-file-style: "linux"
4638 diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_kern.c um/arch/um/drivers/mconsole_kern.c
4639 --- orig/arch/um/drivers/mconsole_kern.c Wed Dec 31 19:00:00 1969
4640 +++ um/arch/um/drivers/mconsole_kern.c Fri Mar 28 21:58:11 2003
4643 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
4644 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4645 + * Licensed under the GPL
4648 +#include "linux/kernel.h"
4649 +#include "linux/slab.h"
4650 +#include "linux/init.h"
4651 +#include "linux/notifier.h"
4652 +#include "linux/reboot.h"
4653 +#include "linux/utsname.h"
4654 +#include "linux/ctype.h"
4655 +#include "linux/interrupt.h"
4656 +#include "linux/sysrq.h"
4657 +#include "linux/tqueue.h"
4658 +#include "linux/module.h"
4659 +#include "linux/proc_fs.h"
4660 +#include "asm/irq.h"
4661 +#include "asm/uaccess.h"
4662 +#include "user_util.h"
4663 +#include "kern_util.h"
4665 +#include "mconsole.h"
4666 +#include "mconsole_kern.h"
4667 +#include "irq_user.h"
4672 +static int do_unlink_socket(struct notifier_block *notifier,
4673 + unsigned long what, void *data)
4675 + return(mconsole_unlink_socket());
4679 +static struct notifier_block reboot_notifier = {
4680 + .notifier_call = do_unlink_socket,
4684 +/* Safe without explicit locking for now. Tasklets provide their own
4685 + * locking, and the interrupt handler is safe because it can't interrupt
4686 + * itself and it can only happen on CPU 0.
4689 +LIST_HEAD(mc_requests);
4691 +void mc_task_proc(void *unused)
4693 + struct mconsole_entry *req;
4694 + unsigned long flags;
4698 + save_flags(flags);
4699 + req = list_entry(mc_requests.next, struct mconsole_entry,
4701 + list_del(&req->list);
4702 + done = list_empty(&mc_requests);
4703 + restore_flags(flags);
4704 + req->request.cmd->handler(&req->request);
4709 +struct tq_struct mconsole_task = {
4710 + .routine = mc_task_proc,
4714 +void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
4717 + struct mconsole_entry *new;
4718 + struct mc_request req;
4720 + fd = (int) dev_id;
4721 + while (mconsole_get_request(fd, &req)){
4722 + if(req.cmd->as_interrupt) (*req.cmd->handler)(&req);
4724 + new = kmalloc(sizeof(req), GFP_ATOMIC);
4726 + mconsole_reply(&req, "Out of memory", 1, 0);
4728 + new->request = req;
4729 + list_add(&new->list, &mc_requests);
4733 + if(!list_empty(&mc_requests)) schedule_task(&mconsole_task);
4734 + reactivate_fd(fd, MCONSOLE_IRQ);
4737 +void mconsole_version(struct mc_request *req)
4739 + char version[256];
4741 + sprintf(version, "%s %s %s %s %s", system_utsname.sysname,
4742 + system_utsname.nodename, system_utsname.release,
4743 + system_utsname.version, system_utsname.machine);
4744 + mconsole_reply(req, version, 0, 0);
4747 +#define UML_MCONSOLE_HELPTEXT \
4749 + version - Get kernel version \n\
4750 + help - Print this message \n\
4751 + halt - Halt UML \n\
4752 + reboot - Reboot UML \n\
4753 + config <dev>=<config> - Add a new device to UML; \n\
4754 + same syntax as command line \n\
4755 + config <dev> - Query the configuration of a device \n\
4756 + remove <dev> - Remove a device from UML \n\
4757 + sysrq <letter> - Performs the SysRq action controlled by the letter \n\
4758 + cad - invoke the Ctl-Alt-Del handler \n\
4759 + stop - pause the UML; it will do nothing until it receives a 'go' \n\
4760 + go - continue the UML after a 'stop' \n\
4763 +void mconsole_help(struct mc_request *req)
4765 + mconsole_reply(req, UML_MCONSOLE_HELPTEXT, 0, 0);
4768 +void mconsole_halt(struct mc_request *req)
4770 + mconsole_reply(req, "", 0, 0);
4774 +void mconsole_reboot(struct mc_request *req)
4776 + mconsole_reply(req, "", 0, 0);
4777 + machine_restart(NULL);
4780 +extern void ctrl_alt_del(void);
4782 +void mconsole_cad(struct mc_request *req)
4784 + mconsole_reply(req, "", 0, 0);
4788 +void mconsole_go(struct mc_request *req)
4790 + mconsole_reply(req, "Not stopped", 1, 0);
4793 +void mconsole_stop(struct mc_request *req)
4795 + deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
4796 + os_set_fd_block(req->originating_fd, 1);
4797 + mconsole_reply(req, "", 0, 0);
4798 + while(mconsole_get_request(req->originating_fd, req)){
4799 + if(req->cmd->handler == mconsole_go) break;
4800 + (*req->cmd->handler)(req);
4802 + os_set_fd_block(req->originating_fd, 0);
4803 + reactivate_fd(req->originating_fd, MCONSOLE_IRQ);
4804 + mconsole_reply(req, "", 0, 0);
4807 +/* This list is populated by __initcall routines. */
4809 +LIST_HEAD(mconsole_devices);
4811 +void mconsole_register_dev(struct mc_device *new)
4813 + list_add(&new->list, &mconsole_devices);
4816 +static struct mc_device *mconsole_find_dev(char *name)
4818 + struct list_head *ele;
4819 + struct mc_device *dev;
4821 + list_for_each(ele, &mconsole_devices){
4822 + dev = list_entry(ele, struct mc_device, list);
4823 + if(!strncmp(name, dev->name, strlen(dev->name)))
4829 +#define CONFIG_BUF_SIZE 64
4831 +static void mconsole_get_config(int (*get_config)(char *, char *, int,
4833 + struct mc_request *req, char *name)
4835 + char default_buf[CONFIG_BUF_SIZE], *error, *buf;
4838 + if(get_config == NULL){
4839 + mconsole_reply(req, "No get_config routine defined", 1, 0);
4844 + size = sizeof(default_buf)/sizeof(default_buf[0]);
4845 + buf = default_buf;
4848 + n = (*get_config)(name, buf, size, &error);
4849 + if(error != NULL){
4850 + mconsole_reply(req, error, 1, 0);
4855 + mconsole_reply(req, buf, 0, 0);
4859 + if(buf != default_buf)
4863 + buf = kmalloc(size, GFP_KERNEL);
4865 + mconsole_reply(req, "Failed to allocate buffer", 1, 0);
4870 + if(buf != default_buf)
4875 +void mconsole_config(struct mc_request *req)
4877 + struct mc_device *dev;
4878 + char *ptr = req->request.data, *name;
4881 + ptr += strlen("config");
4882 + while(isspace(*ptr)) ptr++;
4883 + dev = mconsole_find_dev(ptr);
4885 + mconsole_reply(req, "Bad configuration option", 1, 0);
4889 + name = &ptr[strlen(dev->name)];
4891 + while((*ptr != '=') && (*ptr != '\0'))
4895 + err = (*dev->config)(name);
4896 + mconsole_reply(req, "", err, 0);
4898 + else mconsole_get_config(dev->get_config, req, name);
4901 +void mconsole_remove(struct mc_request *req)
4903 + struct mc_device *dev;
4904 + char *ptr = req->request.data;
4907 + ptr += strlen("remove");
4908 + while(isspace(*ptr)) ptr++;
4909 + dev = mconsole_find_dev(ptr);
4911 + mconsole_reply(req, "Bad remove option", 1, 0);
4914 + err = (*dev->remove)(&ptr[strlen(dev->name)]);
4915 + mconsole_reply(req, "", err, 0);
4918 +#ifdef CONFIG_MAGIC_SYSRQ
4919 +void mconsole_sysrq(struct mc_request *req)
4921 + char *ptr = req->request.data;
4923 + ptr += strlen("sysrq");
4924 + while(isspace(*ptr)) ptr++;
4926 + handle_sysrq(*ptr, ¤t->thread.regs, NULL, NULL);
4927 + mconsole_reply(req, "", 0, 0);
4930 +void mconsole_sysrq(struct mc_request *req)
4932 + mconsole_reply(req, "Sysrq not compiled in", 1, 0);
4936 +/* Changed by mconsole_setup, which is __setup, and called before SMP is
4939 +static char *notify_socket = NULL;
4941 +int mconsole_init(void)
4946 + if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
4947 + snprintf(mconsole_socket_name, sizeof(file), "%s", file);
4949 + sock = create_unix_socket(file, sizeof(file));
4951 + printk("Failed to initialize management console\n");
4955 + register_reboot_notifier(&reboot_notifier);
4957 + err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
4958 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
4959 + "mconsole", (void *)sock);
4961 + printk("Failed to get IRQ for management console\n");
4965 + if(notify_socket != NULL){
4966 + notify_socket = uml_strdup(notify_socket);
4967 + if(notify_socket != NULL)
4968 + mconsole_notify(notify_socket, MCONSOLE_SOCKET,
4969 + mconsole_socket_name,
4970 + strlen(mconsole_socket_name) + 1);
4971 + else printk(KERN_ERR "mconsole_setup failed to strdup "
4975 + printk("mconsole (version %d) initialized on %s\n",
4976 + MCONSOLE_VERSION, mconsole_socket_name);
4980 +__initcall(mconsole_init);
4982 +static int write_proc_mconsole(struct file *file, const char *buffer,
4983 + unsigned long count, void *data)
4987 + buf = kmalloc(count + 1, GFP_KERNEL);
4991 + if(copy_from_user(buf, buffer, count))
4993 + buf[count] = '\0';
4995 + mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
4999 +static int create_proc_mconsole(void)
5001 + struct proc_dir_entry *ent;
5003 + if(notify_socket == NULL) return(0);
5005 + ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
5007 + printk("create_proc_mconsole : create_proc_entry failed\n");
5011 + ent->read_proc = NULL;
5012 + ent->write_proc = write_proc_mconsole;
5016 +static spinlock_t notify_spinlock = SPIN_LOCK_UNLOCKED;
5018 +void lock_notify(void)
5020 + spin_lock(¬ify_spinlock);
5023 +void unlock_notify(void)
5025 + spin_unlock(¬ify_spinlock);
5028 +__initcall(create_proc_mconsole);
5030 +#define NOTIFY "=notify:"
5032 +static int mconsole_setup(char *str)
5034 + if(!strncmp(str, NOTIFY, strlen(NOTIFY))){
5035 + str += strlen(NOTIFY);
5036 + notify_socket = str;
5038 + else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str);
5042 +__setup("mconsole", mconsole_setup);
5044 +__uml_help(mconsole_setup,
5045 +"mconsole=notify:<socket>\n"
5046 +" Requests that the mconsole driver send a message to the named Unix\n"
5047 +" socket containing the name of the mconsole socket. This also serves\n"
5048 +" to notify outside processes when UML has booted far enough to respond\n"
5049 +" to mconsole requests.\n\n"
5052 +static int notify_panic(struct notifier_block *self, unsigned long unused1,
5055 + char *message = ptr;
5057 + if(notify_socket == NULL) return(0);
5059 + mconsole_notify(notify_socket, MCONSOLE_PANIC, message,
5060 + strlen(message) + 1);
5064 +static struct notifier_block panic_exit_notifier = {
5065 + .notifier_call = notify_panic,
5070 +static int add_notifier(void)
5072 + notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
5076 +__initcall(add_notifier);
5078 +char *mconsole_notify_socket(void)
5080 + return(notify_socket);
5083 +EXPORT_SYMBOL(mconsole_notify_socket);
5086 + * Overrides for Emacs so that we follow Linus's tabbing style.
5087 + * Emacs will notice this stuff at the end of the file and automatically
5088 + * adjust the settings for this buffer only. This must remain at the end
5090 + * ---------------------------------------------------------------------------
5091 + * Local variables:
5092 + * c-file-style: "linux"
5095 diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_user.c um/arch/um/drivers/mconsole_user.c
5096 --- orig/arch/um/drivers/mconsole_user.c Wed Dec 31 19:00:00 1969
5097 +++ um/arch/um/drivers/mconsole_user.c Wed Oct 23 21:08:04 2002
5100 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
5101 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
5102 + * Licensed under the GPL
5106 +#include <stdlib.h>
5108 +#include <signal.h>
5109 +#include <sys/socket.h>
5110 +#include <sys/types.h>
5111 +#include <sys/uio.h>
5112 +#include <sys/un.h>
5113 +#include <unistd.h>
5115 +#include "mconsole.h"
5118 +static struct mconsole_command commands[] = {
5119 + { "version", mconsole_version, 1 },
5120 + { "halt", mconsole_halt, 0 },
5121 + { "reboot", mconsole_reboot, 0 },
5122 + { "config", mconsole_config, 0 },
5123 + { "remove", mconsole_remove, 0 },
5124 + { "sysrq", mconsole_sysrq, 1 },
5125 + { "help", mconsole_help, 1 },
5126 + { "cad", mconsole_cad, 1 },
5127 + { "stop", mconsole_stop, 0 },
5128 + { "go", mconsole_go, 1 },
5131 +/* Initialized in mconsole_init, which is an initcall */
5132 +char mconsole_socket_name[256];
5134 +int mconsole_reply_v0(struct mc_request *req, char *reply)
5137 + struct msghdr msg;
5139 + iov.iov_base = reply;
5140 + iov.iov_len = strlen(reply);
5142 + msg.msg_name = &(req->origin);
5143 + msg.msg_namelen = req->originlen;
5144 + msg.msg_iov = &iov;
5145 + msg.msg_iovlen = 1;
5146 + msg.msg_control = NULL;
5147 + msg.msg_controllen = 0;
5148 + msg.msg_flags = 0;
5150 + return sendmsg(req->originating_fd, &msg, 0);
5153 +static struct mconsole_command *mconsole_parse(struct mc_request *req)
5155 + struct mconsole_command *cmd;
5158 + for(i=0;i<sizeof(commands)/sizeof(commands[0]);i++){
5159 + cmd = &commands[i];
5160 + if(!strncmp(req->request.data, cmd->command,
5161 + strlen(cmd->command))){
5168 +#define MIN(a,b) ((a)<(b) ? (a):(b))
5170 +#define STRINGX(x) #x
5171 +#define STRING(x) STRINGX(x)
5173 +int mconsole_get_request(int fd, struct mc_request *req)
5177 + req->originlen = sizeof(req->origin);
5178 + req->len = recvfrom(fd, &req->request, sizeof(req->request), 0,
5179 + (struct sockaddr *) req->origin, &req->originlen);
5183 + req->originating_fd = fd;
5185 + if(req->request.magic != MCONSOLE_MAGIC){
5186 + /* Unversioned request */
5187 + len = MIN(sizeof(req->request.data) - 1,
5188 + strlen((char *) &req->request));
5189 + memmove(req->request.data, &req->request, len);
5190 + req->request.data[len] = '\0';
5192 + req->request.magic = MCONSOLE_MAGIC;
5193 + req->request.version = 0;
5194 + req->request.len = len;
5196 + mconsole_reply_v0(req, "ERR Version 0 mconsole clients are "
5197 + "not supported by this driver");
5201 + if(req->request.len >= MCONSOLE_MAX_DATA){
5202 + mconsole_reply(req, "Request too large", 1, 0);
5205 + if(req->request.version != MCONSOLE_VERSION){
5206 + mconsole_reply(req, "This driver only supports version "
5207 + STRING(MCONSOLE_VERSION) " clients", 1, 0);
5210 + req->request.data[req->request.len] = '\0';
5211 + req->cmd = mconsole_parse(req);
5212 + if(req->cmd == NULL){
5213 + mconsole_reply(req, "Unknown command", 1, 0);
5220 +int mconsole_reply(struct mc_request *req, char *str, int err, int more)
5222 + struct mconsole_reply reply;
5223 + int total, len, n;
5225 + total = strlen(str);
5229 + /* err can only be true on the first packet */
5232 + len = MIN(total, MCONSOLE_MAX_DATA - 1);
5234 + if(len == total) reply.more = more;
5235 + else reply.more = 1;
5237 + memcpy(reply.data, str, len);
5238 + reply.data[len] = '\0';
5240 + reply.len = len + 1;
5242 + len = sizeof(reply) + reply.len - sizeof(reply.data);
5244 + n = sendto(req->originating_fd, &reply, len, 0,
5245 + (struct sockaddr *) req->origin, req->originlen);
5247 + if(n < 0) return(-errno);
5248 + } while(total > 0);
5252 +int mconsole_unlink_socket(void)
5254 + unlink(mconsole_socket_name);
5258 +static int notify_sock = -1;
5260 +int mconsole_notify(char *sock_name, int type, const void *data, int len)
5262 + struct sockaddr_un target;
5263 + struct mconsole_notify packet;
5267 + if(notify_sock < 0){
5268 + notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0);
5269 + if(notify_sock < 0){
5270 + printk("mconsole_notify - socket failed, errno = %d\n",
5280 + target.sun_family = AF_UNIX;
5281 + strcpy(target.sun_path, sock_name);
5283 + packet.magic = MCONSOLE_MAGIC;
5284 + packet.version = MCONSOLE_VERSION;
5285 + packet.type = type;
5286 + len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len;
5288 + memcpy(packet.data, data, len);
5291 + len = sizeof(packet) + packet.len - sizeof(packet.data);
5292 + n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target,
5295 + printk("mconsole_notify - sendto failed, errno = %d\n", errno);
5302 + * Overrides for Emacs so that we follow Linus's tabbing style.
5303 + * Emacs will notice this stuff at the end of the file and automatically
5304 + * adjust the settings for this buffer only. This must remain at the end
5306 + * ---------------------------------------------------------------------------
5307 + * Local variables:
5308 + * c-file-style: "linux"
5311 diff -Naur -X ../exclude-files orig/arch/um/drivers/mmapper_kern.c um/arch/um/drivers/mmapper_kern.c
5312 --- orig/arch/um/drivers/mmapper_kern.c Wed Dec 31 19:00:00 1969
5313 +++ um/arch/um/drivers/mmapper_kern.c Sun Dec 15 21:03:08 2002
5316 + * arch/um/drivers/mmapper_kern.c
5318 + * BRIEF MODULE DESCRIPTION
5320 + * Copyright (C) 2000 RidgeRun, Inc.
5321 + * Author: RidgeRun, Inc.
5322 + * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
5325 +#include <linux/kdev_t.h>
5326 +#include <linux/time.h>
5327 +#include <linux/devfs_fs_kernel.h>
5328 +#include <linux/module.h>
5329 +#include <linux/mm.h>
5330 +#include <linux/slab.h>
5331 +#include <linux/init.h>
5332 +#include <asm/uaccess.h>
5333 +#include <asm/irq.h>
5334 +#include <asm/smplock.h>
5335 +#include <asm/pgtable.h>
5336 +#include "mem_user.h"
5337 +#include "user_util.h"
5339 +/* These are set in mmapper_init, which is called at boot time */
5340 +static unsigned long mmapper_size;
5341 +static unsigned long p_buf = 0;
5342 +static char *v_buf = NULL;
5345 +mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos)
5347 + if(*ppos > mmapper_size)
5350 + if(count + *ppos > mmapper_size)
5351 + count = count + *ppos - mmapper_size;
5356 + copy_to_user(buf,&v_buf[*ppos],count);
5362 +mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
5364 + if(*ppos > mmapper_size)
5367 + if(count + *ppos > mmapper_size)
5368 + count = count + *ppos - mmapper_size;
5373 + copy_from_user(&v_buf[*ppos],buf,count);
5379 +mmapper_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
5380 + unsigned long arg)
5382 + return(-ENOIOCTLCMD);
5386 +mmapper_mmap(struct file *file, struct vm_area_struct * vma)
5388 + int ret = -EINVAL;
5392 + if (vma->vm_pgoff != 0)
5395 + size = vma->vm_end - vma->vm_start;
5396 + if(size > mmapper_size) return(-EFAULT);
5398 + /* XXX A comment above remap_page_range says it should only be
5399 + * called when the mm semaphore is held
5401 + if (remap_page_range(vma->vm_start, p_buf, size, vma->vm_page_prot))
5410 +mmapper_open(struct inode *inode, struct file *file)
5416 +mmapper_release(struct inode *inode, struct file *file)
5421 +static struct file_operations mmapper_fops = {
5422 + .owner = THIS_MODULE,
5423 + .read = mmapper_read,
5424 + .write = mmapper_write,
5425 + .ioctl = mmapper_ioctl,
5426 + .mmap = mmapper_mmap,
5427 + .open = mmapper_open,
5428 + .release = mmapper_release,
5431 +static int __init mmapper_init(void)
5433 + printk(KERN_INFO "Mapper v0.1\n");
5435 + v_buf = (char *) find_iomem("mmapper", &mmapper_size);
5436 + if(mmapper_size == 0) return(0);
5438 + p_buf = __pa(v_buf);
5440 + devfs_register (NULL, "mmapper", DEVFS_FL_DEFAULT,
5441 + 30, 0, S_IFCHR | S_IRUGO | S_IWUGO,
5442 + &mmapper_fops, NULL);
5443 + devfs_mk_symlink(NULL, "mmapper0", DEVFS_FL_DEFAULT, "mmapper",
5448 +static void mmapper_exit(void)
5452 +module_init(mmapper_init);
5453 +module_exit(mmapper_exit);
5455 +MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>");
5456 +MODULE_DESCRIPTION("DSPLinux simulator mmapper driver");
5458 + * ---------------------------------------------------------------------------
5459 + * Local variables:
5460 + * c-file-style: "linux"
5463 diff -Naur -X ../exclude-files orig/arch/um/drivers/net_kern.c um/arch/um/drivers/net_kern.c
5464 --- orig/arch/um/drivers/net_kern.c Wed Dec 31 19:00:00 1969
5465 +++ um/arch/um/drivers/net_kern.c Sun Dec 15 21:19:16 2002
5468 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
5469 + * James Leu (jleu@mindspring.net).
5470 + * Copyright (C) 2001 by various other people who didn't put their name here.
5471 + * Licensed under the GPL.
5474 +#include "linux/config.h"
5475 +#include "linux/kernel.h"
5476 +#include "linux/netdevice.h"
5477 +#include "linux/rtnetlink.h"
5478 +#include "linux/skbuff.h"
5479 +#include "linux/socket.h"
5480 +#include "linux/spinlock.h"
5481 +#include "linux/module.h"
5482 +#include "linux/init.h"
5483 +#include "linux/etherdevice.h"
5484 +#include "linux/list.h"
5485 +#include "linux/inetdevice.h"
5486 +#include "linux/ctype.h"
5487 +#include "linux/bootmem.h"
5488 +#include "user_util.h"
5489 +#include "kern_util.h"
5490 +#include "net_kern.h"
5491 +#include "net_user.h"
5492 +#include "mconsole_kern.h"
5494 +#include "irq_user.h"
5496 +static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
5499 +static int uml_net_rx(struct net_device *dev)
5501 + struct uml_net_private *lp = dev->priv;
5503 + struct sk_buff *skb;
5505 + /* If we can't allocate memory, try again next round. */
5506 + if ((skb = dev_alloc_skb(dev->mtu)) == NULL) {
5507 + lp->stats.rx_dropped++;
5512 + skb_put(skb, dev->mtu);
5513 + skb->mac.raw = skb->data;
5514 + pkt_len = (*lp->read)(lp->fd, &skb, lp);
5516 + if (pkt_len > 0) {
5517 + skb_trim(skb, pkt_len);
5518 + skb->protocol = (*lp->protocol)(skb);
5521 + lp->stats.rx_bytes += skb->len;
5522 + lp->stats.rx_packets++;
5530 +void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
5532 + struct net_device *dev = dev_id;
5533 + struct uml_net_private *lp = dev->priv;
5536 + if(!netif_running(dev))
5539 + spin_lock(&lp->lock);
5540 + while((err = uml_net_rx(dev)) > 0) ;
5543 + "Device '%s' read returned %d, shutting it down\n",
5548 + reactivate_fd(lp->fd, UM_ETH_IRQ);
5551 + spin_unlock(&lp->lock);
5554 +static int uml_net_open(struct net_device *dev)
5556 + struct uml_net_private *lp = dev->priv;
5557 + char addr[sizeof("255.255.255.255\0")];
5560 + spin_lock(&lp->lock);
5567 + if(!lp->have_mac){
5568 + dev_ip_addr(dev, addr, &lp->mac[2]);
5569 + set_ether_mac(dev, lp->mac);
5572 + lp->fd = (*lp->open)(&lp->user);
5578 + err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
5579 + SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
5581 + printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
5582 + if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
5584 + err = -ENETUNREACH;
5587 + lp->tl.data = (unsigned long) &lp->user;
5588 + netif_start_queue(dev);
5590 + spin_lock(&opened_lock);
5591 + list_add(&lp->list, &opened);
5592 + spin_unlock(&opened_lock);
5593 + MOD_INC_USE_COUNT;
5595 + spin_unlock(&lp->lock);
5599 +static int uml_net_close(struct net_device *dev)
5601 + struct uml_net_private *lp = dev->priv;
5603 + netif_stop_queue(dev);
5604 + spin_lock(&lp->lock);
5606 + free_irq(dev->irq, dev);
5607 + if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
5609 + spin_lock(&opened_lock);
5610 + list_del(&lp->list);
5611 + spin_unlock(&opened_lock);
5613 + MOD_DEC_USE_COUNT;
5614 + spin_unlock(&lp->lock);
5618 +static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
5620 + struct uml_net_private *lp = dev->priv;
5621 + unsigned long flags;
5624 + netif_stop_queue(dev);
5626 + spin_lock_irqsave(&lp->lock, flags);
5628 + len = (*lp->write)(lp->fd, &skb, lp);
5630 + if(len == skb->len) {
5631 + lp->stats.tx_packets++;
5632 + lp->stats.tx_bytes += skb->len;
5633 + dev->trans_start = jiffies;
5634 + netif_start_queue(dev);
5636 + /* this is normally done in the interrupt when tx finishes */
5637 + netif_wake_queue(dev);
5639 + else if(len == 0){
5640 + netif_start_queue(dev);
5641 + lp->stats.tx_dropped++;
5644 + netif_start_queue(dev);
5645 + printk(KERN_ERR "uml_net_start_xmit: failed(%d)\n", len);
5648 + spin_unlock_irqrestore(&lp->lock, flags);
5650 + dev_kfree_skb(skb);
5655 +static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
5657 + struct uml_net_private *lp = dev->priv;
5658 + return &lp->stats;
5661 +static void uml_net_set_multicast_list(struct net_device *dev)
5663 + if (dev->flags & IFF_PROMISC) return;
5664 + else if (dev->mc_count) dev->flags |= IFF_ALLMULTI;
5665 + else dev->flags &= ~IFF_ALLMULTI;
5668 +static void uml_net_tx_timeout(struct net_device *dev)
5670 + dev->trans_start = jiffies;
5671 + netif_wake_queue(dev);
5674 +static int uml_net_set_mac(struct net_device *dev, void *addr)
5676 + struct uml_net_private *lp = dev->priv;
5677 + struct sockaddr *hwaddr = addr;
5679 + spin_lock(&lp->lock);
5680 + memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
5681 + spin_unlock(&lp->lock);
5686 +static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
5688 + struct uml_net_private *lp = dev->priv;
5691 + spin_lock(&lp->lock);
5693 + new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
5699 + dev->mtu = new_mtu;
5702 + spin_unlock(&lp->lock);
5706 +static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
5711 +void uml_net_user_timer_expire(unsigned long _conn)
5714 + struct connection *conn = (struct connection *)_conn;
5716 + dprintk(KERN_INFO "uml_net_user_timer_expire [%p]\n", conn);
5722 + * default do nothing hard header packet routines for struct net_device init.
5723 + * real ethernet transports will overwrite with real routines.
5725 +static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
5726 + unsigned short type, void *daddr, void *saddr, unsigned len)
5728 + return(0); /* no change */
5731 +static int uml_net_rebuild_header(struct sk_buff *skb)
5733 + return(0); /* ignore */
5736 +static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
5738 + return(-1); /* fail */
5741 +static void uml_net_header_cache_update(struct hh_cache *hh,
5742 + struct net_device *dev, unsigned char * haddr)
5747 +static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
5749 + return(0); /* nothing */
5752 +static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
5753 +static struct list_head devices = LIST_HEAD_INIT(devices);
5755 +static int eth_configure(int n, void *init, char *mac,
5756 + struct transport *transport)
5758 + struct uml_net *device;
5759 + struct net_device *dev;
5760 + struct uml_net_private *lp;
5761 + int save, err, size;
5763 + size = transport->private_size + sizeof(struct uml_net_private) +
5764 + sizeof(((struct uml_net_private *) 0)->user);
5766 + device = kmalloc(sizeof(*device), GFP_KERNEL);
5767 + if(device == NULL){
5768 + printk(KERN_ERR "eth_configure failed to allocate uml_net\n");
5772 + *device = ((struct uml_net) { .list = LIST_HEAD_INIT(device->list),
5775 + .mac = { [ 0 ... 5 ] = 0 },
5778 + spin_lock(&devices_lock);
5779 + list_add(&device->list, &devices);
5780 + spin_unlock(&devices_lock);
5782 + if(setup_etheraddr(mac, device->mac))
5783 + device->have_mac = 1;
5785 + printk(KERN_INFO "Netdevice %d ", n);
5786 + if(device->have_mac) printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
5787 + device->mac[0], device->mac[1],
5788 + device->mac[2], device->mac[3],
5789 + device->mac[4], device->mac[5]);
5791 + dev = kmalloc(sizeof(*dev) + size, GFP_KERNEL);
5793 + printk(KERN_ERR "eth_configure: failed to allocate device\n");
5796 + memset(dev, 0, sizeof(*dev) + size);
5798 + snprintf(dev->name, sizeof(dev->name), "eth%d", n);
5799 + dev->priv = (void *) &dev[1];
5800 + device->dev = dev;
5802 + dev->hard_header = uml_net_hard_header;
5803 + dev->rebuild_header = uml_net_rebuild_header;
5804 + dev->hard_header_cache = uml_net_header_cache;
5805 + dev->header_cache_update= uml_net_header_cache_update;
5806 + dev->hard_header_parse = uml_net_header_parse;
5808 + (*transport->kern->init)(dev, init);
5810 + dev->mtu = transport->user->max_packet;
5811 + dev->open = uml_net_open;
5812 + dev->hard_start_xmit = uml_net_start_xmit;
5813 + dev->stop = uml_net_close;
5814 + dev->get_stats = uml_net_get_stats;
5815 + dev->set_multicast_list = uml_net_set_multicast_list;
5816 + dev->tx_timeout = uml_net_tx_timeout;
5817 + dev->set_mac_address = uml_net_set_mac;
5818 + dev->change_mtu = uml_net_change_mtu;
5819 + dev->do_ioctl = uml_net_ioctl;
5820 + dev->watchdog_timeo = (HZ >> 1);
5821 + dev->irq = UM_ETH_IRQ;
5824 + err = register_netdevice(dev);
5830 + /* lp.user is the first four bytes of the transport data, which
5831 + * has already been initialized. This structure assignment will
5832 + * overwrite that, so we make sure that .user gets overwritten with
5833 + * what it already has.
5835 + save = lp->user[0];
5836 + *lp = ((struct uml_net_private)
5837 + { .list = LIST_HEAD_INIT(lp->list),
5838 + .lock = SPIN_LOCK_UNLOCKED,
5841 + .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
5842 + .have_mac = device->have_mac,
5843 + .protocol = transport->kern->protocol,
5844 + .open = transport->user->open,
5845 + .close = transport->user->close,
5846 + .remove = transport->user->remove,
5847 + .read = transport->kern->read,
5848 + .write = transport->kern->write,
5849 + .add_address = transport->user->add_address,
5850 + .delete_address = transport->user->delete_address,
5851 + .set_mtu = transport->user->set_mtu,
5852 + .user = { save } });
5853 + init_timer(&lp->tl);
5854 + lp->tl.function = uml_net_user_timer_expire;
5855 + memset(&lp->stats, 0, sizeof(lp->stats));
5856 + if(lp->have_mac) memcpy(lp->mac, device->mac, sizeof(lp->mac));
5858 + if(transport->user->init)
5859 + (*transport->user->init)(&lp->user, dev);
5861 + if(device->have_mac)
5862 + set_ether_mac(dev, device->mac);
5866 +static struct uml_net *find_device(int n)
5868 + struct uml_net *device;
5869 + struct list_head *ele;
5871 + spin_lock(&devices_lock);
5872 + list_for_each(ele, &devices){
5873 + device = list_entry(ele, struct uml_net, list);
5874 + if(device->index == n)
5879 + spin_unlock(&devices_lock);
5883 +static int eth_parse(char *str, int *index_out, char **str_out)
5888 + n = simple_strtoul(str, &end, 0);
5890 + printk(KERN_ERR "eth_setup: Failed to parse '%s'\n", str);
5894 + printk(KERN_ERR "eth_setup: device %d is negative\n", n);
5900 + "eth_setup: expected '=' after device number\n");
5904 + if(find_device(n)){
5905 + printk(KERN_ERR "eth_setup: Device %d already configured\n",
5909 + if(index_out) *index_out = n;
5915 + struct list_head list;
5920 +/* Filled in at boot time. Will need locking if the transports become
5923 +struct list_head transports = LIST_HEAD_INIT(transports);
5925 +/* Filled in during early boot */
5926 +struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
5928 +static int check_transport(struct transport *transport, char *eth, int n,
5929 + void **init_out, char **mac_out)
5933 + len = strlen(transport->name);
5934 + if(strncmp(eth, transport->name, len))
5940 + else if(*eth != '\0')
5943 + *init_out = kmalloc(transport->setup_size, GFP_KERNEL);
5944 + if(*init_out == NULL)
5947 + if(!transport->setup(eth, mac_out, *init_out)){
5954 +void register_transport(struct transport *new)
5956 + struct list_head *ele, *next;
5957 + struct eth_init *eth;
5962 + list_add(&new->list, &transports);
5964 + list_for_each_safe(ele, next, ð_cmd_line){
5965 + eth = list_entry(ele, struct eth_init, list);
5966 + match = check_transport(new, eth->init, eth->index, &init,
5970 + else if(init != NULL){
5971 + eth_configure(eth->index, init, mac, new);
5974 + list_del(ð->list);
5978 +static int eth_setup_common(char *str, int index)
5980 + struct list_head *ele;
5981 + struct transport *transport;
5985 + list_for_each(ele, &transports){
5986 + transport = list_entry(ele, struct transport, list);
5987 + if(!check_transport(transport, str, index, &init, &mac))
5990 + eth_configure(index, init, mac, transport);
5998 +static int eth_setup(char *str)
6000 + struct eth_init *new;
6003 + err = eth_parse(str, &n, &str);
6004 + if(err) return(1);
6006 + new = alloc_bootmem(sizeof(new));
6008 + printk("eth_init : alloc_bootmem failed\n");
6011 + *new = ((struct eth_init) { .list = LIST_HEAD_INIT(new->list),
6014 + list_add_tail(&new->list, ð_cmd_line);
6018 +__setup("eth", eth_setup);
6019 +__uml_help(eth_setup,
6020 +"eth[0-9]+=<transport>,<options>\n"
6021 +" Configure a network device.\n\n"
6024 +static int eth_init(void)
6026 + struct list_head *ele, *next;
6027 + struct eth_init *eth;
6029 + list_for_each_safe(ele, next, ð_cmd_line){
6030 + eth = list_entry(ele, struct eth_init, list);
6032 + if(eth_setup_common(eth->init, eth->index))
6033 + list_del(ð->list);
6039 +__initcall(eth_init);
6041 +static int net_config(char *str)
6045 + err = eth_parse(str, &n, &str);
6046 + if(err) return(err);
6048 + str = uml_strdup(str);
6050 + printk(KERN_ERR "net_config failed to strdup string\n");
6053 + err = !eth_setup_common(str, n);
6059 +static int net_remove(char *str)
6061 + struct uml_net *device;
6062 + struct net_device *dev;
6063 + struct uml_net_private *lp;
6067 + n = simple_strtoul(str, &end, 0);
6068 + if((*end != '\0') || (end == str))
6071 + device = find_device(n);
6072 + if(device == NULL)
6075 + dev = device->dev;
6077 + if(lp->fd > 0) return(-1);
6078 + if(lp->remove != NULL) (*lp->remove)(&lp->user);
6079 + unregister_netdev(dev);
6081 + list_del(&device->list);
6086 +static struct mc_device net_mc = {
6088 + .config = net_config,
6089 + .get_config = NULL,
6090 + .remove = net_remove,
6093 +static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
6096 + struct in_ifaddr *ifa = ptr;
6097 + u32 addr = ifa->ifa_address;
6098 + u32 netmask = ifa->ifa_mask;
6099 + struct net_device *dev = ifa->ifa_dev->dev;
6100 + struct uml_net_private *lp;
6101 + void (*proc)(unsigned char *, unsigned char *, void *);
6102 + unsigned char addr_buf[4], netmask_buf[4];
6104 + if(dev->open != uml_net_open) return(NOTIFY_DONE);
6111 + proc = lp->add_address;
6114 + proc = lp->delete_address;
6118 + addr_buf[0] = addr & 0xff;
6119 + addr_buf[1] = (addr >> 8) & 0xff;
6120 + addr_buf[2] = (addr >> 16) & 0xff;
6121 + addr_buf[3] = addr >> 24;
6122 + netmask_buf[0] = netmask & 0xff;
6123 + netmask_buf[1] = (netmask >> 8) & 0xff;
6124 + netmask_buf[2] = (netmask >> 16) & 0xff;
6125 + netmask_buf[3] = netmask >> 24;
6126 + (*proc)(addr_buf, netmask_buf, &lp->user);
6128 + return(NOTIFY_DONE);
6131 +struct notifier_block uml_inetaddr_notifier = {
6132 + .notifier_call = uml_inetaddr_event,
6135 +static int uml_net_init(void)
6137 + struct list_head *ele;
6138 + struct uml_net_private *lp;
6139 + struct in_device *ip;
6140 + struct in_ifaddr *in;
6142 + mconsole_register_dev(&net_mc);
6143 + register_inetaddr_notifier(¨_inetaddr_notifier);
6145 + /* Devices may have been opened already, so the uml_inetaddr_notifier
6146 + * didn't get a chance to run for them. This fakes it so that
6147 + * addresses which have already been set up get handled properly.
6149 + list_for_each(ele, &opened){
6150 + lp = list_entry(ele, struct uml_net_private, list);
6151 + ip = lp->dev->ip_ptr;
6152 + if(ip == NULL) continue;
6153 + in = ip->ifa_list;
6154 + while(in != NULL){
6155 + uml_inetaddr_event(NULL, NETDEV_UP, in);
6156 + in = in->ifa_next;
6163 +__initcall(uml_net_init);
6165 +static void close_devices(void)
6167 + struct list_head *ele;
6168 + struct uml_net_private *lp;
6170 + list_for_each(ele, &opened){
6171 + lp = list_entry(ele, struct uml_net_private, list);
6172 + if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6173 + if(lp->remove != NULL) (*lp->remove)(&lp->user);
6177 +__uml_exitcall(close_devices);
6179 +int setup_etheraddr(char *str, unsigned char *addr)
6187 + addr[i] = simple_strtoul(str, &end, 16);
6188 + if((end == str) ||
6189 + ((*end != ':') && (*end != ',') && (*end != '\0'))){
6191 + "setup_etheraddr: failed to parse '%s' "
6192 + "as an ethernet address\n", str);
6199 + "Attempt to assign a broadcast ethernet address to a "
6200 + "device disallowed\n");
6206 +void dev_ip_addr(void *d, char *buf, char *bin_buf)
6208 + struct net_device *dev = d;
6209 + struct in_device *ip = dev->ip_ptr;
6210 + struct in_ifaddr *in;
6213 + if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
6214 + printk(KERN_WARNING "dev_ip_addr - device not assigned an "
6218 + addr = in->ifa_address;
6219 + sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff,
6220 + (addr >> 16) & 0xff, addr >> 24);
6222 + bin_buf[0] = addr & 0xff;
6223 + bin_buf[1] = (addr >> 8) & 0xff;
6224 + bin_buf[2] = (addr >> 16) & 0xff;
6225 + bin_buf[3] = addr >> 24;
6229 +void set_ether_mac(void *d, unsigned char *addr)
6231 + struct net_device *dev = d;
6233 + memcpy(dev->dev_addr, addr, ETH_ALEN);
6236 +struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
6238 + if((skb != NULL) && (skb_tailroom(skb) < extra)){
6239 + struct sk_buff *skb2;
6241 + skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
6242 + dev_kfree_skb(skb);
6245 + if(skb != NULL) skb_put(skb, extra);
6249 +void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
6253 + struct net_device *dev = d;
6254 + struct in_device *ip = dev->ip_ptr;
6255 + struct in_ifaddr *in;
6256 + unsigned char address[4], netmask[4];
6258 + if(ip == NULL) return;
6259 + in = ip->ifa_list;
6260 + while(in != NULL){
6261 + address[0] = in->ifa_address & 0xff;
6262 + address[1] = (in->ifa_address >> 8) & 0xff;
6263 + address[2] = (in->ifa_address >> 16) & 0xff;
6264 + address[3] = in->ifa_address >> 24;
6265 + netmask[0] = in->ifa_mask & 0xff;
6266 + netmask[1] = (in->ifa_mask >> 8) & 0xff;
6267 + netmask[2] = (in->ifa_mask >> 16) & 0xff;
6268 + netmask[3] = in->ifa_mask >> 24;
6269 + (*cb)(address, netmask, arg);
6270 + in = in->ifa_next;
6274 +int dev_netmask(void *d, void *m)
6276 + struct net_device *dev = d;
6277 + struct in_device *ip = dev->ip_ptr;
6278 + struct in_ifaddr *in;
6279 + __u32 *mask_out = m;
6284 + in = ip->ifa_list;
6288 + *mask_out = in->ifa_mask;
6292 +void *get_output_buffer(int *len_out)
6296 + ret = (void *) __get_free_pages(GFP_KERNEL, 0);
6297 + if(ret) *len_out = PAGE_SIZE;
6298 + else *len_out = 0;
6302 +void free_output_buffer(void *buffer)
6304 + free_pages((unsigned long) buffer, 0);
6307 +int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out,
6312 + remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL);
6313 + if(remain != NULL){
6314 + printk("tap_setup_common - Extra garbage on specification : "
6315 + "'%s'\n", remain);
6322 +unsigned short eth_protocol(struct sk_buff *skb)
6324 + return(eth_type_trans(skb, skb->dev));
6328 + * Overrides for Emacs so that we follow Linus's tabbing style.
6329 + * Emacs will notice this stuff at the end of the file and automatically
6330 + * adjust the settings for this buffer only. This must remain at the end
6332 + * ---------------------------------------------------------------------------
6333 + * Local variables:
6334 + * c-file-style: "linux"
6337 diff -Naur -X ../exclude-files orig/arch/um/drivers/net_user.c um/arch/um/drivers/net_user.c
6338 --- orig/arch/um/drivers/net_user.c Wed Dec 31 19:00:00 1969
6339 +++ um/arch/um/drivers/net_user.c Wed Oct 23 21:08:04 2002
6342 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
6343 + * Licensed under the GPL
6346 +#include <stddef.h>
6347 +#include <stdarg.h>
6348 +#include <unistd.h>
6351 +#include <stdlib.h>
6352 +#include <string.h>
6353 +#include <sys/socket.h>
6354 +#include <sys/wait.h>
6356 +#include "user_util.h"
6357 +#include "kern_util.h"
6358 +#include "net_user.h"
6359 +#include "helper.h"
6362 +int tap_open_common(void *dev, char *gate_addr)
6366 + if(gate_addr == NULL) return(0);
6367 + if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
6368 + &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
6369 + printk("Invalid tap IP address - '%s'\n",
6376 +void tap_check_ips(char *gate_addr, char *eth_addr)
6380 + if((gate_addr != NULL) &&
6381 + (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
6382 + &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
6383 + (eth_addr[0] == tap_addr[0]) &&
6384 + (eth_addr[1] == tap_addr[1]) &&
6385 + (eth_addr[2] == tap_addr[2]) &&
6386 + (eth_addr[3] == tap_addr[3])){
6387 + printk("The tap IP address and the UML eth IP address"
6388 + " must be different\n");
6392 +void read_output(int fd, char *output, int len)
6394 + int remain, n, actual;
6397 + if(output == NULL){
6403 + if(read(fd, &remain, sizeof(remain)) != sizeof(remain)){
6404 + printk("read_output - read of length failed, errno = %d\n",
6409 + while(remain != 0){
6410 + n = (remain < len) ? remain : len;
6411 + actual = read(fd, output, n);
6413 + printk("read_output - read of data failed, "
6414 + "errno = %d\n", errno);
6422 +int net_read(int fd, void *buf, int len)
6426 + while(((n = read(fd, buf, len)) < 0) && (errno == EINTR)) ;
6429 + if(errno == EAGAIN) return(0);
6432 + else if(n == 0) return(-ENOTCONN);
6436 +int net_recvfrom(int fd, void *buf, int len)
6440 + while(((n = recvfrom(fd, buf, len, 0, NULL, NULL)) < 0) &&
6441 + (errno == EINTR)) ;
6444 + if(errno == EAGAIN) return(0);
6447 + else if(n == 0) return(-ENOTCONN);
6451 +int net_write(int fd, void *buf, int len)
6455 + while(((n = write(fd, buf, len)) < 0) && (errno == EINTR)) ;
6457 + if(errno == EAGAIN) return(0);
6460 + else if(n == 0) return(-ENOTCONN);
6464 +int net_send(int fd, void *buf, int len)
6468 + while(((n = send(fd, buf, len, 0)) < 0) && (errno == EINTR)) ;
6470 + if(errno == EAGAIN) return(0);
6473 + else if(n == 0) return(-ENOTCONN);
6477 +int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
6481 + while(((n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
6482 + sock_len)) < 0) && (errno == EINTR)) ;
6484 + if(errno == EAGAIN) return(0);
6487 + else if(n == 0) return(-ENOTCONN);
6491 +struct change_pre_exec_data {
6496 +static void change_pre_exec(void *arg)
6498 + struct change_pre_exec_data *data = arg;
6500 + close(data->close_me);
6501 + dup2(data->stdout, 1);
6504 +static int change_tramp(char **argv, char *output, int output_len)
6506 + int pid, fds[2], err;
6507 + struct change_pre_exec_data pe_data;
6509 + err = os_pipe(fds, 1, 0);
6511 + printk("change_tramp - pipe failed, errno = %d\n", -err);
6514 + pe_data.close_me = fds[0];
6515 + pe_data.stdout = fds[1];
6516 + pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
6519 + read_output(fds[0], output, output_len);
6520 + waitpid(pid, NULL, 0);
6524 +static void change(char *dev, char *what, unsigned char *addr,
6525 + unsigned char *netmask)
6527 + char addr_buf[sizeof("255.255.255.255\0")];
6528 + char netmask_buf[sizeof("255.255.255.255\0")];
6529 + char version[sizeof("nnnnn\0")];
6530 + char *argv[] = { "uml_net", version, what, dev, addr_buf,
6531 + netmask_buf, NULL };
6533 + int output_len, pid;
6535 + sprintf(version, "%d", UML_NET_VERSION);
6536 + sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
6537 + sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1],
6538 + netmask[2], netmask[3]);
6540 + output_len = page_size();
6541 + output = um_kmalloc(output_len);
6542 + if(output == NULL)
6543 + printk("change : failed to allocate output buffer\n");
6545 + pid = change_tramp(argv, output, output_len);
6546 + if(pid < 0) return;
6548 + if(output != NULL){
6549 + printk("%s", output);
6554 +void open_addr(unsigned char *addr, unsigned char *netmask, void *arg)
6556 + change(arg, "add", addr, netmask);
6559 +void close_addr(unsigned char *addr, unsigned char *netmask, void *arg)
6561 + change(arg, "del", addr, netmask);
6564 +char *split_if_spec(char *str, ...)
6569 + va_start(ap, str);
6570 + while((arg = va_arg(ap, char **)) != NULL){
6573 + end = strchr(str, ',');
6586 + * Overrides for Emacs so that we follow Linus's tabbing style.
6587 + * Emacs will notice this stuff at the end of the file and automatically
6588 + * adjust the settings for this buffer only. This must remain at the end
6590 + * ---------------------------------------------------------------------------
6591 + * Local variables:
6592 + * c-file-style: "linux"
6595 diff -Naur -X ../exclude-files orig/arch/um/drivers/null.c um/arch/um/drivers/null.c
6596 --- orig/arch/um/drivers/null.c Wed Dec 31 19:00:00 1969
6597 +++ um/arch/um/drivers/null.c Sun Dec 15 21:04:00 2002
6600 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
6601 + * Licensed under the GPL
6604 +#include <stdlib.h>
6607 +#include "chan_user.h"
6610 +static int null_chan;
6612 +void *null_init(char *str, int device, struct chan_opts *opts)
6614 + return(&null_chan);
6617 +int null_open(int input, int output, int primary, void *d, char **dev_out)
6620 + return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0));
6623 +int null_read(int fd, char *c_out, void *unused)
6628 +void null_free(void *data)
6632 +struct chan_ops null_ops = {
6634 + .init = null_init,
6635 + .open = null_open,
6636 + .close = generic_close,
6637 + .read = null_read,
6638 + .write = generic_write,
6639 + .console_write = generic_console_write,
6640 + .window_size = generic_window_size,
6641 + .free = null_free,
6646 + * Overrides for Emacs so that we follow Linus's tabbing style.
6647 + * Emacs will notice this stuff at the end of the file and automatically
6648 + * adjust the settings for this buffer only. This must remain at the end
6650 + * ---------------------------------------------------------------------------
6651 + * Local variables:
6652 + * c-file-style: "linux"
6655 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_kern.c um/arch/um/drivers/pcap_kern.c
6656 --- orig/arch/um/drivers/pcap_kern.c Wed Dec 31 19:00:00 1969
6657 +++ um/arch/um/drivers/pcap_kern.c Sun Dec 15 21:19:15 2002
6660 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
6661 + * Licensed under the GPL.
6664 +#include "linux/init.h"
6665 +#include "linux/netdevice.h"
6666 +#include "linux/etherdevice.h"
6667 +#include "net_kern.h"
6668 +#include "net_user.h"
6669 +#include "pcap_user.h"
6678 +void pcap_init(struct net_device *dev, void *data)
6680 + struct uml_net_private *pri;
6681 + struct pcap_data *ppri;
6682 + struct pcap_init *init = data;
6684 + init_etherdev(dev, 0);
6686 + ppri = (struct pcap_data *) pri->user;
6687 + *ppri = ((struct pcap_data)
6688 + { .host_if = init->host_if,
6689 + .promisc = init->promisc,
6690 + .optimize = init->optimize,
6691 + .filter = init->filter,
6696 +static int pcap_read(int fd, struct sk_buff **skb,
6697 + struct uml_net_private *lp)
6699 + *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
6700 + if(*skb == NULL) return(-ENOMEM);
6701 + return(pcap_user_read(fd, (*skb)->mac.raw,
6702 + (*skb)->dev->mtu + ETH_HEADER_OTHER,
6703 + (struct pcap_data *) &lp->user));
6706 +static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
6711 +static struct net_kern_info pcap_kern_info = {
6712 + .init = pcap_init,
6713 + .protocol = eth_protocol,
6714 + .read = pcap_read,
6715 + .write = pcap_write,
6718 +int pcap_setup(char *str, char **mac_out, void *data)
6720 + struct pcap_init *init = data;
6721 + char *remain, *host_if = NULL, *options[2] = { NULL, NULL };
6724 + *init = ((struct pcap_init)
6725 + { .host_if = "eth0",
6728 + .filter = NULL });
6730 + remain = split_if_spec(str, &host_if, &init->filter,
6731 + &options[0], &options[1], NULL);
6732 + if(remain != NULL){
6733 + printk(KERN_ERR "pcap_setup - Extra garbage on "
6734 + "specification : '%s'\n", remain);
6738 + if(host_if != NULL)
6739 + init->host_if = host_if;
6741 + for(i = 0; i < sizeof(options)/sizeof(options[0]); i++){
6742 + if(options[i] == NULL)
6744 + if(!strcmp(options[i], "promisc"))
6745 + init->promisc = 1;
6746 + else if(!strcmp(options[i], "nopromisc"))
6747 + init->promisc = 0;
6748 + else if(!strcmp(options[i], "optimize"))
6749 + init->optimize = 1;
6750 + else if(!strcmp(options[i], "nooptimize"))
6751 + init->optimize = 0;
6752 + else printk("pcap_setup : bad option - '%s'\n", options[i]);
6758 +static struct transport pcap_transport = {
6759 + .list = LIST_HEAD_INIT(pcap_transport.list),
6761 + .setup = pcap_setup,
6762 + .user = &pcap_user_info,
6763 + .kern = &pcap_kern_info,
6764 + .private_size = sizeof(struct pcap_data),
6765 + .setup_size = sizeof(struct pcap_init),
6768 +static int register_pcap(void)
6770 + register_transport(&pcap_transport);
6774 +__initcall(register_pcap);
6777 + * Overrides for Emacs so that we follow Linus's tabbing style.
6778 + * Emacs will notice this stuff at the end of the file and automatically
6779 + * adjust the settings for this buffer only. This must remain at the end
6781 + * ---------------------------------------------------------------------------
6782 + * Local variables:
6783 + * c-file-style: "linux"
6786 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.c um/arch/um/drivers/pcap_user.c
6787 --- orig/arch/um/drivers/pcap_user.c Wed Dec 31 19:00:00 1969
6788 +++ um/arch/um/drivers/pcap_user.c Sun Dec 15 21:04:39 2002
6791 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
6792 + * Licensed under the GPL.
6795 +#include <unistd.h>
6796 +#include <stdlib.h>
6797 +#include <string.h>
6800 +#include <asm/types.h>
6801 +#include "net_user.h"
6802 +#include "pcap_user.h"
6805 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
6807 +#define PCAP_FD(p) (*(int *)(p))
6809 +static void pcap_user_init(void *data, void *dev)
6811 + struct pcap_data *pri = data;
6813 + char errors[PCAP_ERRBUF_SIZE];
6815 + p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors);
6817 + printk("pcap_user_init : pcap_open_live failed - '%s'\n",
6826 +static int pcap_open(void *data)
6828 + struct pcap_data *pri = data;
6832 + if(pri->pcap == NULL)
6835 + if(pri->filter != NULL){
6836 + err = dev_netmask(pri->dev, &netmask);
6838 + printk("pcap_open : dev_netmask failed\n");
6842 + pri->compiled = um_kmalloc(sizeof(struct bpf_program));
6843 + if(pri->compiled == NULL){
6844 + printk("pcap_open : kmalloc failed\n");
6848 + err = pcap_compile(pri->pcap,
6849 + (struct bpf_program *) pri->compiled,
6850 + pri->filter, pri->optimize, netmask);
6852 + printk("pcap_open : pcap_compile failed - '%s'\n",
6853 + pcap_geterr(pri->pcap));
6857 + err = pcap_setfilter(pri->pcap, pri->compiled);
6859 + printk("pcap_open : pcap_setfilter failed - '%s'\n",
6860 + pcap_geterr(pri->pcap));
6865 + return(PCAP_FD(pri->pcap));
6868 +static void pcap_remove(void *data)
6870 + struct pcap_data *pri = data;
6872 + if(pri->compiled != NULL)
6873 + pcap_freecode(pri->compiled);
6875 + pcap_close(pri->pcap);
6878 +struct pcap_handler_data {
6883 +static void handler(u_char *data, const struct pcap_pkthdr *header,
6884 + const u_char *packet)
6888 + struct pcap_handler_data *hdata = (struct pcap_handler_data *) data;
6890 + len = hdata->len < header->caplen ? hdata->len : header->caplen;
6891 + memcpy(hdata->buffer, packet, len);
6895 +int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
6897 + struct pcap_handler_data hdata = ((struct pcap_handler_data)
6898 + { .buffer = buffer,
6902 + n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
6904 + printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap));
6909 + return(hdata.len);
6912 +struct net_user_info pcap_user_info = {
6913 + .init = pcap_user_init,
6914 + .open = pcap_open,
6916 + .remove = pcap_remove,
6918 + .add_address = NULL,
6919 + .delete_address = NULL,
6920 + .max_packet = MAX_PACKET - ETH_HEADER_OTHER
6924 + * Overrides for Emacs so that we follow Linus's tabbing style.
6925 + * Emacs will notice this stuff at the end of the file and automatically
6926 + * adjust the settings for this buffer only. This must remain at the end
6928 + * ---------------------------------------------------------------------------
6929 + * Local variables:
6930 + * c-file-style: "linux"
6933 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.h um/arch/um/drivers/pcap_user.h
6934 --- orig/arch/um/drivers/pcap_user.h Wed Dec 31 19:00:00 1969
6935 +++ um/arch/um/drivers/pcap_user.h Wed Oct 23 21:08:04 2002
6938 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
6939 + * Licensed under the GPL
6942 +#include "net_user.h"
6954 +extern struct net_user_info pcap_user_info;
6956 +extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
6959 + * Overrides for Emacs so that we follow Linus's tabbing style.
6960 + * Emacs will notice this stuff at the end of the file and automatically
6961 + * adjust the settings for this buffer only. This must remain at the end
6963 + * ---------------------------------------------------------------------------
6964 + * Local variables:
6965 + * c-file-style: "linux"
6968 diff -Naur -X ../exclude-files orig/arch/um/drivers/port.h um/arch/um/drivers/port.h
6969 --- orig/arch/um/drivers/port.h Wed Dec 31 19:00:00 1969
6970 +++ um/arch/um/drivers/port.h Wed Oct 23 21:08:04 2002
6973 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
6974 + * Licensed under the GPL
6980 +extern void *port_data(int port);
6981 +extern int port_wait(void *data);
6982 +extern void port_kern_close(void *d);
6983 +extern int port_connection(int fd, int *socket_out, int *pid_out);
6984 +extern int port_listen_fd(int port);
6985 +extern void port_read(int fd, void *data);
6986 +extern void port_kern_free(void *d);
6987 +extern int port_rcv_fd(int fd);
6988 +extern void port_remove_dev(void *d);
6993 + * Overrides for Emacs so that we follow Linus's tabbing style.
6994 + * Emacs will notice this stuff at the end of the file and automatically
6995 + * adjust the settings for this buffer only. This must remain at the end
6997 + * ---------------------------------------------------------------------------
6998 + * Local variables:
6999 + * c-file-style: "linux"
7002 diff -Naur -X ../exclude-files orig/arch/um/drivers/port_kern.c um/arch/um/drivers/port_kern.c
7003 --- orig/arch/um/drivers/port_kern.c Wed Dec 31 19:00:00 1969
7004 +++ um/arch/um/drivers/port_kern.c Mon Dec 30 20:57:42 2002
7007 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7008 + * Licensed under the GPL
7011 +#include "linux/list.h"
7012 +#include "linux/sched.h"
7013 +#include "linux/slab.h"
7014 +#include "linux/irq.h"
7015 +#include "linux/spinlock.h"
7016 +#include "linux/errno.h"
7017 +#include "asm/semaphore.h"
7018 +#include "asm/errno.h"
7019 +#include "kern_util.h"
7021 +#include "irq_user.h"
7027 + struct list_head list;
7028 + int has_connection;
7029 + struct semaphore sem;
7033 + struct list_head pending;
7034 + struct list_head connections;
7038 + struct port_list *port;
7043 +struct connection {
7044 + struct list_head list;
7049 + struct port_list *port;
7052 +static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
7054 + struct connection *conn = data;
7057 + fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
7062 + printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
7064 + os_close_file(conn->fd);
7067 + list_del(&conn->list);
7070 + list_add(&conn->list, &conn->port->connections);
7072 + up(&conn->port->sem);
7075 +static int port_accept(struct port_list *port)
7077 + struct connection *conn;
7078 + int fd, socket[2], pid, ret = 0;
7080 + fd = port_connection(port->fd, socket, &pid);
7083 + printk(KERN_ERR "port_accept : port_connection "
7084 + "returned %d\n", -fd);
7088 + conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
7090 + printk(KERN_ERR "port_accept : failed to allocate "
7094 + *conn = ((struct connection)
7095 + { .list = LIST_HEAD_INIT(conn->list),
7097 + .socket = { socket[0], socket[1] },
7098 + .telnetd_pid = pid,
7101 + if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
7102 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
7103 + "telnetd", conn)){
7104 + printk(KERN_ERR "port_accept : failed to get IRQ for "
7109 + list_add(&conn->list, &port->pending);
7115 + os_close_file(fd);
7117 + os_kill_process(pid, 1);
7122 +DECLARE_MUTEX(ports_sem);
7123 +struct list_head ports = LIST_HEAD_INIT(ports);
7125 +void port_task_proc(void *unused)
7127 + struct port_list *port;
7128 + struct list_head *ele;
7129 + unsigned long flags;
7131 + save_flags(flags);
7132 + list_for_each(ele, &ports){
7133 + port = list_entry(ele, struct port_list, list);
7134 + if(!port->has_connection)
7136 + reactivate_fd(port->fd, ACCEPT_IRQ);
7137 + while(port_accept(port)) ;
7138 + port->has_connection = 0;
7140 + restore_flags(flags);
7143 +struct tq_struct port_task = {
7144 + .routine = port_task_proc,
7148 +static void port_interrupt(int irq, void *data, struct pt_regs *regs)
7150 + struct port_list *port = data;
7152 + port->has_connection = 1;
7153 + schedule_task(&port_task);
7156 +void *port_data(int port_num)
7158 + struct list_head *ele;
7159 + struct port_list *port;
7160 + struct port_dev *dev = NULL;
7164 + list_for_each(ele, &ports){
7165 + port = list_entry(ele, struct port_list, list);
7166 + if(port->port == port_num) goto found;
7168 + port = kmalloc(sizeof(struct port_list), GFP_KERNEL);
7170 + printk(KERN_ERR "Allocation of port list failed\n");
7174 + fd = port_listen_fd(port_num);
7176 + printk(KERN_ERR "binding to port %d failed, errno = %d\n",
7180 + if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
7181 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "port",
7183 + printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
7187 + *port = ((struct port_list)
7188 + { .list = LIST_HEAD_INIT(port->list),
7189 + .has_connection = 0,
7190 + .sem = __SEMAPHORE_INITIALIZER(port->sem,
7192 + .lock = SPIN_LOCK_UNLOCKED,
7195 + .pending = LIST_HEAD_INIT(port->pending),
7196 + .connections = LIST_HEAD_INIT(port->connections) });
7197 + list_add(&port->list, &ports);
7200 + dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL);
7202 + printk(KERN_ERR "Allocation of port device entry failed\n");
7206 + *dev = ((struct port_dev) { .port = port,
7208 + .telnetd_pid = -1 });
7214 + os_close_file(fd);
7220 +int port_wait(void *data)
7222 + struct port_dev *dev = data;
7223 + struct connection *conn;
7224 + struct port_list *port = dev->port;
7228 + if(down_interruptible(&port->sem))
7229 + return(-ERESTARTSYS);
7231 + spin_lock(&port->lock);
7233 + conn = list_entry(port->connections.next, struct connection,
7235 + list_del(&conn->list);
7236 + spin_unlock(&port->lock);
7238 + os_shutdown_socket(conn->socket[0], 1, 1);
7239 + os_close_file(conn->socket[0]);
7240 + os_shutdown_socket(conn->socket[1], 1, 1);
7241 + os_close_file(conn->socket[1]);
7243 + /* This is done here because freeing an IRQ can't be done
7244 + * within the IRQ handler. So, pipe_interrupt always ups
7245 + * the semaphore regardless of whether it got a successful
7246 + * connection. Then we loop here throwing out failed
7247 + * connections until a good one is found.
7249 + free_irq(TELNETD_IRQ, conn);
7251 + if(conn->fd >= 0) break;
7252 + os_close_file(conn->fd);
7257 + dev->helper_pid = conn->helper_pid;
7258 + dev->telnetd_pid = conn->telnetd_pid;
7264 +void port_remove_dev(void *d)
7266 + struct port_dev *dev = d;
7268 + if(dev->helper_pid != -1)
7269 + os_kill_process(dev->helper_pid, 0);
7270 + if(dev->telnetd_pid != -1)
7271 + os_kill_process(dev->telnetd_pid, 1);
7272 + dev->helper_pid = -1;
7273 + dev->telnetd_pid = -1;
7276 +void port_kern_free(void *d)
7278 + struct port_dev *dev = d;
7280 + port_remove_dev(dev);
7284 +static void free_port(void)
7286 + struct list_head *ele;
7287 + struct port_list *port;
7289 + list_for_each(ele, &ports){
7290 + port = list_entry(ele, struct port_list, list);
7291 + free_irq_by_fd(port->fd);
7292 + os_close_file(port->fd);
7296 +__uml_exitcall(free_port);
7299 + * Overrides for Emacs so that we follow Linus's tabbing style.
7300 + * Emacs will notice this stuff at the end of the file and automatically
7301 + * adjust the settings for this buffer only. This must remain at the end
7303 + * ---------------------------------------------------------------------------
7304 + * Local variables:
7305 + * c-file-style: "linux"
7308 diff -Naur -X ../exclude-files orig/arch/um/drivers/port_user.c um/arch/um/drivers/port_user.c
7309 --- orig/arch/um/drivers/port_user.c Wed Dec 31 19:00:00 1969
7310 +++ um/arch/um/drivers/port_user.c Mon Dec 16 22:46:20 2002
7313 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
7314 + * Licensed under the GPL
7318 +#include <stddef.h>
7319 +#include <stdlib.h>
7320 +#include <string.h>
7322 +#include <unistd.h>
7323 +#include <termios.h>
7324 +#include <sys/socket.h>
7325 +#include <sys/un.h>
7326 +#include <netinet/in.h>
7327 +#include "user_util.h"
7328 +#include "kern_util.h"
7330 +#include "chan_user.h"
7332 +#include "helper.h"
7337 + struct termios tt;
7338 + void *kernel_data;
7339 + char dev[sizeof("32768\0")];
7342 +void *port_init(char *str, int device, struct chan_opts *opts)
7344 + struct port_chan *data;
7350 + printk("port_init : channel type 'port' must specify a "
7355 + port = strtoul(str, &end, 0);
7356 + if((*end != '\0') || (end == str)){
7357 + printk("port_init : couldn't parse port '%s'\n", str);
7361 + if((kern_data = port_data(port)) == NULL)
7364 + if((data = um_kmalloc(sizeof(*data))) == NULL)
7367 + *data = ((struct port_chan) { .raw = opts->raw,
7368 + .kernel_data = kern_data });
7369 + sprintf(data->dev, "%d", port);
7373 + port_kern_free(kern_data);
7377 +void port_free(void *d)
7379 + struct port_chan *data = d;
7381 + port_kern_free(data->kernel_data);
7385 +int port_open(int input, int output, int primary, void *d, char **dev_out)
7387 + struct port_chan *data = d;
7390 + fd = port_wait(data->kernel_data);
7391 + if((fd >= 0) && data->raw){
7392 + tcgetattr(fd, &data->tt);
7395 + *dev_out = data->dev;
7399 +void port_close(int fd, void *d)
7401 + struct port_chan *data = d;
7403 + port_remove_dev(data->kernel_data);
7407 +int port_console_write(int fd, const char *buf, int n, void *d)
7409 + struct port_chan *data = d;
7411 + return(generic_console_write(fd, buf, n, &data->tt));
7414 +struct chan_ops port_ops = {
7416 + .init = port_init,
7417 + .open = port_open,
7418 + .close = port_close,
7419 + .read = generic_read,
7420 + .write = generic_write,
7421 + .console_write = port_console_write,
7422 + .window_size = generic_window_size,
7423 + .free = port_free,
7427 +int port_listen_fd(int port)
7429 + struct sockaddr_in addr;
7432 + fd = socket(PF_INET, SOCK_STREAM, 0);
7436 + addr.sin_family = AF_INET;
7437 + addr.sin_port = htons(port);
7438 + addr.sin_addr.s_addr = htonl(INADDR_ANY);
7439 + if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){
7444 + if((listen(fd, 1) < 0) || (os_set_fd_block(fd, 0))){
7451 + os_close_file(fd);
7455 +struct port_pre_exec_data {
7460 +void port_pre_exec(void *arg)
7462 + struct port_pre_exec_data *data = arg;
7464 + dup2(data->sock_fd, 0);
7465 + dup2(data->sock_fd, 1);
7466 + dup2(data->sock_fd, 2);
7467 + close(data->sock_fd);
7468 + dup2(data->pipe_fd, 3);
7469 + os_shutdown_socket(3, 1, 0);
7470 + close(data->pipe_fd);
7473 +int port_connection(int fd, int *socket, int *pid_out)
7476 + char *argv[] = { "/usr/sbin/in.telnetd", "-L",
7477 + "/usr/lib/uml/port-helper", NULL };
7478 + struct port_pre_exec_data data;
7480 + if((new = os_accept_connection(fd)) < 0)
7483 + err = os_pipe(socket, 0, 0);
7487 + data = ((struct port_pre_exec_data)
7489 + .pipe_fd = socket[1] });
7491 + err = run_helper(port_pre_exec, &data, argv, NULL);
7493 + goto out_shutdown;
7499 + os_shutdown_socket(socket[0], 1, 1);
7501 + os_shutdown_socket(socket[1], 1, 1);
7509 + * Overrides for Emacs so that we follow Linus's tabbing style.
7510 + * Emacs will notice this stuff at the end of the file and automatically
7511 + * adjust the settings for this buffer only. This must remain at the end
7513 + * ---------------------------------------------------------------------------
7514 + * Local variables:
7515 + * c-file-style: "linux"
7518 diff -Naur -X ../exclude-files orig/arch/um/drivers/pty.c um/arch/um/drivers/pty.c
7519 --- orig/arch/um/drivers/pty.c Wed Dec 31 19:00:00 1969
7520 +++ um/arch/um/drivers/pty.c Sun Dec 15 21:06:01 2002
7523 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7524 + * Licensed under the GPL
7528 +#include <unistd.h>
7529 +#include <string.h>
7532 +#include <termios.h>
7533 +#include "chan_user.h"
7535 +#include "user_util.h"
7536 +#include "kern_util.h"
7539 + void (*announce)(char *dev_name, int dev);
7542 + struct termios tt;
7543 + char dev_name[sizeof("/dev/pts/0123456\0")];
7546 +void *pty_chan_init(char *str, int device, struct chan_opts *opts)
7548 + struct pty_chan *data;
7550 + if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
7551 + *data = ((struct pty_chan) { .announce = opts->announce,
7553 + .raw = opts->raw });
7557 +int pts_open(int input, int output, int primary, void *d, char **dev_out)
7559 + struct pty_chan *data = d;
7563 + if((fd = get_pty()) < 0){
7564 + printk("open_pts : Failed to open pts\n");
7568 + tcgetattr(fd, &data->tt);
7572 + dev = ptsname(fd);
7573 + sprintf(data->dev_name, "%s", dev);
7574 + *dev_out = data->dev_name;
7575 + if(data->announce) (*data->announce)(dev, data->dev);
7579 +int getmaster(char *line)
7582 + char *pty, *bank, *cp;
7585 + pty = &line[strlen("/dev/ptyp")];
7586 + for (bank = "pqrs"; *bank; bank++) {
7587 + line[strlen("/dev/pty")] = *bank;
7589 + if (stat(line, &stb) < 0)
7591 + for (cp = "0123456789abcdef"; *cp; cp++) {
7593 + master = open(line, O_RDWR);
7594 + if (master >= 0) {
7595 + char *tp = &line[strlen("/dev/")];
7598 + /* verify slave side is usable */
7600 + ok = access(line, R_OK|W_OK) == 0;
7602 + if (ok) return(master);
7603 + (void) close(master);
7610 +int pty_open(int input, int output, int primary, void *d, char **dev_out)
7612 + struct pty_chan *data = d;
7614 + char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
7616 + fd = getmaster(dev);
7617 + if(fd < 0) return(-errno);
7619 + if(data->raw) raw(fd, 0);
7620 + if(data->announce) (*data->announce)(dev, data->dev);
7622 + sprintf(data->dev_name, "%s", dev);
7623 + *dev_out = data->dev_name;
7627 +int pty_console_write(int fd, const char *buf, int n, void *d)
7629 + struct pty_chan *data = d;
7631 + return(generic_console_write(fd, buf, n, &data->tt));
7634 +struct chan_ops pty_ops = {
7636 + .init = pty_chan_init,
7638 + .close = generic_close,
7639 + .read = generic_read,
7640 + .write = generic_write,
7641 + .console_write = pty_console_write,
7642 + .window_size = generic_window_size,
7643 + .free = generic_free,
7647 +struct chan_ops pts_ops = {
7649 + .init = pty_chan_init,
7651 + .close = generic_close,
7652 + .read = generic_read,
7653 + .write = generic_write,
7654 + .console_write = pty_console_write,
7655 + .window_size = generic_window_size,
7656 + .free = generic_free,
7661 + * Overrides for Emacs so that we follow Linus's tabbing style.
7662 + * Emacs will notice this stuff at the end of the file and automatically
7663 + * adjust the settings for this buffer only. This must remain at the end
7665 + * ---------------------------------------------------------------------------
7666 + * Local variables:
7667 + * c-file-style: "linux"
7670 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip.h um/arch/um/drivers/slip.h
7671 --- orig/arch/um/drivers/slip.h Wed Dec 31 19:00:00 1969
7672 +++ um/arch/um/drivers/slip.h Wed Oct 23 21:08:04 2002
7674 +#ifndef __UM_SLIP_H
7675 +#define __UM_SLIP_H
7677 +#define BUF_SIZE 1500
7678 + /* two bytes each for a (pathological) max packet of escaped chars + *
7679 + * terminating END char + initial END char */
7680 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
7684 + char name[sizeof("slnnnnn\0")];
7688 + char ibuf[ENC_BUF_SIZE];
7689 + char obuf[ENC_BUF_SIZE];
7690 + int more; /* more data: do not read fd until ibuf has been drained */
7695 +extern struct net_user_info slip_user_info;
7697 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
7698 +extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri);
7699 +extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri);
7704 + * Overrides for Emacs so that we follow Linus's tabbing style.
7705 + * Emacs will notice this stuff at the end of the file and automatically
7706 + * adjust the settings for this buffer only. This must remain at the end
7708 + * ---------------------------------------------------------------------------
7709 + * Local variables:
7710 + * c-file-style: "linux"
7713 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_kern.c um/arch/um/drivers/slip_kern.c
7714 --- orig/arch/um/drivers/slip_kern.c Wed Dec 31 19:00:00 1969
7715 +++ um/arch/um/drivers/slip_kern.c Sun Dec 15 21:06:24 2002
7717 +#include "linux/config.h"
7718 +#include "linux/kernel.h"
7719 +#include "linux/stddef.h"
7720 +#include "linux/init.h"
7721 +#include "linux/netdevice.h"
7722 +#include "linux/if_arp.h"
7723 +#include "net_kern.h"
7724 +#include "net_user.h"
7732 +void slip_init(struct net_device *dev, void *data)
7734 + struct uml_net_private *private;
7735 + struct slip_data *spri;
7736 + struct slip_init *init = data;
7738 + private = dev->priv;
7739 + spri = (struct slip_data *) private->user;
7740 + *spri = ((struct slip_data)
7741 + { .name = { '\0' },
7743 + .gate_addr = init->gate_addr,
7752 + dev->hard_header_len = 0;
7753 + dev->addr_len = 4;
7754 + dev->type = ARPHRD_ETHER;
7755 + dev->tx_queue_len = 256;
7756 + dev->flags = IFF_NOARP;
7757 + printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr);
7760 +static unsigned short slip_protocol(struct sk_buff *skbuff)
7762 + return(htons(ETH_P_IP));
7765 +static int slip_read(int fd, struct sk_buff **skb,
7766 + struct uml_net_private *lp)
7768 + return(slip_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu,
7769 + (struct slip_data *) &lp->user));
7772 +static int slip_write(int fd, struct sk_buff **skb,
7773 + struct uml_net_private *lp)
7775 + return(slip_user_write(fd, (*skb)->data, (*skb)->len,
7776 + (struct slip_data *) &lp->user));
7779 +struct net_kern_info slip_kern_info = {
7780 + .init = slip_init,
7781 + .protocol = slip_protocol,
7782 + .read = slip_read,
7783 + .write = slip_write,
7786 +static int slip_setup(char *str, char **mac_out, void *data)
7788 + struct slip_init *init = data;
7790 + *init = ((struct slip_init)
7791 + { .gate_addr = NULL });
7793 + if(str[0] != '\0')
7794 + init->gate_addr = str;
7798 +static struct transport slip_transport = {
7799 + .list = LIST_HEAD_INIT(slip_transport.list),
7801 + .setup = slip_setup,
7802 + .user = &slip_user_info,
7803 + .kern = &slip_kern_info,
7804 + .private_size = sizeof(struct slip_data),
7805 + .setup_size = sizeof(struct slip_init),
7808 +static int register_slip(void)
7810 + register_transport(&slip_transport);
7814 +__initcall(register_slip);
7817 + * Overrides for Emacs so that we follow Linus's tabbing style.
7818 + * Emacs will notice this stuff at the end of the file and automatically
7819 + * adjust the settings for this buffer only. This must remain at the end
7821 + * ---------------------------------------------------------------------------
7822 + * Local variables:
7823 + * c-file-style: "linux"
7826 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_proto.h um/arch/um/drivers/slip_proto.h
7827 --- orig/arch/um/drivers/slip_proto.h Wed Dec 31 19:00:00 1969
7828 +++ um/arch/um/drivers/slip_proto.h Wed Oct 23 21:08:04 2002
7831 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7832 + * Licensed under the GPL
7835 +#ifndef __UM_SLIP_PROTO_H__
7836 +#define __UM_SLIP_PROTO_H__
7838 +/* SLIP protocol characters. */
7839 +#define SLIP_END 0300 /* indicates end of frame */
7840 +#define SLIP_ESC 0333 /* indicates byte stuffing */
7841 +#define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */
7842 +#define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
7844 +static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc)
7857 + case SLIP_ESC_ESC:
7863 + case SLIP_ESC_END:
7870 + buf[(*pos)++] = c;
7874 +static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
7876 + unsigned char *ptr = d;
7880 + * Send an initial END character to flush out any
7881 + * data that may have accumulated in the receiver
7882 + * due to line noise.
7885 + *ptr++ = SLIP_END;
7888 + * For each byte in the packet, send the appropriate
7889 + * character sequence, according to the SLIP protocol.
7892 + while (len-- > 0) {
7893 + switch(c = *s++) {
7895 + *ptr++ = SLIP_ESC;
7896 + *ptr++ = SLIP_ESC_END;
7899 + *ptr++ = SLIP_ESC;
7900 + *ptr++ = SLIP_ESC_ESC;
7907 + *ptr++ = SLIP_END;
7914 + * Overrides for Emacs so that we follow Linus's tabbing style.
7915 + * Emacs will notice this stuff at the end of the file and automatically
7916 + * adjust the settings for this buffer only. This must remain at the end
7918 + * ---------------------------------------------------------------------------
7919 + * Local variables:
7920 + * c-file-style: "linux"
7923 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_user.c um/arch/um/drivers/slip_user.c
7924 --- orig/arch/um/drivers/slip_user.c Wed Dec 31 19:00:00 1969
7925 +++ um/arch/um/drivers/slip_user.c Sun Dec 15 21:06:35 2002
7928 +#include <stdlib.h>
7929 +#include <unistd.h>
7930 +#include <stddef.h>
7932 +#include <string.h>
7933 +#include <sys/fcntl.h>
7934 +#include <sys/errno.h>
7935 +#include <sys/termios.h>
7936 +#include <sys/wait.h>
7937 +#include <sys/ioctl.h>
7938 +#include <sys/signal.h>
7939 +#include "user_util.h"
7940 +#include "kern_util.h"
7942 +#include "net_user.h"
7944 +#include "slip_proto.h"
7945 +#include "helper.h"
7948 +void slip_user_init(void *data, void *dev)
7950 + struct slip_data *pri = data;
7955 +static int set_up_tty(int fd)
7958 + struct termios tios;
7960 + if (tcgetattr(fd, &tios) < 0) {
7961 + printk("could not get initial terminal attributes\n");
7965 + tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
7966 + tios.c_iflag = IGNBRK | IGNPAR;
7969 + for (i = 0; i < NCCS; i++)
7971 + tios.c_cc[VMIN] = 1;
7972 + tios.c_cc[VTIME] = 0;
7974 + cfsetospeed(&tios, B38400);
7975 + cfsetispeed(&tios, B38400);
7977 + if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
7978 + printk("failed to set terminal attributes\n");
7984 +struct slip_pre_exec_data {
7990 +static void slip_pre_exec(void *arg)
7992 + struct slip_pre_exec_data *data = arg;
7994 + if(data->stdin != -1) dup2(data->stdin, 0);
7995 + dup2(data->stdout, 1);
7996 + if(data->close_me != -1) close(data->close_me);
7999 +static int slip_tramp(char **argv, int fd)
8001 + struct slip_pre_exec_data pe_data;
8003 + int status, pid, fds[2], err, output_len;
8005 + err = os_pipe(fds, 1, 0);
8007 + printk("slip_tramp : pipe failed, errno = %d\n", -err);
8012 + pe_data.stdin = fd;
8013 + pe_data.stdout = fds[1];
8014 + pe_data.close_me = fds[0];
8015 + pid = run_helper(slip_pre_exec, &pe_data, argv, NULL);
8017 + if(pid < 0) err = pid;
8019 + output_len = page_size();
8020 + output = um_kmalloc(output_len);
8021 + if(output == NULL)
8022 + printk("slip_tramp : failed to allocate output "
8026 + read_output(fds[0], output, output_len);
8027 + if(output != NULL){
8028 + printk("%s", output);
8031 + if(waitpid(pid, &status, 0) < 0) err = errno;
8032 + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
8033 + printk("'%s' didn't exit with status 0\n", argv[0]);
8040 +static int slip_open(void *data)
8042 + struct slip_data *pri = data;
8043 + char version_buf[sizeof("nnnnn\0")];
8044 + char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
8045 + char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf,
8047 + int sfd, mfd, disc, sencap, err;
8049 + if((mfd = get_pty()) < 0){
8050 + printk("umn : Failed to open pty\n");
8053 + if((sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0)) < 0){
8054 + printk("Couldn't open tty for slip line\n");
8057 + if(set_up_tty(sfd)) return(-1);
8061 + if(pri->gate_addr != NULL){
8062 + sprintf(version_buf, "%d", UML_NET_VERSION);
8063 + strcpy(gate_buf, pri->gate_addr);
8065 + err = slip_tramp(argv, sfd);
8068 + printk("slip_tramp failed - errno = %d\n", err);
8071 + if(ioctl(pri->slave, SIOCGIFNAME, pri->name) < 0){
8072 + printk("SIOCGIFNAME failed, errno = %d\n", errno);
8075 + iter_addresses(pri->dev, open_addr, pri->name);
8079 + if(ioctl(sfd, TIOCSETD, &disc) < 0){
8080 + printk("Failed to set slip line discipline - "
8081 + "errno = %d\n", errno);
8085 + if(ioctl(sfd, SIOCSIFENCAP, &sencap) < 0){
8086 + printk("Failed to set slip encapsulation - "
8087 + "errno = %d\n", errno);
8094 +static void slip_close(int fd, void *data)
8096 + struct slip_data *pri = data;
8097 + char version_buf[sizeof("nnnnn\0")];
8098 + char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
8102 + if(pri->gate_addr != NULL)
8103 + iter_addresses(pri->dev, close_addr, pri->name);
8105 + sprintf(version_buf, "%d", UML_NET_VERSION);
8107 + err = slip_tramp(argv, -1);
8110 + printk("slip_tramp failed - errno = %d\n", err);
8112 + close(pri->slave);
8116 +int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
8118 + int i, n, size, start;
8122 + while(i < pri->more) {
8123 + size = slip_unesc(pri->ibuf[i++],
8124 + pri->ibuf, &pri->pos, &pri->esc);
8126 + memcpy(buf, pri->ibuf, size);
8127 + memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
8128 + pri->more=pri->more-i;
8135 + n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
8136 + if(n <= 0) return(n);
8139 + for(i = 0; i < n; i++){
8140 + size = slip_unesc(pri->ibuf[start + i],
8141 + pri->ibuf, &pri->pos, &pri->esc);
8143 + memcpy(buf, pri->ibuf, size);
8144 + memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
8145 + pri->more=n-(i+1);
8152 +int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
8156 + actual = slip_esc(buf, pri->obuf, len);
8157 + n = net_write(fd, pri->obuf, actual);
8158 + if(n < 0) return(n);
8162 +static int slip_set_mtu(int mtu, void *data)
8167 +static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
8170 + struct slip_data *pri = data;
8172 + if(pri->slave == -1) return;
8173 + open_addr(addr, netmask, pri->name);
8176 +static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
8179 + struct slip_data *pri = data;
8181 + if(pri->slave == -1) return;
8182 + close_addr(addr, netmask, pri->name);
8185 +struct net_user_info slip_user_info = {
8186 + .init = slip_user_init,
8187 + .open = slip_open,
8188 + .close = slip_close,
8190 + .set_mtu = slip_set_mtu,
8191 + .add_address = slip_add_addr,
8192 + .delete_address = slip_del_addr,
8193 + .max_packet = BUF_SIZE
8197 + * Overrides for Emacs so that we follow Linus's tabbing style.
8198 + * Emacs will notice this stuff at the end of the file and automatically
8199 + * adjust the settings for this buffer only. This must remain at the end
8201 + * ---------------------------------------------------------------------------
8202 + * Local variables:
8203 + * c-file-style: "linux"
8206 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp.h um/arch/um/drivers/slirp.h
8207 --- orig/arch/um/drivers/slirp.h Wed Dec 31 19:00:00 1969
8208 +++ um/arch/um/drivers/slirp.h Wed Oct 23 21:08:04 2002
8210 +#ifndef __UM_SLIRP_H
8211 +#define __UM_SLIRP_H
8213 +#define BUF_SIZE 1500
8214 + /* two bytes each for a (pathological) max packet of escaped chars + *
8215 + * terminating END char + initial END char */
8216 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8218 +#define SLIRP_MAX_ARGS 100
8220 + * XXX this next definition is here because I don't understand why this
8221 + * initializer doesn't work in slirp_kern.c:
8223 + * argv : { init->argv[ 0 ... SLIRP_MAX_ARGS-1 ] },
8225 + * or why I can't typecast like this:
8227 + * argv : (char* [SLIRP_MAX_ARGS])(init->argv),
8229 +struct arg_list_dummy_wrapper { char *argv[SLIRP_MAX_ARGS]; };
8231 +struct slirp_data {
8233 + struct arg_list_dummy_wrapper argw;
8236 + char ibuf[ENC_BUF_SIZE];
8237 + char obuf[ENC_BUF_SIZE];
8238 + int more; /* more data: do not read fd until ibuf has been drained */
8243 +extern struct net_user_info slirp_user_info;
8245 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
8246 +extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri);
8247 +extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri);
8252 + * Overrides for Emacs so that we follow Linus's tabbing style.
8253 + * Emacs will notice this stuff at the end of the file and automatically
8254 + * adjust the settings for this buffer only. This must remain at the end
8256 + * ---------------------------------------------------------------------------
8257 + * Local variables:
8258 + * c-file-style: "linux"
8261 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_kern.c um/arch/um/drivers/slirp_kern.c
8262 --- orig/arch/um/drivers/slirp_kern.c Wed Dec 31 19:00:00 1969
8263 +++ um/arch/um/drivers/slirp_kern.c Sun Dec 15 21:06:54 2002
8265 +#include "linux/kernel.h"
8266 +#include "linux/stddef.h"
8267 +#include "linux/init.h"
8268 +#include "linux/netdevice.h"
8269 +#include "linux/if_arp.h"
8270 +#include "net_kern.h"
8271 +#include "net_user.h"
8275 +struct slirp_init {
8276 + struct arg_list_dummy_wrapper argw; /* XXX should be simpler... */
8279 +void slirp_init(struct net_device *dev, void *data)
8281 + struct uml_net_private *private;
8282 + struct slirp_data *spri;
8283 + struct slirp_init *init = data;
8286 + private = dev->priv;
8287 + spri = (struct slirp_data *) private->user;
8288 + *spri = ((struct slirp_data)
8289 + { .argw = init->argw,
8299 + dev->hard_header_len = 0;
8300 + dev->addr_len = 4;
8301 + dev->type = ARPHRD_ETHER;
8302 + dev->tx_queue_len = 256;
8303 + dev->flags = IFF_NOARP;
8304 + printk("SLIRP backend - command line:");
8305 + for(i=0;spri->argw.argv[i]!=NULL;i++) {
8306 + printk(" '%s'",spri->argw.argv[i]);
8311 +static unsigned short slirp_protocol(struct sk_buff *skbuff)
8313 + return(htons(ETH_P_IP));
8316 +static int slirp_read(int fd, struct sk_buff **skb,
8317 + struct uml_net_private *lp)
8319 + return(slirp_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu,
8320 + (struct slirp_data *) &lp->user));
8323 +static int slirp_write(int fd, struct sk_buff **skb,
8324 + struct uml_net_private *lp)
8326 + return(slirp_user_write(fd, (*skb)->data, (*skb)->len,
8327 + (struct slirp_data *) &lp->user));
8330 +struct net_kern_info slirp_kern_info = {
8331 + .init = slirp_init,
8332 + .protocol = slirp_protocol,
8333 + .read = slirp_read,
8334 + .write = slirp_write,
8337 +static int slirp_setup(char *str, char **mac_out, void *data)
8339 + struct slirp_init *init = data;
8342 + *init = ((struct slirp_init)
8343 + { argw : { { "slirp", NULL } } });
8345 + str = split_if_spec(str, mac_out, NULL);
8347 + if(str == NULL) { /* no command line given after MAC addr */
8352 + if(i>=SLIRP_MAX_ARGS-1) {
8353 + printk("slirp_setup: truncating slirp arguments\n");
8356 + init->argw.argv[i++] = str;
8357 + while(*str && *str!=',') {
8358 + if(*str=='_') *str=' ';
8365 + init->argw.argv[i]=NULL;
8369 +static struct transport slirp_transport = {
8370 + .list = LIST_HEAD_INIT(slirp_transport.list),
8372 + .setup = slirp_setup,
8373 + .user = &slirp_user_info,
8374 + .kern = &slirp_kern_info,
8375 + .private_size = sizeof(struct slirp_data),
8376 + .setup_size = sizeof(struct slirp_init),
8379 +static int register_slirp(void)
8381 + register_transport(&slirp_transport);
8385 +__initcall(register_slirp);
8388 + * Overrides for Emacs so that we follow Linus's tabbing style.
8389 + * Emacs will notice this stuff at the end of the file and automatically
8390 + * adjust the settings for this buffer only. This must remain at the end
8392 + * ---------------------------------------------------------------------------
8393 + * Local variables:
8394 + * c-file-style: "linux"
8397 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_user.c um/arch/um/drivers/slirp_user.c
8398 --- orig/arch/um/drivers/slirp_user.c Wed Dec 31 19:00:00 1969
8399 +++ um/arch/um/drivers/slirp_user.c Sun Dec 15 21:07:08 2002
8402 +#include <stdlib.h>
8403 +#include <unistd.h>
8404 +#include <stddef.h>
8406 +#include <string.h>
8407 +#include <sys/fcntl.h>
8408 +#include <sys/errno.h>
8409 +#include <sys/wait.h>
8410 +#include <sys/signal.h>
8411 +#include "user_util.h"
8412 +#include "kern_util.h"
8414 +#include "net_user.h"
8416 +#include "slip_proto.h"
8417 +#include "helper.h"
8420 +void slirp_user_init(void *data, void *dev)
8422 + struct slirp_data *pri = data;
8427 +struct slirp_pre_exec_data {
8432 +static void slirp_pre_exec(void *arg)
8434 + struct slirp_pre_exec_data *data = arg;
8436 + if(data->stdin != -1) dup2(data->stdin, 0);
8437 + if(data->stdout != -1) dup2(data->stdout, 1);
8440 +static int slirp_tramp(char **argv, int fd)
8442 + struct slirp_pre_exec_data pe_data;
8445 + pe_data.stdin = fd;
8446 + pe_data.stdout = fd;
8447 + pid = run_helper(slirp_pre_exec, &pe_data, argv, NULL);
8452 +static int slirp_datachan(int *mfd, int *sfd)
8456 + err = os_pipe(fds, 1, 1);
8458 + printk("slirp_datachan: Failed to open pipe, errno = %d\n",
8468 +static int slirp_open(void *data)
8470 + struct slirp_data *pri = data;
8471 + int sfd, mfd, pid, err;
8473 + err = slirp_datachan(&mfd, &sfd);
8477 + pid = slirp_tramp(pri->argw.argv, sfd);
8480 + printk("slirp_tramp failed - errno = %d\n", pid);
8481 + os_close_file(sfd);
8482 + os_close_file(mfd);
8495 +static void slirp_close(int fd, void *data)
8497 + struct slirp_data *pri = data;
8501 + close(pri->slave);
8506 + printk("slirp_close: no child process to shut down\n");
8511 + if(kill(pri->pid, SIGHUP)<0) {
8512 + printk("slirp_close: sending hangup to %d failed (%d)\n",
8517 + err = waitpid(pri->pid, &status, WNOHANG);
8519 + printk("slirp_close: waitpid returned %d\n", errno);
8524 + printk("slirp_close: process %d has not exited\n");
8531 +int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
8533 + int i, n, size, start;
8537 + while(i < pri->more) {
8538 + size = slip_unesc(pri->ibuf[i++],
8539 + pri->ibuf,&pri->pos,&pri->esc);
8541 + memcpy(buf, pri->ibuf, size);
8542 + memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
8543 + pri->more=pri->more-i;
8550 + n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
8551 + if(n <= 0) return(n);
8554 + for(i = 0; i < n; i++){
8555 + size = slip_unesc(pri->ibuf[start + i],
8556 + pri->ibuf,&pri->pos,&pri->esc);
8558 + memcpy(buf, pri->ibuf, size);
8559 + memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
8560 + pri->more=n-(i+1);
8567 +int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
8571 + actual = slip_esc(buf, pri->obuf, len);
8572 + n = net_write(fd, pri->obuf, actual);
8573 + if(n < 0) return(n);
8577 +static int slirp_set_mtu(int mtu, void *data)
8582 +struct net_user_info slirp_user_info = {
8583 + .init = slirp_user_init,
8584 + .open = slirp_open,
8585 + .close = slirp_close,
8587 + .set_mtu = slirp_set_mtu,
8588 + .add_address = NULL,
8589 + .delete_address = NULL,
8590 + .max_packet = BUF_SIZE
8594 + * Overrides for Emacs so that we follow Linus's tabbing style.
8595 + * Emacs will notice this stuff at the end of the file and automatically
8596 + * adjust the settings for this buffer only. This must remain at the end
8598 + * ---------------------------------------------------------------------------
8599 + * Local variables:
8600 + * c-file-style: "linux"
8603 diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.c um/arch/um/drivers/ssl.c
8604 --- orig/arch/um/drivers/ssl.c Wed Dec 31 19:00:00 1969
8605 +++ um/arch/um/drivers/ssl.c Thu Mar 6 18:55:01 2003
8608 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
8609 + * Licensed under the GPL
8612 +#include "linux/config.h"
8613 +#include "linux/fs.h"
8614 +#include "linux/tty.h"
8615 +#include "linux/tty_driver.h"
8616 +#include "linux/major.h"
8617 +#include "linux/mm.h"
8618 +#include "linux/init.h"
8619 +#include "asm/termbits.h"
8620 +#include "asm/irq.h"
8623 +#include "chan_kern.h"
8624 +#include "user_util.h"
8625 +#include "kern_util.h"
8628 +#include "irq_user.h"
8629 +#include "mconsole_kern.h"
8630 +#include "2_5compat.h"
8632 +static int ssl_version = 1;
8634 +/* Referenced only by tty_driver below - presumably it's locked correctly
8635 + * by the tty driver.
8637 +static int ssl_refcount = 0;
8639 +static struct tty_driver ssl_driver;
8641 +#define NR_PORTS 64
8643 +void ssl_announce(char *dev_name, int dev)
8645 + printk(KERN_INFO "Serial line %d assigned device '%s'\n", dev,
8649 +static struct chan_opts opts = {
8650 + .announce = ssl_announce,
8651 + .xterm_title = "Serial Line #%d",
8657 +static int ssl_config(char *str);
8658 +static int ssl_get_config(char *dev, char *str, int size, char **error_out);
8659 +static int ssl_remove(char *str);
8661 +static struct line_driver driver = {
8662 + .name = "UML serial line",
8663 + .devfs_name = "tts/%d",
8664 + .major = TTY_MAJOR,
8665 + .minor_start = 64,
8666 + .type = TTY_DRIVER_TYPE_SERIAL,
8668 + .read_irq = SSL_IRQ,
8669 + .read_irq_name = "ssl",
8670 + .write_irq = SSL_WRITE_IRQ,
8671 + .write_irq_name = "ssl-write",
8672 + .symlink_from = "serial",
8673 + .symlink_to = "tts",
8676 + .config = ssl_config,
8677 + .get_config = ssl_get_config,
8678 + .remove = ssl_remove,
8682 +/* The array is initialized by line_init, which is an initcall. The
8683 + * individual elements are protected by individual semaphores.
8685 +static struct line serial_lines[NR_PORTS] =
8686 + { [0 ... NR_PORTS - 1] = LINE_INIT(CONFIG_SSL_CHAN, &driver) };
8688 +static struct lines lines = LINES_INIT(NR_PORTS);
8690 +static int ssl_config(char *str)
8692 + return(line_config(serial_lines,
8693 + sizeof(serial_lines)/sizeof(serial_lines[0]), str));
8696 +static int ssl_get_config(char *dev, char *str, int size, char **error_out)
8698 + return(line_get_config(dev, serial_lines,
8699 + sizeof(serial_lines)/sizeof(serial_lines[0]),
8700 + str, size, error_out));
8703 +static int ssl_remove(char *str)
8705 + return(line_remove(serial_lines,
8706 + sizeof(serial_lines)/sizeof(serial_lines[0]), str));
8709 +int ssl_open(struct tty_struct *tty, struct file *filp)
8711 + return(line_open(serial_lines, tty, &opts));
8714 +static void ssl_close(struct tty_struct *tty, struct file * filp)
8716 + line_close(serial_lines, tty);
8719 +static int ssl_write(struct tty_struct * tty, int from_user,
8720 + const unsigned char *buf, int count)
8722 + return(line_write(serial_lines, tty, from_user, buf, count));
8725 +static void ssl_put_char(struct tty_struct *tty, unsigned char ch)
8727 + line_write(serial_lines, tty, 0, &ch, sizeof(ch));
8730 +static void ssl_flush_chars(struct tty_struct *tty)
8735 +static int ssl_chars_in_buffer(struct tty_struct *tty)
8740 +static void ssl_flush_buffer(struct tty_struct *tty)
8745 +static int ssl_ioctl(struct tty_struct *tty, struct file * file,
8746 + unsigned int cmd, unsigned long arg)
8759 + ret = -ENOIOCTLCMD;
8763 + "Unimplemented ioctl in ssl_ioctl : 0x%x\n", cmd);
8764 + ret = -ENOIOCTLCMD;
8770 +static void ssl_throttle(struct tty_struct * tty)
8772 + printk(KERN_ERR "Someone should implement ssl_throttle\n");
8775 +static void ssl_unthrottle(struct tty_struct * tty)
8777 + printk(KERN_ERR "Someone should implement ssl_unthrottle\n");
8780 +static void ssl_set_termios(struct tty_struct *tty,
8781 + struct termios *old_termios)
8785 +static void ssl_stop(struct tty_struct *tty)
8787 + printk(KERN_ERR "Someone should implement ssl_stop\n");
8790 +static void ssl_start(struct tty_struct *tty)
8792 + printk(KERN_ERR "Someone should implement ssl_start\n");
8795 +void ssl_hangup(struct tty_struct *tty)
8799 +static struct tty_driver ssl_driver = {
8800 + .refcount = &ssl_refcount,
8802 + .close = ssl_close,
8803 + .write = ssl_write,
8804 + .put_char = ssl_put_char,
8805 + .flush_chars = ssl_flush_chars,
8806 + .chars_in_buffer = ssl_chars_in_buffer,
8807 + .flush_buffer = ssl_flush_buffer,
8808 + .ioctl = ssl_ioctl,
8809 + .throttle = ssl_throttle,
8810 + .unthrottle = ssl_unthrottle,
8811 + .set_termios = ssl_set_termios,
8813 + .start = ssl_start,
8814 + .hangup = ssl_hangup
8817 +/* Changed by ssl_init and referenced by ssl_exit, which are both serialized
8818 + * by being an initcall and exitcall, respectively.
8820 +static int ssl_init_done = 0;
8826 + printk(KERN_INFO "Initializing software serial port version %d\n",
8829 + line_register_devfs(&lines, &driver, &ssl_driver, serial_lines,
8830 + sizeof(serial_lines)/sizeof(serial_lines[0]));
8832 + lines_init(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]));
8834 + new_title = add_xterm_umid(opts.xterm_title);
8835 + if(new_title != NULL) opts.xterm_title = new_title;
8837 + ssl_init_done = 1;
8841 +__initcall(ssl_init);
8843 +static int ssl_chan_setup(char *str)
8845 + line_setup(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]),
8850 +__setup("ssl", ssl_chan_setup);
8851 +__channel_help(ssl_chan_setup, "ssl");
8853 +static void ssl_exit(void)
8855 + if(!ssl_init_done) return;
8856 + close_lines(serial_lines,
8857 + sizeof(serial_lines)/sizeof(serial_lines[0]));
8860 +__uml_exitcall(ssl_exit);
8863 + * Overrides for Emacs so that we follow Linus's tabbing style.
8864 + * Emacs will notice this stuff at the end of the file and automatically
8865 + * adjust the settings for this buffer only. This must remain at the end
8867 + * ---------------------------------------------------------------------------
8868 + * Local variables:
8869 + * c-file-style: "linux"
8872 diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.h um/arch/um/drivers/ssl.h
8873 --- orig/arch/um/drivers/ssl.h Wed Dec 31 19:00:00 1969
8874 +++ um/arch/um/drivers/ssl.h Wed Oct 23 21:08:04 2002
8877 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
8878 + * Licensed under the GPL
8884 +extern int ssl_read(int fd, int line);
8885 +extern void ssl_receive_char(int line, char ch);
8890 + * Overrides for Emacs so that we follow Linus's tabbing style.
8891 + * Emacs will notice this stuff at the end of the file and automatically
8892 + * adjust the settings for this buffer only. This must remain at the end
8894 + * ---------------------------------------------------------------------------
8895 + * Local variables:
8896 + * c-file-style: "linux"
8899 diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.c um/arch/um/drivers/stdio_console.c
8900 --- orig/arch/um/drivers/stdio_console.c Wed Dec 31 19:00:00 1969
8901 +++ um/arch/um/drivers/stdio_console.c Sun Dec 15 21:08:20 2002
8904 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
8905 + * Licensed under the GPL
8908 +#include "linux/config.h"
8909 +#include "linux/posix_types.h"
8910 +#include "linux/tty.h"
8911 +#include "linux/tty_flip.h"
8912 +#include "linux/types.h"
8913 +#include "linux/major.h"
8914 +#include "linux/kdev_t.h"
8915 +#include "linux/console.h"
8916 +#include "linux/string.h"
8917 +#include "linux/sched.h"
8918 +#include "linux/list.h"
8919 +#include "linux/init.h"
8920 +#include "linux/interrupt.h"
8921 +#include "linux/slab.h"
8922 +#include "asm/current.h"
8923 +#include "asm/softirq.h"
8924 +#include "asm/hardirq.h"
8925 +#include "asm/irq.h"
8926 +#include "stdio_console.h"
8928 +#include "chan_kern.h"
8929 +#include "user_util.h"
8930 +#include "kern_util.h"
8931 +#include "irq_user.h"
8932 +#include "mconsole_kern.h"
8934 +#include "2_5compat.h"
8936 +#define MAX_TTYS (8)
8938 +/* Referenced only by tty_driver below - presumably it's locked correctly
8939 + * by the tty driver.
8942 +static struct tty_driver console_driver;
8944 +static int console_refcount = 0;
8946 +static struct chan_ops init_console_ops = {
8947 + .type = "you shouldn't see this",
8953 + .console_write = generic_write,
8954 + .window_size = NULL,
8959 +static struct chan init_console_chan = {
8966 + .pri = INIT_STATIC,
8967 + .ops = &init_console_ops,
8971 +void stdio_announce(char *dev_name, int dev)
8973 + printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
8977 +static struct chan_opts opts = {
8978 + .announce = stdio_announce,
8979 + .xterm_title = "Virtual Console #%d",
8985 +static int con_config(char *str);
8986 +static int con_get_config(char *dev, char *str, int size, char **error_out);
8987 +static int con_remove(char *str);
8989 +static struct line_driver driver = {
8990 + .name = "UML console",
8991 + .devfs_name = "vc/%d",
8992 + .major = TTY_MAJOR,
8994 + .type = TTY_DRIVER_TYPE_CONSOLE,
8995 + .subtype = SYSTEM_TYPE_CONSOLE,
8996 + .read_irq = CONSOLE_IRQ,
8997 + .read_irq_name = "console",
8998 + .write_irq = CONSOLE_WRITE_IRQ,
8999 + .write_irq_name = "console-write",
9000 + .symlink_from = "ttys",
9001 + .symlink_to = "vc",
9004 + .config = con_config,
9005 + .get_config = con_get_config,
9006 + .remove = con_remove,
9010 +static struct lines console_lines = LINES_INIT(MAX_TTYS);
9012 +/* The array is initialized by line_init, which is an initcall. The
9013 + * individual elements are protected by individual semaphores.
9015 +struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
9016 + [ 1 ... MAX_TTYS - 1 ] =
9017 + LINE_INIT(CONFIG_CON_CHAN, &driver) };
9019 +static int con_config(char *str)
9021 + return(line_config(vts, sizeof(vts)/sizeof(vts[0]), str));
9024 +static int con_get_config(char *dev, char *str, int size, char **error_out)
9026 + return(line_get_config(dev, vts, sizeof(vts)/sizeof(vts[0]), str,
9027 + size, error_out));
9030 +static int con_remove(char *str)
9032 + return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str));
9035 +static int open_console(struct tty_struct *tty)
9037 + return(line_open(vts, tty, &opts));
9040 +static int con_open(struct tty_struct *tty, struct file *filp)
9042 + return(open_console(tty));
9045 +static void con_close(struct tty_struct *tty, struct file *filp)
9047 + line_close(vts, tty);
9050 +static int con_write(struct tty_struct *tty, int from_user,
9051 + const unsigned char *buf, int count)
9053 + return(line_write(vts, tty, from_user, buf, count));
9056 +static void set_termios(struct tty_struct *tty, struct termios * old)
9060 +static int chars_in_buffer(struct tty_struct *tty)
9065 +static int con_init_done = 0;
9067 +int stdio_init(void)
9071 + printk(KERN_INFO "Initializing stdio console driver\n");
9073 + line_register_devfs(&console_lines, &driver, &console_driver, vts,
9074 + sizeof(vts)/sizeof(vts[0]));
9076 + lines_init(vts, sizeof(vts)/sizeof(vts[0]));
9078 + new_title = add_xterm_umid(opts.xterm_title);
9079 + if(new_title != NULL) opts.xterm_title = new_title;
9081 + open_console(NULL);
9082 + con_init_done = 1;
9086 +__initcall(stdio_init);
9088 +static void console_write(struct console *console, const char *string,
9091 + if(con_init_done) down(&vts[console->index].sem);
9092 + console_write_chan(&vts[console->index].chan_list, string, len);
9093 + if(con_init_done) up(&vts[console->index].sem);
9096 +static struct tty_driver console_driver = {
9097 + .refcount = &console_refcount,
9099 + .close = con_close,
9100 + .write = con_write,
9101 + .chars_in_buffer = chars_in_buffer,
9102 + .set_termios = set_termios
9105 +static kdev_t console_device(struct console *c)
9107 + return mk_kdev(TTY_MAJOR, c->index);
9110 +static int console_setup(struct console *co, char *options)
9115 +static struct console stdiocons = INIT_CONSOLE("tty", console_write,
9116 + console_device, console_setup,
9119 +void stdio_console_init(void)
9121 + INIT_LIST_HEAD(&vts[0].chan_list);
9122 + list_add(&init_console_chan.list, &vts[0].chan_list);
9123 + register_console(&stdiocons);
9126 +static int console_chan_setup(char *str)
9128 + line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1);
9132 +__setup("con", console_chan_setup);
9133 +__channel_help(console_chan_setup, "con");
9135 +static void console_exit(void)
9137 + if(!con_init_done) return;
9138 + close_lines(vts, sizeof(vts)/sizeof(vts[0]));
9141 +__uml_exitcall(console_exit);
9144 + * Overrides for Emacs so that we follow Linus's tabbing style.
9145 + * Emacs will notice this stuff at the end of the file and automatically
9146 + * adjust the settings for this buffer only. This must remain at the end
9148 + * ---------------------------------------------------------------------------
9149 + * Local variables:
9150 + * c-file-style: "linux"
9153 diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.h um/arch/um/drivers/stdio_console.h
9154 --- orig/arch/um/drivers/stdio_console.h Wed Dec 31 19:00:00 1969
9155 +++ um/arch/um/drivers/stdio_console.h Wed Oct 23 21:08:04 2002
9158 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9159 + * Licensed under the GPL
9162 +#ifndef __STDIO_CONSOLE_H
9163 +#define __STDIO_CONSOLE_H
9165 +extern void save_console_flags(void);
9169 + * Overrides for Emacs so that we follow Linus's tabbing style.
9170 + * Emacs will notice this stuff at the end of the file and automatically
9171 + * adjust the settings for this buffer only. This must remain at the end
9173 + * ---------------------------------------------------------------------------
9174 + * Local variables:
9175 + * c-file-style: "linux"
9178 diff -Naur -X ../exclude-files orig/arch/um/drivers/tty.c um/arch/um/drivers/tty.c
9179 --- orig/arch/um/drivers/tty.c Wed Dec 31 19:00:00 1969
9180 +++ um/arch/um/drivers/tty.c Sun Dec 15 21:08:41 2002
9183 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
9184 + * Licensed under the GPL
9188 +#include <termios.h>
9191 +#include <unistd.h>
9192 +#include "chan_user.h"
9193 +#include "user_util.h"
9200 + struct termios tt;
9203 +void *tty_chan_init(char *str, int device, struct chan_opts *opts)
9205 + struct tty_chan *data;
9208 + printk("tty_init : channel type 'tty' must specify "
9214 + if((data = um_kmalloc(sizeof(*data))) == NULL)
9216 + *data = ((struct tty_chan) { .dev = str,
9217 + .raw = opts->raw });
9222 +int tty_open(int input, int output, int primary, void *d, char **dev_out)
9224 + struct tty_chan *data = d;
9227 + fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0);
9228 + if(fd < 0) return(fd);
9230 + tcgetattr(fd, &data->tt);
9234 + *dev_out = data->dev;
9238 +int tty_console_write(int fd, const char *buf, int n, void *d)
9240 + struct tty_chan *data = d;
9242 + return(generic_console_write(fd, buf, n, &data->tt));
9245 +struct chan_ops tty_ops = {
9247 + .init = tty_chan_init,
9249 + .close = generic_close,
9250 + .read = generic_read,
9251 + .write = generic_write,
9252 + .console_write = tty_console_write,
9253 + .window_size = generic_window_size,
9254 + .free = generic_free,
9259 + * Overrides for Emacs so that we follow Linus's tabbing style.
9260 + * Emacs will notice this stuff at the end of the file and automatically
9261 + * adjust the settings for this buffer only. This must remain at the end
9263 + * ---------------------------------------------------------------------------
9264 + * Local variables:
9265 + * c-file-style: "linux"
9268 diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_kern.c um/arch/um/drivers/ubd_kern.c
9269 --- orig/arch/um/drivers/ubd_kern.c Wed Dec 31 19:00:00 1969
9270 +++ um/arch/um/drivers/ubd_kern.c Tue Mar 11 15:46:36 2003
9273 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9274 + * Licensed under the GPL
9277 +/* 2001-09-28...2002-04-17
9278 + * Partition stuff by James_McMechan@hotmail.com
9279 + * old style ubd by setting UBD_SHIFT to 0
9282 +#define MAJOR_NR UBD_MAJOR
9283 +#define UBD_SHIFT 4
9285 +#include "linux/config.h"
9286 +#include "linux/blk.h"
9287 +#include "linux/blkdev.h"
9288 +#include "linux/hdreg.h"
9289 +#include "linux/init.h"
9290 +#include "linux/devfs_fs_kernel.h"
9291 +#include "linux/cdrom.h"
9292 +#include "linux/proc_fs.h"
9293 +#include "linux/ctype.h"
9294 +#include "linux/capability.h"
9295 +#include "linux/mm.h"
9296 +#include "linux/vmalloc.h"
9297 +#include "linux/blkpg.h"
9298 +#include "linux/genhd.h"
9299 +#include "linux/spinlock.h"
9300 +#include "asm/segment.h"
9301 +#include "asm/uaccess.h"
9302 +#include "asm/irq.h"
9303 +#include "asm/types.h"
9304 +#include "user_util.h"
9305 +#include "mem_user.h"
9306 +#include "kern_util.h"
9308 +#include "mconsole_kern.h"
9310 +#include "irq_user.h"
9311 +#include "ubd_user.h"
9312 +#include "2_5compat.h"
9315 +static int ubd_open(struct inode * inode, struct file * filp);
9316 +static int ubd_release(struct inode * inode, struct file * file);
9317 +static int ubd_ioctl(struct inode * inode, struct file * file,
9318 + unsigned int cmd, unsigned long arg);
9319 +static int ubd_revalidate(kdev_t rdev);
9320 +static int ubd_revalidate1(kdev_t rdev);
9322 +#define MAX_DEV (8)
9323 +#define MAX_MINOR (MAX_DEV << UBD_SHIFT)
9325 +/* Not modified by this driver */
9326 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
9327 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
9329 +/* Protected by ubd_lock */
9330 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
9332 +static struct block_device_operations ubd_blops = {
9334 + .release = ubd_release,
9335 + .ioctl = ubd_ioctl,
9336 + .revalidate = ubd_revalidate,
9339 +/* Protected by ubd_lock, except in prepare_request and ubd_ioctl because
9340 + * the block layer should ensure that the device is idle before closing it.
9342 +static struct hd_struct ubd_part[MAX_MINOR] =
9343 + { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
9345 +/* Protected by io_request_lock */
9346 +static request_queue_t *ubd_queue;
9348 +/* Protected by ubd_lock */
9349 +static int fake_major = MAJOR_NR;
9351 +static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
9353 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
9356 + .major_name = name, \
9357 + .minor_shift = shift, \
9358 + .max_p = 1 << shift, \
9360 + .sizes = bsizes, \
9362 + .real_devices = NULL, \
9369 +static struct gendisk ubd_gendisk = INIT_GENDISK(MAJOR_NR, "ubd", ubd_part,
9370 + UBD_SHIFT, sizes, MAX_DEV,
9372 +static struct gendisk fake_gendisk = INIT_GENDISK(0, "ubd", ubd_part,
9373 + UBD_SHIFT, sizes, MAX_DEV,
9376 +#ifdef CONFIG_BLK_DEV_UBD_SYNC
9377 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
9380 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \
9384 +/* Not protected - changed only in ubd_setup_common and then only to
9385 + * to enable O_SYNC.
9387 +static struct openflags global_openflags = OPEN_FLAGS;
9392 + unsigned long *bitmap;
9393 + unsigned long bitmap_len;
9394 + int bitmap_offset;
9403 + struct openflags boot_openflags;
9404 + struct openflags openflags;
9405 + devfs_handle_t devfs;
9409 +#define DEFAULT_COW { \
9413 + .bitmap_offset = 0, \
9414 + .data_offset = 0, \
9417 +#define DEFAULT_UBD { \
9422 + .boot_openflags = OPEN_FLAGS, \
9423 + .openflags = OPEN_FLAGS, \
9425 + .cow = DEFAULT_COW, \
9428 +struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
9430 +static int ubd0_init(void)
9432 + struct ubd *dev = &ubd_dev[0];
9434 + if(dev->file == NULL)
9435 + dev->file = "root_fs";
9439 +__initcall(ubd0_init);
9441 +/* Only changed by fake_ide_setup which is a setup */
9442 +static int fake_ide = 0;
9443 +static struct proc_dir_entry *proc_ide_root = NULL;
9444 +static struct proc_dir_entry *proc_ide = NULL;
9446 +static void make_proc_ide(void)
9448 + proc_ide_root = proc_mkdir("ide", 0);
9449 + proc_ide = proc_mkdir("ide0", proc_ide_root);
9452 +static int proc_ide_read_media(char *page, char **start, off_t off, int count,
9453 + int *eof, void *data)
9457 + strcpy(page, "disk\n");
9458 + len = strlen("disk\n");
9462 + if (len <= 0) return 0;
9465 + *start = page + off;
9469 +static void make_ide_entries(char *dev_name)
9471 + struct proc_dir_entry *dir, *ent;
9474 + if(!fake_ide) return;
9476 + /* Without locking this could race if a UML was booted with no
9477 + * disks and then two mconsole requests which add disks came in
9478 + * at the same time.
9480 + spin_lock(&ubd_lock);
9481 + if(proc_ide_root == NULL) make_proc_ide();
9482 + spin_unlock(&ubd_lock);
9484 + dir = proc_mkdir(dev_name, proc_ide);
9487 + ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir);
9491 + ent->read_proc = proc_ide_read_media;
9492 + ent->write_proc = NULL;
9493 + sprintf(name,"ide0/%s", dev_name);
9494 + proc_symlink(dev_name, proc_ide_root, name);
9497 +static int fake_ide_setup(char *str)
9503 +__setup("fake_ide", fake_ide_setup);
9505 +__uml_help(fake_ide_setup,
9507 +" Create ide0 entries that map onto ubd devices.\n\n"
9510 +static int parse_unit(char **ptr)
9512 + char *str = *ptr, *end;
9515 + if(isdigit(*str)) {
9516 + n = simple_strtoul(str, &end, 0);
9521 + else if (('a' <= *str) && (*str <= 'h')) {
9529 +static int ubd_setup_common(char *str, int *index_out)
9531 + struct openflags flags = global_openflags;
9533 + char *backing_file;
9536 + if(index_out) *index_out = -1;
9543 + if(!strcmp(str, "sync")){
9544 + global_openflags.s = 1;
9547 + major = simple_strtoul(str, &end, 0);
9548 + if((*end != '\0') || (end == str)){
9550 + "ubd_setup : didn't parse major number\n");
9555 + spin_lock(&ubd_lock);
9556 + if(fake_major != MAJOR_NR){
9557 + printk(KERN_ERR "Can't assign a fake major twice\n");
9561 + fake_gendisk.major = major;
9562 + fake_major = major;
9564 + printk(KERN_INFO "Setting extra ubd major number to %d\n",
9568 + spin_unlock(&ubd_lock);
9572 + n = parse_unit(&str);
9574 + printk(KERN_ERR "ubd_setup : couldn't parse unit number "
9580 + printk(KERN_ERR "ubd_setup : index %d out of range "
9581 + "(%d devices)\n", n, MAX_DEV);
9586 + spin_lock(&ubd_lock);
9588 + dev = &ubd_dev[n];
9589 + if(dev->file != NULL){
9590 + printk(KERN_ERR "ubd_setup : device already configured\n");
9594 + if(index_out) *index_out = n;
9604 + if(*str++ != '='){
9605 + printk(KERN_ERR "ubd_setup : Expected '='\n");
9610 + backing_file = strchr(str, ',');
9612 + *backing_file = '\0';
9616 + dev->cow.file = backing_file;
9617 + dev->boot_openflags = flags;
9619 + spin_unlock(&ubd_lock);
9623 +static int ubd_setup(char *str)
9625 + ubd_setup_common(str, NULL);
9629 +__setup("ubd", ubd_setup);
9630 +__uml_help(ubd_setup,
9631 +"ubd<n>=<filename>\n"
9632 +" This is used to associate a device with a file in the underlying\n"
9633 +" filesystem. Usually, there is a filesystem in the file, but \n"
9634 +" that's not required. Swap devices containing swap files can be\n"
9635 +" specified like this. Also, a file which doesn't contain a\n"
9636 +" filesystem can have its contents read in the virtual \n"
9637 +" machine by running dd on the device. n must be in the range\n"
9638 +" 0 to 7. Appending an 'r' to the number will cause that device\n"
9639 +" to be mounted read-only. For example ubd1r=./ext_fs. Appending\n"
9640 +" an 's' (has to be _after_ 'r', if there is one) will cause data\n"
9641 +" to be written to disk on the host immediately.\n\n"
9644 +static int fakehd(char *str)
9647 + "fakehd : Changing ubd_gendisk.major_name to \"hd\".\n");
9648 + ubd_gendisk.major_name = "hd";
9652 +__setup("fakehd", fakehd);
9655 +" Change the ubd device name to \"hd\".\n\n"
9658 +static void do_ubd_request(request_queue_t * q);
9660 +/* Only changed by ubd_init, which is an initcall. */
9661 +int thread_fd = -1;
9663 +/* Changed by ubd_handler, which is serialized because interrupts only
9664 + * happen on CPU 0.
9666 +int intr_count = 0;
9668 +static void ubd_finish(int error)
9676 + nsect = CURRENT->current_nr_sectors;
9677 + CURRENT->sector += nsect;
9678 + CURRENT->buffer += nsect << 9;
9679 + CURRENT->errors = 0;
9680 + CURRENT->nr_sectors -= nsect;
9681 + CURRENT->current_nr_sectors = 0;
9685 +static void ubd_handler(void)
9687 + struct io_thread_req req;
9690 + DEVICE_INTR = NULL;
9692 + n = read_ubd_fs(thread_fd, &req, sizeof(req));
9693 + if(n != sizeof(req)){
9694 + printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
9695 + "errno = %d\n", os_getpid(), -n);
9696 + spin_lock(&io_request_lock);
9698 + spin_unlock(&io_request_lock);
9702 + if((req.offset != ((__u64) (CURRENT->sector)) << 9) ||
9703 + (req.length != (CURRENT->current_nr_sectors) << 9))
9704 + panic("I/O op mismatch");
9706 + spin_lock(&io_request_lock);
9707 + ubd_finish(req.error);
9708 + reactivate_fd(thread_fd, UBD_IRQ);
9709 + do_ubd_request(ubd_queue);
9710 + spin_unlock(&io_request_lock);
9713 +static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
9718 +/* Only changed by ubd_init, which is an initcall. */
9719 +static int io_pid = -1;
9721 +void kill_io_thread(void)
9724 + os_kill_process(io_pid, 1);
9727 +__uml_exitcall(kill_io_thread);
9729 +/* Initialized in an initcall, and unchanged thereafter */
9730 +devfs_handle_t ubd_dir_handle;
9732 +static int ubd_add(int n)
9734 + struct ubd *dev = &ubd_dev[n];
9735 + char name[sizeof("nnnnnn\0")], dev_name[sizeof("ubd0x")];
9736 + int err = -EISDIR;
9738 + if(dev->file == NULL)
9741 + err = ubd_revalidate1(MKDEV(MAJOR_NR, n << UBD_SHIFT));
9745 + sprintf(name, "%d", n);
9746 + dev->devfs = devfs_register(ubd_dir_handle, name, DEVFS_FL_REMOVABLE,
9747 + MAJOR_NR, n << UBD_SHIFT, S_IFBLK |
9748 + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
9749 + &ubd_blops, NULL);
9751 + if(!strcmp(ubd_gendisk.major_name, "ubd"))
9752 + sprintf(dev_name, "%s%d", ubd_gendisk.major_name, n);
9753 + else sprintf(dev_name, "%s%c", ubd_gendisk.major_name,
9756 + make_ide_entries(dev_name);
9763 +static int ubd_config(char *str)
9767 + str = uml_strdup(str);
9769 + printk(KERN_ERR "ubd_config failed to strdup string\n");
9772 + err = ubd_setup_common(str, &n);
9777 + if(n == -1) return(0);
9779 + spin_lock(&ubd_lock);
9782 + ubd_dev[n].file = NULL;
9783 + spin_unlock(&ubd_lock);
9788 +static int ubd_get_config(char *name, char *str, int size, char **error_out)
9794 + n = simple_strtoul(name, &end, 0);
9795 + if((*end != '\0') || (end == name)){
9796 + *error_out = "ubd_get_config : didn't parse device number";
9800 + if((n >= MAX_DEV) || (n < 0)){
9801 + *error_out = "ubd_get_config : device number out of range";
9805 + dev = &ubd_dev[n];
9806 + spin_lock(&ubd_lock);
9808 + if(dev->file == NULL){
9809 + CONFIG_CHUNK(str, size, len, "", 1);
9813 + CONFIG_CHUNK(str, size, len, dev->file, 0);
9815 + if(dev->cow.file != NULL){
9816 + CONFIG_CHUNK(str, size, len, ",", 0);
9817 + CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
9819 + else CONFIG_CHUNK(str, size, len, "", 1);
9822 + spin_unlock(&ubd_lock);
9826 +static int ubd_remove(char *str)
9829 + int n, err = -ENODEV;
9831 + if(isdigit(*str)){
9833 + n = simple_strtoul(str, &end, 0);
9834 + if ((*end != '\0') || (end == str))
9837 + else if (('a' <= *str) && (*str <= 'h'))
9840 + return(err); /* it should be a number 0-7/a-h */
9842 + if((n < 0) || (n >= MAX_DEV))
9845 + dev = &ubd_dev[n];
9847 + spin_lock(&ubd_lock);
9849 + if(dev->file == NULL)
9852 + if(dev->count > 0)
9854 + if(dev->devfs != NULL)
9855 + devfs_unregister(dev->devfs);
9857 + *dev = ((struct ubd) DEFAULT_UBD);
9860 + spin_unlock(&ubd_lock);
9864 +static struct mc_device ubd_mc = {
9866 + .config = ubd_config,
9867 + .get_config = ubd_get_config,
9868 + .remove = ubd_remove,
9871 +static int ubd_mc_init(void)
9873 + mconsole_register_dev(&ubd_mc);
9877 +__initcall(ubd_mc_init);
9879 +static request_queue_t *ubd_get_queue(kdev_t device)
9881 + return(ubd_queue);
9886 + unsigned long stack;
9889 + ubd_dir_handle = devfs_mk_dir (NULL, "ubd", NULL);
9890 + if (devfs_register_blkdev(MAJOR_NR, "ubd", &ubd_blops)) {
9891 + printk(KERN_ERR "ubd: unable to get major %d\n", MAJOR_NR);
9894 + read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */
9895 + blksize_size[MAJOR_NR] = blk_sizes;
9896 + blk_size[MAJOR_NR] = sizes;
9897 + INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
9899 + ubd_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
9900 + blk_init_queue(ubd_queue, DEVICE_REQUEST);
9901 + INIT_ELV(ubd_queue, &ubd_queue->elevator);
9903 + add_gendisk(&ubd_gendisk);
9904 + if (fake_major != MAJOR_NR){
9905 + /* major number 0 is used to auto select */
9906 + err = devfs_register_blkdev(fake_major, "fake", &ubd_blops);
9907 + if(fake_major == 0){
9908 + /* auto device number case */
9914 + /* not auto so normal error */
9915 + printk(KERN_ERR "ubd: error %d getting major %d\n",
9920 + blk_dev[fake_major].queue = ubd_get_queue;
9921 + read_ahead[fake_major] = 8; /* 8 sector (4kB) read-ahead */
9922 + blksize_size[fake_major] = blk_sizes;
9923 + blk_size[fake_major] = sizes;
9924 + INIT_HARDSECT(hardsect_size, fake_major, hardsect_sizes);
9925 + add_gendisk(&fake_gendisk);
9928 + for(i=0;i<MAX_DEV;i++)
9931 + if(global_openflags.s){
9932 + printk(KERN_INFO "ubd : Synchronous mode\n");
9935 + stack = alloc_stack(0, 0);
9936 + io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
9940 + "ubd : Failed to start I/O thread (errno = %d) - "
9941 + "falling back to synchronous I/O\n", -io_pid);
9944 + err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
9945 + SA_INTERRUPT, "ubd", ubd_dev);
9946 + if(err != 0) printk(KERN_ERR
9947 + "um_request_irq failed - errno = %d\n", -err);
9951 +__initcall(ubd_init);
9953 +static void ubd_close(struct ubd *dev)
9955 + os_close_file(dev->fd);
9956 + if(dev->cow.file != NULL) {
9957 + os_close_file(dev->cow.fd);
9958 + vfree(dev->cow.bitmap);
9959 + dev->cow.bitmap = NULL;
9963 +static int ubd_open_dev(struct ubd *dev)
9965 + struct openflags flags;
9966 + int err, create_cow, *create_ptr;
9968 + dev->openflags = dev->boot_openflags;
9970 + create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
9971 + dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
9972 + &dev->cow.bitmap_offset, &dev->cow.bitmap_len,
9973 + &dev->cow.data_offset, create_ptr);
9975 + if((dev->fd == -ENOENT) && create_cow){
9976 + dev->fd = create_cow_file(dev->file, dev->cow.file,
9977 + dev->openflags, 1 << 9,
9978 + &dev->cow.bitmap_offset,
9979 + &dev->cow.bitmap_len,
9980 + &dev->cow.data_offset);
9982 + printk(KERN_INFO "Creating \"%s\" as COW file for "
9983 + "\"%s\"\n", dev->file, dev->cow.file);
9987 + if(dev->fd < 0) return(dev->fd);
9989 + if(dev->cow.file != NULL){
9991 + dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
9992 + if(dev->cow.bitmap == NULL) goto error;
9993 + flush_tlb_kernel_vm();
9995 + err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
9996 + dev->cow.bitmap_offset,
9997 + dev->cow.bitmap_len);
9998 + if(err) goto error;
10000 + flags = dev->openflags;
10002 + err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL,
10004 + if(err < 0) goto error;
10005 + dev->cow.fd = err;
10009 + os_close_file(dev->fd);
10013 +static int ubd_file_size(struct ubd *dev, __u64 *size_out)
10017 + file = dev->cow.file ? dev->cow.file : dev->file;
10018 + return(os_file_size(file, size_out));
10021 +static int ubd_open(struct inode *inode, struct file *filp)
10024 + int n, offset, err = 0;
10026 + n = DEVICE_NR(inode->i_rdev);
10027 + dev = &ubd_dev[n];
10031 + spin_lock(&ubd_lock);
10032 + offset = n << UBD_SHIFT;
10034 + if(dev->count == 0){
10035 + err = ubd_open_dev(dev);
10037 + printk(KERN_ERR "ubd%d: Can't open \"%s\": "
10038 + "errno = %d\n", n, dev->file, -err);
10041 + err = ubd_file_size(dev, &dev->size);
10044 + sizes[offset] = dev->size / BLOCK_SIZE;
10045 + ubd_part[offset].nr_sects = dev->size / hardsect_sizes[offset];
10048 + if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
10049 + if(--dev->count == 0) ubd_close(dev);
10053 + spin_unlock(&ubd_lock);
10057 +static int ubd_release(struct inode * inode, struct file * file)
10061 + n = DEVICE_NR(inode->i_rdev);
10062 + offset = n << UBD_SHIFT;
10066 + spin_lock(&ubd_lock);
10067 + if(--ubd_dev[n].count == 0)
10068 + ubd_close(&ubd_dev[n]);
10069 + spin_unlock(&ubd_lock);
10074 +void cowify_req(struct io_thread_req *req, struct ubd *dev)
10076 + int i, update_bitmap, sector = req->offset >> 9;
10078 + if(req->length > (sizeof(req->sector_mask) * 8) << 9)
10079 + panic("Operation too long");
10080 + if(req->op == UBD_READ) {
10081 + for(i = 0; i < req->length >> 9; i++){
10082 + if(ubd_test_bit(sector + i, (unsigned char *)
10083 + dev->cow.bitmap)){
10084 + ubd_set_bit(i, (unsigned char *)
10085 + &req->sector_mask);
10090 + update_bitmap = 0;
10091 + for(i = 0; i < req->length >> 9; i++){
10092 + ubd_set_bit(i, (unsigned char *)
10093 + &req->sector_mask);
10094 + if(!ubd_test_bit(sector + i, (unsigned char *)
10095 + dev->cow.bitmap))
10096 + update_bitmap = 1;
10097 + ubd_set_bit(sector + i, (unsigned char *)
10098 + dev->cow.bitmap);
10100 + if(update_bitmap){
10101 + req->cow_offset = sector / (sizeof(unsigned long) * 8);
10102 + req->bitmap_words[0] =
10103 + dev->cow.bitmap[req->cow_offset];
10104 + req->bitmap_words[1] =
10105 + dev->cow.bitmap[req->cow_offset + 1];
10106 + req->cow_offset *= sizeof(unsigned long);
10107 + req->cow_offset += dev->cow.bitmap_offset;
10112 +static int prepare_request(struct request *req, struct io_thread_req *io_req)
10116 + int nsect, minor, n;
10118 + if(req->rq_status == RQ_INACTIVE) return(1);
10120 + minor = MINOR(req->rq_dev);
10121 + n = minor >> UBD_SHIFT;
10122 + dev = &ubd_dev[n];
10123 + if(IS_WRITE(req) && !dev->openflags.w){
10124 + printk("Write attempted on readonly ubd device %d\n", n);
10129 + req->sector += ubd_part[minor].start_sect;
10130 + block = req->sector;
10131 + nsect = req->current_nr_sectors;
10133 + io_req->op = (req->cmd == READ) ? UBD_READ : UBD_WRITE;
10134 + io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
10135 + io_req->fds[1] = dev->fd;
10136 + io_req->offsets[0] = 0;
10137 + io_req->offsets[1] = dev->cow.data_offset;
10138 + io_req->offset = ((__u64) block) << 9;
10139 + io_req->length = nsect << 9;
10140 + io_req->buffer = req->buffer;
10141 + io_req->sectorsize = 1 << 9;
10142 + io_req->sector_mask = 0;
10143 + io_req->cow_offset = -1;
10144 + io_req->error = 0;
10146 + if(dev->cow.file != NULL) cowify_req(io_req, dev);
10150 +static void do_ubd_request(request_queue_t *q)
10152 + struct io_thread_req io_req;
10153 + struct request *req;
10156 + if(thread_fd == -1){
10157 + while(!list_empty(&q->queue_head)){
10158 + req = blkdev_entry_next_request(&q->queue_head);
10159 + err = prepare_request(req, &io_req);
10162 + ubd_finish(io_req.error);
10167 + if(DEVICE_INTR || list_empty(&q->queue_head)) return;
10168 + req = blkdev_entry_next_request(&q->queue_head);
10169 + err = prepare_request(req, &io_req);
10171 + SET_INTR(ubd_handler);
10172 + n = write_ubd_fs(thread_fd, (char *) &io_req,
10174 + if(n != sizeof(io_req))
10175 + printk("write to io thread failed, "
10176 + "errno = %d\n", -n);
10181 +static int ubd_ioctl(struct inode * inode, struct file * file,
10182 + unsigned int cmd, unsigned long arg)
10184 + struct hd_geometry *loc = (struct hd_geometry *) arg;
10186 + int n, minor, err;
10187 + struct hd_driveid ubd_id = {
10193 + if(!inode) return(-EINVAL);
10194 + minor = MINOR(inode->i_rdev);
10195 + n = minor >> UBD_SHIFT;
10198 + dev = &ubd_dev[n];
10200 + struct hd_geometry g;
10201 + struct cdrom_volctrl volume;
10202 + case HDIO_GETGEO:
10203 + if(!loc) return(-EINVAL);
10206 + g.cylinders = dev->size / (128 * 32 * hardsect_sizes[minor]);
10208 + return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
10209 + case BLKGETSIZE: /* Return device size */
10210 + if(!arg) return(-EINVAL);
10211 + err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
10214 + put_user(ubd_part[minor].nr_sects, (long *) arg);
10216 + case BLKRRPART: /* Re-read partition tables */
10217 + return(ubd_revalidate(inode->i_rdev));
10219 + case HDIO_SET_UNMASKINTR:
10220 + if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
10221 + if((arg > 1) || (minor & 0x3F)) return(-EINVAL);
10224 + case HDIO_GET_UNMASKINTR:
10225 + if(!arg) return(-EINVAL);
10226 + err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
10231 + case HDIO_GET_MULTCOUNT:
10232 + if(!arg) return(-EINVAL);
10233 + err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
10238 + case HDIO_SET_MULTCOUNT:
10239 + if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
10240 + if(MINOR(inode->i_rdev) & 0x3F) return(-EINVAL);
10243 + case HDIO_GET_IDENTITY:
10244 + ubd_id.cyls = dev->size / (128 * 32 * hardsect_sizes[minor]);
10245 + if(copy_to_user((char *) arg, (char *) &ubd_id,
10250 + case CDROMVOLREAD:
10251 + if(copy_from_user(&volume, (char *) arg, sizeof(volume)))
10253 + volume.channel0 = 255;
10254 + volume.channel1 = 255;
10255 + volume.channel2 = 255;
10256 + volume.channel3 = 255;
10257 + if(copy_to_user((char *) arg, &volume, sizeof(volume)))
10262 + return blk_ioctl(inode->i_rdev, cmd, arg);
10266 +static int ubd_revalidate1(kdev_t rdev)
10268 + int i, n, offset, err = 0, pcount = 1 << UBD_SHIFT;
10270 + struct hd_struct *part;
10272 + n = DEVICE_NR(rdev);
10273 + offset = n << UBD_SHIFT;
10274 + dev = &ubd_dev[n];
10276 + part = &ubd_part[offset];
10278 + /* clear all old partition counts */
10279 + for(i = 1; i < pcount; i++) {
10280 + part[i].start_sect = 0;
10281 + part[i].nr_sects = 0;
10284 + /* If it already has been opened we can check the partitions
10288 + part->start_sect = 0;
10289 + register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount,
10290 + &ubd_blops, part->nr_sects);
10292 + else if(dev->file){
10293 + err = ubd_open_dev(dev);
10295 + printk(KERN_ERR "unable to open %s for validation\n",
10300 + /* have to recompute sizes since we opened it */
10301 + err = ubd_file_size(dev, &dev->size);
10306 + part->start_sect = 0;
10307 + part->nr_sects = dev->size / hardsect_sizes[offset];
10308 + register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount,
10309 + &ubd_blops, part->nr_sects);
10311 + /* we are done so close it */
10314 + else err = -ENODEV;
10319 +static int ubd_revalidate(kdev_t rdev)
10323 + spin_lock(&ubd_lock);
10324 + err = ubd_revalidate1(rdev);
10325 + spin_unlock(&ubd_lock);
10330 + * Overrides for Emacs so that we follow Linus's tabbing style.
10331 + * Emacs will notice this stuff at the end of the file and automatically
10332 + * adjust the settings for this buffer only. This must remain at the end
10334 + * ---------------------------------------------------------------------------
10335 + * Local variables:
10336 + * c-file-style: "linux"
10339 diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_user.c um/arch/um/drivers/ubd_user.c
10340 --- orig/arch/um/drivers/ubd_user.c Wed Dec 31 19:00:00 1969
10341 +++ um/arch/um/drivers/ubd_user.c Thu Mar 6 18:08:55 2003
10344 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
10345 + * Copyright (C) 2001 Ridgerun,Inc (glonnon@ridgerun.com)
10346 + * Licensed under the GPL
10349 +#include <stddef.h>
10350 +#include <unistd.h>
10351 +#include <errno.h>
10352 +#include <sched.h>
10353 +#include <signal.h>
10354 +#include <string.h>
10355 +#include <netinet/in.h>
10356 +#include <sys/stat.h>
10357 +#include <sys/time.h>
10358 +#include <sys/fcntl.h>
10359 +#include <sys/socket.h>
10360 +#include <string.h>
10361 +#include <sys/mman.h>
10362 +#include <sys/param.h>
10363 +#include "asm/types.h"
10364 +#include "user_util.h"
10365 +#include "kern_util.h"
10367 +#include "ubd_user.h"
10370 +#include <endian.h>
10371 +#include <byteswap.h>
10372 +#if __BYTE_ORDER == __BIG_ENDIAN
10373 +# define ntohll(x) (x)
10374 +# define htonll(x) (x)
10375 +#elif __BYTE_ORDER == __LITTLE_ENDIAN
10376 +# define ntohll(x) bswap_64(x)
10377 +# define htonll(x) bswap_64(x)
10379 +#error "__BYTE_ORDER not defined"
10382 +#define PATH_LEN_V1 256
10384 +struct cow_header_v1 {
10387 + char backing_file[PATH_LEN_V1];
10393 +#define PATH_LEN_V2 MAXPATHLEN
10395 +struct cow_header_v2 {
10396 + unsigned long magic;
10397 + unsigned long version;
10398 + char backing_file[PATH_LEN_V2];
10404 +union cow_header {
10405 + struct cow_header_v1 v1;
10406 + struct cow_header_v2 v2;
10409 +#define COW_MAGIC 0x4f4f4f4d /* MOOO */
10410 +#define COW_VERSION 2
10412 +static void sizes(__u64 size, int sectorsize, int bitmap_offset,
10413 + unsigned long *bitmap_len_out, int *data_offset_out)
10415 + *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
10417 + *data_offset_out = bitmap_offset + *bitmap_len_out;
10418 + *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
10419 + *data_offset_out *= sectorsize;
10422 +static int read_cow_header(int fd, int *magic_out, char **backing_file_out,
10423 + time_t *mtime_out, __u64 *size_out,
10424 + int *sectorsize_out, int *bitmap_offset_out)
10426 + union cow_header *header;
10429 + unsigned long version, magic;
10431 + header = um_kmalloc(sizeof(*header));
10432 + if(header == NULL){
10433 + printk("read_cow_header - Failed to allocate header\n");
10437 + n = read(fd, header, sizeof(*header));
10438 + if(n < offsetof(typeof(header->v1), backing_file)){
10439 + printk("read_cow_header - short header\n");
10443 + magic = header->v1.magic;
10444 + if(magic == COW_MAGIC) {
10445 + version = header->v1.version;
10447 + else if(magic == ntohl(COW_MAGIC)){
10448 + version = ntohl(header->v1.version);
10452 + *magic_out = COW_MAGIC;
10454 + if(version == 1){
10455 + if(n < sizeof(header->v1)){
10456 + printk("read_cow_header - failed to read V1 header\n");
10459 + *mtime_out = header->v1.mtime;
10460 + *size_out = header->v1.size;
10461 + *sectorsize_out = header->v1.sectorsize;
10462 + *bitmap_offset_out = sizeof(header->v1);
10463 + file = header->v1.backing_file;
10465 + else if(version == 2){
10466 + if(n < sizeof(header->v2)){
10467 + printk("read_cow_header - failed to read V2 header\n");
10470 + *mtime_out = ntohl(header->v2.mtime);
10471 + *size_out = ntohll(header->v2.size);
10472 + *sectorsize_out = ntohl(header->v2.sectorsize);
10473 + *bitmap_offset_out = sizeof(header->v2);
10474 + file = header->v2.backing_file;
10477 + printk("read_cow_header - invalid COW version\n");
10481 + *backing_file_out = uml_strdup(file);
10482 + if(*backing_file_out == NULL){
10483 + printk("read_cow_header - failed to allocate backing file\n");
10492 +static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
10494 + struct stat64 buf1, buf2;
10496 + if(from_cmdline == NULL) return(1);
10497 + if(!strcmp(from_cmdline, from_cow)) return(1);
10499 + if(stat64(from_cmdline, &buf1) < 0){
10500 + printk("Couldn't stat '%s', errno = %d\n", from_cmdline,
10504 + if(stat64(from_cow, &buf2) < 0){
10505 + printk("Couldn't stat '%s', errno = %d\n", from_cow, errno);
10508 + if((buf1.st_dev == buf2.st_dev) && (buf1.st_ino == buf2.st_ino))
10511 + printk("Backing file mismatch - \"%s\" requested,\n"
10512 + "\"%s\" specified in COW header of \"%s\"\n",
10513 + from_cmdline, from_cow, cow);
10517 +static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
10519 + struct stat64 buf;
10520 + long long actual;
10523 + if(stat64(file, &buf) < 0){
10524 + printk("Failed to stat backing file \"%s\", errno = %d\n",
10529 + err = os_file_size(file, &actual);
10531 + printk("Failed to get size of backing file \"%s\", "
10532 + "errno = %d\n", file, -err);
10536 + if(actual != size){
10537 + printk("Size mismatch (%ld vs %ld) of COW header vs backing "
10538 + "file\n", size, actual);
10541 + if(buf.st_mtime != mtime){
10542 + printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
10543 + "file\n", mtime, buf.st_mtime);
10549 +int read_cow_bitmap(int fd, void *buf, int offset, int len)
10553 + err = os_seek_file(fd, offset);
10554 + if(err != 0) return(-errno);
10555 + err = read(fd, buf, len);
10556 + if(err < 0) return(-errno);
10560 +static int absolutize(char *to, int size, char *from)
10562 + char save_cwd[256], *slash;
10565 + if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
10566 + printk("absolutize : unable to get cwd - errno = %d\n", errno);
10569 + slash = strrchr(from, '/');
10570 + if(slash != NULL){
10574 + printk("absolutize : Can't cd to '%s' - errno = %d\n",
10579 + if(getcwd(to, size) == NULL){
10580 + printk("absolutize : unable to get cwd of '%s' - "
10581 + "errno = %d\n", from, errno);
10584 + remaining = size - strlen(to);
10585 + if(strlen(slash) + 1 > remaining){
10586 + printk("absolutize : unable to fit '%s' into %d "
10587 + "chars\n", from, size);
10590 + strcat(to, slash);
10593 + if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
10594 + printk("absolutize : unable to fit '%s' into %d "
10595 + "chars\n", from, size);
10598 + strcpy(to, save_cwd);
10600 + strcat(to, from);
10606 +static int write_cow_header(char *cow_file, int fd, char *backing_file,
10607 + int sectorsize, long long *size)
10609 + struct cow_header_v2 *header;
10610 + struct stat64 buf;
10613 + err = os_seek_file(fd, 0);
10615 + printk("write_cow_header - lseek failed, errno = %d\n", errno);
10620 + header = um_kmalloc(sizeof(*header));
10621 + if(header == NULL){
10622 + printk("Failed to allocate COW V2 header\n");
10625 + header->magic = htonl(COW_MAGIC);
10626 + header->version = htonl(COW_VERSION);
10629 + if(strlen(backing_file) > sizeof(header->backing_file) - 1){
10630 + printk("Backing file name \"%s\" is too long - names are "
10631 + "limited to %d characters\n", backing_file,
10632 + sizeof(header->backing_file) - 1);
10636 + if(absolutize(header->backing_file, sizeof(header->backing_file),
10640 + err = stat64(header->backing_file, &buf);
10642 + printk("Stat of backing file '%s' failed, errno = %d\n",
10643 + header->backing_file, errno);
10648 + err = os_file_size(header->backing_file, size);
10650 + printk("Couldn't get size of backing file '%s', errno = %d\n",
10651 + header->backing_file, -*size);
10655 + header->mtime = htonl(buf.st_mtime);
10656 + header->size = htonll(*size);
10657 + header->sectorsize = htonl(sectorsize);
10659 + err = write(fd, header, sizeof(*header));
10660 + if(err != sizeof(*header)){
10661 + printk("Write of header to new COW file '%s' failed, "
10662 + "errno = %d\n", cow_file, errno);
10672 +int open_ubd_file(char *file, struct openflags *openflags,
10673 + char **backing_file_out, int *bitmap_offset_out,
10674 + unsigned long *bitmap_len_out, int *data_offset_out,
10675 + int *create_cow_out)
10679 + char *backing_file;
10680 + int fd, err, sectorsize, magic, same, mode = 0644;
10682 + if((fd = os_open_file(file, *openflags, mode)) < 0){
10683 + if((fd == -ENOENT) && (create_cow_out != NULL))
10684 + *create_cow_out = 1;
10685 + if(!openflags->w ||
10686 + ((errno != EROFS) && (errno != EACCES))) return(-errno);
10687 + openflags->w = 0;
10688 + if((fd = os_open_file(file, *openflags, mode)) < 0)
10692 + err = os_lock_file(fd, openflags->w);
10694 + printk("Failed to lock '%s', errno = %d\n", file, -err);
10698 + if(backing_file_out == NULL) return(fd);
10700 + err = read_cow_header(fd, &magic, &backing_file, &mtime, &size,
10701 + §orsize, bitmap_offset_out);
10702 + if(err && (*backing_file_out != NULL)){
10703 + printk("Failed to read COW header from COW file \"%s\", "
10704 + "errno = %d\n", file, err);
10707 + if(err) return(fd);
10709 + if(backing_file_out == NULL) return(fd);
10711 + same = same_backing_files(*backing_file_out, backing_file, file);
10713 + if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
10714 + printk("Switching backing file to '%s'\n", *backing_file_out);
10715 + err = write_cow_header(file, fd, *backing_file_out,
10716 + sectorsize, &size);
10718 + printk("Switch failed, errno = %d\n", err);
10723 + *backing_file_out = backing_file;
10724 + err = backing_file_mismatch(*backing_file_out, size, mtime);
10725 + if(err) goto error;
10728 + sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out,
10729 + data_offset_out);
10733 + os_close_file(fd);
10737 +int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
10738 + int sectorsize, int *bitmap_offset_out,
10739 + unsigned long *bitmap_len_out, int *data_offset_out)
10747 + fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
10750 + printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
10755 + err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
10756 + if(err) goto out_close;
10758 + sizes(size, sectorsize, sizeof(struct cow_header_v2),
10759 + bitmap_len_out, data_offset_out);
10760 + *bitmap_offset_out = sizeof(struct cow_header_v2);
10762 + offset = *data_offset_out + size - sizeof(zero);
10763 + err = os_seek_file(fd, offset);
10765 + printk("cow bitmap lseek failed : errno = %d\n", errno);
10769 + /* does not really matter how much we write it is just to set EOF
10770 + * this also sets the entire COW bitmap
10771 + * to zero without having to allocate it
10773 + err = os_write_file(fd, &zero, sizeof(zero));
10774 + if(err != sizeof(zero)){
10775 + printk("Write of bitmap to new COW file '%s' failed, "
10776 + "errno = %d\n", cow_file, errno);
10788 +int read_ubd_fs(int fd, void *buffer, int len)
10792 + n = read(fd, buffer, len);
10793 + if(n < 0) return(-errno);
10797 +int write_ubd_fs(int fd, char *buffer, int len)
10801 + n = write(fd, buffer, len);
10802 + if(n < 0) return(-errno);
10806 +void do_io(struct io_thread_req *req)
10809 + unsigned long len;
10810 + int n, nsectors, start, end, bit;
10813 + nsectors = req->length / req->sectorsize;
10816 + bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
10818 + while((end < nsectors) &&
10819 + (ubd_test_bit(end, (unsigned char *)
10820 + &req->sector_mask) == bit))
10823 + if(end != nsectors)
10824 + printk("end != nsectors\n");
10825 + off = req->offset + req->offsets[bit] +
10826 + start * req->sectorsize;
10827 + len = (end - start) * req->sectorsize;
10828 + buf = &req->buffer[start * req->sectorsize];
10830 + if(os_seek_file(req->fds[bit], off) != 0){
10831 + printk("do_io - lseek failed : errno = %d\n", errno);
10835 + if(req->op == UBD_READ){
10840 + n = read(req->fds[bit], buf, len);
10842 + printk("do_io - read returned %d : "
10843 + "errno = %d fd = %d\n", n,
10844 + errno, req->fds[bit]);
10848 + } while((n < len) && (n != 0));
10849 + if (n < len) memset(&buf[n], 0, len - n);
10852 + n = write(req->fds[bit], buf, len);
10854 + printk("do_io - write returned %d : "
10855 + "errno = %d fd = %d\n", n,
10856 + errno, req->fds[bit]);
10863 + } while(start < nsectors);
10865 + if(req->cow_offset != -1){
10866 + if(os_seek_file(req->fds[1], req->cow_offset) != 0){
10867 + printk("do_io - bitmap lseek failed : errno = %d\n",
10872 + n = write(req->fds[1], &req->bitmap_words,
10873 + sizeof(req->bitmap_words));
10874 + if(n != sizeof(req->bitmap_words)){
10875 + printk("do_io - bitmap update returned %d : "
10876 + "errno = %d fd = %d\n", n, errno, req->fds[1]);
10885 +/* Changed in start_io_thread, which is serialized by being called only
10886 + * from ubd_init, which is an initcall.
10888 +int kernel_fd = -1;
10890 +/* Only changed by the io thread */
10893 +int io_thread(void *arg)
10895 + struct io_thread_req req;
10898 + signal(SIGWINCH, SIG_IGN);
10900 + n = read(kernel_fd, &req, sizeof(req));
10901 + if(n < 0) printk("io_thread - read returned %d, errno = %d\n",
10903 + else if(n < sizeof(req)){
10904 + printk("io_thread - short read : length = %d\n", n);
10909 + n = write(kernel_fd, &req, sizeof(req));
10910 + if(n != sizeof(req))
10911 + printk("io_thread - write failed, errno = %d\n",
10916 +int start_io_thread(unsigned long sp, int *fd_out)
10918 + int pid, fds[2], err;
10920 + err = os_pipe(fds, 1, 1);
10922 + printk("start_io_thread - os_pipe failed, errno = %d\n", -err);
10925 + kernel_fd = fds[0];
10926 + *fd_out = fds[1];
10928 + pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
10931 + printk("start_io_thread - clone failed : errno = %d\n", errno);
10938 +int start_io_thread(unsigned long sp, int *fd_out)
10942 + if((kernel_fd = get_pty()) < 0) return(-1);
10943 + raw(kernel_fd, 0);
10944 + if((*fd_out = open(ptsname(kernel_fd), O_RDWR)) < 0){
10945 + printk("Couldn't open tty for IO\n");
10949 + pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
10952 + printk("start_io_thread - clone failed : errno = %d\n", errno);
10960 + * Overrides for Emacs so that we follow Linus's tabbing style.
10961 + * Emacs will notice this stuff at the end of the file and automatically
10962 + * adjust the settings for this buffer only. This must remain at the end
10964 + * ---------------------------------------------------------------------------
10965 + * Local variables:
10966 + * c-file-style: "linux"
10969 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.c um/arch/um/drivers/xterm.c
10970 --- orig/arch/um/drivers/xterm.c Wed Dec 31 19:00:00 1969
10971 +++ um/arch/um/drivers/xterm.c Mon Dec 30 20:49:22 2002
10974 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
10975 + * Licensed under the GPL
10978 +#include <stdio.h>
10979 +#include <stdlib.h>
10980 +#include <unistd.h>
10981 +#include <string.h>
10982 +#include <errno.h>
10983 +#include <fcntl.h>
10984 +#include <termios.h>
10985 +#include <signal.h>
10986 +#include <sched.h>
10987 +#include <sys/socket.h>
10988 +#include "kern_util.h"
10989 +#include "chan_user.h"
10990 +#include "helper.h"
10991 +#include "user_util.h"
10994 +#include "xterm.h"
10996 +struct xterm_chan {
11002 + struct termios tt;
11003 + unsigned long stack;
11007 +void *xterm_init(char *str, int device, struct chan_opts *opts)
11009 + struct xterm_chan *data;
11011 + if((data = malloc(sizeof(*data))) == NULL) return(NULL);
11012 + *data = ((struct xterm_chan) { .pid = -1,
11013 + .helper_pid = -1,
11014 + .device = device,
11015 + .title = opts->xterm_title,
11016 + .raw = opts->raw,
11017 + .stack = opts->tramp_stack,
11018 + .direct_rcv = !opts->in_kernel } );
11022 +/* Only changed by xterm_setup, which is a setup */
11023 +static char *terminal_emulator = "xterm";
11024 +static char *title_switch = "-T";
11025 +static char *exec_switch = "-e";
11027 +static int __init xterm_setup(char *line, int *add)
11030 + terminal_emulator = line;
11032 + line = strchr(line, ',');
11033 + if(line == NULL) return(0);
11035 + if(*line) title_switch = line;
11037 + line = strchr(line, ',');
11038 + if(line == NULL) return(0);
11040 + if(*line) exec_switch = line;
11045 +__uml_setup("xterm=", xterm_setup,
11046 +"xterm=<terminal emulator>,<title switch>,<exec switch>\n"
11047 +" Specifies an alternate terminal emulator to use for the debugger,\n"
11048 +" consoles, and serial lines when they are attached to the xterm channel.\n"
11049 +" The values are the terminal emulator binary, the switch it uses to set\n"
11050 +" its title, and the switch it uses to execute a subprocess,\n"
11051 +" respectively. The title switch must have the form '<switch> title',\n"
11052 +" not '<switch>=title'. Similarly, the exec switch must have the form\n"
11053 +" '<switch> command arg1 arg2 ...'.\n"
11054 +" The default values are 'xterm=xterm,-T,-e'. Values for gnome-terminal\n"
11055 +" are 'xterm=gnome-terminal,-t,-x'.\n\n"
11058 +int xterm_open(int input, int output, int primary, void *d, char **dev_out)
11060 + struct xterm_chan *data = d;
11061 + unsigned long stack;
11062 + int pid, fd, new, err;
11063 + char title[256], file[] = "/tmp/xterm-pipeXXXXXX";
11064 + char *argv[] = { terminal_emulator, title_switch, title, exec_switch,
11065 + "/usr/lib/uml/port-helper", "-uml-socket",
11068 + if(access(argv[4], X_OK))
11069 + argv[4] = "port-helper";
11071 + fd = mkstemp(file);
11073 + printk("xterm_open : mkstemp failed, errno = %d\n", errno);
11077 + if(unlink(file)){
11078 + printk("xterm_open : unlink failed, errno = %d\n", errno);
11083 + fd = create_unix_socket(file, sizeof(file));
11085 + printk("xterm_open : create_unix_socket failed, errno = %d\n",
11090 + sprintf(title, data->title, data->device);
11091 + stack = data->stack;
11092 + pid = run_helper(NULL, NULL, argv, &stack);
11094 + printk("xterm_open : run_helper failed, errno = %d\n", -pid);
11098 + if(data->stack == 0) free_stack(stack, 0);
11100 + if(data->direct_rcv)
11101 + new = os_rcv_fd(fd, &data->helper_pid);
11103 + if((err = os_set_fd_block(fd, 0)) != 0){
11104 + printk("xterm_open : failed to set descriptor "
11105 + "non-blocking, errno = %d\n", err);
11108 + new = xterm_fd(fd, &data->helper_pid);
11111 + printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new);
11115 + tcgetattr(new, &data->tt);
11116 + if(data->raw) raw(new, 0);
11125 +void xterm_close(int fd, void *d)
11127 + struct xterm_chan *data = d;
11129 + if(data->pid != -1)
11130 + os_kill_process(data->pid, 1);
11132 + if(data->helper_pid != -1)
11133 + os_kill_process(data->helper_pid, 0);
11134 + data->helper_pid = -1;
11138 +void xterm_free(void *d)
11143 +int xterm_console_write(int fd, const char *buf, int n, void *d)
11145 + struct xterm_chan *data = d;
11147 + return(generic_console_write(fd, buf, n, &data->tt));
11150 +struct chan_ops xterm_ops = {
11152 + .init = xterm_init,
11153 + .open = xterm_open,
11154 + .close = xterm_close,
11155 + .read = generic_read,
11156 + .write = generic_write,
11157 + .console_write = xterm_console_write,
11158 + .window_size = generic_window_size,
11159 + .free = xterm_free,
11164 + * Overrides for Emacs so that we follow Linus's tabbing style.
11165 + * Emacs will notice this stuff at the end of the file and automatically
11166 + * adjust the settings for this buffer only. This must remain at the end
11168 + * ---------------------------------------------------------------------------
11169 + * Local variables:
11170 + * c-file-style: "linux"
11173 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.h um/arch/um/drivers/xterm.h
11174 --- orig/arch/um/drivers/xterm.h Wed Dec 31 19:00:00 1969
11175 +++ um/arch/um/drivers/xterm.h Wed Oct 23 21:08:04 2002
11178 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
11179 + * Licensed under the GPL
11182 +#ifndef __XTERM_H__
11183 +#define __XTERM_H__
11185 +extern int xterm_fd(int socket, int *pid_out);
11190 + * Overrides for Emacs so that we follow Linus's tabbing style.
11191 + * Emacs will notice this stuff at the end of the file and automatically
11192 + * adjust the settings for this buffer only. This must remain at the end
11194 + * ---------------------------------------------------------------------------
11195 + * Local variables:
11196 + * c-file-style: "linux"
11199 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm_kern.c um/arch/um/drivers/xterm_kern.c
11200 --- orig/arch/um/drivers/xterm_kern.c Wed Dec 31 19:00:00 1969
11201 +++ um/arch/um/drivers/xterm_kern.c Tue Dec 17 17:31:20 2002
11204 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
11205 + * Licensed under the GPL
11208 +#include "linux/errno.h"
11209 +#include "linux/slab.h"
11210 +#include "asm/semaphore.h"
11211 +#include "asm/irq.h"
11212 +#include "irq_user.h"
11213 +#include "kern_util.h"
11215 +#include "xterm.h"
11217 +struct xterm_wait {
11218 + struct semaphore sem;
11224 +static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
11226 + struct xterm_wait *xterm = data;
11229 + fd = os_rcv_fd(xterm->fd, &xterm->pid);
11230 + if(fd == -EAGAIN)
11233 + xterm->new_fd = fd;
11237 +int xterm_fd(int socket, int *pid_out)
11239 + struct xterm_wait *data;
11242 + data = kmalloc(sizeof(*data), GFP_KERNEL);
11243 + if(data == NULL){
11244 + printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
11247 + *data = ((struct xterm_wait)
11248 + { .sem = __SEMAPHORE_INITIALIZER(data->sem, 0),
11253 + err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt,
11254 + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
11257 + printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
11258 + "err = %d\n", err);
11261 + down(&data->sem);
11263 + free_irq(XTERM_IRQ, data);
11265 + ret = data->new_fd;
11266 + *pid_out = data->pid;
11273 + * Overrides for Emacs so that we follow Linus's tabbing style.
11274 + * Emacs will notice this stuff at the end of the file and automatically
11275 + * adjust the settings for this buffer only. This must remain at the end
11277 + * ---------------------------------------------------------------------------
11278 + * Local variables:
11279 + * c-file-style: "linux"
11282 diff -Naur -X ../exclude-files orig/arch/um/dyn_link.ld.in um/arch/um/dyn_link.ld.in
11283 --- orig/arch/um/dyn_link.ld.in Wed Dec 31 19:00:00 1969
11284 +++ um/arch/um/dyn_link.ld.in Fri Jan 17 23:37:27 2003
11286 +OUTPUT_FORMAT("ELF_FORMAT")
11287 +OUTPUT_ARCH(ELF_ARCH)
11289 +SEARCH_DIR("/usr/local/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
11290 +/* Do we need any of these for elf?
11291 + __DYNAMIC = 0; */
11294 + . = START() + SIZEOF_HEADERS;
11295 + .interp : { *(.interp) }
11297 + __binary_start = .;
11298 + . = ALIGN(4096); /* Init code and data */
11300 + __init_begin = .;
11301 + .text.init : { *(.text.init) }
11305 + /* Read-only sections, merged into text segment: */
11306 + .hash : { *(.hash) }
11307 + .dynsym : { *(.dynsym) }
11308 + .dynstr : { *(.dynstr) }
11309 + .gnu.version : { *(.gnu.version) }
11310 + .gnu.version_d : { *(.gnu.version_d) }
11311 + .gnu.version_r : { *(.gnu.version_r) }
11312 + .rel.init : { *(.rel.init) }
11313 + .rela.init : { *(.rela.init) }
11314 + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
11315 + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
11316 + .rel.fini : { *(.rel.fini) }
11317 + .rela.fini : { *(.rela.fini) }
11318 + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
11319 + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
11320 + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
11321 + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
11322 + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
11323 + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
11324 + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
11325 + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
11326 + .rel.ctors : { *(.rel.ctors) }
11327 + .rela.ctors : { *(.rela.ctors) }
11328 + .rel.dtors : { *(.rel.dtors) }
11329 + .rela.dtors : { *(.rela.dtors) }
11330 + .rel.got : { *(.rel.got) }
11331 + .rela.got : { *(.rela.got) }
11332 + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
11333 + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
11334 + .rel.plt : { *(.rel.plt) }
11335 + .rela.plt : { *(.rela.plt) }
11339 + .plt : { *(.plt) }
11341 + *(.text .stub .text.* .gnu.linkonce.t.*)
11342 + /* .gnu.warning sections are handled specially by elf32.em. */
11349 + PROVIDE (__etext = .);
11350 + PROVIDE (_etext = .);
11351 + PROVIDE (etext = .);
11352 + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
11353 + .rodata1 : { *(.rodata1) }
11354 + .eh_frame_hdr : { *(.eh_frame_hdr) }
11358 + PROVIDE (_sdata = .);
11360 +include(`arch/um/common.ld.in')
11362 + /* Ensure the __preinit_array_start label is properly aligned. We
11363 + could instead move the label definition inside the section, but
11364 + the linker would then create the section even if it turns out to
11365 + be empty, which isn't pretty. */
11366 + . = ALIGN(32 / 8);
11367 + .preinit_array : { *(.preinit_array) }
11368 + .init_array : { *(.init_array) }
11369 + .fini_array : { *(.fini_array) }
11371 + . = ALIGN(KERNEL_STACK_SIZE); /* init_task */
11372 + *(.data.init_task)
11373 + *(.data .data.* .gnu.linkonce.d.*)
11374 + SORT(CONSTRUCTORS)
11376 + .data1 : { *(.data1) }
11377 + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
11378 + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
11379 + .eh_frame : { KEEP (*(.eh_frame)) }
11380 + .gcc_except_table : { *(.gcc_except_table) }
11381 + .dynamic : { *(.dynamic) }
11383 + /* gcc uses crtbegin.o to find the start of
11384 + the constructors, so we make sure it is
11385 + first. Because this is a wildcard, it
11386 + doesn't matter if the user does not
11387 + actually link against crtbegin.o; the
11388 + linker won't look for a file to match a
11389 + wildcard. The wildcard also means that it
11390 + doesn't matter which directory crtbegin.o
11392 + KEEP (*crtbegin.o(.ctors))
11393 + /* We don't want to include the .ctor section from
11394 + from the crtend.o file until after the sorted ctors.
11395 + The .ctor section from the crtend file contains the
11396 + end of ctors marker and it must be last */
11397 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
11398 + KEEP (*(SORT(.ctors.*)))
11402 + KEEP (*crtbegin.o(.dtors))
11403 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
11404 + KEEP (*(SORT(.dtors.*)))
11407 + .jcr : { KEEP (*(.jcr)) }
11408 + .got : { *(.got.plt) *(.got) }
11410 + PROVIDE (edata = .);
11414 + *(.bss .bss.* .gnu.linkonce.b.*)
11416 + /* Align here to ensure that the .bss section occupies space up to
11417 + _end. Align after .bss to ensure correct alignment even if the
11418 + .bss section disappears because there are no input sections. */
11419 + . = ALIGN(32 / 8);
11420 + . = ALIGN(32 / 8);
11423 + PROVIDE (end = .);
11424 + /* Stabs debugging sections. */
11425 + .stab 0 : { *(.stab) }
11426 + .stabstr 0 : { *(.stabstr) }
11427 + .stab.excl 0 : { *(.stab.excl) }
11428 + .stab.exclstr 0 : { *(.stab.exclstr) }
11429 + .stab.index 0 : { *(.stab.index) }
11430 + .stab.indexstr 0 : { *(.stab.indexstr) }
11431 + .comment 0 : { *(.comment) }
11432 + /* DWARF debug sections.
11433 + Symbols in the DWARF debugging sections are relative to the beginning
11434 + of the section so we begin them at 0. */
11436 + .debug 0 : { *(.debug) }
11437 + .line 0 : { *(.line) }
11438 + /* GNU DWARF 1 extensions */
11439 + .debug_srcinfo 0 : { *(.debug_srcinfo) }
11440 + .debug_sfnames 0 : { *(.debug_sfnames) }
11441 + /* DWARF 1.1 and DWARF 2 */
11442 + .debug_aranges 0 : { *(.debug_aranges) }
11443 + .debug_pubnames 0 : { *(.debug_pubnames) }
11445 + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
11446 + .debug_abbrev 0 : { *(.debug_abbrev) }
11447 + .debug_line 0 : { *(.debug_line) }
11448 + .debug_frame 0 : { *(.debug_frame) }
11449 + .debug_str 0 : { *(.debug_str) }
11450 + .debug_loc 0 : { *(.debug_loc) }
11451 + .debug_macinfo 0 : { *(.debug_macinfo) }
11452 + /* SGI/MIPS DWARF 2 extensions */
11453 + .debug_weaknames 0 : { *(.debug_weaknames) }
11454 + .debug_funcnames 0 : { *(.debug_funcnames) }
11455 + .debug_typenames 0 : { *(.debug_typenames) }
11456 + .debug_varnames 0 : { *(.debug_varnames) }
11458 diff -Naur -X ../exclude-files orig/arch/um/fs/Makefile um/arch/um/fs/Makefile
11459 --- orig/arch/um/fs/Makefile Wed Dec 31 19:00:00 1969
11460 +++ um/arch/um/fs/Makefile Wed Oct 23 21:08:04 2002
11463 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
11464 +# Licensed under the GPL
11467 +O_TARGET := built-in.o
11472 +subdir-$(CONFIG_HOSTFS) += hostfs
11473 +subdir-$(CONFIG_HPPFS) += hppfs
11475 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
11476 +obj-m += $(join $(subdir-m),$(subdir-m:%=/%.o))
11478 +include $(TOPDIR)/Rules.make
11485 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/Makefile um/arch/um/fs/hostfs/Makefile
11486 --- orig/arch/um/fs/hostfs/Makefile Wed Dec 31 19:00:00 1969
11487 +++ um/arch/um/fs/hostfs/Makefile Wed Oct 23 21:08:04 2002
11490 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
11491 +# Licensed under the GPL
11494 +# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino
11495 +# to __st_ino. It stayed in the same place, so as long as the correct name
11496 +# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa.
11498 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
11501 +USER_CFLAGS := $(USER_CFLAGS) -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
11503 +O_TARGET := hostfs.o
11504 +obj-y = hostfs_kern.o hostfs_user.o
11505 +obj-m = $(O_TARGET)
11507 +USER_OBJS = $(filter %_user.o,$(obj-y))
11509 +include $(TOPDIR)/Rules.make
11511 +$(USER_OBJS) : %.o: %.c
11512 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
11513 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs.h um/arch/um/fs/hostfs/hostfs.h
11514 --- orig/arch/um/fs/hostfs/hostfs.h Wed Dec 31 19:00:00 1969
11515 +++ um/arch/um/fs/hostfs/hostfs.h Mon Feb 24 23:00:47 2003
11517 +#ifndef __UM_FS_HOSTFS
11518 +#define __UM_FS_HOSTFS
11522 +/* These are exactly the same definitions as in fs.h, but the names are
11523 + * changed so that this file can be included in both kernel and user files.
11526 +#define HOSTFS_ATTR_MODE 1
11527 +#define HOSTFS_ATTR_UID 2
11528 +#define HOSTFS_ATTR_GID 4
11529 +#define HOSTFS_ATTR_SIZE 8
11530 +#define HOSTFS_ATTR_ATIME 16
11531 +#define HOSTFS_ATTR_MTIME 32
11532 +#define HOSTFS_ATTR_CTIME 64
11533 +#define HOSTFS_ATTR_ATIME_SET 128
11534 +#define HOSTFS_ATTR_MTIME_SET 256
11535 +#define HOSTFS_ATTR_FORCE 512 /* Not a change, but a change it */
11536 +#define HOSTFS_ATTR_ATTR_FLAG 1024
11538 +struct hostfs_iattr {
11539 + unsigned int ia_valid;
11547 + unsigned int ia_attr_flags;
11550 +extern int stat_file(const char *path, int *dev_out,
11551 + unsigned long long *inode_out, int *mode_out,
11552 + int *nlink_out, int *uid_out, int *gid_out,
11553 + unsigned long long *size_out, unsigned long *atime_out,
11554 + unsigned long *mtime_out, unsigned long *ctime_out,
11555 + int *blksize_out, unsigned long long *blocks_out);
11556 +extern int access_file(char *path, int r, int w, int x);
11557 +extern int open_file(char *path, int r, int w);
11558 +extern int file_type(const char *path, int *rdev);
11559 +extern void *open_dir(char *path, int *err_out);
11560 +extern char *read_dir(void *stream, unsigned long long *pos,
11561 + unsigned long long *ino_out, int *len_out);
11562 +extern void close_file(void *stream);
11563 +extern void close_dir(void *stream);
11564 +extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
11565 +extern int write_file(int fd, unsigned long long *offset, const char *buf,
11567 +extern int lseek_file(int fd, long long offset, int whence);
11568 +extern int file_create(char *name, int ur, int uw, int ux, int gr,
11569 + int gw, int gx, int or, int ow, int ox);
11570 +extern int set_attr(const char *file, struct hostfs_iattr *attrs);
11571 +extern int make_symlink(const char *from, const char *to);
11572 +extern int unlink_file(const char *file);
11573 +extern int do_mkdir(const char *file, int mode);
11574 +extern int do_rmdir(const char *file);
11575 +extern int do_mknod(const char *file, int mode, int dev);
11576 +extern int link_file(const char *from, const char *to);
11577 +extern int do_readlink(char *file, char *buf, int size);
11578 +extern int rename_file(char *from, char *to);
11579 +extern int do_statfs(char *root, long *bsize_out, long long *blocks_out,
11580 + long long *bfree_out, long long *bavail_out,
11581 + long long *files_out, long long *ffree_out,
11582 + void *fsid_out, int fsid_size, long *namelen_out,
11583 + long *spare_out);
11586 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_kern.c um/arch/um/fs/hostfs/hostfs_kern.c
11587 --- orig/arch/um/fs/hostfs/hostfs_kern.c Wed Dec 31 19:00:00 1969
11588 +++ um/arch/um/fs/hostfs/hostfs_kern.c Sun Apr 13 21:29:33 2003
11591 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
11592 + * Licensed under the GPL
11595 +#include <linux/stddef.h>
11596 +#include <linux/fs.h>
11597 +#include <linux/version.h>
11598 +#include <linux/module.h>
11599 +#include <linux/init.h>
11600 +#include <linux/slab.h>
11601 +#include <linux/pagemap.h>
11602 +#include <linux/blkdev.h>
11603 +#include <asm/uaccess.h>
11604 +#include "hostfs.h"
11605 +#include "kern_util.h"
11607 +#include "user_util.h"
11608 +#include "2_5compat.h"
11610 +#define file_hostfs_i(file) (&(file)->f_dentry->d_inode->u.hostfs_i)
11612 +int hostfs_d_delete(struct dentry *dentry)
11617 +struct dentry_operations hostfs_dentry_ops = {
11618 + .d_delete = hostfs_d_delete,
11622 +static char *root_ino = "/";
11624 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
11626 +static struct inode_operations hostfs_iops;
11627 +static struct inode_operations hostfs_dir_iops;
11628 +static struct address_space_operations hostfs_link_aops;
11630 +static char *dentry_name(struct dentry *dentry, int extra)
11632 + struct dentry *parent;
11633 + char *root, *name;
11638 + while(parent->d_parent != parent){
11639 + len += parent->d_name.len + 1;
11640 + parent = parent->d_parent;
11643 + root = parent->d_inode->u.hostfs_i.host_filename;
11644 + len += strlen(root);
11645 + name = kmalloc(len + extra + 1, GFP_KERNEL);
11646 + if(name == NULL) return(NULL);
11648 + name[len] = '\0';
11650 + while(parent->d_parent != parent){
11651 + len -= parent->d_name.len + 1;
11653 + strncpy(&name[len + 1], parent->d_name.name,
11654 + parent->d_name.len);
11655 + parent = parent->d_parent;
11657 + strncpy(name, root, strlen(root));
11661 +static char *inode_name(struct inode *ino, int extra)
11663 + struct dentry *dentry;
11665 + dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
11666 + return(dentry_name(dentry, extra));
11669 +static int read_name(struct inode *ino, char *name)
11671 + /* The non-int inode fields are copied into ints by stat_file and
11672 + * then copied into the inode because passing the actual pointers
11673 + * in and having them treated as int * breaks on big-endian machines
11676 + int i_dev, i_mode, i_nlink, i_blksize;
11677 + unsigned long long i_size;
11678 + unsigned long long i_ino;
11679 + unsigned long long i_blocks;
11680 + err = stat_file(name, &i_dev, &i_ino, &i_mode, &i_nlink,
11681 + &ino->i_uid, &ino->i_gid, &i_size, &ino->i_atime,
11682 + &ino->i_mtime, &ino->i_ctime, &i_blksize, &i_blocks);
11683 + if(err) return(err);
11684 + ino->i_ino = i_ino;
11685 + ino->i_dev = i_dev;
11686 + ino->i_mode = i_mode;
11687 + ino->i_nlink = i_nlink;
11688 + ino->i_size = i_size;
11689 + ino->i_blksize = i_blksize;
11690 + ino->i_blocks = i_blocks;
11691 + if(kdev_same(ino->i_sb->s_dev, ROOT_DEV) && (ino->i_uid == getuid()))
11696 +static char *follow_link(char *link)
11699 + char *name, *resolved, *end;
11704 + name = kmalloc(len, GFP_KERNEL);
11708 + n = do_readlink(link, name, len);
11720 + end = strrchr(link, '/');
11724 + *(end + 1) = '\0';
11725 + len = strlen(link) + strlen(name) + 1;
11727 + resolved = kmalloc(len, GFP_KERNEL);
11728 + if(resolved == NULL){
11733 + sprintf(resolved, "%s%s", link, name);
11736 + return(resolved);
11741 + return(ERR_PTR(n));
11744 +static int read_inode(struct inode *ino)
11750 + name = inode_name(ino, 0);
11754 + if(file_type(name, NULL) == OS_TYPE_SYMLINK){
11755 + name = follow_link(name);
11756 + if(IS_ERR(name)){
11757 + err = PTR_ERR(name);
11762 + err = read_name(ino, name);
11768 +void hostfs_delete_inode(struct inode *ino)
11770 + if(ino->u.hostfs_i.host_filename)
11771 + kfree(ino->u.hostfs_i.host_filename);
11772 + ino->u.hostfs_i.host_filename = NULL;
11774 + if(ino->u.hostfs_i.fd != -1)
11775 + close_file(&ino->u.hostfs_i.fd);
11777 + ino->u.hostfs_i.mode = 0;
11778 + clear_inode(ino);
11781 +int hostfs_statfs(struct super_block *sb, struct statfs *sf)
11783 + /* do_statfs uses struct statfs64 internally, but the linux kernel
11784 + * struct statfs still has 32-bit versions for most of these fields,
11785 + * so we convert them here
11788 + long long f_blocks;
11789 + long long f_bfree;
11790 + long long f_bavail;
11791 + long long f_files;
11792 + long long f_ffree;
11794 + err = do_statfs(sb->s_root->d_inode->u.hostfs_i.host_filename,
11795 + &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
11796 + &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
11797 + &sf->f_namelen, sf->f_spare);
11798 + if(err) return(err);
11799 + sf->f_blocks = f_blocks;
11800 + sf->f_bfree = f_bfree;
11801 + sf->f_bavail = f_bavail;
11802 + sf->f_files = f_files;
11803 + sf->f_ffree = f_ffree;
11804 + sf->f_type = HOSTFS_SUPER_MAGIC;
11808 +static struct super_operations hostfs_sbops = {
11809 + .put_inode = force_delete,
11810 + .delete_inode = hostfs_delete_inode,
11811 + .statfs = hostfs_statfs,
11814 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
11818 + unsigned long long next, ino;
11821 + name = dentry_name(file->f_dentry, 0);
11822 + if(name == NULL) return(-ENOMEM);
11823 + dir = open_dir(name, &error);
11825 + if(dir == NULL) return(-error);
11826 + next = file->f_pos;
11827 + while((name = read_dir(dir, &next, &ino, &len)) != NULL){
11828 + error = (*filldir)(ent, name, len, file->f_pos,
11829 + ino, DT_UNKNOWN);
11831 + file->f_pos = next;
11837 +int hostfs_file_open(struct inode *ino, struct file *file)
11840 + int mode = 0, r = 0, w = 0, fd;
11842 + mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
11843 + if((mode & ino->u.hostfs_i.mode) == mode)
11846 + /* The file may already have been opened, but with the wrong access,
11847 + * so this resets things and reopens the file with the new access.
11849 + if(ino->u.hostfs_i.fd != -1){
11850 + close_file(&ino->u.hostfs_i.fd);
11851 + ino->u.hostfs_i.fd = -1;
11854 + ino->u.hostfs_i.mode |= mode;
11855 + if(ino->u.hostfs_i.mode & FMODE_READ)
11857 + if(ino->u.hostfs_i.mode & FMODE_WRITE)
11862 + name = dentry_name(file->f_dentry, 0);
11866 + fd = open_file(name, r, w);
11868 + if(fd < 0) return(fd);
11869 + file_hostfs_i(file)->fd = fd;
11874 +int hostfs_dir_open(struct inode *ino, struct file *file)
11879 +int hostfs_dir_release(struct inode *ino, struct file *file)
11884 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
11889 +static struct file_operations hostfs_file_fops = {
11891 + .read = generic_file_read,
11892 + .write = generic_file_write,
11893 + .mmap = generic_file_mmap,
11894 + .open = hostfs_file_open,
11896 + .fsync = hostfs_fsync,
11899 +static struct file_operations hostfs_dir_fops = {
11901 + .readdir = hostfs_readdir,
11902 + .open = hostfs_dir_open,
11903 + .release = hostfs_dir_release,
11904 + .fsync = hostfs_fsync,
11907 +int hostfs_writepage(struct page *page)
11909 + struct address_space *mapping = page->mapping;
11910 + struct inode *inode = mapping->host;
11912 + unsigned long long base;
11913 + int count = PAGE_CACHE_SIZE;
11914 + int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
11917 + if (page->index >= end_index)
11918 + count = inode->i_size & (PAGE_CACHE_SIZE-1);
11920 + buffer = kmap(page);
11921 + base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
11923 + err = write_file(inode->u.hostfs_i.fd, &base, buffer, count);
11924 + if(err != count){
11925 + ClearPageUptodate(page);
11929 + if (base > inode->i_size)
11930 + inode->i_size = base;
11932 + if (PageError(page))
11933 + ClearPageError(page);
11939 + UnlockPage(page);
11943 +int hostfs_readpage(struct file *file, struct page *page)
11949 + start = (long long) page->index << PAGE_CACHE_SHIFT;
11950 + buffer = kmap(page);
11951 + err = read_file(file_hostfs_i(file)->fd, &start, buffer,
11952 + PAGE_CACHE_SIZE);
11953 + if(err < 0) goto out;
11955 + flush_dcache_page(page);
11956 + SetPageUptodate(page);
11957 + if (PageError(page)) ClearPageError(page);
11961 + UnlockPage(page);
11965 +int hostfs_prepare_write(struct file *file, struct page *page,
11966 + unsigned int from, unsigned int to)
11969 + long long start, tmp;
11972 + start = (long long) page->index << PAGE_CACHE_SHIFT;
11973 + buffer = kmap(page);
11976 + err = read_file(file_hostfs_i(file)->fd, &tmp, buffer,
11978 + if(err < 0) goto out;
11980 + if(to != PAGE_CACHE_SIZE){
11982 + err = read_file(file_hostfs_i(file)->fd, &start, buffer + to,
11983 + PAGE_CACHE_SIZE - to);
11984 + if(err < 0) goto out;
11992 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
11995 + struct address_space *mapping = page->mapping;
11996 + struct inode *inode = mapping->host;
12001 + start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
12002 + buffer = kmap(page);
12003 + err = write_file(file_hostfs_i(file)->fd, &start, buffer + from,
12005 + if(err > 0) err = 0;
12006 + if(!err && (start > inode->i_size))
12007 + inode->i_size = start;
12013 +static struct address_space_operations hostfs_aops = {
12014 + .writepage = hostfs_writepage,
12015 + .readpage = hostfs_readpage,
12016 + .prepare_write = hostfs_prepare_write,
12017 + .commit_write = hostfs_commit_write
12020 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
12023 + struct inode *inode;
12025 + int type, err = -ENOMEM, rdev;
12027 + inode = new_inode(sb);
12028 + if(inode == NULL)
12031 + inode->u.hostfs_i.host_filename = NULL;
12032 + inode->u.hostfs_i.fd = -1;
12033 + inode->u.hostfs_i.mode = 0;
12034 + insert_inode_hash(inode);
12036 + name = dentry_name(dentry, 0);
12037 + if(name == NULL){
12041 + type = file_type(name, &rdev);
12044 + else type = OS_TYPE_DIR;
12045 + inode->i_sb = sb;
12048 + if(type == OS_TYPE_SYMLINK)
12049 + inode->i_op = &page_symlink_inode_operations;
12050 + else if(type == OS_TYPE_DIR)
12051 + inode->i_op = &hostfs_dir_iops;
12052 + else inode->i_op = &hostfs_iops;
12054 + if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
12055 + else inode->i_fop = &hostfs_file_fops;
12057 + if(type == OS_TYPE_SYMLINK)
12058 + inode->i_mapping->a_ops = &hostfs_link_aops;
12059 + else inode->i_mapping->a_ops = &hostfs_aops;
12062 + case OS_TYPE_CHARDEV:
12063 + init_special_inode(inode, S_IFCHR, rdev);
12065 + case OS_TYPE_BLOCKDEV:
12066 + init_special_inode(inode, S_IFBLK, rdev);
12068 + case OS_TYPE_FIFO:
12069 + init_special_inode(inode, S_IFIFO, 0);
12071 + case OS_TYPE_SOCK:
12072 + init_special_inode(inode, S_IFSOCK, 0);
12076 + if(error) *error = err;
12081 + if(error) *error = err;
12085 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode)
12087 + struct inode *inode;
12091 + inode = get_inode(dir->i_sb, dentry, &error);
12092 + if(error) return(error);
12093 + name = dentry_name(dentry, 0);
12094 + if(name == NULL){
12098 + error = file_create(name,
12099 + mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
12100 + mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
12101 + mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
12102 + if(!error) error = read_name(inode, name);
12108 + d_instantiate(dentry, inode);
12112 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry)
12114 + struct inode *inode;
12118 + inode = get_inode(ino->i_sb, dentry, &error);
12119 + if(error != 0) return(ERR_PTR(error));
12120 + name = dentry_name(dentry, 0);
12121 + if(name == NULL) return(ERR_PTR(-ENOMEM));
12122 + error = read_name(inode, name);
12126 + if(error == -ENOENT) inode = NULL;
12127 + else return(ERR_PTR(error));
12129 + d_add(dentry, inode);
12130 + dentry->d_op = &hostfs_dentry_ops;
12134 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
12139 + file = inode_name(ino, dentry->d_name.len + 1);
12140 + if(file == NULL) return(NULL);
12141 + strcat(file, "/");
12142 + len = strlen(file);
12143 + strncat(file, dentry->d_name.name, dentry->d_name.len);
12144 + file[len + dentry->d_name.len] = '\0';
12148 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
12150 + char *from_name, *to_name;
12153 + if((from_name = inode_dentry_name(ino, from)) == NULL)
12155 + to_name = dentry_name(to, 0);
12156 + if(to_name == NULL){
12157 + kfree(from_name);
12160 + err = link_file(to_name, from_name);
12161 + kfree(from_name);
12166 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
12171 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
12172 + err = unlink_file(file);
12177 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
12182 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
12183 + err = make_symlink(file, to);
12188 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
12193 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
12194 + err = do_mkdir(file, mode);
12199 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
12204 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
12205 + err = do_rmdir(file);
12210 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
12212 + struct inode *inode;
12216 + inode = get_inode(dir->i_sb, dentry, &error);
12217 + if(error) return(error);
12218 + name = dentry_name(dentry, 0);
12219 + if(name == NULL){
12223 + init_special_inode(inode, mode, dev);
12224 + error = do_mknod(name, mode, dev);
12225 + if(!error) error = read_name(inode, name);
12231 + d_instantiate(dentry, inode);
12235 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
12236 + struct inode *to_ino, struct dentry *to)
12238 + char *from_name, *to_name;
12241 + if((from_name = inode_dentry_name(from_ino, from)) == NULL)
12243 + if((to_name = inode_dentry_name(to_ino, to)) == NULL){
12244 + kfree(from_name);
12247 + err = rename_file(from_name, to_name);
12248 + kfree(from_name);
12253 +void hostfs_truncate(struct inode *ino)
12255 + not_implemented();
12258 +int hostfs_permission(struct inode *ino, int desired)
12261 + int r = 0, w = 0, x = 0, err;
12263 + if(desired & MAY_READ) r = 1;
12264 + if(desired & MAY_WRITE) w = 1;
12265 + if(desired & MAY_EXEC) x = 1;
12266 + name = inode_name(ino, 0);
12267 + if(name == NULL) return(-ENOMEM);
12268 + err = access_file(name, r, w, x);
12270 + if(!err) err = vfs_permission(ino, desired);
12274 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
12276 + struct hostfs_iattr attrs;
12280 + attrs.ia_valid = 0;
12281 + if(attr->ia_valid & ATTR_MODE){
12282 + attrs.ia_valid |= HOSTFS_ATTR_MODE;
12283 + attrs.ia_mode = attr->ia_mode;
12285 + if(attr->ia_valid & ATTR_UID){
12286 + if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) &&
12287 + (attr->ia_uid == 0))
12288 + attr->ia_uid = getuid();
12289 + attrs.ia_valid |= HOSTFS_ATTR_UID;
12290 + attrs.ia_uid = attr->ia_uid;
12292 + if(attr->ia_valid & ATTR_GID){
12293 + if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) &&
12294 + (attr->ia_gid == 0))
12295 + attr->ia_gid = getuid();
12296 + attrs.ia_valid |= HOSTFS_ATTR_GID;
12297 + attrs.ia_gid = attr->ia_gid;
12299 + if(attr->ia_valid & ATTR_SIZE){
12300 + attrs.ia_valid |= HOSTFS_ATTR_SIZE;
12301 + attrs.ia_size = attr->ia_size;
12303 + if(attr->ia_valid & ATTR_ATIME){
12304 + attrs.ia_valid |= HOSTFS_ATTR_ATIME;
12305 + attrs.ia_atime = attr->ia_atime;
12307 + if(attr->ia_valid & ATTR_MTIME){
12308 + attrs.ia_valid |= HOSTFS_ATTR_MTIME;
12309 + attrs.ia_mtime = attr->ia_mtime;
12311 + if(attr->ia_valid & ATTR_CTIME){
12312 + attrs.ia_valid |= HOSTFS_ATTR_CTIME;
12313 + attrs.ia_ctime = attr->ia_ctime;
12315 + if(attr->ia_valid & ATTR_ATIME_SET){
12316 + attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
12318 + if(attr->ia_valid & ATTR_MTIME_SET){
12319 + attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
12321 + name = dentry_name(dentry, 0);
12322 + if(name == NULL) return(-ENOMEM);
12323 + err = set_attr(name, &attrs);
12328 + return(inode_setattr(dentry->d_inode, attr));
12331 +int hostfs_getattr(struct dentry *dentry, struct iattr *attr)
12333 + not_implemented();
12337 +static struct inode_operations hostfs_iops = {
12338 + .create = hostfs_create,
12339 + .link = hostfs_link,
12340 + .unlink = hostfs_unlink,
12341 + .symlink = hostfs_symlink,
12342 + .mkdir = hostfs_mkdir,
12343 + .rmdir = hostfs_rmdir,
12344 + .mknod = hostfs_mknod,
12345 + .rename = hostfs_rename,
12346 + .truncate = hostfs_truncate,
12347 + .permission = hostfs_permission,
12348 + .setattr = hostfs_setattr,
12349 + .getattr = hostfs_getattr,
12352 +static struct inode_operations hostfs_dir_iops = {
12353 + .create = hostfs_create,
12354 + .lookup = hostfs_lookup,
12355 + .link = hostfs_link,
12356 + .unlink = hostfs_unlink,
12357 + .symlink = hostfs_symlink,
12358 + .mkdir = hostfs_mkdir,
12359 + .rmdir = hostfs_rmdir,
12360 + .mknod = hostfs_mknod,
12361 + .rename = hostfs_rename,
12362 + .truncate = hostfs_truncate,
12363 + .permission = hostfs_permission,
12364 + .setattr = hostfs_setattr,
12365 + .getattr = hostfs_getattr,
12368 +int hostfs_link_readpage(struct file *file, struct page *page)
12370 + char *buffer, *name;
12374 + start = page->index << PAGE_CACHE_SHIFT;
12375 + buffer = kmap(page);
12376 + name = inode_name(page->mapping->host, 0);
12377 + if(name == NULL) return(-ENOMEM);
12378 + err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
12380 + if(err == PAGE_CACHE_SIZE)
12382 + else if(err > 0){
12383 + flush_dcache_page(page);
12384 + SetPageUptodate(page);
12385 + if (PageError(page)) ClearPageError(page);
12389 + UnlockPage(page);
12393 +static struct address_space_operations hostfs_link_aops = {
12394 + .readpage = hostfs_link_readpage,
12397 +static struct super_block *hostfs_read_super_common(struct super_block *sb,
12400 + struct inode *root_inode;
12403 + sb->s_blocksize = 1024;
12404 + sb->s_blocksize_bits = 10;
12405 + sb->s_magic = HOSTFS_SUPER_MAGIC;
12406 + sb->s_op = &hostfs_sbops;
12407 + if((data == NULL) || (*((char *) data) == '\0')) data = root_ino;
12408 + name = kmalloc(strlen(data) + 1, GFP_KERNEL);
12409 + if(name == NULL) return(NULL);
12410 + strcpy(name, data);
12411 + root_inode = get_inode(sb, NULL, NULL);
12412 + if(root_inode == NULL)
12415 + root_inode->u.hostfs_i.host_filename = name;
12416 + sb->s_root = d_alloc_root(root_inode);
12417 + if(read_inode(root_inode))
12424 + iput(root_inode);
12428 +struct super_block *hostfs_read_super(struct super_block *sb, void *data,
12431 + return(hostfs_read_super_common(sb, data));
12434 +DECLARE_FSTYPE(hostfs_type, "hostfs", hostfs_read_super, 0);
12436 +static int __init init_hostfs(void)
12438 + return(register_filesystem(&hostfs_type));
12441 +static void __exit exit_hostfs(void)
12443 + unregister_filesystem(&hostfs_type);
12446 +module_init(init_hostfs)
12447 +module_exit(exit_hostfs)
12448 +MODULE_LICENSE("GPL");
12451 + * Overrides for Emacs so that we follow Linus's tabbing style.
12452 + * Emacs will notice this stuff at the end of the file and automatically
12453 + * adjust the settings for this buffer only. This must remain at the end
12455 + * ---------------------------------------------------------------------------
12456 + * Local variables:
12457 + * c-file-style: "linux"
12460 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_user.c um/arch/um/fs/hostfs/hostfs_user.c
12461 --- orig/arch/um/fs/hostfs/hostfs_user.c Wed Dec 31 19:00:00 1969
12462 +++ um/arch/um/fs/hostfs/hostfs_user.c Fri Jan 31 21:48:30 2003
12465 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
12466 + * Licensed under the GPL
12469 +#include <unistd.h>
12470 +#include <stdio.h>
12471 +#include <fcntl.h>
12472 +#include <dirent.h>
12473 +#include <errno.h>
12474 +#include <utime.h>
12475 +#include <string.h>
12476 +#include <sys/stat.h>
12477 +#include <sys/time.h>
12478 +#include <sys/vfs.h>
12479 +#include "hostfs.h"
12480 +#include "kern_util.h"
12483 +int stat_file(const char *path, int *dev_out, unsigned long long *inode_out,
12484 + int *mode_out, int *nlink_out, int *uid_out, int *gid_out,
12485 + unsigned long long *size_out, unsigned long *atime_out,
12486 + unsigned long *mtime_out, unsigned long *ctime_out,
12487 + int *blksize_out, unsigned long long *blocks_out)
12489 + struct stat64 buf;
12491 + if(lstat64(path, &buf) < 0)
12493 + if(dev_out != NULL) *dev_out = buf.st_dev;
12495 + /* See the Makefile for why STAT64_INO_FIELD is passed in
12498 + if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
12499 + if(mode_out != NULL) *mode_out = buf.st_mode;
12500 + if(nlink_out != NULL) *nlink_out = buf.st_nlink;
12501 + if(uid_out != NULL) *uid_out = buf.st_uid;
12502 + if(gid_out != NULL) *gid_out = buf.st_gid;
12503 + if(size_out != NULL) *size_out = buf.st_size;
12504 + if(atime_out != NULL) *atime_out = buf.st_atime;
12505 + if(mtime_out != NULL) *mtime_out = buf.st_mtime;
12506 + if(ctime_out != NULL) *ctime_out = buf.st_ctime;
12507 + if(blksize_out != NULL) *blksize_out = buf.st_blksize;
12508 + if(blocks_out != NULL) *blocks_out = buf.st_blocks;
12512 +int file_type(const char *path, int *rdev)
12514 + struct stat64 buf;
12516 + if(lstat64(path, &buf) < 0)
12519 + *rdev = buf.st_rdev;
12521 + if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
12522 + else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
12523 + else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
12524 + else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
12525 + else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
12526 + else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
12527 + else return(OS_TYPE_FILE);
12530 +int access_file(char *path, int r, int w, int x)
12534 + if(r) mode = R_OK;
12535 + if(w) mode |= W_OK;
12536 + if(x) mode |= X_OK;
12537 + if(access(path, mode) != 0) return(-errno);
12541 +int open_file(char *path, int r, int w)
12543 + int mode = 0, fd;
12545 + if(r && !w) mode = O_RDONLY;
12546 + else if(!r && w) mode = O_WRONLY;
12547 + else if(r && w) mode = O_RDWR;
12548 + else panic("Impossible mode in open_file");
12549 + fd = open64(path, mode);
12550 + if(fd < 0) return(-errno);
12554 +void *open_dir(char *path, int *err_out)
12558 + dir = opendir(path);
12559 + *err_out = errno;
12560 + if(dir == NULL) return(NULL);
12564 +char *read_dir(void *stream, unsigned long long *pos,
12565 + unsigned long long *ino_out, int *len_out)
12567 + DIR *dir = stream;
12568 + struct dirent *ent;
12570 + seekdir(dir, *pos);
12571 + ent = readdir(dir);
12572 + if(ent == NULL) return(NULL);
12573 + *len_out = strlen(ent->d_name);
12574 + *ino_out = ent->d_ino;
12575 + *pos = telldir(dir);
12576 + return(ent->d_name);
12579 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
12583 + n = pread64(fd, buf, len, *offset);
12584 + if(n < 0) return(-errno);
12589 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
12593 + n = pwrite64(fd, buf, len, *offset);
12594 + if(n < 0) return(-errno);
12599 +int lseek_file(int fd, long long offset, int whence)
12603 + ret = lseek64(fd, offset, whence);
12604 + if(ret < 0) return(-errno);
12608 +void close_file(void *stream)
12610 + close(*((int *) stream));
12613 +void close_dir(void *stream)
12615 + closedir(stream);
12618 +int file_create(char *name, int ur, int uw, int ux, int gr,
12619 + int gw, int gx, int or, int ow, int ox)
12624 + mode |= ur ? S_IRUSR : 0;
12625 + mode |= uw ? S_IWUSR : 0;
12626 + mode |= ux ? S_IXUSR : 0;
12627 + mode |= gr ? S_IRGRP : 0;
12628 + mode |= gw ? S_IWGRP : 0;
12629 + mode |= gx ? S_IXGRP : 0;
12630 + mode |= or ? S_IROTH : 0;
12631 + mode |= ow ? S_IWOTH : 0;
12632 + mode |= ox ? S_IXOTH : 0;
12633 + fd = open64(name, O_CREAT, mode);
12634 + if(fd < 0) return(-errno);
12639 +int set_attr(const char *file, struct hostfs_iattr *attrs)
12641 + struct utimbuf buf;
12644 + if(attrs->ia_valid & HOSTFS_ATTR_MODE){
12645 + if(chmod(file, attrs->ia_mode) != 0) return(-errno);
12647 + if(attrs->ia_valid & HOSTFS_ATTR_UID){
12648 + if(chown(file, attrs->ia_uid, -1)) return(-errno);
12650 + if(attrs->ia_valid & HOSTFS_ATTR_GID){
12651 + if(chown(file, -1, attrs->ia_gid)) return(-errno);
12653 + if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
12654 + if(truncate(file, attrs->ia_size)) return(-errno);
12656 + ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
12657 + if((attrs->ia_valid & ma) == ma){
12658 + buf.actime = attrs->ia_atime;
12659 + buf.modtime = attrs->ia_mtime;
12660 + if(utime(file, &buf) != 0) return(-errno);
12663 + if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
12664 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
12665 + NULL, NULL, NULL, &buf.modtime, NULL,
12667 + if(err != 0) return(err);
12668 + buf.actime = attrs->ia_atime;
12669 + if(utime(file, &buf) != 0) return(-errno);
12671 + if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
12672 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
12673 + NULL, NULL, &buf.actime, NULL, NULL,
12675 + if(err != 0) return(err);
12676 + buf.modtime = attrs->ia_mtime;
12677 + if(utime(file, &buf) != 0) return(-errno);
12680 + if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
12681 + if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
12682 + err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
12683 + NULL, NULL, &attrs->ia_atime, &attrs->ia_mtime,
12684 + NULL, NULL, NULL);
12685 + if(err != 0) return(err);
12690 +int make_symlink(const char *from, const char *to)
12694 + err = symlink(to, from);
12695 + if(err) return(-errno);
12699 +int unlink_file(const char *file)
12703 + err = unlink(file);
12704 + if(err) return(-errno);
12708 +int do_mkdir(const char *file, int mode)
12712 + err = mkdir(file, mode);
12713 + if(err) return(-errno);
12717 +int do_rmdir(const char *file)
12721 + err = rmdir(file);
12722 + if(err) return(-errno);
12726 +int do_mknod(const char *file, int mode, int dev)
12730 + err = mknod(file, mode, dev);
12731 + if(err) return(-errno);
12735 +int link_file(const char *to, const char *from)
12739 + err = link(to, from);
12740 + if(err) return(-errno);
12744 +int do_readlink(char *file, char *buf, int size)
12748 + n = readlink(file, buf, size);
12756 +int rename_file(char *from, char *to)
12760 + err = rename(from, to);
12761 + if(err < 0) return(-errno);
12765 +int do_statfs(char *root, long *bsize_out, long long *blocks_out,
12766 + long long *bfree_out, long long *bavail_out,
12767 + long long *files_out, long long *ffree_out,
12768 + void *fsid_out, int fsid_size, long *namelen_out,
12771 + struct statfs64 buf;
12774 + err = statfs64(root, &buf);
12775 + if(err < 0) return(-errno);
12776 + *bsize_out = buf.f_bsize;
12777 + *blocks_out = buf.f_blocks;
12778 + *bfree_out = buf.f_bfree;
12779 + *bavail_out = buf.f_bavail;
12780 + *files_out = buf.f_files;
12781 + *ffree_out = buf.f_ffree;
12782 + memcpy(fsid_out, &buf.f_fsid,
12783 + sizeof(buf.f_fsid) > fsid_size ? fsid_size :
12784 + sizeof(buf.f_fsid));
12785 + *namelen_out = buf.f_namelen;
12786 + spare_out[0] = buf.f_spare[0];
12787 + spare_out[1] = buf.f_spare[1];
12788 + spare_out[2] = buf.f_spare[2];
12789 + spare_out[3] = buf.f_spare[3];
12790 + spare_out[4] = buf.f_spare[4];
12791 + spare_out[5] = buf.f_spare[5];
12796 + * Overrides for Emacs so that we follow Linus's tabbing style.
12797 + * Emacs will notice this stuff at the end of the file and automatically
12798 + * adjust the settings for this buffer only. This must remain at the end
12800 + * ---------------------------------------------------------------------------
12801 + * Local variables:
12802 + * c-file-style: "linux"
12805 diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/Makefile um/arch/um/fs/hppfs/Makefile
12806 --- orig/arch/um/fs/hppfs/Makefile Wed Dec 31 19:00:00 1969
12807 +++ um/arch/um/fs/hppfs/Makefile Wed Oct 23 21:08:04 2002
12809 +O_TARGET := hppfs.o
12810 +obj-y = hppfs_kern.o #hppfs_user.o
12811 +obj-m = $(O_TARGET)
12813 +CFLAGS_hppfs_kern.o := $(CFLAGS)
12814 +#CFLAGS_hppfs_user.o := $(USER_CFLAGS)
12818 +include $(TOPDIR)/Rules.make
12819 diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/hppfs_kern.c um/arch/um/fs/hppfs/hppfs_kern.c
12820 --- orig/arch/um/fs/hppfs/hppfs_kern.c Wed Dec 31 19:00:00 1969
12821 +++ um/arch/um/fs/hppfs/hppfs_kern.c Thu Feb 27 13:14:26 2003
12824 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
12825 + * Licensed under the GPL
12828 +#include <linux/fs.h>
12829 +#include <linux/module.h>
12830 +#include <linux/slab.h>
12831 +#include <linux/list.h>
12832 +#include <linux/kernel.h>
12833 +#include <linux/ctype.h>
12834 +#include <asm/uaccess.h>
12837 +struct hppfs_data {
12838 + struct list_head list;
12839 + char contents[PAGE_SIZE - sizeof(struct list_head)];
12842 +struct hppfs_private {
12843 + struct file proc_file;
12846 + struct hppfs_data *contents;
12849 +#define HPPFS_SUPER_MAGIC 0xb00000ee
12851 +static struct super_operations hppfs_sbops;
12853 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
12856 +static int is_pid(struct dentry *dentry)
12858 + struct super_block *sb;
12861 + sb = dentry->d_sb;
12862 + if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
12865 + for(i = 0; i < dentry->d_name.len; i++){
12866 + if(!isdigit(dentry->d_name.name[i]))
12872 +static char *dentry_name(struct dentry *dentry, int extra)
12874 + struct dentry *parent;
12875 + char *root, *name;
12876 + const char *seg_name;
12877 + int len, seg_len;
12881 + while(parent->d_parent != parent){
12882 + if(is_pid(parent))
12883 + len += strlen("pid") + 1;
12884 + else len += parent->d_name.len + 1;
12885 + parent = parent->d_parent;
12889 + len += strlen(root);
12890 + name = kmalloc(len + extra + 1, GFP_KERNEL);
12891 + if(name == NULL) return(NULL);
12893 + name[len] = '\0';
12895 + while(parent->d_parent != parent){
12896 + if(is_pid(parent)){
12897 + seg_name = "pid";
12898 + seg_len = strlen("pid");
12901 + seg_name = parent->d_name.name;
12902 + seg_len = parent->d_name.len;
12905 + len -= seg_len + 1;
12907 + strncpy(&name[len + 1], seg_name, seg_len);
12908 + parent = parent->d_parent;
12910 + strncpy(name, root, strlen(root));
12914 +struct dentry_operations hppfs_dentry_ops = {
12917 +static int file_removed(struct dentry *dentry, const char *file)
12923 + if(file != NULL) extra += strlen(file) + 1;
12925 + host_file = dentry_name(dentry, extra + strlen("/remove"));
12926 + if(host_file == NULL){
12927 + printk("file_removed : allocation failed\n");
12931 + if(file != NULL){
12932 + strcat(host_file, "/");
12933 + strcat(host_file, file);
12935 + strcat(host_file, "/remove");
12937 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
12938 + kfree(host_file);
12940 + os_close_file(fd);
12946 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry)
12948 + struct dentry *proc_dentry;
12949 + struct inode *inode;
12950 + int err, deleted;
12952 + deleted = file_removed(dentry, NULL);
12954 + return(ERR_PTR(deleted));
12956 + return(ERR_PTR(-ENOENT));
12958 + proc_dentry = lookup_hash(&dentry->d_name, ino->u.hppfs_i.proc_dentry);
12959 + if(IS_ERR(proc_dentry))
12960 + return(proc_dentry);
12962 + inode = get_inode(ino->i_sb, proc_dentry, &err);
12964 + return(ERR_PTR(err));
12966 + d_add(dentry, inode);
12967 + dentry->d_op = &hppfs_dentry_ops;
12971 +static struct inode_operations hppfs_file_iops = {
12974 +static struct inode_operations hppfs_dir_iops = {
12975 + .lookup = hppfs_lookup,
12978 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count,
12979 + loff_t *ppos, int is_user)
12981 + ssize_t (*read)(struct file *, char *, size_t, loff_t *);
12984 + read = file->f_dentry->d_inode->i_fop->read;
12987 + set_fs(KERNEL_DS);
12989 + n = (*read)(file, buf, count, &file->f_pos);
12994 + if(ppos) *ppos = file->f_pos;
12998 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
13005 + new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
13006 + if(new_buf == NULL){
13007 + printk("hppfs_read_file : kmalloc failed\n");
13011 + while(count > 0){
13012 + cur = min_t(ssize_t, count, PAGE_SIZE);
13013 + err = os_read_file(fd, new_buf, cur);
13015 + printk("hppfs_read : read failed, errno = %d\n",
13020 + else if(err == 0)
13023 + if(copy_to_user(buf, new_buf, err)){
13036 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
13039 + struct hppfs_private *hppfs = file->private_data;
13040 + struct hppfs_data *data;
13044 + if(hppfs->contents != NULL){
13045 + if(*ppos >= hppfs->len) return(0);
13047 + data = hppfs->contents;
13049 + while(off >= sizeof(data->contents)){
13050 + data = list_entry(data->list.next, struct hppfs_data,
13052 + off -= sizeof(data->contents);
13055 + if(off + count > hppfs->len)
13056 + count = hppfs->len - off;
13057 + copy_to_user(buf, &data->contents[off], count);
13060 + else if(hppfs->host_fd != -1){
13061 + err = os_seek_file(hppfs->host_fd, *ppos);
13063 + printk("hppfs_read : seek failed, errno = %d\n", err);
13066 + count = hppfs_read_file(hppfs->host_fd, buf, count);
13070 + else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
13075 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len,
13078 + struct hppfs_private *data = file->private_data;
13079 + struct file *proc_file = &data->proc_file;
13080 + ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
13083 + write = proc_file->f_dentry->d_inode->i_fop->write;
13085 + proc_file->f_pos = file->f_pos;
13086 + err = (*write)(proc_file, buf, len, &proc_file->f_pos);
13087 + file->f_pos = proc_file->f_pos;
13092 +static int open_host_sock(char *host_file, int *filter_out)
13097 + end = &host_file[strlen(host_file)];
13098 + strcpy(end, "/rw");
13100 + fd = os_connect_socket(host_file);
13104 + strcpy(end, "/r");
13106 + fd = os_connect_socket(host_file);
13110 +static void free_contents(struct hppfs_data *head)
13112 + struct hppfs_data *data;
13113 + struct list_head *ele, *next;
13115 + if(head == NULL) return;
13117 + list_for_each_safe(ele, next, &head->list){
13118 + data = list_entry(ele, struct hppfs_data, list);
13124 +static struct hppfs_data *hppfs_get_data(int fd, int filter,
13125 + struct file *proc_file,
13126 + struct file *hppfs_file,
13127 + loff_t *size_out)
13129 + struct hppfs_data *data, *new, *head;
13133 + data = kmalloc(sizeof(*data), GFP_KERNEL);
13134 + if(data == NULL){
13135 + printk("hppfs_get_data : head allocation failed\n");
13139 + INIT_LIST_HEAD(&data->list);
13145 + while((n = read_proc(proc_file, data->contents,
13146 + sizeof(data->contents), NULL, 0)) > 0)
13147 + os_write_file(fd, data->contents, n);
13148 + err = os_shutdown_socket(fd, 0, 1);
13150 + printk("hppfs_get_data : failed to shut down "
13152 + goto failed_free;
13156 + n = os_read_file(fd, data->contents, sizeof(data->contents));
13159 + printk("hppfs_get_data : read failed, errno = %d\n",
13161 + goto failed_free;
13168 + if(n < sizeof(data->contents))
13171 + new = kmalloc(sizeof(*data), GFP_KERNEL);
13173 + printk("hppfs_get_data : data allocation failed\n");
13175 + goto failed_free;
13178 + INIT_LIST_HEAD(&new->list);
13179 + list_add(&new->list, &data->list);
13185 + free_contents(head);
13187 + return(ERR_PTR(err));
13190 +static struct hppfs_private *hppfs_data(void)
13192 + struct hppfs_private *data;
13194 + data = kmalloc(sizeof(*data), GFP_KERNEL);
13198 + *data = ((struct hppfs_private ) { .host_fd = -1,
13200 + .contents = NULL } );
13204 +static int hppfs_open(struct inode *inode, struct file *file)
13206 + struct hppfs_private *data;
13207 + struct dentry *proc_dentry;
13209 + int err, fd, type, filter;
13212 + data = hppfs_data();
13216 + host_file = dentry_name(file->f_dentry, strlen("/rw"));
13217 + if(host_file == NULL)
13220 + proc_dentry = inode->u.hppfs_i.proc_dentry;
13221 + err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
13225 + type = os_file_type(host_file);
13226 + if(type == OS_TYPE_FILE){
13227 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
13229 + data->host_fd = fd;
13230 + else printk("hppfs_open : failed to open '%s', errno = %d\n",
13233 + data->contents = NULL;
13235 + else if(type == OS_TYPE_DIR){
13236 + fd = open_host_sock(host_file, &filter);
13238 + data->contents = hppfs_get_data(fd, filter,
13239 + &data->proc_file,
13240 + file, &data->len);
13241 + if(!IS_ERR(data->contents))
13242 + data->host_fd = fd;
13244 + else printk("hppfs_open : failed to open a socket in "
13245 + "'%s', errno = %d\n", host_file, -fd);
13247 + kfree(host_file);
13249 + file->private_data = data;
13253 + kfree(host_file);
13255 + free_contents(data->contents);
13261 +static int hppfs_dir_open(struct inode *inode, struct file *file)
13263 + struct hppfs_private *data;
13264 + struct dentry *proc_dentry;
13268 + data = hppfs_data();
13272 + proc_dentry = inode->u.hppfs_i.proc_dentry;
13273 + err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
13277 + file->private_data = data;
13286 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
13288 + struct hppfs_private *data = file->private_data;
13289 + struct file *proc_file = &data->proc_file;
13290 + loff_t (*llseek)(struct file *, loff_t, int);
13293 + llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
13294 + if(llseek != NULL){
13295 + ret = (*llseek)(proc_file, off, where);
13300 + return(default_llseek(file, off, where));
13303 +struct hppfs_dirent {
13304 + void *vfs_dirent;
13305 + filldir_t filldir;
13306 + struct dentry *dentry;
13309 +static int hppfs_filldir(void *d, const char *name, int size,
13310 + loff_t offset, ino_t inode, unsigned int type)
13312 + struct hppfs_dirent *dirent = d;
13314 + if(file_removed(dirent->dentry, name))
13317 + return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
13321 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
13323 + struct hppfs_private *data = file->private_data;
13324 + struct file *proc_file = &data->proc_file;
13325 + int (*readdir)(struct file *, void *, filldir_t);
13326 + struct hppfs_dirent dirent = ((struct hppfs_dirent)
13327 + { .vfs_dirent = ent,
13328 + .filldir = filldir,
13329 + .dentry = file->f_dentry } );
13332 + readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
13334 + proc_file->f_pos = file->f_pos;
13335 + err = (*readdir)(proc_file, &dirent, hppfs_filldir);
13336 + file->f_pos = proc_file->f_pos;
13341 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
13346 +static struct file_operations hppfs_file_fops = {
13348 + .llseek = hppfs_llseek,
13349 + .read = hppfs_read,
13350 + .write = hppfs_write,
13351 + .open = hppfs_open,
13354 +static struct file_operations hppfs_dir_fops = {
13356 + .readdir = hppfs_readdir,
13357 + .open = hppfs_dir_open,
13358 + .fsync = hppfs_fsync,
13361 +static int hppfs_statfs(struct super_block *sb, struct statfs *sf)
13363 + sf->f_blocks = 0;
13365 + sf->f_bavail = 0;
13368 + sf->f_type = HPPFS_SUPER_MAGIC;
13372 +static struct super_operations hppfs_sbops = {
13373 + .put_inode = force_delete,
13374 + .delete_inode = NULL,
13375 + .statfs = hppfs_statfs,
13378 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
13380 + struct file proc_file;
13381 + struct dentry *proc_dentry;
13382 + int (*readlink)(struct dentry *, char *, int);
13385 + proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
13386 + err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
13390 + readlink = proc_dentry->d_inode->i_op->readlink;
13391 + n = (*readlink)(proc_dentry, buffer, buflen);
13393 + if(proc_file.f_op->release)
13394 + (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
13399 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
13401 + struct file proc_file;
13402 + struct dentry *proc_dentry;
13403 + int (*follow_link)(struct dentry *, struct nameidata *);
13406 + proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
13407 + err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
13411 + follow_link = proc_dentry->d_inode->i_op->follow_link;
13412 + n = (*follow_link)(proc_dentry, nd);
13414 + if(proc_file.f_op->release)
13415 + (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
13420 +static struct inode_operations hppfs_link_iops = {
13421 + .readlink = hppfs_readlink,
13422 + .follow_link = hppfs_follow_link,
13425 +static void read_inode(struct inode *ino)
13427 + struct inode *proc_ino;
13429 + proc_ino = ino->u.hppfs_i.proc_dentry->d_inode;
13430 + ino->i_uid = proc_ino->i_uid;
13431 + ino->i_gid = proc_ino->i_gid;
13432 + ino->i_atime = proc_ino->i_atime;
13433 + ino->i_mtime = proc_ino->i_mtime;
13434 + ino->i_ctime = proc_ino->i_ctime;
13435 + ino->i_ino = proc_ino->i_ino;
13436 + ino->i_dev = proc_ino->i_dev;
13437 + ino->i_mode = proc_ino->i_mode;
13438 + ino->i_nlink = proc_ino->i_nlink;
13439 + ino->i_size = proc_ino->i_size;
13440 + ino->i_blksize = proc_ino->i_blksize;
13441 + ino->i_blocks = proc_ino->i_blocks;
13444 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
13447 + struct inode *inode;
13448 + int err = -ENOMEM;
13450 + inode = new_inode(sb);
13451 + if(inode == NULL)
13454 + insert_inode_hash(inode);
13455 + if(S_ISDIR(dentry->d_inode->i_mode)){
13456 + inode->i_op = &hppfs_dir_iops;
13457 + inode->i_fop = &hppfs_dir_fops;
13459 + else if(S_ISLNK(dentry->d_inode->i_mode)){
13460 + inode->i_op = &hppfs_link_iops;
13461 + inode->i_fop = &hppfs_file_fops;
13464 + inode->i_op = &hppfs_file_iops;
13465 + inode->i_fop = &hppfs_file_fops;
13468 + inode->i_sb = sb;
13469 + inode->u.hppfs_i.proc_dentry = dentry;
13471 + read_inode(inode);
13474 + if(error) *error = err;
13477 + if(error) *error = err;
13481 +static struct super_block *hppfs_read_super(struct super_block *sb, void *d,
13484 + struct inode *root_inode;
13485 + struct file_system_type *procfs;
13486 + struct super_block *proc_sb;
13488 + procfs = get_fs_type("proc");
13489 + if(procfs == NULL)
13492 + if(list_empty(&procfs->fs_supers))
13495 + proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
13498 + sb->s_blocksize = 1024;
13499 + sb->s_blocksize_bits = 10;
13500 + sb->s_magic = HPPFS_SUPER_MAGIC;
13501 + sb->s_op = &hppfs_sbops;
13503 + dget(proc_sb->s_root);
13504 + root_inode = get_inode(sb, proc_sb->s_root, NULL);
13505 + if(root_inode == NULL)
13508 + sb->s_root = d_alloc_root(root_inode);
13509 + if(sb->s_root == NULL)
13515 + iput(root_inode);
13517 + dput(proc_sb->s_root);
13522 +DECLARE_FSTYPE(hppfs_type, "hppfs", hppfs_read_super, 0);
13524 +static int __init init_hppfs(void)
13526 + return(register_filesystem(&hppfs_type));
13529 +static void __exit exit_hppfs(void)
13531 + unregister_filesystem(&hppfs_type);
13534 +module_init(init_hppfs)
13535 +module_exit(exit_hppfs)
13536 +MODULE_LICENSE("GPL");
13539 + * Overrides for Emacs so that we follow Linus's tabbing style.
13540 + * Emacs will notice this stuff at the end of the file and automatically
13541 + * adjust the settings for this buffer only. This must remain at the end
13543 + * ---------------------------------------------------------------------------
13544 + * Local variables:
13545 + * c-file-style: "linux"
13548 diff -Naur -X ../exclude-files orig/arch/um/include/2_5compat.h um/arch/um/include/2_5compat.h
13549 --- orig/arch/um/include/2_5compat.h Wed Dec 31 19:00:00 1969
13550 +++ um/arch/um/include/2_5compat.h Thu Feb 27 20:15:19 2003
13553 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
13554 + * Licensed under the GPL
13557 +#ifndef __2_5_COMPAT_H__
13558 +#define __2_5_COMPAT_H__
13560 +#include "linux/version.h"
13562 +#define INIT_CONSOLE(dev_name, write_proc, device_proc, setup_proc, f) { \
13563 + name : dev_name, \
13564 + write : write_proc, \
13566 + device : device_proc, \
13567 + unblank : NULL, \
13568 + setup : setup_proc, \
13575 +#define INIT_ELV(queue, elv) elevator_init(elv, ELV_NOOP)
13577 +#define ELV_NOOP ELEVATOR_NOOP
13579 +#define INIT_HARDSECT(arr, maj, sizes) arr[maj] = sizes
13581 +#define IS_WRITE(req) ((req)->cmd == WRITE)
13583 +#define SET_PRI(task) \
13584 + do { (task)->nice = 20; (task)->counter = -100; } while(0);
13589 + * Overrides for Emacs so that we follow Linus's tabbing style.
13590 + * Emacs will notice this stuff at the end of the file and automatically
13591 + * adjust the settings for this buffer only. This must remain at the end
13593 + * ---------------------------------------------------------------------------
13594 + * Local variables:
13595 + * c-file-style: "linux"
13598 diff -Naur -X ../exclude-files orig/arch/um/include/Makefile um/arch/um/include/Makefile
13599 --- orig/arch/um/include/Makefile Wed Dec 31 19:00:00 1969
13600 +++ um/arch/um/include/Makefile Wed Oct 23 21:08:04 2002
13604 +sc.h : ../util/mk_sc
13605 + ../util/mk_sc > $@
13608 + $(MAKE) -C ../util mk_sc
13609 diff -Naur -X ../exclude-files orig/arch/um/include/chan_kern.h um/arch/um/include/chan_kern.h
13610 --- orig/arch/um/include/chan_kern.h Wed Dec 31 19:00:00 1969
13611 +++ um/arch/um/include/chan_kern.h Fri Nov 15 13:32:35 2002
13614 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
13615 + * Licensed under the GPL
13618 +#ifndef __CHAN_KERN_H__
13619 +#define __CHAN_KERN_H__
13621 +#include "linux/tty.h"
13622 +#include "linux/list.h"
13623 +#include "chan_user.h"
13626 + struct list_head list;
13628 + unsigned int primary:1;
13629 + unsigned int input:1;
13630 + unsigned int output:1;
13631 + unsigned int opened:1;
13633 + enum chan_init_pri pri;
13634 + struct chan_ops *ops;
13638 +extern void chan_interrupt(struct list_head *chans, struct tq_struct *task,
13639 + struct tty_struct *tty, int irq, void *dev);
13640 +extern int parse_chan_pair(char *str, struct list_head *chans, int pri,
13641 + int device, struct chan_opts *opts);
13642 +extern int open_chan(struct list_head *chans);
13643 +extern int write_chan(struct list_head *chans, const char *buf, int len,
13645 +extern int console_write_chan(struct list_head *chans, const char *buf,
13647 +extern void close_chan(struct list_head *chans);
13648 +extern void chan_enable_winch(struct list_head *chans, void *line);
13649 +extern void enable_chan(struct list_head *chans, void *data);
13650 +extern int chan_window_size(struct list_head *chans,
13651 + unsigned short *rows_out,
13652 + unsigned short *cols_out);
13653 +extern int chan_out_fd(struct list_head *chans);
13654 +extern int chan_config_string(struct list_head *chans, char *str, int size,
13655 + char **error_out);
13660 + * Overrides for Emacs so that we follow Linus's tabbing style.
13661 + * Emacs will notice this stuff at the end of the file and automatically
13662 + * adjust the settings for this buffer only. This must remain at the end
13664 + * ---------------------------------------------------------------------------
13665 + * Local variables:
13666 + * c-file-style: "linux"
13669 diff -Naur -X ../exclude-files orig/arch/um/include/chan_user.h um/arch/um/include/chan_user.h
13670 --- orig/arch/um/include/chan_user.h Wed Dec 31 19:00:00 1969
13671 +++ um/arch/um/include/chan_user.h Wed Nov 6 16:44:00 2002
13674 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
13675 + * Licensed under the GPL
13678 +#ifndef __CHAN_USER_H__
13679 +#define __CHAN_USER_H__
13683 +struct chan_opts {
13684 + void (*announce)(char *dev_name, int dev);
13685 + char *xterm_title;
13687 + unsigned long tramp_stack;
13691 +enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE };
13695 + void *(*init)(char *, int, struct chan_opts *);
13696 + int (*open)(int, int, int, void *, char **);
13697 + void (*close)(int, void *);
13698 + int (*read)(int, char *, void *);
13699 + int (*write)(int, const char *, int, void *);
13700 + int (*console_write)(int, const char *, int, void *);
13701 + int (*window_size)(int, void *, unsigned short *, unsigned short *);
13702 + void (*free)(void *);
13706 +extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops,
13709 +extern void generic_close(int fd, void *unused);
13710 +extern int generic_read(int fd, char *c_out, void *unused);
13711 +extern int generic_write(int fd, const char *buf, int n, void *unused);
13712 +extern int generic_console_write(int fd, const char *buf, int n, void *state);
13713 +extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
13714 + unsigned short *cols_out);
13715 +extern void generic_free(void *data);
13717 +extern void register_winch(int fd, void *device_data);
13718 +extern void register_winch_irq(int fd, int tty_fd, int pid, void *line);
13720 +#define __channel_help(fn, prefix) \
13721 +__uml_help(fn, prefix "[0-9]*=<channel description>\n" \
13722 +" Attach a console or serial line to a host channel. See\n" \
13723 +" http://user-mode-linux.sourceforge.net/input.html for a complete\n" \
13724 +" description of this switch.\n\n" \
13730 + * Overrides for Emacs so that we follow Linus's tabbing style.
13731 + * Emacs will notice this stuff at the end of the file and automatically
13732 + * adjust the settings for this buffer only. This must remain at the end
13734 + * ---------------------------------------------------------------------------
13735 + * Local variables:
13736 + * c-file-style: "linux"
13739 diff -Naur -X ../exclude-files orig/arch/um/include/choose-mode.h um/arch/um/include/choose-mode.h
13740 --- orig/arch/um/include/choose-mode.h Wed Dec 31 19:00:00 1969
13741 +++ um/arch/um/include/choose-mode.h Fri Jan 17 13:23:32 2003
13744 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13745 + * Licensed under the GPL
13748 +#ifndef __CHOOSE_MODE_H__
13749 +#define __CHOOSE_MODE_H__
13751 +#include "uml-config.h"
13753 +#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS)
13754 +#define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas))
13756 +#elif defined(UML_CONFIG_MODE_SKAS)
13757 +#define CHOOSE_MODE(tt, skas) (skas)
13759 +#elif defined(UML_CONFIG_MODE_TT)
13760 +#define CHOOSE_MODE(tt, skas) (tt)
13763 +#define CHOOSE_MODE_PROC(tt, skas, args...) \
13764 + CHOOSE_MODE(tt(args), skas(args))
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/frame.h um/arch/um/include/frame.h
13779 --- orig/arch/um/include/frame.h Wed Dec 31 19:00:00 1969
13780 +++ um/arch/um/include/frame.h Mon Dec 2 21:43:03 2002
13783 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13784 + * Licensed under the GPL
13787 +#ifndef __FRAME_H_
13788 +#define __FRAME_H_
13790 +#include "sysdep/frame.h"
13792 +struct frame_common {
13799 + struct arch_frame_data arch;
13803 + struct frame_common common;
13807 +extern struct sc_frame signal_frame_sc;
13809 +extern struct sc_frame signal_frame_sc_sr;
13812 + struct frame_common common;
13819 +extern struct si_frame signal_frame_si;
13821 +extern void capture_signal_stack(void);
13826 + * Overrides for Emacs so that we follow Linus's tabbing style.
13827 + * Emacs will notice this stuff at the end of the file and automatically
13828 + * adjust the settings for this buffer only. This must remain at the end
13830 + * ---------------------------------------------------------------------------
13831 + * Local variables:
13832 + * c-file-style: "linux"
13835 diff -Naur -X ../exclude-files orig/arch/um/include/frame_kern.h um/arch/um/include/frame_kern.h
13836 --- orig/arch/um/include/frame_kern.h Wed Dec 31 19:00:00 1969
13837 +++ um/arch/um/include/frame_kern.h Wed Oct 23 21:08:04 2002
13840 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13841 + * Licensed under the GPL
13844 +#ifndef __FRAME_KERN_H_
13845 +#define __FRAME_KERN_H_
13847 +#include "frame.h"
13848 +#include "sysdep/frame_kern.h"
13850 +extern int setup_signal_stack_sc(unsigned long stack_top, int sig,
13851 + unsigned long handler,
13852 + void (*restorer)(void),
13853 + struct pt_regs *regs,
13855 +extern int setup_signal_stack_si(unsigned long stack_top, int sig,
13856 + unsigned long handler,
13857 + void (*restorer)(void),
13858 + struct pt_regs *regs, siginfo_t *info,
13864 + * Overrides for Emacs so that we follow Linus's tabbing style.
13865 + * Emacs will notice this stuff at the end of the file and automatically
13866 + * adjust the settings for this buffer only. This must remain at the end
13868 + * ---------------------------------------------------------------------------
13869 + * Local variables:
13870 + * c-file-style: "linux"
13873 diff -Naur -X ../exclude-files orig/arch/um/include/frame_user.h um/arch/um/include/frame_user.h
13874 --- orig/arch/um/include/frame_user.h Wed Dec 31 19:00:00 1969
13875 +++ um/arch/um/include/frame_user.h Wed Oct 23 21:08:04 2002
13878 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13879 + * Licensed under the GPL
13882 +#ifndef __FRAME_USER_H_
13883 +#define __FRAME_USER_H_
13885 +#include "sysdep/frame_user.h"
13886 +#include "frame.h"
13891 + * Overrides for Emacs so that we follow Linus's tabbing style.
13892 + * Emacs will notice this stuff at the end of the file and automatically
13893 + * adjust the settings for this buffer only. This must remain at the end
13895 + * ---------------------------------------------------------------------------
13896 + * Local variables:
13897 + * c-file-style: "linux"
13900 diff -Naur -X ../exclude-files orig/arch/um/include/helper.h um/arch/um/include/helper.h
13901 --- orig/arch/um/include/helper.h Wed Dec 31 19:00:00 1969
13902 +++ um/arch/um/include/helper.h Wed Oct 23 21:08:04 2002
13905 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13906 + * Licensed under the GPL
13909 +#ifndef __HELPER_H__
13910 +#define __HELPER_H__
13912 +extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
13913 + unsigned long *stack_out);
13914 +extern int run_helper_thread(int (*proc)(void *), void *arg,
13915 + unsigned int flags, unsigned long *stack_out,
13916 + int stack_order);
13917 +extern int helper_wait(int pid);
13922 + * Overrides for Emacs so that we follow Linus's tabbing style.
13923 + * Emacs will notice this stuff at the end of the file and automatically
13924 + * adjust the settings for this buffer only. This must remain at the end
13926 + * ---------------------------------------------------------------------------
13927 + * Local variables:
13928 + * c-file-style: "linux"
13931 diff -Naur -X ../exclude-files orig/arch/um/include/hostaudio.h um/arch/um/include/hostaudio.h
13932 --- orig/arch/um/include/hostaudio.h Wed Dec 31 19:00:00 1969
13933 +++ um/arch/um/include/hostaudio.h Wed Oct 23 21:08:04 2002
13936 + * Copyright (C) 2002 Steve Schmidtke
13937 + * Licensed under the GPL
13940 +#ifndef HOSTAUDIO_H
13941 +#define HOSTAUDIO_H
13943 +#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
13944 +#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
13946 +struct hostaudio_state {
13950 +struct hostmixer_state {
13954 +/* UML user-side protoypes */
13955 +extern ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer,
13956 + size_t count, loff_t *ppos);
13957 +extern ssize_t hostaudio_write_user(struct hostaudio_state *state,
13958 + const char *buffer, size_t count,
13960 +extern int hostaudio_ioctl_user(struct hostaudio_state *state,
13961 + unsigned int cmd, unsigned long arg);
13962 +extern int hostaudio_open_user(struct hostaudio_state *state, int r, int w,
13964 +extern int hostaudio_release_user(struct hostaudio_state *state);
13965 +extern int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state,
13966 + unsigned int cmd, unsigned long arg);
13967 +extern int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r,
13968 + int w, char *mixer);
13969 +extern int hostmixer_release_mixdev_user(struct hostmixer_state *state);
13971 +#endif /* HOSTAUDIO_H */
13974 + * Overrides for Emacs so that we follow Linus's tabbing style.
13975 + * Emacs will notice this stuff at the end of the file and automatically
13976 + * adjust the settings for this buffer only. This must remain at the end
13978 + * ---------------------------------------------------------------------------
13979 + * Local variables:
13980 + * c-file-style: "linux"
13983 diff -Naur -X ../exclude-files orig/arch/um/include/init.h um/arch/um/include/init.h
13984 --- orig/arch/um/include/init.h Wed Dec 31 19:00:00 1969
13985 +++ um/arch/um/include/init.h Wed Oct 23 21:08:04 2002
13987 +#ifndef _LINUX_UML_INIT_H
13988 +#define _LINUX_UML_INIT_H
13990 +/* These macros are used to mark some functions or
13991 + * initialized data (doesn't apply to uninitialized data)
13992 + * as `initialization' functions. The kernel can take this
13993 + * as hint that the function is used only during the initialization
13994 + * phase and free up used memory resources after
13999 + * You should add __init immediately before the function name, like:
14001 + * static void __init initme(int x, int y)
14003 + * extern int z; z = x * y;
14006 + * If the function has a prototype somewhere, you can also add
14007 + * __init between closing brace of the prototype and semicolon:
14009 + * extern int initialize_foobar_device(int, int, int) __init;
14011 + * For initialized data:
14012 + * You should insert __initdata between the variable name and equal
14013 + * sign followed by value, e.g.:
14015 + * static int init_variable __initdata = 0;
14016 + * static char linux_logo[] __initdata = { 0x32, 0x36, ... };
14018 + * Don't forget to initialize data not at file scope, i.e. within a function,
14019 + * as gcc otherwise puts the data into the bss section and not into the init
14022 + * Also note, that this data cannot be "const".
14025 +#ifndef _LINUX_INIT_H
14026 +typedef int (*initcall_t)(void);
14027 +typedef void (*exitcall_t)(void);
14029 +#define __init __attribute__ ((__section__ (".text.init")))
14030 +#define __exit __attribute__ ((unused, __section__(".text.exit")))
14031 +#define __initdata __attribute__ ((__section__ (".data.init")))
14036 +struct uml_param {
14038 + int (*setup_func)(char *, int *);
14041 +extern initcall_t __uml_initcall_start, __uml_initcall_end;
14042 +extern initcall_t __uml_postsetup_start, __uml_postsetup_end;
14043 +extern const char *__uml_help_start, *__uml_help_end;
14046 +#define __uml_initcall(fn) \
14047 + static initcall_t __uml_initcall_##fn __uml_init_call = fn
14049 +#define __uml_exitcall(fn) \
14050 + static exitcall_t __uml_exitcall_##fn __uml_exit_call = fn
14052 +extern struct uml_param __uml_setup_start, __uml_setup_end;
14054 +#define __uml_postsetup(fn) \
14055 + static initcall_t __uml_postsetup_##fn __uml_postsetup_call = fn
14057 +#define __non_empty_string(dummyname,string) \
14058 + struct __uml_non_empty_string_struct_##dummyname \
14060 + char _string[sizeof(string)-2]; \
14064 +#define __uml_setup(str, fn, help...) \
14065 + __non_empty_string(fn ##_setup, str); \
14066 + __uml_help(fn, help); \
14067 + static char __uml_setup_str_##fn[] __initdata = str; \
14068 + static struct uml_param __uml_setup_##fn __uml_init_setup = { __uml_setup_str_##fn, fn }
14070 +#define __uml_setup(str, fn, help...) \
14074 +#define __uml_help(fn, help...) \
14075 + __non_empty_string(fn ##__help, help); \
14076 + static char __uml_help_str_##fn[] __initdata = help; \
14077 + static const char *__uml_help_##fn __uml_setup_help = __uml_help_str_##fn
14080 + * Mark functions and data as being only used at initialization
14083 +#define __uml_init_setup __attribute__ ((unused,__section__ (".uml.setup.init")))
14084 +#define __uml_setup_help __attribute__ ((unused,__section__ (".uml.help.init")))
14085 +#define __uml_init_call __attribute__ ((unused,__section__ (".uml.initcall.init")))
14086 +#define __uml_postsetup_call __attribute__ ((unused,__section__ (".uml.postsetup.init")))
14087 +#define __uml_exit_call __attribute__ ((unused,__section__ (".uml.exitcall.exit")))
14089 +#endif /* _LINUX_UML_INIT_H */
14092 + * Overrides for Emacs so that we follow Linus's tabbing style.
14093 + * Emacs will notice this stuff at the end of the file and automatically
14094 + * adjust the settings for this buffer only. This must remain at the end
14096 + * ---------------------------------------------------------------------------
14097 + * Local variables:
14098 + * c-file-style: "linux"
14101 diff -Naur -X ../exclude-files orig/arch/um/include/initrd.h um/arch/um/include/initrd.h
14102 --- orig/arch/um/include/initrd.h Wed Dec 31 19:00:00 1969
14103 +++ um/arch/um/include/initrd.h Wed Oct 23 21:08:04 2002
14106 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
14107 + * Licensed under the GPL
14110 +#ifndef __INITRD_USER_H__
14111 +#define __INITRD_USER_H__
14113 +extern int load_initrd(char *filename, void *buf, int size);
14118 + * Overrides for Emacs so that we follow Linus's tabbing style.
14119 + * Emacs will notice this stuff at the end of the file and automatically
14120 + * adjust the settings for this buffer only. This must remain at the end
14122 + * ---------------------------------------------------------------------------
14123 + * Local variables:
14124 + * c-file-style: "linux"
14127 diff -Naur -X ../exclude-files orig/arch/um/include/irq_user.h um/arch/um/include/irq_user.h
14128 --- orig/arch/um/include/irq_user.h Wed Dec 31 19:00:00 1969
14129 +++ um/arch/um/include/irq_user.h Sun Dec 8 20:38:42 2002
14132 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14133 + * Licensed under the GPL
14136 +#ifndef __IRQ_USER_H__
14137 +#define __IRQ_USER_H__
14139 +enum { IRQ_READ, IRQ_WRITE };
14141 +extern void sigio_handler(int sig, union uml_pt_regs *regs);
14142 +extern int activate_fd(int irq, int fd, int type, void *dev_id);
14143 +extern void free_irq_by_irq_and_dev(int irq, void *dev_id);
14144 +extern void free_irq_by_fd(int fd);
14145 +extern void reactivate_fd(int fd, int irqnum);
14146 +extern void deactivate_fd(int fd, int irqnum);
14147 +extern void forward_interrupts(int pid);
14148 +extern void init_irq_signals(int on_sigstack);
14149 +extern void forward_ipi(int fd, int pid);
14150 +extern void free_irq_later(int irq, void *dev_id);
14151 +extern int activate_ipi(int fd, int pid);
14152 +extern unsigned long irq_lock(void);
14153 +extern void irq_unlock(unsigned long flags);
14157 + * Overrides for Emacs so that we follow Linus's tabbing style.
14158 + * Emacs will notice this stuff at the end of the file and automatically
14159 + * adjust the settings for this buffer only. This must remain at the end
14161 + * ---------------------------------------------------------------------------
14162 + * Local variables:
14163 + * c-file-style: "linux"
14166 diff -Naur -X ../exclude-files orig/arch/um/include/kern.h um/arch/um/include/kern.h
14167 --- orig/arch/um/include/kern.h Wed Dec 31 19:00:00 1969
14168 +++ um/arch/um/include/kern.h Sat Nov 2 21:38:02 2002
14171 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
14172 + * Licensed under the GPL
14175 +#ifndef __KERN_H__
14176 +#define __KERN_H__
14178 +/* These are all user-mode things which are convenient to call directly
14179 + * from kernel code and for which writing a wrapper is too much of a pain.
14180 + * The regular include files can't be included because this file is included
14181 + * only into kernel code, and user-space includes conflict with kernel
14187 +extern int clone(int (*proc)(void *), void *sp, int flags, void *data);
14188 +extern int sleep(int);
14189 +extern int printf(char *fmt, ...);
14190 +extern char *strerror(int errnum);
14191 +extern char *ptsname(int __fd);
14192 +extern int munmap(void *, int);
14193 +extern void *sbrk(int increment);
14194 +extern void *malloc(int size);
14195 +extern void perror(char *err);
14196 +extern int kill(int pid, int sig);
14197 +extern int getuid(void);
14198 +extern int pause(void);
14199 +extern int write(int, const void *, int);
14200 +extern int exit(int);
14201 +extern int close(int);
14202 +extern int read(unsigned int, char *, int);
14203 +extern int pipe(int *);
14204 +extern int sched_yield(void);
14205 +extern int ptrace(int op, int pid, long addr, long data);
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/kern_util.h um/arch/um/include/kern_util.h
14219 --- orig/arch/um/include/kern_util.h Wed Dec 31 19:00:00 1969
14220 +++ um/arch/um/include/kern_util.h Wed Apr 16 16:00:11 2003
14223 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
14224 + * Licensed under the GPL
14227 +#ifndef __KERN_UTIL_H__
14228 +#define __KERN_UTIL_H__
14230 +#include "sysdep/ptrace.h"
14233 +extern char *linux_prog;
14234 +extern char *gdb_init;
14235 +extern int kmalloc_ok;
14236 +extern int timer_irq_inited;
14238 +extern int nsyscalls;
14240 +#define UML_ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK))
14241 +#define UML_ROUND_UP(addr) \
14242 + UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
14244 +extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg);
14245 +extern unsigned long stack_sp(unsigned long page);
14246 +extern int kernel_thread_proc(void *data);
14247 +extern void syscall_segv(int sig);
14248 +extern int current_pid(void);
14249 +extern unsigned long alloc_stack(int order, int atomic);
14250 +extern int do_signal(int error);
14251 +extern int is_stack_fault(unsigned long sp);
14252 +extern unsigned long segv(unsigned long address, unsigned long ip,
14253 + int is_write, int is_user, void *sc);
14254 +extern unsigned long handle_page_fault(unsigned long address, unsigned long ip,
14255 + int is_write, int is_user,
14257 +extern void syscall_ready(void);
14258 +extern int segv_syscall(void);
14259 +extern void kern_finish_exec(void *task, int new_pid, unsigned long stack);
14260 +extern int page_size(void);
14261 +extern int page_mask(void);
14262 +extern int need_finish_fork(void);
14263 +extern void free_stack(unsigned long stack, int order);
14264 +extern void add_input_request(int op, void (*proc)(int), void *arg);
14265 +extern int sys_execve(char *file, char **argv, char **env);
14266 +extern char *current_cmd(void);
14267 +extern void timer_handler(int sig, union uml_pt_regs *regs);
14268 +extern int set_signals(int enable);
14269 +extern void force_sigbus(void);
14270 +extern int pid_to_processor_id(int pid);
14271 +extern void block_signals(void);
14272 +extern void unblock_signals(void);
14273 +extern void deliver_signals(void *t);
14274 +extern int next_syscall_index(int max);
14275 +extern int next_trap_index(int max);
14276 +extern void cpu_idle(void);
14277 +extern void finish_fork(void);
14278 +extern void paging_init(void);
14279 +extern void init_flush_vm(void);
14280 +extern void *syscall_sp(void *t);
14281 +extern void syscall_trace(void);
14282 +extern int hz(void);
14283 +extern void idle_timer(void);
14284 +extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
14285 +extern int external_pid(void *t);
14286 +extern void boot_timer_handler(int sig);
14287 +extern void interrupt_end(void);
14288 +extern void initial_thread_cb(void (*proc)(void *), void *arg);
14289 +extern int debugger_signal(int status, int pid);
14290 +extern void debugger_parent_signal(int status, int pid);
14291 +extern void child_signal(int pid, int status);
14292 +extern int init_ptrace_proxy(int idle_pid, int startup, int stop);
14293 +extern int init_parent_proxy(int pid);
14294 +extern void check_stack_overflow(void *ptr);
14295 +extern void relay_signal(int sig, union uml_pt_regs *regs);
14296 +extern void not_implemented(void);
14297 +extern int user_context(unsigned long sp);
14298 +extern void timer_irq(union uml_pt_regs *regs);
14299 +extern void unprotect_stack(unsigned long stack);
14300 +extern void do_uml_exitcalls(void);
14301 +extern int attach_debugger(int idle_pid, int pid, int stop);
14302 +extern void bad_segv(unsigned long address, unsigned long ip, int is_write);
14303 +extern int config_gdb(char *str);
14304 +extern int remove_gdb(void);
14305 +extern char *uml_strdup(char *string);
14306 +extern void unprotect_kernel_mem(void);
14307 +extern void protect_kernel_mem(void);
14308 +extern void set_kmem_end(unsigned long);
14309 +extern void uml_cleanup(void);
14310 +extern void set_current(void *t);
14311 +extern void lock_signalled_task(void *t);
14312 +extern void IPI_handler(int cpu);
14313 +extern int jail_setup(char *line, int *add);
14314 +extern void *get_init_task(void);
14315 +extern int clear_user_proc(void *buf, int size);
14316 +extern int copy_to_user_proc(void *to, void *from, int size);
14317 +extern int copy_from_user_proc(void *to, void *from, int size);
14318 +extern int strlen_user_proc(char *str);
14319 +extern void bus_handler(int sig, union uml_pt_regs *regs);
14320 +extern void winch(int sig, union uml_pt_regs *regs);
14321 +extern long execute_syscall(void *r);
14322 +extern int smp_sigio_handler(void);
14323 +extern void *get_current(void);
14324 +extern struct task_struct *get_task(int pid, int require);
14325 +extern void machine_halt(void);
14326 +extern int is_syscall(unsigned long addr);
14327 +extern void arch_switch(void);
14328 +extern void free_irq(unsigned int, void *);
14329 +extern int um_in_interrupt(void);
14330 +extern int cpu(void);
14334 + * Overrides for Emacs so that we follow Linus's tabbing style.
14335 + * Emacs will notice this stuff at the end of the file and automatically
14336 + * adjust the settings for this buffer only. This must remain at the end
14338 + * ---------------------------------------------------------------------------
14339 + * Local variables:
14340 + * c-file-style: "linux"
14343 diff -Naur -X ../exclude-files orig/arch/um/include/line.h um/arch/um/include/line.h
14344 --- orig/arch/um/include/line.h Wed Dec 31 19:00:00 1969
14345 +++ um/arch/um/include/line.h Fri Nov 15 13:44:44 2002
14348 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14349 + * Licensed under the GPL
14352 +#ifndef __LINE_H__
14353 +#define __LINE_H__
14355 +#include "linux/list.h"
14356 +#include "linux/tqueue.h"
14357 +#include "linux/tty.h"
14358 +#include "asm/semaphore.h"
14359 +#include "chan_user.h"
14360 +#include "mconsole_kern.h"
14362 +struct line_driver {
14364 + char *devfs_name;
14366 + short minor_start;
14370 + char *read_irq_name;
14372 + char *write_irq_name;
14373 + char *symlink_from;
14374 + char *symlink_to;
14375 + struct mc_device mc;
14381 + struct list_head chan_list;
14384 + struct tty_struct *tty;
14385 + struct semaphore sem;
14390 + struct tq_struct task;
14391 + struct line_driver *driver;
14395 +#define LINE_INIT(str, d) \
14396 + { init_str : str, \
14397 + init_pri : INIT_STATIC, \
14398 + chan_list : { }, \
14414 +#define LINES_INIT(n) { num : n }
14416 +extern void line_interrupt(int irq, void *data, struct pt_regs *unused);
14417 +extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
14418 +extern void line_close(struct line *lines, struct tty_struct *tty);
14419 +extern int line_open(struct line *lines, struct tty_struct *tty,
14420 + struct chan_opts *opts);
14421 +extern int line_setup(struct line *lines, int num, char *init,
14422 + int all_allowed);
14423 +extern int line_write(struct line *line, struct tty_struct *tty, int from_user,
14424 + const char *buf, int len);
14425 +extern int line_write_room(struct tty_struct *tty);
14426 +extern char *add_xterm_umid(char *base);
14427 +extern int line_setup_irq(int fd, int input, int output, void *data);
14428 +extern void line_close_chan(struct line *line);
14429 +extern void line_disable(struct line *line, int current_irq);
14430 +extern void line_register_devfs(struct lines *set,
14431 + struct line_driver *line_driver,
14432 + struct tty_driver *driver, struct line *lines,
14434 +extern void lines_init(struct line *lines, int nlines);
14435 +extern void close_lines(struct line *lines, int nlines);
14436 +extern int line_config(struct line *lines, int num, char *str);
14437 +extern int line_remove(struct line *lines, int num, char *str);
14438 +extern int line_get_config(char *dev, struct line *lines, int num, char *str,
14439 + int size, char **error_out);
14444 + * Overrides for Emacs so that we follow Linus's tabbing style.
14445 + * Emacs will notice this stuff at the end of the file and automatically
14446 + * adjust the settings for this buffer only. This must remain at the end
14448 + * ---------------------------------------------------------------------------
14449 + * Local variables:
14450 + * c-file-style: "linux"
14453 diff -Naur -X ../exclude-files orig/arch/um/include/mconsole.h um/arch/um/include/mconsole.h
14454 --- orig/arch/um/include/mconsole.h Wed Dec 31 19:00:00 1969
14455 +++ um/arch/um/include/mconsole.h Fri Jan 17 13:48:25 2003
14458 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
14459 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14460 + * Licensed under the GPL
14463 +#ifndef __MCONSOLE_H__
14464 +#define __MCONSOLE_H__
14466 +#ifndef __KERNEL__
14467 +#include <stdint.h>
14468 +#define u32 uint32_t
14471 +#define MCONSOLE_MAGIC (0xcafebabe)
14472 +#define MCONSOLE_MAX_DATA (512)
14473 +#define MCONSOLE_VERSION 2
14475 +struct mconsole_request {
14479 + char data[MCONSOLE_MAX_DATA];
14482 +struct mconsole_reply {
14486 + char data[MCONSOLE_MAX_DATA];
14489 +struct mconsole_notify {
14492 + enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
14493 + MCONSOLE_USER_NOTIFY } type;
14495 + char data[MCONSOLE_MAX_DATA];
14498 +struct mc_request;
14500 +struct mconsole_command
14503 + void (*handler)(struct mc_request *req);
14504 + int as_interrupt;
14510 + int as_interrupt;
14512 + int originating_fd;
14514 + unsigned char origin[128]; /* sockaddr_un */
14516 + struct mconsole_request request;
14517 + struct mconsole_command *cmd;
14520 +extern char mconsole_socket_name[];
14522 +extern int mconsole_unlink_socket(void);
14523 +extern int mconsole_reply(struct mc_request *req, char *reply, int err,
14526 +extern void mconsole_version(struct mc_request *req);
14527 +extern void mconsole_help(struct mc_request *req);
14528 +extern void mconsole_halt(struct mc_request *req);
14529 +extern void mconsole_reboot(struct mc_request *req);
14530 +extern void mconsole_config(struct mc_request *req);
14531 +extern void mconsole_remove(struct mc_request *req);
14532 +extern void mconsole_sysrq(struct mc_request *req);
14533 +extern void mconsole_cad(struct mc_request *req);
14534 +extern void mconsole_stop(struct mc_request *req);
14535 +extern void mconsole_go(struct mc_request *req);
14537 +extern int mconsole_get_request(int fd, struct mc_request *req);
14538 +extern int mconsole_notify(char *sock_name, int type, const void *data,
14540 +extern char *mconsole_notify_socket(void);
14541 +extern void lock_notify(void);
14542 +extern void unlock_notify(void);
14547 + * Overrides for Emacs so that we follow Linus's tabbing style.
14548 + * Emacs will notice this stuff at the end of the file and automatically
14549 + * adjust the settings for this buffer only. This must remain at the end
14551 + * ---------------------------------------------------------------------------
14552 + * Local variables:
14553 + * c-file-style: "linux"
14556 diff -Naur -X ../exclude-files orig/arch/um/include/mconsole_kern.h um/arch/um/include/mconsole_kern.h
14557 --- orig/arch/um/include/mconsole_kern.h Wed Dec 31 19:00:00 1969
14558 +++ um/arch/um/include/mconsole_kern.h Fri Nov 15 15:21:58 2002
14561 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14562 + * Licensed under the GPL
14565 +#ifndef __MCONSOLE_KERN_H__
14566 +#define __MCONSOLE_KERN_H__
14568 +#include "linux/config.h"
14569 +#include "linux/list.h"
14570 +#include "mconsole.h"
14572 +struct mconsole_entry {
14573 + struct list_head list;
14574 + struct mc_request request;
14577 +struct mc_device {
14578 + struct list_head list;
14580 + int (*config)(char *);
14581 + int (*get_config)(char *, char *, int, char **);
14582 + int (*remove)(char *);
14585 +#define CONFIG_CHUNK(str, size, current, chunk, end) \
14587 + current += strlen(chunk); \
14588 + if(current >= size) \
14590 + if(str != NULL){ \
14591 + strcpy(str, chunk); \
14592 + str += strlen(chunk); \
14598 +#ifdef CONFIG_MCONSOLE
14600 +extern void mconsole_register_dev(struct mc_device *new);
14604 +static inline void mconsole_register_dev(struct mc_device *new)
14613 + * Overrides for Emacs so that we follow Linus's tabbing style.
14614 + * Emacs will notice this stuff at the end of the file and automatically
14615 + * adjust the settings for this buffer only. This must remain at the end
14617 + * ---------------------------------------------------------------------------
14618 + * Local variables:
14619 + * c-file-style: "linux"
14622 diff -Naur -X ../exclude-files orig/arch/um/include/mem.h um/arch/um/include/mem.h
14623 --- orig/arch/um/include/mem.h Wed Dec 31 19:00:00 1969
14624 +++ um/arch/um/include/mem.h Wed Oct 23 21:08:04 2002
14627 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14628 + * Licensed under the GPL
14634 +struct vm_reserved {
14635 + struct list_head list;
14636 + unsigned long start;
14637 + unsigned long end;
14640 +extern void set_usable_vm(unsigned long start, unsigned long end);
14641 +extern void set_kmem_end(unsigned long new);
14646 + * Overrides for Emacs so that we follow Linus's tabbing style.
14647 + * Emacs will notice this stuff at the end of the file and automatically
14648 + * adjust the settings for this buffer only. This must remain at the end
14650 + * ---------------------------------------------------------------------------
14651 + * Local variables:
14652 + * c-file-style: "linux"
14655 diff -Naur -X ../exclude-files orig/arch/um/include/mem_user.h um/arch/um/include/mem_user.h
14656 --- orig/arch/um/include/mem_user.h Wed Dec 31 19:00:00 1969
14657 +++ um/arch/um/include/mem_user.h Wed Oct 23 21:08:04 2002
14660 + * arch/um/include/mem_user.h
14662 + * BRIEF MODULE DESCRIPTION
14663 + * user side memory interface for support IO memory inside user mode linux
14665 + * Copyright (C) 2001 RidgeRun, Inc.
14666 + * Author: RidgeRun, Inc.
14667 + * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
14669 + * This program is free software; you can redistribute it and/or modify it
14670 + * under the terms of the GNU General Public License as published by the
14671 + * Free Software Foundation; either version 2 of the License, or (at your
14672 + * option) any later version.
14674 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
14675 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14676 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
14677 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
14678 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
14679 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
14680 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
14681 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14682 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
14683 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14685 + * You should have received a copy of the GNU General Public License along
14686 + * with this program; if not, write to the Free Software Foundation, Inc.,
14687 + * 675 Mass Ave, Cambridge, MA 02139, USA.
14690 +#ifndef _MEM_USER_H
14691 +#define _MEM_USER_H
14693 +struct mem_region {
14695 + unsigned long start_pfn;
14696 + unsigned long start;
14697 + unsigned long len;
14702 +extern struct mem_region *regions[];
14703 +extern struct mem_region physmem_region;
14705 +#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
14707 +extern unsigned long host_task_size;
14708 +extern unsigned long task_size;
14710 +extern int init_mem_user(void);
14711 +extern int create_mem_file(unsigned long len);
14712 +extern void setup_range(int fd, char *driver, unsigned long start,
14713 + unsigned long pfn, unsigned long total, int need_vm,
14714 + struct mem_region *region, void *reserved);
14715 +extern void setup_memory(void *entry);
14716 +extern unsigned long find_iomem(char *driver, unsigned long *len_out);
14717 +extern int init_maps(struct mem_region *region);
14718 +extern int nregions(void);
14719 +extern int reserve_vm(unsigned long start, unsigned long end, void *e);
14720 +extern unsigned long get_vm(unsigned long len);
14721 +extern void setup_physmem(unsigned long start, unsigned long usable,
14722 + unsigned long len);
14723 +extern int setup_region(struct mem_region *region, void *entry);
14724 +extern void add_iomem(char *name, int fd, unsigned long size);
14725 +extern struct mem_region *phys_region(unsigned long phys);
14726 +extern unsigned long phys_offset(unsigned long phys);
14727 +extern void unmap_physmem(void);
14728 +extern int map_memory(unsigned long virt, unsigned long phys,
14729 + unsigned long len, int r, int w, int x);
14730 +extern int protect_memory(unsigned long addr, unsigned long len,
14731 + int r, int w, int x, int must_succeed);
14732 +extern unsigned long get_kmem_end(void);
14737 + * Overrides for Emacs so that we follow Linus's tabbing style.
14738 + * Emacs will notice this stuff at the end of the file and automatically
14739 + * adjust the settings for this buffer only. This must remain at the end
14741 + * ---------------------------------------------------------------------------
14742 + * Local variables:
14743 + * c-file-style: "linux"
14746 diff -Naur -X ../exclude-files orig/arch/um/include/mode.h um/arch/um/include/mode.h
14747 --- orig/arch/um/include/mode.h Wed Dec 31 19:00:00 1969
14748 +++ um/arch/um/include/mode.h Fri Jan 17 13:23:32 2003
14751 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14752 + * Licensed under the GPL
14755 +#ifndef __MODE_H__
14756 +#define __MODE_H__
14758 +#include "uml-config.h"
14760 +#ifdef UML_CONFIG_MODE_TT
14761 +#include "../kernel/tt/include/mode.h"
14764 +#ifdef UML_CONFIG_MODE_SKAS
14765 +#include "../kernel/skas/include/mode.h"
14771 + * Overrides for Emacs so that we follow Linus's tabbing style.
14772 + * Emacs will notice this stuff at the end of the file and automatically
14773 + * adjust the settings for this buffer only. This must remain at the end
14775 + * ---------------------------------------------------------------------------
14776 + * Local variables:
14777 + * c-file-style: "linux"
14780 diff -Naur -X ../exclude-files orig/arch/um/include/mode_kern.h um/arch/um/include/mode_kern.h
14781 --- orig/arch/um/include/mode_kern.h Wed Dec 31 19:00:00 1969
14782 +++ um/arch/um/include/mode_kern.h Wed Oct 23 21:08:04 2002
14785 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14786 + * Licensed under the GPL
14789 +#ifndef __MODE_KERN_H__
14790 +#define __MODE_KERN_H__
14792 +#include "linux/config.h"
14794 +#ifdef CONFIG_MODE_TT
14795 +#include "../kernel/tt/include/mode_kern.h"
14798 +#ifdef CONFIG_MODE_SKAS
14799 +#include "../kernel/skas/include/mode_kern.h"
14805 + * Overrides for Emacs so that we follow Linus's tabbing style.
14806 + * Emacs will notice this stuff at the end of the file and automatically
14807 + * adjust the settings for this buffer only. This must remain at the end
14809 + * ---------------------------------------------------------------------------
14810 + * Local variables:
14811 + * c-file-style: "linux"
14814 diff -Naur -X ../exclude-files orig/arch/um/include/net_kern.h um/arch/um/include/net_kern.h
14815 --- orig/arch/um/include/net_kern.h Wed Dec 31 19:00:00 1969
14816 +++ um/arch/um/include/net_kern.h Wed Oct 23 21:08:04 2002
14819 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14820 + * Licensed under the GPL
14823 +#ifndef __UM_NET_KERN_H
14824 +#define __UM_NET_KERN_H
14826 +#include "linux/netdevice.h"
14827 +#include "linux/skbuff.h"
14828 +#include "linux/socket.h"
14829 +#include "linux/list.h"
14832 + struct list_head list;
14833 + struct net_device *dev;
14835 + unsigned char mac[ETH_ALEN];
14839 +struct uml_net_private {
14840 + struct list_head list;
14842 + struct net_device *dev;
14843 + struct timer_list tl;
14844 + struct net_device_stats stats;
14846 + unsigned char mac[ETH_ALEN];
14848 + unsigned short (*protocol)(struct sk_buff *);
14849 + int (*open)(void *);
14850 + void (*close)(int, void *);
14851 + void (*remove)(void *);
14852 + int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
14853 + int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
14855 + void (*add_address)(unsigned char *, unsigned char *, void *);
14856 + void (*delete_address)(unsigned char *, unsigned char *, void *);
14857 + int (*set_mtu)(int mtu, void *);
14861 +struct net_kern_info {
14862 + void (*init)(struct net_device *, void *);
14863 + unsigned short (*protocol)(struct sk_buff *);
14864 + int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
14865 + int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
14868 +struct transport {
14869 + struct list_head list;
14871 + int (*setup)(char *, char **, void *);
14872 + struct net_user_info *user;
14873 + struct net_kern_info *kern;
14874 + int private_size;
14878 +extern struct net_device *ether_init(int);
14879 +extern unsigned short ether_protocol(struct sk_buff *);
14880 +extern int setup_etheraddr(char *str, unsigned char *addr);
14881 +extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
14882 +extern int tap_setup_common(char *str, char *type, char **dev_name,
14883 + char **mac_out, char **gate_addr);
14884 +extern void register_transport(struct transport *new);
14885 +extern unsigned short eth_protocol(struct sk_buff *skb);
14890 + * Overrides for Emacs so that we follow Linus's tabbing style.
14891 + * Emacs will notice this stuff at the end of the file and automatically
14892 + * adjust the settings for this buffer only. This must remain at the end
14894 + * ---------------------------------------------------------------------------
14895 + * Local variables:
14896 + * c-file-style: "linux"
14899 diff -Naur -X ../exclude-files orig/arch/um/include/net_user.h um/arch/um/include/net_user.h
14900 --- orig/arch/um/include/net_user.h Wed Dec 31 19:00:00 1969
14901 +++ um/arch/um/include/net_user.h Wed Oct 23 21:08:04 2002
14904 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14905 + * Licensed under the GPL
14908 +#ifndef __UM_NET_USER_H__
14909 +#define __UM_NET_USER_H__
14911 +#define ETH_ADDR_LEN (6)
14912 +#define ETH_HEADER_ETHERTAP (16)
14913 +#define ETH_HEADER_OTHER (14)
14914 +#define ETH_MAX_PACKET (1500)
14916 +#define UML_NET_VERSION (4)
14918 +struct net_user_info {
14919 + void (*init)(void *, void *);
14920 + int (*open)(void *);
14921 + void (*close)(int, void *);
14922 + void (*remove)(void *);
14923 + int (*set_mtu)(int mtu, void *);
14924 + void (*add_address)(unsigned char *, unsigned char *, void *);
14925 + void (*delete_address)(unsigned char *, unsigned char *, void *);
14929 +extern void ether_user_init(void *data, void *dev);
14930 +extern void dev_ip_addr(void *d, char *buf, char *bin_buf);
14931 +extern void set_ether_mac(void *d, unsigned char *addr);
14932 +extern void iter_addresses(void *d, void (*cb)(unsigned char *,
14933 + unsigned char *, void *),
14936 +extern void *get_output_buffer(int *len_out);
14937 +extern void free_output_buffer(void *buffer);
14939 +extern int tap_open_common(void *dev, char *gate_addr);
14940 +extern void tap_check_ips(char *gate_addr, char *eth_addr);
14942 +extern void read_output(int fd, char *output_out, int len);
14944 +extern int net_read(int fd, void *buf, int len);
14945 +extern int net_recvfrom(int fd, void *buf, int len);
14946 +extern int net_write(int fd, void *buf, int len);
14947 +extern int net_send(int fd, void *buf, int len);
14948 +extern int net_sendto(int fd, void *buf, int len, void *to, int sock_len);
14950 +extern void open_addr(unsigned char *addr, unsigned char *netmask, void *arg);
14951 +extern void close_addr(unsigned char *addr, unsigned char *netmask, void *arg);
14953 +extern char *split_if_spec(char *str, ...);
14955 +extern int dev_netmask(void *d, void *m);
14960 + * Overrides for Emacs so that we follow Linus's tabbing style.
14961 + * Emacs will notice this stuff at the end of the file and automatically
14962 + * adjust the settings for this buffer only. This must remain at the end
14964 + * ---------------------------------------------------------------------------
14965 + * Local variables:
14966 + * c-file-style: "linux"
14969 diff -Naur -X ../exclude-files orig/arch/um/include/os.h um/arch/um/include/os.h
14970 --- orig/arch/um/include/os.h Wed Dec 31 19:00:00 1969
14971 +++ um/arch/um/include/os.h Tue Feb 4 19:11:32 2003
14974 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14975 + * Licensed under the GPL
14981 +#include "asm/types.h"
14982 +#include "../os/include/file.h"
14984 +#define OS_TYPE_FILE 1
14985 +#define OS_TYPE_DIR 2
14986 +#define OS_TYPE_SYMLINK 3
14987 +#define OS_TYPE_CHARDEV 4
14988 +#define OS_TYPE_BLOCKDEV 5
14989 +#define OS_TYPE_FIFO 6
14990 +#define OS_TYPE_SOCK 7
14992 +struct openflags {
14993 + unsigned int r : 1;
14994 + unsigned int w : 1;
14995 + unsigned int s : 1; /* O_SYNC */
14996 + unsigned int c : 1; /* O_CREAT */
14997 + unsigned int t : 1; /* O_TRUNC */
14998 + unsigned int a : 1; /* O_APPEND */
14999 + unsigned int e : 1; /* O_EXCL */
15000 + unsigned int cl : 1; /* FD_CLOEXEC */
15003 +#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
15004 + .t = 0, .a = 0, .e = 0, .cl = 0 })
15006 +static inline struct openflags of_read(struct openflags flags)
15012 +static inline struct openflags of_write(struct openflags flags)
15018 +static inline struct openflags of_rdwr(struct openflags flags)
15020 + return(of_read(of_write(flags)));
15023 +static inline struct openflags of_set_rw(struct openflags flags, int r, int w)
15030 +static inline struct openflags of_sync(struct openflags flags)
15036 +static inline struct openflags of_create(struct openflags flags)
15042 +static inline struct openflags of_trunc(struct openflags flags)
15048 +static inline struct openflags of_append(struct openflags flags)
15054 +static inline struct openflags of_excl(struct openflags flags)
15060 +static inline struct openflags of_cloexec(struct openflags flags)
15066 +extern int os_seek_file(int fd, __u64 offset);
15067 +extern int os_open_file(char *file, struct openflags flags, int mode);
15068 +extern int os_read_file(int fd, void *buf, int len);
15069 +extern int os_write_file(int fd, void *buf, int count);
15070 +extern int os_file_size(char *file, long long *size_out);
15071 +extern int os_pipe(int *fd, int stream, int close_on_exec);
15072 +extern int os_set_fd_async(int fd, int owner);
15073 +extern int os_set_fd_block(int fd, int blocking);
15074 +extern int os_accept_connection(int fd);
15075 +extern int os_shutdown_socket(int fd, int r, int w);
15076 +extern void os_close_file(int fd);
15077 +extern int os_rcv_fd(int fd, int *helper_pid_out);
15078 +extern int create_unix_socket(char *file, int len);
15079 +extern int os_connect_socket(char *name);
15080 +extern int os_file_type(char *file);
15081 +extern int os_file_mode(char *file, struct openflags *mode_out);
15082 +extern int os_lock_file(int fd, int excl);
15084 +extern unsigned long os_process_pc(int pid);
15085 +extern int os_process_parent(int pid);
15086 +extern void os_stop_process(int pid);
15087 +extern void os_kill_process(int pid, int reap_child);
15088 +extern void os_usr1_process(int pid);
15089 +extern int os_getpid(void);
15091 +extern int os_map_memory(void *virt, int fd, unsigned long off,
15092 + unsigned long len, int r, int w, int x);
15093 +extern int os_protect_memory(void *addr, unsigned long len,
15094 + int r, int w, int x);
15095 +extern int os_unmap_memory(void *addr, int len);
15096 +extern void os_flush_stdout(void);
15101 + * Overrides for Emacs so that we follow Linus's tabbing style.
15102 + * Emacs will notice this stuff at the end of the file and automatically
15103 + * adjust the settings for this buffer only. This must remain at the end
15105 + * ---------------------------------------------------------------------------
15106 + * Local variables:
15107 + * c-file-style: "linux"
15110 diff -Naur -X ../exclude-files orig/arch/um/include/process.h um/arch/um/include/process.h
15111 --- orig/arch/um/include/process.h Wed Dec 31 19:00:00 1969
15112 +++ um/arch/um/include/process.h Wed Oct 23 21:08:04 2002
15115 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
15116 + * Licensed under the GPL
15119 +#ifndef __PROCESS_H__
15120 +#define __PROCESS_H__
15122 +#include <asm/sigcontext.h>
15124 +extern void sig_handler(int sig, struct sigcontext sc);
15125 +extern void alarm_handler(int sig, struct sigcontext sc);
15130 + * Overrides for Emacs so that we follow Linus's tabbing style.
15131 + * Emacs will notice this stuff at the end of the file and automatically
15132 + * adjust the settings for this buffer only. This must remain at the end
15134 + * ---------------------------------------------------------------------------
15135 + * Local variables:
15136 + * c-file-style: "linux"
15139 diff -Naur -X ../exclude-files orig/arch/um/include/ptrace_user.h um/arch/um/include/ptrace_user.h
15140 --- orig/arch/um/include/ptrace_user.h Wed Dec 31 19:00:00 1969
15141 +++ um/arch/um/include/ptrace_user.h Wed Oct 23 21:08:04 2002
15144 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
15145 + * Licensed under the GPL
15148 +#ifndef __PTRACE_USER_H__
15149 +#define __PTRACE_USER_H__
15151 +#include "sysdep/ptrace_user.h"
15153 +extern int ptrace_getregs(long pid, unsigned long *regs_out);
15154 +extern int ptrace_setregs(long pid, unsigned long *regs_in);
15155 +extern int ptrace_getfpregs(long pid, unsigned long *regs_out);
15156 +extern void arch_enter_kernel(void *task, int pid);
15157 +extern void arch_leave_kernel(void *task, int pid);
15158 +extern void ptrace_pokeuser(unsigned long addr, unsigned long data);
15161 diff -Naur -X ../exclude-files orig/arch/um/include/sigcontext.h um/arch/um/include/sigcontext.h
15162 --- orig/arch/um/include/sigcontext.h Wed Dec 31 19:00:00 1969
15163 +++ um/arch/um/include/sigcontext.h Wed Oct 23 21:08:04 2002
15166 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15167 + * Licensed under the GPL
15170 +#ifndef __UML_SIGCONTEXT_H__
15171 +#define __UML_SIGCONTEXT_H__
15173 +#include "sysdep/sigcontext.h"
15175 +extern int sc_size(void *data);
15176 +extern void sc_to_sc(void *to_ptr, void *from_ptr);
15181 + * Overrides for Emacs so that we follow Linus's tabbing style.
15182 + * Emacs will notice this stuff at the end of the file and automatically
15183 + * adjust the settings for this buffer only. This must remain at the end
15185 + * ---------------------------------------------------------------------------
15186 + * Local variables:
15187 + * c-file-style: "linux"
15190 diff -Naur -X ../exclude-files orig/arch/um/include/sigio.h um/arch/um/include/sigio.h
15191 --- orig/arch/um/include/sigio.h Wed Dec 31 19:00:00 1969
15192 +++ um/arch/um/include/sigio.h Wed Oct 23 21:08:04 2002
15195 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15196 + * Licensed under the GPL
15199 +#ifndef __SIGIO_H__
15200 +#define __SIGIO_H__
15202 +extern int write_sigio_irq(int fd);
15203 +extern int register_sigio_fd(int fd);
15204 +extern int read_sigio_fd(int fd);
15205 +extern int add_sigio_fd(int fd, int read);
15206 +extern int ignore_sigio_fd(int fd);
15207 +extern void sigio_lock(void);
15208 +extern void sigio_unlock(void);
15213 + * Overrides for Emacs so that we follow Linus's tabbing style.
15214 + * Emacs will notice this stuff at the end of the file and automatically
15215 + * adjust the settings for this buffer only. This must remain at the end
15217 + * ---------------------------------------------------------------------------
15218 + * Local variables:
15219 + * c-file-style: "linux"
15222 diff -Naur -X ../exclude-files orig/arch/um/include/signal_kern.h um/arch/um/include/signal_kern.h
15223 --- orig/arch/um/include/signal_kern.h Wed Dec 31 19:00:00 1969
15224 +++ um/arch/um/include/signal_kern.h Thu Dec 5 18:08:47 2002
15227 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15228 + * Licensed under the GPL
15231 +#ifndef __SIGNAL_KERN_H__
15232 +#define __SIGNAL_KERN_H__
15234 +extern int have_signals(void *t);
15239 + * Overrides for Emacs so that we follow Linus's tabbing style.
15240 + * Emacs will notice this stuff at the end of the file and automatically
15241 + * adjust the settings for this buffer only. This must remain at the end
15243 + * ---------------------------------------------------------------------------
15244 + * Local variables:
15245 + * c-file-style: "linux"
15248 diff -Naur -X ../exclude-files orig/arch/um/include/signal_user.h um/arch/um/include/signal_user.h
15249 --- orig/arch/um/include/signal_user.h Wed Dec 31 19:00:00 1969
15250 +++ um/arch/um/include/signal_user.h Wed Oct 23 21:08:04 2002
15253 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
15254 + * Licensed under the GPL
15257 +#ifndef __SIGNAL_USER_H__
15258 +#define __SIGNAL_USER_H__
15260 +extern int signal_stack_size;
15262 +extern int change_sig(int signal, int on);
15263 +extern void set_sigstack(void *stack, int size);
15264 +extern void set_handler(int sig, void (*handler)(int), int flags, ...);
15269 + * Overrides for Emacs so that we follow Linus's tabbing style.
15270 + * Emacs will notice this stuff at the end of the file and automatically
15271 + * adjust the settings for this buffer only. This must remain at the end
15273 + * ---------------------------------------------------------------------------
15274 + * Local variables:
15275 + * c-file-style: "linux"
15278 diff -Naur -X ../exclude-files orig/arch/um/include/skas_ptrace.h um/arch/um/include/skas_ptrace.h
15279 --- orig/arch/um/include/skas_ptrace.h Wed Dec 31 19:00:00 1969
15280 +++ um/arch/um/include/skas_ptrace.h Mon Dec 16 11:54:52 2002
15283 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
15284 + * Licensed under the GPL
15287 +#ifndef __SKAS_PTRACE_H
15288 +#define __SKAS_PTRACE_H
15290 +struct ptrace_faultinfo {
15292 + unsigned long addr;
15295 +struct ptrace_ldt {
15298 + unsigned long bytecount;
15301 +#define PTRACE_FAULTINFO 52
15302 +#define PTRACE_SIGPENDING 53
15303 +#define PTRACE_LDT 54
15304 +#define PTRACE_SWITCH_MM 55
15309 + * Overrides for Emacs so that we follow Linus's tabbing style.
15310 + * Emacs will notice this stuff at the end of the file and automatically
15311 + * adjust the settings for this buffer only. This must remain at the end
15313 + * ---------------------------------------------------------------------------
15314 + * Local variables:
15315 + * c-file-style: "linux"
15318 diff -Naur -X ../exclude-files orig/arch/um/include/syscall_user.h um/arch/um/include/syscall_user.h
15319 --- orig/arch/um/include/syscall_user.h Wed Dec 31 19:00:00 1969
15320 +++ um/arch/um/include/syscall_user.h Wed Oct 23 21:08:04 2002
15323 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15324 + * Licensed under the GPL
15327 +#ifndef __SYSCALL_USER_H
15328 +#define __SYSCALL_USER_H
15330 +extern int record_syscall_start(int syscall);
15331 +extern void record_syscall_end(int index, int result);
15336 + * Overrides for Emacs so that we follow Linus's tabbing style.
15337 + * Emacs will notice this stuff at the end of the file and automatically
15338 + * adjust the settings for this buffer only. This must remain at the end
15340 + * ---------------------------------------------------------------------------
15341 + * Local variables:
15342 + * c-file-style: "linux"
15345 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/checksum.h um/arch/um/include/sysdep-i386/checksum.h
15346 --- orig/arch/um/include/sysdep-i386/checksum.h Wed Dec 31 19:00:00 1969
15347 +++ um/arch/um/include/sysdep-i386/checksum.h Tue Oct 29 21:23:02 2002
15350 + * Licensed under the GPL
15353 +#ifndef __UM_SYSDEP_CHECKSUM_H
15354 +#define __UM_SYSDEP_CHECKSUM_H
15356 +#include "linux/string.h"
15359 + * computes the checksum of a memory block at buff, length len,
15360 + * and adds in "sum" (32-bit)
15362 + * returns a 32-bit number suitable for feeding into itself
15363 + * or csum_tcpudp_magic
15365 + * this function must be called with even lengths, except
15366 + * for the last fragment, which may be odd
15368 + * it's best to have buff aligned on a 32-bit boundary
15370 +unsigned int csum_partial(const unsigned char * buff, int len,
15371 + unsigned int sum);
15374 + * the same as csum_partial, but copies from src while it
15375 + * checksums, and handles user-space pointer exceptions correctly, when needed.
15377 + * here even more important to align src and dst on a 32-bit (or even
15378 + * better 64-bit) boundary
15381 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len,
15382 + int sum, int *err_ptr);
15383 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len,
15384 + int sum, int *err_ptr);
15387 + * Note: when you get a NULL pointer exception here this means someone
15388 + * passed in an incorrect kernel address to one of these functions.
15390 + * If you use these functions directly please don't forget the
15395 +unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
15396 + int len, int sum)
15398 + memcpy(dst, src, len);
15399 + return(csum_partial(dst, len, sum));
15403 +unsigned int csum_partial_copy_from_user(const char *src, char *dst,
15404 + int len, int sum, int *err_ptr)
15406 + return csum_partial_copy_from(src, dst, len, sum, err_ptr);
15410 + * These are the old (and unsafe) way of doing checksums, a warning message
15411 + * will be printed if they are used and an exeption occurs.
15413 + * these functions should go away after some time.
15416 +#define csum_partial_copy_fromuser csum_partial_copy_from_user
15417 +unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
15420 + * This is a version of ip_compute_csum() optimized for IP headers,
15421 + * which always checksum on 4 octet boundaries.
15423 + * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
15424 + * Arnt Gulbrandsen.
15426 +static inline unsigned short ip_fast_csum(unsigned char * iph,
15427 + unsigned int ihl)
15429 + unsigned int sum;
15431 + __asm__ __volatile__(
15432 + "movl (%1), %0 ;\n"
15433 + "subl $4, %2 ;\n"
15435 + "addl 4(%1), %0 ;\n"
15436 + "adcl 8(%1), %0 ;\n"
15437 + "adcl 12(%1), %0 ;\n"
15438 +"1: adcl 16(%1), %0 ;\n"
15439 + "lea 4(%1), %1 ;\n"
15442 + "adcl $0, %0 ;\n"
15443 + "movl %0, %2 ;\n"
15444 + "shrl $16, %0 ;\n"
15445 + "addw %w2, %w0 ;\n"
15446 + "adcl $0, %0 ;\n"
15449 + /* Since the input registers which are loaded with iph and ipl
15450 + are modified, we must also specify them as outputs, or gcc
15451 + will assume they contain their original values. */
15452 + : "=r" (sum), "=r" (iph), "=r" (ihl)
15453 + : "1" (iph), "2" (ihl));
15458 + * Fold a partial checksum
15461 +static inline unsigned int csum_fold(unsigned int sum)
15464 + "addl %1, %0 ;\n"
15465 + "adcl $0xffff, %0 ;\n"
15467 + : "r" (sum << 16), "0" (sum & 0xffff0000)
15469 + return (~sum) >> 16;
15472 +static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
15473 + unsigned long daddr,
15474 + unsigned short len,
15475 + unsigned short proto,
15476 + unsigned int sum)
15479 + "addl %1, %0 ;\n"
15480 + "adcl %2, %0 ;\n"
15481 + "adcl %3, %0 ;\n"
15482 + "adcl $0, %0 ;\n"
15484 + : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum));
15489 + * computes the checksum of the TCP/UDP pseudo-header
15490 + * returns a 16-bit checksum, already complemented
15492 +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
15493 + unsigned long daddr,
15494 + unsigned short len,
15495 + unsigned short proto,
15496 + unsigned int sum)
15498 + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
15502 + * this routine is used for miscellaneous IP-like checksums, mainly
15506 +static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
15508 + return csum_fold (csum_partial(buff, len, 0));
15511 +#define _HAVE_ARCH_IPV6_CSUM
15512 +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
15513 + struct in6_addr *daddr,
15515 + unsigned short proto,
15516 + unsigned int sum)
15519 + "addl 0(%1), %0 ;\n"
15520 + "adcl 4(%1), %0 ;\n"
15521 + "adcl 8(%1), %0 ;\n"
15522 + "adcl 12(%1), %0 ;\n"
15523 + "adcl 0(%2), %0 ;\n"
15524 + "adcl 4(%2), %0 ;\n"
15525 + "adcl 8(%2), %0 ;\n"
15526 + "adcl 12(%2), %0 ;\n"
15527 + "adcl %3, %0 ;\n"
15528 + "adcl %4, %0 ;\n"
15529 + "adcl $0, %0 ;\n"
15531 + : "r" (saddr), "r" (daddr),
15532 + "r"(htonl(len)), "r"(htonl(proto)), "0"(sum));
15534 + return csum_fold(sum);
15538 + * Copy and checksum to user
15540 +#define HAVE_CSUM_COPY_USER
15541 +static __inline__ unsigned int csum_and_copy_to_user(const char *src,
15542 + char *dst, int len,
15543 + int sum, int *err_ptr)
15545 + if (access_ok(VERIFY_WRITE, dst, len))
15546 + return(csum_partial_copy_to(src, dst, len, sum, err_ptr));
15549 + *err_ptr = -EFAULT;
15551 + return -1; /* invalid checksum */
15557 + * Overrides for Emacs so that we follow Linus's tabbing style.
15558 + * Emacs will notice this stuff at the end of the file and automatically
15559 + * adjust the settings for this buffer only. This must remain at the end
15561 + * ---------------------------------------------------------------------------
15562 + * Local variables:
15563 + * c-file-style: "linux"
15566 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame.h um/arch/um/include/sysdep-i386/frame.h
15567 --- orig/arch/um/include/sysdep-i386/frame.h Wed Dec 31 19:00:00 1969
15568 +++ um/arch/um/include/sysdep-i386/frame.h Fri Dec 6 14:07:54 2002
15571 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15572 + * Licensed under the GPL
15575 +#ifndef __FRAME_I386_H
15576 +#define __FRAME_I386_H
15578 +struct arch_frame_data_raw {
15579 + unsigned long fp_start;
15580 + unsigned long sr;
15583 +struct arch_frame_data {
15584 + int fpstate_size;
15590 + * Overrides for Emacs so that we follow Linus's tabbing style.
15591 + * Emacs will notice this stuff at the end of the file and automatically
15592 + * adjust the settings for this buffer only. This must remain at the end
15594 + * ---------------------------------------------------------------------------
15595 + * Local variables:
15596 + * c-file-style: "linux"
15599 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_kern.h um/arch/um/include/sysdep-i386/frame_kern.h
15600 --- orig/arch/um/include/sysdep-i386/frame_kern.h Wed Dec 31 19:00:00 1969
15601 +++ um/arch/um/include/sysdep-i386/frame_kern.h Mon Dec 2 21:45:04 2002
15604 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15605 + * Licensed under the GPL
15608 +#ifndef __FRAME_KERN_I386_H
15609 +#define __FRAME_KERN_I386_H
15611 +/* This is called from sys_sigreturn. It takes the sp at the point of the
15612 + * sigreturn system call and returns the address of the sigcontext struct
15616 +static inline void *sp_to_sc(unsigned long sp)
15618 + return((void *) sp);
15621 +static inline void *sp_to_uc(unsigned long sp)
15623 + unsigned long uc;
15625 + uc = sp + signal_frame_si.uc_index -
15626 + signal_frame_si.common.sp_index - 4;
15627 + return((void *) uc);
15630 +static inline void *sp_to_rt_sc(unsigned long sp)
15632 + unsigned long sc;
15634 + sc = sp - signal_frame_si.common.sp_index +
15635 + signal_frame_si.common.len - 4;
15636 + return((void *) sc);
15639 +static inline void *sp_to_mask(unsigned long sp)
15641 + unsigned long mask;
15643 + mask = sp - signal_frame_sc.common.sp_index +
15644 + signal_frame_sc.common.len - 8;
15645 + return((void *) mask);
15648 +extern int sc_size(void *data);
15650 +static inline void *sp_to_rt_mask(unsigned long sp)
15652 + unsigned long mask;
15654 + mask = sp - signal_frame_si.common.sp_index +
15655 + signal_frame_si.common.len +
15656 + sc_size(&signal_frame_si.common.arch) - 4;
15657 + return((void *) mask);
15663 + * Overrides for Emacs so that we follow Linus's tabbing style.
15664 + * Emacs will notice this stuff at the end of the file and automatically
15665 + * adjust the settings for this buffer only. This must remain at the end
15667 + * ---------------------------------------------------------------------------
15668 + * Local variables:
15669 + * c-file-style: "linux"
15672 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_user.h um/arch/um/include/sysdep-i386/frame_user.h
15673 --- orig/arch/um/include/sysdep-i386/frame_user.h Wed Dec 31 19:00:00 1969
15674 +++ um/arch/um/include/sysdep-i386/frame_user.h Fri Dec 6 14:13:59 2002
15677 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15678 + * Licensed under the GPL
15681 +#ifndef __FRAME_USER_I386_H
15682 +#define __FRAME_USER_I386_H
15684 +#include <asm/page.h>
15685 +#include "sysdep/frame.h"
15687 +/* This stuff is to calculate the size of the fp state struct at runtime
15688 + * because it has changed between 2.2 and 2.4 and it would be good for a
15689 + * UML compiled on one to work on the other.
15690 + * So, setup_arch_frame_raw fills in the arch struct with the raw data, which
15691 + * just contains the address of the end of the sigcontext. This is invoked
15692 + * from the signal handler.
15693 + * setup_arch_frame uses that data to figure out what
15694 + * arch_frame_data.fpstate_size should be. It really has no idea, since it's
15695 + * not allowed to do sizeof(struct fpstate) but it's safe to consider that it's
15696 + * everything from the end of the sigcontext up to the top of the stack. So,
15697 + * it masks off the page number to get the offset within the page and subtracts
15698 + * that from the page size, and that's how big the fpstate struct will be
15699 + * considered to be.
15702 +static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data,
15703 + void *end, unsigned long srp)
15705 + unsigned long sr = *((unsigned long *) srp);
15707 + data->fp_start = (unsigned long) end;
15708 + if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK))
15710 + else data->sr = 0;
15713 +static inline void setup_arch_frame(struct arch_frame_data_raw *in,
15714 + struct arch_frame_data *out)
15716 + unsigned long fpstate_start = in->fp_start;
15719 + fpstate_start &= ~PAGE_MASK;
15720 + out->fpstate_size = PAGE_SIZE - fpstate_start;
15723 + out->fpstate_size = in->sr - fpstate_start;
15727 +/* This figures out where on the stack the SA_RESTORER function address
15728 + * is stored. For i386, it's the signal handler return address, so it's
15729 + * located next to the frame pointer.
15730 + * This is inlined, so __builtin_frame_address(0) is correct. Otherwise,
15731 + * it would have to be __builtin_frame_address(1).
15734 +static inline unsigned long frame_restorer(void)
15736 + unsigned long *fp;
15738 + fp = __builtin_frame_address(0);
15739 + return((unsigned long) (fp + 1));
15742 +/* Similarly, this returns the value of sp when the handler was first
15743 + * entered. This is used to calculate the proper sp when delivering
15747 +static inline unsigned long frame_sp(void)
15749 + unsigned long *fp;
15751 + fp = __builtin_frame_address(0);
15752 + return((unsigned long) (fp + 1));
15758 + * Overrides for Emacs so that we follow Linus's tabbing style.
15759 + * Emacs will notice this stuff at the end of the file and automatically
15760 + * adjust the settings for this buffer only. This must remain at the end
15762 + * ---------------------------------------------------------------------------
15763 + * Local variables:
15764 + * c-file-style: "linux"
15767 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace.h um/arch/um/include/sysdep-i386/ptrace.h
15768 --- orig/arch/um/include/sysdep-i386/ptrace.h Wed Dec 31 19:00:00 1969
15769 +++ um/arch/um/include/sysdep-i386/ptrace.h Fri Jan 17 13:23:31 2003
15772 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
15773 + * Licensed under the GPL
15776 +#ifndef __SYSDEP_I386_PTRACE_H
15777 +#define __SYSDEP_I386_PTRACE_H
15779 +#include "uml-config.h"
15781 +#ifdef UML_CONFIG_MODE_TT
15782 +#include "ptrace-tt.h"
15785 +#ifdef UML_CONFIG_MODE_SKAS
15786 +#include "ptrace-skas.h"
15789 +#include "choose-mode.h"
15791 +union uml_pt_regs {
15792 +#ifdef UML_CONFIG_MODE_TT
15798 +#ifdef UML_CONFIG_MODE_SKAS
15799 + struct skas_regs {
15800 + unsigned long regs[HOST_FRAME_SIZE];
15801 + unsigned long fp[HOST_FP_SIZE];
15802 + unsigned long xfp[HOST_XFP_SIZE];
15803 + unsigned long fault_addr;
15804 + unsigned long fault_type;
15805 + unsigned long trap_type;
15812 +#define EMPTY_UML_PT_REGS { }
15814 +extern int mode_tt;
15816 +#define UPT_SC(r) ((r)->tt.sc)
15817 +#define UPT_IP(r) \
15818 + CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
15819 +#define UPT_SP(r) \
15820 + CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
15821 +#define UPT_EFLAGS(r) \
15822 + CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
15823 +#define UPT_EAX(r) \
15824 + CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs))
15825 +#define UPT_EBX(r) \
15826 + CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs))
15827 +#define UPT_ECX(r) \
15828 + CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs))
15829 +#define UPT_EDX(r) \
15830 + CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs))
15831 +#define UPT_ESI(r) \
15832 + CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs))
15833 +#define UPT_EDI(r) \
15834 + CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs))
15835 +#define UPT_EBP(r) \
15836 + CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs))
15837 +#define UPT_ORIG_EAX(r) \
15838 + CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
15839 +#define UPT_CS(r) \
15840 + CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
15841 +#define UPT_SS(r) \
15842 + CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs))
15843 +#define UPT_DS(r) \
15844 + CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
15845 +#define UPT_ES(r) \
15846 + CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
15847 +#define UPT_FS(r) \
15848 + CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
15849 +#define UPT_GS(r) \
15850 + CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
15852 +#define UPT_SYSCALL_ARG1(r) UPT_EBX(r)
15853 +#define UPT_SYSCALL_ARG2(r) UPT_ECX(r)
15854 +#define UPT_SYSCALL_ARG3(r) UPT_EDX(r)
15855 +#define UPT_SYSCALL_ARG4(r) UPT_ESI(r)
15856 +#define UPT_SYSCALL_ARG5(r) UPT_EDI(r)
15857 +#define UPT_SYSCALL_ARG6(r) UPT_EBP(r)
15859 +extern int user_context(unsigned long sp);
15861 +#define UPT_IS_USER(r) \
15862 + CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
15864 +struct syscall_args {
15865 + unsigned long args[6];
15868 +#define SYSCALL_ARGS(r) ((struct syscall_args) \
15869 + { .args = { UPT_SYSCALL_ARG1(r), \
15870 + UPT_SYSCALL_ARG2(r), \
15871 + UPT_SYSCALL_ARG3(r), \
15872 + UPT_SYSCALL_ARG4(r), \
15873 + UPT_SYSCALL_ARG5(r), \
15874 + UPT_SYSCALL_ARG6(r) } } )
15876 +#define UPT_REG(regs, reg) \
15877 + ({ unsigned long val; \
15879 + case EIP: val = UPT_IP(regs); break; \
15880 + case UESP: val = UPT_SP(regs); break; \
15881 + case EAX: val = UPT_EAX(regs); break; \
15882 + case EBX: val = UPT_EBX(regs); break; \
15883 + case ECX: val = UPT_ECX(regs); break; \
15884 + case EDX: val = UPT_EDX(regs); break; \
15885 + case ESI: val = UPT_ESI(regs); break; \
15886 + case EDI: val = UPT_EDI(regs); break; \
15887 + case EBP: val = UPT_EBP(regs); break; \
15888 + case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \
15889 + case CS: val = UPT_CS(regs); break; \
15890 + case SS: val = UPT_SS(regs); break; \
15891 + case DS: val = UPT_DS(regs); break; \
15892 + case ES: val = UPT_ES(regs); break; \
15893 + case FS: val = UPT_FS(regs); break; \
15894 + case GS: val = UPT_GS(regs); break; \
15895 + case EFL: val = UPT_EFLAGS(regs); break; \
15897 + panic("Bad register in UPT_REG : %d\n", reg); \
15904 +#define UPT_SET(regs, reg, val) \
15907 + case EIP: UPT_IP(regs) = val; break; \
15908 + case UESP: UPT_SP(regs) = val; break; \
15909 + case EAX: UPT_EAX(regs) = val; break; \
15910 + case EBX: UPT_EBX(regs) = val; break; \
15911 + case ECX: UPT_ECX(regs) = val; break; \
15912 + case EDX: UPT_EDX(regs) = val; break; \
15913 + case ESI: UPT_ESI(regs) = val; break; \
15914 + case EDI: UPT_EDI(regs) = val; break; \
15915 + case EBP: UPT_EBP(regs) = val; break; \
15916 + case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \
15917 + case CS: UPT_CS(regs) = val; break; \
15918 + case SS: UPT_SS(regs) = val; break; \
15919 + case DS: UPT_DS(regs) = val; break; \
15920 + case ES: UPT_ES(regs) = val; break; \
15921 + case FS: UPT_FS(regs) = val; break; \
15922 + case GS: UPT_GS(regs) = val; break; \
15923 + case EFL: UPT_EFLAGS(regs) = val; break; \
15925 + panic("Bad register in UPT_SET : %d\n", reg); \
15930 +#define UPT_SET_SYSCALL_RETURN(r, res) \
15931 + CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \
15932 + REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
15934 +#define UPT_RESTART_SYSCALL(r) \
15935 + CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
15936 + REGS_RESTART_SYSCALL((r)->skas.regs))
15938 +#define UPT_ORIG_SYSCALL(r) UPT_EAX(r)
15939 +#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
15940 +#define UPT_SYSCALL_RET(r) UPT_EAX(r)
15942 +#define UPT_SEGV_IS_FIXABLE(r) \
15943 + CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
15944 + REGS_SEGV_IS_FIXABLE(&r->skas))
15946 +#define UPT_FAULT_ADDR(r) \
15947 + CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
15949 +#define UPT_FAULT_WRITE(r) \
15950 + CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
15955 + * Overrides for Emacs so that we follow Linus's tabbing style.
15956 + * Emacs will notice this stuff at the end of the file and automatically
15957 + * adjust the settings for this buffer only. This must remain at the end
15959 + * ---------------------------------------------------------------------------
15960 + * Local variables:
15961 + * c-file-style: "linux"
15964 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace_user.h um/arch/um/include/sysdep-i386/ptrace_user.h
15965 --- orig/arch/um/include/sysdep-i386/ptrace_user.h Wed Dec 31 19:00:00 1969
15966 +++ um/arch/um/include/sysdep-i386/ptrace_user.h Wed Oct 23 21:08:04 2002
15969 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15970 + * Licensed under the GPL
15973 +#ifndef __SYSDEP_I386_PTRACE_USER_H__
15974 +#define __SYSDEP_I386_PTRACE_USER_H__
15976 +#include <asm/ptrace.h>
15978 +#define PT_OFFSET(r) ((r) * sizeof(long))
15980 +#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX])
15981 +#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX)
15983 +#define PT_SYSCALL_ARG1_OFFSET PT_OFFSET(EBX)
15984 +#define PT_SYSCALL_ARG2_OFFSET PT_OFFSET(ECX)
15985 +#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX)
15986 +#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI)
15987 +#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI)
15989 +#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX)
15991 +#define PT_IP_OFFSET PT_OFFSET(EIP)
15992 +#define PT_IP(regs) ((regs)[EIP])
15993 +#define PT_SP(regs) ((regs)[UESP])
15995 +#ifndef FRAME_SIZE
15996 +#define FRAME_SIZE (17)
15998 +#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long))
16000 +#define FP_FRAME_SIZE (27)
16001 +#define FPX_FRAME_SIZE (128)
16003 +#ifdef PTRACE_GETREGS
16004 +#define UM_HAVE_GETREGS
16007 +#ifdef PTRACE_SETREGS
16008 +#define UM_HAVE_SETREGS
16011 +#ifdef PTRACE_GETFPREGS
16012 +#define UM_HAVE_GETFPREGS
16015 +#ifdef PTRACE_SETFPREGS
16016 +#define UM_HAVE_SETFPREGS
16019 +#ifdef PTRACE_GETFPXREGS
16020 +#define UM_HAVE_GETFPXREGS
16023 +#ifdef PTRACE_SETFPXREGS
16024 +#define UM_HAVE_SETFPXREGS
16027 +extern void update_debugregs(int seq);
16030 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/sigcontext.h um/arch/um/include/sysdep-i386/sigcontext.h
16031 --- orig/arch/um/include/sysdep-i386/sigcontext.h Wed Dec 31 19:00:00 1969
16032 +++ um/arch/um/include/sysdep-i386/sigcontext.h Sun Dec 8 18:21:33 2002
16035 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16036 + * Licensed under the GPL
16039 +#ifndef __SYS_SIGCONTEXT_I386_H
16040 +#define __SYS_SIGCONTEXT_I386_H
16044 +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
16046 +#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
16047 +#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
16049 +#define SC_FAULT_ADDR(sc) SC_CR2(sc)
16050 +#define SC_FAULT_TYPE(sc) SC_ERR(sc)
16052 +#define FAULT_WRITE(err) (err & 2)
16053 +#define TO_SC_ERR(is_write) ((is_write) ? 2 : 0)
16055 +#define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc)))
16057 +#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
16059 +/* ptrace expects that, at the start of a system call, %eax contains
16060 + * -ENOSYS, so this makes it so.
16062 +#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
16064 +/* These are General Protection and Page Fault */
16065 +#define SEGV_IS_FIXABLE(trap) ((trap == 13) || (trap == 14))
16067 +#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
16069 +extern unsigned long *sc_sigmask(void *sc_ptr);
16070 +extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
16074 + * Overrides for Emacs so that we follow Linus's tabbing style.
16075 + * Emacs will notice this stuff at the end of the file and automatically
16076 + * adjust the settings for this buffer only. This must remain at the end
16078 + * ---------------------------------------------------------------------------
16079 + * Local variables:
16080 + * c-file-style: "linux"
16083 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/syscalls.h um/arch/um/include/sysdep-i386/syscalls.h
16084 --- orig/arch/um/include/sysdep-i386/syscalls.h Wed Dec 31 19:00:00 1969
16085 +++ um/arch/um/include/sysdep-i386/syscalls.h Sun Dec 8 18:04:15 2002
16088 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16089 + * Licensed under the GPL
16092 +#include "asm/unistd.h"
16093 +#include "sysdep/ptrace.h"
16095 +typedef long syscall_handler_t(struct pt_regs);
16097 +#define EXECUTE_SYSCALL(syscall, regs) \
16098 + ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs))
16100 +extern syscall_handler_t sys_modify_ldt;
16101 +extern syscall_handler_t old_mmap_i386;
16102 +extern syscall_handler_t old_select;
16103 +extern syscall_handler_t sys_ni_syscall;
16105 +#define ARCH_SYSCALLS \
16106 + [ __NR_mmap ] = old_mmap_i386, \
16107 + [ __NR_select ] = old_select, \
16108 + [ __NR_vm86old ] = sys_ni_syscall, \
16109 + [ __NR_modify_ldt ] = sys_modify_ldt, \
16110 + [ __NR_lchown32 ] = sys_lchown, \
16111 + [ __NR_getuid32 ] = sys_getuid, \
16112 + [ __NR_getgid32 ] = sys_getgid, \
16113 + [ __NR_geteuid32 ] = sys_geteuid, \
16114 + [ __NR_getegid32 ] = sys_getegid, \
16115 + [ __NR_setreuid32 ] = sys_setreuid, \
16116 + [ __NR_setregid32 ] = sys_setregid, \
16117 + [ __NR_getgroups32 ] = sys_getgroups, \
16118 + [ __NR_setgroups32 ] = sys_setgroups, \
16119 + [ __NR_fchown32 ] = sys_fchown, \
16120 + [ __NR_setresuid32 ] = sys_setresuid, \
16121 + [ __NR_getresuid32 ] = sys_getresuid, \
16122 + [ __NR_setresgid32 ] = sys_setresgid, \
16123 + [ __NR_getresgid32 ] = sys_getresgid, \
16124 + [ __NR_chown32 ] = sys_chown, \
16125 + [ __NR_setuid32 ] = sys_setuid, \
16126 + [ __NR_setgid32 ] = sys_setgid, \
16127 + [ __NR_setfsuid32 ] = sys_setfsuid, \
16128 + [ __NR_setfsgid32 ] = sys_setfsgid, \
16129 + [ __NR_pivot_root ] = sys_pivot_root, \
16130 + [ __NR_mincore ] = sys_mincore, \
16131 + [ __NR_madvise ] = sys_madvise, \
16132 + [ 222 ] = sys_ni_syscall,
16134 +/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
16136 +#define LAST_ARCH_SYSCALL 222
16139 + * Overrides for Emacs so that we follow Linus's tabbing style.
16140 + * Emacs will notice this stuff at the end of the file and automatically
16141 + * adjust the settings for this buffer only. This must remain at the end
16143 + * ---------------------------------------------------------------------------
16144 + * Local variables:
16145 + * c-file-style: "linux"
16148 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/ptrace.h um/arch/um/include/sysdep-ia64/ptrace.h
16149 --- orig/arch/um/include/sysdep-ia64/ptrace.h Wed Dec 31 19:00:00 1969
16150 +++ um/arch/um/include/sysdep-ia64/ptrace.h Wed Oct 23 21:08:04 2002
16153 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16154 + * Licensed under the GPL
16157 +#ifndef __SYSDEP_IA64_PTRACE_H
16158 +#define __SYSDEP_IA64_PTRACE_H
16160 +struct sys_pt_regs {
16164 +#define EMPTY_REGS { 0 }
16169 + * Overrides for Emacs so that we follow Linus's tabbing style.
16170 + * Emacs will notice this stuff at the end of the file and automatically
16171 + * adjust the settings for this buffer only. This must remain at the end
16173 + * ---------------------------------------------------------------------------
16174 + * Local variables:
16175 + * c-file-style: "linux"
16178 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/sigcontext.h um/arch/um/include/sysdep-ia64/sigcontext.h
16179 --- orig/arch/um/include/sysdep-ia64/sigcontext.h Wed Dec 31 19:00:00 1969
16180 +++ um/arch/um/include/sysdep-ia64/sigcontext.h Wed Oct 23 21:08:04 2002
16183 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16184 + * Licensed under the GPL
16187 +#ifndef __SYSDEP_IA64_SIGCONTEXT_H
16188 +#define __SYSDEP_IA64_SIGCONTEXT_H
16193 + * Overrides for Emacs so that we follow Linus's tabbing style.
16194 + * Emacs will notice this stuff at the end of the file and automatically
16195 + * adjust the settings for this buffer only. This must remain at the end
16197 + * ---------------------------------------------------------------------------
16198 + * Local variables:
16199 + * c-file-style: "linux"
16202 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/syscalls.h um/arch/um/include/sysdep-ia64/syscalls.h
16203 --- orig/arch/um/include/sysdep-ia64/syscalls.h Wed Dec 31 19:00:00 1969
16204 +++ um/arch/um/include/sysdep-ia64/syscalls.h Wed Oct 23 21:08:04 2002
16207 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16208 + * Licensed under the GPL
16211 +#ifndef __SYSDEP_IA64_SYSCALLS_H
16212 +#define __SYSDEP_IA64_SYSCALLS_H
16217 + * Overrides for Emacs so that we follow Linus's tabbing style.
16218 + * Emacs will notice this stuff at the end of the file and automatically
16219 + * adjust the settings for this buffer only. This must remain at the end
16221 + * ---------------------------------------------------------------------------
16222 + * Local variables:
16223 + * c-file-style: "linux"
16226 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/ptrace.h um/arch/um/include/sysdep-ppc/ptrace.h
16227 --- orig/arch/um/include/sysdep-ppc/ptrace.h Wed Dec 31 19:00:00 1969
16228 +++ um/arch/um/include/sysdep-ppc/ptrace.h Wed Oct 23 21:08:04 2002
16231 + * Licensed under the GPL
16234 +#ifndef __SYS_PTRACE_PPC_H
16235 +#define __SYS_PTRACE_PPC_H
16237 +#include "linux/config.h"
16238 +#include "linux/types.h"
16240 +/* the following taken from <asm-ppc/ptrace.h> */
16242 +#ifdef CONFIG_PPC64
16243 +#define PPC_REG unsigned long /*long*/
16245 +#define PPC_REG unsigned long
16247 +struct sys_pt_regs_s {
16251 + PPC_REG orig_gpr3; /* Used for restarting system calls */
16256 + PPC_REG mq; /* 601 only (not used at present) */
16257 + /* Used on APUS to hold IPL value. */
16258 + PPC_REG trap; /* Reason for being here */
16259 + PPC_REG dar; /* Fault registers */
16261 + PPC_REG result; /* Result of a system call */
16264 +#define NUM_REGS (sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG))
16266 +struct sys_pt_regs {
16267 + PPC_REG regs[sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG)];
16270 +#define UM_MAX_REG (PT_FPR0)
16271 +#define UM_MAX_REG_OFFSET (UM_MAX_REG * sizeof(PPC_REG))
16273 +#define EMPTY_REGS { { [ 0 ... NUM_REGS - 1] = 0 } }
16275 +#define UM_REG(r, n) ((r)->regs[n])
16277 +#define UM_SYSCALL_RET(r) UM_REG(r, PT_R3)
16278 +#define UM_SP(r) UM_REG(r, PT_R1)
16279 +#define UM_IP(r) UM_REG(r, PT_NIP)
16280 +#define UM_ELF_ZERO(r) UM_REG(r, PT_FPSCR)
16281 +#define UM_SYSCALL_NR(r) UM_REG(r, PT_R0)
16282 +#define UM_SYSCALL_ARG1(r) UM_REG(r, PT_ORIG_R3)
16283 +#define UM_SYSCALL_ARG2(r) UM_REG(r, PT_R4)
16284 +#define UM_SYSCALL_ARG3(r) UM_REG(r, PT_R5)
16285 +#define UM_SYSCALL_ARG4(r) UM_REG(r, PT_R6)
16286 +#define UM_SYSCALL_ARG5(r) UM_REG(r, PT_R7)
16287 +#define UM_SYSCALL_ARG6(r) UM_REG(r, PT_R8)
16289 +#define UM_SYSCALL_NR_OFFSET (PT_R0 * sizeof(PPC_REG))
16290 +#define UM_SYSCALL_RET_OFFSET (PT_R3 * sizeof(PPC_REG))
16291 +#define UM_SYSCALL_ARG1_OFFSET (PT_R3 * sizeof(PPC_REG))
16292 +#define UM_SYSCALL_ARG2_OFFSET (PT_R4 * sizeof(PPC_REG))
16293 +#define UM_SYSCALL_ARG3_OFFSET (PT_R5 * sizeof(PPC_REG))
16294 +#define UM_SYSCALL_ARG4_OFFSET (PT_R6 * sizeof(PPC_REG))
16295 +#define UM_SYSCALL_ARG5_OFFSET (PT_R7 * sizeof(PPC_REG))
16296 +#define UM_SYSCALL_ARG6_OFFSET (PT_R8 * sizeof(PPC_REG))
16297 +#define UM_SP_OFFSET (PT_R1 * sizeof(PPC_REG))
16298 +#define UM_IP_OFFSET (PT_NIP * sizeof(PPC_REG))
16299 +#define UM_ELF_ZERO_OFFSET (PT_R3 * sizeof(PPC_REG))
16301 +#define UM_SET_SYSCALL_RETURN(_regs, result) \
16303 + if (result < 0) { \
16304 + (_regs)->regs[PT_CCR] |= 0x10000000; \
16305 + UM_SYSCALL_RET((_regs)) = -result; \
16307 + UM_SYSCALL_RET((_regs)) = result; \
16311 +extern void shove_aux_table(unsigned long sp);
16312 +#define UM_FIX_EXEC_STACK(sp) shove_aux_table(sp);
16314 +/* These aren't actually defined. The undefs are just to make sure
16315 + * everyone's clear on the concept.
16317 +#undef UML_HAVE_GETREGS
16318 +#undef UML_HAVE_GETFPREGS
16319 +#undef UML_HAVE_SETREGS
16320 +#undef UML_HAVE_SETFPREGS
16325 + * Overrides for Emacs so that we follow Linus's tabbing style.
16326 + * Emacs will notice this stuff at the end of the file and automatically
16327 + * adjust the settings for this buffer only. This must remain at the end
16329 + * ---------------------------------------------------------------------------
16330 + * Local variables:
16331 + * c-file-style: "linux"
16334 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/sigcontext.h um/arch/um/include/sysdep-ppc/sigcontext.h
16335 --- orig/arch/um/include/sysdep-ppc/sigcontext.h Wed Dec 31 19:00:00 1969
16336 +++ um/arch/um/include/sysdep-ppc/sigcontext.h Sat Nov 23 22:02:19 2002
16339 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16340 + * Licensed under the GPL
16343 +#ifndef __SYS_SIGCONTEXT_PPC_H
16344 +#define __SYS_SIGCONTEXT_PPC_H
16346 +#define DSISR_WRITE 0x02000000
16348 +#define SC_FAULT_ADDR(sc) ({ \
16349 + struct sigcontext *_sc = (sc); \
16350 + long retval = -1; \
16351 + switch (_sc->regs->trap) { \
16353 + /* data exception */ \
16354 + retval = _sc->regs->dar; \
16357 + /* instruction exception */ \
16358 + retval = _sc->regs->nip; \
16361 + panic("SC_FAULT_ADDR: unhandled trap type\n"); \
16366 +#define SC_FAULT_WRITE(sc) ({ \
16367 + struct sigcontext *_sc = (sc); \
16368 + long retval = -1; \
16369 + switch (_sc->regs->trap) { \
16371 + /* data exception */ \
16372 + retval = !!(_sc->regs->dsisr & DSISR_WRITE); \
16375 + /* instruction exception: not a write */ \
16379 + panic("SC_FAULT_ADDR: unhandled trap type\n"); \
16384 +#define SC_IP(sc) ((sc)->regs->nip)
16385 +#define SC_SP(sc) ((sc)->regs->gpr[1])
16386 +#define SEGV_IS_FIXABLE(sc) (1)
16391 + * Overrides for Emacs so that we follow Linus's tabbing style.
16392 + * Emacs will notice this stuff at the end of the file and automatically
16393 + * adjust the settings for this buffer only. This must remain at the end
16395 + * ---------------------------------------------------------------------------
16396 + * Local variables:
16397 + * c-file-style: "linux"
16400 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/syscalls.h um/arch/um/include/sysdep-ppc/syscalls.h
16401 --- orig/arch/um/include/sysdep-ppc/syscalls.h Wed Dec 31 19:00:00 1969
16402 +++ um/arch/um/include/sysdep-ppc/syscalls.h Wed Oct 23 21:08:04 2002
16405 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16406 + * Licensed under the GPL
16409 +typedef long syscall_handler_t(unsigned long arg1, unsigned long arg2,
16410 + unsigned long arg3, unsigned long arg4,
16411 + unsigned long arg5, unsigned long arg6);
16413 +#define EXECUTE_SYSCALL(syscall, regs) \
16414 + (*sys_call_table[syscall])(UM_SYSCALL_ARG1(®s), \
16415 + UM_SYSCALL_ARG2(®s), \
16416 + UM_SYSCALL_ARG3(®s), \
16417 + UM_SYSCALL_ARG4(®s), \
16418 + UM_SYSCALL_ARG5(®s), \
16419 + UM_SYSCALL_ARG6(®s))
16421 +extern syscall_handler_t sys_mincore;
16422 +extern syscall_handler_t sys_madvise;
16424 +/* old_mmap needs the correct prototype since syscall_kern.c includes
16427 +int old_mmap(unsigned long addr, unsigned long len,
16428 + unsigned long prot, unsigned long flags,
16429 + unsigned long fd, unsigned long offset);
16431 +#define ARCH_SYSCALLS \
16432 + [ __NR_modify_ldt ] = sys_ni_syscall, \
16433 + [ __NR_pciconfig_read ] = sys_ni_syscall, \
16434 + [ __NR_pciconfig_write ] = sys_ni_syscall, \
16435 + [ __NR_pciconfig_iobase ] = sys_ni_syscall, \
16436 + [ __NR_pivot_root ] = sys_ni_syscall, \
16437 + [ __NR_multiplexer ] = sys_ni_syscall, \
16438 + [ __NR_mmap ] = old_mmap, \
16439 + [ __NR_madvise ] = sys_madvise, \
16440 + [ __NR_mincore ] = sys_mincore,
16442 +#define LAST_ARCH_SYSCALL __NR_mincore
16445 + * Overrides for Emacs so that we follow Linus's tabbing style.
16446 + * Emacs will notice this stuff at the end of the file and automatically
16447 + * adjust the settings for this buffer only. This must remain at the end
16449 + * ---------------------------------------------------------------------------
16450 + * Local variables:
16451 + * c-file-style: "linux"
16454 diff -Naur -X ../exclude-files orig/arch/um/include/sysrq.h um/arch/um/include/sysrq.h
16455 --- orig/arch/um/include/sysrq.h Wed Dec 31 19:00:00 1969
16456 +++ um/arch/um/include/sysrq.h Wed Oct 23 21:08:04 2002
16458 +#ifndef __UM_SYSRQ_H
16459 +#define __UM_SYSRQ_H
16461 +extern void show_trace(unsigned long *stack);
16464 diff -Naur -X ../exclude-files orig/arch/um/include/tempfile.h um/arch/um/include/tempfile.h
16465 --- orig/arch/um/include/tempfile.h Wed Dec 31 19:00:00 1969
16466 +++ um/arch/um/include/tempfile.h Wed Oct 23 21:08:04 2002
16469 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16470 + * Licensed under the GPL
16473 +#ifndef __TEMPFILE_H__
16474 +#define __TEMPFILE_H__
16476 +extern int make_tempfile(const char *template, char **tempname, int do_unlink);
16480 + * Overrides for Emacs so that we follow Linus's tabbing style.
16481 + * Emacs will notice this stuff at the end of the file and automatically
16482 + * adjust the settings for this buffer only. This must remain at the end
16484 + * ---------------------------------------------------------------------------
16485 + * Local variables:
16486 + * c-file-style: "linux"
16489 diff -Naur -X ../exclude-files orig/arch/um/include/time_user.h um/arch/um/include/time_user.h
16490 --- orig/arch/um/include/time_user.h Wed Dec 31 19:00:00 1969
16491 +++ um/arch/um/include/time_user.h Wed Jan 8 12:55:47 2003
16494 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16495 + * Licensed under the GPL
16498 +#ifndef __TIME_USER_H__
16499 +#define __TIME_USER_H__
16501 +extern void timer(void);
16502 +extern void switch_timers(int to_real);
16503 +extern void set_interval(int timer_type);
16504 +extern void idle_sleep(int secs);
16505 +extern void enable_timer(void);
16506 +extern unsigned long time_lock(void);
16507 +extern void time_unlock(unsigned long);
16510 diff -Naur -X ../exclude-files orig/arch/um/include/tlb.h um/arch/um/include/tlb.h
16511 --- orig/arch/um/include/tlb.h Wed Dec 31 19:00:00 1969
16512 +++ um/arch/um/include/tlb.h Wed Oct 23 21:08:04 2002
16515 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16516 + * Licensed under the GPL
16522 +extern void mprotect_kernel_vm(int w);
16523 +extern void force_flush_all(void);
16528 + * Overrides for Emacs so that we follow Linus's tabbing style.
16529 + * Emacs will notice this stuff at the end of the file and automatically
16530 + * adjust the settings for this buffer only. This must remain at the end
16532 + * ---------------------------------------------------------------------------
16533 + * Local variables:
16534 + * c-file-style: "linux"
16537 diff -Naur -X ../exclude-files orig/arch/um/include/ubd_user.h um/arch/um/include/ubd_user.h
16538 --- orig/arch/um/include/ubd_user.h Wed Dec 31 19:00:00 1969
16539 +++ um/arch/um/include/ubd_user.h Thu Mar 6 18:09:14 2003
16542 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16543 + * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com)
16544 + * Licensed under the GPL
16547 +#ifndef __UM_UBD_USER_H
16548 +#define __UM_UBD_USER_H
16552 +enum ubd_req { UBD_READ, UBD_WRITE };
16554 +struct io_thread_req {
16557 + unsigned long offsets[2];
16558 + unsigned long long offset;
16559 + unsigned long length;
16562 + unsigned long sector_mask;
16563 + unsigned long cow_offset;
16564 + unsigned long bitmap_words[2];
16568 +extern int open_ubd_file(char *file, struct openflags *openflags,
16569 + char **backing_file_out, int *bitmap_offset_out,
16570 + unsigned long *bitmap_len_out, int *data_offset_out,
16571 + int *create_cow_out);
16572 +extern int create_cow_file(char *cow_file, char *backing_file,
16573 + struct openflags flags, int sectorsize,
16574 + int *bitmap_offset_out,
16575 + unsigned long *bitmap_len_out,
16576 + int *data_offset_out);
16577 +extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
16578 +extern int read_ubd_fs(int fd, void *buffer, int len);
16579 +extern int write_ubd_fs(int fd, char *buffer, int len);
16580 +extern int start_io_thread(unsigned long sp, int *fds_out);
16581 +extern void do_io(struct io_thread_req *req);
16583 +static inline int ubd_test_bit(__u64 bit, unsigned char *data)
16588 + bits = sizeof(data[0]) * 8;
16590 + off = bit % bits;
16591 + return((data[n] & (1 << off)) != 0);
16594 +static inline void ubd_set_bit(__u64 bit, unsigned char *data)
16599 + bits = sizeof(data[0]) * 8;
16601 + off = bit % bits;
16602 + data[n] |= (1 << off);
16609 + * Overrides for Emacs so that we follow Linus's tabbing style.
16610 + * Emacs will notice this stuff at the end of the file and automatically
16611 + * adjust the settings for this buffer only. This must remain at the end
16613 + * ---------------------------------------------------------------------------
16614 + * Local variables:
16615 + * c-file-style: "linux"
16618 diff -Naur -X ../exclude-files orig/arch/um/include/um_mmu.h um/arch/um/include/um_mmu.h
16619 --- orig/arch/um/include/um_mmu.h Wed Dec 31 19:00:00 1969
16620 +++ um/arch/um/include/um_mmu.h Sat Nov 9 12:51:43 2002
16623 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16624 + * Licensed under the GPL
16627 +#ifndef __ARCH_UM_MMU_H
16628 +#define __ARCH_UM_MMU_H
16630 +#include "linux/config.h"
16631 +#include "choose-mode.h"
16633 +#ifdef CONFIG_MODE_TT
16634 +#include "../kernel/tt/include/mmu.h"
16637 +#ifdef CONFIG_MODE_SKAS
16638 +#include "../kernel/skas/include/mmu.h"
16642 +#ifdef CONFIG_MODE_TT
16643 + struct mmu_context_tt tt;
16645 +#ifdef CONFIG_MODE_SKAS
16646 + struct mmu_context_skas skas;
16653 + * Overrides for Emacs so that we follow Linus's tabbing style.
16654 + * Emacs will notice this stuff at the end of the file and automatically
16655 + * adjust the settings for this buffer only. This must remain at the end
16657 + * ---------------------------------------------------------------------------
16658 + * Local variables:
16659 + * c-file-style: "linux"
16662 diff -Naur -X ../exclude-files orig/arch/um/include/um_uaccess.h um/arch/um/include/um_uaccess.h
16663 --- orig/arch/um/include/um_uaccess.h Wed Dec 31 19:00:00 1969
16664 +++ um/arch/um/include/um_uaccess.h Sat Nov 23 22:03:02 2002
16667 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16668 + * Licensed under the GPL
16671 +#ifndef __ARCH_UM_UACCESS_H
16672 +#define __ARCH_UM_UACCESS_H
16674 +#include "linux/config.h"
16675 +#include "choose-mode.h"
16677 +#ifdef CONFIG_MODE_TT
16678 +#include "../kernel/tt/include/uaccess.h"
16681 +#ifdef CONFIG_MODE_SKAS
16682 +#include "../kernel/skas/include/uaccess.h"
16685 +#define access_ok(type, addr, size) \
16686 + CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
16688 +static inline int verify_area(int type, const void * addr, unsigned long size)
16690 + return(CHOOSE_MODE_PROC(verify_area_tt, verify_area_skas, type, addr,
16694 +static inline int copy_from_user(void *to, const void *from, int n)
16696 + return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to,
16700 +static inline int copy_to_user(void *to, const void *from, int n)
16702 + return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to,
16706 +static inline int strncpy_from_user(char *dst, const char *src, int count)
16708 + return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
16709 + dst, src, count));
16712 +static inline int __clear_user(void *mem, int len)
16714 + return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
16717 +static inline int clear_user(void *mem, int len)
16719 + return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
16722 +static inline int strnlen_user(const void *str, int len)
16724 + return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
16730 + * Overrides for Emacs so that we follow Linus's tabbing style.
16731 + * Emacs will notice this stuff at the end of the file and automatically
16732 + * adjust the settings for this buffer only. This must remain at the end
16734 + * ---------------------------------------------------------------------------
16735 + * Local variables:
16736 + * c-file-style: "linux"
16739 diff -Naur -X ../exclude-files orig/arch/um/include/umid.h um/arch/um/include/umid.h
16740 --- orig/arch/um/include/umid.h Wed Dec 31 19:00:00 1969
16741 +++ um/arch/um/include/umid.h Mon Dec 16 20:52:19 2002
16744 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
16745 + * Licensed under the GPL
16748 +#ifndef __UMID_H__
16749 +#define __UMID_H__
16751 +extern int umid_file_name(char *name, char *buf, int len);
16756 + * Overrides for Emacs so that we follow Linus's tabbing style.
16757 + * Emacs will notice this stuff at the end of the file and automatically
16758 + * adjust the settings for this buffer only. This must remain at the end
16760 + * ---------------------------------------------------------------------------
16761 + * Local variables:
16762 + * c-file-style: "linux"
16765 diff -Naur -X ../exclude-files orig/arch/um/include/uml_uaccess.h um/arch/um/include/uml_uaccess.h
16766 --- orig/arch/um/include/uml_uaccess.h Wed Dec 31 19:00:00 1969
16767 +++ um/arch/um/include/uml_uaccess.h Thu Dec 19 13:15:22 2002
16770 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
16771 + * Licensed under the GPL
16774 +#ifndef __UML_UACCESS_H__
16775 +#define __UML_UACCESS_H__
16777 +extern int __do_copy_to_user(void *to, const void *from, int n,
16778 + void **fault_addr, void **fault_catcher);
16779 +extern unsigned long __do_user_copy(void *to, const void *from, int n,
16780 + void **fault_addr, void **fault_catcher,
16781 + void (*op)(void *to, const void *from,
16782 + int n), int *faulted_out);
16783 +void __do_copy(void *to, const void *from, int n);
16788 + * Overrides for Emacs so that we follow Linus's tabbing style.
16789 + * Emacs will notice this stuff at the end of the file and automatically
16790 + * adjust the settings for this buffer only. This must remain at the end
16792 + * ---------------------------------------------------------------------------
16793 + * Local variables:
16794 + * c-file-style: "linux"
16797 diff -Naur -X ../exclude-files orig/arch/um/include/umn.h um/arch/um/include/umn.h
16798 --- orig/arch/um/include/umn.h Wed Dec 31 19:00:00 1969
16799 +++ um/arch/um/include/umn.h Wed Oct 23 21:08:04 2002
16802 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16803 + * Licensed under the GPL
16809 +extern int open_umn_tty(int *slave_out, int *slipno_out);
16810 +extern void close_umn_tty(int master, int slave);
16811 +extern int umn_send_packet(int fd, void *data, int len);
16812 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
16813 +extern void slip_unesc(unsigned char s);
16814 +extern void umn_read(int fd);
16819 + * Overrides for Emacs so that we follow Linus's tabbing style.
16820 + * Emacs will notice this stuff at the end of the file and automatically
16821 + * adjust the settings for this buffer only. This must remain at the end
16823 + * ---------------------------------------------------------------------------
16824 + * Local variables:
16825 + * c-file-style: "linux"
16828 diff -Naur -X ../exclude-files orig/arch/um/include/user.h um/arch/um/include/user.h
16829 --- orig/arch/um/include/user.h Wed Dec 31 19:00:00 1969
16830 +++ um/arch/um/include/user.h Wed Oct 23 21:08:04 2002
16833 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16834 + * Licensed under the GPL
16837 +#ifndef __USER_H__
16838 +#define __USER_H__
16840 +extern void panic(const char *fmt, ...);
16841 +extern int printk(const char *fmt, ...);
16842 +extern void schedule(void);
16843 +extern void *um_kmalloc(int size);
16844 +extern void *um_kmalloc_atomic(int size);
16845 +extern void kfree(void *ptr);
16846 +extern int in_aton(char *str);
16847 +extern int open_gdb_chan(void);
16852 + * Overrides for Emacs so that we follow Linus's tabbing style.
16853 + * Emacs will notice this stuff at the end of the file and automatically
16854 + * adjust the settings for this buffer only. This must remain at the end
16856 + * ---------------------------------------------------------------------------
16857 + * Local variables:
16858 + * c-file-style: "linux"
16861 diff -Naur -X ../exclude-files orig/arch/um/include/user_util.h um/arch/um/include/user_util.h
16862 --- orig/arch/um/include/user_util.h Wed Dec 31 19:00:00 1969
16863 +++ um/arch/um/include/user_util.h Wed Apr 23 20:42:00 2003
16866 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16867 + * Licensed under the GPL
16870 +#ifndef __USER_UTIL_H__
16871 +#define __USER_UTIL_H__
16873 +#include "sysdep/ptrace.h"
16875 +extern int mode_tt;
16877 +extern int grantpt(int __fd);
16878 +extern int unlockpt(int __fd);
16879 +extern char *ptsname(int __fd);
16881 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
16888 +extern struct cpu_task cpu_tasks[];
16890 +struct signal_info {
16891 + void (*handler)(int, union uml_pt_regs *);
16895 +extern struct signal_info sig_info[];
16897 +extern unsigned long low_physmem;
16898 +extern unsigned long high_physmem;
16899 +extern unsigned long uml_physmem;
16900 +extern unsigned long uml_reserved;
16901 +extern unsigned long end_vm;
16902 +extern unsigned long start_vm;
16903 +extern unsigned long highmem;
16905 +extern char host_info[];
16907 +extern char saved_command_line[];
16908 +extern char command_line[];
16910 +extern char *tempdir;
16912 +extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
16913 +extern unsigned long _unprotected_end;
16914 +extern unsigned long brk_start;
16916 +extern int pty_output_sigio;
16917 +extern int pty_close_sigio;
16919 +extern void stop(void);
16920 +extern void stack_protections(unsigned long address);
16921 +extern void task_protections(unsigned long address);
16922 +extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
16923 +extern void *add_signal_handler(int sig, void (*handler)(int));
16924 +extern int start_fork_tramp(void *arg, unsigned long temp_stack,
16925 + int clone_flags, int (*tramp)(void *));
16926 +extern int linux_main(int argc, char **argv);
16927 +extern void set_cmdline(char *cmd);
16928 +extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
16929 +extern int get_pty(void);
16930 +extern void *um_kmalloc(int size);
16931 +extern int raw(int fd, int complain);
16932 +extern int switcheroo(int fd, int prot, void *from, void *to, int size);
16933 +extern void setup_machinename(char *machine_out);
16934 +extern void setup_hostinfo(void);
16935 +extern void add_arg(char *cmd_line, char *arg);
16936 +extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
16937 +extern void init_new_thread_signals(int altstack);
16938 +extern void do_exec(int old_pid, int new_pid);
16939 +extern void tracer_panic(char *msg, ...);
16940 +extern char *get_umid(int only_if_set);
16941 +extern void do_longjmp(void *p, int val);
16942 +extern void suspend_new_thread(int fd);
16943 +extern int detach(int pid, int sig);
16944 +extern int attach(int pid);
16945 +extern void kill_child_dead(int pid);
16946 +extern int cont(int pid);
16947 +extern void check_ptrace(void);
16948 +extern void check_sigio(void);
16949 +extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
16950 +extern void write_sigio_workaround(void);
16951 +extern void arch_check_bugs(void);
16952 +extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
16953 +extern int arch_fixup(unsigned long address, void *sc_ptr);
16954 +extern int can_do_skas(void);
16959 + * Overrides for Emacs so that we follow Linus's tabbing style.
16960 + * Emacs will notice this stuff at the end of the file and automatically
16961 + * adjust the settings for this buffer only. This must remain at the end
16963 + * ---------------------------------------------------------------------------
16964 + * Local variables:
16965 + * c-file-style: "linux"
16968 diff -Naur -X ../exclude-files orig/arch/um/kernel/Makefile um/arch/um/kernel/Makefile
16969 --- orig/arch/um/kernel/Makefile Wed Dec 31 19:00:00 1969
16970 +++ um/arch/um/kernel/Makefile Thu Apr 10 11:14:55 2003
16973 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16974 +# Licensed under the GPL
16977 +O_TARGET = built-in.o
16979 +obj-y = config.o checksum.o exec_kern.o exitcode.o frame_kern.o frame.o \
16980 + helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \
16981 + process.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \
16982 + sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o \
16983 + syscall_user.o sysrq.o sys_call_table.o tempfile.o time.o \
16984 + time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
16985 + umid.o user_syms.o user_util.o
16987 +obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
16988 +obj-$(CONFIG_GPROF) += gprof_syms.o
16989 +obj-$(CONFIG_GCOV) += gmon_syms.o
16990 +obj-$(CONFIG_TTY_LOG) += tty_log.o
16992 +subdir-$(CONFIG_MODE_TT) += tt
16993 +subdir-$(CONFIG_MODE_SKAS) += skas
16995 +user-objs-$(CONFIG_TTY_LOG) += tty_log.o
16997 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
16999 +# user_syms.o not included here because Rules.make has its own ideas about
17000 +# building anything in export-objs
17002 +USER_OBJS = $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
17003 + process.o tempfile.o time.o umid.o user_util.o
17005 +DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__
17006 +DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__
17008 +export-objs-$(CONFIG_GPROF) += gprof_syms.o
17009 +export-objs-$(CONFIG_GCOV) += gmon_syms.o
17011 +export-objs = ksyms.o process_kern.o signal_kern.o user_syms.o $(export-objs-y)
17013 +CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \
17014 + -I/usr/include -I../include
17016 +CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
17018 +include $(TOPDIR)/Rules.make
17020 +$(USER_OBJS) : %.o: %.c
17021 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
17023 +# This has to be separate because it needs be compiled with frame pointers
17024 +# regardless of how the rest of the kernel is built.
17027 + $(CC) $(CFLAGS_$@) -c -o $@ $<
17029 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
17031 +config.c : config.c.in $(TOPDIR)/.config
17032 + $(PERL) -e $(QUOTE) < config.c.in > $@
17036 + for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
17044 +archmrproper: clean
17045 diff -Naur -X ../exclude-files orig/arch/um/kernel/checksum.c um/arch/um/kernel/checksum.c
17046 --- orig/arch/um/kernel/checksum.c Wed Dec 31 19:00:00 1969
17047 +++ um/arch/um/kernel/checksum.c Thu Oct 31 22:39:58 2002
17049 +#include "asm/uaccess.h"
17050 +#include "linux/errno.h"
17052 +extern unsigned int arch_csum_partial(const char *buff, int len, int sum);
17054 +extern unsigned int csum_partial(char *buff, int len, int sum)
17056 + return(arch_csum_partial(buff, len, sum));
17059 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len,
17060 + int sum, int *err_ptr)
17062 + if(copy_to_user(dst, src, len)){
17063 + *err_ptr = -EFAULT;
17067 + return(arch_csum_partial(src, len, sum));
17070 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len,
17071 + int sum, int *err_ptr)
17073 + if(copy_from_user(dst, src, len)){
17074 + *err_ptr = -EFAULT;
17078 + return(arch_csum_partial(dst, len, sum));
17082 + * Overrides for Emacs so that we follow Linus's tabbing style.
17083 + * Emacs will notice this stuff at the end of the file and automatically
17084 + * adjust the settings for this buffer only. This must remain at the end
17086 + * ---------------------------------------------------------------------------
17087 + * Local variables:
17088 + * c-file-style: "linux"
17091 diff -Naur -X ../exclude-files orig/arch/um/kernel/config.c.in um/arch/um/kernel/config.c.in
17092 --- orig/arch/um/kernel/config.c.in Wed Dec 31 19:00:00 1969
17093 +++ um/arch/um/kernel/config.c.in Thu Apr 10 11:17:55 2003
17096 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17097 + * Licensed under the GPL
17100 +#include <stdio.h>
17101 +#include <stdlib.h>
17104 +static __initdata char *config = "CONFIG";
17106 +static int __init print_config(char *line, int *add)
17108 + printf("%s", config);
17112 +__uml_setup("--showconfig", print_config,
17114 +" Prints the config file that this UML binary was generated from.\n\n"
17118 + * Overrides for Emacs so that we follow Linus's tabbing style.
17119 + * Emacs will notice this stuff at the end of the file and automatically
17120 + * adjust the settings for this buffer only. This must remain at the end
17122 + * ---------------------------------------------------------------------------
17123 + * Local variables:
17124 + * c-file-style: "linux"
17127 diff -Naur -X ../exclude-files orig/arch/um/kernel/exec_kern.c um/arch/um/kernel/exec_kern.c
17128 --- orig/arch/um/kernel/exec_kern.c Wed Dec 31 19:00:00 1969
17129 +++ um/arch/um/kernel/exec_kern.c Wed Apr 16 16:35:05 2003
17132 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
17133 + * Licensed under the GPL
17136 +#include "linux/slab.h"
17137 +#include "linux/smp_lock.h"
17138 +#include "asm/ptrace.h"
17139 +#include "asm/pgtable.h"
17140 +#include "asm/pgalloc.h"
17141 +#include "asm/uaccess.h"
17142 +#include "user_util.h"
17143 +#include "kern_util.h"
17144 +#include "mem_user.h"
17146 +#include "irq_user.h"
17148 +#include "2_5compat.h"
17150 +#include "time_user.h"
17151 +#include "choose-mode.h"
17152 +#include "mode_kern.h"
17154 +void flush_thread(void)
17156 + CHOOSE_MODE(flush_thread_tt(), flush_thread_skas());
17159 +void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
17161 + CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
17164 +extern void log_exec(char **argv, void *tty);
17166 +static int execve1(char *file, char **argv, char **env)
17170 +#ifdef CONFIG_TTY_LOG
17171 + log_exec(argv, current->tty);
17173 + error = do_execve(file, argv, env, ¤t->thread.regs);
17175 + current->ptrace &= ~PT_DTRACE;
17176 + set_cmdline(current_cmd());
17181 +int um_execve(char *file, char **argv, char **env)
17185 + err = execve1(file, argv, env);
17187 + do_longjmp(current->thread.exec_buf, 1);
17191 +int sys_execve(char *file, char **argv, char **env)
17197 + filename = getname((char *) file);
17198 + error = PTR_ERR(filename);
17199 + if (IS_ERR(filename)) goto out;
17200 + error = execve1(filename, argv, env);
17201 + putname(filename);
17208 + * Overrides for Emacs so that we follow Linus's tabbing style.
17209 + * Emacs will notice this stuff at the end of the file and automatically
17210 + * adjust the settings for this buffer only. This must remain at the end
17212 + * ---------------------------------------------------------------------------
17213 + * Local variables:
17214 + * c-file-style: "linux"
17217 diff -Naur -X ../exclude-files orig/arch/um/kernel/exitcode.c um/arch/um/kernel/exitcode.c
17218 --- orig/arch/um/kernel/exitcode.c Wed Dec 31 19:00:00 1969
17219 +++ um/arch/um/kernel/exitcode.c Thu Nov 7 18:22:04 2002
17222 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17223 + * Licensed under the GPL
17226 +#include "linux/init.h"
17227 +#include "linux/ctype.h"
17228 +#include "linux/proc_fs.h"
17229 +#include "asm/uaccess.h"
17231 +/* If read and write race, the read will still atomically read a valid
17234 +int uml_exitcode = 0;
17236 +static int read_proc_exitcode(char *page, char **start, off_t off,
17237 + int count, int *eof, void *data)
17241 + len = sprintf(page, "%d\n", uml_exitcode);
17243 + if(len <= off+count) *eof = 1;
17244 + *start = page + off;
17245 + if(len > count) len = count;
17246 + if(len < 0) len = 0;
17250 +static int write_proc_exitcode(struct file *file, const char *buffer,
17251 + unsigned long count, void *data)
17253 + char *end, buf[sizeof("nnnnn\0")];
17256 + if(copy_from_user(buf, buffer, count))
17258 + tmp = simple_strtol(buf, &end, 0);
17259 + if((*end != '\0') && !isspace(*end))
17261 + uml_exitcode = tmp;
17265 +static int make_proc_exitcode(void)
17267 + struct proc_dir_entry *ent;
17269 + ent = create_proc_entry("exitcode", 0600, &proc_root);
17271 + printk("make_proc_exitcode : Failed to register "
17272 + "/proc/exitcode\n");
17276 + ent->read_proc = read_proc_exitcode;
17277 + ent->write_proc = write_proc_exitcode;
17282 +__initcall(make_proc_exitcode);
17285 + * Overrides for Emacs so that we follow Linus's tabbing style.
17286 + * Emacs will notice this stuff at the end of the file and automatically
17287 + * adjust the settings for this buffer only. This must remain at the end
17289 + * ---------------------------------------------------------------------------
17290 + * Local variables:
17291 + * c-file-style: "linux"
17294 diff -Naur -X ../exclude-files orig/arch/um/kernel/frame.c um/arch/um/kernel/frame.c
17295 --- orig/arch/um/kernel/frame.c Wed Dec 31 19:00:00 1969
17296 +++ um/arch/um/kernel/frame.c Wed Dec 11 11:12:41 2002
17299 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17300 + * Licensed under the GPL
17303 +#include <stdio.h>
17304 +#include <stdlib.h>
17305 +#include <unistd.h>
17306 +#include <string.h>
17307 +#include <signal.h>
17309 +#include <sched.h>
17310 +#include <errno.h>
17311 +#include <sys/ptrace.h>
17312 +#include <sys/syscall.h>
17313 +#include <sys/mman.h>
17314 +#include <asm/page.h>
17315 +#include <asm/ptrace.h>
17316 +#include <asm/sigcontext.h>
17317 +#include "sysdep/ptrace.h"
17318 +#include "sysdep/sigcontext.h"
17319 +#include "frame_user.h"
17320 +#include "kern_util.h"
17321 +#include "ptrace_user.h"
17324 +static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
17325 + unsigned long top, void **data_out)
17327 + unsigned long regs[FRAME_SIZE];
17328 + int pid, status, n, len;
17330 + /* Start the child as a thread */
17331 + pid = clone(child, sp, CLONE_VM | SIGCHLD, arg);
17333 + printf("capture_stack : clone failed - errno = %d\n", errno);
17337 + /* Wait for it to stop itself and continue it with a SIGUSR1 to force
17338 + * it into the signal handler.
17340 + n = waitpid(pid, &status, WUNTRACED);
17342 + printf("capture_stack : waitpid failed - errno = %d\n", errno);
17345 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
17346 + fprintf(stderr, "capture_stack : Expected SIGSTOP, "
17347 + "got status = 0x%x\n", status);
17350 + if(ptrace(PTRACE_CONT, pid, 0, SIGUSR1) < 0){
17351 + printf("capture_stack : PTRACE_CONT failed - errno = %d\n",
17356 + /* Wait for it to stop itself again and grab its registers again.
17357 + * At this point, the handler has stuffed the addresses of
17358 + * sig, sc, and SA_RESTORER in raw.
17360 + n = waitpid(pid, &status, WUNTRACED);
17362 + printf("capture_stack : waitpid failed - errno = %d\n", errno);
17365 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
17366 + fprintf(stderr, "capture_stack : Expected SIGSTOP, "
17367 + "got status = 0x%x\n", status);
17370 + if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0){
17371 + printf("capture_stack : PTRACE_GETREGS failed - errno = %d\n",
17376 + /* It has outlived its usefulness, so continue it so it can exit */
17377 + if(ptrace(PTRACE_CONT, pid, 0, 0) < 0){
17378 + printf("capture_stack : PTRACE_CONT failed - errno = %d\n",
17382 + if(waitpid(pid, &status, 0) < 0){
17383 + printf("capture_stack : waitpid failed - errno = %d\n", errno);
17386 + if(!WIFSIGNALED(status) || (WTERMSIG(status) != 9)){
17387 + printf("capture_stack : Expected exit signal 9, "
17388 + "got status = 0x%x\n", status);
17392 + /* The frame that we want is the top of the signal stack */
17394 + len = top - PT_SP(regs);
17395 + *data_out = malloc(len);
17396 + if(*data_out == NULL){
17397 + printf("capture_stack : malloc failed - errno = %d\n", errno);
17400 + memcpy(*data_out, (void *) PT_SP(regs), len);
17405 +struct common_raw {
17408 + unsigned long sig;
17409 + unsigned long sr;
17410 + unsigned long sp;
17411 + struct arch_frame_data_raw arch;
17414 +#define SA_RESTORER (0x04000000)
17416 +typedef unsigned long old_sigset_t;
17418 +struct old_sigaction {
17419 + __sighandler_t handler;
17420 + old_sigset_t sa_mask;
17421 + unsigned long sa_flags;
17422 + void (*sa_restorer)(void);
17425 +static void child_common(struct common_raw *common, sighandler_t handler,
17426 + int restorer, int flags)
17428 + stack_t ss = ((stack_t) { .ss_sp = common->stack,
17430 + .ss_size = common->size });
17433 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
17434 + printf("PTRACE_TRACEME failed, errno = %d\n", errno);
17436 + if(sigaltstack(&ss, NULL) < 0){
17437 + printf("sigaltstack failed - errno = %d\n", errno);
17438 + kill(getpid(), SIGKILL);
17442 + struct sigaction sa;
17444 + sa.sa_handler = handler;
17445 + sigemptyset(&sa.sa_mask);
17446 + sa.sa_flags = SA_ONSTACK | flags;
17447 + err = sigaction(SIGUSR1, &sa, NULL);
17450 + struct old_sigaction sa;
17452 + sa.handler = handler;
17454 + sa.sa_flags = (SA_ONSTACK | flags) & ~SA_RESTORER;
17455 + err = syscall(__NR_sigaction, SIGUSR1, &sa, NULL);
17459 + printf("sigaction failed - errno = %d\n", errno);
17460 + kill(getpid(), SIGKILL);
17463 + os_stop_process(os_getpid());
17466 +/* Changed only during early boot */
17467 +struct sc_frame signal_frame_sc;
17469 +struct sc_frame signal_frame_sc_sr;
17471 +struct sc_frame_raw {
17472 + struct common_raw common;
17473 + unsigned long sc;
17477 +/* Changed only during early boot */
17478 +static struct sc_frame_raw *raw_sc = NULL;
17480 +static void sc_handler(int sig, struct sigcontext sc)
17482 + raw_sc->common.sig = (unsigned long) &sig;
17483 + raw_sc->common.sr = frame_restorer();
17484 + raw_sc->common.sp = frame_sp();
17485 + raw_sc->sc = (unsigned long) ≻
17486 + setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr);
17488 + os_stop_process(os_getpid());
17489 + kill(getpid(), SIGKILL);
17492 +static int sc_child(void *arg)
17495 + child_common(&raw_sc->common, (sighandler_t) sc_handler,
17496 + raw_sc->restorer, 0);
17500 +/* Changed only during early boot */
17501 +struct si_frame signal_frame_si;
17503 +struct si_frame_raw {
17504 + struct common_raw common;
17505 + unsigned long sip;
17506 + unsigned long si;
17507 + unsigned long ucp;
17508 + unsigned long uc;
17511 +/* Changed only during early boot */
17512 +static struct si_frame_raw *raw_si = NULL;
17514 +static void si_handler(int sig, siginfo_t *si, struct ucontext *ucontext)
17516 + raw_si->common.sig = (unsigned long) &sig;
17517 + raw_si->common.sr = frame_restorer();
17518 + raw_si->common.sp = frame_sp();
17519 + raw_si->sip = (unsigned long) &si;
17520 + raw_si->si = (unsigned long) si;
17521 + raw_si->ucp = (unsigned long) &ucontext;
17522 + raw_si->uc = (unsigned long) ucontext;
17523 + setup_arch_frame_raw(&raw_si->common.arch,
17524 + ucontext->uc_mcontext.fpregs, raw_si->common.sr);
17526 + os_stop_process(os_getpid());
17527 + kill(getpid(), SIGKILL);
17530 +static int si_child(void *arg)
17533 + child_common(&raw_si->common, (sighandler_t) si_handler, 1,
17538 +static int relative_sr(unsigned long sr, int sr_index, void *stack,
17541 + unsigned long *srp = (unsigned long *) sr;
17542 + unsigned long frame = (unsigned long) framep;
17544 + if((*srp & PAGE_MASK) == (unsigned long) stack){
17546 + *((unsigned long *) (frame + sr_index)) = *srp;
17552 +static unsigned long capture_stack_common(int (*proc)(void *), void *arg,
17553 + struct common_raw *common_in,
17554 + void *top, void *sigstack,
17556 + struct frame_common *common_out)
17558 + unsigned long sig_top = (unsigned long) sigstack + stack_len, base;
17560 + common_in->stack = (void *) sigstack;
17561 + common_in->size = stack_len;
17562 + common_out->len = capture_stack(proc, arg, top, sig_top,
17563 + &common_out->data);
17564 + base = sig_top - common_out->len;
17565 + common_out->sig_index = common_in->sig - base;
17566 + common_out->sp_index = common_in->sp - base;
17567 + common_out->sr_index = common_in->sr - base;
17568 + common_out->sr_relative = relative_sr(common_in->sr,
17569 + common_out->sr_index, sigstack,
17570 + common_out->data);
17574 +void capture_signal_stack(void)
17576 + struct sc_frame_raw raw_sc;
17577 + struct si_frame_raw raw_si;
17578 + void *stack, *sigstack;
17579 + unsigned long top, sig_top, base;
17581 + stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
17582 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
17583 + sigstack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
17584 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
17585 + if((stack == MAP_FAILED) || (sigstack == MAP_FAILED)){
17586 + printf("capture_signal_stack : mmap failed - errno = %d\n",
17591 + top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
17592 + sig_top = (unsigned long) sigstack + PAGE_SIZE;
17594 + /* Get the sigcontext, no sigrestorer layout */
17595 + raw_sc.restorer = 0;
17596 + base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common,
17597 + (void *) top, sigstack, PAGE_SIZE,
17598 + &signal_frame_sc.common);
17600 + signal_frame_sc.sc_index = raw_sc.sc - base;
17601 + setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc.common.arch);
17603 + /* Ditto for the sigcontext, sigrestorer layout */
17604 + raw_sc.restorer = 1;
17605 + base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common,
17606 + (void *) top, sigstack, PAGE_SIZE,
17607 + &signal_frame_sc_sr.common);
17608 + signal_frame_sc_sr.sc_index = raw_sc.sc - base;
17609 + setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc_sr.common.arch);
17611 + /* And the siginfo layout */
17613 + base = capture_stack_common(si_child, &raw_si, &raw_si.common,
17614 + (void *) top, sigstack, PAGE_SIZE,
17615 + &signal_frame_si.common);
17616 + signal_frame_si.sip_index = raw_si.sip - base;
17617 + signal_frame_si.si_index = raw_si.si - base;
17618 + signal_frame_si.ucp_index = raw_si.ucp - base;
17619 + signal_frame_si.uc_index = raw_si.uc - base;
17620 + setup_arch_frame(&raw_si.common.arch, &signal_frame_si.common.arch);
17622 + if((munmap(stack, PAGE_SIZE) < 0) ||
17623 + (munmap(sigstack, PAGE_SIZE) < 0)){
17624 + printf("capture_signal_stack : munmap failed - errno = %d\n",
17631 + * Overrides for Emacs so that we follow Linus's tabbing style.
17632 + * Emacs will notice this stuff at the end of the file and automatically
17633 + * adjust the settings for this buffer only. This must remain at the end
17635 + * ---------------------------------------------------------------------------
17636 + * Local variables:
17637 + * c-file-style: "linux"
17640 diff -Naur -X ../exclude-files orig/arch/um/kernel/frame_kern.c um/arch/um/kernel/frame_kern.c
17641 --- orig/arch/um/kernel/frame_kern.c Wed Dec 31 19:00:00 1969
17642 +++ um/arch/um/kernel/frame_kern.c Sun Dec 8 19:44:13 2002
17645 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17646 + * Licensed under the GPL
17649 +#include "asm/ptrace.h"
17650 +#include "asm/uaccess.h"
17651 +#include "asm/signal.h"
17652 +#include "asm/uaccess.h"
17653 +#include "asm/ucontext.h"
17654 +#include "frame_kern.h"
17655 +#include "sigcontext.h"
17656 +#include "sysdep/ptrace.h"
17657 +#include "choose-mode.h"
17660 +int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
17662 + if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
17664 + if (from->si_code < 0)
17665 + return __copy_to_user(to, from, sizeof(siginfo_t));
17669 + /* If you change siginfo_t structure, please be sure
17670 + this code is fixed accordingly.
17671 + It should never copy any pad contained in the structure
17672 + to avoid security leaks, but must copy the generic
17673 + 3 ints plus the relevant union member. */
17674 + err = __put_user(from->si_signo, &to->si_signo);
17675 + err |= __put_user(from->si_errno, &to->si_errno);
17676 + err |= __put_user((short)from->si_code, &to->si_code);
17677 + /* First 32bits of unions are always present. */
17678 + err |= __put_user(from->si_pid, &to->si_pid);
17679 + switch (from->si_code >> 16) {
17680 + case __SI_FAULT >> 16:
17682 + case __SI_CHLD >> 16:
17683 + err |= __put_user(from->si_utime, &to->si_utime);
17684 + err |= __put_user(from->si_stime, &to->si_stime);
17685 + err |= __put_user(from->si_status, &to->si_status);
17687 + err |= __put_user(from->si_uid, &to->si_uid);
17694 +static int copy_restorer(void (*restorer)(void), unsigned long start,
17695 + unsigned long sr_index, int sr_relative)
17697 + unsigned long sr;
17700 + sr = (unsigned long) restorer;
17701 + sr += start + sr_index;
17702 + restorer = (void (*)(void)) sr;
17705 + return(copy_to_user((void *) (start + sr_index), &restorer,
17706 + sizeof(restorer)));
17709 +static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from,
17710 + struct arch_frame_data *arch)
17712 + return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
17714 + copy_sc_to_user_skas(to, fp, &from->regs,
17715 + current->thread.cr2,
17716 + current->thread.err)));
17719 +static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set,
17720 + unsigned long sp)
17724 + err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
17725 + err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
17726 + err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
17727 + err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs,
17728 + &signal_frame_si.common.arch);
17729 + err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
17733 +int setup_signal_stack_si(unsigned long stack_top, int sig,
17734 + unsigned long handler, void (*restorer)(void),
17735 + struct pt_regs *regs, siginfo_t *info,
17738 + unsigned long start;
17739 + void *sip, *ucp, *fp;
17741 + start = stack_top - signal_frame_si.common.len;
17742 + sip = (void *) (start + signal_frame_si.si_index);
17743 + ucp = (void *) (start + signal_frame_si.uc_index);
17744 + fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext));
17746 + if(restorer == NULL)
17747 + panic("setup_signal_stack_si - no restorer");
17749 + if(copy_to_user((void *) start, signal_frame_si.common.data,
17750 + signal_frame_si.common.len) ||
17751 + copy_to_user((void *) (start + signal_frame_si.common.sig_index),
17752 + &sig, sizeof(sig)) ||
17753 + copy_siginfo_to_user(sip, info) ||
17754 + copy_to_user((void *) (start + signal_frame_si.sip_index), &sip,
17756 + copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) ||
17757 + copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp,
17759 + copy_restorer(restorer, start, signal_frame_si.common.sr_index,
17760 + signal_frame_si.common.sr_relative))
17763 + PT_REGS_IP(regs) = handler;
17764 + PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
17768 +int setup_signal_stack_sc(unsigned long stack_top, int sig,
17769 + unsigned long handler, void (*restorer)(void),
17770 + struct pt_regs *regs, sigset_t *mask)
17772 + struct frame_common *frame = &signal_frame_sc_sr.common;
17774 + int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
17775 + unsigned long sigs, sr;
17776 + unsigned long start = stack_top - frame->len - sig_size;
17778 + user_sc = (void *) (start + signal_frame_sc_sr.sc_index);
17779 + if(restorer == NULL){
17780 + frame = &signal_frame_sc.common;
17781 + user_sc = (void *) (start + signal_frame_sc.sc_index);
17782 + sr = (unsigned long) frame->data;
17783 + sr += frame->sr_index;
17784 + sr = *((unsigned long *) sr);
17785 + restorer = ((void (*)(void)) sr);
17788 + sigs = start + frame->len;
17789 + if(copy_to_user((void *) start, frame->data, frame->len) ||
17790 + copy_to_user((void *) (start + frame->sig_index), &sig,
17792 + copy_sc_to_user(user_sc, NULL, regs,
17793 + &signal_frame_sc.common.arch) ||
17794 + copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) ||
17795 + copy_to_user((void *) sigs, &mask->sig[1], sig_size) ||
17796 + copy_restorer(restorer, start, frame->sr_index, frame->sr_relative))
17799 + PT_REGS_IP(regs) = handler;
17800 + PT_REGS_SP(regs) = start + frame->sp_index;
17806 + * Overrides for Emacs so that we follow Linus's tabbing style.
17807 + * Emacs will notice this stuff at the end of the file and automatically
17808 + * adjust the settings for this buffer only. This must remain at the end
17810 + * ---------------------------------------------------------------------------
17811 + * Local variables:
17812 + * c-file-style: "linux"
17815 diff -Naur -X ../exclude-files orig/arch/um/kernel/gmon_syms.c um/arch/um/kernel/gmon_syms.c
17816 --- orig/arch/um/kernel/gmon_syms.c Wed Dec 31 19:00:00 1969
17817 +++ um/arch/um/kernel/gmon_syms.c Wed Oct 23 21:08:04 2002
17820 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17821 + * Licensed under the GPL
17824 +#include "linux/module.h"
17826 +extern void __bb_init_func(void *);
17827 +EXPORT_SYMBOL(__bb_init_func);
17830 + * Overrides for Emacs so that we follow Linus's tabbing style.
17831 + * Emacs will notice this stuff at the end of the file and automatically
17832 + * adjust the settings for this buffer only. This must remain at the end
17834 + * ---------------------------------------------------------------------------
17835 + * Local variables:
17836 + * c-file-style: "linux"
17839 diff -Naur -X ../exclude-files orig/arch/um/kernel/gprof_syms.c um/arch/um/kernel/gprof_syms.c
17840 --- orig/arch/um/kernel/gprof_syms.c Wed Dec 31 19:00:00 1969
17841 +++ um/arch/um/kernel/gprof_syms.c Wed Oct 23 21:08:04 2002
17844 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17845 + * Licensed under the GPL
17848 +#include "linux/module.h"
17850 +extern void mcount(void);
17851 +EXPORT_SYMBOL(mcount);
17854 + * Overrides for Emacs so that we follow Linus's tabbing style.
17855 + * Emacs will notice this stuff at the end of the file and automatically
17856 + * adjust the settings for this buffer only. This must remain at the end
17858 + * ---------------------------------------------------------------------------
17859 + * Local variables:
17860 + * c-file-style: "linux"
17863 diff -Naur -X ../exclude-files orig/arch/um/kernel/helper.c um/arch/um/kernel/helper.c
17864 --- orig/arch/um/kernel/helper.c Wed Dec 31 19:00:00 1969
17865 +++ um/arch/um/kernel/helper.c Thu Oct 31 10:34:23 2002
17868 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17869 + * Licensed under the GPL
17872 +#include <stdio.h>
17873 +#include <stdlib.h>
17874 +#include <unistd.h>
17875 +#include <errno.h>
17876 +#include <fcntl.h>
17877 +#include <sched.h>
17878 +#include <sys/signal.h>
17879 +#include <sys/wait.h>
17881 +#include "kern_util.h"
17884 +struct helper_data {
17885 + void (*pre_exec)(void*);
17891 +/* Debugging aid, changed only from gdb */
17892 +int helper_pause = 0;
17894 +static void helper_hup(int sig)
17898 +static int helper_child(void *arg)
17900 + struct helper_data *data = arg;
17901 + char **argv = data->argv;
17903 + if(helper_pause){
17904 + signal(SIGHUP, helper_hup);
17907 + if(data->pre_exec != NULL)
17908 + (*data->pre_exec)(data->pre_data);
17909 + execvp(argv[0], argv);
17910 + printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
17911 + write(data->fd, &errno, sizeof(errno));
17912 + os_kill_process(os_getpid(), 0);
17916 +/* XXX The alloc_stack here breaks if this is called in the tracing thread */
17918 +int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
17919 + unsigned long *stack_out)
17921 + struct helper_data data;
17922 + unsigned long stack, sp;
17923 + int pid, fds[2], err, n;
17925 + if((stack_out != NULL) && (*stack_out != 0))
17926 + stack = *stack_out;
17927 + else stack = alloc_stack(0, um_in_interrupt());
17928 + if(stack == 0) return(-ENOMEM);
17930 + err = os_pipe(fds, 1, 0);
17932 + printk("run_helper : pipe failed, errno = %d\n", -err);
17935 + if(fcntl(fds[1], F_SETFD, 1) != 0){
17936 + printk("run_helper : setting FD_CLOEXEC failed, errno = %d\n",
17941 + sp = stack + page_size() - sizeof(void *);
17942 + data.pre_exec = pre_exec;
17943 + data.pre_data = pre_data;
17944 + data.argv = argv;
17945 + data.fd = fds[1];
17946 + pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
17948 + printk("run_helper : clone failed, errno = %d\n", errno);
17952 + n = read(fds[0], &err, sizeof(err));
17954 + printk("run_helper : read on pipe failed, errno = %d\n",
17959 + waitpid(pid, NULL, 0);
17963 + if(stack_out == NULL) free_stack(stack, 0);
17964 + else *stack_out = stack;
17968 +int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
17969 + unsigned long *stack_out, int stack_order)
17971 + unsigned long stack, sp;
17974 + stack = alloc_stack(stack_order, um_in_interrupt());
17975 + if(stack == 0) return(-ENOMEM);
17977 + sp = stack + (page_size() << stack_order) - sizeof(void *);
17978 + pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
17980 + printk("run_helper_thread : clone failed, errno = %d\n",
17984 + if(stack_out == NULL){
17985 + pid = waitpid(pid, &status, 0);
17987 + printk("run_helper_thread - wait failed, errno = %d\n",
17989 + if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
17990 + printk("run_helper_thread - thread returned status "
17991 + "0x%x\n", status);
17992 + free_stack(stack, stack_order);
17994 + else *stack_out = stack;
17998 +int helper_wait(int pid, int block)
18002 + ret = waitpid(pid, NULL, WNOHANG);
18004 + printk("helper_wait : waitpid failed, errno = %d\n", errno);
18011 + * Overrides for Emacs so that we follow Linus's tabbing style.
18012 + * Emacs will notice this stuff at the end of the file and automatically
18013 + * adjust the settings for this buffer only. This must remain at the end
18015 + * ---------------------------------------------------------------------------
18016 + * Local variables:
18017 + * c-file-style: "linux"
18020 diff -Naur -X ../exclude-files orig/arch/um/kernel/init_task.c um/arch/um/kernel/init_task.c
18021 --- orig/arch/um/kernel/init_task.c Wed Dec 31 19:00:00 1969
18022 +++ um/arch/um/kernel/init_task.c Sat Dec 28 19:58:44 2002
18025 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
18026 + * Licensed under the GPL
18029 +#include "linux/config.h"
18030 +#include "linux/mm.h"
18031 +#include "linux/sched.h"
18032 +#include "linux/version.h"
18033 +#include "asm/uaccess.h"
18034 +#include "asm/pgtable.h"
18035 +#include "user_util.h"
18036 +#include "mem_user.h"
18038 +static struct fs_struct init_fs = INIT_FS;
18039 +static struct files_struct init_files = INIT_FILES;
18040 +static struct signal_struct init_signals = INIT_SIGNALS;
18041 +struct mm_struct init_mm = INIT_MM(init_mm);
18044 + * Initial task structure.
18046 + * We need to make sure that this is 16384-byte aligned due to the
18047 + * way process stacks are handled. This is done by having a special
18048 + * "init_task" linker map entry..
18051 +union task_union init_task_union
18052 +__attribute__((__section__(".data.init_task"))) =
18053 +{ INIT_TASK(init_task_union.task) };
18055 +struct task_struct *alloc_task_struct(void)
18057 + return((struct task_struct *)
18058 + __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
18061 +void unprotect_stack(unsigned long stack)
18063 + protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
18067 +void free_task_struct(struct task_struct *task)
18069 + /* free_pages decrements the page counter and only actually frees
18070 + * the pages if they are now not accessed by anything.
18072 + free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
18076 + * Overrides for Emacs so that we follow Linus's tabbing style.
18077 + * Emacs will notice this stuff at the end of the file and automatically
18078 + * adjust the settings for this buffer only. This must remain at the end
18080 + * ---------------------------------------------------------------------------
18081 + * Local variables:
18082 + * c-file-style: "linux"
18085 diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_kern.c um/arch/um/kernel/initrd_kern.c
18086 --- orig/arch/um/kernel/initrd_kern.c Wed Dec 31 19:00:00 1969
18087 +++ um/arch/um/kernel/initrd_kern.c Wed Oct 23 21:08:04 2002
18090 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
18091 + * Licensed under the GPL
18094 +#include "linux/init.h"
18095 +#include "linux/bootmem.h"
18096 +#include "linux/blk.h"
18097 +#include "asm/types.h"
18098 +#include "user_util.h"
18099 +#include "kern_util.h"
18100 +#include "initrd.h"
18104 +/* Changed by uml_initrd_setup, which is a setup */
18105 +static char *initrd __initdata = NULL;
18107 +static int __init read_initrd(void)
18113 + if(initrd == NULL) return 0;
18114 + err = os_file_size(initrd, &size);
18115 + if(err) return 0;
18116 + area = alloc_bootmem(size);
18117 + if(area == NULL) return 0;
18118 + if(load_initrd(initrd, area, size) == -1) return 0;
18119 + initrd_start = (unsigned long) area;
18120 + initrd_end = initrd_start + size;
18124 +__uml_postsetup(read_initrd);
18126 +static int __init uml_initrd_setup(char *line, int *add)
18132 +__uml_setup("initrd=", uml_initrd_setup,
18133 +"initrd=<initrd image>\n"
18134 +" This is used to boot UML from an initrd image. The argument is the\n"
18135 +" name of the file containing the image.\n\n"
18139 + * Overrides for Emacs so that we follow Linus's tabbing style.
18140 + * Emacs will notice this stuff at the end of the file and automatically
18141 + * adjust the settings for this buffer only. This must remain at the end
18143 + * ---------------------------------------------------------------------------
18144 + * Local variables:
18145 + * c-file-style: "linux"
18148 diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_user.c um/arch/um/kernel/initrd_user.c
18149 --- orig/arch/um/kernel/initrd_user.c Wed Dec 31 19:00:00 1969
18150 +++ um/arch/um/kernel/initrd_user.c Wed Oct 23 21:08:04 2002
18153 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
18154 + * Licensed under the GPL
18157 +#include <unistd.h>
18158 +#include <sys/types.h>
18159 +#include <sys/stat.h>
18160 +#include <fcntl.h>
18161 +#include <errno.h>
18163 +#include "user_util.h"
18164 +#include "kern_util.h"
18166 +#include "initrd.h"
18169 +int load_initrd(char *filename, void *buf, int size)
18173 + if((fd = os_open_file(filename, of_read(OPENFLAGS()), 0)) < 0){
18174 + printk("Opening '%s' failed - errno = %d\n", filename, errno);
18177 + if((n = read(fd, buf, size)) != size){
18178 + printk("Read of %d bytes from '%s' returned %d, errno = %d\n",
18179 + size, filename, n, errno);
18186 + * Overrides for Emacs so that we follow Linus's tabbing style.
18187 + * Emacs will notice this stuff at the end of the file and automatically
18188 + * adjust the settings for this buffer only. This must remain at the end
18190 + * ---------------------------------------------------------------------------
18191 + * Local variables:
18192 + * c-file-style: "linux"
18195 diff -Naur -X ../exclude-files orig/arch/um/kernel/irq.c um/arch/um/kernel/irq.c
18196 --- orig/arch/um/kernel/irq.c Wed Dec 31 19:00:00 1969
18197 +++ um/arch/um/kernel/irq.c Wed Mar 26 14:45:29 2003
18200 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
18201 + * Licensed under the GPL
18202 + * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
18203 + * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
18206 +#include "linux/config.h"
18207 +#include "linux/kernel.h"
18208 +#include "linux/smp.h"
18209 +#include "linux/irq.h"
18210 +#include "linux/kernel_stat.h"
18211 +#include "linux/interrupt.h"
18212 +#include "linux/random.h"
18213 +#include "linux/slab.h"
18214 +#include "linux/file.h"
18215 +#include "linux/proc_fs.h"
18216 +#include "linux/init.h"
18217 +#include "linux/seq_file.h"
18218 +#include "asm/irq.h"
18219 +#include "asm/hw_irq.h"
18220 +#include "asm/hardirq.h"
18221 +#include "asm/atomic.h"
18222 +#include "asm/signal.h"
18223 +#include "asm/system.h"
18224 +#include "asm/errno.h"
18225 +#include "asm/uaccess.h"
18226 +#include "user_util.h"
18227 +#include "kern_util.h"
18228 +#include "irq_user.h"
18230 +static void register_irq_proc (unsigned int irq);
18232 +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
18233 + { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
18236 + * Generic no controller code
18239 +static void enable_none(unsigned int irq) { }
18240 +static unsigned int startup_none(unsigned int irq) { return 0; }
18241 +static void disable_none(unsigned int irq) { }
18242 +static void ack_none(unsigned int irq)
18245 + * 'what should we do if we get a hw irq event on an illegal vector'.
18246 + * each architecture has to answer this themselves, it doesnt deserve
18247 + * a generic callback i think.
18250 + printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
18251 +#ifdef CONFIG_X86_LOCAL_APIC
18253 + * Currently unexpected vectors happen only on SMP and APIC.
18254 + * We _must_ ack these because every local APIC has only N
18255 + * irq slots per priority level, and a 'hanging, unacked' IRQ
18256 + * holds up an irq slot - in excessive cases (when multiple
18257 + * unexpected vectors occur) that might lock up the APIC
18265 +/* startup is the same as "enable", shutdown is same as "disable" */
18266 +#define shutdown_none disable_none
18267 +#define end_none enable_none
18269 +struct hw_interrupt_type no_irq_type = {
18280 +volatile unsigned long irq_err_count;
18283 + * Generic, controller-independent functions:
18286 +int get_irq_list(char *buf)
18289 + unsigned long flags;
18290 + struct irqaction * action;
18293 + p += sprintf(p, " ");
18294 + for (j=0; j<smp_num_cpus; j++)
18295 + p += sprintf(p, "CPU%d ",j);
18298 + for (i = 0 ; i < NR_IRQS ; i++) {
18299 + spin_lock_irqsave(&irq_desc[i].lock, flags);
18300 + action = irq_desc[i].action;
18303 + p += sprintf(p, "%3d: ",i);
18304 +#ifndef CONFIG_SMP
18305 + p += sprintf(p, "%10u ", kstat_irqs(i));
18307 + for (j = 0; j < smp_num_cpus; j++)
18308 + p += sprintf(p, "%10u ",
18309 + kstat.irqs[cpu_logical_map(j)][i]);
18311 + p += sprintf(p, " %14s", irq_desc[i].handler->typename);
18312 + p += sprintf(p, " %s", action->name);
18314 + for (action=action->next; action; action = action->next)
18315 + p += sprintf(p, ", %s", action->name);
18318 + spin_unlock_irqrestore(&irq_desc[i].lock, flags);
18320 + p += sprintf(p, "\n");
18323 + p += sprintf(p, "LOC: ");
18324 + for (j = 0; j < smp_num_cpus; j++)
18325 + p += sprintf(p, "%10u ",
18326 + apic_timer_irqs[cpu_logical_map(j)]);
18327 + p += sprintf(p, "\n");
18330 + p += sprintf(p, "ERR: %10lu\n", irq_err_count);
18336 + * This should really return information about whether
18337 + * we should do bottom half handling etc. Right now we
18338 + * end up _always_ checking the bottom half, which is a
18339 + * waste of time and is not what some drivers would
18342 +int handle_IRQ_event(unsigned int irq, struct pt_regs * regs,
18343 + struct irqaction * action)
18346 + int cpu = smp_processor_id();
18348 + irq_enter(cpu, irq);
18350 + status = 1; /* Force the "do bottom halves" bit */
18352 + if (!(action->flags & SA_INTERRUPT))
18356 + status |= action->flags;
18357 + action->handler(irq, action->dev_id, regs);
18358 + action = action->next;
18359 + } while (action);
18360 + if (status & SA_SAMPLE_RANDOM)
18361 + add_interrupt_randomness(irq);
18364 + irq_exit(cpu, irq);
18370 + * Generic enable/disable code: this just calls
18371 + * down into the PIC-specific version for the actual
18372 + * hardware disable after having gotten the irq
18373 + * controller lock.
18377 + * disable_irq_nosync - disable an irq without waiting
18378 + * @irq: Interrupt to disable
18380 + * Disable the selected interrupt line. Disables of an interrupt
18381 + * stack. Unlike disable_irq(), this function does not ensure existing
18382 + * instances of the IRQ handler have completed before returning.
18384 + * This function may be called from IRQ context.
18387 +void inline disable_irq_nosync(unsigned int irq)
18389 + irq_desc_t *desc = irq_desc + irq;
18390 + unsigned long flags;
18392 + spin_lock_irqsave(&desc->lock, flags);
18393 + if (!desc->depth++) {
18394 + desc->status |= IRQ_DISABLED;
18395 + desc->handler->disable(irq);
18397 + spin_unlock_irqrestore(&desc->lock, flags);
18401 + * disable_irq - disable an irq and wait for completion
18402 + * @irq: Interrupt to disable
18404 + * Disable the selected interrupt line. Disables of an interrupt
18405 + * stack. That is for two disables you need two enables. This
18406 + * function waits for any pending IRQ handlers for this interrupt
18407 + * to complete before returning. If you use this function while
18408 + * holding a resource the IRQ handler may need you will deadlock.
18410 + * This function may be called - with care - from IRQ context.
18413 +void disable_irq(unsigned int irq)
18415 + disable_irq_nosync(irq);
18417 + if (!local_irq_count(smp_processor_id())) {
18420 + } while (irq_desc[irq].status & IRQ_INPROGRESS);
18425 + * enable_irq - enable interrupt handling on an irq
18426 + * @irq: Interrupt to enable
18428 + * Re-enables the processing of interrupts on this IRQ line
18429 + * providing no disable_irq calls are now in effect.
18431 + * This function may be called from IRQ context.
18434 +void enable_irq(unsigned int irq)
18436 + irq_desc_t *desc = irq_desc + irq;
18437 + unsigned long flags;
18439 + spin_lock_irqsave(&desc->lock, flags);
18440 + switch (desc->depth) {
18442 + unsigned int status = desc->status & ~IRQ_DISABLED;
18443 + desc->status = status;
18444 + if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
18445 + desc->status = status | IRQ_REPLAY;
18446 + hw_resend_irq(desc->handler,irq);
18448 + desc->handler->enable(irq);
18449 + /* fall-through */
18455 + printk(KERN_ERR "enable_irq() unbalanced from %p\n",
18456 + __builtin_return_address(0));
18458 + spin_unlock_irqrestore(&desc->lock, flags);
18462 + * do_IRQ handles all normal device IRQ's (the special
18463 + * SMP cross-CPU interrupts have their own specific
18466 +unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
18469 + * 0 return value means that this irq is already being
18470 + * handled by some other CPU. (or is disabled)
18472 + int cpu = smp_processor_id();
18473 + irq_desc_t *desc = irq_desc + irq;
18474 + struct irqaction * action;
18475 + unsigned int status;
18477 + kstat.irqs[cpu][irq]++;
18478 + spin_lock(&desc->lock);
18479 + desc->handler->ack(irq);
18481 + REPLAY is when Linux resends an IRQ that was dropped earlier
18482 + WAITING is used by probe to mark irqs that are being tested
18484 + status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
18485 + status |= IRQ_PENDING; /* we _want_ to handle it */
18488 + * If the IRQ is disabled for whatever reason, we cannot
18489 + * use the action we have.
18492 + if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
18493 + action = desc->action;
18494 + status &= ~IRQ_PENDING; /* we commit to handling */
18495 + status |= IRQ_INPROGRESS; /* we are handling it */
18497 + desc->status = status;
18500 + * If there is no IRQ handler or it was disabled, exit early.
18501 + Since we set PENDING, if another processor is handling
18502 + a different instance of this same irq, the other processor
18503 + will take care of it.
18509 + * Edge triggered interrupts need to remember
18510 + * pending events.
18511 + * This applies to any hw interrupts that allow a second
18512 + * instance of the same irq to arrive while we are in do_IRQ
18513 + * or in the handler. But the code here only handles the _second_
18514 + * instance of the irq, not the third or fourth. So it is mostly
18515 + * useful for irq hardware that does not mask cleanly in an
18516 + * SMP environment.
18519 + spin_unlock(&desc->lock);
18520 + handle_IRQ_event(irq, (struct pt_regs *) regs, action);
18521 + spin_lock(&desc->lock);
18523 + if (!(desc->status & IRQ_PENDING))
18525 + desc->status &= ~IRQ_PENDING;
18527 + desc->status &= ~IRQ_INPROGRESS;
18530 + * The ->end() handler has to deal with interrupts which got
18531 + * disabled while the handler was running.
18533 + desc->handler->end(irq);
18534 + spin_unlock(&desc->lock);
18536 + if (softirq_pending(cpu))
18542 + * request_irq - allocate an interrupt line
18543 + * @irq: Interrupt line to allocate
18544 + * @handler: Function to be called when the IRQ occurs
18545 + * @irqflags: Interrupt type flags
18546 + * @devname: An ascii name for the claiming device
18547 + * @dev_id: A cookie passed back to the handler function
18549 + * This call allocates interrupt resources and enables the
18550 + * interrupt line and IRQ handling. From the point this
18551 + * call is made your handler function may be invoked. Since
18552 + * your handler function must clear any interrupt the board
18553 + * raises, you must take care both to initialise your hardware
18554 + * and to set up the interrupt handler in the right order.
18556 + * Dev_id must be globally unique. Normally the address of the
18557 + * device data structure is used as the cookie. Since the handler
18558 + * receives this value it makes sense to use it.
18560 + * If your interrupt is shared you must pass a non NULL dev_id
18561 + * as this is required when freeing the interrupt.
18565 + * SA_SHIRQ Interrupt is shared
18567 + * SA_INTERRUPT Disable local interrupts while processing
18569 + * SA_SAMPLE_RANDOM The interrupt can be used for entropy
18573 +int request_irq(unsigned int irq,
18574 + void (*handler)(int, void *, struct pt_regs *),
18575 + unsigned long irqflags,
18576 + const char * devname,
18580 + struct irqaction * action;
18584 + * Sanity-check: shared interrupts should REALLY pass in
18585 + * a real dev-ID, otherwise we'll have trouble later trying
18586 + * to figure out which interrupt is which (messes up the
18587 + * interrupt freeing logic etc).
18589 + if (irqflags & SA_SHIRQ) {
18591 + printk(KERN_ERR "Bad boy: %s (at 0x%x) called us "
18592 + "without a dev_id!\n", devname, (&irq)[-1]);
18596 + if (irq >= NR_IRQS)
18601 + action = (struct irqaction *)
18602 + kmalloc(sizeof(struct irqaction), GFP_KERNEL);
18606 + action->handler = handler;
18607 + action->flags = irqflags;
18608 + action->mask = 0;
18609 + action->name = devname;
18610 + action->next = NULL;
18611 + action->dev_id = dev_id;
18613 + retval = setup_irq(irq, action);
18619 +int um_request_irq(unsigned int irq, int fd, int type,
18620 + void (*handler)(int, void *, struct pt_regs *),
18621 + unsigned long irqflags, const char * devname,
18626 + err = request_irq(irq, handler, irqflags, devname, dev_id);
18631 + err = activate_fd(irq, fd, type, dev_id);
18635 +/* this was setup_x86_irq but it seems pretty generic */
18636 +int setup_irq(unsigned int irq, struct irqaction * new)
18639 + unsigned long flags;
18640 + struct irqaction *old, **p;
18641 + irq_desc_t *desc = irq_desc + irq;
18644 + * Some drivers like serial.c use request_irq() heavily,
18645 + * so we have to be careful not to interfere with a
18646 + * running system.
18648 + if (new->flags & SA_SAMPLE_RANDOM) {
18650 + * This function might sleep, we want to call it first,
18651 + * outside of the atomic block.
18652 + * Yes, this might clear the entropy pool if the wrong
18653 + * driver is attempted to be loaded, without actually
18654 + * installing a new handler, but is this really a problem,
18655 + * only the sysadmin is able to do this.
18657 + rand_initialize_irq(irq);
18661 + * The following block of code has to be executed atomically
18663 + spin_lock_irqsave(&desc->lock,flags);
18664 + p = &desc->action;
18665 + if ((old = *p) != NULL) {
18666 + /* Can't share interrupts unless both agree to */
18667 + if (!(old->flags & new->flags & SA_SHIRQ)) {
18668 + spin_unlock_irqrestore(&desc->lock,flags);
18672 + /* add new interrupt at end of irq queue */
18684 + desc->status &= ~IRQ_DISABLED;
18685 + desc->handler->startup(irq);
18687 + spin_unlock_irqrestore(&desc->lock,flags);
18689 + register_irq_proc(irq);
18694 + * free_irq - free an interrupt
18695 + * @irq: Interrupt line to free
18696 + * @dev_id: Device identity to free
18698 + * Remove an interrupt handler. The handler is removed and if the
18699 + * interrupt line is no longer in use by any driver it is disabled.
18700 + * On a shared IRQ the caller must ensure the interrupt is disabled
18701 + * on the card it drives before calling this function. The function
18702 + * does not return until any executing interrupts for this IRQ
18703 + * have completed.
18705 + * This function may be called from interrupt context.
18707 + * Bugs: Attempting to free an irq in a handler for the same irq hangs
18711 +void free_irq(unsigned int irq, void *dev_id)
18713 + irq_desc_t *desc;
18714 + struct irqaction **p;
18715 + unsigned long flags;
18717 + if (irq >= NR_IRQS)
18720 + desc = irq_desc + irq;
18721 + spin_lock_irqsave(&desc->lock,flags);
18722 + p = &desc->action;
18724 + struct irqaction * action = *p;
18726 + struct irqaction **pp = p;
18727 + p = &action->next;
18728 + if (action->dev_id != dev_id)
18731 + /* Found it - now remove it from the list of entries */
18732 + *pp = action->next;
18733 + if (!desc->action) {
18734 + desc->status |= IRQ_DISABLED;
18735 + desc->handler->shutdown(irq);
18737 + free_irq_by_irq_and_dev(irq, dev_id);
18738 + spin_unlock_irqrestore(&desc->lock,flags);
18741 + /* Wait to make sure it's not being used on another CPU */
18742 + while (desc->status & IRQ_INPROGRESS)
18748 + printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
18749 + spin_unlock_irqrestore(&desc->lock,flags);
18754 +/* These are initialized by sysctl_init, which is called from init/main.c */
18755 +static struct proc_dir_entry * root_irq_dir;
18756 +static struct proc_dir_entry * irq_dir [NR_IRQS];
18757 +static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
18759 +/* These are read and written as longs, so a read won't see a partial write
18760 + * even during a race.
18762 +static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
18764 +#define HEX_DIGITS 8
18766 +static int irq_affinity_read_proc (char *page, char **start, off_t off,
18767 + int count, int *eof, void *data)
18769 + if (count < HEX_DIGITS+1)
18771 + return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
18774 +static unsigned int parse_hex_value (const char *buffer,
18775 + unsigned long count, unsigned long *ret)
18777 + unsigned char hexnum [HEX_DIGITS];
18778 + unsigned long value;
18783 + if (count > HEX_DIGITS)
18784 + count = HEX_DIGITS;
18785 + if (copy_from_user(hexnum, buffer, count))
18789 + * Parse the first 8 characters as a hex string, any non-hex char
18790 + * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
18794 + for (i = 0; i < count; i++) {
18795 + unsigned int c = hexnum[i];
18798 + case '0' ... '9': c -= '0'; break;
18799 + case 'a' ... 'f': c -= 'a'-10; break;
18800 + case 'A' ... 'F': c -= 'A'-10; break;
18804 + value = (value << 4) | c;
18811 +static int irq_affinity_write_proc (struct file *file, const char *buffer,
18812 + unsigned long count, void *data)
18814 + int irq = (long) data, full_count = count, err;
18815 + unsigned long new_value;
18817 + if (!irq_desc[irq].handler->set_affinity)
18820 + err = parse_hex_value(buffer, count, &new_value);
18824 + * Do not allow disabling IRQs completely - it's a too easy
18825 + * way to make the system unusable accidentally :-) At least
18826 + * one online CPU still has to be targeted.
18828 + if (!(new_value & cpu_online_map))
18832 + irq_affinity[irq] = new_value;
18833 + irq_desc[irq].handler->set_affinity(irq, new_value);
18835 + return full_count;
18838 +static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
18839 + int count, int *eof, void *data)
18841 + unsigned long *mask = (unsigned long *) data;
18842 + if (count < HEX_DIGITS+1)
18844 + return sprintf (page, "%08lx\n", *mask);
18847 +static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
18848 + unsigned long count, void *data)
18850 + unsigned long *mask = (unsigned long *) data, full_count = count, err;
18851 + unsigned long new_value;
18853 + err = parse_hex_value(buffer, count, &new_value);
18857 + *mask = new_value;
18858 + return full_count;
18861 +#define MAX_NAMELEN 10
18863 +static void register_irq_proc (unsigned int irq)
18865 + struct proc_dir_entry *entry;
18866 + char name [MAX_NAMELEN];
18868 + if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
18872 + memset(name, 0, MAX_NAMELEN);
18873 + sprintf(name, "%d", irq);
18875 + /* create /proc/irq/1234 */
18876 + irq_dir[irq] = proc_mkdir(name, root_irq_dir);
18878 + /* create /proc/irq/1234/smp_affinity */
18879 + entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
18881 + entry->nlink = 1;
18882 + entry->data = (void *)(long)irq;
18883 + entry->read_proc = irq_affinity_read_proc;
18884 + entry->write_proc = irq_affinity_write_proc;
18886 + smp_affinity_entry[irq] = entry;
18889 +/* Read and written as a long */
18890 +unsigned long prof_cpu_mask = -1;
18892 +void __init init_irq_proc (void)
18894 + struct proc_dir_entry *entry;
18897 + /* create /proc/irq */
18898 + root_irq_dir = proc_mkdir("irq", 0);
18900 + /* create /proc/irq/prof_cpu_mask */
18901 + entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
18903 + entry->nlink = 1;
18904 + entry->data = (void *)&prof_cpu_mask;
18905 + entry->read_proc = prof_cpu_mask_read_proc;
18906 + entry->write_proc = prof_cpu_mask_write_proc;
18909 + * Create entries for all existing IRQs.
18911 + for (i = 0; i < NR_IRQS; i++)
18912 + register_irq_proc(i);
18915 +static spinlock_t irq_spinlock = SPIN_LOCK_UNLOCKED;
18917 +unsigned long irq_lock(void)
18919 + unsigned long flags;
18921 + spin_lock_irqsave(&irq_spinlock, flags);
18925 +void irq_unlock(unsigned long flags)
18927 + spin_unlock_irqrestore(&irq_spinlock, flags);
18930 +unsigned long probe_irq_on(void)
18935 +int probe_irq_off(unsigned long val)
18940 +static unsigned int startup_SIGIO_irq(unsigned int irq)
18945 +static void shutdown_SIGIO_irq(unsigned int irq)
18949 +static void enable_SIGIO_irq(unsigned int irq)
18953 +static void disable_SIGIO_irq(unsigned int irq)
18957 +static void mask_and_ack_SIGIO(unsigned int irq)
18961 +static void end_SIGIO_irq(unsigned int irq)
18965 +static unsigned int startup_SIGVTALRM_irq(unsigned int irq)
18970 +static void shutdown_SIGVTALRM_irq(unsigned int irq)
18974 +static void enable_SIGVTALRM_irq(unsigned int irq)
18978 +static void disable_SIGVTALRM_irq(unsigned int irq)
18982 +static void mask_and_ack_SIGVTALRM(unsigned int irq)
18986 +static void end_SIGVTALRM_irq(unsigned int irq)
18990 +static struct hw_interrupt_type SIGIO_irq_type = {
18992 + startup_SIGIO_irq,
18993 + shutdown_SIGIO_irq,
18994 + enable_SIGIO_irq,
18995 + disable_SIGIO_irq,
18996 + mask_and_ack_SIGIO,
19001 +static struct hw_interrupt_type SIGVTALRM_irq_type = {
19003 + startup_SIGVTALRM_irq,
19004 + shutdown_SIGVTALRM_irq,
19005 + enable_SIGVTALRM_irq,
19006 + disable_SIGVTALRM_irq,
19007 + mask_and_ack_SIGVTALRM,
19008 + end_SIGVTALRM_irq,
19012 +void __init init_IRQ(void)
19016 + irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
19017 + irq_desc[TIMER_IRQ].action = 0;
19018 + irq_desc[TIMER_IRQ].depth = 1;
19019 + irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type;
19020 + enable_irq(TIMER_IRQ);
19021 + for(i=1;i<NR_IRQS;i++){
19022 + irq_desc[i].status = IRQ_DISABLED;
19023 + irq_desc[i].action = 0;
19024 + irq_desc[i].depth = 1;
19025 + irq_desc[i].handler = &SIGIO_irq_type;
19028 + init_irq_signals(0);
19032 + * Overrides for Emacs so that we follow Linus's tabbing style.
19033 + * Emacs will notice this stuff at the end of the file and automatically
19034 + * adjust the settings for this buffer only. This must remain at the end
19036 + * ---------------------------------------------------------------------------
19037 + * Local variables:
19038 + * c-file-style: "linux"
19041 diff -Naur -X ../exclude-files orig/arch/um/kernel/irq_user.c um/arch/um/kernel/irq_user.c
19042 --- orig/arch/um/kernel/irq_user.c Wed Dec 31 19:00:00 1969
19043 +++ um/arch/um/kernel/irq_user.c Sun Dec 22 15:49:46 2002
19046 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19047 + * Licensed under the GPL
19050 +#include <stdlib.h>
19051 +#include <unistd.h>
19052 +#include <errno.h>
19053 +#include <fcntl.h>
19054 +#include <signal.h>
19055 +#include <string.h>
19056 +#include <sys/poll.h>
19057 +#include <sys/types.h>
19058 +#include <sys/time.h>
19059 +#include "user_util.h"
19060 +#include "kern_util.h"
19062 +#include "process.h"
19063 +#include "signal_user.h"
19064 +#include "sigio.h"
19065 +#include "irq_user.h"
19069 + struct irq_fd *next;
19076 + int current_events;
19080 +static struct irq_fd *active_fds = NULL;
19081 +static struct irq_fd **last_irq_ptr = &active_fds;
19083 +static struct pollfd *pollfds = NULL;
19084 +static int pollfds_num = 0;
19085 +static int pollfds_size = 0;
19087 +extern int io_count, intr_count;
19089 +void sigio_handler(int sig, union uml_pt_regs *regs)
19091 + struct irq_fd *irq_fd, *next;
19094 + if(smp_sigio_handler()) return;
19096 + if((n = poll(pollfds, pollfds_num, 0)) < 0){
19097 + if(errno == EINTR) continue;
19098 + printk("sigio_handler : poll returned %d, "
19099 + "errno = %d\n", n, errno);
19102 + if(n == 0) break;
19104 + irq_fd = active_fds;
19105 + for(i = 0; i < pollfds_num; i++){
19106 + if(pollfds[i].revents != 0){
19107 + irq_fd->current_events = pollfds[i].revents;
19108 + pollfds[i].fd = -1;
19110 + irq_fd = irq_fd->next;
19113 + for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){
19114 + next = irq_fd->next;
19115 + if(irq_fd->current_events != 0){
19116 + irq_fd->current_events = 0;
19117 + do_IRQ(irq_fd->irq, regs);
19119 + /* This is here because the next irq may be
19120 + * freed in the handler. If a console goes
19121 + * away, both the read and write irqs will be
19122 + * freed. After do_IRQ, ->next will point to
19124 + * Irqs can't be freed inside their handlers,
19125 + * so the next best thing is to have them
19126 + * marked as needing freeing, so that they
19127 + * can be freed here.
19129 + next = irq_fd->next;
19130 + if(irq_fd->freed)
19131 + free_irq(irq_fd->irq, irq_fd->id);
19137 +int activate_ipi(int fd, int pid)
19139 + return(os_set_fd_async(fd, pid));
19142 +static void maybe_sigio_broken(int fd, int type)
19145 + if((type == IRQ_WRITE) && !pty_output_sigio){
19146 + write_sigio_workaround();
19147 + add_sigio_fd(fd, 0);
19149 + else if((type == IRQ_READ) && !pty_close_sigio){
19150 + write_sigio_workaround();
19151 + add_sigio_fd(fd, 1);
19156 +int activate_fd(int irq, int fd, int type, void *dev_id)
19158 + struct pollfd *tmp_pfd;
19159 + struct irq_fd *new_fd, *irq_fd;
19160 + unsigned long flags;
19161 + int pid, events, err, n, size;
19163 + pid = os_getpid();
19164 + err = os_set_fd_async(fd, pid);
19168 + new_fd = um_kmalloc(sizeof(*new_fd));
19170 + if(new_fd == NULL)
19173 + if(type == IRQ_READ) events = POLLIN | POLLPRI;
19174 + else events = POLLOUT;
19175 + *new_fd = ((struct irq_fd) { .next = NULL,
19181 + .events = events,
19182 + .current_events = 0,
19185 + /* Critical section - locked by a spinlock because this stuff can
19186 + * be changed from interrupt handlers. The stuff above is done
19187 + * outside the lock because it allocates memory.
19190 + /* Actually, it only looks like it can be called from interrupt
19191 + * context. The culprit is reactivate_fd, which calls
19192 + * maybe_sigio_broken, which calls write_sigio_workaround,
19193 + * which calls activate_fd. However, write_sigio_workaround should
19194 + * only be called once, at boot time. That would make it clear that
19195 + * this is called only from process context, and can be locked with
19198 + flags = irq_lock();
19199 + for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
19200 + if((irq_fd->fd == fd) && (irq_fd->type == type)){
19201 + printk("Registering fd %d twice\n", fd);
19202 + printk("Irqs : %d, %d\n", irq_fd->irq, irq);
19203 + printk("Ids : 0x%x, 0x%x\n", irq_fd->id, dev_id);
19209 + if(n == pollfds_size){
19211 + /* Here we have to drop the lock in order to call
19212 + * kmalloc, which might sleep. If something else
19213 + * came in and changed the pollfds array, we free
19214 + * the buffer and try again.
19216 + irq_unlock(flags);
19217 + size = (pollfds_num + 1) * sizeof(pollfds[0]);
19218 + tmp_pfd = um_kmalloc(size);
19219 + flags = irq_lock();
19220 + if(tmp_pfd == NULL)
19222 + if(n == pollfds_size)
19226 + if(pollfds != NULL){
19227 + memcpy(tmp_pfd, pollfds,
19228 + sizeof(pollfds[0]) * pollfds_size);
19231 + pollfds = tmp_pfd;
19235 + if(type == IRQ_WRITE)
19238 + pollfds[pollfds_num] = ((struct pollfd) { .fd = fd,
19239 + .events = events,
19243 + *last_irq_ptr = new_fd;
19244 + last_irq_ptr = &new_fd->next;
19246 + irq_unlock(flags);
19248 + /* This calls activate_fd, so it has to be outside the critical
19251 + maybe_sigio_broken(fd, type);
19256 + irq_unlock(flags);
19262 +static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
19264 + struct irq_fd **prev;
19265 + unsigned long flags;
19268 + flags = irq_lock();
19269 + prev = &active_fds;
19270 + while(*prev != NULL){
19271 + if((*test)(*prev, arg)){
19272 + struct irq_fd *old_fd = *prev;
19273 + if((pollfds[i].fd != -1) &&
19274 + (pollfds[i].fd != (*prev)->fd)){
19275 + printk("free_irq_by_cb - mismatch between "
19276 + "active_fds and pollfds, fd %d vs %d\n",
19277 + (*prev)->fd, pollfds[i].fd);
19280 + memcpy(&pollfds[i], &pollfds[i + 1],
19281 + (pollfds_num - i - 1) * sizeof(pollfds[0]));
19283 + if(last_irq_ptr == &old_fd->next)
19284 + last_irq_ptr = prev;
19285 + *prev = (*prev)->next;
19286 + if(old_fd->type == IRQ_WRITE)
19287 + ignore_sigio_fd(old_fd->fd);
19291 + prev = &(*prev)->next;
19295 + irq_unlock(flags);
19298 +struct irq_and_dev {
19303 +static int same_irq_and_dev(struct irq_fd *irq, void *d)
19305 + struct irq_and_dev *data = d;
19307 + return((irq->irq == data->irq) && (irq->id == data->dev));
19310 +void free_irq_by_irq_and_dev(int irq, void *dev)
19312 + struct irq_and_dev data = ((struct irq_and_dev) { .irq = irq,
19315 + free_irq_by_cb(same_irq_and_dev, &data);
19318 +static int same_fd(struct irq_fd *irq, void *fd)
19320 + return(irq->fd == *((int *) fd));
19323 +void free_irq_by_fd(int fd)
19325 + free_irq_by_cb(same_fd, &fd);
19328 +static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
19330 + struct irq_fd *irq;
19333 + for(irq=active_fds; irq != NULL; irq = irq->next){
19334 + if((irq->fd == fd) && (irq->irq == irqnum)) break;
19338 + printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
19341 + if((pollfds[i].fd != -1) && (pollfds[i].fd != fd)){
19342 + printk("find_irq_by_fd - mismatch between active_fds and "
19343 + "pollfds, fd %d vs %d, need %d\n", irq->fd,
19344 + pollfds[i].fd, fd);
19353 +void free_irq_later(int irq, void *dev_id)
19355 + struct irq_fd *irq_fd;
19356 + unsigned long flags;
19358 + flags = irq_lock();
19359 + for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
19360 + if((irq_fd->irq == irq) && (irq_fd->id == dev_id))
19363 + if(irq_fd == NULL){
19364 + printk("free_irq_later found no irq, irq = %d, "
19365 + "dev_id = 0x%p\n", irq, dev_id);
19368 + irq_fd->freed = 1;
19370 + irq_unlock(flags);
19373 +void reactivate_fd(int fd, int irqnum)
19375 + struct irq_fd *irq;
19376 + unsigned long flags;
19379 + flags = irq_lock();
19380 + irq = find_irq_by_fd(fd, irqnum, &i);
19382 + irq_unlock(flags);
19386 + pollfds[i].fd = irq->fd;
19388 + irq_unlock(flags);
19390 + /* This calls activate_fd, so it has to be outside the critical
19393 + maybe_sigio_broken(fd, irq->type);
19396 +void deactivate_fd(int fd, int irqnum)
19398 + struct irq_fd *irq;
19399 + unsigned long flags;
19402 + flags = irq_lock();
19403 + irq = find_irq_by_fd(fd, irqnum, &i);
19406 + pollfds[i].fd = -1;
19408 + irq_unlock(flags);
19411 +void forward_ipi(int fd, int pid)
19413 + if(fcntl(fd, F_SETOWN, pid) < 0){
19414 + int save_errno = errno;
19415 + if(fcntl(fd, F_GETOWN, 0) != pid){
19416 + printk("forward_ipi: F_SETOWN failed, fd = %d, "
19417 + "me = %d, target = %d, errno = %d\n", fd,
19418 + os_getpid(), pid, save_errno);
19423 +void forward_interrupts(int pid)
19425 + struct irq_fd *irq;
19426 + unsigned long flags;
19428 + flags = irq_lock();
19429 + for(irq=active_fds;irq != NULL;irq = irq->next){
19430 + if(fcntl(irq->fd, F_SETOWN, pid) < 0){
19431 + int save_errno = errno;
19432 + if(fcntl(irq->fd, F_GETOWN, 0) != pid){
19433 + /* XXX Just remove the irq rather than
19434 + * print out an infinite stream of these
19436 + printk("Failed to forward %d to pid %d, "
19437 + "errno = %d\n", irq->fd, pid,
19443 + irq_unlock(flags);
19446 +void init_irq_signals(int on_sigstack)
19448 + __sighandler_t h;
19451 + flags = on_sigstack ? SA_ONSTACK : 0;
19452 + if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
19453 + else h = boot_timer_handler;
19455 + set_handler(SIGVTALRM, h, flags | SA_RESTART,
19456 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
19457 + set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
19458 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
19459 + signal(SIGWINCH, SIG_IGN);
19463 + * Overrides for Emacs so that we follow Linus's tabbing style.
19464 + * Emacs will notice this stuff at the end of the file and automatically
19465 + * adjust the settings for this buffer only. This must remain at the end
19467 + * ---------------------------------------------------------------------------
19468 + * Local variables:
19469 + * c-file-style: "linux"
19472 diff -Naur -X ../exclude-files orig/arch/um/kernel/ksyms.c um/arch/um/kernel/ksyms.c
19473 --- orig/arch/um/kernel/ksyms.c Wed Dec 31 19:00:00 1969
19474 +++ um/arch/um/kernel/ksyms.c Tue Dec 17 13:29:43 2002
19477 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
19478 + * Licensed under the GPL
19481 +#include "linux/config.h"
19482 +#include "linux/module.h"
19483 +#include "linux/string.h"
19484 +#include "linux/smp_lock.h"
19485 +#include "linux/spinlock.h"
19486 +#include "asm/current.h"
19487 +#include "asm/delay.h"
19488 +#include "asm/processor.h"
19489 +#include "asm/unistd.h"
19490 +#include "asm/pgalloc.h"
19491 +#include "asm/pgtable.h"
19492 +#include "asm/page.h"
19493 +#include "kern_util.h"
19494 +#include "user_util.h"
19496 +#include "helper.h"
19498 +EXPORT_SYMBOL(stop);
19499 +EXPORT_SYMBOL(strtok);
19500 +EXPORT_SYMBOL(uml_physmem);
19501 +EXPORT_SYMBOL(set_signals);
19502 +EXPORT_SYMBOL(get_signals);
19503 +EXPORT_SYMBOL(kernel_thread);
19504 +EXPORT_SYMBOL(__const_udelay);
19505 +EXPORT_SYMBOL(__udelay);
19506 +EXPORT_SYMBOL(sys_waitpid);
19507 +EXPORT_SYMBOL(task_size);
19508 +EXPORT_SYMBOL(flush_tlb_range);
19509 +EXPORT_SYMBOL(host_task_size);
19510 +EXPORT_SYMBOL(arch_validate);
19512 +EXPORT_SYMBOL(region_pa);
19513 +EXPORT_SYMBOL(region_va);
19514 +EXPORT_SYMBOL(phys_mem_map);
19515 +EXPORT_SYMBOL(page_mem_map);
19516 +EXPORT_SYMBOL(high_physmem);
19517 +EXPORT_SYMBOL(empty_zero_page);
19518 +EXPORT_SYMBOL(um_virt_to_phys);
19519 +EXPORT_SYMBOL(mode_tt);
19520 +EXPORT_SYMBOL(handle_page_fault);
19522 +EXPORT_SYMBOL(os_getpid);
19523 +EXPORT_SYMBOL(os_open_file);
19524 +EXPORT_SYMBOL(os_read_file);
19525 +EXPORT_SYMBOL(os_write_file);
19526 +EXPORT_SYMBOL(os_seek_file);
19527 +EXPORT_SYMBOL(os_pipe);
19528 +EXPORT_SYMBOL(os_file_type);
19529 +EXPORT_SYMBOL(os_close_file);
19530 +EXPORT_SYMBOL(helper_wait);
19531 +EXPORT_SYMBOL(os_shutdown_socket);
19532 +EXPORT_SYMBOL(os_connect_socket);
19533 +EXPORT_SYMBOL(run_helper);
19534 +EXPORT_SYMBOL(start_thread);
19535 +EXPORT_SYMBOL(dump_thread);
19537 +/* This is here because UML expands open to sys_open, not to a system
19538 + * call instruction.
19540 +EXPORT_SYMBOL(sys_open);
19541 +EXPORT_SYMBOL(sys_lseek);
19542 +EXPORT_SYMBOL(sys_read);
19543 +EXPORT_SYMBOL(sys_wait4);
19547 +/* required for SMP */
19549 +extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
19550 +EXPORT_SYMBOL_NOVERS(__write_lock_failed);
19552 +extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
19553 +EXPORT_SYMBOL_NOVERS(__read_lock_failed);
19555 +EXPORT_SYMBOL(kernel_flag_cacheline);
19556 +EXPORT_SYMBOL(smp_num_cpus);
19561 + * Overrides for Emacs so that we follow Linus's tabbing style.
19562 + * Emacs will notice this stuff at the end of the file and automatically
19563 + * adjust the settings for this buffer only. This must remain at the end
19565 + * ---------------------------------------------------------------------------
19566 + * Local variables:
19567 + * c-file-style: "linux"
19570 diff -Naur -X ../exclude-files orig/arch/um/kernel/mem.c um/arch/um/kernel/mem.c
19571 --- orig/arch/um/kernel/mem.c Wed Dec 31 19:00:00 1969
19572 +++ um/arch/um/kernel/mem.c Sun Mar 30 14:30:26 2003
19575 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
19576 + * Licensed under the GPL
19579 +#include "linux/config.h"
19580 +#include "linux/types.h"
19581 +#include "linux/mm.h"
19582 +#include "linux/fs.h"
19583 +#include "linux/init.h"
19584 +#include "linux/bootmem.h"
19585 +#include "linux/swap.h"
19586 +#include "linux/slab.h"
19587 +#include "linux/vmalloc.h"
19588 +#include "linux/highmem.h"
19589 +#include "asm/page.h"
19590 +#include "asm/pgtable.h"
19591 +#include "asm/pgalloc.h"
19592 +#include "asm/bitops.h"
19593 +#include "asm/uaccess.h"
19594 +#include "asm/tlb.h"
19595 +#include "user_util.h"
19596 +#include "kern_util.h"
19597 +#include "mem_user.h"
19602 +#include "mode_kern.h"
19603 +#include "uml_uaccess.h"
19605 +/* Changed during early boot */
19606 +pgd_t swapper_pg_dir[1024];
19607 +unsigned long high_physmem;
19608 +unsigned long vm_start;
19609 +unsigned long vm_end;
19610 +unsigned long highmem;
19611 +unsigned long *empty_zero_page = NULL;
19612 +unsigned long *empty_bad_page = NULL;
19614 +/* Not modified */
19615 +const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
19617 +/* Changed during early boot */
19618 +static unsigned long totalram_pages = 0;
19620 +extern char __init_begin, __init_end;
19621 +extern long physmem_size;
19624 +/* Not changed by UML */
19625 +mmu_gather_t mmu_gathers[NR_CPUS];
19628 +/* Changed during early boot */
19629 +int kmalloc_ok = 0;
19631 +#define NREGIONS (phys_region_index(0xffffffff) - phys_region_index(0x0) + 1)
19632 +struct mem_region *regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] = NULL };
19633 +#define REGION_SIZE ((0xffffffff & ~REGION_MASK) + 1)
19635 +/* Changed during early boot */
19636 +static unsigned long brk_end;
19638 +static void map_cb(void *unused)
19640 + map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
19643 +void unmap_physmem(void)
19645 + os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
19648 +extern char __binary_start;
19650 +void mem_init(void)
19652 + unsigned long start;
19654 +#ifdef CONFIG_HIGHMEM
19655 + highmem_start_page = phys_page(__pa(high_physmem));
19658 + /* clear the zero-page */
19659 + memset((void *) empty_zero_page, 0, PAGE_SIZE);
19661 + /* Map in the area just after the brk now that kmalloc is about
19662 + * to be turned on.
19664 + brk_end = (unsigned long) UML_ROUND_UP(sbrk(0));
19666 + initial_thread_cb(map_cb, NULL);
19667 + free_bootmem(__pa(brk_end), uml_reserved - brk_end);
19668 + uml_reserved = brk_end;
19670 + /* Fill in any hole at the start of the binary */
19671 + start = (unsigned long) &__binary_start;
19672 + if(uml_physmem != start){
19673 + map_memory(uml_physmem, __pa(uml_physmem), start - uml_physmem,
19677 + /* this will put all low memory onto the freelists */
19678 + totalram_pages = free_all_bootmem();
19679 + totalram_pages += highmem >> PAGE_SHIFT;
19680 + max_mapnr = totalram_pages;
19681 + num_physpages = totalram_pages;
19682 + printk(KERN_INFO "Memory: %luk available\n",
19683 + (unsigned long) nr_free_pages() << (PAGE_SHIFT-10));
19687 +/* Changed during early boot */
19688 +static unsigned long kmem_top = 0;
19690 +unsigned long get_kmem_end(void)
19692 + if(kmem_top == 0)
19693 + kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
19694 + return(kmem_top);
19697 +void set_kmem_end(unsigned long new)
19702 +#if CONFIG_HIGHMEM
19703 +/* Changed during early boot */
19705 +pgprot_t kmap_prot;
19707 +#define kmap_get_fixmap_pte(vaddr) \
19708 + pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
19710 +void __init kmap_init(void)
19712 + unsigned long kmap_vstart;
19714 + /* cache the first kmap pte */
19715 + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
19716 + kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
19718 + kmap_prot = PAGE_KERNEL;
19720 +#endif /* CONFIG_HIGHMEM */
19722 +static void __init fixrange_init(unsigned long start, unsigned long end,
19729 + unsigned long vaddr;
19732 + i = __pgd_offset(vaddr);
19733 + j = __pmd_offset(vaddr);
19734 + pgd = pgd_base + i;
19736 + for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
19737 + pmd = (pmd_t *)pgd;
19738 + for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
19739 + if (pmd_none(*pmd)) {
19740 + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
19741 + set_pmd(pmd, __pmd(_KERNPG_TABLE +
19742 + (unsigned long) __pa(pte)));
19743 + if (pte != pte_offset(pmd, 0))
19746 + vaddr += PMD_SIZE;
19752 +int init_maps(struct mem_region *region)
19754 + struct page *p, *map;
19757 + if(region == &physmem_region){
19758 + region->mem_map = mem_map;
19761 + else if(region->mem_map != NULL) return(0);
19763 + n = region->len >> PAGE_SHIFT;
19764 + len = n * sizeof(struct page);
19766 + map = kmalloc(len, GFP_KERNEL);
19767 + if(map == NULL) map = vmalloc(len);
19769 + else map = alloc_bootmem_low_pages(len);
19773 + for(i = 0; i < n; i++){
19775 + set_page_count(p, 0);
19776 + SetPageReserved(p);
19777 + INIT_LIST_HEAD(&p->list);
19779 + region->mem_map = map;
19783 +DECLARE_MUTEX(regions_sem);
19785 +static int setup_one_range(int fd, char *driver, unsigned long start,
19786 + unsigned long pfn, int len,
19787 + struct mem_region *region)
19791 + down(®ions_sem);
19792 + for(i = 0; i < NREGIONS; i++){
19793 + if(regions[i] == NULL) break;
19795 + if(i == NREGIONS){
19796 + printk("setup_one_range : no free regions\n");
19802 + fd = create_mem_file(len);
19804 + if(region == NULL){
19806 + region = kmalloc(sizeof(*region), GFP_KERNEL);
19807 + else region = alloc_bootmem_low_pages(sizeof(*region));
19808 + if(region == NULL)
19809 + panic("Failed to allocating mem_region");
19812 + *region = ((struct mem_region) { .driver = driver,
19813 + .start_pfn = pfn,
19817 + regions[i] = region;
19819 + up(®ions_sem);
19823 +#ifdef CONFIG_HIGHMEM
19824 +static void init_highmem(void)
19829 + unsigned long vaddr;
19832 + * Permanent kmaps:
19834 + vaddr = PKMAP_BASE;
19835 + fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, swapper_pg_dir);
19837 + pgd = swapper_pg_dir + __pgd_offset(vaddr);
19838 + pmd = pmd_offset(pgd, vaddr);
19839 + pte = pte_offset(pmd, vaddr);
19840 + pkmap_page_table = pte;
19845 +void setup_highmem(unsigned long len)
19847 + struct mem_region *region;
19848 + struct page *page, *map;
19849 + unsigned long phys;
19850 + int i, cur, index;
19852 + phys = physmem_size;
19854 + cur = min(len, (unsigned long) REGION_SIZE);
19855 + i = setup_one_range(-1, NULL, -1, phys >> PAGE_SHIFT, cur,
19858 + printk("setup_highmem - setup_one_range failed\n");
19861 + region = regions[i];
19862 + index = phys / PAGE_SIZE;
19863 + region->mem_map = &mem_map[index];
19865 + map = region->mem_map;
19866 + for(i = 0; i < (cur >> PAGE_SHIFT); i++){
19868 + ClearPageReserved(page);
19869 + set_bit(PG_highmem, &page->flags);
19870 + atomic_set(&page->count, 1);
19871 + __free_page(page);
19875 + } while(len > 0);
19879 +void paging_init(void)
19881 + struct mem_region *region;
19882 + unsigned long zones_size[MAX_NR_ZONES], start, end, vaddr;
19885 + empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
19886 + empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
19887 + for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++)
19888 + zones_size[i] = 0;
19889 + zones_size[0] = (high_physmem >> PAGE_SHIFT) -
19890 + (uml_physmem >> PAGE_SHIFT);
19891 + zones_size[2] = highmem >> PAGE_SHIFT;
19892 + free_area_init(zones_size);
19893 + start = phys_region_index(__pa(uml_physmem));
19894 + end = phys_region_index(__pa(high_physmem - 1));
19895 + for(i = start; i <= end; i++){
19896 + region = regions[i];
19897 + index = (region->start - uml_physmem) / PAGE_SIZE;
19898 + region->mem_map = &mem_map[index];
19899 + if(i > start) free_bootmem(__pa(region->start), region->len);
19903 + * Fixed mappings, only the page table structure has to be
19904 + * created - mappings will be set by set_fixmap():
19906 + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
19907 + fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir);
19909 +#if CONFIG_HIGHMEM
19911 + setup_highmem(highmem);
19915 +/* Changed by meminfo_compat, which is a setup */
19916 +static int meminfo_22 = 0;
19918 +static int meminfo_compat(char *str)
19924 +__setup("22_meminfo", meminfo_compat);
19926 +void si_meminfo(struct sysinfo *val)
19928 + val->totalram = totalram_pages;
19929 + val->sharedram = 0;
19930 + val->freeram = nr_free_pages();
19931 + val->bufferram = atomic_read(&buffermem_pages);
19932 + val->totalhigh = highmem >> PAGE_SHIFT;
19933 + val->freehigh = nr_free_highpages();
19934 + val->mem_unit = PAGE_SIZE;
19936 + val->freeram <<= PAGE_SHIFT;
19937 + val->bufferram <<= PAGE_SHIFT;
19938 + val->totalram <<= PAGE_SHIFT;
19939 + val->sharedram <<= PAGE_SHIFT;
19943 +pte_t __bad_page(void)
19945 + clear_page(empty_bad_page);
19946 + return pte_mkdirty(mk_pte((struct page *) empty_bad_page,
19950 +/* This can't do anything because nothing in the kernel image can be freed
19951 + * since it's not in kernel physical memory.
19954 +void free_initmem(void)
19958 +#ifdef CONFIG_BLK_DEV_INITRD
19960 +void free_initrd_mem(unsigned long start, unsigned long end)
19963 + printk ("Freeing initrd memory: %ldk freed\n",
19964 + (end - start) >> 10);
19965 + for (; start < end; start += PAGE_SIZE) {
19966 + ClearPageReserved(virt_to_page(start));
19967 + set_page_count(virt_to_page(start), 1);
19968 + free_page(start);
19969 + totalram_pages++;
19975 +int do_check_pgt_cache(int low, int high)
19978 + if(pgtable_cache_size > high) {
19980 + if (pgd_quicklist) {
19981 + free_pgd_slow(get_pgd_fast());
19984 + if (pmd_quicklist) {
19985 + pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
19988 + if (pte_quicklist) {
19989 + pte_free_slow(pte_alloc_one_fast(NULL, 0));
19992 + } while(pgtable_cache_size > low);
19997 +void show_mem(void)
19999 + int i, total = 0, reserved = 0;
20000 + int shared = 0, cached = 0;
20003 + printk("Mem-info:\n");
20004 + show_free_areas();
20005 + printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
20009 + if(PageHighMem(mem_map + i))
20011 + if(PageReserved(mem_map + i))
20013 + else if(PageSwapCache(mem_map + i))
20015 + else if(page_count(mem_map + i))
20016 + shared += page_count(mem_map + i) - 1;
20018 + printk("%d pages of RAM\n", total);
20019 + printk("%d pages of HIGHMEM\n", highmem);
20020 + printk("%d reserved pages\n", reserved);
20021 + printk("%d pages shared\n", shared);
20022 + printk("%d pages swap cached\n", cached);
20023 + printk("%ld pages in page table cache\n", pgtable_cache_size);
20027 +static int __init uml_mem_setup(char *line, int *add)
20030 + physmem_size = memparse(line,&retptr);
20033 +__uml_setup("mem=", uml_mem_setup,
20034 +"mem=<Amount of desired ram>\n"
20035 +" This controls how much \"physical\" memory the kernel allocates\n"
20036 +" for the system. The size is specified as a number followed by\n"
20037 +" one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
20038 +" This is not related to the amount of memory in the physical\n"
20039 +" machine. It can be more, and the excess, if it's ever used, will\n"
20040 +" just be swapped out.\n Example: mem=64M\n\n"
20043 +struct page *arch_validate(struct page *page, int mask, int order)
20045 + unsigned long addr, zero = 0;
20049 + if(page == NULL) return(page);
20050 + if(PageHighMem(page)) return(page);
20052 + addr = (unsigned long) page_address(page);
20053 + for(i = 0; i < (1 << order); i++){
20054 + current->thread.fault_addr = (void *) addr;
20055 + if(__do_copy_to_user((void *) addr, &zero,
20057 + ¤t->thread.fault_addr,
20058 + ¤t->thread.fault_catcher)){
20059 + if(!(mask & __GFP_WAIT)) return(NULL);
20062 + addr += PAGE_SIZE;
20064 + if(i == (1 << order)) return(page);
20065 + page = _alloc_pages(mask, order);
20069 +DECLARE_MUTEX(vm_reserved_sem);
20070 +static struct list_head vm_reserved = LIST_HEAD_INIT(vm_reserved);
20072 +/* Static structures, linked in to the list in early boot */
20073 +static struct vm_reserved head = {
20074 + .list = LIST_HEAD_INIT(head.list),
20076 + .end = 0xffffffff
20079 +static struct vm_reserved tail = {
20080 + .list = LIST_HEAD_INIT(tail.list),
20082 + .end = 0xffffffff
20085 +void set_usable_vm(unsigned long start, unsigned long end)
20087 + list_add(&head.list, &vm_reserved);
20088 + list_add(&tail.list, &head.list);
20089 + head.end = start;
20090 + tail.start = end;
20093 +int reserve_vm(unsigned long start, unsigned long end, void *e)
20096 + struct vm_reserved *entry = e, *reserved, *prev;
20097 + struct list_head *ele;
20100 + down(&vm_reserved_sem);
20101 + list_for_each(ele, &vm_reserved){
20102 + reserved = list_entry(ele, struct vm_reserved, list);
20103 + if(reserved->start >= end) goto found;
20105 + panic("Reserved vm out of range");
20107 + prev = list_entry(ele->prev, struct vm_reserved, list);
20108 + if(prev->end > start)
20109 + panic("Can't reserve vm");
20110 + if(entry == NULL)
20111 + entry = kmalloc(sizeof(*entry), GFP_KERNEL);
20112 + if(entry == NULL){
20113 + printk("reserve_vm : Failed to allocate entry\n");
20117 + *entry = ((struct vm_reserved)
20118 + { .list = LIST_HEAD_INIT(entry->list),
20121 + list_add(&entry->list, &prev->list);
20124 + up(&vm_reserved_sem);
20128 +unsigned long get_vm(unsigned long len)
20130 + struct vm_reserved *this, *next;
20131 + struct list_head *ele;
20132 + unsigned long start;
20135 + down(&vm_reserved_sem);
20136 + list_for_each(ele, &vm_reserved){
20137 + this = list_entry(ele, struct vm_reserved, list);
20138 + next = list_entry(ele->next, struct vm_reserved, list);
20139 + if((this->start < next->start) &&
20140 + (this->end + len + PAGE_SIZE <= next->start))
20143 + up(&vm_reserved_sem);
20146 + up(&vm_reserved_sem);
20147 + start = (unsigned long) UML_ROUND_UP(this->end) + PAGE_SIZE;
20148 + err = reserve_vm(start, start + len, NULL);
20149 + if(err) return(0);
20153 +int nregions(void)
20155 + return(NREGIONS);
20158 +void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn,
20159 + unsigned long len, int need_vm, struct mem_region *region,
20165 + cur = min(len, (unsigned long) REGION_SIZE);
20166 + i = setup_one_range(fd, driver, start, pfn, cur, region);
20167 + region = regions[i];
20168 + if(need_vm && setup_region(region, reserved)){
20170 + regions[i] = NULL;
20174 + if(pfn != -1) pfn += cur;
20176 + } while(len > 0);
20182 + unsigned long size;
20185 +/* iomem regions can only be added on the command line at the moment.
20186 + * Locking will be needed when they can be added via mconsole.
20189 +struct iomem iomem_regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] =
20194 +int num_iomem_regions = 0;
20196 +void add_iomem(char *name, int fd, unsigned long size)
20198 + if(num_iomem_regions == sizeof(iomem_regions)/sizeof(iomem_regions[0]))
20200 + size = (size + PAGE_SIZE - 1) & PAGE_MASK;
20201 + iomem_regions[num_iomem_regions++] =
20202 + ((struct iomem) { .name = name,
20204 + .size = size } );
20207 +int setup_iomem(void)
20209 + struct iomem *iomem;
20212 + for(i = 0; i < num_iomem_regions; i++){
20213 + iomem = &iomem_regions[i];
20214 + setup_range(iomem->fd, iomem->name, -1, -1, iomem->size, 1,
20220 +__initcall(setup_iomem);
20222 +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
20223 +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
20225 +/* Changed during early boot */
20226 +static struct mem_region physmem_region;
20227 +static struct vm_reserved physmem_reserved;
20229 +void setup_physmem(unsigned long start, unsigned long reserve_end,
20230 + unsigned long len)
20232 + struct mem_region *region = &physmem_region;
20233 + struct vm_reserved *reserved = &physmem_reserved;
20234 + unsigned long cur, pfn = 0;
20235 + int do_free = 1, bootmap_size;
20238 + cur = min(len, (unsigned long) REGION_SIZE);
20239 + if(region == NULL)
20240 + region = alloc_bootmem_low_pages(sizeof(*region));
20241 + if(reserved == NULL)
20242 + reserved = alloc_bootmem_low_pages(sizeof(*reserved));
20243 + if((region == NULL) || (reserved == NULL))
20244 + panic("Couldn't allocate physmem region or vm "
20245 + "reservation\n");
20246 + setup_range(-1, NULL, start, pfn, cur, 1, region, reserved);
20249 + unsigned long reserve = reserve_end - start;
20250 + int pfn = PFN_UP(__pa(reserve_end));
20251 + int delta = (len - reserve) >> PAGE_SHIFT;
20253 + bootmap_size = init_bootmem(pfn, pfn + delta);
20254 + free_bootmem(__pa(reserve_end) + bootmap_size,
20255 + cur - bootmap_size - reserve);
20259 + pfn += cur >> PAGE_SHIFT;
20263 + } while(len > 0);
20266 +struct mem_region *phys_region(unsigned long phys)
20268 + unsigned int n = phys_region_index(phys);
20270 + if(regions[n] == NULL)
20271 + panic("Physical address in uninitialized region");
20272 + return(regions[n]);
20275 +unsigned long phys_offset(unsigned long phys)
20277 + return(phys_addr(phys));
20280 +struct page *phys_mem_map(unsigned long phys)
20282 + return((struct page *) phys_region(phys)->mem_map);
20285 +struct page *pte_mem_map(pte_t pte)
20287 + return(phys_mem_map(pte_val(pte)));
20290 +struct mem_region *page_region(struct page *page, int *index_out)
20293 + struct mem_region *region;
20294 + struct page *map;
20296 + for(i = 0; i < NREGIONS; i++){
20297 + region = regions[i];
20298 + if(region == NULL) continue;
20299 + map = region->mem_map;
20300 + if((page >= map) && (page < &map[region->len >> PAGE_SHIFT])){
20301 + if(index_out != NULL) *index_out = i;
20305 + panic("No region found for page");
20309 +unsigned long page_to_pfn(struct page *page)
20311 + struct mem_region *region = page_region(page, NULL);
20313 + return(region->start_pfn + (page - (struct page *) region->mem_map));
20316 +struct mem_region *pfn_to_region(unsigned long pfn, int *index_out)
20318 + struct mem_region *region;
20321 + for(i = 0; i < NREGIONS; i++){
20322 + region = regions[i];
20323 + if(region == NULL)
20326 + if((region->start_pfn <= pfn) &&
20327 + (region->start_pfn + (region->len >> PAGE_SHIFT) > pfn)){
20328 + if(index_out != NULL)
20336 +struct page *pfn_to_page(unsigned long pfn)
20338 + struct mem_region *region = pfn_to_region(pfn, NULL);
20339 + struct page *mem_map = (struct page *) region->mem_map;
20341 + return(&mem_map[pfn - region->start_pfn]);
20344 +unsigned long phys_to_pfn(unsigned long p)
20346 + struct mem_region *region = regions[phys_region_index(p)];
20348 + return(region->start_pfn + (phys_addr(p) >> PAGE_SHIFT));
20351 +unsigned long pfn_to_phys(unsigned long pfn)
20354 + struct mem_region *region = pfn_to_region(pfn, &n);
20356 + return(mk_phys((pfn - region->start_pfn) << PAGE_SHIFT, n));
20359 +struct page *page_mem_map(struct page *page)
20361 + return((struct page *) page_region(page, NULL)->mem_map);
20364 +extern unsigned long region_pa(void *virt)
20366 + struct mem_region *region;
20367 + unsigned long addr = (unsigned long) virt;
20370 + for(i = 0; i < NREGIONS; i++){
20371 + region = regions[i];
20372 + if(region == NULL) continue;
20373 + if((region->start <= addr) &&
20374 + (addr <= region->start + region->len))
20375 + return(mk_phys(addr - region->start, i));
20377 + panic("region_pa : no region for virtual address");
20381 +extern void *region_va(unsigned long phys)
20383 + return((void *) (phys_region(phys)->start + phys_addr(phys)));
20386 +unsigned long page_to_phys(struct page *page)
20389 + struct mem_region *region = page_region(page, &n);
20390 + struct page *map = region->mem_map;
20391 + return(mk_phys((page - map) << PAGE_SHIFT, n));
20394 +struct page *phys_to_page(unsigned long phys)
20396 + struct page *mem_map;
20398 + mem_map = phys_mem_map(phys);
20399 + return(mem_map + (phys_offset(phys) >> PAGE_SHIFT));
20402 +static int setup_mem_maps(void)
20404 + struct mem_region *region;
20407 + for(i = 0; i < NREGIONS; i++){
20408 + region = regions[i];
20409 + if((region != NULL) && (region->fd > 0)) init_maps(region);
20414 +__initcall(setup_mem_maps);
20417 + * Overrides for Emacs so that we follow Linus's tabbing style.
20418 + * Emacs will notice this stuff at the end of the file and automatically
20419 + * adjust the settings for this buffer only. This must remain at the end
20421 + * ---------------------------------------------------------------------------
20422 + * Local variables:
20423 + * c-file-style: "linux"
20426 diff -Naur -X ../exclude-files orig/arch/um/kernel/mem_user.c um/arch/um/kernel/mem_user.c
20427 --- orig/arch/um/kernel/mem_user.c Wed Dec 31 19:00:00 1969
20428 +++ um/arch/um/kernel/mem_user.c Thu Mar 6 16:05:21 2003
20431 + * arch/um/kernel/mem_user.c
20433 + * BRIEF MODULE DESCRIPTION
20434 + * user side memory routines for supporting IO memory inside user mode linux
20436 + * Copyright (C) 2001 RidgeRun, Inc.
20437 + * Author: RidgeRun, Inc.
20438 + * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
20440 + * This program is free software; you can redistribute it and/or modify it
20441 + * under the terms of the GNU General Public License as published by the
20442 + * Free Software Foundation; either version 2 of the License, or (at your
20443 + * option) any later version.
20445 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
20446 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20447 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20448 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20449 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20450 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
20451 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20452 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20453 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20454 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20456 + * You should have received a copy of the GNU General Public License along
20457 + * with this program; if not, write to the Free Software Foundation, Inc.,
20458 + * 675 Mass Ave, Cambridge, MA 02139, USA.
20461 +#include <stdio.h>
20462 +#include <stdlib.h>
20463 +#include <stddef.h>
20464 +#include <stdarg.h>
20465 +#include <unistd.h>
20466 +#include <fcntl.h>
20467 +#include <errno.h>
20468 +#include <string.h>
20469 +#include <sys/stat.h>
20470 +#include <sys/types.h>
20471 +#include <sys/mman.h>
20472 +#include "kern_util.h"
20474 +#include "user_util.h"
20475 +#include "mem_user.h"
20478 +#include "tempfile.h"
20480 +extern struct mem_region physmem_region;
20482 +#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
20484 +int create_mem_file(unsigned long len)
20489 + fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
20490 + if (fchmod(fd, 0777) < 0){
20491 + perror("fchmod");
20494 + if(os_seek_file(fd, len) < 0){
20499 + if(write(fd, &zero, 1) != 1){
20503 + if(fcntl(fd, F_SETFD, 1) != 0)
20504 + perror("Setting FD_CLOEXEC failed");
20508 +int setup_region(struct mem_region *region, void *entry)
20510 + void *loc, *start;
20514 + if(region->start != -1){
20515 + err = reserve_vm(region->start,
20516 + region->start + region->len, entry);
20518 + printk("setup_region : failed to reserve "
20519 + "0x%x - 0x%x for driver '%s'\n",
20521 + region->start + region->len,
20526 + else region->start = get_vm(region->len);
20527 + if(region->start == 0){
20528 + if(region->driver == NULL) driver = "physmem";
20529 + else driver = region->driver;
20530 + printk("setup_region : failed to find vm for "
20531 + "driver '%s' (length %d)\n", driver, region->len);
20534 + if(region->start == uml_physmem){
20535 + start = (void *) uml_reserved;
20536 + offset = uml_reserved - uml_physmem;
20539 + start = (void *) region->start;
20543 + loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE,
20544 + MAP_SHARED | MAP_FIXED, region->fd, offset);
20545 + if(loc != start){
20546 + perror("Mapping memory");
20552 +static int __init parse_iomem(char *str, int *add)
20554 + struct stat64 buf;
20555 + char *file, *driver;
20559 + file = strchr(str,',');
20560 + if(file == NULL){
20561 + printf("parse_iomem : failed to parse iomem\n");
20566 + fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
20568 + printf("parse_iomem - Couldn't open io file, errno = %d\n",
20572 + if(fstat64(fd, &buf) < 0) {
20573 + printf("parse_iomem - cannot fstat file, errno = %d\n", errno);
20576 + add_iomem(driver, fd, buf.st_size);
20580 +__uml_setup("iomem=", parse_iomem,
20581 +"iomem=<name>,<file>\n"
20582 +" Configure <file> as an IO memory region named <name>.\n\n"
20587 +int logging_fd = -1;
20589 +int logging_line = 0;
20590 +char logging_buf[256];
20592 +void log(char *fmt, ...)
20595 + struct timeval tv;
20596 + struct openflags flags;
20598 + if(logging == 0) return;
20599 + if(logging_fd < 0){
20600 + flags = of_create(of_trunc(of_rdrw(OPENFLAGS())));
20601 + logging_fd = os_open_file("log", flags, 0644);
20603 + gettimeofday(&tv, NULL);
20604 + sprintf(logging_buf, "%d\t %u.%u ", logging_line++, tv.tv_sec,
20606 + va_start(ap, fmt);
20607 + vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
20609 + write(logging_fd, logging_buf, strlen(logging_buf));
20613 +int map_memory(unsigned long virt, unsigned long phys, unsigned long len,
20614 + int r, int w, int x)
20616 + struct mem_region *region = phys_region(phys);
20618 + return(os_map_memory((void *) virt, region->fd, phys_offset(phys), len,
20622 +int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
20623 + int must_succeed)
20625 + if(os_protect_memory((void *) addr, len, r, w, x) < 0){
20627 + panic("protect failed, errno = %d", errno);
20628 + else return(-errno);
20633 +unsigned long find_iomem(char *driver, unsigned long *len_out)
20635 + struct mem_region *region;
20639 + for(i = 0; i < n; i++){
20640 + region = regions[i];
20641 + if(region == NULL) continue;
20642 + if((region->driver != NULL) &&
20643 + !strcmp(region->driver, driver)){
20644 + *len_out = region->len;
20645 + return(region->start);
20653 + * Overrides for Emacs so that we follow Linus's tabbing style.
20654 + * Emacs will notice this stuff at the end of the file and automatically
20655 + * adjust the settings for this buffer only. This must remain at the end
20657 + * ---------------------------------------------------------------------------
20658 + * Local variables:
20659 + * c-file-style: "linux"
20662 diff -Naur -X ../exclude-files orig/arch/um/kernel/mprot.h um/arch/um/kernel/mprot.h
20663 --- orig/arch/um/kernel/mprot.h Wed Dec 31 19:00:00 1969
20664 +++ um/arch/um/kernel/mprot.h Wed Oct 23 21:08:04 2002
20666 +#ifndef __MPROT_H__
20667 +#define __MPROT_H__
20669 +extern void no_access(unsigned long addr, unsigned int len);
20672 diff -Naur -X ../exclude-files orig/arch/um/kernel/process.c um/arch/um/kernel/process.c
20673 --- orig/arch/um/kernel/process.c Wed Dec 31 19:00:00 1969
20674 +++ um/arch/um/kernel/process.c Wed Apr 23 20:36:15 2003
20677 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
20678 + * Licensed under the GPL
20681 +#include <stdio.h>
20682 +#include <unistd.h>
20683 +#include <signal.h>
20684 +#include <sched.h>
20685 +#include <errno.h>
20686 +#include <stdarg.h>
20687 +#include <fcntl.h>
20688 +#include <stdlib.h>
20689 +#include <setjmp.h>
20690 +#include <sys/time.h>
20691 +#include <sys/ptrace.h>
20692 +#include <sys/ioctl.h>
20693 +#include <sys/wait.h>
20694 +#include <sys/mman.h>
20695 +#include <asm/ptrace.h>
20696 +#include <asm/sigcontext.h>
20697 +#include <asm/unistd.h>
20698 +#include <asm/page.h>
20699 +#include "user_util.h"
20700 +#include "kern_util.h"
20702 +#include "process.h"
20703 +#include "signal_kern.h"
20704 +#include "signal_user.h"
20705 +#include "sysdep/ptrace.h"
20706 +#include "sysdep/sigcontext.h"
20707 +#include "irq_user.h"
20708 +#include "ptrace_user.h"
20709 +#include "time_user.h"
20712 +#include "uml-config.h"
20713 +#include "choose-mode.h"
20715 +#ifdef UML_CONFIG_MODE_SKAS
20717 +#include "skas_ptrace.h"
20720 +void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
20722 + int flags = 0, pages;
20724 + if(sig_stack != NULL){
20725 + pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
20726 + set_sigstack(sig_stack, pages * page_size());
20727 + flags = SA_ONSTACK;
20729 + if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
20732 +void init_new_thread_signals(int altstack)
20734 + int flags = altstack ? SA_ONSTACK : 0;
20736 + set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags,
20737 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20738 + set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags,
20739 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20740 + set_handler(SIGFPE, (__sighandler_t) sig_handler, flags,
20741 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20742 + set_handler(SIGILL, (__sighandler_t) sig_handler, flags,
20743 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20744 + set_handler(SIGBUS, (__sighandler_t) sig_handler, flags,
20745 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20746 + set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags,
20747 + SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20748 + set_handler(SIGUSR2, (__sighandler_t) sig_handler,
20749 + SA_NOMASK | flags, -1);
20750 + signal(SIGHUP, SIG_IGN);
20752 + init_irq_signals(altstack);
20756 + int (*tramp)(void *);
20757 + void *tramp_data;
20758 + unsigned long temp_stack;
20763 +/* See above for why sigkill is here */
20765 +int sigkill = SIGKILL;
20767 +int outer_tramp(void *arg)
20770 + int sig = sigkill;
20773 + t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2,
20774 + t->flags, t->tramp_data);
20775 + if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
20776 + kill(os_getpid(), sig);
20780 +int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
20781 + int clone_flags, int (*tramp)(void *))
20783 + struct tramp arg;
20784 + unsigned long sp;
20785 + int new_pid, status, err;
20787 + /* The trampoline will run on the temporary stack */
20788 + sp = stack_sp(temp_stack);
20790 + clone_flags |= CLONE_FILES | SIGCHLD;
20792 + arg.tramp = tramp;
20793 + arg.tramp_data = thread_arg;
20794 + arg.temp_stack = temp_stack;
20795 + arg.flags = clone_flags;
20797 + /* Start the process and wait for it to kill itself */
20798 + new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
20799 + if(new_pid < 0) return(-errno);
20800 + while((err = waitpid(new_pid, &status, 0) < 0) && (errno == EINTR)) ;
20801 + if(err < 0) panic("Waiting for outer trampoline failed - errno = %d",
20803 + if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
20804 + panic("outer trampoline didn't exit with SIGKILL");
20809 +void suspend_new_thread(int fd)
20813 + os_stop_process(os_getpid());
20815 + if(read(fd, &c, sizeof(c)) != sizeof(c))
20816 + panic("read failed in suspend_new_thread");
20819 +static int ptrace_child(void *arg)
20821 + int pid = os_getpid();
20823 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
20824 + perror("ptrace");
20825 + os_kill_process(pid, 0);
20827 + os_stop_process(pid);
20828 + _exit(os_getpid() == pid);
20831 +static int start_ptraced_child(void **stack_out)
20834 + unsigned long sp;
20835 + int pid, n, status;
20837 + stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
20838 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
20839 + if(stack == MAP_FAILED)
20840 + panic("check_ptrace : mmap failed, errno = %d", errno);
20841 + sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
20842 + pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
20844 + panic("check_ptrace : clone failed, errno = %d", errno);
20845 + n = waitpid(pid, &status, WUNTRACED);
20847 + panic("check_ptrace : wait failed, errno = %d", errno);
20848 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
20849 + panic("check_ptrace : expected SIGSTOP, got status = %d",
20852 + *stack_out = stack;
20856 +static void stop_ptraced_child(int pid, void *stack, int exitcode)
20860 + if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
20861 + panic("check_ptrace : ptrace failed, errno = %d", errno);
20862 + n = waitpid(pid, &status, 0);
20863 + if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode))
20864 + panic("check_ptrace : child exited with status 0x%x", status);
20866 + if(munmap(stack, PAGE_SIZE) < 0)
20867 + panic("check_ptrace : munmap failed, errno = %d", errno);
20870 +void __init check_ptrace(void)
20873 + int pid, syscall, n, status;
20875 + printk("Checking that ptrace can change system call numbers...");
20876 + pid = start_ptraced_child(&stack);
20879 + if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
20880 + panic("check_ptrace : ptrace failed, errno = %d",
20882 + n = waitpid(pid, &status, WUNTRACED);
20884 + panic("check_ptrace : wait failed, errno = %d", errno);
20885 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
20886 + panic("check_ptrace : expected SIGTRAP, "
20887 + "got status = %d", status);
20889 + syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET,
20891 + if(syscall == __NR_getpid){
20892 + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
20895 + panic("check_ptrace : failed to modify system "
20896 + "call, errno = %d", errno);
20900 + stop_ptraced_child(pid, stack, 0);
20904 +int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
20917 +int can_do_skas(void)
20919 +#ifdef UML_CONFIG_MODE_SKAS
20920 + struct ptrace_faultinfo fi;
20922 + int pid, n, ret = 1;
20924 + printf("Checking for the skas3 patch in the host...");
20925 + pid = start_ptraced_child(&stack);
20927 + n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
20930 + printf("not found\n");
20931 + else printf("No (unexpected errno - %d)\n", errno);
20934 + else printf("found\n");
20936 + init_registers(pid);
20937 + stop_ptraced_child(pid, stack, 1);
20939 + printf("Checking for /proc/mm...");
20940 + if(access("/proc/mm", W_OK)){
20941 + printf("not found\n");
20944 + else printf("found\n");
20953 + * Overrides for Emacs so that we follow Linus's tabbing style.
20954 + * Emacs will notice this stuff at the end of the file and automatically
20955 + * adjust the settings for this buffer only. This must remain at the end
20957 + * ---------------------------------------------------------------------------
20958 + * Local variables:
20959 + * c-file-style: "linux"
20962 diff -Naur -X ../exclude-files orig/arch/um/kernel/process_kern.c um/arch/um/kernel/process_kern.c
20963 --- orig/arch/um/kernel/process_kern.c Wed Dec 31 19:00:00 1969
20964 +++ um/arch/um/kernel/process_kern.c Wed Apr 16 16:02:09 2003
20967 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
20968 + * Licensed under the GPL
20971 +#include "linux/config.h"
20972 +#include "linux/kernel.h"
20973 +#include "linux/sched.h"
20974 +#include "linux/interrupt.h"
20975 +#include "linux/mm.h"
20976 +#include "linux/slab.h"
20977 +#include "linux/utsname.h"
20978 +#include "linux/fs.h"
20979 +#include "linux/utime.h"
20980 +#include "linux/smp_lock.h"
20981 +#include "linux/module.h"
20982 +#include "linux/init.h"
20983 +#include "linux/capability.h"
20984 +#include "asm/unistd.h"
20985 +#include "asm/mman.h"
20986 +#include "asm/segment.h"
20987 +#include "asm/stat.h"
20988 +#include "asm/pgtable.h"
20989 +#include "asm/processor.h"
20990 +#include "asm/pgalloc.h"
20991 +#include "asm/spinlock.h"
20992 +#include "asm/uaccess.h"
20993 +#include "asm/user.h"
20994 +#include "user_util.h"
20995 +#include "kern_util.h"
20997 +#include "signal_kern.h"
20998 +#include "signal_user.h"
21000 +#include "irq_user.h"
21001 +#include "mem_user.h"
21002 +#include "time_user.h"
21004 +#include "frame_kern.h"
21005 +#include "sigcontext.h"
21006 +#include "2_5compat.h"
21009 +#include "mode_kern.h"
21010 +#include "choose-mode.h"
21012 +/* This is a per-cpu array. A processor only modifies its entry and it only
21013 + * cares about its entry, so it's OK if another processor is modifying its
21016 +struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
21018 +struct task_struct *get_task(int pid, int require)
21020 + struct task_struct *ret;
21022 + read_lock(&tasklist_lock);
21023 + ret = find_task_by_pid(pid);
21024 + read_unlock(&tasklist_lock);
21026 + if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
21030 +int external_pid(void *t)
21032 + struct task_struct *task = t ? t : current;
21034 + return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
21037 +int pid_to_processor_id(int pid)
21041 + for(i = 0; i < smp_num_cpus; i++){
21042 + if(cpu_tasks[i].pid == pid) return(i);
21047 +void free_stack(unsigned long stack, int order)
21049 + free_pages(stack, order);
21052 +unsigned long alloc_stack(int order, int atomic)
21054 + unsigned long page;
21055 + int flags = GFP_KERNEL;
21057 + if(atomic) flags |= GFP_ATOMIC;
21058 + if((page = __get_free_pages(flags, order)) == 0)
21060 + stack_protections(page);
21064 +int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
21068 + current->thread.request.u.thread.proc = fn;
21069 + current->thread.request.u.thread.arg = arg;
21070 + pid = do_fork(CLONE_VM | flags, 0, NULL, 0);
21071 + if(pid < 0) panic("do_fork failed in kernel_thread");
21075 +void switch_mm(struct mm_struct *prev, struct mm_struct *next,
21076 + struct task_struct *tsk, unsigned cpu)
21078 + if (prev != next)
21079 + clear_bit(cpu, &prev->cpu_vm_mask);
21080 + set_bit(cpu, &next->cpu_vm_mask);
21083 +void set_current(void *t)
21085 + struct task_struct *task = t;
21087 + cpu_tasks[task->processor] = ((struct cpu_task)
21088 + { external_pid(task), task });
21091 +void *_switch_to(void *prev, void *next)
21093 + return(CHOOSE_MODE(_switch_to_tt(prev, next),
21094 + _switch_to_skas(prev, next)));
21097 +void interrupt_end(void)
21099 + if(current->need_resched) schedule();
21100 + if(current->sigpending != 0) do_signal(0);
21103 +void release_thread(struct task_struct *task)
21105 + CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
21108 +void exit_thread(void)
21110 + CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
21111 + unprotect_stack((unsigned long) current);
21114 +void *get_current(void)
21119 +int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
21120 + unsigned long stack_top, struct task_struct * p,
21121 + struct pt_regs *regs)
21123 + p->thread = (struct thread_struct) INIT_THREAD;
21124 + p->thread.kernel_stack = (unsigned long) p + 2 * PAGE_SIZE;
21126 + return(CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr,
21127 + clone_flags, sp, stack_top, p, regs));
21130 +void initial_thread_cb(void (*proc)(void *), void *arg)
21132 + int save_kmalloc_ok = kmalloc_ok;
21135 + CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc,
21137 + kmalloc_ok = save_kmalloc_ok;
21140 +unsigned long stack_sp(unsigned long page)
21142 + return(page + PAGE_SIZE - sizeof(void *));
21145 +int current_pid(void)
21147 + return(current->pid);
21150 +void cpu_idle(void)
21152 + CHOOSE_MODE(init_idle_tt(), init_idle_skas());
21154 + atomic_inc(&init_mm.mm_count);
21155 + current->mm = &init_mm;
21156 + current->active_mm = &init_mm;
21159 + /* endless idle loop with no priority at all */
21160 + SET_PRI(current);
21163 + * although we are an idle CPU, we do not want to
21164 + * get into the scheduler unnecessarily.
21166 + if (current->need_resched) {
21168 + check_pgt_cache();
21174 +int page_size(void)
21176 + return(PAGE_SIZE);
21179 +int page_mask(void)
21181 + return(PAGE_MASK);
21184 +void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
21191 + if(task->mm == NULL)
21192 + return(ERR_PTR(-EINVAL));
21193 + pgd = pgd_offset(task->mm, addr);
21194 + pmd = pmd_offset(pgd, addr);
21195 + if(!pmd_present(*pmd))
21196 + return(ERR_PTR(-EINVAL));
21197 + pte = pte_offset(pmd, addr);
21198 + if(!pte_present(*pte))
21199 + return(ERR_PTR(-EINVAL));
21200 + if(pte_out != NULL)
21202 + return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK));
21205 +char *current_cmd(void)
21207 +#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
21208 + return("(Unknown)");
21210 + void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
21211 + return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
21215 +void force_sigbus(void)
21217 + printk(KERN_ERR "Killing pid %d because of a lack of memory\n",
21220 + sigaddset(¤t->pending.signal, SIGBUS);
21221 + recalc_sigpending(current);
21222 + current->flags |= PF_SIGNALED;
21223 + do_exit(SIGBUS | 0x80);
21226 +void dump_thread(struct pt_regs *regs, struct user *u)
21230 +void enable_hlt(void)
21232 + panic("enable_hlt");
21235 +void disable_hlt(void)
21237 + panic("disable_hlt");
21240 +extern int signal_frame_size;
21242 +void *um_kmalloc(int size)
21244 + return(kmalloc(size, GFP_KERNEL));
21247 +void *um_kmalloc_atomic(int size)
21249 + return(kmalloc(size, GFP_ATOMIC));
21252 +unsigned long get_fault_addr(void)
21254 + return((unsigned long) current->thread.fault_addr);
21257 +EXPORT_SYMBOL(get_fault_addr);
21259 +void not_implemented(void)
21261 + printk(KERN_DEBUG "Something isn't implemented in here\n");
21264 +EXPORT_SYMBOL(not_implemented);
21266 +int user_context(unsigned long sp)
21268 + unsigned long stack;
21270 + stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
21271 + stack += 2 * PAGE_SIZE;
21272 + return(stack != current->thread.kernel_stack);
21275 +extern void remove_umid_dir(void);
21277 +__uml_exitcall(remove_umid_dir);
21279 +extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
21281 +void do_uml_exitcalls(void)
21283 + exitcall_t *call;
21285 + call = &__uml_exitcall_end;
21286 + while (--call >= &__uml_exitcall_begin)
21290 +char *uml_strdup(char *string)
21294 + new = kmalloc(strlen(string) + 1, GFP_KERNEL);
21295 + if(new == NULL) return(NULL);
21296 + strcpy(new, string);
21300 +void *get_init_task(void)
21302 + return(&init_task_union.task);
21305 +int copy_to_user_proc(void *to, void *from, int size)
21307 + return(copy_to_user(to, from, size));
21310 +int copy_from_user_proc(void *to, void *from, int size)
21312 + return(copy_from_user(to, from, size));
21315 +int clear_user_proc(void *buf, int size)
21317 + return(clear_user(buf, size));
21320 +int strlen_user_proc(char *str)
21322 + return(strlen_user(str));
21325 +int smp_sigio_handler(void)
21328 + int cpu = current->processor;
21330 + IPI_handler(cpu);
21337 +int um_in_interrupt(void)
21339 + return(in_interrupt());
21344 + return(current->processor);
21348 + * Overrides for Emacs so that we follow Linus's tabbing style.
21349 + * Emacs will notice this stuff at the end of the file and automatically
21350 + * adjust the settings for this buffer only. This must remain at the end
21352 + * ---------------------------------------------------------------------------
21353 + * Local variables:
21354 + * c-file-style: "linux"
21357 diff -Naur -X ../exclude-files orig/arch/um/kernel/ptrace.c um/arch/um/kernel/ptrace.c
21358 --- orig/arch/um/kernel/ptrace.c Wed Dec 31 19:00:00 1969
21359 +++ um/arch/um/kernel/ptrace.c Sat Dec 28 22:50:21 2002
21362 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
21363 + * Licensed under the GPL
21366 +#include "linux/sched.h"
21367 +#include "linux/mm.h"
21368 +#include "linux/errno.h"
21369 +#include "linux/smp_lock.h"
21370 +#ifdef CONFIG_PROC_MM
21371 +#include "linux/proc_mm.h"
21373 +#include "asm/ptrace.h"
21374 +#include "asm/uaccess.h"
21375 +#include "kern_util.h"
21376 +#include "ptrace_user.h"
21379 + * Called by kernel/ptrace.c when detaching..
21381 +void ptrace_disable(struct task_struct *child)
21385 +extern long do_mmap2(struct task_struct *task, unsigned long addr,
21386 + unsigned long len, unsigned long prot,
21387 + unsigned long flags, unsigned long fd,
21388 + unsigned long pgoff);
21390 +int sys_ptrace(long request, long pid, long addr, long data)
21392 + struct task_struct *child;
21397 + if (request == PTRACE_TRACEME) {
21398 + /* are we already being traced? */
21399 + if (current->ptrace & PT_PTRACED)
21401 + /* set the ptrace bit in the process flags. */
21402 + current->ptrace |= PT_PTRACED;
21407 + read_lock(&tasklist_lock);
21408 + child = find_task_by_pid(pid);
21410 + get_task_struct(child);
21411 + read_unlock(&tasklist_lock);
21416 + if (pid == 1) /* you may not mess with init */
21419 + if (request == PTRACE_ATTACH) {
21420 + ret = ptrace_attach(child);
21424 + ret = ptrace_check_attach(child, request == PTRACE_KILL);
21428 + switch (request) {
21429 + /* when I and D space are separate, these will need to be fixed. */
21430 + case PTRACE_PEEKTEXT: /* read word at location addr. */
21431 + case PTRACE_PEEKDATA: {
21432 + unsigned long tmp;
21436 + copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
21437 + if (copied != sizeof(tmp))
21439 + ret = put_user(tmp,(unsigned long *) data);
21443 + /* read the word at location addr in the USER area. */
21444 + case PTRACE_PEEKUSR: {
21445 + unsigned long tmp;
21448 + if ((addr & 3) || addr < 0)
21451 + tmp = 0; /* Default return condition */
21452 + if(addr < FRAME_SIZE_OFFSET){
21453 + tmp = getreg(child, addr);
21455 + else if((addr >= offsetof(struct user, u_debugreg[0])) &&
21456 + (addr <= offsetof(struct user, u_debugreg[7]))){
21457 + addr -= offsetof(struct user, u_debugreg[0]);
21458 + addr = addr >> 2;
21459 + tmp = child->thread.arch.debugregs[addr];
21461 + ret = put_user(tmp, (unsigned long *) data);
21465 + /* when I and D space are separate, this will have to be fixed. */
21466 + case PTRACE_POKETEXT: /* write the word at location addr. */
21467 + case PTRACE_POKEDATA:
21469 + if (access_process_vm(child, addr, &data, sizeof(data),
21470 + 1) != sizeof(data))
21475 + case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
21477 + if ((addr & 3) || addr < 0)
21480 + if (addr < FRAME_SIZE_OFFSET) {
21481 + ret = putreg(child, addr, data);
21484 + else if((addr >= offsetof(struct user, u_debugreg[0])) &&
21485 + (addr <= offsetof(struct user, u_debugreg[7]))){
21486 + addr -= offsetof(struct user, u_debugreg[0]);
21487 + addr = addr >> 2;
21488 + if((addr == 4) || (addr == 5)) break;
21489 + child->thread.arch.debugregs[addr] = data;
21495 + case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
21496 + case PTRACE_CONT: { /* restart after signal. */
21498 + if ((unsigned long) data > _NSIG)
21500 + if (request == PTRACE_SYSCALL)
21501 + child->ptrace |= PT_TRACESYS;
21503 + child->ptrace &= ~PT_TRACESYS;
21504 + child->exit_code = data;
21505 + wake_up_process(child);
21511 + * make the child exit. Best I can do is send it a sigkill.
21512 + * perhaps it should be put in the status that it wants to
21515 + case PTRACE_KILL: {
21517 + if (child->state == TASK_ZOMBIE) /* already dead */
21519 + child->exit_code = SIGKILL;
21520 + wake_up_process(child);
21524 + case PTRACE_SINGLESTEP: { /* set the trap flag. */
21526 + if ((unsigned long) data > _NSIG)
21528 + child->ptrace &= ~PT_TRACESYS;
21529 + child->ptrace |= PT_DTRACE;
21530 + child->exit_code = data;
21531 + /* give it a chance to run. */
21532 + wake_up_process(child);
21537 + case PTRACE_DETACH:
21538 + /* detach a process that was attached. */
21539 + ret = ptrace_detach(child, data);
21542 +#ifdef PTRACE_GETREGS
21543 + case PTRACE_GETREGS: { /* Get all gp regs from the child. */
21544 + if (!access_ok(VERIFY_WRITE, (unsigned long *)data,
21545 + FRAME_SIZE_OFFSET)) {
21549 + for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
21550 + __put_user(getreg(child, i), (unsigned long *) data);
21551 + data += sizeof(long);
21557 +#ifdef PTRACE_SETREGS
21558 + case PTRACE_SETREGS: { /* Set all gp regs in the child. */
21559 + unsigned long tmp = 0;
21560 + if (!access_ok(VERIFY_READ, (unsigned *)data,
21561 + FRAME_SIZE_OFFSET)) {
21565 + for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
21566 + __get_user(tmp, (unsigned long *) data);
21567 + putreg(child, i, tmp);
21568 + data += sizeof(long);
21574 +#ifdef PTRACE_GETFPREGS
21575 + case PTRACE_GETFPREGS: /* Get the child FPU state. */
21576 + ret = get_fpregs(data, child);
21579 +#ifdef PTRACE_SETFPREGS
21580 + case PTRACE_SETFPREGS: /* Set the child FPU state. */
21581 + ret = set_fpregs(data, child);
21584 +#ifdef PTRACE_GETFPXREGS
21585 + case PTRACE_GETFPXREGS: /* Get the child FPU state. */
21586 + ret = get_fpxregs(data, child);
21589 +#ifdef PTRACE_SETFPXREGS
21590 + case PTRACE_SETFPXREGS: /* Set the child FPU state. */
21591 + ret = set_fpxregs(data, child);
21594 + case PTRACE_FAULTINFO: {
21595 + struct ptrace_faultinfo fault;
21597 + fault = ((struct ptrace_faultinfo)
21598 + { .is_write = child->thread.err,
21599 + .addr = child->thread.cr2 });
21600 + ret = copy_to_user((unsigned long *) data, &fault,
21606 + case PTRACE_SIGPENDING:
21607 + ret = copy_to_user((unsigned long *) data,
21608 + &child->pending.signal,
21609 + sizeof(child->pending.signal));
21612 + case PTRACE_LDT: {
21613 + struct ptrace_ldt ldt;
21615 + if(copy_from_user(&ldt, (unsigned long *) data,
21621 + /* This one is confusing, so just punt and return -EIO for
21627 +#ifdef CONFIG_PROC_MM
21628 + case PTRACE_SWITCH_MM: {
21629 + struct mm_struct *old = child->mm;
21630 + struct mm_struct *new = proc_mm_get_mm(data);
21633 + ret = PTR_ERR(new);
21637 + atomic_inc(&new->mm_users);
21639 + child->active_mm = new;
21650 + free_task_struct(child);
21656 +void syscall_trace(void)
21658 + if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
21659 + != (PT_PTRACED|PT_TRACESYS))
21661 + current->exit_code = SIGTRAP;
21662 + current->state = TASK_STOPPED;
21663 + notify_parent(current, SIGCHLD);
21666 + * this isn't the same as continuing with a signal, but it will do
21667 + * for normal use. strace only continues with a signal if the
21668 + * stopping signal is not SIGTRAP. -brl
21670 + if (current->exit_code) {
21671 + send_sig(current->exit_code, current, 1);
21672 + current->exit_code = 0;
21677 + * Overrides for Emacs so that we follow Linus's tabbing style.
21678 + * Emacs will notice this stuff at the end of the file and automatically
21679 + * adjust the settings for this buffer only. This must remain at the end
21681 + * ---------------------------------------------------------------------------
21682 + * Local variables:
21683 + * c-file-style: "linux"
21686 diff -Naur -X ../exclude-files orig/arch/um/kernel/reboot.c um/arch/um/kernel/reboot.c
21687 --- orig/arch/um/kernel/reboot.c Wed Dec 31 19:00:00 1969
21688 +++ um/arch/um/kernel/reboot.c Mon Dec 30 20:57:42 2002
21691 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
21692 + * Licensed under the GPL
21695 +#include "linux/sched.h"
21696 +#include "user_util.h"
21697 +#include "kern_util.h"
21701 +#include "choose-mode.h"
21704 +static void kill_idlers(int me)
21706 + struct task_struct *p;
21709 + for(i = 0; i < sizeof(init_tasks)/sizeof(init_tasks[0]); i++){
21710 + p = init_tasks[i];
21711 + if((p != NULL) && (p->thread.mode.tt.extern_pid != me) &&
21712 + (p->thread.mode.tt.extern_pid != -1))
21713 + os_kill_process(p->thread.mode.tt.extern_pid, 0);
21718 +static void kill_off_processes(void)
21720 + CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas());
21722 + kill_idlers(os_getpid());
21726 +void uml_cleanup(void)
21728 + kill_off_processes();
21729 + do_uml_exitcalls();
21732 +void machine_restart(char * __unused)
21734 + do_uml_exitcalls();
21735 + kill_off_processes();
21736 + CHOOSE_MODE(reboot_tt(), reboot_skas());
21739 +void machine_power_off(void)
21741 + do_uml_exitcalls();
21742 + kill_off_processes();
21743 + CHOOSE_MODE(halt_tt(), halt_skas());
21746 +void machine_halt(void)
21748 + machine_power_off();
21752 + * Overrides for Emacs so that we follow Linus's tabbing style.
21753 + * Emacs will notice this stuff at the end of the file and automatically
21754 + * adjust the settings for this buffer only. This must remain at the end
21756 + * ---------------------------------------------------------------------------
21757 + * Local variables:
21758 + * c-file-style: "linux"
21761 diff -Naur -X ../exclude-files orig/arch/um/kernel/resource.c um/arch/um/kernel/resource.c
21762 --- orig/arch/um/kernel/resource.c Wed Dec 31 19:00:00 1969
21763 +++ um/arch/um/kernel/resource.c Wed Oct 23 21:08:04 2002
21766 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
21767 + * Licensed under the GPL
21770 +#include "linux/pci.h"
21772 +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
21773 + unsigned long start, unsigned long size)
21779 + * Overrides for Emacs so that we follow Linus's tabbing style.
21780 + * Emacs will notice this stuff at the end of the file and automatically
21781 + * adjust the settings for this buffer only. This must remain at the end
21783 + * ---------------------------------------------------------------------------
21784 + * Local variables:
21785 + * c-file-style: "linux"
21788 diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_kern.c um/arch/um/kernel/sigio_kern.c
21789 --- orig/arch/um/kernel/sigio_kern.c Wed Dec 31 19:00:00 1969
21790 +++ um/arch/um/kernel/sigio_kern.c Wed Oct 23 21:08:04 2002
21793 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
21794 + * Licensed under the GPL
21797 +#include "linux/kernel.h"
21798 +#include "linux/list.h"
21799 +#include "linux/slab.h"
21800 +#include "asm/irq.h"
21802 +#include "sigio.h"
21803 +#include "irq_user.h"
21805 +/* Protected by sigio_lock() called from write_sigio_workaround */
21806 +static int sigio_irq_fd = -1;
21808 +void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
21810 + read_sigio_fd(sigio_irq_fd);
21811 + reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
21814 +int write_sigio_irq(int fd)
21816 + if(um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
21817 + SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio",
21819 + printk("write_sigio_irq : um_request_irq failed\n");
21822 + sigio_irq_fd = fd;
21826 +static spinlock_t sigio_spinlock = SPIN_LOCK_UNLOCKED;
21828 +void sigio_lock(void)
21830 + spin_lock(&sigio_spinlock);
21833 +void sigio_unlock(void)
21835 + spin_unlock(&sigio_spinlock);
21839 + * Overrides for Emacs so that we follow Linus's tabbing style.
21840 + * Emacs will notice this stuff at the end of the file and automatically
21841 + * adjust the settings for this buffer only. This must remain at the end
21843 + * ---------------------------------------------------------------------------
21844 + * Local variables:
21845 + * c-file-style: "linux"
21848 diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_user.c um/arch/um/kernel/sigio_user.c
21849 --- orig/arch/um/kernel/sigio_user.c Wed Dec 31 19:00:00 1969
21850 +++ um/arch/um/kernel/sigio_user.c Sun Dec 29 23:36:35 2002
21853 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
21854 + * Licensed under the GPL
21857 +#include <unistd.h>
21858 +#include <stdlib.h>
21859 +#include <termios.h>
21861 +#include <fcntl.h>
21862 +#include <signal.h>
21863 +#include <errno.h>
21864 +#include <string.h>
21865 +#include <sched.h>
21866 +#include <sys/socket.h>
21867 +#include <sys/poll.h>
21870 +#include "kern_util.h"
21871 +#include "sigio.h"
21872 +#include "helper.h"
21875 +/* Changed during early boot */
21876 +int pty_output_sigio = 0;
21877 +int pty_close_sigio = 0;
21879 +/* Used as a flag during SIGIO testing early in boot */
21880 +static int got_sigio = 0;
21882 +void __init handler(int sig)
21887 +struct openpty_arg {
21893 +static void openpty_cb(void *arg)
21895 + struct openpty_arg *info = arg;
21898 + if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
21899 + info->err = errno;
21902 +void __init check_one_sigio(void (*proc)(int, int))
21904 + struct sigaction old, new;
21905 + struct termios tt;
21906 + struct openpty_arg pty = { .master = -1, .slave = -1 };
21907 + int master, slave, flags;
21909 + initial_thread_cb(openpty_cb, &pty);
21911 + printk("openpty failed, errno = %d\n", pty.err);
21915 + master = pty.master;
21916 + slave = pty.slave;
21918 + if((master == -1) || (slave == -1)){
21919 + printk("openpty failed to allocate a pty\n");
21923 + if(tcgetattr(master, &tt) < 0)
21924 + panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
21926 + if(tcsetattr(master, TCSADRAIN, &tt) < 0)
21927 + panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
21929 + if((flags = fcntl(master, F_GETFL)) < 0)
21930 + panic("tty_fds : fcntl F_GETFL failed, errno = %d\n", errno);
21932 + if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
21933 + (fcntl(master, F_SETOWN, os_getpid()) < 0))
21934 + panic("check_sigio : fcntl F_SETFL or F_SETOWN failed, "
21935 + "errno = %d\n", errno);
21937 + if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
21938 + panic("check_sigio : fcntl F_SETFL failed, errno = %d\n",
21941 + if(sigaction(SIGIO, NULL, &old) < 0)
21942 + panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
21944 + new.sa_handler = handler;
21945 + if(sigaction(SIGIO, &new, NULL) < 0)
21946 + panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
21949 + (*proc)(master, slave);
21954 + if(sigaction(SIGIO, &old, NULL) < 0)
21955 + panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
21958 +static void tty_output(int master, int slave)
21963 + printk("Checking that host ptys support output SIGIO...");
21965 + memset(buf, 0, sizeof(buf));
21966 + while(write(master, buf, sizeof(buf)) > 0) ;
21967 + if(errno != EAGAIN)
21968 + panic("check_sigio : write failed, errno = %d\n", errno);
21970 + while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
21974 + pty_output_sigio = 1;
21976 + else if(errno == EAGAIN) printk("No, enabling workaround\n");
21977 + else panic("check_sigio : read failed, errno = %d\n", errno);
21980 +static void tty_close(int master, int slave)
21982 + printk("Checking that host ptys support SIGIO on close...");
21987 + pty_close_sigio = 1;
21989 + else printk("No, enabling workaround\n");
21992 +void __init check_sigio(void)
21994 + if(access("/dev/ptmx", R_OK) && access("/dev/ptyp0", R_OK)){
21995 + printk("No pseudo-terminals available - skipping pty SIGIO "
21999 + check_one_sigio(tty_output);
22000 + check_one_sigio(tty_close);
22003 +/* Protected by sigio_lock(), also used by sigio_cleanup, which is an
22006 +static int write_sigio_pid = -1;
22008 +/* These arrays are initialized before the sigio thread is started, and
22009 + * the descriptors closed after it is killed. So, it can't see them change.
22010 + * On the UML side, they are changed under the sigio_lock.
22012 +static int write_sigio_fds[2] = { -1, -1 };
22013 +static int sigio_private[2] = { -1, -1 };
22016 + struct pollfd *poll;
22021 +/* Protected by sigio_lock(). Used by the sigio thread, but the UML thread
22022 + * synchronizes with it.
22024 +struct pollfds current_poll = {
22030 +struct pollfds next_poll = {
22036 +static int write_sigio_thread(void *unused)
22038 + struct pollfds *fds, tmp;
22039 + struct pollfd *p;
22040 + int i, n, respond_fd;
22043 + fds = ¤t_poll;
22045 + n = poll(fds->poll, fds->used, -1);
22047 + if(errno == EINTR) continue;
22048 + printk("write_sigio_thread : poll returned %d, "
22049 + "errno = %d\n", n, errno);
22051 + for(i = 0; i < fds->used; i++){
22052 + p = &fds->poll[i];
22053 + if(p->revents == 0) continue;
22054 + if(p->fd == sigio_private[1]){
22055 + n = read(sigio_private[1], &c, sizeof(c));
22056 + if(n != sizeof(c))
22057 + printk("write_sigio_thread : "
22058 + "read failed, errno = %d\n",
22060 + tmp = current_poll;
22061 + current_poll = next_poll;
22063 + respond_fd = sigio_private[1];
22066 + respond_fd = write_sigio_fds[1];
22068 + memmove(&fds->poll[i], &fds->poll[i + 1],
22069 + (fds->used - i) * sizeof(*fds->poll));
22072 + n = write(respond_fd, &c, sizeof(c));
22073 + if(n != sizeof(c))
22074 + printk("write_sigio_thread : write failed, "
22075 + "errno = %d\n", errno);
22080 +static int need_poll(int n)
22082 + if(n <= next_poll.size){
22083 + next_poll.used = n;
22086 + if(next_poll.poll != NULL) kfree(next_poll.poll);
22087 + next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
22088 + if(next_poll.poll == NULL){
22089 + printk("need_poll : failed to allocate new pollfds\n");
22090 + next_poll.size = 0;
22091 + next_poll.used = 0;
22094 + next_poll.size = n;
22095 + next_poll.used = n;
22099 +static void update_thread(void)
22101 + unsigned long flags;
22105 + flags = set_signals(0);
22106 + n = write(sigio_private[0], &c, sizeof(c));
22107 + if(n != sizeof(c)){
22108 + printk("update_thread : write failed, errno = %d\n", errno);
22112 + n = read(sigio_private[0], &c, sizeof(c));
22113 + if(n != sizeof(c)){
22114 + printk("update_thread : read failed, errno = %d\n", errno);
22118 + set_signals(flags);
22122 + if(write_sigio_pid != -1)
22123 + os_kill_process(write_sigio_pid, 1);
22124 + write_sigio_pid = -1;
22125 + close(sigio_private[0]);
22126 + close(sigio_private[1]);
22127 + close(write_sigio_fds[0]);
22128 + close(write_sigio_fds[1]);
22130 + set_signals(flags);
22133 +int add_sigio_fd(int fd, int read)
22135 + int err = 0, i, n, events;
22138 + for(i = 0; i < current_poll.used; i++){
22139 + if(current_poll.poll[i].fd == fd)
22143 + n = current_poll.used + 1;
22144 + err = need_poll(n);
22148 + for(i = 0; i < current_poll.used; i++)
22149 + next_poll.poll[i] = current_poll.poll[i];
22151 + if(read) events = POLLIN;
22152 + else events = POLLOUT;
22154 + next_poll.poll[n - 1] = ((struct pollfd) { .fd = fd,
22155 + .events = events,
22163 +int ignore_sigio_fd(int fd)
22165 + struct pollfd *p;
22166 + int err = 0, i, n = 0;
22169 + for(i = 0; i < current_poll.used; i++){
22170 + if(current_poll.poll[i].fd == fd) break;
22172 + if(i == current_poll.used)
22175 + err = need_poll(current_poll.used - 1);
22179 + for(i = 0; i < current_poll.used; i++){
22180 + p = ¤t_poll.poll[i];
22181 + if(p->fd != fd) next_poll.poll[n++] = current_poll.poll[i];
22184 + printk("ignore_sigio_fd : fd %d not found\n", fd);
22195 +static int setup_initial_poll(int fd)
22197 + struct pollfd *p;
22199 + p = um_kmalloc(sizeof(struct pollfd));
22201 + printk("setup_initial_poll : failed to allocate poll\n");
22204 + *p = ((struct pollfd) { .fd = fd,
22205 + .events = POLLIN,
22207 + current_poll = ((struct pollfds) { .poll = p,
22213 +void write_sigio_workaround(void)
22215 + unsigned long stack;
22219 + if(write_sigio_pid != -1)
22222 + err = os_pipe(write_sigio_fds, 1, 1);
22224 + printk("write_sigio_workaround - os_pipe 1 failed, "
22225 + "errno = %d\n", -err);
22228 + err = os_pipe(sigio_private, 1, 1);
22230 + printk("write_sigio_workaround - os_pipe 2 failed, "
22231 + "errno = %d\n", -err);
22234 + if(setup_initial_poll(sigio_private[1]))
22237 + write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
22238 + CLONE_FILES | CLONE_VM, &stack, 0);
22240 + if(write_sigio_pid < 0) goto out_close2;
22242 + if(write_sigio_irq(write_sigio_fds[0]))
22250 + os_kill_process(write_sigio_pid, 1);
22251 + write_sigio_pid = -1;
22253 + close(sigio_private[0]);
22254 + close(sigio_private[1]);
22256 + close(write_sigio_fds[0]);
22257 + close(write_sigio_fds[1]);
22261 +int read_sigio_fd(int fd)
22266 + n = read(fd, &c, sizeof(c));
22267 + if(n != sizeof(c)){
22268 + printk("read_sigio_fd - read failed, errno = %d\n", errno);
22274 +static void sigio_cleanup(void)
22276 + if(write_sigio_pid != -1)
22277 + os_kill_process(write_sigio_pid, 1);
22280 +__uml_exitcall(sigio_cleanup);
22283 + * Overrides for Emacs so that we follow Linus's tabbing style.
22284 + * Emacs will notice this stuff at the end of the file and automatically
22285 + * adjust the settings for this buffer only. This must remain at the end
22287 + * ---------------------------------------------------------------------------
22288 + * Local variables:
22289 + * c-file-style: "linux"
22292 diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_kern.c um/arch/um/kernel/signal_kern.c
22293 --- orig/arch/um/kernel/signal_kern.c Wed Dec 31 19:00:00 1969
22294 +++ um/arch/um/kernel/signal_kern.c Sun Dec 8 19:44:13 2002
22297 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
22298 + * Licensed under the GPL
22301 +#include "linux/config.h"
22302 +#include "linux/stddef.h"
22303 +#include "linux/sys.h"
22304 +#include "linux/sched.h"
22305 +#include "linux/wait.h"
22306 +#include "linux/kernel.h"
22307 +#include "linux/smp_lock.h"
22308 +#include "linux/module.h"
22309 +#include "linux/slab.h"
22310 +#include "asm/signal.h"
22311 +#include "asm/uaccess.h"
22312 +#include "asm/ucontext.h"
22313 +#include "user_util.h"
22314 +#include "kern_util.h"
22315 +#include "signal_kern.h"
22316 +#include "signal_user.h"
22318 +#include "frame_kern.h"
22319 +#include "sigcontext.h"
22322 +EXPORT_SYMBOL(block_signals);
22323 +EXPORT_SYMBOL(unblock_signals);
22325 +static void force_segv(int sig)
22327 + if(sig == SIGSEGV){
22328 + struct k_sigaction *ka;
22330 + ka = ¤t->sig->action[SIGSEGV - 1];
22331 + ka->sa.sa_handler = SIG_DFL;
22333 + force_sig(SIGSEGV, current);
22336 +#define _S(nr) (1<<((nr)-1))
22338 +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
22341 + * OK, we're invoking a handler
22343 +static int handle_signal(struct pt_regs *regs, unsigned long signr,
22344 + struct k_sigaction *ka, siginfo_t *info,
22345 + sigset_t *oldset, int error)
22347 + __sighandler_t handler;
22348 + void (*restorer)(void);
22349 + unsigned long sp;
22355 + case -ERESTARTNOHAND:
22359 + case -ERESTARTSYS:
22360 + if (!(ka->sa.sa_flags & SA_RESTART)) {
22364 + /* fallthrough */
22365 + case -ERESTARTNOINTR:
22366 + PT_REGS_RESTART_SYSCALL(regs);
22367 + PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
22369 + /* This is because of the UM_SET_SYSCALL_RETURN and the fact
22370 + * that on i386 the system call number and return value are
22371 + * in the same register. When the system call restarts, %eax
22372 + * had better have the system call number in it. Since the
22373 + * return value doesn't matter (except that it shouldn't be
22374 + * -ERESTART*), we'll stick the system call number there.
22376 + ret = PT_REGS_SYSCALL_NR(regs);
22380 + handler = ka->sa.sa_handler;
22383 + if (ka->sa.sa_flags & SA_ONESHOT)
22384 + ka->sa.sa_handler = SIG_DFL;
22386 + if (!(ka->sa.sa_flags & SA_NODEFER)) {
22387 + spin_lock_irq(¤t->sigmask_lock);
22388 + sigorsets(¤t->blocked, ¤t->blocked,
22389 + &ka->sa.sa_mask);
22390 + sigaddset(¤t->blocked, signr);
22391 + recalc_sigpending(current);
22392 + spin_unlock_irq(¤t->sigmask_lock);
22395 + sp = PT_REGS_SP(regs);
22397 + if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
22398 + sp = current->sas_ss_sp + current->sas_ss_size;
22400 + if(error != 0) PT_REGS_SET_SYSCALL_RETURN(regs, ret);
22402 + if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer;
22403 + else restorer = NULL;
22405 + if(ka->sa.sa_flags & SA_SIGINFO)
22406 + err = setup_signal_stack_si(sp, signr, (unsigned long) handler,
22407 + restorer, regs, info, &save);
22409 + err = setup_signal_stack_sc(sp, signr, (unsigned long) handler,
22410 + restorer, regs, &save);
22411 + if(err) goto segv;
22415 + force_segv(signr);
22420 + * Note that 'init' is a special process: it doesn't get signals it doesn't
22421 + * want to handle. Thus you cannot kill init even with a SIGKILL even by
22425 +static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error)
22428 + struct k_sigaction *ka;
22432 + oldset = ¤t->blocked;
22435 + unsigned long signr;
22437 + spin_lock_irq(¤t->sigmask_lock);
22438 + signr = dequeue_signal(¤t->blocked, &info);
22439 + spin_unlock_irq(¤t->sigmask_lock);
22444 + if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
22445 + /* Let the debugger run. */
22446 + current->exit_code = signr;
22447 + current->state = TASK_STOPPED;
22448 + notify_parent(current, SIGCHLD);
22451 + /* We're back. Did the debugger cancel the sig? */
22452 + if (!(signr = current->exit_code))
22454 + current->exit_code = 0;
22456 + /* The debugger continued. Ignore SIGSTOP. */
22457 + if (signr == SIGSTOP)
22460 + /* Update the siginfo structure. Is this good? */
22461 + if (signr != info.si_signo) {
22462 + info.si_signo = signr;
22463 + info.si_errno = 0;
22464 + info.si_code = SI_USER;
22465 + info.si_pid = current->p_pptr->pid;
22466 + info.si_uid = current->p_pptr->uid;
22469 + /* If the (new) signal is now blocked, requeue it. */
22470 + if (sigismember(¤t->blocked, signr)) {
22471 + send_sig_info(signr, &info, current);
22476 + ka = ¤t->sig->action[signr-1];
22477 + if (ka->sa.sa_handler == SIG_IGN) {
22478 + if (signr != SIGCHLD)
22480 + /* Check for SIGCHLD: it's special. */
22481 + while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
22486 + if (ka->sa.sa_handler == SIG_DFL) {
22487 + int exit_code = signr;
22489 + /* Init gets no signals it doesn't want. */
22490 + if (current->pid == 1)
22494 + case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
22497 + case SIGTSTP: case SIGTTIN: case SIGTTOU:
22498 + if (is_orphaned_pgrp(current->pgrp))
22503 + struct signal_struct *sig;
22504 + current->state = TASK_STOPPED;
22505 + current->exit_code = signr;
22506 + sig = current->p_pptr->sig;
22507 + if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
22508 + notify_parent(current, SIGCHLD);
22512 + case SIGQUIT: case SIGILL: case SIGTRAP:
22513 + case SIGABRT: case SIGFPE: case SIGSEGV:
22514 + case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
22515 + if (do_coredump(signr, ¤t->thread.regs))
22516 + exit_code |= 0x80;
22520 + sig_exit(signr, exit_code, &info);
22525 + /* Whee! Actually deliver the signal. */
22526 + err = handle_signal(regs, signr, ka, &info, oldset, error);
22527 + if(!err) return(1);
22530 + /* Did we come from a system call? */
22531 + if(PT_REGS_SYSCALL_NR(regs) >= 0){
22532 + /* Restart the system call - no handlers present */
22533 + if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND ||
22534 + PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS ||
22535 + PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOINTR){
22536 + PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
22537 + PT_REGS_RESTART_SYSCALL(regs);
22541 + /* This closes a way to execute a system call on the host. If
22542 + * you set a breakpoint on a system call instruction and singlestep
22543 + * from it, the tracing thread used to PTRACE_SINGLESTEP the process
22544 + * rather than PTRACE_SYSCALL it, allowing the system call to execute
22545 + * on the host. The tracing thread will check this flag and
22546 + * PTRACE_SYSCALL if necessary.
22548 + if((current->ptrace & PT_DTRACE) &&
22549 + is_syscall(PT_REGS_IP(¤t->thread.regs)))
22550 + (void) CHOOSE_MODE(current->thread.mode.tt.singlestep_syscall = 1, 0);
22555 +int do_signal(int error)
22557 + return(kern_do_signal(¤t->thread.regs, NULL, error));
22561 + * Atomically swap in the new signal mask, and wait for a signal.
22563 +int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
22565 + sigset_t saveset;
22567 + mask &= _BLOCKABLE;
22568 + spin_lock_irq(¤t->sigmask_lock);
22569 + saveset = current->blocked;
22570 + siginitset(¤t->blocked, mask);
22571 + recalc_sigpending(current);
22572 + spin_unlock_irq(¤t->sigmask_lock);
22575 + current->state = TASK_INTERRUPTIBLE;
22577 + if(kern_do_signal(¤t->thread.regs, &saveset, -EINTR))
22582 +int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
22584 + sigset_t saveset, newset;
22586 + /* XXX: Don't preclude handling different sized sigset_t's. */
22587 + if (sigsetsize != sizeof(sigset_t))
22590 + if (copy_from_user(&newset, unewset, sizeof(newset)))
22592 + sigdelsetmask(&newset, ~_BLOCKABLE);
22594 + spin_lock_irq(¤t->sigmask_lock);
22595 + saveset = current->blocked;
22596 + current->blocked = newset;
22597 + recalc_sigpending(current);
22598 + spin_unlock_irq(¤t->sigmask_lock);
22601 + current->state = TASK_INTERRUPTIBLE;
22603 + if (kern_do_signal(¤t->thread.regs, &saveset, -EINTR))
22608 +static int copy_sc_from_user(struct pt_regs *to, void *from,
22609 + struct arch_frame_data *arch)
22613 + ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
22614 + copy_sc_from_user_skas(&to->regs, from));
22618 +int sys_sigreturn(struct pt_regs regs)
22620 + void *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
22621 + void *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
22622 + int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
22624 + spin_lock_irq(¤t->sigmask_lock);
22625 + copy_from_user(¤t->blocked.sig[0], sc_sigmask(sc),
22626 + sizeof(current->blocked.sig[0]));
22627 + copy_from_user(¤t->blocked.sig[1], mask, sig_size);
22628 + sigdelsetmask(¤t->blocked, ~_BLOCKABLE);
22629 + recalc_sigpending(current);
22630 + spin_unlock_irq(¤t->sigmask_lock);
22631 + copy_sc_from_user(¤t->thread.regs, sc,
22632 + &signal_frame_sc.common.arch);
22633 + return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
22636 +int sys_rt_sigreturn(struct pt_regs regs)
22638 + struct ucontext *uc = sp_to_uc(PT_REGS_SP(¤t->thread.regs));
22640 + int sig_size = _NSIG_WORDS * sizeof(unsigned long);
22642 + spin_lock_irq(¤t->sigmask_lock);
22643 + copy_from_user(¤t->blocked, &uc->uc_sigmask, sig_size);
22644 + sigdelsetmask(¤t->blocked, ~_BLOCKABLE);
22645 + recalc_sigpending(current);
22646 + spin_unlock_irq(¤t->sigmask_lock);
22647 + fp = (void *) (((unsigned long) uc) + sizeof(struct ucontext));
22648 + copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext,
22649 + &signal_frame_si.common.arch);
22650 + return(PT_REGS_SYSCALL_RET(¤t->thread.regs));
22654 + * Overrides for Emacs so that we follow Linus's tabbing style.
22655 + * Emacs will notice this stuff at the end of the file and automatically
22656 + * adjust the settings for this buffer only. This must remain at the end
22658 + * ---------------------------------------------------------------------------
22659 + * Local variables:
22660 + * c-file-style: "linux"
22663 diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_user.c um/arch/um/kernel/signal_user.c
22664 --- orig/arch/um/kernel/signal_user.c Wed Dec 31 19:00:00 1969
22665 +++ um/arch/um/kernel/signal_user.c Wed Oct 23 21:08:04 2002
22668 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
22669 + * Licensed under the GPL
22672 +#include <stdio.h>
22673 +#include <unistd.h>
22674 +#include <stdlib.h>
22675 +#include <signal.h>
22676 +#include <errno.h>
22677 +#include <stdarg.h>
22678 +#include <string.h>
22679 +#include <sys/mman.h>
22680 +#include "user_util.h"
22681 +#include "kern_util.h"
22683 +#include "signal_user.h"
22684 +#include "signal_kern.h"
22685 +#include "sysdep/sigcontext.h"
22686 +#include "sigcontext.h"
22688 +void set_sigstack(void *sig_stack, int size)
22690 + stack_t stack = ((stack_t) { .ss_flags = 0,
22691 + .ss_sp = (__ptr_t) sig_stack,
22692 + .ss_size = size - sizeof(void *) });
22694 + if(sigaltstack(&stack, NULL) != 0)
22695 + panic("enabling signal stack failed, errno = %d\n", errno);
22698 +void set_handler(int sig, void (*handler)(int), int flags, ...)
22700 + struct sigaction action;
22704 + va_start(ap, flags);
22705 + action.sa_handler = handler;
22706 + sigemptyset(&action.sa_mask);
22707 + while((mask = va_arg(ap, int)) != -1){
22708 + sigaddset(&action.sa_mask, mask);
22710 + action.sa_flags = flags;
22711 + action.sa_restorer = NULL;
22712 + if(sigaction(sig, &action, NULL) < 0)
22713 + panic("sigaction failed");
22716 +int change_sig(int signal, int on)
22718 + sigset_t sigset, old;
22720 + sigemptyset(&sigset);
22721 + sigaddset(&sigset, signal);
22722 + sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
22723 + return(!sigismember(&old, signal));
22726 +static void change_signals(int type)
22730 + sigemptyset(&mask);
22731 + sigaddset(&mask, SIGVTALRM);
22732 + sigaddset(&mask, SIGALRM);
22733 + sigaddset(&mask, SIGIO);
22734 + sigaddset(&mask, SIGPROF);
22735 + if(sigprocmask(type, &mask, NULL) < 0)
22736 + panic("Failed to change signal mask - errno = %d", errno);
22739 +void block_signals(void)
22741 + change_signals(SIG_BLOCK);
22744 +void unblock_signals(void)
22746 + change_signals(SIG_UNBLOCK);
22749 +#define SIGIO_BIT 0
22750 +#define SIGVTALRM_BIT 1
22752 +static int enable_mask(sigset_t *mask)
22756 + sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
22757 + sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
22758 + sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
22762 +int get_signals(void)
22766 + if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
22767 + panic("Failed to get signal mask");
22768 + return(enable_mask(&mask));
22771 +int set_signals(int enable)
22776 + sigemptyset(&mask);
22777 + if(enable & (1 << SIGIO_BIT))
22778 + sigaddset(&mask, SIGIO);
22779 + if(enable & (1 << SIGVTALRM_BIT)){
22780 + sigaddset(&mask, SIGVTALRM);
22781 + sigaddset(&mask, SIGALRM);
22783 + if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
22784 + panic("Failed to enable signals");
22785 + ret = enable_mask(&mask);
22786 + sigemptyset(&mask);
22787 + if((enable & (1 << SIGIO_BIT)) == 0)
22788 + sigaddset(&mask, SIGIO);
22789 + if((enable & (1 << SIGVTALRM_BIT)) == 0){
22790 + sigaddset(&mask, SIGVTALRM);
22791 + sigaddset(&mask, SIGALRM);
22793 + if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
22794 + panic("Failed to block signals");
22800 + * Overrides for Emacs so that we follow Linus's tabbing style.
22801 + * Emacs will notice this stuff at the end of the file and automatically
22802 + * adjust the settings for this buffer only. This must remain at the end
22804 + * ---------------------------------------------------------------------------
22805 + * Local variables:
22806 + * c-file-style: "linux"
22809 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/Makefile um/arch/um/kernel/skas/Makefile
22810 --- orig/arch/um/kernel/skas/Makefile Wed Dec 31 19:00:00 1969
22811 +++ um/arch/um/kernel/skas/Makefile Fri Nov 1 16:05:44 2002
22814 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22815 +# Licensed under the GPL
22820 +obj-y = exec_kern.o exec_user.o mem.o mem_user.o mmu.o process.o \
22821 + process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o
22823 +subdir-y = sys-$(SUBARCH)
22825 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
22827 +USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
22829 +include $(TOPDIR)/Rules.make
22831 +include/skas_ptregs.h : util/mk_ptregs
22832 + util/mk_ptregs > $@
22837 +$(USER_OBJS) : %.o: %.c
22838 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
22841 + $(MAKE) -C util clean
22842 + $(RM) -f include/skas_ptregs.h
22843 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_kern.c um/arch/um/kernel/skas/exec_kern.c
22844 --- orig/arch/um/kernel/skas/exec_kern.c Wed Dec 31 19:00:00 1969
22845 +++ um/arch/um/kernel/skas/exec_kern.c Mon Nov 11 18:57:19 2002
22848 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22849 + * Licensed under the GPL
22852 +#include "linux/kernel.h"
22853 +#include "asm/current.h"
22854 +#include "asm/page.h"
22855 +#include "asm/signal.h"
22856 +#include "asm/ptrace.h"
22857 +#include "asm/uaccess.h"
22858 +#include "asm/mmu_context.h"
22864 +void flush_thread_skas(void)
22866 + force_flush_all();
22867 + switch_mm_skas(current->mm->context.skas.mm_fd);
22870 +void start_thread_skas(struct pt_regs *regs, unsigned long eip,
22871 + unsigned long esp)
22874 + PT_REGS_IP(regs) = eip;
22875 + PT_REGS_SP(regs) = esp;
22879 + * Overrides for Emacs so that we follow Linus's tabbing style.
22880 + * Emacs will notice this stuff at the end of the file and automatically
22881 + * adjust the settings for this buffer only. This must remain at the end
22883 + * ---------------------------------------------------------------------------
22884 + * Local variables:
22885 + * c-file-style: "linux"
22888 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_user.c um/arch/um/kernel/skas/exec_user.c
22889 --- orig/arch/um/kernel/skas/exec_user.c Wed Dec 31 19:00:00 1969
22890 +++ um/arch/um/kernel/skas/exec_user.c Sun Nov 3 19:23:01 2002
22893 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22894 + * Licensed under the GPL
22897 +#include <stdlib.h>
22898 +#include <errno.h>
22899 +#include <signal.h>
22900 +#include <sched.h>
22901 +#include <sys/wait.h>
22902 +#include <sys/ptrace.h>
22904 +#include "kern_util.h"
22906 +#include "time_user.h"
22908 +static int user_thread_tramp(void *arg)
22910 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
22911 + panic("user_thread_tramp - PTRACE_TRACEME failed, "
22912 + "errno = %d\n", errno);
22914 + os_stop_process(os_getpid());
22918 +int user_thread(unsigned long stack, int flags)
22922 + pid = clone(user_thread_tramp, (void *) stack_sp(stack),
22923 + flags | CLONE_FILES | SIGCHLD, NULL);
22925 + printk("user_thread - clone failed, errno = %d\n", errno);
22929 + if(waitpid(pid, &status, WUNTRACED) < 0){
22930 + printk("user_thread - waitpid failed, errno = %d\n", errno);
22934 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
22935 + printk("user_thread - trampoline didn't stop, status = %d\n",
22944 + * Overrides for Emacs so that we follow Linus's tabbing style.
22945 + * Emacs will notice this stuff at the end of the file and automatically
22946 + * adjust the settings for this buffer only. This must remain at the end
22948 + * ---------------------------------------------------------------------------
22949 + * Local variables:
22950 + * c-file-style: "linux"
22953 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mmu.h um/arch/um/kernel/skas/include/mmu.h
22954 --- orig/arch/um/kernel/skas/include/mmu.h Wed Dec 31 19:00:00 1969
22955 +++ um/arch/um/kernel/skas/include/mmu.h Sun Nov 10 21:21:50 2002
22958 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22959 + * Licensed under the GPL
22962 +#ifndef __SKAS_MMU_H
22963 +#define __SKAS_MMU_H
22965 +#include "linux/list.h"
22966 +#include "linux/spinlock.h"
22968 +struct mmu_context_skas {
22975 + * Overrides for Emacs so that we follow Linus's tabbing style.
22976 + * Emacs will notice this stuff at the end of the file and automatically
22977 + * adjust the settings for this buffer only. This must remain at the end
22979 + * ---------------------------------------------------------------------------
22980 + * Local variables:
22981 + * c-file-style: "linux"
22984 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode.h um/arch/um/kernel/skas/include/mode.h
22985 --- orig/arch/um/kernel/skas/include/mode.h Wed Dec 31 19:00:00 1969
22986 +++ um/arch/um/kernel/skas/include/mode.h Wed Mar 26 13:27:46 2003
22989 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22990 + * Licensed under the GPL
22993 +#ifndef __MODE_SKAS_H__
22994 +#define __MODE_SKAS_H__
22996 +extern unsigned long exec_regs[];
22997 +extern unsigned long exec_fp_regs[];
22998 +extern unsigned long exec_fpx_regs[];
22999 +extern int have_fpx_regs;
23001 +extern void user_time_init_skas(void);
23002 +extern int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr);
23003 +extern int copy_sc_to_user_skas(void *to_ptr, void *fp,
23004 + union uml_pt_regs *regs,
23005 + unsigned long fault_addr, int fault_type);
23006 +extern void sig_handler_common_skas(int sig, void *sc_ptr);
23007 +extern void halt_skas(void);
23008 +extern void reboot_skas(void);
23009 +extern void kill_off_processes_skas(void);
23010 +extern int is_skas_winch(int pid, int fd, void *data);
23015 + * Overrides for Emacs so that we follow Linus's tabbing style.
23016 + * Emacs will notice this stuff at the end of the file and automatically
23017 + * adjust the settings for this buffer only. This must remain at the end
23019 + * ---------------------------------------------------------------------------
23020 + * Local variables:
23021 + * c-file-style: "linux"
23024 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode_kern.h um/arch/um/kernel/skas/include/mode_kern.h
23025 --- orig/arch/um/kernel/skas/include/mode_kern.h Wed Dec 31 19:00:00 1969
23026 +++ um/arch/um/kernel/skas/include/mode_kern.h Mon Dec 16 21:49:11 2002
23029 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23030 + * Licensed under the GPL
23033 +#ifndef __SKAS_MODE_KERN_H__
23034 +#define __SKAS_MODE_KERN_H__
23036 +#include "linux/sched.h"
23037 +#include "asm/page.h"
23038 +#include "asm/ptrace.h"
23040 +extern void flush_thread_skas(void);
23041 +extern void *_switch_to_skas(void *prev, void *next);
23042 +extern void start_thread_skas(struct pt_regs *regs, unsigned long eip,
23043 + unsigned long esp);
23044 +extern int copy_thread_skas(int nr, unsigned long clone_flags,
23045 + unsigned long sp, unsigned long stack_top,
23046 + struct task_struct *p, struct pt_regs *regs);
23047 +extern void release_thread_skas(struct task_struct *task);
23048 +extern void exit_thread_skas(void);
23049 +extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
23050 +extern void init_idle_skas(void);
23051 +extern void flush_tlb_kernel_vm_skas(void);
23052 +extern void __flush_tlb_one_skas(unsigned long addr);
23053 +extern void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start,
23054 + unsigned long end);
23055 +extern void flush_tlb_mm_skas(struct mm_struct *mm);
23056 +extern void force_flush_all_skas(void);
23057 +extern long execute_syscall_skas(void *r);
23058 +extern void before_mem_skas(unsigned long unused);
23059 +extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
23060 + unsigned long *task_size_out);
23061 +extern int start_uml_skas(void);
23062 +extern int external_pid_skas(struct task_struct *task);
23063 +extern int thread_pid_skas(struct thread_struct *thread);
23065 +#define kmem_end_skas (host_task_size - 1024 * 1024)
23070 + * Overrides for Emacs so that we follow Linus's tabbing style.
23071 + * Emacs will notice this stuff at the end of the file and automatically
23072 + * adjust the settings for this buffer only. This must remain at the end
23074 + * ---------------------------------------------------------------------------
23075 + * Local variables:
23076 + * c-file-style: "linux"
23079 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/proc_mm.h um/arch/um/kernel/skas/include/proc_mm.h
23080 --- orig/arch/um/kernel/skas/include/proc_mm.h Wed Dec 31 19:00:00 1969
23081 +++ um/arch/um/kernel/skas/include/proc_mm.h Wed Nov 13 11:57:23 2002
23084 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23085 + * Licensed under the GPL
23088 +#ifndef __SKAS_PROC_MM_H
23089 +#define __SKAS_PROC_MM_H
23091 +#define MM_MMAP 54
23092 +#define MM_MUNMAP 55
23093 +#define MM_MPROTECT 56
23094 +#define MM_COPY_SEGMENTS 57
23097 + unsigned long addr;
23098 + unsigned long len;
23099 + unsigned long prot;
23100 + unsigned long flags;
23101 + unsigned long fd;
23102 + unsigned long offset;
23105 +struct mm_munmap {
23106 + unsigned long addr;
23107 + unsigned long len;
23110 +struct mm_mprotect {
23111 + unsigned long addr;
23112 + unsigned long len;
23113 + unsigned int prot;
23116 +struct proc_mm_op {
23119 + struct mm_mmap mmap;
23120 + struct mm_munmap munmap;
23121 + struct mm_mprotect mprotect;
23122 + int copy_segments;
23129 + * Overrides for Emacs so that we follow Linus's tabbing style.
23130 + * Emacs will notice this stuff at the end of the file and automatically
23131 + * adjust the settings for this buffer only. This must remain at the end
23133 + * ---------------------------------------------------------------------------
23134 + * Local variables:
23135 + * c-file-style: "linux"
23138 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/ptrace-skas.h um/arch/um/kernel/skas/include/ptrace-skas.h
23139 --- orig/arch/um/kernel/skas/include/ptrace-skas.h Wed Dec 31 19:00:00 1969
23140 +++ um/arch/um/kernel/skas/include/ptrace-skas.h Fri Jan 17 13:22:09 2003
23143 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23144 + * Licensed under the GPL
23147 +#ifndef __PTRACE_SKAS_H
23148 +#define __PTRACE_SKAS_H
23150 +#include "uml-config.h"
23152 +#ifdef UML_CONFIG_MODE_SKAS
23154 +#include "skas_ptregs.h"
23156 +#define HOST_FRAME_SIZE 17
23158 +#define REGS_IP(r) ((r)[HOST_IP])
23159 +#define REGS_SP(r) ((r)[HOST_SP])
23160 +#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
23161 +#define REGS_EAX(r) ((r)[HOST_EAX])
23162 +#define REGS_EBX(r) ((r)[HOST_EBX])
23163 +#define REGS_ECX(r) ((r)[HOST_ECX])
23164 +#define REGS_EDX(r) ((r)[HOST_EDX])
23165 +#define REGS_ESI(r) ((r)[HOST_ESI])
23166 +#define REGS_EDI(r) ((r)[HOST_EDI])
23167 +#define REGS_EBP(r) ((r)[HOST_EBP])
23168 +#define REGS_CS(r) ((r)[HOST_CS])
23169 +#define REGS_SS(r) ((r)[HOST_SS])
23170 +#define REGS_DS(r) ((r)[HOST_DS])
23171 +#define REGS_ES(r) ((r)[HOST_ES])
23172 +#define REGS_FS(r) ((r)[HOST_FS])
23173 +#define REGS_GS(r) ((r)[HOST_GS])
23175 +#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res)
23177 +#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
23179 +#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
23181 +#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
23183 +#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
23190 + * Overrides for Emacs so that we follow Linus's tabbing style.
23191 + * Emacs will notice this stuff at the end of the file and automatically
23192 + * adjust the settings for this buffer only. This must remain at the end
23194 + * ---------------------------------------------------------------------------
23195 + * Local variables:
23196 + * c-file-style: "linux"
23199 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/skas.h um/arch/um/kernel/skas/include/skas.h
23200 --- orig/arch/um/kernel/skas/include/skas.h Wed Dec 31 19:00:00 1969
23201 +++ um/arch/um/kernel/skas/include/skas.h Sun Dec 8 21:00:12 2002
23204 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23205 + * Licensed under the GPL
23211 +#include "sysdep/ptrace.h"
23213 +extern int userspace_pid;
23215 +extern void switch_threads(void *me, void *next);
23216 +extern void thread_wait(void *sw, void *fb);
23217 +extern void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
23218 + void (*handler)(int));
23219 +extern int start_idle_thread(void *stack, void *switch_buf_ptr,
23220 + void **fork_buf_ptr);
23221 +extern int user_thread(unsigned long stack, int flags);
23222 +extern void userspace(union uml_pt_regs *regs);
23223 +extern void new_thread_proc(void *stack, void (*handler)(int sig));
23224 +extern void remove_sigstack(void);
23225 +extern void new_thread_handler(int sig);
23226 +extern void handle_syscall(union uml_pt_regs *regs);
23227 +extern void map(int fd, unsigned long virt, unsigned long phys,
23228 + unsigned long len, int r, int w, int x);
23229 +extern int unmap(int fd, void *addr, int len);
23230 +extern int protect(int fd, unsigned long addr, unsigned long len,
23231 + int r, int w, int x, int must_succeed);
23232 +extern void user_signal(int sig, union uml_pt_regs *regs);
23233 +extern int singlestepping_skas(void);
23234 +extern int new_mm(int from);
23235 +extern void save_registers(union uml_pt_regs *regs);
23236 +extern void restore_registers(union uml_pt_regs *regs);
23237 +extern void start_userspace(void);
23238 +extern void init_registers(int pid);
23243 + * Overrides for Emacs so that we follow Linus's tabbing style.
23244 + * Emacs will notice this stuff at the end of the file and automatically
23245 + * adjust the settings for this buffer only. This must remain at the end
23247 + * ---------------------------------------------------------------------------
23248 + * Local variables:
23249 + * c-file-style: "linux"
23252 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/uaccess.h um/arch/um/kernel/skas/include/uaccess.h
23253 --- orig/arch/um/kernel/skas/include/uaccess.h Wed Dec 31 19:00:00 1969
23254 +++ um/arch/um/kernel/skas/include/uaccess.h Fri Jan 31 23:05:56 2003
23257 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23258 + * Licensed under the GPL
23261 +#ifndef __SKAS_UACCESS_H
23262 +#define __SKAS_UACCESS_H
23264 +#include "linux/string.h"
23265 +#include "linux/sched.h"
23266 +#include "asm/processor.h"
23267 +#include "asm/pgtable.h"
23268 +#include "asm/errno.h"
23269 +#include "asm/current.h"
23270 +#include "asm/a.out.h"
23271 +#include "kern_util.h"
23273 +#define access_ok_skas(type, addr, size) \
23274 + ((segment_eq(get_fs(), KERNEL_DS)) || \
23275 + (((unsigned long) (addr) < TASK_SIZE) && \
23276 + ((unsigned long) (addr) + (size) <= TASK_SIZE)))
23278 +static inline int verify_area_skas(int type, const void * addr,
23279 + unsigned long size)
23281 + return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
23284 +static inline unsigned long maybe_map(unsigned long virt, int is_write)
23288 + void *phys = um_virt_to_phys(current, virt, &pte);
23291 + if(IS_ERR(phys) || (is_write && !pte_write(pte))){
23292 + if(!handle_page_fault(virt, 0, is_write, 0, &dummy_code))
23294 + phys = um_virt_to_phys(current, virt, NULL);
23296 + return((unsigned long) __va((unsigned long) phys));
23299 +static inline int buffer_op(unsigned long addr, int len,
23300 + int (*op)(unsigned long addr, int len, void *arg),
23303 + int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
23304 + int remain = len, n;
23306 + n = (*op)(addr, size, arg);
23308 + return(n < 0 ? remain : 0);
23315 + while(addr < ((addr + remain) & PAGE_MASK)){
23316 + n = (*op)(addr, PAGE_SIZE, arg);
23318 + return(n < 0 ? remain : 0);
23320 + addr += PAGE_SIZE;
23321 + remain -= PAGE_SIZE;
23326 + n = (*op)(addr, remain, arg);
23328 + return(n < 0 ? remain : 0);
23332 +static inline int copy_chunk_from_user(unsigned long from, int len, void *arg)
23334 + unsigned long *to_ptr = arg, to = *to_ptr;
23336 + from = maybe_map(from, 0);
23340 + memcpy((void *) to, (void *) from, len);
23345 +static inline int copy_from_user_skas(void *to, const void *from, int n)
23347 + if(segment_eq(get_fs(), KERNEL_DS)){
23348 + memcpy(to, from, n);
23352 + return(access_ok_skas(VERIFY_READ, from, n) ?
23353 + buffer_op((unsigned long) from, n, copy_chunk_from_user, &to) :
23357 +static inline int copy_chunk_to_user(unsigned long to, int len, void *arg)
23359 + unsigned long *from_ptr = arg, from = *from_ptr;
23361 + to = maybe_map(to, 1);
23365 + memcpy((void *) to, (void *) from, len);
23366 + *from_ptr += len;
23370 +static inline int copy_to_user_skas(void *to, const void *from, int n)
23372 + if(segment_eq(get_fs(), KERNEL_DS)){
23373 + memcpy(to, from, n);
23377 + return(access_ok_skas(VERIFY_WRITE, to, n) ?
23378 + buffer_op((unsigned long) to, n, copy_chunk_to_user, &from) :
23382 +static inline int strncpy_chunk_from_user(unsigned long from, int len,
23385 + char **to_ptr = arg, *to = *to_ptr;
23388 + from = maybe_map(from, 0);
23392 + strncpy(to, (void *) from, len);
23393 + n = strnlen(to, len);
23401 +static inline int strncpy_from_user_skas(char *dst, const char *src, int count)
23406 + if(segment_eq(get_fs(), KERNEL_DS)){
23407 + strncpy(dst, src, count);
23408 + return(strnlen(dst, count));
23411 + if(!access_ok_skas(VERIFY_READ, src, 1))
23414 + n = buffer_op((unsigned long) src, count, strncpy_chunk_from_user,
23418 + return(strnlen(dst, count));
23421 +static inline int clear_chunk(unsigned long addr, int len, void *unused)
23423 + addr = maybe_map(addr, 1);
23427 + memset((void *) addr, 0, len);
23431 +static inline int __clear_user_skas(void *mem, int len)
23433 + return(buffer_op((unsigned long) mem, len, clear_chunk, NULL));
23436 +static inline int clear_user_skas(void *mem, int len)
23438 + if(segment_eq(get_fs(), KERNEL_DS)){
23439 + memset(mem, 0, len);
23443 + return(access_ok_skas(VERIFY_WRITE, mem, len) ?
23444 + buffer_op((unsigned long) mem, len, clear_chunk, NULL) : len);
23447 +static inline int strnlen_chunk(unsigned long str, int len, void *arg)
23449 + int *len_ptr = arg, n;
23451 + str = maybe_map(str, 0);
23455 + n = strnlen((void *) str, len);
23463 +static inline int strnlen_user_skas(const void *str, int len)
23465 + int count = 0, n;
23467 + if(segment_eq(get_fs(), KERNEL_DS))
23468 + return(strnlen(str, len) + 1);
23470 + n = buffer_op((unsigned long) str, len, strnlen_chunk, &count);
23472 + return(count + 1);
23479 + * Overrides for Emacs so that we follow Linus's tabbing style.
23480 + * Emacs will notice this stuff at the end of the file and automatically
23481 + * adjust the settings for this buffer only. This must remain at the end
23483 + * ---------------------------------------------------------------------------
23484 + * Local variables:
23485 + * c-file-style: "linux"
23488 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mem.c um/arch/um/kernel/skas/mem.c
23489 --- orig/arch/um/kernel/skas/mem.c Wed Dec 31 19:00:00 1969
23490 +++ um/arch/um/kernel/skas/mem.c Mon Dec 16 21:49:39 2002
23493 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23494 + * Licensed under the GPL
23497 +#include "linux/config.h"
23498 +#include "linux/mm.h"
23499 +#include "mem_user.h"
23501 +unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
23502 + unsigned long *task_size_out)
23504 + /* Round up to the nearest 4M */
23505 + unsigned long top = ROUND_4M((unsigned long) &arg);
23507 + *host_size_out = top;
23508 + *task_size_out = top;
23509 + return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
23513 + * Overrides for Emacs so that we follow Linus's tabbing style.
23514 + * Emacs will notice this stuff at the end of the file and automatically
23515 + * adjust the settings for this buffer only. This must remain at the end
23517 + * ---------------------------------------------------------------------------
23518 + * Local variables:
23519 + * c-file-style: "linux"
23522 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mem_user.c um/arch/um/kernel/skas/mem_user.c
23523 --- orig/arch/um/kernel/skas/mem_user.c Wed Dec 31 19:00:00 1969
23524 +++ um/arch/um/kernel/skas/mem_user.c Tue Dec 31 00:13:18 2002
23527 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23528 + * Licensed under the GPL
23531 +#include <errno.h>
23532 +#include <sys/mman.h>
23533 +#include <sys/ptrace.h>
23534 +#include "mem_user.h"
23537 +#include "proc_mm.h"
23539 +void map(int fd, unsigned long virt, unsigned long phys, unsigned long len,
23540 + int r, int w, int x)
23542 + struct proc_mm_op map;
23543 + struct mem_region *region;
23546 + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
23547 + (x ? PROT_EXEC : 0);
23548 + region = phys_region(phys);
23550 + map = ((struct proc_mm_op) { .op = MM_MMAP,
23556 + .flags = MAP_SHARED |
23558 + .fd = region->fd,
23559 + .offset = phys_offset(phys)
23561 + n = os_write_file(fd, &map, sizeof(map));
23562 + if(n != sizeof(map))
23563 + printk("map : /proc/mm map failed, errno = %d\n", errno);
23566 +int unmap(int fd, void *addr, int len)
23568 + struct proc_mm_op unmap;
23571 + unmap = ((struct proc_mm_op) { .op = MM_MUNMAP,
23574 + { .addr = (unsigned long) addr,
23575 + .len = len } } } );
23576 + n = os_write_file(fd, &unmap, sizeof(unmap));
23577 + if((n != 0) && (n != sizeof(unmap)))
23582 +int protect(int fd, unsigned long addr, unsigned long len, int r, int w,
23583 + int x, int must_succeed)
23585 + struct proc_mm_op protect;
23588 + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
23589 + (x ? PROT_EXEC : 0);
23591 + protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
23594 + { .addr = (unsigned long) addr,
23596 + .prot = prot } } } );
23598 + n = os_write_file(fd, &protect, sizeof(protect));
23599 + if((n != 0) && (n != sizeof(protect))){
23601 + panic("protect failed, errno = %d", errno);
23607 +void before_mem_skas(unsigned long unused)
23612 + * Overrides for Emacs so that we follow Linus's tabbing style.
23613 + * Emacs will notice this stuff at the end of the file and automatically
23614 + * adjust the settings for this buffer only. This must remain at the end
23616 + * ---------------------------------------------------------------------------
23617 + * Local variables:
23618 + * c-file-style: "linux"
23621 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mmu.c um/arch/um/kernel/skas/mmu.c
23622 --- orig/arch/um/kernel/skas/mmu.c Wed Dec 31 19:00:00 1969
23623 +++ um/arch/um/kernel/skas/mmu.c Wed Nov 13 13:09:57 2002
23626 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23627 + * Licensed under the GPL
23630 +#include "linux/list.h"
23631 +#include "linux/spinlock.h"
23632 +#include "linux/slab.h"
23633 +#include "asm/segment.h"
23634 +#include "asm/mmu.h"
23638 +int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
23642 + if((current->mm != NULL) && (current->mm != &init_mm))
23643 + from = current->mm->context.skas.mm_fd;
23646 + mm->context.skas.mm_fd = new_mm(from);
23647 + if(mm->context.skas.mm_fd < 0)
23648 + panic("init_new_context_skas - new_mm failed, errno = %d\n",
23649 + mm->context.skas.mm_fd);
23654 +void destroy_context_skas(struct mm_struct *mm)
23656 + os_close_file(mm->context.skas.mm_fd);
23660 + * Overrides for Emacs so that we follow Linus's tabbing style.
23661 + * Emacs will notice this stuff at the end of the file and automatically
23662 + * adjust the settings for this buffer only. This must remain at the end
23664 + * ---------------------------------------------------------------------------
23665 + * Local variables:
23666 + * c-file-style: "linux"
23669 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process.c um/arch/um/kernel/skas/process.c
23670 --- orig/arch/um/kernel/skas/process.c Wed Dec 31 19:00:00 1969
23671 +++ um/arch/um/kernel/skas/process.c Wed Mar 26 14:43:19 2003
23674 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23675 + * Licensed under the GPL
23678 +#include <stdlib.h>
23679 +#include <unistd.h>
23680 +#include <errno.h>
23681 +#include <signal.h>
23682 +#include <setjmp.h>
23683 +#include <sched.h>
23684 +#include <sys/wait.h>
23685 +#include <sys/ptrace.h>
23686 +#include <sys/mman.h>
23687 +#include <sys/user.h>
23688 +#include <asm/unistd.h>
23690 +#include "ptrace_user.h"
23691 +#include "time_user.h"
23692 +#include "sysdep/ptrace.h"
23693 +#include "user_util.h"
23694 +#include "kern_util.h"
23696 +#include "sysdep/sigcontext.h"
23698 +#include "proc_mm.h"
23699 +#include "skas_ptrace.h"
23700 +#include "chan_user.h"
23702 +int is_skas_winch(int pid, int fd, void *data)
23704 + if(pid != getpid())
23707 + register_winch_irq(-1, fd, -1, data);
23711 +unsigned long exec_regs[FRAME_SIZE];
23712 +unsigned long exec_fp_regs[HOST_FP_SIZE];
23713 +unsigned long exec_fpx_regs[HOST_XFP_SIZE];
23714 +int have_fpx_regs = 1;
23716 +static void handle_segv(int pid)
23718 + struct ptrace_faultinfo fault;
23721 + err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault);
23723 + panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n",
23726 + segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
23729 +static void handle_trap(int pid, union uml_pt_regs *regs)
23731 + int err, syscall_nr, status;
23733 + syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
23734 + if(syscall_nr < 1){
23735 + relay_signal(SIGTRAP, regs);
23738 + UPT_SYSCALL_NR(regs) = syscall_nr;
23740 + err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
23742 + panic("handle_trap - nullifying syscall failed errno = %d\n",
23745 + err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
23747 + panic("handle_trap - continuing to end of syscall failed, "
23748 + "errno = %d\n", errno);
23750 + err = waitpid(pid, &status, WUNTRACED);
23751 + if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
23752 + panic("handle_trap - failed to wait at end of syscall, "
23753 + "errno = %d, status = %d\n", errno, status);
23755 + handle_syscall(regs);
23758 +static int userspace_tramp(void *arg)
23760 + init_new_thread_signals(0);
23762 + ptrace(PTRACE_TRACEME, 0, 0, 0);
23763 + os_stop_process(os_getpid());
23767 +int userspace_pid;
23769 +void start_userspace(void)
23772 + unsigned long sp;
23773 + int pid, status, n;
23775 + stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
23776 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
23777 + if(stack == MAP_FAILED)
23778 + panic("start_userspace : mmap failed, errno = %d", errno);
23779 + sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
23781 + pid = clone(userspace_tramp, (void *) sp,
23782 + CLONE_FILES | CLONE_VM | SIGCHLD, NULL);
23784 + panic("start_userspace : clone failed, errno = %d", errno);
23787 + n = waitpid(pid, &status, WUNTRACED);
23789 + panic("start_userspace : wait failed, errno = %d",
23791 + } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
23793 + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
23794 + panic("start_userspace : expected SIGSTOP, got status = %d",
23797 + if(munmap(stack, PAGE_SIZE) < 0)
23798 + panic("start_userspace : munmap failed, errno = %d\n", errno);
23800 + userspace_pid = pid;
23803 +void userspace(union uml_pt_regs *regs)
23805 + int err, status, op;
23807 + restore_registers(regs);
23809 + err = ptrace(PTRACE_SYSCALL, userspace_pid, 0, 0);
23811 + panic("userspace - PTRACE_SYSCALL failed, errno = %d\n",
23814 + err = waitpid(userspace_pid, &status, WUNTRACED);
23816 + panic("userspace - waitpid failed, errno = %d\n",
23819 + regs->skas.is_user = 1;
23820 + save_registers(regs);
23822 + if(WIFSTOPPED(status)){
23823 + switch(WSTOPSIG(status)){
23825 + handle_segv(userspace_pid);
23828 + handle_trap(userspace_pid, regs);
23836 + user_signal(WSTOPSIG(status), regs);
23839 + printk("userspace - child stopped with signal "
23840 + "%d\n", WSTOPSIG(status));
23845 + restore_registers(regs);
23847 + op = singlestepping_skas() ? PTRACE_SINGLESTEP :
23849 + err = ptrace(op, userspace_pid, 0, 0);
23851 + panic("userspace - PTRACE_SYSCALL failed, "
23852 + "errno = %d\n", errno);
23856 +void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
23857 + void (*handler)(int))
23859 + jmp_buf switch_buf, fork_buf;
23861 + *switch_buf_ptr = &switch_buf;
23862 + *fork_buf_ptr = &fork_buf;
23864 + if(setjmp(fork_buf) == 0)
23865 + new_thread_proc(stack, handler);
23867 + remove_sigstack();
23870 +void thread_wait(void *sw, void *fb)
23872 + jmp_buf buf, **switch_buf = sw, *fork_buf;
23874 + *switch_buf = &buf;
23876 + if(setjmp(buf) == 0)
23877 + longjmp(*fork_buf, 1);
23880 +static int move_registers(int int_op, int fp_op, union uml_pt_regs *regs,
23881 + unsigned long *fp_regs)
23883 + if(ptrace(int_op, userspace_pid, 0, regs->skas.regs) < 0)
23885 + if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0)
23890 +void save_registers(union uml_pt_regs *regs)
23892 + unsigned long *fp_regs;
23895 + if(have_fpx_regs){
23896 + fp_op = PTRACE_GETFPXREGS;
23897 + fp_regs = regs->skas.xfp;
23900 + fp_op = PTRACE_GETFPREGS;
23901 + fp_regs = regs->skas.fp;
23904 + err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs);
23906 + panic("save_registers - saving registers failed, errno = %d\n",
23910 +void restore_registers(union uml_pt_regs *regs)
23912 + unsigned long *fp_regs;
23915 + if(have_fpx_regs){
23916 + fp_op = PTRACE_SETFPXREGS;
23917 + fp_regs = regs->skas.xfp;
23920 + fp_op = PTRACE_SETFPREGS;
23921 + fp_regs = regs->skas.fp;
23924 + err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs);
23926 + panic("restore_registers - saving registers failed, "
23927 + "errno = %d\n", err);
23930 +void switch_threads(void *me, void *next)
23932 + jmp_buf my_buf, **me_ptr = me, *next_buf = next;
23934 + *me_ptr = &my_buf;
23935 + if(setjmp(my_buf) == 0)
23936 + longjmp(*next_buf, 1);
23939 +static jmp_buf initial_jmpbuf;
23941 +/* XXX Make these percpu */
23942 +static void (*cb_proc)(void *arg);
23943 +static void *cb_arg;
23944 +static jmp_buf *cb_back;
23946 +int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
23948 + jmp_buf **switch_buf = switch_buf_ptr;
23951 + *fork_buf_ptr = &initial_jmpbuf;
23952 + n = setjmp(initial_jmpbuf);
23954 + new_thread_proc((void *) stack, new_thread_handler);
23956 + remove_sigstack();
23958 + (*cb_proc)(cb_arg);
23959 + longjmp(*cb_back, 1);
23969 + longjmp(**switch_buf, 1);
23972 +void remove_sigstack(void)
23974 + stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE,
23978 + if(sigaltstack(&stack, NULL) != 0)
23979 + panic("disabling signal stack failed, errno = %d\n", errno);
23982 +void initial_thread_cb_skas(void (*proc)(void *), void *arg)
23991 + if(setjmp(here) == 0)
23992 + longjmp(initial_jmpbuf, 2);
23993 + unblock_signals();
24000 +void halt_skas(void)
24003 + longjmp(initial_jmpbuf, 3);
24006 +void reboot_skas(void)
24009 + longjmp(initial_jmpbuf, 4);
24012 +int new_mm(int from)
24014 + struct proc_mm_op copy;
24015 + int n, fd = os_open_file("/proc/mm", of_write(OPENFLAGS()), 0);
24021 + copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS,
24023 + { .copy_segments = from } } );
24024 + n = os_write_file(fd, ©, sizeof(copy));
24025 + if(n != sizeof(copy))
24026 + printk("new_mm : /proc/mm copy_segments failed, "
24027 + "errno = %d\n", errno);
24032 +void switch_mm_skas(int mm_fd)
24036 + err = ptrace(PTRACE_SWITCH_MM, userspace_pid, 0, mm_fd);
24038 + panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
24042 +void kill_off_processes_skas(void)
24044 + os_kill_process(userspace_pid, 1);
24047 +void init_registers(int pid)
24051 + if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0)
24052 + panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
24055 + err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
24059 + have_fpx_regs = 0;
24061 + panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
24064 + err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
24066 + panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
24071 + * Overrides for Emacs so that we follow Linus's tabbing style.
24072 + * Emacs will notice this stuff at the end of the file and automatically
24073 + * adjust the settings for this buffer only. This must remain at the end
24075 + * ---------------------------------------------------------------------------
24076 + * Local variables:
24077 + * c-file-style: "linux"
24080 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process_kern.c um/arch/um/kernel/skas/process_kern.c
24081 --- orig/arch/um/kernel/skas/process_kern.c Wed Dec 31 19:00:00 1969
24082 +++ um/arch/um/kernel/skas/process_kern.c Sun Dec 22 20:37:39 2002
24085 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24086 + * Licensed under the GPL
24089 +#include "linux/sched.h"
24090 +#include "linux/slab.h"
24091 +#include "kern_util.h"
24092 +#include "time_user.h"
24093 +#include "signal_user.h"
24096 +#include "user_util.h"
24098 +#include "frame.h"
24102 +int singlestepping_skas(void)
24104 + int ret = current->ptrace & PT_DTRACE;
24106 + current->ptrace &= ~PT_DTRACE;
24110 +void *_switch_to_skas(void *prev, void *next)
24112 + struct task_struct *from, *to;
24117 + /* XXX need to check runqueues[cpu].idle */
24118 + if(current->pid == 0)
24119 + switch_timers(0);
24121 + to->thread.prev_sched = from;
24124 + switch_threads(&from->thread.mode.skas.switch_buf,
24125 + to->thread.mode.skas.switch_buf);
24127 + if(current->pid == 0)
24128 + switch_timers(1);
24130 + return(current->thread.prev_sched);
24133 +extern void schedule_tail(struct task_struct *prev);
24135 +void new_thread_handler(int sig)
24137 + int (*fn)(void *), n;
24140 + fn = current->thread.request.u.thread.proc;
24141 + arg = current->thread.request.u.thread.arg;
24142 + change_sig(SIGUSR1, 1);
24143 + thread_wait(¤t->thread.mode.skas.switch_buf,
24144 + current->thread.mode.skas.fork_buf);
24146 + if(current->thread.prev_sched != NULL)
24147 + schedule_tail(current->thread.prev_sched);
24148 + current->thread.prev_sched = NULL;
24150 + n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf);
24152 + userspace(¤t->thread.regs.regs);
24156 +void new_thread_proc(void *stack, void (*handler)(int sig))
24158 + init_new_thread_stack(stack, handler);
24159 + os_usr1_process(os_getpid());
24162 +void release_thread_skas(struct task_struct *task)
24166 +void exit_thread_skas(void)
24170 +void fork_handler(int sig)
24172 + change_sig(SIGUSR1, 1);
24173 + thread_wait(¤t->thread.mode.skas.switch_buf,
24174 + current->thread.mode.skas.fork_buf);
24176 + force_flush_all();
24177 + if(current->thread.prev_sched != NULL)
24178 + schedule_tail(current->thread.prev_sched);
24179 + current->thread.prev_sched = NULL;
24180 + unblock_signals();
24182 + userspace(¤t->thread.regs.regs);
24185 +int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
24186 + unsigned long stack_top, struct task_struct * p,
24187 + struct pt_regs *regs)
24189 + void (*handler)(int);
24191 + if(current->thread.forking){
24192 + memcpy(&p->thread.regs.regs.skas,
24193 + ¤t->thread.regs.regs.skas,
24194 + sizeof(p->thread.regs.regs.skas));
24195 + REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
24196 + if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
24198 + handler = fork_handler;
24201 + memcpy(p->thread.regs.regs.skas.regs, exec_regs,
24202 + sizeof(p->thread.regs.regs.skas.regs));
24203 + memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs,
24204 + sizeof(p->thread.regs.regs.skas.fp));
24205 + memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs,
24206 + sizeof(p->thread.regs.regs.skas.xfp));
24207 + p->thread.request.u.thread = current->thread.request.u.thread;
24208 + handler = new_thread_handler;
24211 + new_thread((void *) p->thread.kernel_stack,
24212 + &p->thread.mode.skas.switch_buf,
24213 + &p->thread.mode.skas.fork_buf, handler);
24217 +void init_idle_skas(void)
24219 + cpu_tasks[current->processor].pid = os_getpid();
24222 +extern void start_kernel(void);
24224 +static int start_kernel_proc(void *unused)
24229 + pid = os_getpid();
24231 + cpu_tasks[0].pid = pid;
24232 + cpu_tasks[0].task = current;
24234 + cpu_online_map = 1;
24240 +int start_uml_skas(void)
24242 + start_userspace();
24243 + capture_signal_stack();
24245 + init_new_thread_signals(1);
24248 + init_task.thread.request.u.thread.proc = start_kernel_proc;
24249 + init_task.thread.request.u.thread.arg = NULL;
24250 + return(start_idle_thread((void *) init_task.thread.kernel_stack,
24251 + &init_task.thread.mode.skas.switch_buf,
24252 + &init_task.thread.mode.skas.fork_buf));
24255 +int external_pid_skas(struct task_struct *task)
24257 + return(userspace_pid);
24260 +int thread_pid_skas(struct thread_struct *thread)
24262 + return(userspace_pid);
24266 + * Overrides for Emacs so that we follow Linus's tabbing style.
24267 + * Emacs will notice this stuff at the end of the file and automatically
24268 + * adjust the settings for this buffer only. This must remain at the end
24270 + * ---------------------------------------------------------------------------
24271 + * Local variables:
24272 + * c-file-style: "linux"
24275 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/Makefile um/arch/um/kernel/skas/sys-i386/Makefile
24276 --- orig/arch/um/kernel/skas/sys-i386/Makefile Wed Dec 31 19:00:00 1969
24277 +++ um/arch/um/kernel/skas/sys-i386/Makefile Wed Oct 23 21:08:04 2002
24280 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24281 +# Licensed under the GPL
24284 +O_TARGET = sys-i386.o
24286 +obj-y = sigcontext.o
24288 +USER_OBJS = sigcontext.o
24290 +include $(TOPDIR)/Rules.make
24292 +$(USER_OBJS) : %.o: %.c
24293 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
24296 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/sigcontext.c um/arch/um/kernel/skas/sys-i386/sigcontext.c
24297 --- orig/arch/um/kernel/skas/sys-i386/sigcontext.c Wed Dec 31 19:00:00 1969
24298 +++ um/arch/um/kernel/skas/sys-i386/sigcontext.c Sun Dec 8 20:38:46 2002
24301 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24302 + * Licensed under the GPL
24305 +#include <errno.h>
24306 +#include <asm/sigcontext.h>
24307 +#include <sys/ptrace.h>
24308 +#include <linux/ptrace.h>
24309 +#include "sysdep/ptrace.h"
24310 +#include "sysdep/ptrace_user.h"
24311 +#include "kern_util.h"
24313 +#include "sigcontext.h"
24315 +extern int userspace_pid;
24317 +int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr)
24319 + struct sigcontext sc, *from = from_ptr;
24320 + unsigned long fpregs[FP_FRAME_SIZE];
24323 + err = copy_from_user_proc(&sc, from, sizeof(sc));
24324 + err |= copy_from_user_proc(fpregs, sc.fpstate, sizeof(fpregs));
24328 + regs->skas.regs[GS] = sc.gs;
24329 + regs->skas.regs[FS] = sc.fs;
24330 + regs->skas.regs[ES] = sc.es;
24331 + regs->skas.regs[DS] = sc.ds;
24332 + regs->skas.regs[EDI] = sc.edi;
24333 + regs->skas.regs[ESI] = sc.esi;
24334 + regs->skas.regs[EBP] = sc.ebp;
24335 + regs->skas.regs[UESP] = sc.esp;
24336 + regs->skas.regs[EBX] = sc.ebx;
24337 + regs->skas.regs[EDX] = sc.edx;
24338 + regs->skas.regs[ECX] = sc.ecx;
24339 + regs->skas.regs[EAX] = sc.eax;
24340 + regs->skas.regs[EIP] = sc.eip;
24341 + regs->skas.regs[CS] = sc.cs;
24342 + regs->skas.regs[EFL] = sc.eflags;
24343 + regs->skas.regs[UESP] = sc.esp_at_signal;
24344 + regs->skas.regs[SS] = sc.ss;
24345 + regs->skas.fault_addr = sc.cr2;
24346 + regs->skas.fault_type = FAULT_WRITE(sc.err);
24347 + regs->skas.trap_type = sc.trapno;
24349 + err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs);
24351 + printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
24352 + "errno = %d\n", errno);
24359 +int copy_sc_to_user_skas(void *to_ptr, void *fp, union uml_pt_regs *regs,
24360 + unsigned long fault_addr, int fault_type)
24362 + struct sigcontext sc, *to = to_ptr;
24363 + struct _fpstate *to_fp;
24364 + unsigned long fpregs[FP_FRAME_SIZE];
24367 + sc.gs = regs->skas.regs[GS];
24368 + sc.fs = regs->skas.regs[FS];
24369 + sc.es = regs->skas.regs[ES];
24370 + sc.ds = regs->skas.regs[DS];
24371 + sc.edi = regs->skas.regs[EDI];
24372 + sc.esi = regs->skas.regs[ESI];
24373 + sc.ebp = regs->skas.regs[EBP];
24374 + sc.esp = regs->skas.regs[UESP];
24375 + sc.ebx = regs->skas.regs[EBX];
24376 + sc.edx = regs->skas.regs[EDX];
24377 + sc.ecx = regs->skas.regs[ECX];
24378 + sc.eax = regs->skas.regs[EAX];
24379 + sc.eip = regs->skas.regs[EIP];
24380 + sc.cs = regs->skas.regs[CS];
24381 + sc.eflags = regs->skas.regs[EFL];
24382 + sc.esp_at_signal = regs->skas.regs[UESP];
24383 + sc.ss = regs->skas.regs[SS];
24384 + sc.cr2 = fault_addr;
24385 + sc.err = TO_SC_ERR(fault_type);
24386 + sc.trapno = regs->skas.trap_type;
24388 + err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs);
24390 + printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
24391 + "errno = %d\n", errno);
24394 + to_fp = (struct _fpstate *)
24395 + (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
24396 + sc.fpstate = to_fp;
24401 + return(copy_to_user_proc(to, &sc, sizeof(sc)) ||
24402 + copy_to_user_proc(to_fp, fpregs, sizeof(fpregs)));
24406 + * Overrides for Emacs so that we follow Linus's tabbing style.
24407 + * Emacs will notice this stuff at the end of the file and automatically
24408 + * adjust the settings for this buffer only. This must remain at the end
24410 + * ---------------------------------------------------------------------------
24411 + * Local variables:
24412 + * c-file-style: "linux"
24415 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_kern.c um/arch/um/kernel/skas/syscall_kern.c
24416 --- orig/arch/um/kernel/skas/syscall_kern.c Wed Dec 31 19:00:00 1969
24417 +++ um/arch/um/kernel/skas/syscall_kern.c Sun Dec 8 21:01:44 2002
24420 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24421 + * Licensed under the GPL
24424 +#include "linux/sys.h"
24425 +#include "asm/errno.h"
24426 +#include "asm/unistd.h"
24427 +#include "asm/ptrace.h"
24428 +#include "asm/current.h"
24429 +#include "sysdep/syscalls.h"
24430 +#include "kern_util.h"
24432 +extern syscall_handler_t *sys_call_table[];
24434 +long execute_syscall_skas(void *r)
24436 + struct pt_regs *regs = r;
24440 + current->thread.nsyscalls++;
24442 + syscall = UPT_SYSCALL_NR(®s->regs);
24444 + if((syscall >= NR_syscalls) || (syscall < 0))
24446 + else res = EXECUTE_SYSCALL(syscall, regs);
24452 + * Overrides for Emacs so that we follow Linus's tabbing style.
24453 + * Emacs will notice this stuff at the end of the file and automatically
24454 + * adjust the settings for this buffer only. This must remain at the end
24456 + * ---------------------------------------------------------------------------
24457 + * Local variables:
24458 + * c-file-style: "linux"
24461 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_user.c um/arch/um/kernel/skas/syscall_user.c
24462 --- orig/arch/um/kernel/skas/syscall_user.c Wed Dec 31 19:00:00 1969
24463 +++ um/arch/um/kernel/skas/syscall_user.c Sun Dec 8 21:00:12 2002
24466 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24467 + * Licensed under the GPL
24470 +#include <stdlib.h>
24471 +#include <signal.h>
24472 +#include "kern_util.h"
24473 +#include "syscall_user.h"
24474 +#include "sysdep/ptrace.h"
24475 +#include "sysdep/sigcontext.h"
24478 +#define ERESTARTSYS 512
24479 +#define ERESTARTNOINTR 513
24480 +#define ERESTARTNOHAND 514
24482 +void handle_syscall(union uml_pt_regs *regs)
24487 + index = record_syscall_start(UPT_SYSCALL_NR(regs));
24490 + result = execute_syscall(regs);
24492 + REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
24493 + if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) ||
24494 + (result == -ERESTARTNOINTR))
24495 + do_signal(result);
24498 + record_syscall_end(index, result);
24502 + * Overrides for Emacs so that we follow Linus's tabbing style.
24503 + * Emacs will notice this stuff at the end of the file and automatically
24504 + * adjust the settings for this buffer only. This must remain at the end
24506 + * ---------------------------------------------------------------------------
24507 + * Local variables:
24508 + * c-file-style: "linux"
24511 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/time.c um/arch/um/kernel/skas/time.c
24512 --- orig/arch/um/kernel/skas/time.c Wed Dec 31 19:00:00 1969
24513 +++ um/arch/um/kernel/skas/time.c Wed Oct 23 21:08:04 2002
24516 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24517 + * Licensed under the GPL
24520 +#include <sys/signal.h>
24521 +#include <sys/time.h>
24522 +#include "time_user.h"
24523 +#include "process.h"
24526 +void user_time_init_skas(void)
24528 + if(signal(SIGALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
24529 + panic("Couldn't set SIGALRM handler");
24530 + if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
24531 + panic("Couldn't set SIGVTALRM handler");
24532 + set_interval(ITIMER_VIRTUAL);
24536 + * Overrides for Emacs so that we follow Linus's tabbing style.
24537 + * Emacs will notice this stuff at the end of the file and automatically
24538 + * adjust the settings for this buffer only. This must remain at the end
24540 + * ---------------------------------------------------------------------------
24541 + * Local variables:
24542 + * c-file-style: "linux"
24545 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/tlb.c um/arch/um/kernel/skas/tlb.c
24546 --- orig/arch/um/kernel/skas/tlb.c Wed Dec 31 19:00:00 1969
24547 +++ um/arch/um/kernel/skas/tlb.c Sun Dec 22 18:30:35 2002
24550 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24551 + * Licensed under the GPL
24554 +#include "linux/stddef.h"
24555 +#include "linux/sched.h"
24556 +#include "asm/page.h"
24557 +#include "asm/pgtable.h"
24558 +#include "asm/mmu.h"
24559 +#include "user_util.h"
24560 +#include "mem_user.h"
24564 +static void fix_range(struct mm_struct *mm, unsigned long start_addr,
24565 + unsigned long end_addr, int force)
24570 + unsigned long addr;
24571 + int r, w, x, err, fd;
24573 + if(mm == NULL) return;
24574 + fd = mm->context.skas.mm_fd;
24575 + for(addr = start_addr; addr < end_addr;){
24576 + npgd = pgd_offset(mm, addr);
24577 + npmd = pmd_offset(npgd, addr);
24578 + if(pmd_present(*npmd)){
24579 + npte = pte_offset(npmd, addr);
24580 + r = pte_read(*npte);
24581 + w = pte_write(*npte);
24582 + x = pte_exec(*npte);
24583 + if(!pte_dirty(*npte)) w = 0;
24584 + if(!pte_young(*npte)){
24588 + if(force || pte_newpage(*npte)){
24589 + err = unmap(fd, (void *) addr, PAGE_SIZE);
24591 + panic("munmap failed, errno = %d\n",
24593 + if(pte_present(*npte))
24595 + pte_val(*npte) & PAGE_MASK,
24596 + PAGE_SIZE, r, w, x);
24598 + else if(pte_newprot(*npte)){
24599 + protect(fd, addr, PAGE_SIZE, r, w, x, 1);
24601 + *npte = pte_mkuptodate(*npte);
24602 + addr += PAGE_SIZE;
24605 + if(force || pmd_newpage(*npmd)){
24606 + err = unmap(fd, (void *) addr, PMD_SIZE);
24608 + panic("munmap failed, errno = %d\n",
24610 + pmd_mkuptodate(*npmd);
24612 + addr += PMD_SIZE;
24617 +static void flush_kernel_vm_range(unsigned long start, unsigned long end)
24619 + struct mm_struct *mm;
24623 + unsigned long addr;
24624 + int updated = 0, err;
24627 + for(addr = start_vm; addr < end_vm;){
24628 + pgd = pgd_offset(mm, addr);
24629 + pmd = pmd_offset(pgd, addr);
24630 + if(pmd_present(*pmd)){
24631 + pte = pte_offset(pmd, addr);
24632 + if(!pte_present(*pte) || pte_newpage(*pte)){
24634 + err = os_unmap_memory((void *) addr,
24637 + panic("munmap failed, errno = %d\n",
24639 + if(pte_present(*pte))
24641 + pte_val(*pte) & PAGE_MASK,
24642 + PAGE_SIZE, 1, 1, 1);
24644 + else if(pte_newprot(*pte)){
24646 + protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
24648 + addr += PAGE_SIZE;
24651 + if(pmd_newpage(*pmd)){
24653 + err = os_unmap_memory((void *) addr, PMD_SIZE);
24655 + panic("munmap failed, errno = %d\n",
24658 + addr += PMD_SIZE;
24663 +void flush_tlb_kernel_vm_skas(void)
24665 + flush_kernel_vm_range(start_vm, end_vm);
24668 +void __flush_tlb_one_skas(unsigned long addr)
24670 + flush_kernel_vm_range(addr, addr + PAGE_SIZE);
24673 +void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start,
24674 + unsigned long end)
24677 + flush_kernel_vm_range(start, end);
24678 + else fix_range(mm, start, end, 0);
24681 +void flush_tlb_mm_skas(struct mm_struct *mm)
24683 + flush_tlb_kernel_vm_skas();
24684 + fix_range(mm, 0, host_task_size, 0);
24687 +void force_flush_all_skas(void)
24689 + fix_range(current->mm, 0, host_task_size, 1);
24693 + * Overrides for Emacs so that we follow Linus's tabbing style.
24694 + * Emacs will notice this stuff at the end of the file and automatically
24695 + * adjust the settings for this buffer only. This must remain at the end
24697 + * ---------------------------------------------------------------------------
24698 + * Local variables:
24699 + * c-file-style: "linux"
24702 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/trap_user.c um/arch/um/kernel/skas/trap_user.c
24703 --- orig/arch/um/kernel/skas/trap_user.c Wed Dec 31 19:00:00 1969
24704 +++ um/arch/um/kernel/skas/trap_user.c Sun Dec 15 13:28:41 2002
24707 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24708 + * Licensed under the GPL
24711 +#include <signal.h>
24712 +#include <errno.h>
24713 +#include <asm/sigcontext.h>
24714 +#include "sysdep/ptrace.h"
24715 +#include "signal_user.h"
24716 +#include "user_util.h"
24717 +#include "kern_util.h"
24719 +#include "sigcontext.h"
24721 +void sig_handler_common_skas(int sig, void *sc_ptr)
24723 + struct sigcontext *sc = sc_ptr;
24724 + struct skas_regs *r;
24725 + struct signal_info *info;
24726 + int save_errno = errno;
24728 + r = &TASK_REGS(get_current())->skas;
24730 + r->fault_addr = SC_FAULT_ADDR(sc);
24731 + r->fault_type = SC_FAULT_TYPE(sc);
24732 + r->trap_type = SC_TRAP_TYPE(sc);
24734 + change_sig(SIGUSR1, 1);
24735 + info = &sig_info[sig];
24736 + if(!info->is_irq) unblock_signals();
24738 + (*info->handler)(sig, (union uml_pt_regs *) r);
24740 + errno = save_errno;
24743 +extern int missed_ticks[];
24745 +void user_signal(int sig, union uml_pt_regs *regs)
24747 + struct signal_info *info;
24749 + if(sig == SIGVTALRM)
24750 + missed_ticks[cpu()]++;
24751 + regs->skas.is_user = 1;
24752 + regs->skas.fault_addr = 0;
24753 + regs->skas.fault_type = 0;
24754 + regs->skas.trap_type = 0;
24755 + info = &sig_info[sig];
24756 + (*info->handler)(sig, regs);
24758 + unblock_signals();
24762 + * Overrides for Emacs so that we follow Linus's tabbing style.
24763 + * Emacs will notice this stuff at the end of the file and automatically
24764 + * adjust the settings for this buffer only. This must remain at the end
24766 + * ---------------------------------------------------------------------------
24767 + * Local variables:
24768 + * c-file-style: "linux"
24771 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/Makefile um/arch/um/kernel/skas/util/Makefile
24772 --- orig/arch/um/kernel/skas/util/Makefile Wed Dec 31 19:00:00 1969
24773 +++ um/arch/um/kernel/skas/util/Makefile Wed Oct 23 21:08:04 2002
24777 +mk_ptregs : mk_ptregs.o
24778 + $(CC) -o mk_ptregs mk_ptregs.o
24780 +mk_ptregs.o : mk_ptregs.c
24784 + $(RM) -f mk_ptregs *.o *~
24785 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/mk_ptregs.c um/arch/um/kernel/skas/util/mk_ptregs.c
24786 --- orig/arch/um/kernel/skas/util/mk_ptregs.c Wed Dec 31 19:00:00 1969
24787 +++ um/arch/um/kernel/skas/util/mk_ptregs.c Mon Nov 11 12:10:06 2002
24789 +#include <asm/ptrace.h>
24790 +#include <asm/user.h>
24792 +#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val))
24794 +int main(int argc, char **argv)
24796 + printf("/* Automatically generated by "
24797 + "arch/um/kernel/skas/util/mk_ptregs */\n");
24799 + printf("#ifndef __SKAS_PT_REGS_\n");
24800 + printf("#define __SKAS_PT_REGS_\n");
24802 + printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE);
24803 + printf("#define HOST_FP_SIZE %d\n",
24804 + sizeof(struct user_i387_struct) / sizeof(unsigned long));
24805 + printf("#define HOST_XFP_SIZE %d\n",
24806 + sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
24808 + PRINT_REG("IP", EIP);
24809 + PRINT_REG("SP", UESP);
24810 + PRINT_REG("EFLAGS", EFL);
24811 + PRINT_REG("EAX", EAX);
24812 + PRINT_REG("EBX", EBX);
24813 + PRINT_REG("ECX", ECX);
24814 + PRINT_REG("EDX", EDX);
24815 + PRINT_REG("ESI", ESI);
24816 + PRINT_REG("EDI", EDI);
24817 + PRINT_REG("EBP", EBP);
24818 + PRINT_REG("CS", CS);
24819 + PRINT_REG("SS", SS);
24820 + PRINT_REG("DS", DS);
24821 + PRINT_REG("FS", FS);
24822 + PRINT_REG("ES", ES);
24823 + PRINT_REG("GS", GS);
24825 + printf("#endif\n");
24830 + * Overrides for Emacs so that we follow Linus's tabbing style.
24831 + * Emacs will notice this stuff at the end of the file and automatically
24832 + * adjust the settings for this buffer only. This must remain at the end
24834 + * ---------------------------------------------------------------------------
24835 + * Local variables:
24836 + * c-file-style: "linux"
24839 diff -Naur -X ../exclude-files orig/arch/um/kernel/smp.c um/arch/um/kernel/smp.c
24840 --- orig/arch/um/kernel/smp.c Wed Dec 31 19:00:00 1969
24841 +++ um/arch/um/kernel/smp.c Sat Feb 22 14:28:45 2003
24844 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
24845 + * Licensed under the GPL
24848 +#include "linux/config.h"
24853 +#include "linux/sched.h"
24854 +#include "linux/threads.h"
24855 +#include "linux/interrupt.h"
24856 +#include "asm/smp.h"
24857 +#include "asm/processor.h"
24858 +#include "asm/spinlock.h"
24859 +#include "asm/softirq.h"
24860 +#include "asm/hardirq.h"
24861 +#include "user_util.h"
24862 +#include "kern_util.h"
24863 +#include "irq_user.h"
24867 +/* Total count of live CPUs, set by smp_boot_cpus */
24868 +int smp_num_cpus = 1;
24870 +/* The 'big kernel lock' */
24871 +spinlock_cacheline_t kernel_flag_cacheline = {SPIN_LOCK_UNLOCKED};
24873 +/* Per CPU bogomips and other parameters */
24875 +/* The only piece used here is the ipi pipe, which is set before SMP is
24876 + * started and never changed.
24878 +struct cpuinfo_um cpu_data[NR_CPUS];
24880 +/* CPU online map, set by smp_boot_cpus */
24881 +unsigned long cpu_online_map;
24883 +atomic_t global_bh_count;
24885 +/* Set when the idlers are all forked */
24886 +int smp_threads_ready = 0;
24888 +/* Not used by UML */
24889 +unsigned char global_irq_holder = 0;
24890 +unsigned volatile long global_irq_lock;
24892 +/* A statistic, can be a little off */
24893 +static int num_reschedules_sent = 0;
24895 +void smp_send_reschedule(int cpu)
24897 + write(cpu_data[cpu].ipi_pipe[1], "R", 1);
24898 + num_reschedules_sent++;
24901 +static void show(char * str)
24903 + int cpu = smp_processor_id();
24905 + printk(KERN_INFO "\n%s, CPU %d:\n", str, cpu);
24908 +#define MAXCOUNT 100000000
24910 +static inline void wait_on_bh(void)
24912 + int count = MAXCOUNT;
24915 + show("wait_on_bh");
24918 + /* nothing .. wait for the other bh's to go away */
24919 + } while (atomic_read(&global_bh_count) != 0);
24923 + * This is called when we want to synchronize with
24924 + * bottom half handlers. We need to wait until
24925 + * no other CPU is executing any bottom half handler.
24927 + * Don't wait if we're already running in an interrupt
24928 + * context or are inside a bh handler.
24930 +void synchronize_bh(void)
24932 + if (atomic_read(&global_bh_count) && !in_interrupt())
24936 +void smp_send_stop(void)
24940 + printk(KERN_INFO "Stopping all CPUs...");
24941 + for(i = 0; i < ncpus; i++){
24942 + if(i == current->processor)
24944 + write(cpu_data[i].ipi_pipe[1], "S", 1);
24946 + printk("done\n");
24950 +static atomic_t smp_commenced = ATOMIC_INIT(0);
24951 +static volatile unsigned long smp_callin_map = 0;
24953 +void smp_commence(void)
24955 + printk("All CPUs are go!\n");
24958 + atomic_set(&smp_commenced, 1);
24961 +static int idle_proc(void *unused)
24965 + set_current(current);
24966 + del_from_runqueue(current);
24967 + unhash_process(current);
24969 + cpu = current->processor;
24970 + err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
24972 + panic("CPU#%d failed to create IPI pipe, errno = %d", cpu,
24975 + activate_ipi(cpu_data[cpu].ipi_pipe[0],
24976 + current->thread.mode.tt.extern_pid);
24979 + if (test_and_set_bit(current->processor, &smp_callin_map)) {
24980 + printk("huh, CPU#%d already present??\n", current->processor);
24984 + while (!atomic_read(&smp_commenced))
24992 +static int idle_thread(int (*fn)(void *), int cpu)
24994 + struct task_struct *new_task;
24998 + current->thread.request.u.thread.proc = fn;
24999 + current->thread.request.u.thread.arg = NULL;
25000 + pid = do_fork(CLONE_VM | CLONE_PID, 0, NULL, 0);
25001 + if(pid < 0) panic("do_fork failed in idle_thread");
25002 + new_task = get_task(pid, 1);
25004 + cpu_tasks[cpu].pid = new_task->thread.mode.tt.extern_pid;
25005 + cpu_tasks[cpu].task = new_task;
25006 + init_tasks[cpu] = new_task;
25007 + new_task->processor = cpu;
25008 + new_task->cpus_allowed = 1 << cpu;
25009 + new_task->cpus_runnable = new_task->cpus_allowed;
25010 + CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c,
25012 + ({ panic("skas mode doesn't support SMP"); }));
25013 + return(new_task->thread.mode.tt.extern_pid);
25016 +void smp_boot_cpus(void)
25020 + set_bit(0, &cpu_online_map);
25021 + set_bit(0, &smp_callin_map);
25023 + err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
25024 + if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
25026 + activate_ipi(cpu_data[0].ipi_pipe[0],
25027 + current->thread.mode.tt.extern_pid);
25030 + printk(KERN_INFO "ncpus set to 1\n");
25033 + else if(ncpus > NR_CPUS){
25035 + "ncpus can't be greater than NR_CPUS, set to %d\n",
25043 + printk(KERN_INFO "Starting up other processors:\n");
25044 + for(i=1;i<ncpus;i++){
25047 + /* Do this early, for hard_smp_processor_id() */
25048 + cpu_tasks[i].pid = -1;
25049 + set_bit(i, &cpu_online_map);
25052 + pid = idle_thread(idle_proc, i);
25053 + printk(KERN_INFO "\t#%d - idle thread pid = %d.. ",
25056 + waittime = 200000000;
25057 + while (waittime-- && !test_bit(i, &smp_callin_map))
25060 + if (test_bit(i, &smp_callin_map))
25061 + printk("online\n");
25063 + printk("failed\n");
25064 + clear_bit(i, &cpu_online_map);
25070 +int setup_profiling_timer(unsigned int multiplier)
25072 + printk(KERN_INFO "setup_profiling_timer\n");
25076 +void smp_call_function_slave(int cpu);
25078 +void IPI_handler(int cpu)
25083 + fd = cpu_data[cpu].ipi_pipe[0];
25084 + while (read(fd, &c, 1) == 1) {
25087 + smp_call_function_slave(cpu);
25091 + current->need_resched = 1;
25095 + printk("CPU#%d stopping\n", cpu);
25101 + printk("CPU#%d received unknown IPI [%c]!\n", cpu, c);
25107 +int hard_smp_processor_id(void)
25109 + return(pid_to_processor_id(os_getpid()));
25112 +static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
25113 +static atomic_t scf_started;
25114 +static atomic_t scf_finished;
25115 +static void (*func)(void *info);
25116 +static void *info;
25118 +void smp_call_function_slave(int cpu)
25120 + atomic_inc(&scf_started);
25122 + atomic_inc(&scf_finished);
25125 +int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic,
25128 + int cpus = smp_num_cpus - 1;
25134 + spin_lock_bh(&call_lock);
25135 + atomic_set(&scf_started, 0);
25136 + atomic_set(&scf_finished, 0);
25140 + for (i=0;i<NR_CPUS;i++)
25141 + if (i != current->processor && test_bit(i, &cpu_online_map))
25142 + write(cpu_data[i].ipi_pipe[1], "C", 1);
25144 + while (atomic_read(&scf_started) != cpus)
25148 + while (atomic_read(&scf_finished) != cpus)
25151 + spin_unlock_bh(&call_lock);
25158 + * Overrides for Emacs so that we follow Linus's tabbing style.
25159 + * Emacs will notice this stuff at the end of the file and automatically
25160 + * adjust the settings for this buffer only. This must remain at the end
25162 + * ---------------------------------------------------------------------------
25163 + * Local variables:
25164 + * c-file-style: "linux"
25167 diff -Naur -X ../exclude-files orig/arch/um/kernel/sys_call_table.c um/arch/um/kernel/sys_call_table.c
25168 --- orig/arch/um/kernel/sys_call_table.c Wed Dec 31 19:00:00 1969
25169 +++ um/arch/um/kernel/sys_call_table.c Thu Feb 27 13:33:23 2003
25172 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
25173 + * Licensed under the GPL
25176 +#include "linux/unistd.h"
25177 +#include "linux/version.h"
25178 +#include "linux/sys.h"
25179 +#include "asm/signal.h"
25180 +#include "sysdep/syscalls.h"
25181 +#include "kern_util.h"
25183 +extern syscall_handler_t sys_ni_syscall;
25184 +extern syscall_handler_t sys_exit;
25185 +extern syscall_handler_t sys_fork;
25186 +extern syscall_handler_t sys_creat;
25187 +extern syscall_handler_t sys_link;
25188 +extern syscall_handler_t sys_unlink;
25189 +extern syscall_handler_t sys_chdir;
25190 +extern syscall_handler_t sys_mknod;
25191 +extern syscall_handler_t sys_chmod;
25192 +extern syscall_handler_t sys_lchown16;
25193 +extern syscall_handler_t sys_ni_syscall;
25194 +extern syscall_handler_t sys_stat;
25195 +extern syscall_handler_t sys_getpid;
25196 +extern syscall_handler_t sys_oldumount;
25197 +extern syscall_handler_t sys_setuid16;
25198 +extern syscall_handler_t sys_getuid16;
25199 +extern syscall_handler_t sys_ptrace;
25200 +extern syscall_handler_t sys_alarm;
25201 +extern syscall_handler_t sys_fstat;
25202 +extern syscall_handler_t sys_pause;
25203 +extern syscall_handler_t sys_utime;
25204 +extern syscall_handler_t sys_ni_syscall;
25205 +extern syscall_handler_t sys_ni_syscall;
25206 +extern syscall_handler_t sys_access;
25207 +extern syscall_handler_t sys_nice;
25208 +extern syscall_handler_t sys_ni_syscall;
25209 +extern syscall_handler_t sys_sync;
25210 +extern syscall_handler_t sys_kill;
25211 +extern syscall_handler_t sys_rename;
25212 +extern syscall_handler_t sys_mkdir;
25213 +extern syscall_handler_t sys_rmdir;
25214 +extern syscall_handler_t sys_pipe;
25215 +extern syscall_handler_t sys_times;
25216 +extern syscall_handler_t sys_ni_syscall;
25217 +extern syscall_handler_t sys_brk;
25218 +extern syscall_handler_t sys_setgid16;
25219 +extern syscall_handler_t sys_getgid16;
25220 +extern syscall_handler_t sys_signal;
25221 +extern syscall_handler_t sys_geteuid16;
25222 +extern syscall_handler_t sys_getegid16;
25223 +extern syscall_handler_t sys_acct;
25224 +extern syscall_handler_t sys_umount;
25225 +extern syscall_handler_t sys_ni_syscall;
25226 +extern syscall_handler_t sys_ioctl;
25227 +extern syscall_handler_t sys_fcntl;
25228 +extern syscall_handler_t sys_ni_syscall;
25229 +extern syscall_handler_t sys_setpgid;
25230 +extern syscall_handler_t sys_ni_syscall;
25231 +extern syscall_handler_t sys_olduname;
25232 +extern syscall_handler_t sys_umask;
25233 +extern syscall_handler_t sys_chroot;
25234 +extern syscall_handler_t sys_ustat;
25235 +extern syscall_handler_t sys_dup2;
25236 +extern syscall_handler_t sys_getppid;
25237 +extern syscall_handler_t sys_getpgrp;
25238 +extern syscall_handler_t sys_sigaction;
25239 +extern syscall_handler_t sys_sgetmask;
25240 +extern syscall_handler_t sys_ssetmask;
25241 +extern syscall_handler_t sys_setreuid16;
25242 +extern syscall_handler_t sys_setregid16;
25243 +extern syscall_handler_t sys_sigsuspend;
25244 +extern syscall_handler_t sys_sigpending;
25245 +extern syscall_handler_t sys_sethostname;
25246 +extern syscall_handler_t sys_setrlimit;
25247 +extern syscall_handler_t sys_old_getrlimit;
25248 +extern syscall_handler_t sys_getrusage;
25249 +extern syscall_handler_t sys_gettimeofday;
25250 +extern syscall_handler_t sys_settimeofday;
25251 +extern syscall_handler_t sys_getgroups16;
25252 +extern syscall_handler_t sys_setgroups16;
25253 +extern syscall_handler_t sys_symlink;
25254 +extern syscall_handler_t sys_lstat;
25255 +extern syscall_handler_t sys_readlink;
25256 +extern syscall_handler_t sys_uselib;
25257 +extern syscall_handler_t sys_swapon;
25258 +extern syscall_handler_t sys_reboot;
25259 +extern syscall_handler_t old_readdir;
25260 +extern syscall_handler_t sys_munmap;
25261 +extern syscall_handler_t sys_truncate;
25262 +extern syscall_handler_t sys_ftruncate;
25263 +extern syscall_handler_t sys_fchmod;
25264 +extern syscall_handler_t sys_fchown16;
25265 +extern syscall_handler_t sys_getpriority;
25266 +extern syscall_handler_t sys_setpriority;
25267 +extern syscall_handler_t sys_ni_syscall;
25268 +extern syscall_handler_t sys_statfs;
25269 +extern syscall_handler_t sys_fstatfs;
25270 +extern syscall_handler_t sys_ni_syscall;
25271 +extern syscall_handler_t sys_socketcall;
25272 +extern syscall_handler_t sys_syslog;
25273 +extern syscall_handler_t sys_setitimer;
25274 +extern syscall_handler_t sys_getitimer;
25275 +extern syscall_handler_t sys_newstat;
25276 +extern syscall_handler_t sys_newlstat;
25277 +extern syscall_handler_t sys_newfstat;
25278 +extern syscall_handler_t sys_uname;
25279 +extern syscall_handler_t sys_ni_syscall;
25280 +extern syscall_handler_t sys_vhangup;
25281 +extern syscall_handler_t sys_ni_syscall;
25282 +extern syscall_handler_t sys_ni_syscall;
25283 +extern syscall_handler_t sys_swapoff;
25284 +extern syscall_handler_t sys_sysinfo;
25285 +extern syscall_handler_t sys_ipc;
25286 +extern syscall_handler_t sys_fsync;
25287 +extern syscall_handler_t sys_sigreturn;
25288 +extern syscall_handler_t sys_rt_sigreturn;
25289 +extern syscall_handler_t sys_clone;
25290 +extern syscall_handler_t sys_setdomainname;
25291 +extern syscall_handler_t sys_newuname;
25292 +extern syscall_handler_t sys_ni_syscall;
25293 +extern syscall_handler_t sys_adjtimex;
25294 +extern syscall_handler_t sys_mprotect;
25295 +extern syscall_handler_t sys_sigprocmask;
25296 +extern syscall_handler_t sys_create_module;
25297 +extern syscall_handler_t sys_init_module;
25298 +extern syscall_handler_t sys_delete_module;
25299 +extern syscall_handler_t sys_get_kernel_syms;
25300 +extern syscall_handler_t sys_quotactl;
25301 +extern syscall_handler_t sys_getpgid;
25302 +extern syscall_handler_t sys_fchdir;
25303 +extern syscall_handler_t sys_bdflush;
25304 +extern syscall_handler_t sys_sysfs;
25305 +extern syscall_handler_t sys_personality;
25306 +extern syscall_handler_t sys_ni_syscall;
25307 +extern syscall_handler_t sys_setfsuid16;
25308 +extern syscall_handler_t sys_setfsgid16;
25309 +extern syscall_handler_t sys_llseek;
25310 +extern syscall_handler_t sys_getdents;
25311 +extern syscall_handler_t sys_flock;
25312 +extern syscall_handler_t sys_msync;
25313 +extern syscall_handler_t sys_readv;
25314 +extern syscall_handler_t sys_writev;
25315 +extern syscall_handler_t sys_getsid;
25316 +extern syscall_handler_t sys_fdatasync;
25317 +extern syscall_handler_t sys_sysctl;
25318 +extern syscall_handler_t sys_mlock;
25319 +extern syscall_handler_t sys_munlock;
25320 +extern syscall_handler_t sys_mlockall;
25321 +extern syscall_handler_t sys_munlockall;
25322 +extern syscall_handler_t sys_sched_setparam;
25323 +extern syscall_handler_t sys_sched_getparam;
25324 +extern syscall_handler_t sys_sched_setscheduler;
25325 +extern syscall_handler_t sys_sched_getscheduler;
25326 +extern syscall_handler_t sys_sched_get_priority_max;
25327 +extern syscall_handler_t sys_sched_get_priority_min;
25328 +extern syscall_handler_t sys_sched_rr_get_interval;
25329 +extern syscall_handler_t sys_nanosleep;
25330 +extern syscall_handler_t sys_mremap;
25331 +extern syscall_handler_t sys_setresuid16;
25332 +extern syscall_handler_t sys_getresuid16;
25333 +extern syscall_handler_t sys_ni_syscall;
25334 +extern syscall_handler_t sys_query_module;
25335 +extern syscall_handler_t sys_poll;
25336 +extern syscall_handler_t sys_nfsservctl;
25337 +extern syscall_handler_t sys_setresgid16;
25338 +extern syscall_handler_t sys_getresgid16;
25339 +extern syscall_handler_t sys_prctl;
25340 +extern syscall_handler_t sys_ni_syscall;
25341 +extern syscall_handler_t sys_rt_sigaction;
25342 +extern syscall_handler_t sys_rt_sigprocmask;
25343 +extern syscall_handler_t sys_rt_sigpending;
25344 +extern syscall_handler_t sys_rt_sigtimedwait;
25345 +extern syscall_handler_t sys_rt_sigqueueinfo;
25346 +extern syscall_handler_t sys_rt_sigsuspend;
25347 +extern syscall_handler_t sys_pread;
25348 +extern syscall_handler_t sys_pwrite;
25349 +extern syscall_handler_t sys_chown16;
25350 +extern syscall_handler_t sys_getcwd;
25351 +extern syscall_handler_t sys_capget;
25352 +extern syscall_handler_t sys_capset;
25353 +extern syscall_handler_t sys_sigaltstack;
25354 +extern syscall_handler_t sys_sendfile;
25355 +extern syscall_handler_t sys_ni_syscall;
25356 +extern syscall_handler_t sys_ni_syscall;
25357 +extern syscall_handler_t sys_vfork;
25358 +extern syscall_handler_t sys_getrlimit;
25359 +extern syscall_handler_t sys_mmap2;
25360 +extern syscall_handler_t sys_truncate64;
25361 +extern syscall_handler_t sys_ftruncate64;
25362 +extern syscall_handler_t sys_stat64;
25363 +extern syscall_handler_t sys_lstat64;
25364 +extern syscall_handler_t sys_fstat64;
25365 +extern syscall_handler_t sys_lchown;
25366 +extern syscall_handler_t sys_getuid;
25367 +extern syscall_handler_t sys_getgid;
25368 +extern syscall_handler_t sys_geteuid;
25369 +extern syscall_handler_t sys_getegid;
25370 +extern syscall_handler_t sys_setreuid;
25371 +extern syscall_handler_t sys_setregid;
25372 +extern syscall_handler_t sys_getgroups;
25373 +extern syscall_handler_t sys_setgroups;
25374 +extern syscall_handler_t sys_fchown;
25375 +extern syscall_handler_t sys_setresuid;
25376 +extern syscall_handler_t sys_getresuid;
25377 +extern syscall_handler_t sys_setresgid;
25378 +extern syscall_handler_t sys_getresgid;
25379 +extern syscall_handler_t sys_chown;
25380 +extern syscall_handler_t sys_setuid;
25381 +extern syscall_handler_t sys_setgid;
25382 +extern syscall_handler_t sys_setfsuid;
25383 +extern syscall_handler_t sys_setfsgid;
25384 +extern syscall_handler_t sys_pivot_root;
25385 +extern syscall_handler_t sys_mincore;
25386 +extern syscall_handler_t sys_madvise;
25387 +extern syscall_handler_t sys_fcntl64;
25388 +extern syscall_handler_t sys_getdents64;
25389 +extern syscall_handler_t sys_gettid;
25390 +extern syscall_handler_t sys_readahead;
25391 +extern syscall_handler_t sys_tkill;
25392 +extern syscall_handler_t sys_setxattr;
25393 +extern syscall_handler_t sys_lsetxattr;
25394 +extern syscall_handler_t sys_fsetxattr;
25395 +extern syscall_handler_t sys_getxattr;
25396 +extern syscall_handler_t sys_lgetxattr;
25397 +extern syscall_handler_t sys_fgetxattr;
25398 +extern syscall_handler_t sys_listxattr;
25399 +extern syscall_handler_t sys_llistxattr;
25400 +extern syscall_handler_t sys_flistxattr;
25401 +extern syscall_handler_t sys_removexattr;
25402 +extern syscall_handler_t sys_lremovexattr;
25403 +extern syscall_handler_t sys_fremovexattr;
25405 +extern syscall_handler_t um_mount;
25406 +extern syscall_handler_t um_time;
25407 +extern syscall_handler_t um_stime;
25409 +#define LAST_GENERIC_SYSCALL __NR_sched_getaffinity
25411 +#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
25412 +#define LAST_SYSCALL LAST_GENERIC_SYSCALL
25414 +#define LAST_SYSCALL LAST_ARCH_SYSCALL
25417 +syscall_handler_t *sys_call_table[] = {
25418 + [ 0 ] = sys_ni_syscall,
25419 + [ __NR_exit ] = sys_exit,
25420 + [ __NR_fork ] = sys_fork,
25421 + [ __NR_read ] = (syscall_handler_t *) sys_read,
25422 + [ __NR_write ] = (syscall_handler_t *) sys_write,
25424 + /* These three are declared differently in asm/unistd.h */
25425 + [ __NR_open ] = (syscall_handler_t *) sys_open,
25426 + [ __NR_close ] = (syscall_handler_t *) sys_close,
25427 + [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid,
25428 + [ __NR_creat ] = sys_creat,
25429 + [ __NR_link ] = sys_link,
25430 + [ __NR_unlink ] = sys_unlink,
25432 + /* declared differently in kern_util.h */
25433 + [ __NR_execve ] = (syscall_handler_t *) sys_execve,
25434 + [ __NR_chdir ] = sys_chdir,
25435 + [ __NR_time ] = um_time,
25436 + [ __NR_mknod ] = sys_mknod,
25437 + [ __NR_chmod ] = sys_chmod,
25438 + [ __NR_lchown ] = sys_lchown16,
25439 + [ __NR_break ] = sys_ni_syscall,
25440 + [ __NR_oldstat ] = sys_stat,
25441 + [ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
25442 + [ __NR_getpid ] = sys_getpid,
25443 + [ __NR_mount ] = um_mount,
25444 + [ __NR_umount ] = sys_oldumount,
25445 + [ __NR_setuid ] = sys_setuid16,
25446 + [ __NR_getuid ] = sys_getuid16,
25447 + [ __NR_stime ] = um_stime,
25448 + [ __NR_ptrace ] = sys_ptrace,
25449 + [ __NR_alarm ] = sys_alarm,
25450 + [ __NR_oldfstat ] = sys_fstat,
25451 + [ __NR_pause ] = sys_pause,
25452 + [ __NR_utime ] = sys_utime,
25453 + [ __NR_stty ] = sys_ni_syscall,
25454 + [ __NR_gtty ] = sys_ni_syscall,
25455 + [ __NR_access ] = sys_access,
25456 + [ __NR_nice ] = sys_nice,
25457 + [ __NR_ftime ] = sys_ni_syscall,
25458 + [ __NR_sync ] = sys_sync,
25459 + [ __NR_kill ] = sys_kill,
25460 + [ __NR_rename ] = sys_rename,
25461 + [ __NR_mkdir ] = sys_mkdir,
25462 + [ __NR_rmdir ] = sys_rmdir,
25464 + /* Declared differently in asm/unistd.h */
25465 + [ __NR_dup ] = (syscall_handler_t *) sys_dup,
25466 + [ __NR_pipe ] = sys_pipe,
25467 + [ __NR_times ] = sys_times,
25468 + [ __NR_prof ] = sys_ni_syscall,
25469 + [ __NR_brk ] = sys_brk,
25470 + [ __NR_setgid ] = sys_setgid16,
25471 + [ __NR_getgid ] = sys_getgid16,
25472 + [ __NR_signal ] = sys_signal,
25473 + [ __NR_geteuid ] = sys_geteuid16,
25474 + [ __NR_getegid ] = sys_getegid16,
25475 + [ __NR_acct ] = sys_acct,
25476 + [ __NR_umount2 ] = sys_umount,
25477 + [ __NR_lock ] = sys_ni_syscall,
25478 + [ __NR_ioctl ] = sys_ioctl,
25479 + [ __NR_fcntl ] = sys_fcntl,
25480 + [ __NR_mpx ] = sys_ni_syscall,
25481 + [ __NR_setpgid ] = sys_setpgid,
25482 + [ __NR_ulimit ] = sys_ni_syscall,
25483 + [ __NR_oldolduname ] = sys_olduname,
25484 + [ __NR_umask ] = sys_umask,
25485 + [ __NR_chroot ] = sys_chroot,
25486 + [ __NR_ustat ] = sys_ustat,
25487 + [ __NR_dup2 ] = sys_dup2,
25488 + [ __NR_getppid ] = sys_getppid,
25489 + [ __NR_getpgrp ] = sys_getpgrp,
25490 + [ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
25491 + [ __NR_sigaction ] = sys_sigaction,
25492 + [ __NR_sgetmask ] = sys_sgetmask,
25493 + [ __NR_ssetmask ] = sys_ssetmask,
25494 + [ __NR_setreuid ] = sys_setreuid16,
25495 + [ __NR_setregid ] = sys_setregid16,
25496 + [ __NR_sigsuspend ] = sys_sigsuspend,
25497 + [ __NR_sigpending ] = sys_sigpending,
25498 + [ __NR_sethostname ] = sys_sethostname,
25499 + [ __NR_setrlimit ] = sys_setrlimit,
25500 + [ __NR_getrlimit ] = sys_old_getrlimit,
25501 + [ __NR_getrusage ] = sys_getrusage,
25502 + [ __NR_gettimeofday ] = sys_gettimeofday,
25503 + [ __NR_settimeofday ] = sys_settimeofday,
25504 + [ __NR_getgroups ] = sys_getgroups16,
25505 + [ __NR_setgroups ] = sys_setgroups16,
25506 + [ __NR_symlink ] = sys_symlink,
25507 + [ __NR_oldlstat ] = sys_lstat,
25508 + [ __NR_readlink ] = sys_readlink,
25509 + [ __NR_uselib ] = sys_uselib,
25510 + [ __NR_swapon ] = sys_swapon,
25511 + [ __NR_reboot ] = sys_reboot,
25512 + [ __NR_readdir ] = old_readdir,
25513 + [ __NR_munmap ] = sys_munmap,
25514 + [ __NR_truncate ] = sys_truncate,
25515 + [ __NR_ftruncate ] = sys_ftruncate,
25516 + [ __NR_fchmod ] = sys_fchmod,
25517 + [ __NR_fchown ] = sys_fchown16,
25518 + [ __NR_getpriority ] = sys_getpriority,
25519 + [ __NR_setpriority ] = sys_setpriority,
25520 + [ __NR_profil ] = sys_ni_syscall,
25521 + [ __NR_statfs ] = sys_statfs,
25522 + [ __NR_fstatfs ] = sys_fstatfs,
25523 + [ __NR_ioperm ] = sys_ni_syscall,
25524 + [ __NR_socketcall ] = sys_socketcall,
25525 + [ __NR_syslog ] = sys_syslog,
25526 + [ __NR_setitimer ] = sys_setitimer,
25527 + [ __NR_getitimer ] = sys_getitimer,
25528 + [ __NR_stat ] = sys_newstat,
25529 + [ __NR_lstat ] = sys_newlstat,
25530 + [ __NR_fstat ] = sys_newfstat,
25531 + [ __NR_olduname ] = sys_uname,
25532 + [ __NR_iopl ] = sys_ni_syscall,
25533 + [ __NR_vhangup ] = sys_vhangup,
25534 + [ __NR_idle ] = sys_ni_syscall,
25535 + [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
25536 + [ __NR_swapoff ] = sys_swapoff,
25537 + [ __NR_sysinfo ] = sys_sysinfo,
25538 + [ __NR_ipc ] = sys_ipc,
25539 + [ __NR_fsync ] = sys_fsync,
25540 + [ __NR_sigreturn ] = sys_sigreturn,
25541 + [ __NR_clone ] = sys_clone,
25542 + [ __NR_setdomainname ] = sys_setdomainname,
25543 + [ __NR_uname ] = sys_newuname,
25544 + [ __NR_adjtimex ] = sys_adjtimex,
25545 + [ __NR_mprotect ] = sys_mprotect,
25546 + [ __NR_sigprocmask ] = sys_sigprocmask,
25547 + [ __NR_create_module ] = sys_create_module,
25548 + [ __NR_init_module ] = sys_init_module,
25549 + [ __NR_delete_module ] = sys_delete_module,
25550 + [ __NR_get_kernel_syms ] = sys_get_kernel_syms,
25551 + [ __NR_quotactl ] = sys_quotactl,
25552 + [ __NR_getpgid ] = sys_getpgid,
25553 + [ __NR_fchdir ] = sys_fchdir,
25554 + [ __NR_bdflush ] = sys_bdflush,
25555 + [ __NR_sysfs ] = sys_sysfs,
25556 + [ __NR_personality ] = sys_personality,
25557 + [ __NR_afs_syscall ] = sys_ni_syscall,
25558 + [ __NR_setfsuid ] = sys_setfsuid16,
25559 + [ __NR_setfsgid ] = sys_setfsgid16,
25560 + [ __NR__llseek ] = sys_llseek,
25561 + [ __NR_getdents ] = sys_getdents,
25562 + [ __NR__newselect ] = (syscall_handler_t *) sys_select,
25563 + [ __NR_flock ] = sys_flock,
25564 + [ __NR_msync ] = sys_msync,
25565 + [ __NR_readv ] = sys_readv,
25566 + [ __NR_writev ] = sys_writev,
25567 + [ __NR_getsid ] = sys_getsid,
25568 + [ __NR_fdatasync ] = sys_fdatasync,
25569 + [ __NR__sysctl ] = sys_sysctl,
25570 + [ __NR_mlock ] = sys_mlock,
25571 + [ __NR_munlock ] = sys_munlock,
25572 + [ __NR_mlockall ] = sys_mlockall,
25573 + [ __NR_munlockall ] = sys_munlockall,
25574 + [ __NR_sched_setparam ] = sys_sched_setparam,
25575 + [ __NR_sched_getparam ] = sys_sched_getparam,
25576 + [ __NR_sched_setscheduler ] = sys_sched_setscheduler,
25577 + [ __NR_sched_getscheduler ] = sys_sched_getscheduler,
25578 + [ __NR_sched_yield ] = (syscall_handler_t *) yield,
25579 + [ __NR_sched_get_priority_max ] = sys_sched_get_priority_max,
25580 + [ __NR_sched_get_priority_min ] = sys_sched_get_priority_min,
25581 + [ __NR_sched_rr_get_interval ] = sys_sched_rr_get_interval,
25582 + [ __NR_nanosleep ] = sys_nanosleep,
25583 + [ __NR_mremap ] = sys_mremap,
25584 + [ __NR_setresuid ] = sys_setresuid16,
25585 + [ __NR_getresuid ] = sys_getresuid16,
25586 + [ __NR_vm86 ] = sys_ni_syscall,
25587 + [ __NR_query_module ] = sys_query_module,
25588 + [ __NR_poll ] = sys_poll,
25589 + [ __NR_nfsservctl ] = sys_nfsservctl,
25590 + [ __NR_setresgid ] = sys_setresgid16,
25591 + [ __NR_getresgid ] = sys_getresgid16,
25592 + [ __NR_prctl ] = sys_prctl,
25593 + [ __NR_rt_sigreturn ] = sys_rt_sigreturn,
25594 + [ __NR_rt_sigaction ] = sys_rt_sigaction,
25595 + [ __NR_rt_sigprocmask ] = sys_rt_sigprocmask,
25596 + [ __NR_rt_sigpending ] = sys_rt_sigpending,
25597 + [ __NR_rt_sigtimedwait ] = sys_rt_sigtimedwait,
25598 + [ __NR_rt_sigqueueinfo ] = sys_rt_sigqueueinfo,
25599 + [ __NR_rt_sigsuspend ] = sys_rt_sigsuspend,
25600 + [ __NR_pread ] = sys_pread,
25601 + [ __NR_pwrite ] = sys_pwrite,
25602 + [ __NR_chown ] = sys_chown16,
25603 + [ __NR_getcwd ] = sys_getcwd,
25604 + [ __NR_capget ] = sys_capget,
25605 + [ __NR_capset ] = sys_capset,
25606 + [ __NR_sigaltstack ] = sys_sigaltstack,
25607 + [ __NR_sendfile ] = sys_sendfile,
25608 + [ __NR_getpmsg ] = sys_ni_syscall,
25609 + [ __NR_putpmsg ] = sys_ni_syscall,
25610 + [ __NR_vfork ] = sys_vfork,
25611 + [ __NR_ugetrlimit ] = sys_getrlimit,
25612 + [ __NR_mmap2 ] = sys_mmap2,
25613 + [ __NR_truncate64 ] = sys_truncate64,
25614 + [ __NR_ftruncate64 ] = sys_ftruncate64,
25615 + [ __NR_stat64 ] = sys_stat64,
25616 + [ __NR_lstat64 ] = sys_lstat64,
25617 + [ __NR_fstat64 ] = sys_fstat64,
25618 + [ __NR_fcntl64 ] = sys_fcntl64,
25619 + [ __NR_getdents64 ] = sys_getdents64,
25620 + [ __NR_security ] = sys_ni_syscall,
25621 + [ __NR_gettid ] = sys_gettid,
25622 + [ __NR_readahead ] = sys_readahead,
25623 + [ __NR_setxattr ] = sys_setxattr,
25624 + [ __NR_lsetxattr ] = sys_lsetxattr,
25625 + [ __NR_fsetxattr ] = sys_fsetxattr,
25626 + [ __NR_getxattr ] = sys_getxattr,
25627 + [ __NR_lgetxattr ] = sys_lgetxattr,
25628 + [ __NR_fgetxattr ] = sys_fgetxattr,
25629 + [ __NR_listxattr ] = sys_listxattr,
25630 + [ __NR_llistxattr ] = sys_llistxattr,
25631 + [ __NR_flistxattr ] = sys_flistxattr,
25632 + [ __NR_removexattr ] = sys_removexattr,
25633 + [ __NR_lremovexattr ] = sys_lremovexattr,
25634 + [ __NR_fremovexattr ] = sys_fremovexattr,
25635 + [ __NR_tkill ] = sys_tkill,
25636 + [ __NR_sendfile64 ] = sys_ni_syscall,
25637 + [ __NR_futex ] = sys_ni_syscall,
25638 + [ __NR_sched_setaffinity ] = sys_ni_syscall,
25639 + [ __NR_sched_getaffinity ] = sys_ni_syscall,
25642 + [ LAST_SYSCALL + 1 ... NR_syscalls ] =
25643 + (syscall_handler_t *) sys_ni_syscall
25647 + * Overrides for Emacs so that we follow Linus's tabbing style.
25648 + * Emacs will notice this stuff at the end of the file and automatically
25649 + * adjust the settings for this buffer only. This must remain at the end
25651 + * ---------------------------------------------------------------------------
25652 + * Local variables:
25653 + * c-file-style: "linux"
25656 diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_kern.c um/arch/um/kernel/syscall_kern.c
25657 --- orig/arch/um/kernel/syscall_kern.c Wed Dec 31 19:00:00 1969
25658 +++ um/arch/um/kernel/syscall_kern.c Fri Nov 8 14:04:10 2002
25661 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
25662 + * Licensed under the GPL
25665 +#include "linux/sched.h"
25666 +#include "linux/file.h"
25667 +#include "linux/smp_lock.h"
25668 +#include "linux/mm.h"
25669 +#include "linux/utsname.h"
25670 +#include "linux/msg.h"
25671 +#include "linux/shm.h"
25672 +#include "linux/sys.h"
25673 +#include "linux/unistd.h"
25674 +#include "linux/slab.h"
25675 +#include "linux/utime.h"
25676 +#include "asm/mman.h"
25677 +#include "asm/uaccess.h"
25678 +#include "asm/ipc.h"
25679 +#include "kern_util.h"
25680 +#include "user_util.h"
25681 +#include "sysdep/syscalls.h"
25682 +#include "mode_kern.h"
25683 +#include "choose-mode.h"
25685 +/* Unlocked, I don't care if this is a bit off */
25686 +int nsyscalls = 0;
25688 +long um_mount(char * dev_name, char * dir_name, char * type,
25689 + unsigned long new_flags, void * data)
25691 + if(type == NULL) type = "";
25692 + return(sys_mount(dev_name, dir_name, type, new_flags, data));
25695 +long sys_fork(void)
25699 + current->thread.forking = 1;
25700 + ret = do_fork(SIGCHLD, 0, NULL, 0);
25701 + current->thread.forking = 0;
25705 +long sys_clone(unsigned long clone_flags, unsigned long newsp)
25709 + current->thread.forking = 1;
25710 + ret = do_fork(clone_flags, newsp, NULL, 0);
25711 + current->thread.forking = 0;
25715 +long sys_vfork(void)
25719 + current->thread.forking = 1;
25720 + ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0);
25721 + current->thread.forking = 0;
25725 +/* common code for old and new mmaps */
25726 +long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
25727 + unsigned long prot, unsigned long flags, unsigned long fd,
25728 + unsigned long pgoff)
25730 + int error = -EBADF;
25731 + struct file * file = NULL;
25733 + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
25734 + if (!(flags & MAP_ANONYMOUS)) {
25740 + down_write(&mm->mmap_sem);
25741 + error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
25742 + up_write(&mm->mmap_sem);
25750 +long sys_mmap2(unsigned long addr, unsigned long len,
25751 + unsigned long prot, unsigned long flags,
25752 + unsigned long fd, unsigned long pgoff)
25754 + return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
25758 + * Perform the select(nd, in, out, ex, tv) and mmap() system
25759 + * calls. Linux/i386 didn't use to be able to handle more than
25760 + * 4 system call parameters, so these system calls used a memory
25761 + * block for parameter passing..
25764 +struct mmap_arg_struct {
25765 + unsigned long addr;
25766 + unsigned long len;
25767 + unsigned long prot;
25768 + unsigned long flags;
25769 + unsigned long fd;
25770 + unsigned long offset;
25773 +int old_mmap(unsigned long addr, unsigned long len,
25774 + unsigned long prot, unsigned long flags,
25775 + unsigned long fd, unsigned long offset)
25777 + int err = -EINVAL;
25778 + if (offset & ~PAGE_MASK)
25781 + err = do_mmap2(current->mm, addr, len, prot, flags, fd,
25782 + offset >> PAGE_SHIFT);
25787 + * sys_pipe() is the normal C calling standard for creating
25788 + * a pipe. It's not the way unix traditionally does this, though.
25790 +int sys_pipe(unsigned long * fildes)
25795 + error = do_pipe(fd);
25797 + if (copy_to_user(fildes, fd, 2*sizeof(int)))
25803 +int sys_pause(void)
25805 + current->state = TASK_INTERRUPTIBLE;
25807 + return -ERESTARTNOHAND;
25810 +int sys_sigaction(int sig, const struct old_sigaction *act,
25811 + struct old_sigaction *oact)
25813 + struct k_sigaction new_ka, old_ka;
25817 + old_sigset_t mask;
25818 + if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
25819 + __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
25820 + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
25822 + __get_user(new_ka.sa.sa_flags, &act->sa_flags);
25823 + __get_user(mask, &act->sa_mask);
25824 + siginitset(&new_ka.sa.sa_mask, mask);
25827 + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
25829 + if (!ret && oact) {
25830 + if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
25831 + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
25832 + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
25834 + __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
25835 + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
25842 + * sys_ipc() is the de-multiplexer for the SysV IPC calls..
25844 + * This is really horribly ugly.
25846 +int sys_ipc (uint call, int first, int second,
25847 + int third, void *ptr, long fifth)
25849 + int version, ret;
25851 + version = call >> 16; /* hack for backward compatibility */
25856 + return sys_semop (first, (struct sembuf *)ptr, second);
25858 + return sys_semget (first, second, third);
25860 + union semun fourth;
25863 + if (get_user(fourth.__pad, (void **) ptr))
25865 + return sys_semctl (first, second, third, fourth);
25869 + return sys_msgsnd (first, (struct msgbuf *) ptr,
25872 + switch (version) {
25874 + struct ipc_kludge tmp;
25878 + if (copy_from_user(&tmp,
25879 + (struct ipc_kludge *) ptr,
25882 + return sys_msgrcv (first, tmp.msgp, second,
25883 + tmp.msgtyp, third);
25886 + panic("msgrcv with version != 0");
25887 + return sys_msgrcv (first,
25888 + (struct msgbuf *) ptr,
25889 + second, fifth, third);
25892 + return sys_msgget ((key_t) first, second);
25894 + return sys_msgctl (first, second, (struct msqid_ds *) ptr);
25897 + switch (version) {
25900 + ret = sys_shmat (first, (char *) ptr, second, &raddr);
25903 + return put_user (raddr, (ulong *) third);
25905 + case 1: /* iBCS2 emulator entry point */
25906 + if (!segment_eq(get_fs(), get_ds()))
25908 + return sys_shmat (first, (char *) ptr, second, (ulong *) third);
25911 + return sys_shmdt ((char *)ptr);
25913 + return sys_shmget (first, second, third);
25915 + return sys_shmctl (first, second,
25916 + (struct shmid_ds *) ptr);
25922 +int sys_uname(struct old_utsname * name)
25927 + down_read(&uts_sem);
25928 + err=copy_to_user(name, &system_utsname, sizeof (*name));
25929 + up_read(&uts_sem);
25930 + return err?-EFAULT:0;
25933 +int sys_olduname(struct oldold_utsname * name)
25939 + if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
25942 + down_read(&uts_sem);
25944 + error = __copy_to_user(&name->sysname,&system_utsname.sysname,
25946 + error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
25947 + error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
25949 + error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
25950 + error |= __copy_to_user(&name->release,&system_utsname.release,
25952 + error |= __put_user(0,name->release+__OLD_UTS_LEN);
25953 + error |= __copy_to_user(&name->version,&system_utsname.version,
25955 + error |= __put_user(0,name->version+__OLD_UTS_LEN);
25956 + error |= __copy_to_user(&name->machine,&system_utsname.machine,
25958 + error |= __put_user(0,name->machine+__OLD_UTS_LEN);
25960 + up_read(&uts_sem);
25962 + error = error ? -EFAULT : 0;
25967 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
25969 + return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
25972 +long execute_syscall(void *r)
25974 + return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
25977 +spinlock_t syscall_lock = SPIN_LOCK_UNLOCKED;
25979 +static int syscall_index = 0;
25981 +int next_syscall_index(int limit)
25985 + spin_lock(&syscall_lock);
25986 + ret = syscall_index;
25987 + if(++syscall_index == limit)
25988 + syscall_index = 0;
25989 + spin_unlock(&syscall_lock);
25994 + * Overrides for Emacs so that we follow Linus's tabbing style.
25995 + * Emacs will notice this stuff at the end of the file and automatically
25996 + * adjust the settings for this buffer only. This must remain at the end
25998 + * ---------------------------------------------------------------------------
25999 + * Local variables:
26000 + * c-file-style: "linux"
26003 diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_user.c um/arch/um/kernel/syscall_user.c
26004 --- orig/arch/um/kernel/syscall_user.c Wed Dec 31 19:00:00 1969
26005 +++ um/arch/um/kernel/syscall_user.c Wed Oct 23 21:08:04 2002
26008 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
26009 + * Licensed under the GPL
26012 +#include <stdlib.h>
26013 +#include <sys/time.h>
26014 +#include "kern_util.h"
26015 +#include "syscall_user.h"
26021 + struct timeval start;
26022 + struct timeval end;
26023 +} syscall_record[1024];
26025 +int record_syscall_start(int syscall)
26029 + max = sizeof(syscall_record)/sizeof(syscall_record[0]);
26030 + index = next_syscall_index(max);
26032 + syscall_record[index].syscall = syscall;
26033 + syscall_record[index].pid = current_pid();
26034 + syscall_record[index].result = 0xdeadbeef;
26035 + gettimeofday(&syscall_record[index].start, NULL);
26039 +void record_syscall_end(int index, int result)
26041 + syscall_record[index].result = result;
26042 + gettimeofday(&syscall_record[index].end, NULL);
26046 + * Overrides for Emacs so that we follow Linus's tabbing style.
26047 + * Emacs will notice this stuff at the end of the file and automatically
26048 + * adjust the settings for this buffer only. This must remain at the end
26050 + * ---------------------------------------------------------------------------
26051 + * Local variables:
26052 + * c-file-style: "linux"
26055 diff -Naur -X ../exclude-files orig/arch/um/kernel/sysrq.c um/arch/um/kernel/sysrq.c
26056 --- orig/arch/um/kernel/sysrq.c Wed Dec 31 19:00:00 1969
26057 +++ um/arch/um/kernel/sysrq.c Wed Oct 23 21:08:04 2002
26060 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
26061 + * Licensed under the GPL
26064 +#include "linux/sched.h"
26065 +#include "linux/kernel.h"
26066 +#include "linux/module.h"
26067 +#include "asm/page.h"
26068 +#include "asm/processor.h"
26069 +#include "sysrq.h"
26070 +#include "user_util.h"
26073 + * If the address is either in the .text section of the
26074 + * kernel, or in the vmalloc'ed module regions, it *may*
26075 + * be the address of a calling routine
26078 +#ifdef CONFIG_MODULES
26080 +extern struct module *module_list;
26081 +extern struct module kernel_module;
26083 +static inline int kernel_text_address(unsigned long addr)
26086 + struct module *mod;
26088 + if (addr >= (unsigned long) &_stext &&
26089 + addr <= (unsigned long) &_etext)
26092 + for (mod = module_list; mod != &kernel_module; mod = mod->next) {
26093 + /* mod_bound tests for addr being inside the vmalloc'ed
26094 + * module area. Of course it'd be better to test only
26095 + * for the .text subset... */
26096 + if (mod_bound(addr, 0, mod)) {
26107 +static inline int kernel_text_address(unsigned long addr)
26109 + return (addr >= (unsigned long) &_stext &&
26110 + addr <= (unsigned long) &_etext);
26115 +void show_trace(unsigned long * stack)
26118 + unsigned long addr;
26121 + stack = (unsigned long*) &stack;
26123 + printk("Call Trace: ");
26125 + while (((long) stack & (THREAD_SIZE-1)) != 0) {
26127 + if (kernel_text_address(addr)) {
26128 + if (i && ((i % 6) == 0))
26130 + printk("[<%08lx>] ", addr);
26137 +void show_trace_task(struct task_struct *tsk)
26139 + unsigned long esp = PT_REGS_SP(&tsk->thread.regs);
26141 + /* User space on another CPU? */
26142 + if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
26144 + show_trace((unsigned long *)esp);
26148 + * Overrides for Emacs so that we follow Linus's tabbing style.
26149 + * Emacs will notice this stuff at the end of the file and automatically
26150 + * adjust the settings for this buffer only. This must remain at the end
26152 + * ---------------------------------------------------------------------------
26153 + * Local variables:
26154 + * c-file-style: "linux"
26157 diff -Naur -X ../exclude-files orig/arch/um/kernel/tempfile.c um/arch/um/kernel/tempfile.c
26158 --- orig/arch/um/kernel/tempfile.c Wed Dec 31 19:00:00 1969
26159 +++ um/arch/um/kernel/tempfile.c Fri Jan 17 23:16:19 2003
26162 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
26163 + * Licensed under the GPL
26166 +#include <stdio.h>
26167 +#include <stdlib.h>
26168 +#include <unistd.h>
26169 +#include <string.h>
26170 +#include <errno.h>
26171 +#include <sys/param.h>
26174 +/* Modified from create_mem_file and start_debugger */
26175 +static char *tempdir = NULL;
26177 +static void __init find_tempdir(void)
26179 + char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
26181 + char *dir = NULL;
26183 + if(tempdir != NULL) return; /* We've already been called */
26184 + for(i = 0; dirs[i]; i++){
26185 + dir = getenv(dirs[i]);
26186 + if((dir != NULL) && (*dir != '\0'))
26189 + if((dir == NULL) || (*dir == '\0'))
26192 + tempdir = malloc(strlen(dir) + 2);
26193 + if(tempdir == NULL){
26194 + fprintf(stderr, "Failed to malloc tempdir, "
26195 + "errno = %d\n", errno);
26198 + strcpy(tempdir, dir);
26199 + strcat(tempdir, "/");
26202 +int make_tempfile(const char *template, char **out_tempname, int do_unlink)
26204 + char tempname[MAXPATHLEN];
26208 + if (*template != '/')
26209 + strcpy(tempname, tempdir);
26212 + strcat(tempname, template);
26213 + if((fd = mkstemp(tempname)) < 0){
26214 + fprintf(stderr, "open - cannot create %s: %s\n", tempname,
26215 + strerror(errno));
26218 + if(do_unlink && (unlink(tempname) < 0)){
26219 + perror("unlink");
26222 + if(out_tempname){
26223 + if((*out_tempname = strdup(tempname)) == NULL){
26224 + perror("strdup");
26232 + * Overrides for Emacs so that we follow Linus's tabbing style.
26233 + * Emacs will notice this stuff at the end of the file and automatically
26234 + * adjust the settings for this buffer only. This must remain at the end
26236 + * ---------------------------------------------------------------------------
26237 + * Local variables:
26238 + * c-file-style: "linux"
26241 diff -Naur -X ../exclude-files orig/arch/um/kernel/time.c um/arch/um/kernel/time.c
26242 --- orig/arch/um/kernel/time.c Wed Dec 31 19:00:00 1969
26243 +++ um/arch/um/kernel/time.c Wed Apr 23 20:45:19 2003
26246 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
26247 + * Licensed under the GPL
26250 +#include <stdio.h>
26251 +#include <unistd.h>
26253 +#include <sys/time.h>
26254 +#include <signal.h>
26255 +#include <errno.h>
26256 +#include "user_util.h"
26257 +#include "kern_util.h"
26259 +#include "process.h"
26260 +#include "signal_user.h"
26261 +#include "time_user.h"
26263 +extern struct timeval xtime;
26265 +struct timeval local_offset = { 0, 0 };
26269 + gettimeofday(&xtime, NULL);
26270 + timeradd(&xtime, &local_offset, &xtime);
26273 +void set_interval(int timer_type)
26275 + int usec = 1000000/hz();
26276 + struct itimerval interval = ((struct itimerval) { { 0, usec },
26279 + if(setitimer(timer_type, &interval, NULL) == -1)
26280 + panic("setitimer failed - errno = %d\n", errno);
26283 +void enable_timer(void)
26285 + int usec = 1000000/hz();
26286 + struct itimerval enable = ((struct itimerval) { { 0, usec },
26288 + if(setitimer(ITIMER_VIRTUAL, &enable, NULL))
26289 + printk("enable_timer - setitimer failed, errno = %d\n",
26293 +void switch_timers(int to_real)
26295 + struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
26296 + struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
26297 + { 0, 1000000/hz() }});
26301 + old = ITIMER_VIRTUAL;
26302 + new = ITIMER_REAL;
26305 + old = ITIMER_REAL;
26306 + new = ITIMER_VIRTUAL;
26309 + if((setitimer(old, &disable, NULL) < 0) ||
26310 + (setitimer(new, &enable, NULL)))
26311 + printk("switch_timers - setitimer failed, errno = %d\n",
26315 +void idle_timer(void)
26317 + if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
26318 + panic("Couldn't unset SIGVTALRM handler");
26320 + set_handler(SIGALRM, (__sighandler_t) alarm_handler,
26321 + SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
26322 + set_interval(ITIMER_REAL);
26325 +void time_init(void)
26327 + if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
26328 + panic("Couldn't set SIGVTALRM handler");
26329 + set_interval(ITIMER_VIRTUAL);
26332 +void do_gettimeofday(struct timeval *tv)
26334 + unsigned long flags;
26336 + flags = time_lock();
26337 + gettimeofday(tv, NULL);
26338 + timeradd(tv, &local_offset, tv);
26339 + time_unlock(flags);
26342 +void do_settimeofday(struct timeval *tv)
26344 + struct timeval now;
26345 + unsigned long flags;
26347 + flags = time_lock();
26348 + gettimeofday(&now, NULL);
26349 + timersub(tv, &now, &local_offset);
26350 + time_unlock(flags);
26353 +void idle_sleep(int secs)
26355 + struct timespec ts;
26357 + ts.tv_sec = secs;
26359 + nanosleep(&ts, NULL);
26363 + * Overrides for Emacs so that we follow Linus's tabbing style.
26364 + * Emacs will notice this stuff at the end of the file and automatically
26365 + * adjust the settings for this buffer only. This must remain at the end
26367 + * ---------------------------------------------------------------------------
26368 + * Local variables:
26369 + * c-file-style: "linux"
26372 diff -Naur -X ../exclude-files orig/arch/um/kernel/time_kern.c um/arch/um/kernel/time_kern.c
26373 --- orig/arch/um/kernel/time_kern.c Wed Dec 31 19:00:00 1969
26374 +++ um/arch/um/kernel/time_kern.c Wed Apr 23 22:19:08 2003
26377 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
26378 + * Licensed under the GPL
26381 +#include "linux/kernel.h"
26382 +#include "linux/unistd.h"
26383 +#include "linux/stddef.h"
26384 +#include "linux/spinlock.h"
26385 +#include "linux/sched.h"
26386 +#include "linux/interrupt.h"
26387 +#include "linux/init.h"
26388 +#include "linux/delay.h"
26389 +#include "asm/irq.h"
26390 +#include "asm/param.h"
26391 +#include "asm/current.h"
26392 +#include "kern_util.h"
26393 +#include "user_util.h"
26394 +#include "time_user.h"
26397 +extern rwlock_t xtime_lock;
26404 +/* Changed at early boot */
26405 +int timer_irq_inited = 0;
26407 +/* missed_ticks will be modified after kernel memory has been
26408 + * write-protected, so this puts it in a section which will be left
26411 +int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
26413 +void timer_irq(union uml_pt_regs *regs)
26415 + int cpu = current->processor, ticks = missed_ticks[cpu];
26417 + if(!timer_irq_inited) return;
26418 + missed_ticks[cpu] = 0;
26419 + while(ticks--) do_IRQ(TIMER_IRQ, regs);
26422 +void boot_timer_handler(int sig)
26424 + struct pt_regs regs;
26426 + CHOOSE_MODE((void)
26427 + (UPT_SC(®s.regs) = (struct sigcontext *) (&sig + 1)),
26428 + (void) (regs.regs.skas.is_user = 0));
26432 +void um_timer(int irq, void *dev, struct pt_regs *regs)
26435 + write_lock(&xtime_lock);
26439 + write_unlock(&xtime_lock);
26442 +long um_time(int * tloc)
26444 + struct timeval now;
26446 + do_gettimeofday(&now);
26448 + if (put_user(now.tv_sec,tloc))
26449 + now.tv_sec = -EFAULT;
26451 + return now.tv_sec;
26454 +long um_stime(int * tptr)
26457 + struct timeval new;
26459 + if (get_user(value, tptr))
26461 + new.tv_sec = value;
26463 + do_settimeofday(&new);
26467 +/* XXX Needs to be moved under sys-i386 */
26468 +void __delay(um_udelay_t time)
26470 + /* Stolen from the i386 __loop_delay */
26472 + __asm__ __volatile__(
26477 + "2:\tdecl %0\n\tjns 2b"
26482 +void __udelay(um_udelay_t usecs)
26486 + n = (loops_per_jiffy * HZ * usecs) / 1000000;
26487 + for(i=0;i<n;i++) ;
26490 +void __const_udelay(um_udelay_t usecs)
26494 + n = (loops_per_jiffy * HZ * usecs) / 1000000;
26495 + for(i=0;i<n;i++) ;
26498 +void timer_handler(int sig, union uml_pt_regs *regs)
26501 + update_process_times(user_context(UPT_SP(regs)));
26503 + if(current->processor == 0)
26507 +static spinlock_t timer_spinlock = SPIN_LOCK_UNLOCKED;
26509 +unsigned long time_lock(void)
26511 + unsigned long flags;
26513 + spin_lock_irqsave(&timer_spinlock, flags);
26517 +void time_unlock(unsigned long flags)
26519 + spin_unlock_irqrestore(&timer_spinlock, flags);
26522 +int __init timer_init(void)
26526 + CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
26527 + if((err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer",
26529 + printk(KERN_ERR "timer_init : request_irq failed - "
26530 + "errno = %d\n", -err);
26531 + timer_irq_inited = 1;
26535 +__initcall(timer_init);
26539 + * Overrides for Emacs so that we follow Linus's tabbing style.
26540 + * Emacs will notice this stuff at the end of the file and automatically
26541 + * adjust the settings for this buffer only. This must remain at the end
26543 + * ---------------------------------------------------------------------------
26544 + * Local variables:
26545 + * c-file-style: "linux"
26548 diff -Naur -X ../exclude-files orig/arch/um/kernel/tlb.c um/arch/um/kernel/tlb.c
26549 --- orig/arch/um/kernel/tlb.c Wed Dec 31 19:00:00 1969
26550 +++ um/arch/um/kernel/tlb.c Wed Oct 23 22:15:51 2002
26553 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
26554 + * Licensed under the GPL
26557 +#include "linux/mm.h"
26558 +#include "asm/page.h"
26559 +#include "asm/pgalloc.h"
26560 +#include "choose-mode.h"
26561 +#include "mode_kern.h"
26563 +void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
26565 + address &= PAGE_MASK;
26566 + flush_tlb_range(vma->vm_mm, address, address + PAGE_SIZE);
26569 +void flush_tlb_all(void)
26571 + flush_tlb_mm(current->mm);
26574 +void flush_tlb_kernel_vm(void)
26576 + CHOOSE_MODE(flush_tlb_kernel_vm_tt(), flush_tlb_kernel_vm_skas());
26579 +void __flush_tlb_one(unsigned long addr)
26581 + CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
26584 +void flush_tlb_range(struct mm_struct *mm, unsigned long start,
26585 + unsigned long end)
26587 + CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, mm, start,
26591 +void flush_tlb_mm(struct mm_struct *mm)
26593 + CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
26596 +void force_flush_all(void)
26598 + CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
26602 +pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
26604 + return(pgd_offset(mm, address));
26607 +pmd_t *pmd_offset_proc(pgd_t *pgd, unsigned long address)
26609 + return(pmd_offset(pgd, address));
26612 +pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
26614 + return(pte_offset(pmd, address));
26617 +pte_t *addr_pte(struct task_struct *task, unsigned long addr)
26619 + return(pte_offset(pmd_offset(pgd_offset(task->mm, addr), addr), addr));
26623 + * Overrides for Emacs so that we follow Linus's tabbing style.
26624 + * Emacs will notice this stuff at the end of the file and automatically
26625 + * adjust the settings for this buffer only. This must remain at the end
26627 + * ---------------------------------------------------------------------------
26628 + * Local variables:
26629 + * c-file-style: "linux"
26632 diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_kern.c um/arch/um/kernel/trap_kern.c
26633 --- orig/arch/um/kernel/trap_kern.c Wed Dec 31 19:00:00 1969
26634 +++ um/arch/um/kernel/trap_kern.c Wed Mar 26 13:26:00 2003
26637 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
26638 + * Licensed under the GPL
26641 +#include "linux/kernel.h"
26642 +#include "linux/sched.h"
26643 +#include "linux/mm.h"
26644 +#include "linux/spinlock.h"
26645 +#include "linux/config.h"
26646 +#include "linux/init.h"
26647 +#include "asm/semaphore.h"
26648 +#include "asm/pgtable.h"
26649 +#include "asm/pgalloc.h"
26650 +#include "asm/a.out.h"
26651 +#include "asm/current.h"
26652 +#include "asm/irq.h"
26653 +#include "user_util.h"
26654 +#include "kern_util.h"
26656 +#include "chan_kern.h"
26657 +#include "mconsole_kern.h"
26658 +#include "2_5compat.h"
26660 +unsigned long handle_page_fault(unsigned long address, unsigned long ip,
26661 + int is_write, int is_user, int *code_out)
26663 + struct mm_struct *mm = current->mm;
26664 + struct vm_area_struct *vma;
26668 + unsigned long page;
26671 + *code_out = SEGV_MAPERR;
26672 + down_read(&mm->mmap_sem);
26673 + vma = find_vma(mm, address);
26676 + else if(vma->vm_start <= address)
26678 + else if(!(vma->vm_flags & VM_GROWSDOWN))
26680 + else if(expand_stack(vma, address))
26684 + *code_out = SEGV_ACCERR;
26685 + if(is_write && !(vma->vm_flags & VM_WRITE))
26687 + page = address & PAGE_MASK;
26688 + if(page == (unsigned long) current + PAGE_SIZE)
26689 + panic("Kernel stack overflow");
26690 + pgd = pgd_offset(mm, page);
26691 + pmd = pmd_offset(pgd, page);
26694 + switch (handle_mm_fault(mm, vma, address, is_write)) {
26696 + current->min_flt++;
26699 + current->maj_flt++;
26702 + if (current->pid == 1) {
26703 + up_read(&mm->mmap_sem);
26705 + down_read(&mm->mmap_sem);
26708 + /* Fall through to bad area case */
26712 + pte = pte_offset(pmd, page);
26713 + } while(!pte_present(*pte));
26715 + *pte = pte_mkyoung(*pte);
26716 + if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
26717 + flush_tlb_page(vma, page);
26719 + up_read(&mm->mmap_sem);
26723 +unsigned long segv(unsigned long address, unsigned long ip, int is_write,
26724 + int is_user, void *sc)
26726 + struct siginfo si;
26730 + if(!is_user && (address >= start_vm) && (address < end_vm)){
26731 + flush_tlb_kernel_vm();
26734 + if(current->mm == NULL)
26735 + panic("Segfault with no mm");
26737 + handled = handle_page_fault(address, ip, is_write, is_user,
26740 + catcher = current->thread.fault_catcher;
26743 + else if(catcher != NULL){
26744 + current->thread.fault_addr = (void *) address;
26745 + do_longjmp(catcher, 1);
26747 + else if(current->thread.fault_addr != NULL){
26748 + panic("fault_addr set but no fault catcher");
26750 + else if(arch_fixup(ip, sc))
26754 + panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
26756 + si.si_signo = SIGSEGV;
26757 + si.si_addr = (void *) address;
26758 + current->thread.cr2 = address;
26759 + current->thread.err = is_write;
26760 + force_sig_info(SIGSEGV, &si, current);
26764 +void bad_segv(unsigned long address, unsigned long ip, int is_write)
26766 + struct siginfo si;
26768 + printk(KERN_ERR "Unfixable SEGV in '%s' (pid %d) at 0x%lx "
26769 + "(ip 0x%lx)\n", current->comm, current->pid, address, ip);
26770 + si.si_signo = SIGSEGV;
26771 + si.si_code = SEGV_ACCERR;
26772 + si.si_addr = (void *) address;
26773 + current->thread.cr2 = address;
26774 + current->thread.err = is_write;
26775 + force_sig_info(SIGSEGV, &si, current);
26778 +void relay_signal(int sig, union uml_pt_regs *regs)
26780 + if(arch_handle_signal(sig, regs)) return;
26781 + if(!UPT_IS_USER(regs))
26782 + panic("Kernel mode signal %d", sig);
26783 + force_sig(sig, current);
26786 +void bus_handler(int sig, union uml_pt_regs *regs)
26788 + if(current->thread.fault_catcher != NULL)
26789 + do_longjmp(current->thread.fault_catcher, 1);
26790 + else relay_signal(sig, regs);
26793 +void winch(int sig, union uml_pt_regs *regs)
26795 + do_IRQ(WINCH_IRQ, regs);
26798 +void trap_init(void)
26802 +spinlock_t trap_lock = SPIN_LOCK_UNLOCKED;
26804 +static int trap_index = 0;
26806 +int next_trap_index(int limit)
26810 + spin_lock(&trap_lock);
26811 + ret = trap_index;
26812 + if(++trap_index == limit)
26814 + spin_unlock(&trap_lock);
26819 + * Overrides for Emacs so that we follow Linus's tabbing style.
26820 + * Emacs will notice this stuff at the end of the file and automatically
26821 + * adjust the settings for this buffer only. This must remain at the end
26823 + * ---------------------------------------------------------------------------
26824 + * Local variables:
26825 + * c-file-style: "linux"
26828 diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_user.c um/arch/um/kernel/trap_user.c
26829 --- orig/arch/um/kernel/trap_user.c Wed Dec 31 19:00:00 1969
26830 +++ um/arch/um/kernel/trap_user.c Wed Mar 26 13:25:50 2003
26833 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
26834 + * Licensed under the GPL
26837 +#include <stdlib.h>
26838 +#include <errno.h>
26839 +#include <fcntl.h>
26840 +#include <setjmp.h>
26841 +#include <signal.h>
26842 +#include <sys/time.h>
26843 +#include <sys/ioctl.h>
26844 +#include <sys/ptrace.h>
26845 +#include <sys/wait.h>
26846 +#include <asm/page.h>
26847 +#include <asm/unistd.h>
26848 +#include <asm/ptrace.h>
26850 +#include "sysdep/ptrace.h"
26851 +#include "sigcontext.h"
26852 +#include "sysdep/sigcontext.h"
26853 +#include "irq_user.h"
26854 +#include "frame_user.h"
26855 +#include "signal_user.h"
26856 +#include "time_user.h"
26859 +#include "choose-mode.h"
26860 +#include "kern_util.h"
26861 +#include "user_util.h"
26864 +void kill_child_dead(int pid)
26866 + kill(pid, SIGKILL);
26867 + kill(pid, SIGCONT);
26868 + while(waitpid(pid, NULL, 0) > 0) kill(pid, SIGCONT);
26871 +/* Unlocked - don't care if this is a bit off */
26872 +int nsegfaults = 0;
26875 + unsigned long address;
26878 + unsigned long sp;
26880 +} segfault_record[1024];
26882 +void segv_handler(int sig, union uml_pt_regs *regs)
26886 + if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){
26887 + bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs),
26888 + UPT_FAULT_WRITE(regs));
26891 + max = sizeof(segfault_record)/sizeof(segfault_record[0]);
26892 + index = next_trap_index(max);
26895 + segfault_record[index].address = UPT_FAULT_ADDR(regs);
26896 + segfault_record[index].pid = os_getpid();
26897 + segfault_record[index].is_write = UPT_FAULT_WRITE(regs);
26898 + segfault_record[index].sp = UPT_SP(regs);
26899 + segfault_record[index].is_user = UPT_IS_USER(regs);
26900 + segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs),
26901 + UPT_IS_USER(regs), regs);
26904 +void usr2_handler(int sig, union uml_pt_regs *regs)
26906 + CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
26909 +struct signal_info sig_info[] = {
26910 + [ SIGTRAP ] { .handler = relay_signal,
26912 + [ SIGFPE ] { .handler = relay_signal,
26914 + [ SIGILL ] { .handler = relay_signal,
26916 + [ SIGWINCH ] { .handler = winch,
26918 + [ SIGBUS ] { .handler = bus_handler,
26920 + [ SIGSEGV] { .handler = segv_handler,
26922 + [ SIGIO ] { .handler = sigio_handler,
26924 + [ SIGVTALRM ] { .handler = timer_handler,
26926 + [ SIGALRM ] { .handler = timer_handler,
26928 + [ SIGUSR2 ] { .handler = usr2_handler,
26932 +void sig_handler(int sig, struct sigcontext sc)
26934 + CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
26938 +extern int timer_irq_inited, missed_ticks[];
26940 +void alarm_handler(int sig, struct sigcontext sc)
26942 + if(!timer_irq_inited) return;
26943 + missed_ticks[cpu()]++;
26945 + if(sig == SIGALRM)
26946 + switch_timers(0);
26948 + CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
26951 + if(sig == SIGALRM)
26952 + switch_timers(1);
26955 +void do_longjmp(void *b, int val)
26957 + jmp_buf *buf = b;
26959 + longjmp(*buf, val);
26963 + * Overrides for Emacs so that we follow Linus's tabbing style.
26964 + * Emacs will notice this stuff at the end of the file and automatically
26965 + * adjust the settings for this buffer only. This must remain at the end
26967 + * ---------------------------------------------------------------------------
26968 + * Local variables:
26969 + * c-file-style: "linux"
26972 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/Makefile um/arch/um/kernel/tt/Makefile
26973 --- orig/arch/um/kernel/tt/Makefile Wed Dec 31 19:00:00 1969
26974 +++ um/arch/um/kernel/tt/Makefile Fri Dec 20 23:29:42 2002
26977 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
26978 +# Licensed under the GPL
26983 +obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
26984 + syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
26987 +obj-$(CONFIG_PT_PROXY) += gdb_kern.o
26989 +subdir-y = sys-$(SUBARCH)
26990 +subdir-$(CONFIG_PT_PROXY) += ptproxy
26992 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
26994 +export-objs = ksyms.o
26996 +USER_OBJS = $(filter %_user.o,$(obj-y)) gdb.o time.o tracer.o
26998 +UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS))
26999 +UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS))
27001 +include $(TOPDIR)/Rules.make
27003 +$(USER_OBJS) : %.o: %.c
27004 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
27006 +$(O_TARGET) : unmap_fin.o
27009 + $(CC) $(UNMAP_CFLAGS) -c -o $@ $<
27011 +unmap_fin.o : unmap.o
27012 + ld -r -o $@ $< -lc -L/usr/lib
27015 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_kern.c um/arch/um/kernel/tt/exec_kern.c
27016 --- orig/arch/um/kernel/tt/exec_kern.c Wed Dec 31 19:00:00 1969
27017 +++ um/arch/um/kernel/tt/exec_kern.c Thu Oct 24 19:22:17 2002
27020 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27021 + * Licensed under the GPL
27024 +#include "linux/kernel.h"
27025 +#include "linux/mm.h"
27026 +#include "asm/signal.h"
27027 +#include "asm/ptrace.h"
27028 +#include "asm/uaccess.h"
27029 +#include "asm/pgalloc.h"
27030 +#include "user_util.h"
27031 +#include "kern_util.h"
27032 +#include "irq_user.h"
27033 +#include "time_user.h"
27034 +#include "mem_user.h"
27038 +static int exec_tramp(void *sig_stack)
27040 + init_new_thread_stack(sig_stack, NULL);
27041 + init_new_thread_signals(1);
27042 + os_stop_process(os_getpid());
27046 +void flush_thread_tt(void)
27048 + unsigned long stack;
27051 + stack = alloc_stack(0, 0);
27054 + "flush_thread : failed to allocate temporary stack\n");
27055 + do_exit(SIGKILL);
27058 + new_pid = start_fork_tramp((void *) current->thread.kernel_stack,
27059 + stack, 0, exec_tramp);
27062 + "flush_thread : new thread failed, errno = %d\n",
27064 + do_exit(SIGKILL);
27067 + if(current->processor == 0)
27068 + forward_interrupts(new_pid);
27069 + current->thread.request.op = OP_EXEC;
27070 + current->thread.request.u.exec.pid = new_pid;
27071 + unprotect_stack((unsigned long) current);
27072 + os_usr1_process(os_getpid());
27075 + free_page(stack);
27076 + protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
27077 + task_protections((unsigned long) current);
27078 + force_flush_all();
27079 + unblock_signals();
27082 +void start_thread_tt(struct pt_regs *regs, unsigned long eip,
27083 + unsigned long esp)
27086 + flush_tlb_mm(current->mm);
27087 + PT_REGS_IP(regs) = eip;
27088 + PT_REGS_SP(regs) = esp;
27089 + PT_FIX_EXEC_STACK(esp);
27093 + * Overrides for Emacs so that we follow Linus's tabbing style.
27094 + * Emacs will notice this stuff at the end of the file and automatically
27095 + * adjust the settings for this buffer only. This must remain at the end
27097 + * ---------------------------------------------------------------------------
27098 + * Local variables:
27099 + * c-file-style: "linux"
27102 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_user.c um/arch/um/kernel/tt/exec_user.c
27103 --- orig/arch/um/kernel/tt/exec_user.c Wed Dec 31 19:00:00 1969
27104 +++ um/arch/um/kernel/tt/exec_user.c Thu Dec 5 19:36:57 2002
27107 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
27108 + * Licensed under the GPL
27111 +#include <stdio.h>
27112 +#include <unistd.h>
27113 +#include <stdlib.h>
27114 +#include <sched.h>
27115 +#include <errno.h>
27116 +#include <sys/wait.h>
27117 +#include <sys/ptrace.h>
27118 +#include <signal.h>
27119 +#include "user_util.h"
27120 +#include "kern_util.h"
27122 +#include "ptrace_user.h"
27124 +void do_exec(int old_pid, int new_pid)
27126 + unsigned long regs[FRAME_SIZE];
27128 + if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) ||
27129 + (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0) ||
27130 + (waitpid(new_pid, 0, WUNTRACED) < 0))
27131 + tracer_panic("do_exec failed to attach proc - errno = %d",
27134 + if(ptrace_getregs(old_pid, regs) < 0)
27135 + tracer_panic("do_exec failed to get registers - errno = %d",
27138 + kill(old_pid, SIGKILL);
27140 + if(ptrace_setregs(new_pid, regs) < 0)
27141 + tracer_panic("do_exec failed to start new proc - errno = %d",
27146 + * Overrides for Emacs so that we follow Linus's tabbing style.
27147 + * Emacs will notice this stuff at the end of the file and automatically
27148 + * adjust the settings for this buffer only. This must remain at the end
27150 + * ---------------------------------------------------------------------------
27151 + * Local variables:
27152 + * c-file-style: "linux"
27155 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb.c um/arch/um/kernel/tt/gdb.c
27156 --- orig/arch/um/kernel/tt/gdb.c Wed Dec 31 19:00:00 1969
27157 +++ um/arch/um/kernel/tt/gdb.c Fri Jan 17 13:23:31 2003
27160 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27161 + * Licensed under the GPL
27164 +#include <stdio.h>
27165 +#include <stdlib.h>
27166 +#include <errno.h>
27167 +#include <string.h>
27168 +#include <signal.h>
27169 +#include <sys/ptrace.h>
27170 +#include <sys/types.h>
27171 +#include "uml-config.h"
27172 +#include "kern_constants.h"
27173 +#include "chan_user.h"
27176 +#include "debug.h"
27177 +#include "kern_util.h"
27178 +#include "user_util.h"
27180 +#include "sysdep/thread.h"
27182 +extern int debugger_pid;
27183 +extern int debugger_fd;
27184 +extern int debugger_parent;
27186 +int detach(int pid, int sig)
27188 + return(ptrace(PTRACE_DETACH, pid, 0, sig));
27191 +int attach(int pid)
27195 + err = ptrace(PTRACE_ATTACH, pid, 0, 0);
27196 + if(err < 0) return(-errno);
27197 + else return(err);
27202 + return(ptrace(PTRACE_CONT, pid, 0, 0));
27205 +#ifdef UML_CONFIG_PT_PROXY
27207 +int debugger_signal(int status, pid_t pid)
27209 + return(debugger_proxy(status, pid));
27212 +void child_signal(pid_t pid, int status)
27214 + child_proxy(pid, status);
27217 +static void gdb_announce(char *dev_name, int dev)
27219 + printf("gdb assigned device '%s'\n", dev_name);
27222 +static struct chan_opts opts = {
27223 + .announce = gdb_announce,
27224 + .xterm_title = "UML kernel debugger",
27226 + .tramp_stack = 0,
27230 +/* Accessed by the tracing thread, which automatically serializes access */
27231 +static void *xterm_data;
27232 +static int xterm_fd;
27234 +extern void *xterm_init(char *, int, struct chan_opts *);
27235 +extern int xterm_open(int, int, int, void *, char **);
27236 +extern void xterm_close(int, void *);
27238 +int open_gdb_chan(void)
27240 + char stack[UM_KERN_PAGE_SIZE], *dummy;
27242 + opts.tramp_stack = (unsigned long) stack;
27243 + xterm_data = xterm_init("", 0, &opts);
27244 + xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy);
27245 + return(xterm_fd);
27248 +static void exit_debugger_cb(void *unused)
27250 + if(debugger_pid != -1){
27251 + if(gdb_pid != -1){
27252 + fake_child_exit();
27255 + else kill_child_dead(debugger_pid);
27256 + debugger_pid = -1;
27257 + if(debugger_parent != -1)
27258 + detach(debugger_parent, SIGINT);
27260 + if(xterm_data != NULL) xterm_close(xterm_fd, xterm_data);
27263 +static void exit_debugger(void)
27265 + initial_thread_cb(exit_debugger_cb, NULL);
27268 +__uml_exitcall(exit_debugger);
27275 +static void config_gdb_cb(void *arg)
27277 + struct gdb_data *data = arg;
27282 + if(debugger_pid != -1) exit_debugger_cb(NULL);
27283 + if(!strncmp(data->str, "pid,", strlen("pid,"))){
27284 + data->str += strlen("pid,");
27285 + pid = strtoul(data->str, NULL, 0);
27286 + task = cpu_tasks[0].task;
27287 + debugger_pid = attach_debugger(TASK_EXTERN_PID(task), pid, 0);
27288 + if(debugger_pid != -1){
27295 + debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
27296 + init_proxy(debugger_pid, 0, 0);
27299 +int gdb_config(char *str)
27301 + struct gdb_data data;
27303 + if(*str++ != '=') return(-1);
27305 + initial_thread_cb(config_gdb_cb, &data);
27306 + return(data.err);
27309 +void remove_gdb_cb(void *unused)
27311 + exit_debugger_cb(NULL);
27314 +int gdb_remove(char *unused)
27316 + initial_thread_cb(remove_gdb_cb, NULL);
27320 +void signal_usr1(int sig)
27322 + if(debugger_pid != -1){
27323 + printk(UM_KERN_ERR "The debugger is already running\n");
27326 + debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
27327 + init_proxy(debugger_pid, 0, 0);
27330 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
27334 + pid = start_debugger(linux_prog, startup, stop, &debugger_fd);
27335 + status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
27340 + init_proxy(pid, 1, status);
27344 +int attach_debugger(int idle_pid, int pid, int stop)
27346 + int status = 0, err;
27348 + err = attach(pid);
27350 + printf("Failed to attach pid %d, errno = %d\n", pid, -err);
27353 + if(stop) status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
27354 + init_proxy(pid, 1, status);
27358 +#ifdef notdef /* Put this back in when it does something useful */
27359 +static int __init uml_gdb_init_setup(char *line, int *add)
27361 + gdb_init = uml_strdup(line);
27365 +__uml_setup("gdb=", uml_gdb_init_setup,
27366 +"gdb=<channel description>\n\n"
27370 +static int __init uml_gdb_pid_setup(char *line, int *add)
27372 + gdb_pid = strtoul(line, NULL, 0);
27377 +__uml_setup("gdb-pid=", uml_gdb_pid_setup,
27379 +" gdb-pid is used to attach an external debugger to UML. This may be\n"
27380 +" an already-running gdb or a debugger-like process like strace.\n\n"
27385 +int debugger_signal(int status, pid_t pid){ return(0); }
27386 +void child_signal(pid_t pid, int status){ }
27387 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
27389 + printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
27390 + kill_child_dead(idle_pid);
27394 +void signal_usr1(int sig)
27396 + printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
27399 +int attach_debugger(int idle_pid, int pid, int stop)
27401 + printk(UM_KERN_ERR "attach_debugger called when CONFIG_PT_PROXY "
27406 +int config_gdb(char *str)
27411 +int remove_gdb(void)
27416 +int init_parent_proxy(int pid)
27421 +void debugger_parent_signal(int status, int pid)
27428 + * Overrides for Emacs so that we follow Linus's tabbing style.
27429 + * Emacs will notice this stuff at the end of the file and automatically
27430 + * adjust the settings for this buffer only. This must remain at the end
27432 + * ---------------------------------------------------------------------------
27433 + * Local variables:
27434 + * c-file-style: "linux"
27437 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb_kern.c um/arch/um/kernel/tt/gdb_kern.c
27438 --- orig/arch/um/kernel/tt/gdb_kern.c Wed Dec 31 19:00:00 1969
27439 +++ um/arch/um/kernel/tt/gdb_kern.c Sun Dec 15 21:16:17 2002
27442 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27443 + * Licensed under the GPL
27446 +#include "linux/init.h"
27447 +#include "linux/config.h"
27448 +#include "mconsole_kern.h"
27450 +#ifdef CONFIG_MCONSOLE
27452 +extern int gdb_config(char *str);
27453 +extern int gdb_remove(char *unused);
27455 +static struct mc_device gdb_mc = {
27457 + .config = gdb_config,
27458 + .remove = gdb_remove,
27461 +int gdb_mc_init(void)
27463 + mconsole_register_dev(&gdb_mc);
27467 +__initcall(gdb_mc_init);
27472 + * Overrides for Emacs so that we follow Linus's tabbing style.
27473 + * Emacs will notice this stuff at the end of the file and automatically
27474 + * adjust the settings for this buffer only. This must remain at the end
27476 + * ---------------------------------------------------------------------------
27477 + * Local variables:
27478 + * c-file-style: "linux"
27481 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/debug.h um/arch/um/kernel/tt/include/debug.h
27482 --- orig/arch/um/kernel/tt/include/debug.h Wed Dec 31 19:00:00 1969
27483 +++ um/arch/um/kernel/tt/include/debug.h Wed Oct 23 21:08:04 2002
27486 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) and
27487 + * Lars Brinkhoff.
27488 + * Licensed under the GPL
27494 +extern int debugger_proxy(int status, pid_t pid);
27495 +extern void child_proxy(pid_t pid, int status);
27496 +extern void init_proxy (pid_t pid, int waiting, int status);
27497 +extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
27498 +extern void fake_child_exit(void);
27499 +extern int gdb_config(char *str);
27500 +extern int gdb_remove(char *unused);
27505 + * Overrides for Emacs so that we follow Linus's tabbing style.
27506 + * Emacs will notice this stuff at the end of the file and automatically
27507 + * adjust the settings for this buffer only. This must remain at the end
27509 + * ---------------------------------------------------------------------------
27510 + * Local variables:
27511 + * c-file-style: "linux"
27514 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mmu.h um/arch/um/kernel/tt/include/mmu.h
27515 --- orig/arch/um/kernel/tt/include/mmu.h Wed Dec 31 19:00:00 1969
27516 +++ um/arch/um/kernel/tt/include/mmu.h Sat Nov 9 12:51:32 2002
27519 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27520 + * Licensed under the GPL
27523 +#ifndef __TT_MMU_H
27524 +#define __TT_MMU_H
27526 +struct mmu_context_tt {
27532 + * Overrides for Emacs so that we follow Linus's tabbing style.
27533 + * Emacs will notice this stuff at the end of the file and automatically
27534 + * adjust the settings for this buffer only. This must remain at the end
27536 + * ---------------------------------------------------------------------------
27537 + * Local variables:
27538 + * c-file-style: "linux"
27541 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode.h um/arch/um/kernel/tt/include/mode.h
27542 --- orig/arch/um/kernel/tt/include/mode.h Wed Dec 31 19:00:00 1969
27543 +++ um/arch/um/kernel/tt/include/mode.h Mon Dec 9 00:34:40 2002
27546 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27547 + * Licensed under the GPL
27550 +#ifndef __MODE_TT_H__
27551 +#define __MODE_TT_H__
27553 +#include "sysdep/ptrace.h"
27555 +extern int tracing_pid;
27557 +extern int tracer(int (*init_proc)(void *), void *sp);
27558 +extern void user_time_init_tt(void);
27559 +extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data);
27560 +extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr,
27562 +extern void sig_handler_common_tt(int sig, void *sc);
27563 +extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
27564 +extern void reboot_tt(void);
27565 +extern void halt_tt(void);
27566 +extern int is_tracer_winch(int pid, int fd, void *data);
27567 +extern void kill_off_processes_tt(void);
27572 + * Overrides for Emacs so that we follow Linus's tabbing style.
27573 + * Emacs will notice this stuff at the end of the file and automatically
27574 + * adjust the settings for this buffer only. This must remain at the end
27576 + * ---------------------------------------------------------------------------
27577 + * Local variables:
27578 + * c-file-style: "linux"
27581 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode_kern.h um/arch/um/kernel/tt/include/mode_kern.h
27582 --- orig/arch/um/kernel/tt/include/mode_kern.h Wed Dec 31 19:00:00 1969
27583 +++ um/arch/um/kernel/tt/include/mode_kern.h Mon Dec 16 21:49:18 2002
27586 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27587 + * Licensed under the GPL
27590 +#ifndef __TT_MODE_KERN_H__
27591 +#define __TT_MODE_KERN_H__
27593 +#include "linux/sched.h"
27594 +#include "asm/page.h"
27595 +#include "asm/ptrace.h"
27596 +#include "asm/uaccess.h"
27598 +extern void *_switch_to_tt(void *prev, void *next);
27599 +extern void flush_thread_tt(void);
27600 +extern void start_thread_tt(struct pt_regs *regs, unsigned long eip,
27601 + unsigned long esp);
27602 +extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
27603 + unsigned long stack_top, struct task_struct *p,
27604 + struct pt_regs *regs);
27605 +extern void release_thread_tt(struct task_struct *task);
27606 +extern void exit_thread_tt(void);
27607 +extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
27608 +extern void init_idle_tt(void);
27609 +extern void flush_tlb_kernel_vm_tt(void);
27610 +extern void __flush_tlb_one_tt(unsigned long addr);
27611 +extern void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start,
27612 + unsigned long end);
27613 +extern void flush_tlb_mm_tt(struct mm_struct *mm);
27614 +extern void force_flush_all_tt(void);
27615 +extern long execute_syscall_tt(void *r);
27616 +extern void before_mem_tt(unsigned long brk_start);
27617 +extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
27618 + unsigned long *task_size_out);
27619 +extern int start_uml_tt(void);
27620 +extern int external_pid_tt(struct task_struct *task);
27621 +extern int thread_pid_tt(struct thread_struct *thread);
27623 +#define kmem_end_tt (host_task_size - ABOVE_KMEM)
27628 + * Overrides for Emacs so that we follow Linus's tabbing style.
27629 + * Emacs will notice this stuff at the end of the file and automatically
27630 + * adjust the settings for this buffer only. This must remain at the end
27632 + * ---------------------------------------------------------------------------
27633 + * Local variables:
27634 + * c-file-style: "linux"
27637 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/ptrace-tt.h um/arch/um/kernel/tt/include/ptrace-tt.h
27638 --- orig/arch/um/kernel/tt/include/ptrace-tt.h Wed Dec 31 19:00:00 1969
27639 +++ um/arch/um/kernel/tt/include/ptrace-tt.h Fri Jan 17 13:23:30 2003
27642 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
27643 + * Licensed under the GPL
27646 +#ifndef __PTRACE_TT_H
27647 +#define __PTRACE_TT_H
27649 +#include "uml-config.h"
27651 +#ifdef UML_CONFIG_MODE_TT
27652 +#include "sysdep/sc.h"
27658 + * Overrides for Emacs so that we follow Linus's tabbing style.
27659 + * Emacs will notice this stuff at the end of the file and automatically
27660 + * adjust the settings for this buffer only. This must remain at the end
27662 + * ---------------------------------------------------------------------------
27663 + * Local variables:
27664 + * c-file-style: "linux"
27667 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/tt.h um/arch/um/kernel/tt/include/tt.h
27668 --- orig/arch/um/kernel/tt/include/tt.h Wed Dec 31 19:00:00 1969
27669 +++ um/arch/um/kernel/tt/include/tt.h Fri Dec 20 23:29:11 2002
27672 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27673 + * Licensed under the GPL
27679 +#include "sysdep/ptrace.h"
27681 +extern int gdb_pid;
27683 +extern int debug_stop;
27684 +extern int debug_trace;
27686 +extern int honeypot;
27688 +extern int fork_tramp(void *sig_stack);
27689 +extern int do_proc_op(void *t, int proc_id);
27690 +extern int tracer(int (*init_proc)(void *), void *sp);
27691 +extern void attach_process(int pid);
27692 +extern void tracer_panic(char *format, ...);
27693 +extern void set_init_pid(int pid);
27694 +extern int set_user_mode(void *task);
27695 +extern void set_tracing(void *t, int tracing);
27696 +extern int is_tracing(void *task);
27697 +extern int singlestepping_tt(void *t);
27698 +extern void clear_singlestep(void *t);
27699 +extern void syscall_handler(int sig, union uml_pt_regs *regs);
27700 +extern void exit_kernel(int pid, void *task);
27701 +extern int do_syscall(void *task, int pid);
27702 +extern int is_valid_pid(int pid);
27703 +extern void remap_data(void *segment_start, void *segment_end, int w);
27708 + * Overrides for Emacs so that we follow Linus's tabbing style.
27709 + * Emacs will notice this stuff at the end of the file and automatically
27710 + * adjust the settings for this buffer only. This must remain at the end
27712 + * ---------------------------------------------------------------------------
27713 + * Local variables:
27714 + * c-file-style: "linux"
27717 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/uaccess.h um/arch/um/kernel/tt/include/uaccess.h
27718 --- orig/arch/um/kernel/tt/include/uaccess.h Wed Dec 31 19:00:00 1969
27719 +++ um/arch/um/kernel/tt/include/uaccess.h Tue Mar 25 16:58:42 2003
27722 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
27723 + * Licensed under the GPL
27726 +#ifndef __TT_UACCESS_H
27727 +#define __TT_UACCESS_H
27729 +#include "linux/string.h"
27730 +#include "linux/sched.h"
27731 +#include "asm/processor.h"
27732 +#include "asm/errno.h"
27733 +#include "asm/current.h"
27734 +#include "asm/a.out.h"
27735 +#include "uml_uaccess.h"
27737 +#define ABOVE_KMEM (16 * 1024 * 1024)
27739 +extern unsigned long end_vm;
27740 +extern unsigned long uml_physmem;
27742 +#define under_task_size(addr, size) \
27743 + (((unsigned long) (addr) < TASK_SIZE) && \
27744 + (((unsigned long) (addr) + (size)) < TASK_SIZE))
27746 +#define is_stack(addr, size) \
27747 + (((unsigned long) (addr) < STACK_TOP) && \
27748 + ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
27749 + (((unsigned long) (addr) + (size)) <= STACK_TOP))
27751 +#define access_ok_tt(type, addr, size) \
27752 + ((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \
27753 + (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
27754 + (under_task_size(addr, size) || is_stack(addr, size))))
27756 +static inline int verify_area_tt(int type, const void * addr,
27757 + unsigned long size)
27759 + return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
27762 +extern unsigned long get_fault_addr(void);
27764 +extern int __do_copy_from_user(void *to, const void *from, int n,
27765 + void **fault_addr, void **fault_catcher);
27767 +static inline int copy_from_user_tt(void *to, const void *from, int n)
27769 + if(!access_ok_tt(VERIFY_READ, from, n))
27772 + return(__do_copy_from_user(to, from, n, ¤t->thread.fault_addr,
27773 + ¤t->thread.fault_catcher));
27776 +static inline int copy_to_user_tt(void *to, const void *from, int n)
27778 + if(!access_ok_tt(VERIFY_WRITE, to, n))
27781 + return(__do_copy_to_user(to, from, n, ¤t->thread.fault_addr,
27782 + ¤t->thread.fault_catcher));
27785 +extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
27786 + void **fault_addr, void **fault_catcher);
27788 +static inline int strncpy_from_user_tt(char *dst, const char *src, int count)
27792 + if(!access_ok_tt(VERIFY_READ, src, 1))
27795 + n = __do_strncpy_from_user(dst, src, count,
27796 + ¤t->thread.fault_addr,
27797 + ¤t->thread.fault_catcher);
27798 + if(n < 0) return(-EFAULT);
27802 +extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
27803 + void **fault_catcher);
27805 +static inline int __clear_user_tt(void *mem, int len)
27807 + return(__do_clear_user(mem, len,
27808 + ¤t->thread.fault_addr,
27809 + ¤t->thread.fault_catcher));
27812 +static inline int clear_user_tt(void *mem, int len)
27814 + if(!access_ok_tt(VERIFY_WRITE, mem, len))
27817 + return(__do_clear_user(mem, len, ¤t->thread.fault_addr,
27818 + ¤t->thread.fault_catcher));
27821 +extern int __do_strnlen_user(const char *str, unsigned long n,
27822 + void **fault_addr, void **fault_catcher);
27824 +static inline int strnlen_user_tt(const void *str, int len)
27826 + return(__do_strnlen_user(str, len,
27827 + ¤t->thread.fault_addr,
27828 + ¤t->thread.fault_catcher));
27834 + * Overrides for Emacs so that we follow Linus's tabbing style.
27835 + * Emacs will notice this stuff at the end of the file and automatically
27836 + * adjust the settings for this buffer only. This must remain at the end
27838 + * ---------------------------------------------------------------------------
27839 + * Local variables:
27840 + * c-file-style: "linux"
27843 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ksyms.c um/arch/um/kernel/tt/ksyms.c
27844 --- orig/arch/um/kernel/tt/ksyms.c Wed Dec 31 19:00:00 1969
27845 +++ um/arch/um/kernel/tt/ksyms.c Sun Oct 27 17:01:56 2002
27848 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
27849 + * Licensed under the GPL
27852 +#include "linux/module.h"
27853 +#include "asm/uaccess.h"
27856 +EXPORT_SYMBOL(__do_copy_from_user);
27857 +EXPORT_SYMBOL(__do_copy_to_user);
27858 +EXPORT_SYMBOL(__do_strncpy_from_user);
27859 +EXPORT_SYMBOL(__do_strnlen_user);
27860 +EXPORT_SYMBOL(__do_clear_user);
27862 +EXPORT_SYMBOL(tracing_pid);
27863 +EXPORT_SYMBOL(honeypot);
27866 + * Overrides for Emacs so that we follow Linus's tabbing style.
27867 + * Emacs will notice this stuff at the end of the file and automatically
27868 + * adjust the settings for this buffer only. This must remain at the end
27870 + * ---------------------------------------------------------------------------
27871 + * Local variables:
27872 + * c-file-style: "linux"
27875 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem.c um/arch/um/kernel/tt/mem.c
27876 --- orig/arch/um/kernel/tt/mem.c Wed Dec 31 19:00:00 1969
27877 +++ um/arch/um/kernel/tt/mem.c Mon Dec 16 21:49:51 2002
27880 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27881 + * Licensed under the GPL
27884 +#include "linux/stddef.h"
27885 +#include "linux/config.h"
27886 +#include "linux/mm.h"
27887 +#include "asm/uaccess.h"
27888 +#include "mem_user.h"
27889 +#include "kern_util.h"
27890 +#include "user_util.h"
27894 +void before_mem_tt(unsigned long brk_start)
27896 + if(!jail || debug)
27897 + remap_data(UML_ROUND_DOWN(&_stext), UML_ROUND_UP(&_etext), 1);
27898 + remap_data(UML_ROUND_DOWN(&_sdata), UML_ROUND_UP(&_edata), 1);
27899 + remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(brk_start), 1);
27902 +#ifdef CONFIG_HOST_2G_2G
27903 +#define TOP 0x80000000
27905 +#define TOP 0xc0000000
27908 +#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
27909 +#define START (TOP - SIZE)
27911 +unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
27912 + unsigned long *task_size_out)
27914 + /* Round up to the nearest 4M */
27915 + *host_size_out = ROUND_4M((unsigned long) &arg);
27916 + *task_size_out = START;
27921 + * Overrides for Emacs so that we follow Linus's tabbing style.
27922 + * Emacs will notice this stuff at the end of the file and automatically
27923 + * adjust the settings for this buffer only. This must remain at the end
27925 + * ---------------------------------------------------------------------------
27926 + * Local variables:
27927 + * c-file-style: "linux"
27930 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem_user.c um/arch/um/kernel/tt/mem_user.c
27931 --- orig/arch/um/kernel/tt/mem_user.c Wed Dec 31 19:00:00 1969
27932 +++ um/arch/um/kernel/tt/mem_user.c Fri Jan 17 22:07:31 2003
27935 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27936 + * Licensed under the GPL
27939 +#include <stdlib.h>
27940 +#include <stdio.h>
27941 +#include <unistd.h>
27942 +#include <string.h>
27943 +#include <errno.h>
27944 +#include <sys/mman.h>
27946 +#include "mem_user.h"
27947 +#include "user_util.h"
27949 +void remap_data(void *segment_start, void *segment_end, int w)
27952 + unsigned long size;
27955 + if(w) prot = PROT_WRITE;
27957 + prot |= PROT_READ | PROT_EXEC;
27958 + size = (unsigned long) segment_end -
27959 + (unsigned long) segment_start;
27960 + data = create_mem_file(size);
27961 + if((addr = mmap(NULL, size, PROT_WRITE | PROT_READ,
27962 + MAP_SHARED, data, 0)) == MAP_FAILED){
27963 + perror("mapping new data segment");
27966 + memcpy(addr, segment_start, size);
27967 + if(switcheroo(data, prot, addr, segment_start,
27969 + printf("switcheroo failed\n");
27975 + * Overrides for Emacs so that we follow Linus's tabbing style.
27976 + * Emacs will notice this stuff at the end of the file and automatically
27977 + * adjust the settings for this buffer only. This must remain at the end
27979 + * ---------------------------------------------------------------------------
27980 + * Local variables:
27981 + * c-file-style: "linux"
27984 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/process_kern.c um/arch/um/kernel/tt/process_kern.c
27985 --- orig/arch/um/kernel/tt/process_kern.c Wed Dec 31 19:00:00 1969
27986 +++ um/arch/um/kernel/tt/process_kern.c Sun Feb 16 21:34:23 2003
27989 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27990 + * Licensed under the GPL
27993 +#include "linux/sched.h"
27994 +#include "linux/signal.h"
27995 +#include "linux/kernel.h"
27996 +#include "asm/system.h"
27997 +#include "asm/pgalloc.h"
27998 +#include "asm/ptrace.h"
27999 +#include "irq_user.h"
28000 +#include "signal_user.h"
28001 +#include "kern_util.h"
28002 +#include "user_util.h"
28005 +#include "sigcontext.h"
28006 +#include "time_user.h"
28007 +#include "mem_user.h"
28013 +void *_switch_to_tt(void *prev, void *next)
28015 + struct task_struct *from, *to;
28016 + unsigned long flags;
28017 + int err, vtalrm, alrm, prof, cpu;
28019 + /* jailing and SMP are incompatible, so this doesn't need to be
28022 + static int reading;
28027 + to->thread.prev_sched = from;
28029 + cpu = from->processor;
28031 + forward_interrupts(to->thread.mode.tt.extern_pid);
28033 + forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid);
28035 + local_irq_save(flags);
28037 + vtalrm = change_sig(SIGVTALRM, 0);
28038 + alrm = change_sig(SIGALRM, 0);
28039 + prof = change_sig(SIGPROF, 0);
28045 + err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
28046 + if(err != sizeof(c))
28047 + panic("write of switch_pipe failed, errno = %d", -err);
28050 + if(from->state == TASK_ZOMBIE)
28051 + os_kill_process(os_getpid(), 0);
28053 + err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
28054 + if(err != sizeof(c))
28055 + panic("read of switch_pipe failed, errno = %d", -err);
28057 + /* This works around a nasty race with 'jail'. If we are switching
28058 + * between two threads of a threaded app and the incoming process
28059 + * runs before the outgoing process reaches the read, and it makes
28060 + * it all the way out to userspace, then it will have write-protected
28061 + * the outgoing process stack. Then, when the outgoing process
28062 + * returns from the write, it will segfault because it can no longer
28063 + * write its own stack. So, in order to avoid that, the incoming
28064 + * thread sits in a loop yielding until 'reading' is set. This
28065 + * isn't entirely safe, since there may be a reschedule from a timer
28066 + * happening between setting 'reading' and sleeping in read. But,
28067 + * it should get a whole quantum in which to reach the read and sleep,
28068 + * which should be enough.
28072 + while(!reading) sched_yield();
28075 + change_sig(SIGVTALRM, vtalrm);
28076 + change_sig(SIGALRM, alrm);
28077 + change_sig(SIGPROF, prof);
28082 + local_irq_restore(flags);
28084 + return(current->thread.prev_sched);
28087 +void release_thread_tt(struct task_struct *task)
28089 + os_kill_process(task->thread.mode.tt.extern_pid, 0);
28092 +void exit_thread_tt(void)
28094 + close(current->thread.mode.tt.switch_pipe[0]);
28095 + close(current->thread.mode.tt.switch_pipe[1]);
28098 +extern void schedule_tail(struct task_struct *prev);
28100 +static void new_thread_handler(int sig)
28102 + int (*fn)(void *);
28105 + fn = current->thread.request.u.thread.proc;
28106 + arg = current->thread.request.u.thread.arg;
28107 + UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
28108 + suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
28110 + init_new_thread_signals(1);
28112 + free_page(current->thread.temp_stack);
28113 + set_cmdline("(kernel thread)");
28114 + force_flush_all();
28116 + if(current->thread.prev_sched != NULL)
28117 + schedule_tail(current->thread.prev_sched);
28118 + current->thread.prev_sched = NULL;
28120 + change_sig(SIGUSR1, 1);
28121 + change_sig(SIGVTALRM, 1);
28122 + change_sig(SIGPROF, 1);
28124 + if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf))
28128 +static int new_thread_proc(void *stack)
28131 + init_new_thread_stack(stack, new_thread_handler);
28132 + os_usr1_process(os_getpid());
28136 +/* Signal masking - signals are blocked at the start of fork_tramp. They
28137 + * are re-enabled when finish_fork_handler is entered by fork_tramp hitting
28138 + * itself with a SIGUSR1. set_user_mode has to be run with SIGUSR1 off,
28139 + * so it is blocked before it's called. They are re-enabled on sigreturn
28140 + * despite the fact that they were blocked when the SIGUSR1 was issued because
28141 + * copy_thread copies the parent's signcontext, including the signal mask
28142 + * onto the signal frame.
28145 +static void finish_fork_handler(int sig)
28147 + UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
28148 + suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
28150 + init_new_thread_signals(1);
28153 + force_flush_all();
28154 + if(current->mm != current->p_pptr->mm)
28155 + protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
28157 + task_protections((unsigned long) current);
28159 + if(current->thread.prev_sched != NULL)
28160 + schedule_tail(current->thread.prev_sched);
28161 + current->thread.prev_sched = NULL;
28163 + free_page(current->thread.temp_stack);
28165 + change_sig(SIGUSR1, 0);
28166 + set_user_mode(current);
28169 +int fork_tramp(void *stack)
28172 + init_new_thread_stack(stack, finish_fork_handler);
28173 + os_usr1_process(os_getpid());
28177 +int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
28178 + unsigned long stack_top, struct task_struct * p,
28179 + struct pt_regs *regs)
28181 + int (*tramp)(void *);
28182 + int new_pid, err;
28183 + unsigned long stack;
28185 + if(current->thread.forking)
28186 + tramp = fork_tramp;
28188 + tramp = new_thread_proc;
28189 + p->thread.request.u.thread = current->thread.request.u.thread;
28192 + err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
28194 + printk("copy_thread : pipe failed, errno = %d\n", -err);
28198 + stack = alloc_stack(0, 0);
28200 + printk(KERN_ERR "copy_thread : failed to allocate "
28201 + "temporary stack\n");
28205 + clone_flags &= CLONE_VM;
28206 + p->thread.temp_stack = stack;
28207 + new_pid = start_fork_tramp((void *) p->thread.kernel_stack, stack,
28208 + clone_flags, tramp);
28210 + printk(KERN_ERR "copy_thread : clone failed - errno = %d\n",
28215 + if(current->thread.forking){
28216 + sc_to_sc(UPT_SC(&p->thread.regs.regs),
28217 + UPT_SC(¤t->thread.regs.regs));
28218 + SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
28219 + if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
28221 + p->thread.mode.tt.extern_pid = new_pid;
28223 + current->thread.request.op = OP_FORK;
28224 + current->thread.request.u.fork.pid = new_pid;
28225 + os_usr1_process(os_getpid());
28229 +void reboot_tt(void)
28231 + current->thread.request.op = OP_REBOOT;
28232 + os_usr1_process(os_getpid());
28233 + os_kill_process(os_getpid(), 0);
28236 +void halt_tt(void)
28238 + current->thread.request.op = OP_HALT;
28239 + os_usr1_process(os_getpid());
28240 + os_kill_process(os_getpid(), 0);
28243 +void kill_off_processes_tt(void)
28245 + struct task_struct *p;
28248 + me = os_getpid();
28249 + for_each_task(p){
28250 + int pid = p->thread.mode.tt.extern_pid;
28251 + if((pid != me) && (pid != -1))
28252 + os_kill_process(p->thread.mode.tt.extern_pid, 0);
28254 + if((init_task.thread.mode.tt.extern_pid != me) &&
28255 + (init_task.thread.mode.tt.extern_pid != -1))
28256 + os_kill_process(init_task.thread.mode.tt.extern_pid, 0);
28259 +void initial_thread_cb_tt(void (*proc)(void *), void *arg)
28261 + if(os_getpid() == tracing_pid){
28265 + current->thread.request.op = OP_CB;
28266 + current->thread.request.u.cb.proc = proc;
28267 + current->thread.request.u.cb.arg = arg;
28268 + os_usr1_process(os_getpid());
28272 +int do_proc_op(void *t, int proc_id)
28274 + struct task_struct *task;
28275 + struct thread_struct *thread;
28279 + thread = &task->thread;
28280 + op = thread->request.op;
28283 + case OP_TRACE_ON:
28286 + pid = thread->request.u.exec.pid;
28287 + do_exec(thread->mode.tt.extern_pid, pid);
28288 + thread->mode.tt.extern_pid = pid;
28289 + cpu_tasks[task->processor].pid = pid;
28292 + attach_process(thread->request.u.fork.pid);
28295 + (*thread->request.u.cb.proc)(thread->request.u.cb.arg);
28301 + tracer_panic("Bad op in do_proc_op");
28304 + thread->request.op = OP_NONE;
28308 +void init_idle_tt(void)
28313 +/* Changed by jail_setup, which is a setup */
28316 +int __init jail_setup(char *line, int *add)
28320 + if(jail) return(0);
28322 + printf("'jail' may not used used in a kernel with CONFIG_SMP "
28326 +#ifdef CONFIG_HOSTFS
28327 + printf("'jail' may not used used in a kernel with CONFIG_HOSTFS "
28331 +#ifdef CONFIG_MODULES
28332 + printf("'jail' may not used used in a kernel with CONFIG_MODULES "
28338 + /* CAP_SYS_RAWIO controls the ability to open /dev/mem and /dev/kmem.
28339 + * Removing it from the bounding set eliminates the ability of anything
28340 + * to acquire it, and thus read or write kernel memory.
28342 + cap_lower(cap_bset, CAP_SYS_RAWIO);
28347 +__uml_setup("jail", jail_setup,
28349 +" Enables the protection of kernel memory from processes.\n\n"
28352 +static void mprotect_kernel_mem(int w)
28354 + unsigned long start, end;
28357 + if(!jail || (current == &init_task)) return;
28359 + pages = (1 << CONFIG_KERNEL_STACK_ORDER);
28361 + start = (unsigned long) current + PAGE_SIZE;
28362 + end = (unsigned long) current + PAGE_SIZE * pages;
28363 + protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
28364 + protect_memory(end, high_physmem - end, 1, w, 1, 1);
28366 + start = (unsigned long) UML_ROUND_DOWN(&_stext);
28367 + end = (unsigned long) UML_ROUND_UP(&_etext);
28368 + protect_memory(start, end - start, 1, w, 1, 1);
28370 + start = (unsigned long) UML_ROUND_DOWN(&_unprotected_end);
28371 + end = (unsigned long) UML_ROUND_UP(&_edata);
28372 + protect_memory(start, end - start, 1, w, 1, 1);
28374 + start = (unsigned long) UML_ROUND_DOWN(&__bss_start);
28375 + end = (unsigned long) UML_ROUND_UP(brk_start);
28376 + protect_memory(start, end - start, 1, w, 1, 1);
28378 + mprotect_kernel_vm(w);
28381 +void unprotect_kernel_mem(void)
28383 + mprotect_kernel_mem(1);
28386 +void protect_kernel_mem(void)
28388 + mprotect_kernel_mem(0);
28391 +extern void start_kernel(void);
28393 +static int start_kernel_proc(void *unused)
28398 + pid = os_getpid();
28400 + cpu_tasks[0].pid = pid;
28401 + cpu_tasks[0].task = current;
28403 + cpu_online_map = 1;
28405 + if(debug) os_stop_process(pid);
28410 +void set_tracing(void *task, int tracing)
28412 + ((struct task_struct *) task)->thread.mode.tt.tracing = tracing;
28415 +int is_tracing(void *t)
28417 + return (((struct task_struct *) t)->thread.mode.tt.tracing);
28420 +int set_user_mode(void *t)
28422 + struct task_struct *task;
28424 + task = t ? t : current;
28425 + if(task->thread.mode.tt.tracing)
28427 + task->thread.request.op = OP_TRACE_ON;
28428 + os_usr1_process(os_getpid());
28432 +void set_init_pid(int pid)
28436 + init_task.thread.mode.tt.extern_pid = pid;
28437 + err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
28438 + if(err) panic("Can't create switch pipe for init_task, errno = %d",
28442 +int singlestepping_tt(void *t)
28444 + struct task_struct *task = t;
28446 + if(task->thread.mode.tt.singlestep_syscall)
28448 + return(task->ptrace & PT_DTRACE);
28451 +void clear_singlestep(void *t)
28453 + struct task_struct *task = t;
28455 + task->ptrace &= ~PT_DTRACE;
28458 +int start_uml_tt(void)
28463 + pages = (1 << CONFIG_KERNEL_STACK_ORDER) - 2;
28464 + sp = (void *) init_task.thread.kernel_stack + pages * PAGE_SIZE -
28465 + sizeof(unsigned long);
28466 + return(tracer(start_kernel_proc, sp));
28469 +int external_pid_tt(struct task_struct *task)
28471 + return(task->thread.mode.tt.extern_pid);
28474 +int thread_pid_tt(struct thread_struct *thread)
28476 + return(thread->mode.tt.extern_pid);
28479 +int is_valid_pid(int pid)
28481 + struct task_struct *task;
28483 + read_lock(&tasklist_lock);
28484 + for_each_task(task){
28485 + if(task->thread.mode.tt.extern_pid == pid){
28486 + read_unlock(&tasklist_lock);
28490 + read_unlock(&tasklist_lock);
28495 + * Overrides for Emacs so that we follow Linus's tabbing style.
28496 + * Emacs will notice this stuff at the end of the file and automatically
28497 + * adjust the settings for this buffer only. This must remain at the end
28499 + * ---------------------------------------------------------------------------
28500 + * Local variables:
28501 + * c-file-style: "linux"
28504 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/Makefile um/arch/um/kernel/tt/ptproxy/Makefile
28505 --- orig/arch/um/kernel/tt/ptproxy/Makefile Wed Dec 31 19:00:00 1969
28506 +++ um/arch/um/kernel/tt/ptproxy/Makefile Wed Oct 23 21:08:04 2002
28508 +O_TARGET = ptproxy.o
28510 +obj-y = proxy.o ptrace.o sysdep.o wait.o
28512 +USER_OBJS = $(obj-y)
28514 +include $(TOPDIR)/Rules.make
28516 +$(USER_OBJS) : %.o: %.c
28517 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
28520 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/proxy.c um/arch/um/kernel/tt/ptproxy/proxy.c
28521 --- orig/arch/um/kernel/tt/ptproxy/proxy.c Wed Dec 31 19:00:00 1969
28522 +++ um/arch/um/kernel/tt/ptproxy/proxy.c Wed Apr 16 14:01:03 2003
28524 +/**********************************************************************
28527 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
28528 +terms and conditions.
28530 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
28531 +**********************************************************************/
28533 +/* XXX This file shouldn't refer to CONFIG_* */
28535 +#include <errno.h>
28536 +#include <stdio.h>
28537 +#include <stdlib.h>
28538 +#include <unistd.h>
28539 +#include <signal.h>
28540 +#include <string.h>
28541 +#include <fcntl.h>
28542 +#include <termios.h>
28543 +#include <sys/wait.h>
28544 +#include <sys/types.h>
28545 +#include <sys/ptrace.h>
28546 +#include <sys/ioctl.h>
28547 +#include <asm/unistd.h>
28549 +#include "ptproxy.h"
28550 +#include "sysdep.h"
28553 +#include "user_util.h"
28556 +#include "tempfile.h"
28558 +static int debugger_wait(debugger_state *debugger, int *status, int options,
28559 + int (*syscall)(debugger_state *debugger, pid_t child),
28560 + int (*normal_return)(debugger_state *debugger,
28562 + int (*wait_return)(debugger_state *debugger,
28565 + if(debugger->real_wait){
28566 + debugger->handle_trace = normal_return;
28567 + syscall_continue(debugger->pid);
28568 + debugger->real_wait = 0;
28571 + debugger->wait_status_ptr = status;
28572 + debugger->wait_options = options;
28573 + if((debugger->debugee != NULL) && debugger->debugee->event){
28574 + syscall_continue(debugger->pid);
28575 + wait_for_stop(debugger->pid, SIGTRAP, PTRACE_SYSCALL,
28577 + (*wait_return)(debugger, -1);
28580 + else if(debugger->wait_options & WNOHANG){
28581 + syscall_cancel(debugger->pid, 0);
28582 + debugger->handle_trace = syscall;
28586 + syscall_pause(debugger->pid);
28587 + debugger->handle_trace = wait_return;
28588 + debugger->waiting = 1;
28594 + * Handle debugger trap, i.e. syscall.
28597 +int debugger_syscall(debugger_state *debugger, pid_t child)
28599 + long arg1, arg2, arg3, arg4, arg5, result;
28600 + int syscall, ret = 0;
28602 + syscall = get_syscall(debugger->pid, &arg1, &arg2, &arg3, &arg4,
28606 + case __NR_execve:
28607 + /* execve never returns */
28608 + debugger->handle_trace = debugger_syscall;
28611 + case __NR_ptrace:
28612 + if(debugger->debugee->pid != 0) arg2 = debugger->debugee->pid;
28613 + if(!debugger->debugee->in_context)
28614 + child = debugger->debugee->pid;
28615 + result = proxy_ptrace(debugger, arg1, arg2, arg3, arg4, child,
28617 + syscall_cancel(debugger->pid, result);
28618 + debugger->handle_trace = debugger_syscall;
28621 + case __NR_waitpid:
28623 + if(!debugger_wait(debugger, (int *) arg2, arg3,
28624 + debugger_syscall, debugger_normal_return,
28625 + proxy_wait_return))
28630 + if(!debugger->debugee->in_context)
28631 + child = debugger->debugee->pid;
28632 + if(arg1 == debugger->debugee->pid){
28633 + result = kill(child, arg2);
28634 + syscall_cancel(debugger->pid, result);
28635 + debugger->handle_trace = debugger_syscall;
28638 + else debugger->handle_trace = debugger_normal_return;
28642 + debugger->handle_trace = debugger_normal_return;
28645 + syscall_continue(debugger->pid);
28649 +/* Used by the tracing thread */
28650 +static debugger_state parent;
28651 +static int parent_syscall(debugger_state *debugger, int pid);
28653 +int init_parent_proxy(int pid)
28655 + parent = ((debugger_state) { .pid = pid,
28656 + .wait_options = 0,
28657 + .wait_status_ptr = NULL,
28660 + .expecting_child = 0,
28661 + .handle_trace = parent_syscall,
28662 + .debugee = NULL } );
28666 +int parent_normal_return(debugger_state *debugger, pid_t unused)
28668 + debugger->handle_trace = parent_syscall;
28669 + syscall_continue(debugger->pid);
28673 +static int parent_syscall(debugger_state *debugger, int pid)
28675 + long arg1, arg2, arg3, arg4, arg5;
28678 + syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5);
28680 + if((syscall == __NR_waitpid) || (syscall == __NR_wait4)){
28681 + debugger_wait(&parent, (int *) arg2, arg3, parent_syscall,
28682 + parent_normal_return, parent_wait_return);
28684 + else ptrace(PTRACE_SYSCALL, pid, 0, 0);
28688 +int debugger_normal_return(debugger_state *debugger, pid_t unused)
28690 + debugger->handle_trace = debugger_syscall;
28691 + syscall_continue(debugger->pid);
28695 +void debugger_cancelled_return(debugger_state *debugger, int result)
28697 + debugger->handle_trace = debugger_syscall;
28698 + syscall_set_result(debugger->pid, result);
28699 + syscall_continue(debugger->pid);
28702 +/* Used by the tracing thread */
28703 +static debugger_state debugger;
28704 +static debugee_state debugee;
28706 +void init_proxy (pid_t debugger_pid, int stopped, int status)
28708 + debugger.pid = debugger_pid;
28709 + debugger.handle_trace = debugger_syscall;
28710 + debugger.debugee = &debugee;
28711 + debugger.waiting = 0;
28712 + debugger.real_wait = 0;
28713 + debugger.expecting_child = 0;
28716 + debugee.traced = 0;
28717 + debugee.stopped = stopped;
28718 + debugee.event = 0;
28719 + debugee.zombie = 0;
28720 + debugee.died = 0;
28721 + debugee.wait_status = status;
28722 + debugee.in_context = 1;
28725 +int debugger_proxy(int status, int pid)
28727 + int ret = 0, sig;
28729 + if(WIFSTOPPED(status)){
28730 + sig = WSTOPSIG(status);
28731 + if (sig == SIGTRAP)
28732 + ret = (*debugger.handle_trace)(&debugger, pid);
28734 + else if(sig == SIGCHLD){
28735 + if(debugger.expecting_child){
28736 + ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
28737 + debugger.expecting_child = 0;
28739 + else if(debugger.waiting)
28740 + real_wait_return(&debugger);
28742 + ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
28743 + debugger.real_wait = 1;
28746 + else ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
28748 + else if(WIFEXITED(status)){
28749 + tracer_panic("debugger (pid %d) exited with status %d",
28750 + debugger.pid, WEXITSTATUS(status));
28752 + else if(WIFSIGNALED(status)){
28753 + tracer_panic("debugger (pid %d) exited with signal %d",
28754 + debugger.pid, WTERMSIG(status));
28757 + tracer_panic("proxy got unknown status (0x%x) on debugger "
28758 + "(pid %d)", status, debugger.pid);
28763 +void child_proxy(pid_t pid, int status)
28765 + debugee.event = 1;
28766 + debugee.wait_status = status;
28768 + if(WIFSTOPPED(status)){
28769 + debugee.stopped = 1;
28770 + debugger.expecting_child = 1;
28771 + kill(debugger.pid, SIGCHLD);
28773 + else if(WIFEXITED(status) || WIFSIGNALED(status)){
28774 + debugee.zombie = 1;
28775 + debugger.expecting_child = 1;
28776 + kill(debugger.pid, SIGCHLD);
28778 + else panic("proxy got unknown status (0x%x) on child (pid %d)",
28782 +void debugger_parent_signal(int status, int pid)
28786 + if(WIFSTOPPED(status)){
28787 + sig = WSTOPSIG(status);
28788 + if(sig == SIGTRAP) (*parent.handle_trace)(&parent, pid);
28789 + else ptrace(PTRACE_SYSCALL, pid, 0, sig);
28793 +void fake_child_exit(void)
28797 + child_proxy(1, W_EXITCODE(0, 0));
28798 + while(debugger.waiting == 1){
28799 + pid = waitpid(debugger.pid, &status, WUNTRACED);
28800 + if(pid != debugger.pid){
28801 + printk("fake_child_exit - waitpid failed, "
28802 + "errno = %d\n", errno);
28805 + debugger_proxy(status, debugger.pid);
28807 + pid = waitpid(debugger.pid, &status, WUNTRACED);
28808 + if(pid != debugger.pid){
28809 + printk("fake_child_exit - waitpid failed, "
28810 + "errno = %d\n", errno);
28813 + if(ptrace(PTRACE_DETACH, debugger.pid, 0, SIGCONT) < 0)
28814 + printk("fake_child_exit - PTRACE_DETACH failed, errno = %d\n",
28818 +char gdb_init_string[] =
28822 +handle SIGWINCH nostop noprint pass \n\
28825 +int start_debugger(char *prog, int startup, int stop, int *fd_out)
28827 + int slave, child;
28829 + slave = open_gdb_chan();
28830 + if((child = fork()) == 0){
28831 + char *tempname = NULL;
28834 + if(setsid() < 0) perror("setsid");
28835 + if((dup2(slave, 0) < 0) || (dup2(slave, 1) < 0) ||
28836 + (dup2(slave, 2) < 0)){
28837 + printk("start_debugger : dup2 failed, errno = %d\n",
28841 + if(ioctl(0, TIOCSCTTY, 0) < 0){
28842 + printk("start_debugger : TIOCSCTTY failed, "
28843 + "errno = %d\n", errno);
28846 + if(tcsetpgrp (1, os_getpid()) < 0){
28847 + printk("start_debugger : tcsetpgrp failed, "
28848 + "errno = %d\n", errno);
28853 + if((fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0)) < 0){
28854 + printk("start_debugger : make_tempfile failed, errno = %d\n",
28858 + write(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
28861 + write(fd, "b start_kernel\n",
28862 + strlen("b start_kernel\n"));
28864 + write(fd, "c\n", strlen("c\n"));
28866 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
28867 + printk("start_debugger : PTRACE_TRACEME failed, "
28868 + "errno = %d\n", errno);
28871 + execlp("gdb", "gdb", "--command", tempname, prog, NULL);
28872 + printk("start_debugger : exec of gdb failed, errno = %d\n",
28876 + printk("start_debugger : fork for gdb failed, errno = %d\n",
28885 + * Overrides for Emacs so that we follow Linus's tabbing style.
28886 + * Emacs will notice this stuff at the end of the file and automatically
28887 + * adjust the settings for this buffer only. This must remain at the end
28889 + * ---------------------------------------------------------------------------
28890 + * Local variables:
28891 + * c-file-style: "linux"
28894 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptproxy.h um/arch/um/kernel/tt/ptproxy/ptproxy.h
28895 --- orig/arch/um/kernel/tt/ptproxy/ptproxy.h Wed Dec 31 19:00:00 1969
28896 +++ um/arch/um/kernel/tt/ptproxy/ptproxy.h Wed Oct 23 21:08:04 2002
28898 +/**********************************************************************
28901 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
28902 +terms and conditions.
28903 +**********************************************************************/
28905 +#ifndef __PTPROXY_H
28906 +#define __PTPROXY_H
28908 +#include <sys/types.h>
28910 +typedef struct debugger debugger_state;
28911 +typedef struct debugee debugee_state;
28916 + int wait_options;
28917 + int *wait_status_ptr;
28918 + unsigned int waiting : 1;
28919 + unsigned int real_wait : 1;
28920 + unsigned int expecting_child : 1;
28921 + int (*handle_trace) (debugger_state *, pid_t);
28923 + debugee_state *debugee;
28930 + unsigned int died : 1;
28931 + unsigned int event : 1;
28932 + unsigned int stopped : 1;
28933 + unsigned int trace_singlestep : 1;
28934 + unsigned int trace_syscall : 1;
28935 + unsigned int traced : 1;
28936 + unsigned int zombie : 1;
28937 + unsigned int in_context : 1;
28940 +extern int debugger_syscall(debugger_state *debugger, pid_t pid);
28941 +extern int debugger_normal_return (debugger_state *debugger, pid_t unused);
28943 +extern long proxy_ptrace (struct debugger *, int, pid_t, long, long, pid_t,
28944 + int *strace_out);
28945 +extern void debugger_cancelled_return(debugger_state *debugger, int result);
28950 + * Overrides for Emacs so that we follow Linus's tabbing style.
28951 + * Emacs will notice this stuff at the end of the file and automatically
28952 + * adjust the settings for this buffer only. This must remain at the end
28954 + * ---------------------------------------------------------------------------
28955 + * Local variables:
28956 + * c-file-style: "linux"
28959 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptrace.c um/arch/um/kernel/tt/ptproxy/ptrace.c
28960 --- orig/arch/um/kernel/tt/ptproxy/ptrace.c Wed Dec 31 19:00:00 1969
28961 +++ um/arch/um/kernel/tt/ptproxy/ptrace.c Mon Nov 11 13:06:03 2002
28963 +/**********************************************************************
28966 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
28967 +terms and conditions.
28969 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
28970 +**********************************************************************/
28972 +#include <errno.h>
28973 +#include <unistd.h>
28974 +#include <signal.h>
28975 +#include <sys/types.h>
28976 +#include <sys/time.h>
28977 +#include <sys/ptrace.h>
28978 +#include <sys/wait.h>
28979 +#include <asm/ptrace.h>
28981 +#include "ptproxy.h"
28982 +#include "debug.h"
28983 +#include "user_util.h"
28984 +#include "kern_util.h"
28985 +#include "ptrace_user.h"
28988 +long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
28989 + long arg3, long arg4, pid_t child, int *ret)
28996 + if(debugger->debugee->died) return(-ESRCH);
28999 + case PTRACE_ATTACH:
29000 + if(debugger->debugee->traced) return(-EPERM);
29002 + debugger->debugee->pid = arg2;
29003 + debugger->debugee->traced = 1;
29005 + if(is_valid_pid(arg2) && (arg2 != child)){
29006 + debugger->debugee->in_context = 0;
29007 + kill(arg2, SIGSTOP);
29008 + debugger->debugee->event = 1;
29009 + debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);
29012 + debugger->debugee->in_context = 1;
29013 + if(debugger->debugee->stopped)
29014 + child_proxy(child, W_STOPCODE(SIGSTOP));
29015 + else kill(child, SIGSTOP);
29020 + case PTRACE_DETACH:
29021 + if(!debugger->debugee->traced) return(-EPERM);
29023 + debugger->debugee->traced = 0;
29024 + debugger->debugee->pid = 0;
29025 + if(!debugger->debugee->in_context)
29026 + kill(child, SIGCONT);
29030 + case PTRACE_CONT:
29031 + if(!debugger->debugee->in_context) return(-EPERM);
29032 + *ret = PTRACE_CONT;
29033 + return(ptrace(PTRACE_CONT, child, arg3, arg4));
29035 +#ifdef UM_HAVE_GETFPREGS
29036 + case PTRACE_GETFPREGS:
29038 + long regs[FP_FRAME_SIZE];
29041 + result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
29042 + if(result == -1) return(-errno);
29044 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
29045 + ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
29051 +#ifdef UM_HAVE_GETFPXREGS
29052 + case PTRACE_GETFPXREGS:
29054 + long regs[FPX_FRAME_SIZE];
29057 + result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
29058 + if(result == -1) return(-errno);
29060 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
29061 + ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
29067 +#ifdef UM_HAVE_GETREGS
29068 + case PTRACE_GETREGS:
29070 + long regs[FRAME_SIZE];
29073 + result = ptrace(PTRACE_GETREGS, child, 0, regs);
29074 + if(result == -1) return(-errno);
29076 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
29077 + ptrace (PTRACE_POKEDATA, debugger->pid,
29078 + arg4 + 4 * i, regs[i]);
29084 + case PTRACE_KILL:
29085 + result = ptrace(PTRACE_KILL, child, arg3, arg4);
29086 + if(result == -1) return(-errno);
29090 + case PTRACE_PEEKDATA:
29091 + case PTRACE_PEEKTEXT:
29092 + case PTRACE_PEEKUSER:
29093 + /* The value being read out could be -1, so we have to
29094 + * check errno to see if there's an error, and zero it
29095 + * beforehand so we're not faked out by an old error
29099 + result = ptrace(arg1, child, arg3, 0);
29100 + if((result == -1) && (errno != 0)) return(-errno);
29102 + result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
29103 + if(result == -1) return(-errno);
29107 + case PTRACE_POKEDATA:
29108 + case PTRACE_POKETEXT:
29109 + case PTRACE_POKEUSER:
29110 + result = ptrace(arg1, child, arg3, arg4);
29111 + if(result == -1) return(-errno);
29113 + if(arg1 == PTRACE_POKEUSER) ptrace_pokeuser(arg3, arg4);
29116 +#ifdef UM_HAVE_SETFPREGS
29117 + case PTRACE_SETFPREGS:
29119 + long regs[FP_FRAME_SIZE];
29122 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
29123 + regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
29124 + arg4 + 4 * i, 0);
29125 + result = ptrace(PTRACE_SETFPREGS, child, 0, regs);
29126 + if(result == -1) return(-errno);
29132 +#ifdef UM_HAVE_SETFPXREGS
29133 + case PTRACE_SETFPXREGS:
29135 + long regs[FPX_FRAME_SIZE];
29138 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
29139 + regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
29140 + arg4 + 4 * i, 0);
29141 + result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);
29142 + if(result == -1) return(-errno);
29148 +#ifdef UM_HAVE_SETREGS
29149 + case PTRACE_SETREGS:
29151 + long regs[FRAME_SIZE];
29154 + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
29155 + regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,
29156 + arg4 + 4 * i, 0);
29157 + result = ptrace(PTRACE_SETREGS, child, 0, regs);
29158 + if(result == -1) return(-errno);
29164 + case PTRACE_SINGLESTEP:
29165 + if(!debugger->debugee->in_context) return(-EPERM);
29166 + sigemptyset(&relay);
29167 + sigaddset(&relay, SIGSEGV);
29168 + sigaddset(&relay, SIGILL);
29169 + sigaddset(&relay, SIGBUS);
29170 + result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4);
29171 + if(result == -1) return(-errno);
29173 + status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
29175 + child_proxy(child, status);
29178 + case PTRACE_SYSCALL:
29179 + if(!debugger->debugee->in_context) return(-EPERM);
29180 + result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);
29181 + if(result == -1) return(-errno);
29183 + *ret = PTRACE_SYSCALL;
29186 + case PTRACE_TRACEME:
29193 + * Overrides for Emacs so that we follow Linus's tabbing style.
29194 + * Emacs will notice this stuff at the end of the file and automatically
29195 + * adjust the settings for this buffer only. This must remain at the end
29197 + * ---------------------------------------------------------------------------
29198 + * Local variables:
29199 + * c-file-style: "linux"
29202 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.c um/arch/um/kernel/tt/ptproxy/sysdep.c
29203 --- orig/arch/um/kernel/tt/ptproxy/sysdep.c Wed Dec 31 19:00:00 1969
29204 +++ um/arch/um/kernel/tt/ptproxy/sysdep.c Wed Oct 23 21:08:04 2002
29206 +/**********************************************************************
29209 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
29210 +terms and conditions.
29211 +**********************************************************************/
29213 +#include <stdio.h>
29214 +#include <string.h>
29215 +#include <stdlib.h>
29216 +#include <signal.h>
29217 +#include <sys/types.h>
29218 +#include <sys/ptrace.h>
29219 +#include <asm/ptrace.h>
29220 +#include <linux/unistd.h>
29221 +#include "ptrace_user.h"
29222 +#include "user_util.h"
29225 +int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4,
29228 + *arg1 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG1_OFFSET, 0);
29229 + *arg2 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG2_OFFSET, 0);
29230 + *arg3 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG3_OFFSET, 0);
29231 + *arg4 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG4_OFFSET, 0);
29232 + *arg5 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG5_OFFSET, 0);
29233 + return(ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET, 0));
29236 +void syscall_cancel(pid_t pid, int result)
29238 + if((ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
29239 + __NR_getpid) < 0) ||
29240 + (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) ||
29241 + (wait_for_stop(pid, SIGTRAP, PTRACE_SYSCALL, NULL) < 0) ||
29242 + (ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result) < 0) ||
29243 + (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0))
29244 + printk("ptproxy: couldn't cancel syscall: errno = %d\n",
29248 +void syscall_set_result(pid_t pid, long result)
29250 + ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result);
29253 +void syscall_continue(pid_t pid)
29255 + ptrace(PTRACE_SYSCALL, pid, 0, 0);
29258 +int syscall_pause(pid_t pid)
29260 + if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_pause) < 0){
29261 + printk("syscall_change - ptrace failed, errno = %d\n", errno);
29268 + * Overrides for Emacs so that we follow Linus's tabbing style.
29269 + * Emacs will notice this stuff at the end of the file and automatically
29270 + * adjust the settings for this buffer only. This must remain at the end
29272 + * ---------------------------------------------------------------------------
29273 + * Local variables:
29274 + * c-file-style: "linux"
29277 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.h um/arch/um/kernel/tt/ptproxy/sysdep.h
29278 --- orig/arch/um/kernel/tt/ptproxy/sysdep.h Wed Dec 31 19:00:00 1969
29279 +++ um/arch/um/kernel/tt/ptproxy/sysdep.h Wed Oct 23 21:08:04 2002
29281 +/**********************************************************************
29284 +Copyright (C) 1999 Lars Brinkhoff.
29285 +Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
29286 +See the file COPYING for licensing terms and conditions.
29287 +**********************************************************************/
29289 +extern int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3,
29290 + long *arg4, long *arg5);
29291 +extern void syscall_cancel (pid_t pid, long result);
29292 +extern void syscall_set_result (pid_t pid, long result);
29293 +extern void syscall_continue (pid_t pid);
29294 +extern int syscall_pause(pid_t pid);
29297 + * Overrides for Emacs so that we follow Linus's tabbing style.
29298 + * Emacs will notice this stuff at the end of the file and automatically
29299 + * adjust the settings for this buffer only. This must remain at the end
29301 + * ---------------------------------------------------------------------------
29302 + * Local variables:
29303 + * c-file-style: "linux"
29306 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.c um/arch/um/kernel/tt/ptproxy/wait.c
29307 --- orig/arch/um/kernel/tt/ptproxy/wait.c Wed Dec 31 19:00:00 1969
29308 +++ um/arch/um/kernel/tt/ptproxy/wait.c Wed Oct 23 21:08:04 2002
29310 +/**********************************************************************
29313 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
29314 +terms and conditions.
29316 +**********************************************************************/
29318 +#include <errno.h>
29319 +#include <signal.h>
29320 +#include <sys/wait.h>
29321 +#include <sys/ptrace.h>
29322 +#include <asm/ptrace.h>
29324 +#include "ptproxy.h"
29325 +#include "sysdep.h"
29327 +#include "user_util.h"
29328 +#include "sysdep/ptrace.h"
29329 +#include "sysdep/ptrace_user.h"
29330 +#include "sysdep/sigcontext.h"
29332 +int proxy_wait_return(struct debugger *debugger, pid_t unused)
29334 + debugger->waiting = 0;
29336 + if(debugger->debugee->died || (debugger->wait_options & __WCLONE)){
29337 + debugger_cancelled_return(debugger, -ECHILD);
29341 + if(debugger->debugee->zombie && debugger->debugee->event)
29342 + debugger->debugee->died = 1;
29344 + if(debugger->debugee->event){
29345 + debugger->debugee->event = 0;
29346 + ptrace(PTRACE_POKEDATA, debugger->pid,
29347 + debugger->wait_status_ptr,
29348 + debugger->debugee->wait_status);
29350 + ptrace (PTRACE_POKEDATA, pid, rusage_ptr, ...); */
29351 + debugger_cancelled_return(debugger, debugger->debugee->pid);
29355 + /* pause will return -EINTR, which happens to be right for wait */
29356 + debugger_normal_return(debugger, -1);
29360 +int parent_wait_return(struct debugger *debugger, pid_t unused)
29362 + return(debugger_normal_return(debugger, -1));
29365 +int real_wait_return(struct debugger *debugger)
29367 + unsigned long ip;
29370 + pid = debugger->pid;
29371 + ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
29372 + ip = IP_RESTART_SYSCALL(ip);
29373 + err = ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip);
29374 + if(ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip) < 0)
29375 + tracer_panic("real_wait_return : Failed to restart system "
29376 + "call, errno = %d\n");
29377 + if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
29378 + (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
29379 + (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
29380 + debugger_normal_return(debugger, -1))
29381 + tracer_panic("real_wait_return : gdb failed to wait, "
29387 + * Overrides for Emacs so that we follow Linus's tabbing style.
29388 + * Emacs will notice this stuff at the end of the file and automatically
29389 + * adjust the settings for this buffer only. This must remain at the end
29391 + * ---------------------------------------------------------------------------
29392 + * Local variables:
29393 + * c-file-style: "linux"
29396 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.h um/arch/um/kernel/tt/ptproxy/wait.h
29397 --- orig/arch/um/kernel/tt/ptproxy/wait.h Wed Dec 31 19:00:00 1969
29398 +++ um/arch/um/kernel/tt/ptproxy/wait.h Wed Oct 23 21:08:04 2002
29400 +/**********************************************************************
29403 +Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
29404 +terms and conditions.
29405 +**********************************************************************/
29407 +#ifndef __PTPROXY_WAIT_H
29408 +#define __PTPROXY_WAIT_H
29410 +extern int proxy_wait_return(struct debugger *debugger, pid_t unused);
29411 +extern int real_wait_return(struct debugger *debugger);
29412 +extern int parent_wait_return(struct debugger *debugger, pid_t unused);
29415 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/Makefile um/arch/um/kernel/tt/sys-i386/Makefile
29416 --- orig/arch/um/kernel/tt/sys-i386/Makefile Wed Dec 31 19:00:00 1969
29417 +++ um/arch/um/kernel/tt/sys-i386/Makefile Wed Oct 23 21:08:04 2002
29420 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29421 +# Licensed under the GPL
29424 +O_TARGET = sys-i386.o
29426 +obj-y = sigcontext.o
29428 +USER_OBJS = sigcontext.o
29430 +include $(TOPDIR)/Rules.make
29432 +$(USER_OBJS) : %.o: %.c
29433 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
29436 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/sigcontext.c um/arch/um/kernel/tt/sys-i386/sigcontext.c
29437 --- orig/arch/um/kernel/tt/sys-i386/sigcontext.c Wed Dec 31 19:00:00 1969
29438 +++ um/arch/um/kernel/tt/sys-i386/sigcontext.c Sun Dec 1 23:33:52 2002
29441 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29442 + * Licensed under the GPL
29445 +#include <stdlib.h>
29446 +#include <asm/sigcontext.h>
29447 +#include "kern_util.h"
29448 +#include "sysdep/frame.h"
29450 +int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data)
29452 + struct arch_frame_data *arch = data;
29453 + struct sigcontext *to = to_ptr, *from = from_ptr;
29454 + struct _fpstate *to_fp, *from_fp;
29455 + unsigned long sigs;
29458 + to_fp = to->fpstate;
29459 + from_fp = from->fpstate;
29460 + sigs = to->oldmask;
29461 + err = copy_from_user_proc(to, from, sizeof(*to));
29462 + to->oldmask = sigs;
29463 + if(to_fp != NULL){
29464 + err |= copy_from_user_proc(&to->fpstate, &to_fp,
29465 + sizeof(to->fpstate));
29466 + err |= copy_from_user_proc(to_fp, from_fp, arch->fpstate_size);
29471 +int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data)
29473 + struct arch_frame_data *arch = data;
29474 + struct sigcontext *to = to_ptr, *from = from_ptr;
29475 + struct _fpstate *to_fp, *from_fp;
29478 + to_fp = (struct _fpstate *)
29479 + (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
29480 + from_fp = from->fpstate;
29481 + err = copy_to_user_proc(to, from, sizeof(*to));
29482 + if(from_fp != NULL){
29483 + err |= copy_to_user_proc(&to->fpstate, &to_fp,
29484 + sizeof(to->fpstate));
29485 + err |= copy_to_user_proc(to_fp, from_fp, arch->fpstate_size);
29491 + * Overrides for Emacs so that we follow Linus's tabbing style.
29492 + * Emacs will notice this stuff at the end of the file and automatically
29493 + * adjust the settings for this buffer only. This must remain at the end
29495 + * ---------------------------------------------------------------------------
29496 + * Local variables:
29497 + * c-file-style: "linux"
29500 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_kern.c um/arch/um/kernel/tt/syscall_kern.c
29501 --- orig/arch/um/kernel/tt/syscall_kern.c Wed Dec 31 19:00:00 1969
29502 +++ um/arch/um/kernel/tt/syscall_kern.c Sun Dec 8 19:32:53 2002
29505 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
29506 + * Licensed under the GPL
29509 +#include "linux/types.h"
29510 +#include "linux/utime.h"
29511 +#include "linux/sys.h"
29512 +#include "asm/unistd.h"
29513 +#include "asm/ptrace.h"
29514 +#include "asm/uaccess.h"
29515 +#include "sysdep/syscalls.h"
29516 +#include "kern_util.h"
29518 +static inline int check_area(void *ptr, int size)
29520 + return(verify_area(VERIFY_WRITE, ptr, size));
29523 +static int check_readlink(struct pt_regs *regs)
29525 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
29526 + UPT_SYSCALL_ARG2(®s->regs)));
29529 +static int check_utime(struct pt_regs *regs)
29531 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
29532 + sizeof(struct utimbuf)));
29535 +static int check_oldstat(struct pt_regs *regs)
29537 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
29538 + sizeof(struct __old_kernel_stat)));
29541 +static int check_stat(struct pt_regs *regs)
29543 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
29544 + sizeof(struct stat)));
29547 +static int check_stat64(struct pt_regs *regs)
29549 + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs),
29550 + sizeof(struct stat64)));
29555 + int (*check_params)(struct pt_regs *);
29558 +struct bogus this_is_bogus[256] = {
29559 + [ __NR_mknod ] = { 1, NULL },
29560 + [ __NR_mkdir ] = { 1, NULL },
29561 + [ __NR_rmdir ] = { 1, NULL },
29562 + [ __NR_unlink ] = { 1, NULL },
29563 + [ __NR_symlink ] = { 1, NULL },
29564 + [ __NR_link ] = { 1, NULL },
29565 + [ __NR_rename ] = { 1, NULL },
29566 + [ __NR_umount ] = { 1, NULL },
29567 + [ __NR_mount ] = { 1, NULL },
29568 + [ __NR_pivot_root ] = { 1, NULL },
29569 + [ __NR_chdir ] = { 1, NULL },
29570 + [ __NR_chroot ] = { 1, NULL },
29571 + [ __NR_open ] = { 1, NULL },
29572 + [ __NR_quotactl ] = { 1, NULL },
29573 + [ __NR_sysfs ] = { 1, NULL },
29574 + [ __NR_readlink ] = { 1, check_readlink },
29575 + [ __NR_acct ] = { 1, NULL },
29576 + [ __NR_execve ] = { 1, NULL },
29577 + [ __NR_uselib ] = { 1, NULL },
29578 + [ __NR_statfs ] = { 1, NULL },
29579 + [ __NR_truncate ] = { 1, NULL },
29580 + [ __NR_access ] = { 1, NULL },
29581 + [ __NR_chmod ] = { 1, NULL },
29582 + [ __NR_chown ] = { 1, NULL },
29583 + [ __NR_lchown ] = { 1, NULL },
29584 + [ __NR_utime ] = { 1, check_utime },
29585 + [ __NR_oldlstat ] = { 1, check_oldstat },
29586 + [ __NR_oldstat ] = { 1, check_oldstat },
29587 + [ __NR_stat ] = { 1, check_stat },
29588 + [ __NR_lstat ] = { 1, check_stat },
29589 + [ __NR_stat64 ] = { 1, check_stat64 },
29590 + [ __NR_lstat64 ] = { 1, check_stat64 },
29591 + [ __NR_chown32 ] = { 1, NULL },
29596 +static int check_bogosity(struct pt_regs *regs)
29598 + struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(®s->regs)];
29600 + if(!bogon->kernel_ds) return(0);
29601 + if(bogon->check_params && (*bogon->check_params)(regs))
29603 + set_fs(KERNEL_DS);
29607 +extern syscall_handler_t *sys_call_table[];
29609 +long execute_syscall_tt(void *r)
29611 + struct pt_regs *regs = r;
29615 + current->thread.nsyscalls++;
29617 + syscall = UPT_SYSCALL_NR(®s->regs);
29619 + if((syscall >= NR_syscalls) || (syscall < 0))
29621 + else if(honeypot && check_bogosity(regs))
29623 + else res = EXECUTE_SYSCALL(syscall, regs);
29627 + if(current->thread.mode.tt.singlestep_syscall){
29628 + current->thread.mode.tt.singlestep_syscall = 0;
29629 + current->ptrace &= ~PT_DTRACE;
29630 + force_sig(SIGTRAP, current);
29637 + * Overrides for Emacs so that we follow Linus's tabbing style.
29638 + * Emacs will notice this stuff at the end of the file and automatically
29639 + * adjust the settings for this buffer only. This must remain at the end
29641 + * ---------------------------------------------------------------------------
29642 + * Local variables:
29643 + * c-file-style: "linux"
29646 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_user.c um/arch/um/kernel/tt/syscall_user.c
29647 --- orig/arch/um/kernel/tt/syscall_user.c Wed Dec 31 19:00:00 1969
29648 +++ um/arch/um/kernel/tt/syscall_user.c Sun Dec 8 21:00:11 2002
29651 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
29652 + * Licensed under the GPL
29655 +#include <unistd.h>
29656 +#include <signal.h>
29657 +#include <errno.h>
29658 +#include <sys/ptrace.h>
29659 +#include <asm/unistd.h>
29660 +#include "sysdep/ptrace.h"
29661 +#include "sigcontext.h"
29662 +#include "ptrace_user.h"
29664 +#include "user_util.h"
29665 +#include "kern_util.h"
29666 +#include "syscall_user.h"
29670 +#define ERESTARTSYS 512
29671 +#define ERESTARTNOINTR 513
29672 +#define ERESTARTNOHAND 514
29674 +void syscall_handler_tt(int sig, union uml_pt_regs *regs)
29678 + int index, syscall;
29680 + syscall = UPT_SYSCALL_NR(regs);
29681 + sc = UPT_SC(regs);
29682 + SC_START_SYSCALL(sc);
29684 + index = record_syscall_start(syscall);
29686 + result = execute_syscall(regs);
29688 + /* regs->sc may have changed while the system call ran (there may
29689 + * have been an interrupt or segfault), so it needs to be refreshed.
29691 + UPT_SC(regs) = sc;
29693 + SC_SET_SYSCALL_RETURN(sc, result);
29694 + if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) ||
29695 + (result == -ERESTARTNOINTR))
29696 + do_signal(result);
29699 + record_syscall_end(index, result);
29702 +int do_syscall(void *task, int pid)
29704 + unsigned long proc_regs[FRAME_SIZE];
29705 + union uml_pt_regs *regs;
29708 + if(ptrace_getregs(pid, proc_regs) < 0)
29709 + tracer_panic("Couldn't read registers");
29710 + syscall = PT_SYSCALL_NR(proc_regs);
29712 + regs = TASK_REGS(task);
29713 + UPT_SYSCALL_NR(regs) = syscall;
29715 + if(syscall < 1) return(0);
29717 + if((syscall != __NR_sigreturn) &&
29718 + ((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
29719 + ((unsigned long *) PT_IP(proc_regs) <= &_etext))
29720 + tracer_panic("I'm tracing myself and I can't get out");
29722 + if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
29723 + __NR_getpid) < 0)
29724 + tracer_panic("do_syscall : Nullifying syscall failed, "
29725 + "errno = %d", errno);
29730 + * Overrides for Emacs so that we follow Linus's tabbing style.
29731 + * Emacs will notice this stuff at the end of the file and automatically
29732 + * adjust the settings for this buffer only. This must remain at the end
29734 + * ---------------------------------------------------------------------------
29735 + * Local variables:
29736 + * c-file-style: "linux"
29739 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/time.c um/arch/um/kernel/tt/time.c
29740 --- orig/arch/um/kernel/tt/time.c Wed Dec 31 19:00:00 1969
29741 +++ um/arch/um/kernel/tt/time.c Wed Oct 23 21:08:04 2002
29744 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
29745 + * Licensed under the GPL
29748 +#include <signal.h>
29749 +#include <sys/time.h>
29750 +#include <time_user.h>
29751 +#include "process.h"
29754 +void user_time_init_tt(void)
29756 + if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
29757 + panic("Couldn't set SIGVTALRM handler");
29758 + set_interval(ITIMER_VIRTUAL);
29762 + * Overrides for Emacs so that we follow Linus's tabbing style.
29763 + * Emacs will notice this stuff at the end of the file and automatically
29764 + * adjust the settings for this buffer only. This must remain at the end
29766 + * ---------------------------------------------------------------------------
29767 + * Local variables:
29768 + * c-file-style: "linux"
29771 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tlb.c um/arch/um/kernel/tt/tlb.c
29772 --- orig/arch/um/kernel/tt/tlb.c Wed Dec 31 19:00:00 1969
29773 +++ um/arch/um/kernel/tt/tlb.c Thu Dec 19 13:03:11 2002
29776 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29777 + * Licensed under the GPL
29780 +#include "linux/stddef.h"
29781 +#include "linux/kernel.h"
29782 +#include "linux/sched.h"
29783 +#include "asm/page.h"
29784 +#include "asm/pgtable.h"
29785 +#include "asm/uaccess.h"
29786 +#include "user_util.h"
29787 +#include "mem_user.h"
29790 +static void fix_range(struct mm_struct *mm, unsigned long start_addr,
29791 + unsigned long end_addr, int force)
29796 + unsigned long addr;
29797 + int r, w, x, err;
29799 + if((current->thread.mode.tt.extern_pid != -1) &&
29800 + (current->thread.mode.tt.extern_pid != os_getpid()))
29801 + panic("fix_range fixing wrong address space, current = 0x%p",
29803 + if(mm == NULL) return;
29804 + for(addr=start_addr;addr<end_addr;){
29805 + if(addr == TASK_SIZE){
29806 + /* Skip over kernel text, kernel data, and physical
29807 + * memory, which don't have ptes, plus kernel virtual
29808 + * memory, which is flushed separately, and remap
29809 + * the process stack. The only way to get here is
29810 + * if (end_addr == STACK_TOP) > TASK_SIZE, which is
29811 + * only true in the honeypot case.
29813 + addr = STACK_TOP - ABOVE_KMEM;
29816 + npgd = pgd_offset(mm, addr);
29817 + npmd = pmd_offset(npgd, addr);
29818 + if(pmd_present(*npmd)){
29819 + npte = pte_offset(npmd, addr);
29820 + r = pte_read(*npte);
29821 + w = pte_write(*npte);
29822 + x = pte_exec(*npte);
29823 + if(!pte_dirty(*npte)) w = 0;
29824 + if(!pte_young(*npte)){
29828 + if(force || pte_newpage(*npte)){
29829 + err = os_unmap_memory((void *) addr,
29832 + panic("munmap failed, errno = %d\n",
29834 + if(pte_present(*npte))
29836 + pte_val(*npte) & PAGE_MASK,
29837 + PAGE_SIZE, r, w, x);
29839 + else if(pte_newprot(*npte)){
29840 + protect_memory(addr, PAGE_SIZE, r, w, x, 1);
29842 + *npte = pte_mkuptodate(*npte);
29843 + addr += PAGE_SIZE;
29846 + if(force || pmd_newpage(*npmd)){
29847 + err = os_unmap_memory((void *) addr, PMD_SIZE);
29849 + panic("munmap failed, errno = %d\n",
29851 + pmd_mkuptodate(*npmd);
29853 + addr += PMD_SIZE;
29858 +atomic_t vmchange_seq = ATOMIC_INIT(1);
29860 +static void flush_kernel_vm_range(unsigned long start, unsigned long end,
29863 + struct mm_struct *mm;
29867 + unsigned long addr;
29868 + int updated = 0, err;
29871 + for(addr = start; addr < end;){
29872 + pgd = pgd_offset(mm, addr);
29873 + pmd = pmd_offset(pgd, addr);
29874 + if(pmd_present(*pmd)){
29875 + pte = pte_offset(pmd, addr);
29876 + if(!pte_present(*pte) || pte_newpage(*pte)){
29878 + err = os_unmap_memory((void *) addr,
29881 + panic("munmap failed, errno = %d\n",
29883 + if(pte_present(*pte))
29885 + pte_val(*pte) & PAGE_MASK,
29886 + PAGE_SIZE, 1, 1, 1);
29888 + else if(pte_newprot(*pte)){
29890 + protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
29892 + addr += PAGE_SIZE;
29895 + if(pmd_newpage(*pmd)){
29897 + err = os_unmap_memory((void *) addr, PMD_SIZE);
29899 + panic("munmap failed, errno = %d\n",
29902 + addr += PMD_SIZE;
29905 + if(updated && update_seq) atomic_inc(&vmchange_seq);
29908 +static void protect_vm_page(unsigned long addr, int w, int must_succeed)
29912 + err = protect_memory(addr, PAGE_SIZE, 1, w, 1, must_succeed);
29913 + if(err == 0) return;
29914 + else if((err == -EFAULT) || (err == -ENOMEM)){
29915 + flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
29916 + protect_vm_page(addr, w, 1);
29918 + else panic("protect_vm_page : protect failed, errno = %d\n", err);
29921 +void mprotect_kernel_vm(int w)
29923 + struct mm_struct *mm;
29927 + unsigned long addr;
29930 + for(addr = start_vm; addr < end_vm;){
29931 + pgd = pgd_offset(mm, addr);
29932 + pmd = pmd_offset(pgd, addr);
29933 + if(pmd_present(*pmd)){
29934 + pte = pte_offset(pmd, addr);
29935 + if(pte_present(*pte)) protect_vm_page(addr, w, 0);
29936 + addr += PAGE_SIZE;
29938 + else addr += PMD_SIZE;
29942 +void flush_tlb_kernel_vm_tt(void)
29944 + flush_kernel_vm_range(start_vm, end_vm, 1);
29947 +void __flush_tlb_one_tt(unsigned long addr)
29949 + flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
29952 +void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start,
29953 + unsigned long end)
29955 + if(mm != current->mm) return;
29957 + /* Assumes that the range start ... end is entirely within
29958 + * either process memory or kernel vm
29960 + if((start >= start_vm) && (start < end_vm))
29961 + flush_kernel_vm_range(start, end, 1);
29962 + else fix_range(mm, start, end, 0);
29965 +void flush_tlb_mm_tt(struct mm_struct *mm)
29967 + unsigned long seq;
29969 + if(mm != current->mm) return;
29971 + fix_range(mm, 0, STACK_TOP, 0);
29973 + seq = atomic_read(&vmchange_seq);
29974 + if(current->thread.mode.tt.vm_seq == seq) return;
29975 + current->thread.mode.tt.vm_seq = seq;
29976 + flush_kernel_vm_range(start_vm, end_vm, 0);
29979 +void force_flush_all_tt(void)
29981 + fix_range(current->mm, 0, STACK_TOP, 1);
29982 + flush_kernel_vm_range(start_vm, end_vm, 0);
29986 + * Overrides for Emacs so that we follow Linus's tabbing style.
29987 + * Emacs will notice this stuff at the end of the file and automatically
29988 + * adjust the settings for this buffer only. This must remain at the end
29990 + * ---------------------------------------------------------------------------
29991 + * Local variables:
29992 + * c-file-style: "linux"
29995 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tracer.c um/arch/um/kernel/tt/tracer.c
29996 --- orig/arch/um/kernel/tt/tracer.c Wed Dec 31 19:00:00 1969
29997 +++ um/arch/um/kernel/tt/tracer.c Wed Mar 26 10:01:33 2003
30000 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
30001 + * Licensed under the GPL
30004 +#include <stdio.h>
30005 +#include <stdlib.h>
30006 +#include <stdarg.h>
30007 +#include <unistd.h>
30008 +#include <signal.h>
30009 +#include <errno.h>
30010 +#include <sched.h>
30011 +#include <string.h>
30012 +#include <sys/mman.h>
30013 +#include <sys/ptrace.h>
30014 +#include <sys/time.h>
30015 +#include <sys/wait.h>
30017 +#include "sysdep/ptrace.h"
30018 +#include "sigcontext.h"
30019 +#include "sysdep/sigcontext.h"
30021 +#include "signal_user.h"
30022 +#include "user_util.h"
30023 +#include "mem_user.h"
30024 +#include "process.h"
30025 +#include "kern_util.h"
30026 +#include "frame.h"
30027 +#include "chan_user.h"
30028 +#include "ptrace_user.h"
30032 +static int tracer_winch[2];
30034 +int is_tracer_winch(int pid, int fd, void *data)
30036 + if(pid != tracing_pid)
30039 + register_winch_irq(tracer_winch[0], fd, -1, data);
30043 +static void tracer_winch_handler(int sig)
30047 + if(write(tracer_winch[1], &c, sizeof(c)) != sizeof(c))
30048 + printk("tracer_winch_handler - write failed, errno = %d\n",
30052 +/* Called only by the tracing thread during initialization */
30054 +static void setup_tracer_winch(void)
30058 + err = os_pipe(tracer_winch, 1, 1);
30060 + printk("setup_tracer_winch : os_pipe failed, errno = %d\n",
30064 + signal(SIGWINCH, tracer_winch_handler);
30067 +void attach_process(int pid)
30069 + if((ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) ||
30070 + (ptrace(PTRACE_CONT, pid, 0, 0) < 0))
30071 + tracer_panic("OP_FORK failed to attach pid");
30072 + wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
30073 + if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
30074 + tracer_panic("OP_FORK failed to continue process");
30077 +void tracer_panic(char *format, ...)
30081 + va_start(ap, format);
30082 + vprintf(format, ap);
30084 + while(1) pause();
30087 +static void tracer_segv(int sig, struct sigcontext sc)
30089 + printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
30090 + SC_FAULT_ADDR(&sc), SC_IP(&sc));
30095 +/* Changed early in boot, and then only read */
30097 +int debug_stop = 1;
30098 +int debug_parent = 0;
30101 +static int signal_tramp(void *arg)
30103 + int (*proc)(void *);
30105 + if(honeypot && munmap((void *) (host_task_size - 0x10000000),
30107 + panic("Unmapping stack failed");
30108 + if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
30109 + panic("ptrace PTRACE_TRACEME failed");
30110 + os_stop_process(os_getpid());
30111 + change_sig(SIGWINCH, 0);
30112 + signal(SIGUSR1, SIG_IGN);
30113 + change_sig(SIGCHLD, 0);
30114 + signal(SIGSEGV, (__sighandler_t) sig_handler);
30115 + set_cmdline("(idle thread)");
30116 + set_init_pid(os_getpid());
30118 + return((*proc)(NULL));
30121 +static void sleeping_process_signal(int pid, int sig)
30124 + /* These two result from UML being ^Z-ed and bg-ed. PTRACE_CONT is
30125 + * right because the process must be in the kernel already.
30129 + if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
30130 + tracer_panic("sleeping_process_signal : Failed to "
30131 + "continue pid %d, errno = %d\n", pid,
30135 + /* This happens when the debugger (e.g. strace) is doing system call
30136 + * tracing on the kernel. During a context switch, the current task
30137 + * will be set to the incoming process and the outgoing process will
30138 + * hop into write and then read. Since it's not the current process
30139 + * any more, the trace of those will land here. So, we need to just
30140 + * PTRACE_SYSCALL it.
30143 + if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
30144 + tracer_panic("sleeping_process_signal : Failed to "
30145 + "PTRACE_SYSCALL pid %d, errno = %d\n",
30151 + tracer_panic("sleeping process %d got unexpected "
30152 + "signal : %d\n", pid, sig);
30157 +/* Accessed only by the tracing thread */
30158 +int debugger_pid = -1;
30159 +int debugger_parent = -1;
30160 +int debugger_fd = -1;
30166 + unsigned long addr;
30167 + struct timeval time;
30168 +} signal_record[1024][32];
30170 +int signal_index[32];
30172 +int debug_trace = 0;
30173 +extern int io_nsignals, io_count, intr_count;
30175 +extern void signal_usr1(int sig);
30177 +int tracing_pid = -1;
30179 +int tracer(int (*init_proc)(void *), void *sp)
30181 + void *task = NULL;
30182 + unsigned long eip = 0;
30183 + int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
30184 + int last_index, proc_id = 0, n, err, old_tracing = 0, strace = 0;
30186 + capture_signal_stack();
30187 + signal(SIGPIPE, SIG_IGN);
30188 + setup_tracer_winch();
30189 + tracing_pid = os_getpid();
30190 + printf("tracing thread pid = %d\n", tracing_pid);
30192 + pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
30193 + n = waitpid(pid, &status, WUNTRACED);
30195 + printf("waitpid on idle thread failed, errno = %d\n", errno);
30198 + if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
30199 + printf("Failed to continue idle thread, errno = %d\n", errno);
30203 + signal(SIGSEGV, (sighandler_t) tracer_segv);
30204 + signal(SIGUSR1, signal_usr1);
30206 + printf("Tracing thread pausing to be attached\n");
30210 + if(gdb_pid != -1)
30211 + debugger_pid = attach_debugger(pid, gdb_pid, 1);
30212 + else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop);
30213 + if(debug_parent){
30214 + debugger_parent = os_process_parent(debugger_pid);
30215 + init_parent_proxy(debugger_parent);
30216 + err = attach(debugger_parent);
30218 + printf("Failed to attach debugger parent %d, "
30219 + "errno = %d\n", debugger_parent, err);
30220 + debugger_parent = -1;
30223 + if(ptrace(PTRACE_SYSCALL, debugger_parent,
30225 + printf("Failed to continue debugger "
30226 + "parent, errno = %d\n", errno);
30227 + debugger_parent = -1;
30232 + set_cmdline("(tracing thread)");
30234 + if((pid = waitpid(-1, &status, WUNTRACED)) <= 0){
30235 + if(errno != ECHILD){
30236 + printf("wait failed - errno = %d\n", errno);
30240 + if(pid == debugger_pid){
30243 + if(WIFEXITED(status) || WIFSIGNALED(status))
30244 + debugger_pid = -1;
30245 + /* XXX Figure out how to deal with gdb and SMP */
30246 + else cont = debugger_signal(status, cpu_tasks[0].pid);
30247 + if(cont == PTRACE_SYSCALL) strace = 1;
30250 + else if(pid == debugger_parent){
30251 + debugger_parent_signal(status, pid);
30255 + if(WIFEXITED(status)) ;
30258 + printf("Child %d exited with status %d\n", pid,
30259 + WEXITSTATUS(status));
30262 + else if(WIFSIGNALED(status)){
30263 + sig = WTERMSIG(status);
30265 + printf("Child %d exited with signal %d\n", pid,
30269 + else if(WIFSTOPPED(status)){
30270 + proc_id = pid_to_processor_id(pid);
30271 + sig = WSTOPSIG(status);
30272 + if(signal_index[proc_id] == 1024){
30273 + signal_index[proc_id] = 0;
30274 + last_index = 1023;
30276 + else last_index = signal_index[proc_id] - 1;
30277 + if(((sig == SIGPROF) || (sig == SIGVTALRM) ||
30278 + (sig == SIGALRM)) &&
30279 + (signal_record[proc_id][last_index].signal == sig)&&
30280 + (signal_record[proc_id][last_index].pid == pid))
30281 + signal_index[proc_id] = last_index;
30282 + signal_record[proc_id][signal_index[proc_id]].pid = pid;
30283 + gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL);
30284 + eip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
30285 + signal_record[proc_id][signal_index[proc_id]].addr = eip;
30286 + signal_record[proc_id][signal_index[proc_id]++].signal = sig;
30288 + if(proc_id == -1){
30289 + sleeping_process_signal(pid, sig);
30293 + task = cpu_tasks[proc_id].task;
30294 + tracing = is_tracing(task);
30295 + old_tracing = tracing;
30300 + op = do_proc_op(task, proc_id);
30302 + case OP_TRACE_ON:
30303 + arch_leave_kernel(task, pid);
30310 + ptrace(PTRACE_KILL, pid, 0, 0);
30311 + return(op == OP_REBOOT);
30313 + printf("Detaching pid %d\n", pid);
30314 + detach(pid, SIGSTOP);
30319 + /* OP_EXEC switches host processes on us,
30320 + * we want to continue the new one.
30322 + pid = cpu_tasks[proc_id].pid;
30325 + if(!tracing && (debugger_pid != -1)){
30326 + child_signal(pid, status);
30330 + if(do_syscall(task, pid)) sig = SIGUSR2;
30331 + else clear_singlestep(task);
30334 + if(tracing) sig = 0;
30352 + set_tracing(task, tracing);
30354 + if(!tracing && old_tracing)
30355 + arch_enter_kernel(task, pid);
30357 + if(!tracing && (debugger_pid != -1) && (sig != 0) &&
30358 + (sig != SIGALRM) && (sig != SIGVTALRM) &&
30359 + (sig != SIGSEGV) && (sig != SIGTRAP) &&
30360 + (sig != SIGUSR2) && (sig != SIGIO) &&
30361 + (sig != SIGFPE)){
30362 + child_signal(pid, status);
30367 + if(singlestepping_tt(task))
30368 + cont_type = PTRACE_SINGLESTEP;
30369 + else cont_type = PTRACE_SYSCALL;
30371 + else cont_type = PTRACE_CONT;
30373 + if((cont_type == PTRACE_CONT) &&
30374 + (debugger_pid != -1) && strace)
30375 + cont_type = PTRACE_SYSCALL;
30377 + if(ptrace(cont_type, pid, 0, sig) != 0){
30378 + tracer_panic("ptrace failed to continue "
30379 + "process - errno = %d\n",
30387 +static int __init uml_debug_setup(char *line, int *add)
30393 + if(*line != '=') return(0);
30396 + while(line != NULL){
30397 + next = strchr(line, ',');
30398 + if(next) *next++ = '\0';
30400 + if(!strcmp(line, "go")) debug_stop = 0;
30401 + else if(!strcmp(line, "parent")) debug_parent = 1;
30402 + else printf("Unknown debug option : '%s'\n", line);
30409 +__uml_setup("debug", uml_debug_setup,
30411 +" Starts up the kernel under the control of gdb. See the \n"
30412 +" kernel debugging tutorial and the debugging session pages\n"
30413 +" at http://user-mode-linux.sourceforge.net/ for more information.\n\n"
30416 +static int __init uml_debugtrace_setup(char *line, int *add)
30421 +__uml_setup("debugtrace", uml_debugtrace_setup,
30423 +" Causes the tracing thread to pause until it is attached by a\n"
30424 +" debugger and continued. This is mostly for debugging crashes\n"
30425 +" early during boot, and should be pretty much obsoleted by\n"
30426 +" the debug switch.\n\n"
30429 +static int __init uml_honeypot_setup(char *line, int *add)
30431 + jail_setup("", add);
30435 +__uml_setup("honeypot", uml_honeypot_setup,
30437 +" This makes UML put process stacks in the same location as they are\n"
30438 +" on the host, allowing expoits such as stack smashes to work against\n"
30439 +" UML. This implies 'jail'.\n\n"
30443 + * Overrides for Emacs so that we follow Linus's tabbing style.
30444 + * Emacs will notice this stuff at the end of the file and automatically
30445 + * adjust the settings for this buffer only. This must remain at the end
30447 + * ---------------------------------------------------------------------------
30448 + * Local variables:
30449 + * c-file-style: "linux"
30452 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/trap_user.c um/arch/um/kernel/tt/trap_user.c
30453 --- orig/arch/um/kernel/tt/trap_user.c Wed Dec 31 19:00:00 1969
30454 +++ um/arch/um/kernel/tt/trap_user.c Mon Dec 9 13:14:42 2002
30457 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
30458 + * Licensed under the GPL
30461 +#include <stdlib.h>
30462 +#include <errno.h>
30463 +#include <signal.h>
30464 +#include <asm/sigcontext.h>
30465 +#include "sysdep/ptrace.h"
30466 +#include "signal_user.h"
30467 +#include "user_util.h"
30468 +#include "kern_util.h"
30472 +void sig_handler_common_tt(int sig, void *sc_ptr)
30474 + struct sigcontext *sc = sc_ptr;
30475 + struct tt_regs save_regs, *r;
30476 + struct signal_info *info;
30477 + int save_errno = errno, is_user;
30479 + unprotect_kernel_mem();
30481 + r = &TASK_REGS(get_current())->tt;
30483 + is_user = user_context(SC_SP(sc));
30485 + if(sig != SIGUSR2)
30488 + change_sig(SIGUSR1, 1);
30489 + info = &sig_info[sig];
30490 + if(!info->is_irq) unblock_signals();
30492 + (*info->handler)(sig, (union uml_pt_regs *) r);
30497 + change_sig(SIGUSR1, 0);
30498 + set_user_mode(NULL);
30501 + errno = save_errno;
30502 + if(is_user) protect_kernel_mem();
30506 + * Overrides for Emacs so that we follow Linus's tabbing style.
30507 + * Emacs will notice this stuff at the end of the file and automatically
30508 + * adjust the settings for this buffer only. This must remain at the end
30510 + * ---------------------------------------------------------------------------
30511 + * Local variables:
30512 + * c-file-style: "linux"
30515 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/uaccess_user.c um/arch/um/kernel/tt/uaccess_user.c
30516 --- orig/arch/um/kernel/tt/uaccess_user.c Wed Dec 31 19:00:00 1969
30517 +++ um/arch/um/kernel/tt/uaccess_user.c Tue Mar 25 17:10:54 2003
30520 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
30521 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
30522 + * Licensed under the GPL
30525 +#include <setjmp.h>
30526 +#include <string.h>
30527 +#include "user_util.h"
30528 +#include "uml_uaccess.h"
30530 +#include "kern_util.h"
30532 +int __do_copy_from_user(void *to, const void *from, int n,
30533 + void **fault_addr, void **fault_catcher)
30535 + struct tt_regs save = TASK_REGS(get_current())->tt;
30536 + unsigned long fault;
30539 + fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
30540 + __do_copy, &faulted);
30541 + TASK_REGS(get_current())->tt = save;
30543 + if(!faulted) return(0);
30544 + else return(n - (fault - (unsigned long) from));
30547 +static void __do_strncpy(void *dst, const void *src, int count)
30549 + strncpy(dst, src, count);
30552 +int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
30553 + void **fault_addr, void **fault_catcher)
30555 + struct tt_regs save = TASK_REGS(get_current())->tt;
30556 + unsigned long fault;
30559 + fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
30560 + __do_strncpy, &faulted);
30561 + TASK_REGS(get_current())->tt = save;
30563 + if(!faulted) return(strlen(dst));
30567 +static void __do_clear(void *to, const void *from, int n)
30569 + memset(to, 0, n);
30572 +int __do_clear_user(void *mem, unsigned long len,
30573 + void **fault_addr, void **fault_catcher)
30575 + struct tt_regs save = TASK_REGS(get_current())->tt;
30576 + unsigned long fault;
30579 + fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
30580 + __do_clear, &faulted);
30581 + TASK_REGS(get_current())->tt = save;
30583 + if(!faulted) return(0);
30584 + else return(len - (fault - (unsigned long) mem));
30587 +int __do_strnlen_user(const char *str, unsigned long n,
30588 + void **fault_addr, void **fault_catcher)
30590 + struct tt_regs save = TASK_REGS(get_current())->tt;
30592 + unsigned long *faddrp = (unsigned long *)fault_addr;
30595 + *fault_catcher = &jbuf;
30596 + if(setjmp(jbuf) == 0){
30597 + ret = strlen(str) + 1;
30600 + ret = *faddrp - (unsigned long) str;
30602 + *fault_addr = NULL;
30603 + *fault_catcher = NULL;
30605 + TASK_REGS(get_current())->tt = save;
30610 + * Overrides for Emacs so that we follow Linus's tabbing style.
30611 + * Emacs will notice this stuff at the end of the file and automatically
30612 + * adjust the settings for this buffer only. This must remain at the end
30614 + * ---------------------------------------------------------------------------
30615 + * Local variables:
30616 + * c-file-style: "linux"
30619 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/unmap.c um/arch/um/kernel/tt/unmap.c
30620 --- orig/arch/um/kernel/tt/unmap.c Wed Dec 31 19:00:00 1969
30621 +++ um/arch/um/kernel/tt/unmap.c Wed Dec 11 10:42:21 2002
30624 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
30625 + * Licensed under the GPL
30628 +#include <sys/mman.h>
30630 +int switcheroo(int fd, int prot, void *from, void *to, int size)
30632 + if(munmap(to, size) < 0){
30635 + if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
30638 + if(munmap(from, size) < 0){
30645 + * Overrides for Emacs so that we follow Linus's tabbing style.
30646 + * Emacs will notice this stuff at the end of the file and automatically
30647 + * adjust the settings for this buffer only. This must remain at the end
30649 + * ---------------------------------------------------------------------------
30650 + * Local variables:
30651 + * c-file-style: "linux"
30654 diff -Naur -X ../exclude-files orig/arch/um/kernel/tty_log.c um/arch/um/kernel/tty_log.c
30655 --- orig/arch/um/kernel/tty_log.c Wed Dec 31 19:00:00 1969
30656 +++ um/arch/um/kernel/tty_log.c Wed Apr 16 16:35:20 2003
30659 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and
30660 + * geoffrey hing <ghing@net.ohio-state.edu>
30661 + * Licensed under the GPL
30664 +#include <errno.h>
30665 +#include <string.h>
30666 +#include <stdio.h>
30667 +#include <stdlib.h>
30668 +#include <unistd.h>
30669 +#include <fcntl.h>
30670 +#include <sys/time.h>
30673 +#include "kern_util.h"
30676 +#define TTY_LOG_DIR "./"
30678 +/* Set early in boot and then unchanged */
30679 +static char *tty_log_dir = TTY_LOG_DIR;
30680 +static int tty_log_fd = -1;
30682 +#define TTY_LOG_OPEN 1
30683 +#define TTY_LOG_CLOSE 2
30684 +#define TTY_LOG_WRITE 3
30685 +#define TTY_LOG_EXEC 4
30687 +#define TTY_READ 1
30688 +#define TTY_WRITE 2
30690 +struct tty_log_buf {
30692 + unsigned long tty;
30695 + unsigned long sec;
30696 + unsigned long usec;
30699 +int open_tty_log(void *tty, void *current_tty)
30701 + struct timeval tv;
30702 + struct tty_log_buf data;
30703 + char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
30706 + gettimeofday(&tv, NULL);
30707 + if(tty_log_fd != -1){
30708 + data = ((struct tty_log_buf) { .what = TTY_LOG_OPEN,
30709 + .tty = (unsigned long) tty,
30710 + .len = sizeof(current_tty),
30712 + .sec = tv.tv_sec,
30713 + .usec = tv.tv_usec } );
30714 + write(tty_log_fd, &data, sizeof(data));
30715 + write(tty_log_fd, ¤t_tty, data.len);
30716 + return(tty_log_fd);
30719 + sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
30720 + (unsigned int) tv.tv_usec);
30722 + fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
30725 + printk("open_tty_log : couldn't open '%s', errno = %d\n",
30731 +void close_tty_log(int fd, void *tty)
30733 + struct tty_log_buf data;
30734 + struct timeval tv;
30736 + if(tty_log_fd != -1){
30737 + gettimeofday(&tv, NULL);
30738 + data = ((struct tty_log_buf) { .what = TTY_LOG_CLOSE,
30739 + .tty = (unsigned long) tty,
30742 + .sec = tv.tv_sec,
30743 + .usec = tv.tv_usec } );
30744 + write(tty_log_fd, &data, sizeof(data));
30750 +static int log_chunk(int fd, char *buf, int len)
30752 + int total = 0, try, missed, n;
30756 + try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
30757 + missed = copy_from_user_proc(chunk, buf, try);
30759 + n = write(fd, chunk, try);
30773 +int write_tty_log(int fd, char *buf, int len, void *tty, int is_read)
30775 + struct timeval tv;
30776 + struct tty_log_buf data;
30779 + if(fd == tty_log_fd){
30780 + gettimeofday(&tv, NULL);
30781 + direction = is_read ? TTY_READ : TTY_WRITE;
30782 + data = ((struct tty_log_buf) { .what = TTY_LOG_WRITE,
30783 + .tty = (unsigned long) tty,
30785 + .direction = direction,
30786 + .sec = tv.tv_sec,
30787 + .usec = tv.tv_usec } );
30788 + write(tty_log_fd, &data, sizeof(data));
30791 + return(log_chunk(fd, buf, len));
30794 +void log_exec(char **argv, void *tty)
30796 + struct timeval tv;
30797 + struct tty_log_buf data;
30801 + if(tty_log_fd == -1) return;
30803 + gettimeofday(&tv, NULL);
30806 + for(ptr = argv; ; ptr++){
30807 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
30809 + if(arg == NULL) break;
30810 + len += strlen_user_proc(arg);
30813 + data = ((struct tty_log_buf) { .what = TTY_LOG_EXEC,
30814 + .tty = (unsigned long) tty,
30817 + .sec = tv.tv_sec,
30818 + .usec = tv.tv_usec } );
30819 + write(tty_log_fd, &data, sizeof(data));
30821 + for(ptr = argv; ; ptr++){
30822 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
30824 + if(arg == NULL) break;
30825 + log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
30829 +static int __init set_tty_log_dir(char *name, int *add)
30831 + tty_log_dir = name;
30835 +__uml_setup("tty_log_dir=", set_tty_log_dir,
30836 +"tty_log_dir=<directory>\n"
30837 +" This is used to specify the directory where the logs of all pty\n"
30838 +" data from this UML machine will be written.\n\n"
30841 +static int __init set_tty_log_fd(char *name, int *add)
30845 + tty_log_fd = strtoul(name, &end, 0);
30846 + if((*end != '\0') || (end == name)){
30847 + printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
30853 +__uml_setup("tty_log_fd=", set_tty_log_fd,
30854 +"tty_log_fd=<fd>\n"
30855 +" This is used to specify a preconfigured file descriptor to which all\n"
30856 +" tty data will be written. Preconfigure the descriptor with something\n"
30857 +" like '10>tty_log tty_log_fd=10'.\n\n"
30862 + * Overrides for Emacs so that we follow Linus's tabbing style.
30863 + * Emacs will notice this stuff at the end of the file and automatically
30864 + * adjust the settings for this buffer only. This must remain at the end
30866 + * ---------------------------------------------------------------------------
30867 + * Local variables:
30868 + * c-file-style: "linux"
30871 diff -Naur -X ../exclude-files orig/arch/um/kernel/uaccess_user.c um/arch/um/kernel/uaccess_user.c
30872 --- orig/arch/um/kernel/uaccess_user.c Wed Dec 31 19:00:00 1969
30873 +++ um/arch/um/kernel/uaccess_user.c Tue Mar 25 17:06:05 2003
30876 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
30877 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
30878 + * Licensed under the GPL
30881 +#include <setjmp.h>
30882 +#include <string.h>
30884 +/* These are here rather than tt/uaccess.c because skas mode needs them in
30885 + * order to do SIGBUS recovery when a tmpfs mount runs out of room.
30888 +unsigned long __do_user_copy(void *to, const void *from, int n,
30889 + void **fault_addr, void **fault_catcher,
30890 + void (*op)(void *to, const void *from,
30891 + int n), int *faulted_out)
30893 + unsigned long *faddrp = (unsigned long *) fault_addr, ret;
30896 + *fault_catcher = &jbuf;
30897 + if(setjmp(jbuf) == 0){
30898 + (*op)(to, from, n);
30900 + *faulted_out = 0;
30904 + *faulted_out = 1;
30906 + *fault_addr = NULL;
30907 + *fault_catcher = NULL;
30911 +void __do_copy(void *to, const void *from, int n)
30913 + memcpy(to, from, n);
30917 +int __do_copy_to_user(void *to, const void *from, int n,
30918 + void **fault_addr, void **fault_catcher)
30920 + unsigned long fault;
30923 + fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
30924 + __do_copy, &faulted);
30925 + if(!faulted) return(0);
30926 + else return(n - (fault - (unsigned long) to));
30930 + * Overrides for Emacs so that we follow Linus's tabbing style.
30931 + * Emacs will notice this stuff at the end of the file and automatically
30932 + * adjust the settings for this buffer only. This must remain at the end
30934 + * ---------------------------------------------------------------------------
30935 + * Local variables:
30936 + * c-file-style: "linux"
30939 diff -Naur -X ../exclude-files orig/arch/um/kernel/um_arch.c um/arch/um/kernel/um_arch.c
30940 --- orig/arch/um/kernel/um_arch.c Wed Dec 31 19:00:00 1969
30941 +++ um/arch/um/kernel/um_arch.c Thu Mar 6 19:06:09 2003
30944 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
30945 + * Licensed under the GPL
30948 +#include "linux/config.h"
30949 +#include "linux/kernel.h"
30950 +#include "linux/sched.h"
30951 +#include "linux/notifier.h"
30952 +#include "linux/mm.h"
30953 +#include "linux/types.h"
30954 +#include "linux/tty.h"
30955 +#include "linux/init.h"
30956 +#include "linux/bootmem.h"
30957 +#include "linux/spinlock.h"
30958 +#include "linux/utsname.h"
30959 +#include "linux/sysrq.h"
30960 +#include "linux/seq_file.h"
30961 +#include "linux/delay.h"
30962 +#include "asm/page.h"
30963 +#include "asm/pgtable.h"
30964 +#include "asm/ptrace.h"
30965 +#include "asm/elf.h"
30966 +#include "asm/user.h"
30967 +#include "ubd_user.h"
30968 +#include "asm/current.h"
30969 +#include "user_util.h"
30970 +#include "kern_util.h"
30972 +#include "mprot.h"
30973 +#include "mem_user.h"
30976 +#include "initrd.h"
30979 +#include "choose-mode.h"
30980 +#include "mode_kern.h"
30983 +#define DEFAULT_COMMAND_LINE "root=/dev/ubd0"
30985 +struct cpuinfo_um boot_cpu_data = {
30986 + .loops_per_jiffy = 0,
30987 + .pgd_quick = NULL,
30988 + .pmd_quick = NULL,
30989 + .pte_quick = NULL,
30990 + .pgtable_cache_sz = 0,
30991 + .ipi_pipe = { -1, -1 }
30994 +unsigned long thread_saved_pc(struct thread_struct *thread)
30996 + return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
31000 +static int show_cpuinfo(struct seq_file *m, void *v)
31004 + index = (struct cpuinfo_um *)v - cpu_data;
31006 + if (!(cpu_online_map & (1 << index)))
31010 + seq_printf(m, "processor\t: %d\n", index);
31011 + seq_printf(m, "vendor_id\t: User Mode Linux\n");
31012 + seq_printf(m, "model name\t: UML\n");
31013 + seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
31014 + seq_printf(m, "host\t\t: %s\n", host_info);
31015 + seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
31016 + loops_per_jiffy/(500000/HZ),
31017 + (loops_per_jiffy/(5000/HZ)) % 100);
31022 +static void *c_start(struct seq_file *m, loff_t *pos)
31024 + return *pos < NR_CPUS ? cpu_data + *pos : NULL;
31027 +static void *c_next(struct seq_file *m, void *v, loff_t *pos)
31030 + return c_start(m, pos);
31033 +static void c_stop(struct seq_file *m, void *v)
31037 +struct seq_operations cpuinfo_op = {
31038 + .start = c_start,
31041 + .show = show_cpuinfo,
31044 +pte_t * __bad_pagetable(void)
31046 + panic("Someone should implement __bad_pagetable");
31050 +/* Set in linux_main */
31051 +unsigned long host_task_size;
31052 +unsigned long task_size;
31053 +unsigned long uml_start;
31055 +/* Set in early boot */
31056 +unsigned long uml_physmem;
31057 +unsigned long uml_reserved;
31058 +unsigned long start_vm;
31059 +unsigned long end_vm;
31062 +#ifdef CONFIG_MODE_TT
31063 +/* Pointer set in linux_main, the array itself is private to each thread,
31064 + * and changed at address space creation time so this poses no concurrency
31067 +static char *argv1_begin = NULL;
31068 +static char *argv1_end = NULL;
31071 +/* Set in early boot */
31072 +static int have_root __initdata = 0;
31073 +long physmem_size = 32 * 1024 * 1024;
31075 +void set_cmdline(char *cmd)
31077 +#ifdef CONFIG_MODE_TT
31078 + char *umid, *ptr;
31080 + if(CHOOSE_MODE(honeypot, 0)) return;
31082 + umid = get_umid(1);
31083 + if(umid != NULL){
31084 + snprintf(argv1_begin,
31085 + (argv1_end - argv1_begin) * sizeof(*ptr),
31087 + ptr = &argv1_begin[strlen(argv1_begin)];
31089 + else ptr = argv1_begin;
31091 + snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
31092 + memset(argv1_begin + strlen(argv1_begin), '\0',
31093 + argv1_end - argv1_begin - strlen(argv1_begin));
31097 +static char *usage_string =
31098 +"User Mode Linux v%s\n"
31099 +" available at http://user-mode-linux.sourceforge.net/\n\n";
31101 +static int __init uml_version_setup(char *line, int *add)
31103 + printf("%s\n", system_utsname.release);
31107 +__uml_setup("--version", uml_version_setup,
31109 +" Prints the version number of the kernel.\n\n"
31112 +static int __init uml_root_setup(char *line, int *add)
31118 +__uml_setup("root=", uml_root_setup,
31119 +"root=<file containing the root fs>\n"
31120 +" This is actually used by the generic kernel in exactly the same\n"
31121 +" way as in any other kernel. If you configure a number of block\n"
31122 +" devices and want to boot off something other than ubd0, you \n"
31123 +" would use something like:\n"
31124 +" root=/dev/ubd5\n\n"
31128 +static int __init uml_ncpus_setup(char *line, int *add)
31130 + if (!sscanf(line, "%d", &ncpus)) {
31131 + printf("Couldn't parse [%s]\n", line);
31138 +__uml_setup("ncpus=", uml_ncpus_setup,
31139 +"ncpus=<# of desired CPUs>\n"
31140 +" This tells an SMP kernel how many virtual processors to start.\n\n"
31146 +#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
31147 +#define DEFAULT_TT 0
31149 +static int __init mode_tt_setup(char *line, int *add)
31156 +#ifdef CONFIG_MODE_SKAS
31158 +#define DEFAULT_TT 0
31160 +static int __init mode_tt_setup(char *line, int *add)
31162 + printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
31167 +#ifdef CONFIG_MODE_TT
31169 +#define DEFAULT_TT 1
31171 +static int __init mode_tt_setup(char *line, int *add)
31173 + printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
31179 +#error Either CONFIG_MODE_TT or CONFIG_MODE_SKAS must be enabled
31185 +__uml_setup("mode=tt", mode_tt_setup,
31187 +" When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n"
31188 +" forces UML to run in tt (tracing thread) mode. It is not the default\n"
31189 +" because it's slower and less secure than skas mode.\n\n"
31192 +int mode_tt = DEFAULT_TT;
31194 +static int __init Usage(char *line, int *add)
31198 + printf(usage_string, system_utsname.release);
31199 + p = &__uml_help_start;
31200 + while (p < &__uml_help_end) {
31201 + printf("%s", *p);
31207 +__uml_setup("--help", Usage,
31209 +" Prints this message.\n\n"
31212 +static int __init uml_checksetup(char *line, int *add)
31214 + struct uml_param *p;
31216 + p = &__uml_setup_start;
31217 + while(p < &__uml_setup_end) {
31220 + n = strlen(p->str);
31221 + if(!strncmp(line, p->str, n)){
31222 + if (p->setup_func(line + n, add)) return 1;
31229 +static void __init uml_postsetup(void)
31233 + p = &__uml_postsetup_start;
31234 + while(p < &__uml_postsetup_end){
31241 +/* Set during early boot */
31242 +unsigned long brk_start;
31243 +static struct vm_reserved kernel_vm_reserved;
31245 +#define MIN_VMALLOC (32 * 1024 * 1024)
31247 +int linux_main(int argc, char **argv)
31249 + unsigned long avail;
31250 + unsigned long virtmem_size, max_physmem;
31251 + unsigned int i, add, err;
31253 + for (i = 1; i < argc; i++){
31254 + if((i == 1) && (argv[i][0] == ' ')) continue;
31256 + uml_checksetup(argv[i], &add);
31257 + if(add) add_arg(saved_command_line, argv[i]);
31259 + if(have_root == 0) add_arg(saved_command_line, DEFAULT_COMMAND_LINE);
31261 + mode_tt = force_tt ? 1 : !can_do_skas();
31262 + uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
31263 + &host_task_size, &task_size);
31265 + brk_start = (unsigned long) sbrk(0);
31266 + CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
31268 + uml_physmem = uml_start;
31270 + /* Reserve up to 4M after the current brk */
31271 + uml_reserved = ROUND_4M(brk_start) + (1 << 22);
31273 + setup_machinename(system_utsname.machine);
31275 +#ifdef CONFIG_MODE_TT
31276 + argv1_begin = argv[1];
31277 + argv1_end = &argv[1][strlen(argv[1])];
31280 + set_usable_vm(uml_physmem, get_kmem_end());
31283 + max_physmem = get_kmem_end() - uml_physmem - MIN_VMALLOC;
31284 + if(physmem_size > max_physmem){
31285 + highmem = physmem_size - max_physmem;
31286 + physmem_size -= highmem;
31287 +#ifndef CONFIG_HIGHMEM
31289 + printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
31290 + "to %ld bytes\n", physmem_size);
31294 + high_physmem = uml_physmem + physmem_size;
31295 + high_memory = (void *) high_physmem;
31297 + start_vm = VMALLOC_START;
31299 + setup_physmem(uml_physmem, uml_reserved, physmem_size);
31300 + virtmem_size = physmem_size;
31301 + avail = get_kmem_end() - start_vm;
31302 + if(physmem_size > avail) virtmem_size = avail;
31303 + end_vm = start_vm + virtmem_size;
31305 + if(virtmem_size < physmem_size)
31306 + printf("Kernel virtual memory size shrunk to %ld bytes\n",
31309 + err = reserve_vm(high_physmem, end_vm, &kernel_vm_reserved);
31311 + printf("Failed to reserve VM area for kernel VM\n");
31317 + init_task.thread.kernel_stack = (unsigned long) &init_task +
31320 + task_protections((unsigned long) &init_task);
31321 + os_flush_stdout();
31323 + return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
31326 +static int panic_exit(struct notifier_block *self, unsigned long unused1,
31329 +#ifdef CONFIG_SYSRQ
31330 + handle_sysrq('p', ¤t->thread.regs, NULL, NULL);
31336 +static struct notifier_block panic_exit_notifier = {
31337 + .notifier_call = panic_exit,
31342 +void __init setup_arch(char **cmdline_p)
31344 + notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
31346 + strcpy(command_line, saved_command_line);
31347 + *cmdline_p = command_line;
31348 + setup_hostinfo();
31351 +void __init check_bugs(void)
31353 + arch_check_bugs();
31359 + * Overrides for Emacs so that we follow Linus's tabbing style.
31360 + * Emacs will notice this stuff at the end of the file and automatically
31361 + * adjust the settings for this buffer only. This must remain at the end
31363 + * ---------------------------------------------------------------------------
31364 + * Local variables:
31365 + * c-file-style: "linux"
31368 diff -Naur -X ../exclude-files orig/arch/um/kernel/umid.c um/arch/um/kernel/umid.c
31369 --- orig/arch/um/kernel/umid.c Wed Dec 31 19:00:00 1969
31370 +++ um/arch/um/kernel/umid.c Mon Feb 24 23:11:23 2003
31373 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
31374 + * Licensed under the GPL
31377 +#include <stdio.h>
31378 +#include <unistd.h>
31379 +#include <fcntl.h>
31380 +#include <errno.h>
31381 +#include <string.h>
31382 +#include <stdlib.h>
31383 +#include <dirent.h>
31384 +#include <signal.h>
31385 +#include <sys/stat.h>
31386 +#include <sys/param.h>
31391 +#include "user_util.h"
31392 +#include "choose-mode.h"
31394 +#define UMID_LEN 64
31395 +#define UML_DIR "~/.uml/"
31397 +/* Changed by set_umid and make_umid, which are run early in boot */
31398 +static char umid[UMID_LEN] = { 0 };
31400 +/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
31401 +static char *uml_dir = UML_DIR;
31403 +/* Changed by set_umid */
31404 +static int umid_is_random = 1;
31405 +static int umid_inited = 0;
31407 +static int make_umid(int (*printer)(const char *fmt, ...));
31409 +static int __init set_umid(char *name, int is_random,
31410 + int (*printer)(const char *fmt, ...))
31413 + (*printer)("Unique machine name can't be set twice\n");
31417 + if(strlen(name) > UMID_LEN - 1)
31418 + (*printer)("Unique machine name is being truncated to %s "
31419 + "characters\n", UMID_LEN);
31420 + strncpy(umid, name, UMID_LEN - 1);
31421 + umid[UMID_LEN - 1] = '\0';
31423 + umid_is_random = is_random;
31428 +static int __init set_umid_arg(char *name, int *add)
31430 + return(set_umid(name, 0, printf));
31433 +__uml_setup("umid=", set_umid_arg,
31435 +" This is used to assign a unique identity to this UML machine and\n"
31436 +" is used for naming the pid file and management console socket.\n\n"
31439 +int __init umid_file_name(char *name, char *buf, int len)
31443 + if(!umid_inited && make_umid(printk)) return(-1);
31445 + n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
31447 + printk("umid_file_name : buffer too short\n");
31451 + sprintf(buf, "%s%s/%s", uml_dir, umid, name);
31455 +extern int tracing_pid;
31457 +static int __init create_pid_file(void)
31459 + char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
31460 + char pid[sizeof("nnnnn\0")];
31463 + if(umid_file_name("pid", file, sizeof(file))) return 0;
31465 + fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
31468 + printf("Open of machine pid file \"%s\" failed - "
31469 + "errno = %d\n", file, -fd);
31473 + sprintf(pid, "%d\n", os_getpid());
31474 + if(write(fd, pid, strlen(pid)) != strlen(pid))
31475 + printf("Write of pid file failed - errno = %d\n", errno);
31480 +static int actually_do_remove(char *dir)
31483 + struct dirent *ent;
31487 + if((directory = opendir(dir)) == NULL){
31488 + printk("actually_do_remove : couldn't open directory '%s', "
31489 + "errno = %d\n", dir, errno);
31492 + while((ent = readdir(directory)) != NULL){
31493 + if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
31495 + len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
31496 + if(len > sizeof(file)){
31497 + printk("Not deleting '%s' from '%s' - name too long\n",
31498 + ent->d_name, dir);
31501 + sprintf(file, "%s/%s", dir, ent->d_name);
31502 + if(unlink(file) < 0){
31503 + printk("actually_do_remove : couldn't remove '%s' "
31504 + "from '%s', errno = %d\n", ent->d_name, dir,
31509 + if(rmdir(dir) < 0){
31510 + printk("actually_do_remove : couldn't rmdir '%s', "
31511 + "errno = %d\n", dir, errno);
31517 +void remove_umid_dir(void)
31519 + char dir[strlen(uml_dir) + UMID_LEN + 1];
31520 + if(!umid_inited) return;
31522 + sprintf(dir, "%s%s", uml_dir, umid);
31523 + actually_do_remove(dir);
31526 +char *get_umid(int only_if_set)
31528 + if(only_if_set && umid_is_random) return(NULL);
31532 +int not_dead_yet(char *dir)
31534 + char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
31535 + char pid[sizeof("nnnnn\0")], *end;
31538 + sprintf(file, "%s/pid", dir);
31540 + if((fd = os_open_file(file, of_read(OPENFLAGS()), 0)) < 0){
31541 + if(fd != -ENOENT){
31542 + printk("not_dead_yet : couldn't open pid file '%s', "
31543 + "errno = %d\n", file, -fd);
31549 + if(read(fd, pid, sizeof(pid)) < 0){
31550 + printk("not_dead_yet : couldn't read pid file '%s', "
31551 + "errno = %d\n", file, errno);
31554 + p = strtoul(pid, &end, 0);
31556 + printk("not_dead_yet : couldn't parse pid file '%s', "
31557 + "errno = %d\n", file, errno);
31560 + if(((kill(p, 0) < 0) && (errno == ESRCH)) ||
31561 + (p == CHOOSE_MODE(tracing_pid, os_getpid())))
31564 + if(!dead) return(1);
31565 + return(actually_do_remove(dir));
31568 +static int __init set_uml_dir(char *name, int *add)
31570 + if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
31571 + uml_dir = malloc(strlen(name) + 1);
31572 + if(uml_dir == NULL){
31573 + printf("Failed to malloc uml_dir - error = %d\n",
31578 + sprintf(uml_dir, "%s/", name);
31580 + else uml_dir = name;
31584 +static int __init make_uml_dir(void)
31586 + char dir[MAXPATHLEN + 1] = { '\0' };
31589 + if(*uml_dir == '~'){
31590 + char *home = getenv("HOME");
31592 + if(home == NULL){
31593 + printf("make_uml_dir : no value in environment for "
31597 + strncpy(dir, home, sizeof(dir));
31600 + len = strlen(dir);
31601 + strncat(dir, uml_dir, sizeof(dir) - len);
31602 + len = strlen(dir);
31603 + if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){
31605 + dir[len + 1] = '\0';
31608 + if((uml_dir = malloc(strlen(dir) + 1)) == NULL){
31609 + printf("make_uml_dir : malloc failed, errno = %d\n", errno);
31612 + strcpy(uml_dir, dir);
31614 + if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
31615 + printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
31621 +static int __init make_umid(int (*printer)(const char *fmt, ...))
31624 + char tmp[strlen(uml_dir) + UMID_LEN + 1];
31626 + strncpy(tmp, uml_dir, sizeof(tmp) - 1);
31627 + tmp[sizeof(tmp) - 1] = '\0';
31629 + if(!umid_inited){
31630 + strcat(tmp, "XXXXXX");
31631 + fd = mkstemp(tmp);
31633 + (*printer)("make_umid - mkstemp failed, errno = %d\n",
31639 + /* There's a nice tiny little race between this unlink and
31640 + * the mkdir below. It'd be nice if there were a mkstemp
31641 + * for directories.
31644 + set_umid(&tmp[strlen(uml_dir)], 1, printer);
31647 + sprintf(tmp, "%s%s", uml_dir, umid);
31649 + if((err = mkdir(tmp, 0777)) < 0){
31650 + if(errno == EEXIST){
31651 + if(not_dead_yet(tmp)){
31652 + (*printer)("umid '%s' is in use\n", umid);
31655 + err = mkdir(tmp, 0777);
31659 + (*printer)("Failed to create %s - errno = %d\n", umid, errno);
31666 +__uml_setup("uml_dir=", set_uml_dir,
31667 +"uml_dir=<directory>\n"
31668 +" The location to place the pid and umid files.\n\n"
31671 +__uml_postsetup(make_uml_dir);
31673 +static int __init make_umid_setup(void)
31675 + return(make_umid(printf));
31678 +__uml_postsetup(make_umid_setup);
31679 +__uml_postsetup(create_pid_file);
31682 + * Overrides for Emacs so that we follow Linus's tabbing style.
31683 + * Emacs will notice this stuff at the end of the file and automatically
31684 + * adjust the settings for this buffer only. This must remain at the end
31686 + * ---------------------------------------------------------------------------
31687 + * Local variables:
31688 + * c-file-style: "linux"
31691 diff -Naur -X ../exclude-files orig/arch/um/kernel/user_syms.c um/arch/um/kernel/user_syms.c
31692 --- orig/arch/um/kernel/user_syms.c Wed Dec 31 19:00:00 1969
31693 +++ um/arch/um/kernel/user_syms.c Wed Oct 23 21:08:04 2002
31695 +#include <stdio.h>
31696 +#include <unistd.h>
31697 +#include <fcntl.h>
31698 +#include <dirent.h>
31699 +#include <errno.h>
31700 +#include <utime.h>
31701 +#include <string.h>
31702 +#include <sys/stat.h>
31703 +#include <sys/vfs.h>
31704 +#include <sys/ioctl.h>
31705 +#include "user_util.h"
31706 +#include "mem_user.h"
31708 +/* XXX All the __CONFIG_* stuff is broken because this file can't include
31712 +/* Had to steal this from linux/module.h because that file can't be included
31713 + * since this includes various user-level headers.
31716 +struct module_symbol
31718 + unsigned long value;
31719 + const char *name;
31722 +/* Indirect stringification. */
31724 +#define __MODULE_STRING_1(x) #x
31725 +#define __MODULE_STRING(x) __MODULE_STRING_1(x)
31727 +#if !defined(__AUTOCONF_INCLUDED__)
31729 +#define __EXPORT_SYMBOL(sym,str) error config_must_be_included_before_module
31730 +#define EXPORT_SYMBOL(var) error config_must_be_included_before_module
31731 +#define EXPORT_SYMBOL_NOVERS(var) error config_must_be_included_before_module
31733 +#elif !defined(__CONFIG_MODULES__)
31735 +#define __EXPORT_SYMBOL(sym,str)
31736 +#define EXPORT_SYMBOL(var)
31737 +#define EXPORT_SYMBOL_NOVERS(var)
31741 +#define __EXPORT_SYMBOL(sym, str) \
31742 +const char __kstrtab_##sym[] \
31743 +__attribute__((section(".kstrtab"))) = str; \
31744 +const struct module_symbol __ksymtab_##sym \
31745 +__attribute__((section("__ksymtab"))) = \
31746 +{ (unsigned long)&sym, __kstrtab_##sym }
31748 +#if defined(__MODVERSIONS__) || !defined(__CONFIG_MODVERSIONS__)
31749 +#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var))
31751 +#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var)))
31754 +#define EXPORT_SYMBOL_NOVERS(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var))
31758 +EXPORT_SYMBOL(__errno_location);
31760 +EXPORT_SYMBOL(access);
31761 +EXPORT_SYMBOL(open);
31762 +EXPORT_SYMBOL(open64);
31763 +EXPORT_SYMBOL(close);
31764 +EXPORT_SYMBOL(read);
31765 +EXPORT_SYMBOL(write);
31766 +EXPORT_SYMBOL(dup2);
31767 +EXPORT_SYMBOL(__xstat);
31768 +EXPORT_SYMBOL(__lxstat);
31769 +EXPORT_SYMBOL(__lxstat64);
31770 +EXPORT_SYMBOL(lseek);
31771 +EXPORT_SYMBOL(lseek64);
31772 +EXPORT_SYMBOL(chown);
31773 +EXPORT_SYMBOL(truncate);
31774 +EXPORT_SYMBOL(utime);
31775 +EXPORT_SYMBOL(chmod);
31776 +EXPORT_SYMBOL(rename);
31777 +EXPORT_SYMBOL(__xmknod);
31779 +EXPORT_SYMBOL(symlink);
31780 +EXPORT_SYMBOL(link);
31781 +EXPORT_SYMBOL(unlink);
31782 +EXPORT_SYMBOL(readlink);
31784 +EXPORT_SYMBOL(mkdir);
31785 +EXPORT_SYMBOL(rmdir);
31786 +EXPORT_SYMBOL(opendir);
31787 +EXPORT_SYMBOL(readdir);
31788 +EXPORT_SYMBOL(closedir);
31789 +EXPORT_SYMBOL(seekdir);
31790 +EXPORT_SYMBOL(telldir);
31792 +EXPORT_SYMBOL(ioctl);
31794 +extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes,
31795 + __off64_t __offset);
31796 +extern ssize_t pwrite64 (int __fd, __const void *__buf, size_t __n,
31797 + __off64_t __offset);
31798 +EXPORT_SYMBOL(pread64);
31799 +EXPORT_SYMBOL(pwrite64);
31801 +EXPORT_SYMBOL(statfs);
31802 +EXPORT_SYMBOL(statfs64);
31804 +EXPORT_SYMBOL(memcpy);
31805 +EXPORT_SYMBOL(getuid);
31807 +EXPORT_SYMBOL(memset);
31808 +EXPORT_SYMBOL(strstr);
31810 +EXPORT_SYMBOL(find_iomem);
31811 diff -Naur -X ../exclude-files orig/arch/um/kernel/user_util.c um/arch/um/kernel/user_util.c
31812 --- orig/arch/um/kernel/user_util.c Wed Dec 31 19:00:00 1969
31813 +++ um/arch/um/kernel/user_util.c Wed Apr 23 20:41:54 2003
31816 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
31817 + * Licensed under the GPL
31820 +#include <stdio.h>
31821 +#include <stdlib.h>
31822 +#include <fcntl.h>
31823 +#include <unistd.h>
31824 +#include <limits.h>
31825 +#include <sys/mman.h>
31826 +#include <sys/stat.h>
31827 +#include <sys/ptrace.h>
31828 +#include <sys/utsname.h>
31829 +#include <sys/param.h>
31830 +#include <sys/time.h>
31831 +#include "asm/types.h"
31832 +#include <ctype.h>
31833 +#include <signal.h>
31835 +#include <errno.h>
31836 +#include <stdarg.h>
31837 +#include <sched.h>
31838 +#include <termios.h>
31839 +#include <string.h>
31840 +#include "user_util.h"
31841 +#include "kern_util.h"
31843 +#include "mem_user.h"
31845 +#include "helper.h"
31846 +#include "uml-config.h"
31848 +#define COMMAND_LINE_SIZE _POSIX_ARG_MAX
31850 +/* Changed in linux_main and setup_arch, which run before SMP is started */
31851 +char saved_command_line[COMMAND_LINE_SIZE] = { 0 };
31852 +char command_line[COMMAND_LINE_SIZE] = { 0 };
31854 +void add_arg(char *cmd_line, char *arg)
31856 + if (strlen(cmd_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
31857 + printf("add_arg: Too much command line!\n");
31860 + if(strlen(cmd_line) > 0) strcat(cmd_line, " ");
31861 + strcat(cmd_line, arg);
31866 + while(1) sleep(1000000);
31869 +void stack_protections(unsigned long address)
31871 + int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
31873 + if(mprotect((void *) address, page_size(), prot) < 0)
31874 + panic("protecting stack failed, errno = %d", errno);
31877 +void task_protections(unsigned long address)
31879 + unsigned long guard = address + page_size();
31880 + unsigned long stack = guard + page_size();
31881 + int prot = 0, pages;
31883 + if(mprotect((void *) guard, page_size(), prot) < 0)
31884 + panic("protecting guard page failed, errno = %d", errno);
31886 + pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
31887 + prot = PROT_READ | PROT_WRITE | PROT_EXEC;
31888 + if(mprotect((void *) stack, pages * page_size(), prot) < 0)
31889 + panic("protecting stack failed, errno = %d", errno);
31892 +int wait_for_stop(int pid, int sig, int cont_type, void *relay)
31894 + sigset_t *relay_signals = relay;
31898 + if(((ret = waitpid(pid, &status, WUNTRACED)) < 0) ||
31899 + !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
31901 + if(errno == EINTR) continue;
31902 + printk("wait failed, errno = %d\n",
31905 + else if(WIFEXITED(status))
31906 + printk("process exited with status %d\n",
31907 + WEXITSTATUS(status));
31908 + else if(WIFSIGNALED(status))
31909 + printk("process exited with signal %d\n",
31910 + WTERMSIG(status));
31911 + else if((WSTOPSIG(status) == SIGVTALRM) ||
31912 + (WSTOPSIG(status) == SIGALRM) ||
31913 + (WSTOPSIG(status) == SIGIO) ||
31914 + (WSTOPSIG(status) == SIGPROF) ||
31915 + (WSTOPSIG(status) == SIGCHLD) ||
31916 + (WSTOPSIG(status) == SIGWINCH) ||
31917 + (WSTOPSIG(status) == SIGINT)){
31918 + ptrace(cont_type, pid, 0, WSTOPSIG(status));
31921 + else if((relay_signals != NULL) &&
31922 + sigismember(relay_signals, WSTOPSIG(status))){
31923 + ptrace(cont_type, pid, 0, WSTOPSIG(status));
31926 + else printk("process stopped with signal %d\n",
31927 + WSTOPSIG(status));
31928 + panic("wait_for_stop failed to wait for %d to stop "
31929 + "with %d\n", pid, sig);
31935 +int raw(int fd, int complain)
31937 + struct termios tt;
31940 + tcgetattr(fd, &tt);
31942 + err = tcsetattr(fd, TCSANOW, &tt);
31943 + if((err < 0) && complain){
31944 + printk("tcsetattr failed, errno = %d\n", errno);
31950 +void setup_machinename(char *machine_out)
31952 + struct utsname host;
31955 + strcpy(machine_out, host.machine);
31958 +char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1];
31960 +void setup_hostinfo(void)
31962 + struct utsname host;
31965 + sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename,
31966 + host.release, host.version, host.machine);
31970 + * Overrides for Emacs so that we follow Linus's tabbing style.
31971 + * Emacs will notice this stuff at the end of the file and automatically
31972 + * adjust the settings for this buffer only. This must remain at the end
31974 + * ---------------------------------------------------------------------------
31975 + * Local variables:
31976 + * c-file-style: "linux"
31979 diff -Naur -X ../exclude-files orig/arch/um/link.ld.in um/arch/um/link.ld.in
31980 --- orig/arch/um/link.ld.in Wed Dec 31 19:00:00 1969
31981 +++ um/arch/um/link.ld.in Fri Jan 17 23:11:30 2003
31983 +OUTPUT_FORMAT("ELF_FORMAT")
31984 +OUTPUT_ARCH(ELF_ARCH)
31989 + . = START() + SIZEOF_HEADERS;
31992 + __binary_start = .;
31993 +ifdef(`MODE_TT', `
31994 + .thread_private : {
31995 + __start_thread_private = .;
31998 + arch/um/kernel/tt/unmap_fin.o (.data)
31999 + __end_thread_private = .;
32002 + .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
32004 + . = ALIGN(4096); /* Init code and data */
32006 + __init_begin = .;
32007 + .text.init : { *(.text.init) }
32012 + /* .gnu.warning sections are handled specially by elf32.em. */
32014 + *(.gnu.linkonce.t*)
32016 + .fini : { *(.fini) } =0x9090
32017 + .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
32018 + .rodata1 : { *(.rodata1) }
32020 + PROVIDE (etext = .);
32023 + PROVIDE (_sdata = .);
32025 +include(`arch/um/common.ld.in')
32029 + . = ALIGN(KERNEL_STACK_SIZE); /* init_task */
32030 + *(.data.init_task)
32032 + *(.gnu.linkonce.d*)
32035 + .data1 : { *(.data1) }
32045 + .got : { *(.got.plt) *(.got) }
32046 + .dynamic : { *(.dynamic) }
32047 + /* We want the small data sections together, so single-instruction offsets
32048 + can access them all, and initialized data all before uninitialized, so
32049 + we can shorten the on-disk segment size. */
32050 + .sdata : { *(.sdata) }
32052 + PROVIDE (edata = .);
32053 + . = ALIGN(0x1000);
32057 + PROVIDE(_bss_start = .);
32068 + PROVIDE (end = .);
32069 + /* Stabs debugging sections. */
32070 + .stab 0 : { *(.stab) }
32071 + .stabstr 0 : { *(.stabstr) }
32072 + .stab.excl 0 : { *(.stab.excl) }
32073 + .stab.exclstr 0 : { *(.stab.exclstr) }
32074 + .stab.index 0 : { *(.stab.index) }
32075 + .stab.indexstr 0 : { *(.stab.indexstr) }
32076 + .comment 0 : { *(.comment) }
32078 diff -Naur -X ../exclude-files orig/arch/um/main.c um/arch/um/main.c
32079 --- orig/arch/um/main.c Wed Dec 31 19:00:00 1969
32080 +++ um/arch/um/main.c Fri Jan 17 13:22:40 2003
32083 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
32084 + * Licensed under the GPL
32087 +#include <unistd.h>
32088 +#include <stdio.h>
32089 +#include <stdlib.h>
32090 +#include <string.h>
32091 +#include <signal.h>
32092 +#include <sys/resource.h>
32093 +#include <sys/mman.h>
32094 +#include <sys/user.h>
32095 +#include <asm/page.h>
32096 +#include "user_util.h"
32097 +#include "kern_util.h"
32098 +#include "mem_user.h"
32099 +#include "signal_user.h"
32103 +#include "choose-mode.h"
32104 +#include "uml-config.h"
32106 +/* Set in set_stklim, which is called from main and __wrap_malloc.
32107 + * __wrap_malloc only calls it if main hasn't started.
32109 +unsigned long stacksizelim;
32114 +#define PGD_BOUND (4 * 1024 * 1024)
32115 +#define STACKSIZE (8 * 1024 * 1024)
32116 +#define THREAD_NAME_LEN (256)
32118 +static void set_stklim(void)
32120 + struct rlimit lim;
32122 + if(getrlimit(RLIMIT_STACK, &lim) < 0){
32123 + perror("getrlimit");
32126 + if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){
32127 + lim.rlim_cur = STACKSIZE;
32128 + if(setrlimit(RLIMIT_STACK, &lim) < 0){
32129 + perror("setrlimit");
32133 + stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1);
32136 +static __init void do_uml_initcalls(void)
32138 + initcall_t *call;
32140 + call = &__uml_initcall_start;
32141 + while (call < &__uml_initcall_end){;
32147 +static void last_ditch_exit(int sig)
32149 + CHOOSE_MODE(kmalloc_ok = 0, (void) 0);
32150 + signal(SIGINT, SIG_DFL);
32151 + signal(SIGTERM, SIG_DFL);
32152 + signal(SIGHUP, SIG_DFL);
32157 +extern int uml_exitcode;
32159 +int main(int argc, char **argv, char **envp)
32165 + /* Enable all signals except SIGIO - in some environments, we can
32166 + * enter with some signals blocked
32169 + sigemptyset(&mask);
32170 + sigaddset(&mask, SIGIO);
32171 + if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){
32172 + perror("sigprocmask");
32176 +#ifdef UML_CONFIG_MODE_TT
32177 + /* Allocate memory for thread command lines */
32178 + if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
32180 + char padding[THREAD_NAME_LEN] = {
32181 + [ 0 ... THREAD_NAME_LEN - 2] = ' ', '\0'
32184 + new_argv = malloc((argc + 2) * sizeof(char*));
32186 + perror("Allocating extended argv");
32190 + new_argv[0] = argv[0];
32191 + new_argv[1] = padding;
32193 + for(i = 2; i <= argc; i++)
32194 + new_argv[i] = argv[i - 1];
32195 + new_argv[argc + 1] = NULL;
32197 + execvp(new_argv[0], new_argv);
32198 + perror("execing with extended args");
32203 + linux_prog = argv[0];
32207 + if((new_argv = malloc((argc + 1) * sizeof(char *))) == NULL){
32208 + perror("Mallocing argv");
32211 + for(i=0;i<argc;i++){
32212 + if((new_argv[i] = strdup(argv[i])) == NULL){
32213 + perror("Mallocing an arg");
32217 + new_argv[argc] = NULL;
32219 + set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
32220 + set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
32221 + set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
32223 + do_uml_initcalls();
32224 + ret = linux_main(argc, argv);
32229 + execvp(new_argv[0], new_argv);
32230 + perror("Failed to exec kernel");
32234 + return(uml_exitcode);
32237 +#define CAN_KMALLOC() \
32238 + (kmalloc_ok && CHOOSE_MODE((getpid() != tracing_pid), 1))
32240 +extern void *__real_malloc(int);
32242 +void *__wrap_malloc(int size)
32244 + if(CAN_KMALLOC())
32245 + return(um_kmalloc(size));
32247 + return(__real_malloc(size));
32250 +void *__wrap_calloc(int n, int size)
32252 + void *ptr = __wrap_malloc(n * size);
32254 + if(ptr == NULL) return(NULL);
32255 + memset(ptr, 0, n * size);
32259 +extern void __real_free(void *);
32261 +void __wrap_free(void *ptr)
32263 + if(CAN_KMALLOC()) kfree(ptr);
32264 + else __real_free(ptr);
32268 + * Overrides for Emacs so that we follow Linus's tabbing style.
32269 + * Emacs will notice this stuff at the end of the file and automatically
32270 + * adjust the settings for this buffer only. This must remain at the end
32272 + * ---------------------------------------------------------------------------
32273 + * Local variables:
32274 + * c-file-style: "linux"
32277 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/Makefile um/arch/um/os-Linux/Makefile
32278 --- orig/arch/um/os-Linux/Makefile Wed Dec 31 19:00:00 1969
32279 +++ um/arch/um/os-Linux/Makefile Wed Oct 23 21:08:04 2002
32282 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
32283 +# Licensed under the GPL
32286 +O_TARGET = built-in.o
32288 +obj-y = file.o process.o tty.o
32290 +include $(TOPDIR)/Rules.make
32292 +$(obj-y) : %.o: %.c
32293 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
32298 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/Makefile um/arch/um/os-Linux/drivers/Makefile
32299 --- orig/arch/um/os-Linux/drivers/Makefile Wed Dec 31 19:00:00 1969
32300 +++ um/arch/um/os-Linux/drivers/Makefile Wed Oct 23 21:08:04 2002
32303 +# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
32304 +# Licensed under the GPL
32307 +O_TARGET := drivers.o
32309 +list-multi := tuntap.o ethertap.o
32311 +ethertap-objs := ethertap_kern.o ethertap_user.o
32312 +tuntap-objs := tuntap_kern.o tuntap_user.o
32315 +obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap.o
32316 +obj-$(CONFIG_UML_NET_TUNTAP) += tuntap.o
32318 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y)),$($(f)-objs))
32320 +USER_OBJS = $(filter %_user.o,$(obj-y) $(USER_SINGLE_OBJS))
32322 +include $(TOPDIR)/Rules.make
32324 +$(USER_OBJS) : %.o: %.c
32325 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
32327 +ethertap.o : $(ethertap-objs)
32329 +tuntap.o : $(tuntap-objs)
32331 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
32332 + $(LD) $(LD_RFLAG) -r -o $@ $($(patsubst %.o,%,$@)-objs)
32333 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/etap.h um/arch/um/os-Linux/drivers/etap.h
32334 --- orig/arch/um/os-Linux/drivers/etap.h Wed Dec 31 19:00:00 1969
32335 +++ um/arch/um/os-Linux/drivers/etap.h Wed Oct 23 21:08:04 2002
32338 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
32339 + * Licensed under the GPL
32342 +#include "net_user.h"
32344 +struct ethertap_data {
32352 +extern struct net_user_info ethertap_user_info;
32355 + * Overrides for Emacs so that we follow Linus's tabbing style.
32356 + * Emacs will notice this stuff at the end of the file and automatically
32357 + * adjust the settings for this buffer only. This must remain at the end
32359 + * ---------------------------------------------------------------------------
32360 + * Local variables:
32361 + * c-file-style: "linux"
32364 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_kern.c um/arch/um/os-Linux/drivers/ethertap_kern.c
32365 --- orig/arch/um/os-Linux/drivers/ethertap_kern.c Wed Dec 31 19:00:00 1969
32366 +++ um/arch/um/os-Linux/drivers/ethertap_kern.c Sun Dec 15 21:17:37 2002
32369 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
32370 + * James Leu (jleu@mindspring.net).
32371 + * Copyright (C) 2001 by various other people who didn't put their name here.
32372 + * Licensed under the GPL.
32375 +#include "linux/init.h"
32376 +#include "linux/netdevice.h"
32377 +#include "linux/etherdevice.h"
32378 +#include "linux/init.h"
32379 +#include "net_kern.h"
32380 +#include "net_user.h"
32383 +struct ethertap_init {
32388 +static void etap_init(struct net_device *dev, void *data)
32390 + struct uml_net_private *pri;
32391 + struct ethertap_data *epri;
32392 + struct ethertap_init *init = data;
32394 + init_etherdev(dev, 0);
32396 + epri = (struct ethertap_data *) pri->user;
32397 + *epri = ((struct ethertap_data)
32398 + { .dev_name = init->dev_name,
32399 + .gate_addr = init->gate_addr,
32401 + .control_fd = -1,
32404 + printk("ethertap backend - %s", epri->dev_name);
32405 + if(epri->gate_addr != NULL)
32406 + printk(", IP = %s", epri->gate_addr);
32410 +static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
32414 + *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
32415 + if(*skb == NULL) return(-ENOMEM);
32416 + len = net_recvfrom(fd, (*skb)->mac.raw,
32417 + (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
32418 + if(len <= 0) return(len);
32419 + skb_pull(*skb, 2);
32424 +static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
32426 + if(skb_headroom(*skb) < 2){
32427 + struct sk_buff *skb2;
32429 + skb2 = skb_realloc_headroom(*skb, 2);
32430 + dev_kfree_skb(*skb);
32431 + if (skb2 == NULL) return(-ENOMEM);
32434 + skb_push(*skb, 2);
32435 + return(net_send(fd, (*skb)->data, (*skb)->len));
32438 +struct net_kern_info ethertap_kern_info = {
32439 + .init = etap_init,
32440 + .protocol = eth_protocol,
32441 + .read = etap_read,
32442 + .write = etap_write,
32445 +int ethertap_setup(char *str, char **mac_out, void *data)
32447 + struct ethertap_init *init = data;
32449 + *init = ((struct ethertap_init)
32450 + { .dev_name = NULL,
32451 + .gate_addr = NULL });
32452 + if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
32453 + &init->gate_addr))
32455 + if(init->dev_name == NULL){
32456 + printk("ethertap_setup : Missing tap device name\n");
32463 +static struct transport ethertap_transport = {
32464 + .list = LIST_HEAD_INIT(ethertap_transport.list),
32465 + .name = "ethertap",
32466 + .setup = ethertap_setup,
32467 + .user = ðertap_user_info,
32468 + .kern = ðertap_kern_info,
32469 + .private_size = sizeof(struct ethertap_data),
32472 +static int register_ethertap(void)
32474 + register_transport(ðertap_transport);
32478 +__initcall(register_ethertap);
32481 + * Overrides for Emacs so that we follow Linus's tabbing style.
32482 + * Emacs will notice this stuff at the end of the file and automatically
32483 + * adjust the settings for this buffer only. This must remain at the end
32485 + * ---------------------------------------------------------------------------
32486 + * Local variables:
32487 + * c-file-style: "linux"
32490 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_user.c um/arch/um/os-Linux/drivers/ethertap_user.c
32491 --- orig/arch/um/os-Linux/drivers/ethertap_user.c Wed Dec 31 19:00:00 1969
32492 +++ um/arch/um/os-Linux/drivers/ethertap_user.c Sun Dec 15 21:17:52 2002
32495 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
32496 + * James Leu (jleu@mindspring.net).
32497 + * Copyright (C) 2001 by various other people who didn't put their name here.
32498 + * Licensed under the GPL.
32501 +#include <stdio.h>
32502 +#include <unistd.h>
32503 +#include <stddef.h>
32504 +#include <fcntl.h>
32505 +#include <stdlib.h>
32506 +#include <sys/errno.h>
32507 +#include <sys/socket.h>
32508 +#include <sys/wait.h>
32509 +#include <sys/un.h>
32510 +#include <net/if.h>
32512 +#include "kern_util.h"
32513 +#include "net_user.h"
32515 +#include "helper.h"
32518 +#define MAX_PACKET ETH_MAX_PACKET
32520 +void etap_user_init(void *data, void *dev)
32522 + struct ethertap_data *pri = data;
32527 +struct addr_change {
32528 + enum { ADD_ADDR, DEL_ADDR } what;
32529 + unsigned char addr[4];
32530 + unsigned char netmask[4];
32533 +static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
32536 + struct addr_change change;
32539 + change.what = op;
32540 + memcpy(change.addr, addr, sizeof(change.addr));
32541 + memcpy(change.netmask, netmask, sizeof(change.netmask));
32542 + if(write(fd, &change, sizeof(change)) != sizeof(change))
32543 + printk("etap_change - request failed, errno = %d\n",
32545 + output = um_kmalloc(page_size());
32546 + if(output == NULL)
32547 + printk("etap_change : Failed to allocate output buffer\n");
32548 + read_output(fd, output, page_size());
32549 + if(output != NULL){
32550 + printk("%s", output);
32555 +static void etap_open_addr(unsigned char *addr, unsigned char *netmask,
32558 + etap_change(ADD_ADDR, addr, netmask, *((int *) arg));
32561 +static void etap_close_addr(unsigned char *addr, unsigned char *netmask,
32564 + etap_change(DEL_ADDR, addr, netmask, *((int *) arg));
32567 +struct etap_pre_exec_data {
32568 + int control_remote;
32573 +static void etap_pre_exec(void *arg)
32575 + struct etap_pre_exec_data *data = arg;
32577 + dup2(data->control_remote, 1);
32578 + close(data->data_me);
32579 + close(data->control_me);
32582 +static int etap_tramp(char *dev, char *gate, int control_me,
32583 + int control_remote, int data_me, int data_remote)
32585 + struct etap_pre_exec_data pe_data;
32586 + int pid, status, err;
32587 + char version_buf[sizeof("nnnnn\0")];
32588 + char data_fd_buf[sizeof("nnnnnn\0")];
32589 + char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
32590 + char *setup_args[] = { "uml_net", version_buf, "ethertap", dev,
32591 + data_fd_buf, gate_buf, NULL };
32592 + char *nosetup_args[] = { "uml_net", version_buf, "ethertap",
32593 + dev, data_fd_buf, NULL };
32596 + sprintf(data_fd_buf, "%d", data_remote);
32597 + sprintf(version_buf, "%d", UML_NET_VERSION);
32598 + if(gate != NULL){
32599 + strcpy(gate_buf, gate);
32600 + args = setup_args;
32602 + else args = nosetup_args;
32605 + pe_data.control_remote = control_remote;
32606 + pe_data.control_me = control_me;
32607 + pe_data.data_me = data_me;
32608 + pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
32610 + if(pid < 0) err = errno;
32611 + close(data_remote);
32612 + close(control_remote);
32613 + if(read(control_me, &c, sizeof(c)) != sizeof(c)){
32614 + printk("etap_tramp : read of status failed, errno = %d\n",
32619 + printk("etap_tramp : uml_net failed\n");
32621 + if(waitpid(pid, &status, 0) < 0) err = errno;
32622 + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)){
32623 + printk("uml_net didn't exit with status 1\n");
32629 +static int etap_open(void *data)
32631 + struct ethertap_data *pri = data;
32633 + int data_fds[2], control_fds[2], err, output_len;
32635 + err = tap_open_common(pri->dev, pri->gate_addr);
32636 + if(err) return(err);
32638 + err = os_pipe(data_fds, 0, 0);
32640 + printk("data os_pipe failed - errno = %d\n", -err);
32644 + err = os_pipe(control_fds, 1, 0);
32646 + printk("control os_pipe failed - errno = %d\n", -err);
32650 + err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
32651 + control_fds[1], data_fds[0], data_fds[1]);
32652 + output_len = page_size();
32653 + output = um_kmalloc(output_len);
32654 + read_output(control_fds[0], output, output_len);
32656 + if(output == NULL)
32657 + printk("etap_open : failed to allocate output buffer\n");
32659 + printk("%s", output);
32664 + printk("etap_tramp failed - errno = %d\n", err);
32668 + pri->data_fd = data_fds[0];
32669 + pri->control_fd = control_fds[0];
32670 + iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
32671 + return(data_fds[0]);
32674 +static void etap_close(int fd, void *data)
32676 + struct ethertap_data *pri = data;
32678 + iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
32680 + os_shutdown_socket(pri->data_fd, 1, 1);
32681 + close(pri->data_fd);
32682 + pri->data_fd = -1;
32683 + close(pri->control_fd);
32684 + pri->control_fd = -1;
32687 +static int etap_set_mtu(int mtu, void *data)
32692 +static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
32695 + struct ethertap_data *pri = data;
32697 + tap_check_ips(pri->gate_addr, addr);
32698 + if(pri->control_fd == -1) return;
32699 + etap_open_addr(addr, netmask, &pri->control_fd);
32702 +static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
32705 + struct ethertap_data *pri = data;
32707 + if(pri->control_fd == -1) return;
32708 + etap_close_addr(addr, netmask, &pri->control_fd);
32711 +struct net_user_info ethertap_user_info = {
32712 + .init = etap_user_init,
32713 + .open = etap_open,
32714 + .close = etap_close,
32716 + .set_mtu = etap_set_mtu,
32717 + .add_address = etap_add_addr,
32718 + .delete_address = etap_del_addr,
32719 + .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP
32723 + * Overrides for Emacs so that we follow Linus's tabbing style.
32724 + * Emacs will notice this stuff at the end of the file and automatically
32725 + * adjust the settings for this buffer only. This must remain at the end
32727 + * ---------------------------------------------------------------------------
32728 + * Local variables:
32729 + * c-file-style: "linux"
32732 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap.h um/arch/um/os-Linux/drivers/tuntap.h
32733 --- orig/arch/um/os-Linux/drivers/tuntap.h Wed Dec 31 19:00:00 1969
32734 +++ um/arch/um/os-Linux/drivers/tuntap.h Wed Oct 23 21:08:04 2002
32737 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32738 + * Licensed under the GPL
32741 +#ifndef __UM_TUNTAP_H
32742 +#define __UM_TUNTAP_H
32744 +#include "net_user.h"
32746 +struct tuntap_data {
32748 + int fixed_config;
32754 +extern struct net_user_info tuntap_user_info;
32759 + * Overrides for Emacs so that we follow Linus's tabbing style.
32760 + * Emacs will notice this stuff at the end of the file and automatically
32761 + * adjust the settings for this buffer only. This must remain at the end
32763 + * ---------------------------------------------------------------------------
32764 + * Local variables:
32765 + * c-file-style: "linux"
32768 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_kern.c um/arch/um/os-Linux/drivers/tuntap_kern.c
32769 --- orig/arch/um/os-Linux/drivers/tuntap_kern.c Wed Dec 31 19:00:00 1969
32770 +++ um/arch/um/os-Linux/drivers/tuntap_kern.c Sun Dec 15 21:18:16 2002
32773 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
32774 + * Licensed under the GPL
32777 +#include "linux/stddef.h"
32778 +#include "linux/netdevice.h"
32779 +#include "linux/etherdevice.h"
32780 +#include "linux/skbuff.h"
32781 +#include "linux/init.h"
32782 +#include "asm/errno.h"
32783 +#include "net_kern.h"
32784 +#include "net_user.h"
32785 +#include "tuntap.h"
32787 +struct tuntap_init {
32792 +static void tuntap_init(struct net_device *dev, void *data)
32794 + struct uml_net_private *pri;
32795 + struct tuntap_data *tpri;
32796 + struct tuntap_init *init = data;
32798 + init_etherdev(dev, 0);
32800 + tpri = (struct tuntap_data *) pri->user;
32801 + *tpri = ((struct tuntap_data)
32802 + { .dev_name = init->dev_name,
32803 + .fixed_config = (init->dev_name != NULL),
32804 + .gate_addr = init->gate_addr,
32807 + printk("TUN/TAP backend - ");
32808 + if(tpri->gate_addr != NULL)
32809 + printk("IP = %s", tpri->gate_addr);
32813 +static int tuntap_read(int fd, struct sk_buff **skb,
32814 + struct uml_net_private *lp)
32816 + *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
32817 + if(*skb == NULL) return(-ENOMEM);
32818 + return(net_read(fd, (*skb)->mac.raw,
32819 + (*skb)->dev->mtu + ETH_HEADER_OTHER));
32822 +static int tuntap_write(int fd, struct sk_buff **skb,
32823 + struct uml_net_private *lp)
32825 + return(net_write(fd, (*skb)->data, (*skb)->len));
32828 +struct net_kern_info tuntap_kern_info = {
32829 + .init = tuntap_init,
32830 + .protocol = eth_protocol,
32831 + .read = tuntap_read,
32832 + .write = tuntap_write,
32835 +int tuntap_setup(char *str, char **mac_out, void *data)
32837 + struct tuntap_init *init = data;
32839 + *init = ((struct tuntap_init)
32840 + { .dev_name = NULL,
32841 + .gate_addr = NULL });
32842 + if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
32843 + &init->gate_addr))
32849 +static struct transport tuntap_transport = {
32850 + .list = LIST_HEAD_INIT(tuntap_transport.list),
32851 + .name = "tuntap",
32852 + .setup = tuntap_setup,
32853 + .user = &tuntap_user_info,
32854 + .kern = &tuntap_kern_info,
32855 + .private_size = sizeof(struct tuntap_data),
32856 + .setup_size = sizeof(struct tuntap_init),
32859 +static int register_tuntap(void)
32861 + register_transport(&tuntap_transport);
32865 +__initcall(register_tuntap);
32868 + * Overrides for Emacs so that we follow Linus's tabbing style.
32869 + * Emacs will notice this stuff at the end of the file and automatically
32870 + * adjust the settings for this buffer only. This must remain at the end
32872 + * ---------------------------------------------------------------------------
32873 + * Local variables:
32874 + * c-file-style: "linux"
32877 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_user.c um/arch/um/os-Linux/drivers/tuntap_user.c
32878 --- orig/arch/um/os-Linux/drivers/tuntap_user.c Wed Dec 31 19:00:00 1969
32879 +++ um/arch/um/os-Linux/drivers/tuntap_user.c Sun Dec 15 21:18:25 2002
32882 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32883 + * Licensed under the GPL
32886 +#include <stdio.h>
32887 +#include <stddef.h>
32888 +#include <stdlib.h>
32889 +#include <unistd.h>
32890 +#include <errno.h>
32891 +#include <fcntl.h>
32892 +#include <sys/wait.h>
32893 +#include <sys/socket.h>
32894 +#include <sys/un.h>
32895 +#include <sys/uio.h>
32896 +#include <sys/ioctl.h>
32897 +#include <net/if.h>
32898 +#include <linux/if_tun.h>
32899 +#include "net_user.h"
32900 +#include "tuntap.h"
32901 +#include "kern_util.h"
32903 +#include "helper.h"
32906 +#define MAX_PACKET ETH_MAX_PACKET
32908 +void tuntap_user_init(void *data, void *dev)
32910 + struct tuntap_data *pri = data;
32915 +static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
32918 + struct tuntap_data *pri = data;
32920 + tap_check_ips(pri->gate_addr, addr);
32921 + if((pri->fd == -1) || pri->fixed_config) return;
32922 + open_addr(addr, netmask, pri->dev_name);
32925 +static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
32928 + struct tuntap_data *pri = data;
32930 + if((pri->fd == -1) || pri->fixed_config) return;
32931 + close_addr(addr, netmask, pri->dev_name);
32934 +struct tuntap_pre_exec_data {
32939 +static void tuntap_pre_exec(void *arg)
32941 + struct tuntap_pre_exec_data *data = arg;
32943 + dup2(data->stdout, 1);
32944 + close(data->close_me);
32947 +static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
32948 + char *buffer, int buffer_len, int *used_out)
32950 + struct tuntap_pre_exec_data data;
32951 + char version_buf[sizeof("nnnnn\0")];
32952 + char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate,
32954 + char buf[CMSG_SPACE(sizeof(*fd_out))];
32955 + struct msghdr msg;
32956 + struct cmsghdr *cmsg;
32957 + struct iovec iov;
32960 + sprintf(version_buf, "%d", UML_NET_VERSION);
32962 + data.stdout = remote;
32963 + data.close_me = me;
32965 + pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
32967 + if(pid < 0) return(-pid);
32971 + msg.msg_name = NULL;
32972 + msg.msg_namelen = 0;
32973 + if(buffer != NULL){
32974 + iov = ((struct iovec) { buffer, buffer_len });
32975 + msg.msg_iov = &iov;
32976 + msg.msg_iovlen = 1;
32979 + msg.msg_iov = NULL;
32980 + msg.msg_iovlen = 0;
32982 + msg.msg_control = buf;
32983 + msg.msg_controllen = sizeof(buf);
32984 + msg.msg_flags = 0;
32985 + n = recvmsg(me, &msg, 0);
32988 + printk("tuntap_open_tramp : recvmsg failed - errno = %d\n",
32992 + waitpid(pid, NULL, 0);
32994 + cmsg = CMSG_FIRSTHDR(&msg);
32995 + if(cmsg == NULL){
32996 + printk("tuntap_open_tramp : didn't receive a message\n");
32999 + if((cmsg->cmsg_level != SOL_SOCKET) ||
33000 + (cmsg->cmsg_type != SCM_RIGHTS)){
33001 + printk("tuntap_open_tramp : didn't receive a descriptor\n");
33004 + *fd_out = ((int *) CMSG_DATA(cmsg))[0];
33008 +static int tuntap_open(void *data)
33010 + struct ifreq ifr;
33011 + struct tuntap_data *pri = data;
33012 + char *output, *buffer;
33013 + int err, fds[2], len, used;
33015 + err = tap_open_common(pri->dev, pri->gate_addr);
33016 + if(err) return(err);
33018 + if(pri->fixed_config){
33019 + if((pri->fd = open("/dev/net/tun", O_RDWR)) < 0){
33020 + printk("Failed to open /dev/net/tun, errno = %d\n",
33024 + memset(&ifr, 0, sizeof(ifr));
33025 + ifr.ifr_flags = IFF_TAP;
33026 + strncpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name) - 1);
33027 + if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
33028 + printk("TUNSETIFF failed, errno = %d", errno);
33034 + err = os_pipe(fds, 0, 0);
33036 + printk("tuntap_open : os_pipe failed - errno = %d\n",
33041 + buffer = get_output_buffer(&len);
33042 + if(buffer != NULL) len--;
33045 + err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
33046 + fds[1], buffer, len, &used);
33050 + pri->dev_name = uml_strdup(buffer);
33051 + output += IFNAMSIZ;
33053 + free_output_buffer(buffer);
33057 + free_output_buffer(buffer);
33058 + printk("tuntap_open_tramp failed - errno = %d\n", err);
33062 + iter_addresses(pri->dev, open_addr, pri->dev_name);
33068 +static void tuntap_close(int fd, void *data)
33070 + struct tuntap_data *pri = data;
33072 + if(!pri->fixed_config)
33073 + iter_addresses(pri->dev, close_addr, pri->dev_name);
33078 +static int tuntap_set_mtu(int mtu, void *data)
33083 +struct net_user_info tuntap_user_info = {
33084 + .init = tuntap_user_init,
33085 + .open = tuntap_open,
33086 + .close = tuntap_close,
33088 + .set_mtu = tuntap_set_mtu,
33089 + .add_address = tuntap_add_addr,
33090 + .delete_address = tuntap_del_addr,
33091 + .max_packet = MAX_PACKET
33095 + * Overrides for Emacs so that we follow Linus's tabbing style.
33096 + * Emacs will notice this stuff at the end of the file and automatically
33097 + * adjust the settings for this buffer only. This must remain at the end
33099 + * ---------------------------------------------------------------------------
33100 + * Local variables:
33101 + * c-file-style: "linux"
33104 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/file.c um/arch/um/os-Linux/file.c
33105 --- orig/arch/um/os-Linux/file.c Wed Dec 31 19:00:00 1969
33106 +++ um/arch/um/os-Linux/file.c Tue Feb 4 19:32:10 2003
33109 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33110 + * Licensed under the GPL
33113 +#include <stdio.h>
33114 +#include <unistd.h>
33115 +#include <errno.h>
33116 +#include <fcntl.h>
33117 +#include <signal.h>
33118 +#include <sys/socket.h>
33119 +#include <sys/un.h>
33120 +#include <sys/ioctl.h>
33121 +#include <sys/mount.h>
33122 +#include <sys/uio.h>
33125 +#include "kern_util.h"
33127 +int os_file_type(char *file)
33129 + struct stat64 buf;
33131 + if(stat64(file, &buf) == -1)
33134 + if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
33135 + else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
33136 + else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
33137 + else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
33138 + else if(S_ISFIFO(buf.st_mode)) return(OS_TYPE_FIFO);
33139 + else if(S_ISSOCK(buf.st_mode)) return(OS_TYPE_SOCK);
33140 + else return(OS_TYPE_FILE);
33143 +int os_file_mode(char *file, struct openflags *mode_out)
33145 + *mode_out = OPENFLAGS();
33147 + if(!access(file, W_OK)) *mode_out = of_write(*mode_out);
33148 + else if(errno != EACCES)
33151 + if(!access(file, R_OK)) *mode_out = of_read(*mode_out);
33152 + else if(errno != EACCES)
33158 +int os_open_file(char *file, struct openflags flags, int mode)
33162 + if(flags.r && flags.w) f = O_RDWR;
33163 + else if(flags.r) f = O_RDONLY;
33164 + else if(flags.w) f = O_WRONLY;
33167 + if(flags.s) f |= O_SYNC;
33168 + if(flags.c) f |= O_CREAT;
33169 + if(flags.t) f |= O_TRUNC;
33170 + if(flags.e) f |= O_EXCL;
33172 + fd = open64(file, f, mode);
33173 + if(fd < 0) return(-errno);
33176 + if(fcntl(fd, F_SETFD, 1)){
33185 +int os_connect_socket(char *name)
33187 + struct sockaddr_un sock;
33190 + sock.sun_family = AF_UNIX;
33191 + snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
33193 + fd = socket(AF_UNIX, SOCK_STREAM, 0);
33197 + err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
33204 +void os_close_file(int fd)
33209 +int os_seek_file(int fd, __u64 offset)
33213 + actual = lseek64(fd, offset, SEEK_SET);
33214 + if(actual != offset) return(-errno);
33218 +int os_read_file(int fd, void *buf, int len)
33222 + /* Force buf into memory if it's not already. */
33224 + /* XXX This fails if buf is kernel memory */
33226 + if(copy_to_user_proc(buf, &c, sizeof(c)))
33230 + n = read(fd, buf, len);
33236 +int os_write_file(int fd, void *buf, int count)
33240 + /* Force buf into memory if it's not already. */
33242 + /* XXX This fails if buf is kernel memory */
33244 + if(copy_to_user_proc(buf, buf, buf[0]))
33248 + n = write(fd, buf, count);
33254 +int os_file_size(char *file, long long *size_out)
33256 + struct stat64 buf;
33258 + if(stat64(file, &buf) == -1){
33259 + printk("Couldn't stat \"%s\" : errno = %d\n", file, errno);
33262 + if(S_ISBLK(buf.st_mode)){
33265 + if((fd = open64(file, O_RDONLY)) < 0){
33266 + printk("Couldn't open \"%s\", errno = %d\n", file,
33270 + if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
33271 + printk("Couldn't get the block size of \"%s\", "
33272 + "errno = %d\n", file, errno);
33276 + *size_out = ((long long) blocks) * 512;
33280 + *size_out = buf.st_size;
33284 +int os_pipe(int *fds, int stream, int close_on_exec)
33286 + int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
33288 + err = socketpair(AF_UNIX, type, 0, fds);
33292 + if(!close_on_exec)
33295 + if((fcntl(fds[0], F_SETFD, 1) < 0) || (fcntl(fds[1], F_SETFD, 1) < 0))
33296 + printk("os_pipe : Setting FD_CLOEXEC failed, errno = %d",
33302 +int os_set_fd_async(int fd, int owner)
33304 + /* XXX This should do F_GETFL first */
33305 + if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){
33306 + printk("os_set_fd_async : failed to set O_ASYNC and "
33307 + "O_NONBLOCK on fd # %d, errno = %d\n", fd, errno);
33311 + if(fcntl(fd, F_SETFD, 1) < 0){
33312 + printk("os_set_fd_async : Setting FD_CLOEXEC failed, "
33313 + "errno = %d\n", errno);
33317 + if((fcntl(fd, F_SETSIG, SIGIO) < 0) ||
33318 + (fcntl(fd, F_SETOWN, owner) < 0)){
33319 + printk("os_set_fd_async : Failed to fcntl F_SETOWN "
33320 + "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd,
33328 +int os_set_fd_block(int fd, int blocking)
33332 + flags = fcntl(fd, F_GETFL);
33334 + if(blocking) flags &= ~O_NONBLOCK;
33335 + else flags |= O_NONBLOCK;
33337 + if(fcntl(fd, F_SETFL, flags) < 0){
33338 + printk("Failed to change blocking on fd # %d, errno = %d\n",
33345 +int os_accept_connection(int fd)
33349 + new = accept(fd, NULL, 0);
33364 +#define SHUT_RDWR 2
33367 +int os_shutdown_socket(int fd, int r, int w)
33371 + if(r && w) what = SHUT_RDWR;
33372 + else if(r) what = SHUT_RD;
33373 + else if(w) what = SHUT_WR;
33375 + printk("os_shutdown_socket : neither r or w was set\n");
33378 + err = shutdown(fd, what);
33384 +int os_rcv_fd(int fd, int *helper_pid_out)
33387 + char buf[CMSG_SPACE(sizeof(new))];
33388 + struct msghdr msg;
33389 + struct cmsghdr *cmsg;
33390 + struct iovec iov;
33392 + msg.msg_name = NULL;
33393 + msg.msg_namelen = 0;
33394 + iov = ((struct iovec) { .iov_base = helper_pid_out,
33395 + .iov_len = sizeof(*helper_pid_out) });
33396 + msg.msg_iov = &iov;
33397 + msg.msg_iovlen = 1;
33398 + msg.msg_control = buf;
33399 + msg.msg_controllen = sizeof(buf);
33400 + msg.msg_flags = 0;
33402 + n = recvmsg(fd, &msg, 0);
33406 + else if(n != sizeof(iov.iov_len))
33407 + *helper_pid_out = -1;
33409 + cmsg = CMSG_FIRSTHDR(&msg);
33410 + if(cmsg == NULL){
33411 + printk("rcv_fd didn't receive anything, error = %d\n", errno);
33414 + if((cmsg->cmsg_level != SOL_SOCKET) ||
33415 + (cmsg->cmsg_type != SCM_RIGHTS)){
33416 + printk("rcv_fd didn't receive a descriptor\n");
33420 + new = ((int *) CMSG_DATA(cmsg))[0];
33424 +int create_unix_socket(char *file, int len)
33426 + struct sockaddr_un addr;
33429 + sock = socket(PF_UNIX, SOCK_DGRAM, 0);
33431 + printk("create_unix_socket - socket failed, errno = %d\n",
33436 + addr.sun_family = AF_UNIX;
33438 + /* XXX Be more careful about overflow */
33439 + snprintf(addr.sun_path, len, "%s", file);
33441 + err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
33443 + printk("create_listening_socket - bind failed, errno = %d\n",
33451 +void os_flush_stdout(void)
33456 +int os_lock_file(int fd, int excl)
33458 + int type = excl ? F_WRLCK : F_RDLCK;
33459 + struct flock lock = ((struct flock) { .l_type = type,
33460 + .l_whence = SEEK_SET,
33465 + err = fcntl(fd, F_SETLK, &lock);
33470 + err = fcntl(fd, F_GETLK, &lock);
33476 + printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
33483 + * Overrides for Emacs so that we follow Linus's tabbing style.
33484 + * Emacs will notice this stuff at the end of the file and automatically
33485 + * adjust the settings for this buffer only. This must remain at the end
33487 + * ---------------------------------------------------------------------------
33488 + * Local variables:
33489 + * c-file-style: "linux"
33492 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/include/file.h um/arch/um/os-Linux/include/file.h
33493 --- orig/arch/um/os-Linux/include/file.h Wed Dec 31 19:00:00 1969
33494 +++ um/arch/um/os-Linux/include/file.h Wed Oct 23 21:08:04 2002
33497 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33498 + * Licensed under the GPL
33501 +#ifndef __OS_FILE_H__
33502 +#define __OS_FILE_H__
33504 +#define DEV_NULL "/dev/null"
33509 + * Overrides for Emacs so that we follow Linus's tabbing style.
33510 + * Emacs will notice this stuff at the end of the file and automatically
33511 + * adjust the settings for this buffer only. This must remain at the end
33513 + * ---------------------------------------------------------------------------
33514 + * Local variables:
33515 + * c-file-style: "linux"
33518 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/process.c um/arch/um/os-Linux/process.c
33519 --- orig/arch/um/os-Linux/process.c Wed Dec 31 19:00:00 1969
33520 +++ um/arch/um/os-Linux/process.c Wed Jan 8 14:19:00 2003
33523 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33524 + * Licensed under the GPL
33527 +#include <unistd.h>
33528 +#include <stdio.h>
33529 +#include <errno.h>
33530 +#include <signal.h>
33531 +#include <sys/mman.h>
33532 +#include <sys/wait.h>
33536 +unsigned long os_process_pc(int pid)
33538 + char proc_stat[sizeof("/proc/#####/stat\0")], buf[256];
33539 + unsigned long pc;
33542 + sprintf(proc_stat, "/proc/%d/stat", pid);
33543 + fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
33545 + printk("os_process_pc - couldn't open '%s', errno = %d\n",
33546 + proc_stat, errno);
33549 + if(read(fd, buf, sizeof(buf)) < 0){
33550 + printk("os_process_pc - couldn't read '%s', errno = %d\n",
33551 + proc_stat, errno);
33557 + if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d "
33558 + "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
33559 + "%*d %*d %*d %*d %ld", &pc) != 1){
33560 + printk("os_process_pc - couldn't find pc in '%s'\n", buf);
33565 +int os_process_parent(int pid)
33567 + char stat[sizeof("/proc/nnnnn/stat\0")];
33569 + int parent, n, fd;
33571 + if(pid == -1) return(-1);
33573 + snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
33574 + fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
33576 + printk("Couldn't open '%s', errno = %d\n", stat, -fd);
33580 + n = read(fd, data, sizeof(data));
33584 + printk("Couldn't read '%s', errno = %d\n", stat);
33589 + /* XXX This will break if there is a space in the command */
33590 + n = sscanf(data, "%*d %*s %*c %d", &parent);
33591 + if(n != 1) printk("Failed to scan '%s'\n", data);
33596 +void os_stop_process(int pid)
33598 + kill(pid, SIGSTOP);
33601 +void os_kill_process(int pid, int reap_child)
33603 + kill(pid, SIGKILL);
33605 + waitpid(pid, NULL, 0);
33609 +void os_usr1_process(int pid)
33611 + kill(pid, SIGUSR1);
33614 +int os_getpid(void)
33616 + return(getpid());
33619 +int os_map_memory(void *virt, int fd, unsigned long off, unsigned long len,
33620 + int r, int w, int x)
33625 + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
33626 + (x ? PROT_EXEC : 0);
33628 + loc = mmap((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
33630 + if(loc == MAP_FAILED)
33635 +int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
33637 + int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
33638 + (x ? PROT_EXEC : 0));
33640 + if(mprotect(addr, len, prot) < 0)
33645 +int os_unmap_memory(void *addr, int len)
33649 + err = munmap(addr, len);
33650 + if(err < 0) return(-errno);
33655 + * Overrides for Emacs so that we follow Linus's tabbing style.
33656 + * Emacs will notice this stuff at the end of the file and automatically
33657 + * adjust the settings for this buffer only. This must remain at the end
33659 + * ---------------------------------------------------------------------------
33660 + * Local variables:
33661 + * c-file-style: "linux"
33664 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/tty.c um/arch/um/os-Linux/tty.c
33665 --- orig/arch/um/os-Linux/tty.c Wed Dec 31 19:00:00 1969
33666 +++ um/arch/um/os-Linux/tty.c Wed Oct 23 21:08:04 2002
33669 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33670 + * Licensed under the GPL
33673 +#include <stdlib.h>
33674 +#include <errno.h>
33677 +#include "kern_util.h"
33679 +struct grantpt_info {
33685 +static void grantpt_cb(void *arg)
33687 + struct grantpt_info *info = arg;
33689 + info->res = grantpt(info->fd);
33690 + info->err = errno;
33695 + struct grantpt_info info;
33698 + if((fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0)) < 0){
33699 + printk("get_pty : Couldn't open /dev/ptmx - errno = %d\n",
33705 + initial_thread_cb(grantpt_cb, &info);
33707 + if(info.res < 0){
33708 + printk("get_pty : Couldn't grant pty - errno = %d\n",
33712 + if(unlockpt(fd) < 0){
33713 + printk("get_pty : Couldn't unlock pty - errno = %d\n", errno);
33720 + * Overrides for Emacs so that we follow Linus's tabbing style.
33721 + * Emacs will notice this stuff at the end of the file and automatically
33722 + * adjust the settings for this buffer only. This must remain at the end
33724 + * ---------------------------------------------------------------------------
33725 + * Local variables:
33726 + * c-file-style: "linux"
33729 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/Makefile um/arch/um/sys-i386/Makefile
33730 --- orig/arch/um/sys-i386/Makefile Wed Dec 31 19:00:00 1969
33731 +++ um/arch/um/sys-i386/Makefile Sat Nov 23 23:34:24 2002
33734 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33735 +# Licensed under the GPL
33738 +O_TARGET = built-in.o
33740 +obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \
33741 + ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
33742 +export-objs = ksyms.o
33744 +USER_OBJS = bugs.o ptrace_user.o sigcontext.o fault.o
33746 +SYMLINKS = semaphore.c extable.c
33748 +semaphore.c-dir = kernel
33749 +extable.c-dir = mm
33751 +include $(TOPDIR)/Rules.make
33753 +$(USER_OBJS) : %.o: %.c
33754 + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
33758 + ln -sf $(TOPDIR)/arch/i386/$($1-dir)/$1 $1
33762 + $(call make_link,$@)
33765 + $(MAKE) -C util clean
33766 + rm -f $(SYMLINKS)
33779 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/bugs.c um/arch/um/sys-i386/bugs.c
33780 --- orig/arch/um/sys-i386/bugs.c Wed Dec 31 19:00:00 1969
33781 +++ um/arch/um/sys-i386/bugs.c Sun Dec 8 20:38:45 2002
33784 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33785 + * Licensed under the GPL
33788 +#include <unistd.h>
33789 +#include <fcntl.h>
33790 +#include <errno.h>
33791 +#include <string.h>
33792 +#include <sys/signal.h>
33793 +#include "kern_util.h"
33795 +#include "sysdep/ptrace.h"
33798 +#define MAXTOKEN 64
33800 +/* Set during early boot */
33801 +int cpu_has_cmov = 1;
33802 +int cpu_has_xmm = 0;
33804 +static char token(int fd, char *buf, int len, char stop)
33807 + char *ptr, *end, c;
33812 + n = read(fd, ptr, sizeof(*ptr));
33814 + if(n == 0) return(0);
33815 + else if(n != sizeof(*ptr)){
33816 + printk("Reading /proc/cpuinfo failed, "
33817 + "errno = %d\n", errno);
33820 + } while((c != '\n') && (c != stop) && (ptr < end));
33823 + printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
33826 + *(ptr - 1) = '\0';
33830 +static int check_cpu_feature(char *feature, int *have_it)
33832 + char buf[MAXTOKEN], c;
33833 + int fd, len = sizeof(buf)/sizeof(buf[0]), n;
33835 + printk("Checking for host processor %s support...", feature);
33836 + fd = open("/proc/cpuinfo", O_RDONLY);
33838 + printk("Couldn't open /proc/cpuinfo, errno = %d\n", errno);
33843 + buf[len - 1] = '\0';
33845 + c = token(fd, buf, len - 1, ':');
33846 + if(c <= 0) goto out;
33847 + else if(c != ':'){
33848 + printk("Failed to find ':' in /proc/cpuinfo\n");
33852 + if(!strncmp(buf, "flags", strlen("flags"))) break;
33855 + n = read(fd, &c, sizeof(c));
33856 + if(n != sizeof(c)){
33857 + printk("Failed to find newline in "
33858 + "/proc/cpuinfo, n = %d, errno = %d\n",
33862 + } while(c != '\n');
33865 + c = token(fd, buf, len - 1, ' ');
33866 + if(c < 0) goto out;
33867 + else if(c != ' '){
33868 + printk("Failed to find ':' in /proc/cpuinfo\n");
33873 + c = token(fd, buf, len - 1, ' ');
33874 + if(c < 0) goto out;
33875 + else if(c == '\n') break;
33877 + if(!strcmp(buf, feature)){
33883 + if(*have_it == 0) printk("No\n");
33884 + else if(*have_it == 1) printk("Yes\n");
33889 +void arch_check_bugs(void)
33893 + if(access("/proc/cpuinfo", R_OK)){
33894 + printk("/proc/cpuinfo not available - skipping CPU capability "
33898 + if(check_cpu_feature("cmov", &have_it)) cpu_has_cmov = have_it;
33899 + if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
33902 +int arch_handle_signal(int sig, union uml_pt_regs *regs)
33904 + unsigned long ip;
33906 + /* This is testing for a cmov (0x0f 0x4x) instruction causing a
33907 + * SIGILL in init.
33909 + if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0);
33911 + ip = UPT_IP(regs);
33912 + if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
33915 + if(cpu_has_cmov == 0)
33916 + panic("SIGILL caused by cmov, which this processor doesn't "
33917 + "implement, boot a filesystem compiled for older "
33919 + else if(cpu_has_cmov == 1)
33920 + panic("SIGILL caused by cmov, which this processor claims to "
33922 + else if(cpu_has_cmov == -1)
33923 + panic("SIGILL caused by cmov, couldn't tell if this processor "
33924 + "implements it, boot a filesystem compiled for older "
33926 + else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
33931 + * Overrides for Emacs so that we follow Linus's tabbing style.
33932 + * Emacs will notice this stuff at the end of the file and automatically
33933 + * adjust the settings for this buffer only. This must remain at the end
33935 + * ---------------------------------------------------------------------------
33936 + * Local variables:
33937 + * c-file-style: "linux"
33940 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/checksum.S um/arch/um/sys-i386/checksum.S
33941 --- orig/arch/um/sys-i386/checksum.S Wed Dec 31 19:00:00 1969
33942 +++ um/arch/um/sys-i386/checksum.S Thu Oct 31 20:17:50 2002
33945 + * INET An implementation of the TCP/IP protocol suite for the LINUX
33946 + * operating system. INET is implemented using the BSD Socket
33947 + * interface as the means of communication with the user level.
33949 + * IP/TCP/UDP checksumming routines
33951 + * Authors: Jorge Cwik, <jorge@laser.satlink.net>
33952 + * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
33953 + * Tom May, <ftom@netcom.com>
33954 + * Pentium Pro/II routines:
33955 + * Alexander Kjeldaas <astor@guardian.no>
33956 + * Finn Arne Gangstad <finnag@guardian.no>
33957 + * Lots of code moved from tcp.c and ip.c; see those files
33958 + * for more names.
33960 + * Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception
33962 + * Andi Kleen, add zeroing on error
33963 + * converted to pure assembler
33965 + * This program is free software; you can redistribute it and/or
33966 + * modify it under the terms of the GNU General Public License
33967 + * as published by the Free Software Foundation; either version
33968 + * 2 of the License, or (at your option) any later version.
33971 +#include <linux/config.h>
33972 +#include <asm/errno.h>
33975 + * computes a partial checksum, e.g. for TCP/UDP fragments
33979 +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
33984 +.globl arch_csum_partial
33986 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
33989 + * Experiments with Ethernet and SLIP connections show that buff
33990 + * is aligned on either a 2-byte or 4-byte boundary. We get at
33991 + * least a twofold speedup on 486 and Pentium if it is 4-byte aligned.
33992 + * Fortunately, it is easy to convert 2-byte alignment to 4-byte
33993 + * alignment for the unrolled loop.
33995 +arch_csum_partial:
33998 + movl 20(%esp),%eax # Function arg: unsigned int sum
33999 + movl 16(%esp),%ecx # Function arg: int len
34000 + movl 12(%esp),%esi # Function arg: unsigned char *buff
34001 + testl $2, %esi # Check alignment.
34002 + jz 2f # Jump if alignment is ok.
34003 + subl $2, %ecx # Alignment uses up two bytes.
34004 + jae 1f # Jump if we had at least two bytes.
34005 + addl $2, %ecx # ecx was < 2. Deal with it.
34007 +1: movw (%esi), %bx
34016 +1: movl (%esi), %ebx
34018 + movl 4(%esi), %ebx
34020 + movl 8(%esi), %ebx
34022 + movl 12(%esi), %ebx
34024 + movl 16(%esi), %ebx
34026 + movl 20(%esi), %ebx
34028 + movl 24(%esi), %ebx
34030 + movl 28(%esi), %ebx
34032 + lea 32(%esi), %esi
34036 +2: movl %edx, %ecx
34039 + shrl $2, %edx # This clears CF
34040 +3: adcl (%esi), %eax
34041 + lea 4(%esi), %esi
34050 + leal 2(%esi),%esi
34053 +5: movb (%esi),%cl
34063 +/* Version for PentiumII/PPro */
34065 +arch_csum_partial:
34068 + movl 20(%esp),%eax # Function arg: unsigned int sum
34069 + movl 16(%esp),%ecx # Function arg: int len
34070 + movl 12(%esp),%esi # Function arg: const unsigned char *buf
34082 + lea 45f(%ebx,%ebx,2), %ebx
34086 + # Handle 2-byte-aligned regions
34087 +20: addw (%esi), %ax
34088 + lea 2(%esi), %esi
34095 + movzbl (%esi),%ebx # csumming 1 byte, 2-aligned
34100 + addw (%esi), %ax # csumming 2 bytes, 2-aligned
34105 + addl -128(%esi), %eax
34106 + adcl -124(%esi), %eax
34107 + adcl -120(%esi), %eax
34108 + adcl -116(%esi), %eax
34109 + adcl -112(%esi), %eax
34110 + adcl -108(%esi), %eax
34111 + adcl -104(%esi), %eax
34112 + adcl -100(%esi), %eax
34113 + adcl -96(%esi), %eax
34114 + adcl -92(%esi), %eax
34115 + adcl -88(%esi), %eax
34116 + adcl -84(%esi), %eax
34117 + adcl -80(%esi), %eax
34118 + adcl -76(%esi), %eax
34119 + adcl -72(%esi), %eax
34120 + adcl -68(%esi), %eax
34121 + adcl -64(%esi), %eax
34122 + adcl -60(%esi), %eax
34123 + adcl -56(%esi), %eax
34124 + adcl -52(%esi), %eax
34125 + adcl -48(%esi), %eax
34126 + adcl -44(%esi), %eax
34127 + adcl -40(%esi), %eax
34128 + adcl -36(%esi), %eax
34129 + adcl -32(%esi), %eax
34130 + adcl -28(%esi), %eax
34131 + adcl -24(%esi), %eax
34132 + adcl -20(%esi), %eax
34133 + adcl -16(%esi), %eax
34134 + adcl -12(%esi), %eax
34135 + adcl -8(%esi), %eax
34136 + adcl -4(%esi), %eax
34138 + lea 128(%esi), %esi
34146 + # Handle the last 1-3 bytes without jumping
34147 + notl %ecx # 1->2, 2->1, 3->0, higher bits are masked
34148 + movl $0xffffff,%ebx # by the shll and shrl instructions
34151 + andl -128(%esi),%ebx # esi is 4-aligned so should be ok
34162 +unsigned int csum_partial_copy_generic (const char *src, char *dst,
34163 + int len, int sum, int *src_err_ptr, int *dst_err_ptr)
34167 + * Copy from ds while checksumming, otherwise like csum_partial
34169 + * The macros SRC and DST specify the type of access for the instruction.
34170 + * thus we can call a custom exception handler for all access types.
34172 + * FIXME: could someone double-check whether I haven't mixed up some SRC and
34173 + * DST definitions? It's damn hard to trigger all cases. I hope I got
34174 + * them all but there's no guarantee.
34177 +#define SRC(y...) \
34179 + .section __ex_table, "a"; \
34180 + .long 9999b, 6001f ; \
34183 +#define DST(y...) \
34185 + .section __ex_table, "a"; \
34186 + .long 9999b, 6002f ; \
34190 +.globl csum_partial_copy_generic_i386
34192 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
34194 +#define ARGBASE 16
34197 +csum_partial_copy_generic_i386:
34202 + movl ARGBASE+16(%esp),%eax # sum
34203 + movl ARGBASE+12(%esp),%ecx # len
34204 + movl ARGBASE+4(%esp),%esi # src
34205 + movl ARGBASE+8(%esp),%edi # dst
34207 + testl $2, %edi # Check alignment.
34208 + jz 2f # Jump if alignment is ok.
34209 + subl $2, %ecx # Alignment uses up two bytes.
34210 + jae 1f # Jump if we had at least two bytes.
34211 + addl $2, %ecx # ecx was < 2. Deal with it.
34213 +SRC(1: movw (%esi), %bx )
34215 +DST( movw %bx, (%edi) )
34220 + movl %ecx, FP(%esp)
34224 +SRC(1: movl (%esi), %ebx )
34225 +SRC( movl 4(%esi), %edx )
34227 +DST( movl %ebx, (%edi) )
34229 +DST( movl %edx, 4(%edi) )
34231 +SRC( movl 8(%esi), %ebx )
34232 +SRC( movl 12(%esi), %edx )
34234 +DST( movl %ebx, 8(%edi) )
34236 +DST( movl %edx, 12(%edi) )
34238 +SRC( movl 16(%esi), %ebx )
34239 +SRC( movl 20(%esi), %edx )
34241 +DST( movl %ebx, 16(%edi) )
34243 +DST( movl %edx, 20(%edi) )
34245 +SRC( movl 24(%esi), %ebx )
34246 +SRC( movl 28(%esi), %edx )
34248 +DST( movl %ebx, 24(%edi) )
34250 +DST( movl %edx, 28(%edi) )
34252 + lea 32(%esi), %esi
34253 + lea 32(%edi), %edi
34257 +2: movl FP(%esp), %edx
34261 + shrl $2, %edx # This clears CF
34262 +SRC(3: movl (%esi), %ebx )
34264 +DST( movl %ebx, (%edi) )
34265 + lea 4(%esi), %esi
34266 + lea 4(%edi), %edi
34274 +SRC( movw (%esi), %cx )
34275 + leal 2(%esi), %esi
34276 +DST( movw %cx, (%edi) )
34277 + leal 2(%edi), %edi
34280 +SRC(5: movb (%esi), %cl )
34281 +DST( movb %cl, (%edi) )
34282 +6: addl %ecx, %eax
34287 +# Exception handler:
34288 +.section .fixup, "ax"
34291 + movl ARGBASE+20(%esp), %ebx # src_err_ptr
34292 + movl $-EFAULT, (%ebx)
34294 + # zero the complete destination - computing the rest
34295 + # is too much work
34296 + movl ARGBASE+8(%esp), %edi # dst
34297 + movl ARGBASE+12(%esp), %ecx # len
34304 + movl ARGBASE+24(%esp), %ebx # dst_err_ptr
34305 + movl $-EFAULT,(%ebx)
34313 + popl %ecx # equivalent to addl $4,%esp
34318 +/* Version for PentiumII/PPro */
34320 +#define ROUND1(x) \
34321 + SRC(movl x(%esi), %ebx ) ; \
34322 + addl %ebx, %eax ; \
34323 + DST(movl %ebx, x(%edi) ) ;
34325 +#define ROUND(x) \
34326 + SRC(movl x(%esi), %ebx ) ; \
34327 + adcl %ebx, %eax ; \
34328 + DST(movl %ebx, x(%edi) ) ;
34330 +#define ARGBASE 12
34332 +csum_partial_copy_generic_i386:
34336 + movl ARGBASE+4(%esp),%esi #src
34337 + movl ARGBASE+8(%esp),%edi #dst
34338 + movl ARGBASE+12(%esp),%ecx #len
34339 + movl ARGBASE+16(%esp),%eax #sum
34348 + lea -1(%esi),%edx
34350 + lea 3f(%ebx,%ebx), %ebx
34355 + SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl)
34356 + ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52)
34357 + ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36)
34358 + ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20)
34359 + ROUND (-16) ROUND(-12) ROUND(-8) ROUND(-4)
34364 +4: movl ARGBASE+12(%esp),%edx #len
34369 +SRC( movw (%esi), %dx )
34370 + leal 2(%esi), %esi
34371 +DST( movw %dx, (%edi) )
34372 + leal 2(%edi), %edi
34376 +SRC( movb (%esi), %dl )
34377 +DST( movb %dl, (%edi) )
34378 +6: addl %edx, %eax
34381 +.section .fixup, "ax"
34382 +6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
34383 + movl $-EFAULT, (%ebx)
34384 + # zero the complete destination (computing the rest is too much work)
34385 + movl ARGBASE+8(%esp),%edi # dst
34386 + movl ARGBASE+12(%esp),%ecx # len
34390 +6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
34391 + movl $-EFAULT, (%ebx)
34404 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/fault.c um/arch/um/sys-i386/fault.c
34405 --- orig/arch/um/sys-i386/fault.c Wed Dec 31 19:00:00 1969
34406 +++ um/arch/um/sys-i386/fault.c Sun Oct 27 16:49:35 2002
34409 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34410 + * Licensed under the GPL
34413 +#include <signal.h>
34414 +#include "sysdep/ptrace.h"
34415 +#include "sysdep/sigcontext.h"
34417 +extern unsigned long search_exception_table(unsigned long addr);
34419 +int arch_fixup(unsigned long address, void *sc_ptr)
34421 + struct sigcontext *sc = sc_ptr;
34422 + unsigned long fixup;
34424 + fixup = search_exception_table(address);
34433 + * Overrides for Emacs so that we follow Linus's tabbing style.
34434 + * Emacs will notice this stuff at the end of the file and automatically
34435 + * adjust the settings for this buffer only. This must remain at the end
34437 + * ---------------------------------------------------------------------------
34438 + * Local variables:
34439 + * c-file-style: "linux"
34442 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ksyms.c um/arch/um/sys-i386/ksyms.c
34443 --- orig/arch/um/sys-i386/ksyms.c Wed Dec 31 19:00:00 1969
34444 +++ um/arch/um/sys-i386/ksyms.c Tue Oct 29 21:01:45 2002
34446 +#include "linux/module.h"
34447 +#include "linux/in6.h"
34448 +#include "linux/rwsem.h"
34449 +#include "asm/byteorder.h"
34450 +#include "asm/semaphore.h"
34451 +#include "asm/uaccess.h"
34452 +#include "asm/checksum.h"
34453 +#include "asm/errno.h"
34455 +EXPORT_SYMBOL(__down_failed);
34456 +EXPORT_SYMBOL(__down_failed_interruptible);
34457 +EXPORT_SYMBOL(__down_failed_trylock);
34458 +EXPORT_SYMBOL(__up_wakeup);
34460 +/* Networking helper routines. */
34461 +EXPORT_SYMBOL(csum_partial_copy_from);
34462 +EXPORT_SYMBOL(csum_partial_copy_to);
34463 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ldt.c um/arch/um/sys-i386/ldt.c
34464 --- orig/arch/um/sys-i386/ldt.c Wed Dec 31 19:00:00 1969
34465 +++ um/arch/um/sys-i386/ldt.c Wed Nov 13 12:43:04 2002
34468 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
34469 + * Licensed under the GPL
34472 +#include "linux/config.h"
34473 +#include "linux/slab.h"
34474 +#include "asm/uaccess.h"
34475 +#include "asm/ptrace.h"
34476 +#include "choose-mode.h"
34479 +#ifdef CONFIG_MODE_TT
34480 +extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
34482 +int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
34484 + if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT);
34485 + return(modify_ldt(func, ptr, bytecount));
34489 +#ifdef CONFIG_MODE_SKAS
34490 +extern int userspace_pid;
34492 +int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
34494 + struct ptrace_ldt ldt;
34498 + buf = kmalloc(bytecount, GFP_KERNEL);
34507 + res = copy_from_user(buf, ptr, bytecount);
34516 + ldt = ((struct ptrace_ldt) { .func = func,
34518 + .bytecount = bytecount });
34519 + res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt);
34527 + res = copy_to_user(ptr, buf, n);
34541 +int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
34543 + return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
34544 + ptr, bytecount));
34550 + * Overrides for Emacs so that we follow Linus's tabbing style.
34551 + * Emacs will notice this stuff at the end of the file and automatically
34552 + * adjust the settings for this buffer only. This must remain at the end
34554 + * ---------------------------------------------------------------------------
34555 + * Local variables:
34556 + * c-file-style: "linux"
34559 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace.c um/arch/um/sys-i386/ptrace.c
34560 --- orig/arch/um/sys-i386/ptrace.c Wed Dec 31 19:00:00 1969
34561 +++ um/arch/um/sys-i386/ptrace.c Sun Oct 27 16:49:35 2002
34564 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
34565 + * Licensed under the GPL
34568 +#include "linux/sched.h"
34569 +#include "asm/elf.h"
34570 +#include "asm/ptrace.h"
34571 +#include "asm/uaccess.h"
34572 +#include "ptrace_user.h"
34573 +#include "sysdep/sigcontext.h"
34574 +#include "sysdep/sc.h"
34576 +void arch_switch(void)
34578 + update_debugregs(current->thread.arch.debugregs_seq);
34581 +int is_syscall(unsigned long addr)
34583 + unsigned short instr;
34586 + n = copy_from_user(&instr, (void *) addr, sizeof(instr));
34588 + printk("is_syscall : failed to read instruction from 0x%lu\n",
34592 + return(instr == 0x80cd);
34595 +/* determines which flags the user has access to. */
34596 +/* 1 = access 0 = no access */
34597 +#define FLAG_MASK 0x00044dd5
34599 +int putreg(struct task_struct *child, int regno, unsigned long value)
34604 + if (value && (value & 3) != 3)
34606 + PT_REGS_FS(&child->thread.regs) = value;
34609 + if (value && (value & 3) != 3)
34611 + PT_REGS_GS(&child->thread.regs) = value;
34615 + if (value && (value & 3) != 3)
34621 + if ((value & 3) != 3)
34626 + value &= FLAG_MASK;
34627 + value |= PT_REGS_EFLAGS(&child->thread.regs);
34630 + PT_REGS_SET(&child->thread.regs, regno, value);
34634 +unsigned long getreg(struct task_struct *child, int regno)
34636 + unsigned long retval = ~0UL;
34647 + /* fall through */
34649 + retval &= PT_REG(&child->thread.regs, regno);
34654 +struct i387_fxsave_struct {
34655 + unsigned short cwd;
34656 + unsigned short swd;
34657 + unsigned short twd;
34658 + unsigned short fop;
34665 + long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
34666 + long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
34667 + long padding[56];
34671 + * FPU tag word conversions.
34674 +static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
34676 + unsigned int tmp; /* to avoid 16 bit prefixes in the code */
34678 + /* Transform each pair of bits into 01 (valid) or 00 (empty) */
34680 + tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
34681 + /* and move the valid bits to the lower byte. */
34682 + tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
34683 + tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
34684 + tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
34688 +static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
34690 + struct _fpxreg *st = NULL;
34691 + unsigned long twd = (unsigned long) fxsave->twd;
34692 + unsigned long tag;
34693 + unsigned long ret = 0xffff0000;
34696 +#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
34698 + for ( i = 0 ; i < 8 ; i++ ) {
34699 + if ( twd & 0x1 ) {
34700 + st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
34702 + switch ( st->exponent & 0x7fff ) {
34704 + tag = 2; /* Special */
34707 + if ( !st->significand[0] &&
34708 + !st->significand[1] &&
34709 + !st->significand[2] &&
34710 + !st->significand[3] ) {
34711 + tag = 1; /* Zero */
34713 + tag = 2; /* Special */
34717 + if ( st->significand[3] & 0x8000 ) {
34718 + tag = 0; /* Valid */
34720 + tag = 2; /* Special */
34725 + tag = 3; /* Empty */
34727 + ret |= (tag << (2 * i));
34734 + * FXSR floating point environment conversions.
34737 +#ifdef CONFIG_MODE_TT
34738 +static inline int convert_fxsr_to_user_tt(struct _fpstate *buf,
34739 + struct pt_regs *regs)
34741 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
34742 + unsigned long env[7];
34743 + struct _fpreg *to;
34744 + struct _fpxreg *from;
34747 + env[0] = (unsigned long)fxsave->cwd | 0xffff0000;
34748 + env[1] = (unsigned long)fxsave->swd | 0xffff0000;
34749 + env[2] = twd_fxsr_to_i387(fxsave);
34750 + env[3] = fxsave->fip;
34751 + env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
34752 + env[5] = fxsave->foo;
34753 + env[6] = fxsave->fos;
34755 + if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
34758 + to = &buf->_st[0];
34759 + from = (struct _fpxreg *) &fxsave->st_space[0];
34760 + for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
34761 + if ( __copy_to_user( to, from, sizeof(*to) ) )
34768 +static inline int convert_fxsr_to_user(struct _fpstate *buf,
34769 + struct pt_regs *regs)
34771 + return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0));
34774 +#ifdef CONFIG_MODE_TT
34775 +static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
34776 + struct _fpstate *buf)
34778 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
34779 + unsigned long env[7];
34780 + struct _fpxreg *to;
34781 + struct _fpreg *from;
34784 + if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
34787 + fxsave->cwd = (unsigned short)(env[0] & 0xffff);
34788 + fxsave->swd = (unsigned short)(env[1] & 0xffff);
34789 + fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
34790 + fxsave->fip = env[3];
34791 + fxsave->fop = (unsigned short)((env[4] & 0xffff0000) >> 16);
34792 + fxsave->fcs = (env[4] & 0xffff);
34793 + fxsave->foo = env[5];
34794 + fxsave->fos = env[6];
34796 + to = (struct _fpxreg *) &fxsave->st_space[0];
34797 + from = &buf->_st[0];
34798 + for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
34799 + if ( __copy_from_user( to, from, sizeof(*from) ) )
34806 +static inline int convert_fxsr_from_user(struct pt_regs *regs,
34807 + struct _fpstate *buf)
34809 + return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0));
34812 +int get_fpregs(unsigned long buf, struct task_struct *child)
34816 + err = convert_fxsr_to_user((struct _fpstate *) buf,
34817 + &child->thread.regs);
34818 + if(err) return(-EFAULT);
34822 +int set_fpregs(unsigned long buf, struct task_struct *child)
34826 + err = convert_fxsr_from_user(&child->thread.regs,
34827 + (struct _fpstate *) buf);
34828 + if(err) return(-EFAULT);
34832 +#ifdef CONFIG_MODE_TT
34833 +int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
34835 + struct pt_regs *regs = &tsk->thread.regs;
34836 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
34839 + err = __copy_to_user((void *) buf, fxsave,
34840 + sizeof(struct user_fxsr_struct));
34841 + if(err) return -EFAULT;
34846 +int get_fpxregs(unsigned long buf, struct task_struct *tsk)
34848 + return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0));
34851 +#ifdef CONFIG_MODE_TT
34852 +int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
34854 + struct pt_regs *regs = &tsk->thread.regs;
34855 + struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
34858 + err = __copy_from_user(fxsave, (void *) buf,
34859 + sizeof(struct user_fxsr_struct) );
34860 + if(err) return -EFAULT;
34865 +int set_fpxregs(unsigned long buf, struct task_struct *tsk)
34867 + return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0));
34871 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
34873 + fpu->cwd = (((SC_FP_CW(PT_REGS_SC(regs)) & 0xffff) << 16) |
34874 + (SC_FP_SW(PT_REGS_SC(regs)) & 0xffff));
34875 + fpu->swd = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
34876 + fpu->twd = SC_FP_IPOFF(PT_REGS_SC(regs));
34877 + fpu->fip = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
34878 + fpu->fcs = SC_FP_DATAOFF(PT_REGS_SC(regs));
34879 + fpu->foo = SC_FP_DATASEL(PT_REGS_SC(regs));
34881 + memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)),
34882 + sizeof(fpu->st_space));
34887 +#ifdef CONFIG_MODE_TT
34888 +static inline void copy_fpu_fxsave_tt(struct pt_regs *regs,
34889 + struct user_i387_struct *buf)
34891 + struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs));
34892 + unsigned short *to;
34893 + unsigned short *from;
34896 + memcpy( buf, fpu, 7 * sizeof(long) );
34898 + to = (unsigned short *) &buf->st_space[0];
34899 + from = (unsigned short *) &fpu->st_space[0];
34900 + for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) {
34901 + memcpy( to, from, 5 * sizeof(unsigned short) );
34906 +static inline void copy_fpu_fxsave(struct pt_regs *regs,
34907 + struct user_i387_struct *buf)
34909 + (void) CHOOSE_MODE(copy_fpu_fxsave_tt(regs, buf), 0);
34912 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
34914 + copy_fpu_fxsave(regs, (struct user_i387_struct *) fpu);
34919 + * Overrides for Emacs so that we follow Linus's tabbing style.
34920 + * Emacs will notice this stuff at the end of the file and automatically
34921 + * adjust the settings for this buffer only. This must remain at the end
34923 + * ---------------------------------------------------------------------------
34924 + * Local variables:
34925 + * c-file-style: "linux"
34928 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace_user.c um/arch/um/sys-i386/ptrace_user.c
34929 --- orig/arch/um/sys-i386/ptrace_user.c Wed Dec 31 19:00:00 1969
34930 +++ um/arch/um/sys-i386/ptrace_user.c Wed Oct 23 21:08:04 2002
34933 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34934 + * Licensed under the GPL
34937 +#include <stdio.h>
34938 +#include <errno.h>
34939 +#include <unistd.h>
34940 +#include <linux/stddef.h>
34941 +#include <sys/ptrace.h>
34942 +#include <asm/ptrace.h>
34943 +#include <asm/user.h>
34944 +#include "kern_util.h"
34945 +#include "sysdep/thread.h"
34949 +int ptrace_getregs(long pid, unsigned long *regs_out)
34951 + return(ptrace(PTRACE_GETREGS, pid, 0, regs_out));
34954 +int ptrace_setregs(long pid, unsigned long *regs)
34956 + return(ptrace(PTRACE_SETREGS, pid, 0, regs));
34959 +int ptrace_getfpregs(long pid, unsigned long *regs)
34961 + return(ptrace(PTRACE_GETFPREGS, pid, 0, regs));
34964 +static void write_debugregs(int pid, unsigned long *regs)
34966 + struct user *dummy;
34970 + nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
34971 + for(i = 0; i < nregs; i++){
34972 + if((i == 4) || (i == 5)) continue;
34973 + if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
34975 + printk("write_debugregs - ptrace failed, "
34976 + "errno = %d\n", errno);
34980 +static void read_debugregs(int pid, unsigned long *regs)
34982 + struct user *dummy;
34986 + nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
34987 + for(i = 0; i < nregs; i++){
34988 + regs[i] = ptrace(PTRACE_PEEKUSR, pid,
34989 + &dummy->u_debugreg[i], 0);
34993 +/* Accessed only by the tracing thread */
34994 +static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
34995 +static int debugregs_seq = 0;
34997 +void arch_enter_kernel(void *task, int pid)
34999 + read_debugregs(pid, TASK_DEBUGREGS(task));
35000 + write_debugregs(pid, kernel_debugregs);
35003 +void arch_leave_kernel(void *task, int pid)
35005 + read_debugregs(pid, kernel_debugregs);
35006 + write_debugregs(pid, TASK_DEBUGREGS(task));
35009 +void ptrace_pokeuser(unsigned long addr, unsigned long data)
35011 + if((addr < offsetof(struct user, u_debugreg[0])) ||
35012 + (addr > offsetof(struct user, u_debugreg[7])))
35014 + addr -= offsetof(struct user, u_debugreg[0]);
35015 + addr = addr >> 2;
35016 + if(kernel_debugregs[addr] == data) return;
35018 + kernel_debugregs[addr] = data;
35022 +static void update_debugregs_cb(void *arg)
35024 + int pid = *((int *) arg);
35026 + write_debugregs(pid, kernel_debugregs);
35029 +void update_debugregs(int seq)
35033 + if(seq == debugregs_seq) return;
35035 + me = os_getpid();
35036 + initial_thread_cb(update_debugregs_cb, &me);
35040 + * Overrides for Emacs so that we follow Linus's tabbing style.
35041 + * Emacs will notice this stuff at the end of the file and automatically
35042 + * adjust the settings for this buffer only. This must remain at the end
35044 + * ---------------------------------------------------------------------------
35045 + * Local variables:
35046 + * c-file-style: "linux"
35049 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sigcontext.c um/arch/um/sys-i386/sigcontext.c
35050 --- orig/arch/um/sys-i386/sigcontext.c Wed Dec 31 19:00:00 1969
35051 +++ um/arch/um/sys-i386/sigcontext.c Mon Dec 2 23:20:13 2002
35054 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
35055 + * Licensed under the GPL
35058 +#include <stddef.h>
35059 +#include <string.h>
35060 +#include <asm/ptrace.h>
35061 +#include <asm/sigcontext.h>
35062 +#include "sysdep/ptrace.h"
35063 +#include "kern_util.h"
35064 +#include "frame_user.h"
35066 +int sc_size(void *data)
35068 + struct arch_frame_data *arch = data;
35070 + return(sizeof(struct sigcontext) + arch->fpstate_size);
35073 +void sc_to_sc(void *to_ptr, void *from_ptr)
35075 + struct sigcontext *to = to_ptr, *from = from_ptr;
35076 + int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size;
35078 + memcpy(to, from, size);
35079 + if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1);
35082 +unsigned long *sc_sigmask(void *sc_ptr)
35084 + struct sigcontext *sc = sc_ptr;
35086 + return(&sc->oldmask);
35089 +int sc_get_fpregs(unsigned long buf, void *sc_ptr)
35091 + struct sigcontext *sc = sc_ptr;
35092 + struct _fpstate *from = sc->fpstate, *to = (struct _fpstate *) buf;
35095 + if(from == NULL){
35096 + err |= clear_user_proc(&to->cw, sizeof(to->cw));
35097 + err |= clear_user_proc(&to->sw, sizeof(to->sw));
35098 + err |= clear_user_proc(&to->tag, sizeof(to->tag));
35099 + err |= clear_user_proc(&to->ipoff, sizeof(to->ipoff));
35100 + err |= clear_user_proc(&to->cssel, sizeof(to->cssel));
35101 + err |= clear_user_proc(&to->dataoff, sizeof(to->dataoff));
35102 + err |= clear_user_proc(&to->datasel, sizeof(to->datasel));
35103 + err |= clear_user_proc(&to->_st, sizeof(to->_st));
35106 + err |= copy_to_user_proc(&to->cw, &from->cw, sizeof(to->cw));
35107 + err |= copy_to_user_proc(&to->sw, &from->sw, sizeof(to->sw));
35108 + err |= copy_to_user_proc(&to->tag, &from->tag,
35109 + sizeof(to->tag));
35110 + err |= copy_to_user_proc(&to->ipoff, &from->ipoff,
35111 + sizeof(to->ipoff));
35112 + err |= copy_to_user_proc(&to->cssel,& from->cssel,
35113 + sizeof(to->cssel));
35114 + err |= copy_to_user_proc(&to->dataoff, &from->dataoff,
35115 + sizeof(to->dataoff));
35116 + err |= copy_to_user_proc(&to->datasel, &from->datasel,
35117 + sizeof(to->datasel));
35118 + err |= copy_to_user_proc(to->_st, from->_st, sizeof(to->_st));
35124 + * Overrides for Emacs so that we follow Linus's tabbing style.
35125 + * Emacs will notice this stuff at the end of the file and automatically
35126 + * adjust the settings for this buffer only. This must remain at the end
35128 + * ---------------------------------------------------------------------------
35129 + * Local variables:
35130 + * c-file-style: "linux"
35133 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/syscalls.c um/arch/um/sys-i386/syscalls.c
35134 --- orig/arch/um/sys-i386/syscalls.c Wed Dec 31 19:00:00 1969
35135 +++ um/arch/um/sys-i386/syscalls.c Wed Oct 23 21:08:04 2002
35138 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
35139 + * Licensed under the GPL
35142 +#include "asm/mman.h"
35143 +#include "asm/uaccess.h"
35144 +#include "asm/unistd.h"
35147 + * Perform the select(nd, in, out, ex, tv) and mmap() system
35148 + * calls. Linux/i386 didn't use to be able to handle more than
35149 + * 4 system call parameters, so these system calls used a memory
35150 + * block for parameter passing..
35153 +struct mmap_arg_struct {
35154 + unsigned long addr;
35155 + unsigned long len;
35156 + unsigned long prot;
35157 + unsigned long flags;
35158 + unsigned long fd;
35159 + unsigned long offset;
35162 +extern int old_mmap(unsigned long addr, unsigned long len,
35163 + unsigned long prot, unsigned long flags,
35164 + unsigned long fd, unsigned long offset);
35166 +int old_mmap_i386(struct mmap_arg_struct *arg)
35168 + struct mmap_arg_struct a;
35169 + int err = -EFAULT;
35171 + if (copy_from_user(&a, arg, sizeof(a)))
35174 + err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
35179 +struct sel_arg_struct {
35181 + fd_set *inp, *outp, *exp;
35182 + struct timeval *tvp;
35185 +int old_select(struct sel_arg_struct *arg)
35187 + struct sel_arg_struct a;
35189 + if (copy_from_user(&a, arg, sizeof(a)))
35191 + /* sys_select() does the appropriate kernel locking */
35192 + return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
35196 + * Overrides for Emacs so that we follow Linus's tabbing style.
35197 + * Emacs will notice this stuff at the end of the file and automatically
35198 + * adjust the settings for this buffer only. This must remain at the end
35200 + * ---------------------------------------------------------------------------
35201 + * Local variables:
35202 + * c-file-style: "linux"
35205 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sysrq.c um/arch/um/sys-i386/sysrq.c
35206 --- orig/arch/um/sys-i386/sysrq.c Wed Dec 31 19:00:00 1969
35207 +++ um/arch/um/sys-i386/sysrq.c Wed Oct 23 21:08:04 2002
35209 +#include "linux/kernel.h"
35210 +#include "linux/smp.h"
35211 +#include "linux/sched.h"
35212 +#include "asm/ptrace.h"
35213 +#include "sysrq.h"
35215 +void show_regs(struct pt_regs *regs)
35218 + printk("EIP: %04lx:[<%08lx>] CPU: %d %s",
35219 + 0xffff & PT_REGS_CS(regs), PT_REGS_IP(regs),
35220 + smp_processor_id(), print_tainted());
35221 + if (PT_REGS_CS(regs) & 3)
35222 + printk(" ESP: %04lx:%08lx", 0xffff & PT_REGS_SS(regs),
35223 + PT_REGS_SP(regs));
35224 + printk(" EFLAGS: %08lx\n %s\n", PT_REGS_EFLAGS(regs),
35225 + print_tainted());
35226 + printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
35227 + PT_REGS_EAX(regs), PT_REGS_EBX(regs),
35228 + PT_REGS_ECX(regs),
35229 + PT_REGS_EDX(regs));
35230 + printk("ESI: %08lx EDI: %08lx EBP: %08lx",
35231 + PT_REGS_ESI(regs), PT_REGS_EDI(regs),
35232 + PT_REGS_EBP(regs));
35233 + printk(" DS: %04lx ES: %04lx\n",
35234 + 0xffff & PT_REGS_DS(regs),
35235 + 0xffff & PT_REGS_ES(regs));
35237 + show_trace((unsigned long *) ®s);
35239 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/Makefile um/arch/um/sys-i386/util/Makefile
35240 --- orig/arch/um/sys-i386/util/Makefile Wed Dec 31 19:00:00 1969
35241 +++ um/arch/um/sys-i386/util/Makefile Wed Oct 23 21:08:04 2002
35243 +EXE = mk_sc mk_thread
35245 +include $(TOPDIR)/Rules.make
35250 + $(CC) -o mk_sc mk_sc.o
35255 +mk_thread : mk_thread_user.o mk_thread_kern.o
35256 + $(CC) -o mk_thread mk_thread_user.o mk_thread_kern.o
35258 +mk_thread_user.o : mk_thread_user.c
35261 +mk_thread_kern.o : mk_thread_kern.c
35262 + $(CC) $(CFLAGS) -c $<
35267 +archmrproper : clean
35271 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/mk_sc.c um/arch/um/sys-i386/util/mk_sc.c
35272 --- orig/arch/um/sys-i386/util/mk_sc.c Wed Dec 31 19:00:00 1969
35273 +++ um/arch/um/sys-i386/util/mk_sc.c Wed Oct 23 21:08:04 2002
35275 +#include <stdio.h>
35276 +#include <signal.h>
35277 +#include <linux/stddef.h>
35279 +#define SC_OFFSET(name, field) \
35280 + printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
35281 + offsetof(struct sigcontext, field))
35283 +#define SC_FP_OFFSET(name, field) \
35284 + printf("#define " name \
35285 + "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
35286 + offsetof(struct _fpstate, field))
35288 +#define SC_FP_OFFSET_PTR(name, field, type) \
35289 + printf("#define " name \
35290 + "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
35291 + offsetof(struct _fpstate, field))
35293 +int main(int argc, char **argv)
35295 + SC_OFFSET("SC_IP", eip);
35296 + SC_OFFSET("SC_SP", esp);
35297 + SC_OFFSET("SC_FS", fs);
35298 + SC_OFFSET("SC_GS", gs);
35299 + SC_OFFSET("SC_DS", ds);
35300 + SC_OFFSET("SC_ES", es);
35301 + SC_OFFSET("SC_SS", ss);
35302 + SC_OFFSET("SC_CS", cs);
35303 + SC_OFFSET("SC_EFLAGS", eflags);
35304 + SC_OFFSET("SC_EAX", eax);
35305 + SC_OFFSET("SC_EBX", ebx);
35306 + SC_OFFSET("SC_ECX", ecx);
35307 + SC_OFFSET("SC_EDX", edx);
35308 + SC_OFFSET("SC_EDI", edi);
35309 + SC_OFFSET("SC_ESI", esi);
35310 + SC_OFFSET("SC_EBP", ebp);
35311 + SC_OFFSET("SC_TRAPNO", trapno);
35312 + SC_OFFSET("SC_ERR", err);
35313 + SC_OFFSET("SC_CR2", cr2);
35314 + SC_OFFSET("SC_FPSTATE", fpstate);
35315 + SC_FP_OFFSET("SC_FP_CW", cw);
35316 + SC_FP_OFFSET("SC_FP_SW", sw);
35317 + SC_FP_OFFSET("SC_FP_TAG", tag);
35318 + SC_FP_OFFSET("SC_FP_IPOFF", ipoff);
35319 + SC_FP_OFFSET("SC_FP_CSSEL", cssel);
35320 + SC_FP_OFFSET("SC_FP_DATAOFF", dataoff);
35321 + SC_FP_OFFSET("SC_FP_DATASEL", datasel);
35322 + SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate");
35323 + SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void");
35326 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
35327 --- orig/arch/um/sys-i386/util/mk_thread_kern.c Wed Dec 31 19:00:00 1969
35328 +++ um/arch/um/sys-i386/util/mk_thread_kern.c Mon Dec 9 23:24:38 2002
35330 +#include "linux/config.h"
35331 +#include "linux/stddef.h"
35332 +#include "linux/sched.h"
35334 +extern void print_head(void);
35335 +extern void print_constant_ptr(char *name, int value);
35336 +extern void print_constant(char *name, char *type, int value);
35337 +extern void print_tail(void);
35339 +#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
35341 +int main(int argc, char **argv)
35344 + print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs));
35345 +#ifdef CONFIG_MODE_TT
35346 + print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
35352 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
35353 --- orig/arch/um/sys-i386/util/mk_thread_user.c Wed Dec 31 19:00:00 1969
35354 +++ um/arch/um/sys-i386/util/mk_thread_user.c Wed Oct 23 21:08:04 2002
35356 +#include <stdio.h>
35358 +void print_head(void)
35361 + printf(" * Generated by mk_thread\n");
35364 + printf("#ifndef __UM_THREAD_H\n");
35365 + printf("#define __UM_THREAD_H\n");
35369 +void print_constant_ptr(char *name, int value)
35371 + printf("#define %s(task) ((unsigned long *) "
35372 + "&(((char *) (task))[%d]))\n", name, value);
35375 +void print_constant(char *name, char *type, int value)
35377 + printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
35381 +void print_tail(void)
35384 + printf("#endif\n");
35386 diff -Naur -X ../exclude-files orig/arch/um/sys-ia64/Makefile um/arch/um/sys-ia64/Makefile
35387 --- orig/arch/um/sys-ia64/Makefile Wed Dec 31 19:00:00 1969
35388 +++ um/arch/um/sys-ia64/Makefile Wed Oct 23 21:08:04 2002
35398 + $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
35408 + @$(MAKEBOOT) clean
35415 +include $(TOPDIR)/Rules.make
35416 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/Makefile um/arch/um/sys-ppc/Makefile
35417 --- orig/arch/um/sys-ppc/Makefile Wed Dec 31 19:00:00 1969
35418 +++ um/arch/um/sys-ppc/Makefile Wed Oct 23 21:08:04 2002
35423 + $(CC) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
35425 +OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \
35426 + ptrace_user.o sysrq.o
35428 +EXTRA_AFLAGS := -DCONFIG_ALL_PPC -I. -I$(TOPDIR)/arch/ppc/kernel
35434 + $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
35436 +ptrace_user.o: ptrace_user.c
35437 + $(CC) -D__KERNEL__ $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
35439 +sigcontext.o: sigcontext.c
35440 + $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
35444 + ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
35448 + ln -s $(TOPDIR)/arch/ppc/lib/$@ $@
35452 + ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
35456 + ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
35458 +ppc_defs.h: mk_defs.c ppc_defs.head \
35459 + $(TOPDIR)/include/asm-ppc/mmu.h \
35460 + $(TOPDIR)/include/asm-ppc/processor.h \
35461 + $(TOPDIR)/include/asm-ppc/pgtable.h \
35462 + $(TOPDIR)/include/asm-ppc/ptrace.h
35463 +# $(CC) $(CFLAGS) -S mk_defs.c
35464 + cp ppc_defs.head ppc_defs.h
35465 +# for bk, this way we can write to the file even if it's not checked out
35466 + echo '#define THREAD 608' >> ppc_defs.h
35467 + echo '#define PT_REGS 8' >> ppc_defs.h
35468 + echo '#define CLONE_VM 256' >> ppc_defs.h
35469 +# chmod u+w ppc_defs.h
35470 +# grep '^#define' mk_defs.s >> ppc_defs.h
35473 +# the asm link is horrible, and breaks the other targets. This is also
35474 +# not going to work with parallel makes.
35476 +checksum.o: checksum.S
35478 + ln -s $(TOPDIR)/include/asm-ppc asm
35479 + $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
35482 +misc.o: misc.S ppc_defs.h
35484 + ln -s $(TOPDIR)/include/asm-ppc asm
35485 + $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
35491 + rm -f checksum.S semaphore.c mk_defs.c
35499 +include $(TOPDIR)/Rules.make
35500 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/misc.S um/arch/um/sys-ppc/misc.S
35501 --- orig/arch/um/sys-ppc/misc.S Wed Dec 31 19:00:00 1969
35502 +++ um/arch/um/sys-ppc/misc.S Wed Oct 23 21:08:04 2002
35505 + * This file contains miscellaneous low-level functions.
35506 + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
35508 + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
35509 + * and Paul Mackerras.
35511 + * A couple of functions stolen from arch/ppc/kernel/misc.S for UML
35512 + * by Chris Emerson.
35514 + * This program is free software; you can redistribute it and/or
35515 + * modify it under the terms of the GNU General Public License
35516 + * as published by the Free Software Foundation; either version
35517 + * 2 of the License, or (at your option) any later version.
35521 +#include <linux/config.h>
35522 +#include <asm/processor.h>
35523 +#include "ppc_asm.h"
35525 +#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
35526 +#define CACHE_LINE_SIZE 16
35527 +#define LG_CACHE_LINE_SIZE 4
35528 +#define MAX_COPY_PREFETCH 1
35529 +#elif !defined(CONFIG_PPC64BRIDGE)
35530 +#define CACHE_LINE_SIZE 32
35531 +#define LG_CACHE_LINE_SIZE 5
35532 +#define MAX_COPY_PREFETCH 4
35534 +#define CACHE_LINE_SIZE 128
35535 +#define LG_CACHE_LINE_SIZE 7
35536 +#define MAX_COPY_PREFETCH 1
35537 +#endif /* CONFIG_4xx || CONFIG_8xx */
35542 + * Clear a page using the dcbz instruction, which doesn't cause any
35543 + * memory traffic (except to write out any cache lines which get
35544 + * displaced). This only works on cacheable memory.
35546 +_GLOBAL(clear_page)
35547 + li r0,4096/CACHE_LINE_SIZE
35558 + addi r3,r3,CACHE_LINE_SIZE
35563 + * Copy a whole page. We use the dcbz instruction on the destination
35564 + * to reduce memory traffic (it eliminates the unnecessary reads of
35565 + * the destination into cache). This requires that the destination
35568 +#define COPY_16_BYTES \
35572 + lwzu r9,16(r4); \
35578 +_GLOBAL(copy_page)
35583 +#ifndef CONFIG_8xx
35584 +#if MAX_COPY_PREFETCH > 1
35585 + li r0,MAX_COPY_PREFETCH
35589 + addi r11,r11,CACHE_LINE_SIZE
35591 +#else /* MAX_COPY_PREFETCH == 1 */
35593 + li r11,CACHE_LINE_SIZE+4
35594 +#endif /* MAX_COPY_PREFETCH */
35595 +#endif /* CONFIG_8xx */
35597 + li r0,4096/CACHE_LINE_SIZE
35600 +#ifndef CONFIG_8xx
35605 +#if CACHE_LINE_SIZE >= 32
35607 +#if CACHE_LINE_SIZE >= 64
35610 +#if CACHE_LINE_SIZE >= 128
35620 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/miscthings.c um/arch/um/sys-ppc/miscthings.c
35621 --- orig/arch/um/sys-ppc/miscthings.c Wed Dec 31 19:00:00 1969
35622 +++ um/arch/um/sys-ppc/miscthings.c Wed Oct 23 21:08:04 2002
35624 +#include "linux/threads.h"
35625 +#include "linux/stddef.h" // for NULL
35626 +#include "linux/elf.h" // for AT_NULL
35628 +/* The following function nicked from arch/ppc/kernel/process.c and
35629 + * adapted slightly */
35631 + * XXX ld.so expects the auxiliary table to start on
35632 + * a 16-byte boundary, so we have to find it and
35633 + * move it up. :-(
35635 +void shove_aux_table(unsigned long sp)
35640 + unsigned long aux_start, offset;
35642 + argc = *(int *)sp;
35643 + sp += sizeof(int) + (argc + 1) * sizeof(char *);
35644 + /* skip over the environment pointers */
35646 + p = *(char **)sp;
35647 + sp += sizeof(char *);
35648 + } while (p != NULL);
35650 + /* skip to the end of the auxiliary table */
35652 + e = *(unsigned long *)sp;
35653 + sp += 2 * sizeof(unsigned long);
35654 + } while (e != AT_NULL);
35655 + offset = ((aux_start + 15) & ~15) - aux_start;
35656 + if (offset != 0) {
35658 + sp -= sizeof(unsigned long);
35659 + e = *(unsigned long *)sp;
35660 + *(unsigned long *)(sp + offset) = e;
35661 + } while (sp > aux_start);
35664 +/* END stuff taken from arch/ppc/kernel/process.c */
35668 + * Overrides for Emacs so that we follow Linus's tabbing style.
35669 + * Emacs will notice this stuff at the end of the file and automatically
35670 + * adjust the settings for this buffer only. This must remain at the end
35672 + * ---------------------------------------------------------------------------
35673 + * Local variables:
35674 + * c-file-style: "linux"
35677 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace.c um/arch/um/sys-ppc/ptrace.c
35678 --- orig/arch/um/sys-ppc/ptrace.c Wed Dec 31 19:00:00 1969
35679 +++ um/arch/um/sys-ppc/ptrace.c Wed Oct 23 21:08:04 2002
35681 +#include "linux/sched.h"
35682 +#include "asm/ptrace.h"
35684 +int putreg(struct task_struct *child, unsigned long regno,
35685 + unsigned long value)
35687 + child->thread.process_regs.regs[regno >> 2] = value;
35691 +unsigned long getreg(struct task_struct *child, unsigned long regno)
35693 + unsigned long retval = ~0UL;
35695 + retval &= child->thread.process_regs.regs[regno >> 2];
35700 + * Overrides for Emacs so that we follow Linus's tabbing style.
35701 + * Emacs will notice this stuff at the end of the file and automatically
35702 + * adjust the settings for this buffer only. This must remain at the end
35704 + * ---------------------------------------------------------------------------
35705 + * Local variables:
35706 + * c-file-style: "linux"
35709 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace_user.c um/arch/um/sys-ppc/ptrace_user.c
35710 --- orig/arch/um/sys-ppc/ptrace_user.c Wed Dec 31 19:00:00 1969
35711 +++ um/arch/um/sys-ppc/ptrace_user.c Wed Oct 23 21:08:04 2002
35713 +#include <sys/ptrace.h>
35714 +#include <errno.h>
35715 +#include <asm/ptrace.h>
35716 +#include "sysdep/ptrace.h"
35718 +int ptrace_getregs(long pid, unsigned long *regs_out)
35721 + for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
35723 + regs_out->regs[i] = ptrace(PTRACE_PEEKUSER, pid, i*4, 0);
35731 +int ptrace_setregs(long pid, unsigned long *regs_in)
35734 + for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
35735 + if (i != 34 /* FIXME: PT_ORIG_R3 */ && i <= PT_MQ) {
35736 + if (ptrace(PTRACE_POKEUSER, pid, i*4, regs_in->regs[i]) < 0) {
35744 + * Overrides for Emacs so that we follow Linus's tabbing style.
35745 + * Emacs will notice this stuff at the end of the file and automatically
35746 + * adjust the settings for this buffer only. This must remain at the end
35748 + * ---------------------------------------------------------------------------
35749 + * Local variables:
35750 + * c-file-style: "linux"
35753 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sigcontext.c um/arch/um/sys-ppc/sigcontext.c
35754 --- orig/arch/um/sys-ppc/sigcontext.c Wed Dec 31 19:00:00 1969
35755 +++ um/arch/um/sys-ppc/sigcontext.c Wed Oct 23 21:08:04 2002
35757 +#include "asm/ptrace.h"
35758 +#include "asm/sigcontext.h"
35759 +#include "sysdep/ptrace.h"
35760 +#include "user_util.h"
35763 + * Overrides for Emacs so that we follow Linus's tabbing style.
35764 + * Emacs will notice this stuff at the end of the file and automatically
35765 + * adjust the settings for this buffer only. This must remain at the end
35767 + * ---------------------------------------------------------------------------
35768 + * Local variables:
35769 + * c-file-style: "linux"
35772 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sysrq.c um/arch/um/sys-ppc/sysrq.c
35773 --- orig/arch/um/sys-ppc/sysrq.c Wed Dec 31 19:00:00 1969
35774 +++ um/arch/um/sys-ppc/sysrq.c Wed Oct 23 21:08:04 2002
35777 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
35778 + * Licensed under the GPL
35781 +#include "linux/kernel.h"
35782 +#include "linux/smp.h"
35783 +#include "asm/ptrace.h"
35784 +#include "sysrq.h"
35786 +void show_regs(struct pt_regs_subarch *regs)
35789 + printk("show_regs(): insert regs here.\n");
35792 + printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs, regs->eip,
35793 + smp_processor_id());
35794 + if (regs->xcs & 3)
35795 + printk(" ESP: %04x:%08lx",0xffff & regs->xss, regs->esp);
35796 + printk(" EFLAGS: %08lx\n", regs->eflags);
35797 + printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
35798 + regs->eax, regs->ebx, regs->ecx, regs->edx);
35799 + printk("ESI: %08lx EDI: %08lx EBP: %08lx",
35800 + regs->esi, regs->edi, regs->ebp);
35801 + printk(" DS: %04x ES: %04x\n",
35802 + 0xffff & regs->xds, 0xffff & regs->xes);
35805 + show_trace(®s->gpr[1]);
35810 + * Overrides for Emacs so that we follow Linus's tabbing style.
35811 + * Emacs will notice this stuff at the end of the file and automatically
35812 + * adjust the settings for this buffer only. This must remain at the end
35814 + * ---------------------------------------------------------------------------
35815 + * Local variables:
35816 + * c-file-style: "linux"
35819 diff -Naur -X ../exclude-files orig/arch/um/util/Makefile um/arch/um/util/Makefile
35820 --- orig/arch/um/util/Makefile Wed Dec 31 19:00:00 1969
35821 +++ um/arch/um/util/Makefile Wed Oct 23 21:09:14 2002
35823 +ALL = mk_task mk_constants
35827 +mk_task : mk_task_user.o mk_task_kern.o
35828 + $(CC) -o mk_task mk_task_user.o mk_task_kern.o
35830 +mk_task_user.o : mk_task_user.c
35833 +mk_task_kern.o : mk_task_kern.c
35834 + $(CC) $(CFLAGS) -c $<
35836 +mk_constants : mk_constants_user.o mk_constants_kern.o
35837 + $(CC) -o mk_constants mk_constants_user.o mk_constants_kern.o
35839 +mk_constants_user.o : mk_constants_user.c
35842 +mk_constants_kern.o : mk_constants_kern.c
35843 + $(CC) $(CFLAGS) -c $<
35846 + $(RM) $(ALL) *.o *~
35848 +archmrproper : clean
35849 diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_kern.c um/arch/um/util/mk_constants_kern.c
35850 --- orig/arch/um/util/mk_constants_kern.c Wed Dec 31 19:00:00 1969
35851 +++ um/arch/um/util/mk_constants_kern.c Wed Oct 23 21:08:04 2002
35853 +#include "linux/kernel.h"
35854 +#include "linux/stringify.h"
35855 +#include "asm/page.h"
35857 +extern void print_head(void);
35858 +extern void print_constant_str(char *name, char *value);
35859 +extern void print_constant_int(char *name, int value);
35860 +extern void print_tail(void);
35862 +int main(int argc, char **argv)
35865 + print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
35866 + print_constant_str("UM_KERN_EMERG", KERN_EMERG);
35867 + print_constant_str("UM_KERN_ALERT", KERN_ALERT);
35868 + print_constant_str("UM_KERN_CRIT", KERN_CRIT);
35869 + print_constant_str("UM_KERN_ERR", KERN_ERR);
35870 + print_constant_str("UM_KERN_WARNING", KERN_WARNING);
35871 + print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
35872 + print_constant_str("UM_KERN_INFO", KERN_INFO);
35873 + print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
35877 diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_user.c um/arch/um/util/mk_constants_user.c
35878 --- orig/arch/um/util/mk_constants_user.c Wed Dec 31 19:00:00 1969
35879 +++ um/arch/um/util/mk_constants_user.c Wed Oct 23 21:08:04 2002
35881 +#include <stdio.h>
35883 +void print_head(void)
35886 + printf(" * Generated by mk_constants\n");
35889 + printf("#ifndef __UM_CONSTANTS_H\n");
35890 + printf("#define __UM_CONSTANTS_H\n");
35894 +void print_constant_str(char *name, char *value)
35896 + printf("#define %s \"%s\"\n", name, value);
35899 +void print_constant_int(char *name, int value)
35901 + printf("#define %s %d\n", name, value);
35904 +void print_tail(void)
35907 + printf("#endif\n");
35909 diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_kern.c um/arch/um/util/mk_task_kern.c
35910 --- orig/arch/um/util/mk_task_kern.c Wed Dec 31 19:00:00 1969
35911 +++ um/arch/um/util/mk_task_kern.c Sun Dec 8 21:03:34 2002
35913 +#include "linux/sched.h"
35914 +#include "linux/stddef.h"
35916 +extern void print(char *name, char *type, int offset);
35917 +extern void print_ptr(char *name, char *type, int offset);
35918 +extern void print_head(void);
35919 +extern void print_tail(void);
35921 +int main(int argc, char **argv)
35924 + print_ptr("TASK_REGS", "union uml_pt_regs",
35925 + offsetof(struct task_struct, thread.regs));
35926 + print("TASK_PID", "int", offsetof(struct task_struct, pid));
35930 diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_user.c um/arch/um/util/mk_task_user.c
35931 --- orig/arch/um/util/mk_task_user.c Wed Dec 31 19:00:00 1969
35932 +++ um/arch/um/util/mk_task_user.c Wed Oct 23 21:08:04 2002
35934 +#include <stdio.h>
35936 +void print(char *name, char *type, int offset)
35938 + printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
35942 +void print_ptr(char *name, char *type, int offset)
35944 + printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
35948 +void print_head(void)
35951 + printf(" * Generated by mk_task\n");
35954 + printf("#ifndef __TASK_H\n");
35955 + printf("#define __TASK_H\n");
35959 +void print_tail(void)
35962 + printf("#endif\n");
35964 diff -Naur -X ../exclude-files orig/drivers/char/Makefile um/drivers/char/Makefile
35965 --- orig/drivers/char/Makefile Thu Feb 27 13:04:15 2003
35966 +++ um/drivers/char/Makefile Thu Feb 27 13:05:21 2003
35980 diff -Naur -X ../exclude-files orig/drivers/char/tty_io.c um/drivers/char/tty_io.c
35981 --- orig/drivers/char/tty_io.c Thu Feb 27 13:04:15 2003
35982 +++ um/drivers/char/tty_io.c Thu Feb 27 13:05:21 2003
35983 @@ -637,6 +637,9 @@
35984 wake_up_interruptible(&tty->write_wait);
35987 +extern int write_tty_log(int fd, const unsigned char *buf, int len, void *tty,
35990 static ssize_t tty_read(struct file * file, char * buf, size_t count,
35993 @@ -677,8 +680,13 @@
35999 inode->i_atime = CURRENT_TIME;
36000 +#ifdef CONFIG_TTY_LOG
36001 + if(tty->log_fd >= 0)
36002 + write_tty_log(tty->log_fd, buf, i, tty, 1);
36008 @@ -732,6 +740,10 @@
36010 file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
36012 +#ifdef CONFIG_TTY_LOG
36013 + if(tty->log_fd >= 0)
36014 + write_tty_log(tty->log_fd, buf - ret, ret, tty, 0);
36017 up(&tty->atomic_write);
36019 @@ -945,6 +957,9 @@
36020 goto release_mem_out;
36023 +#ifdef CONFIG_TTY_LOG
36024 + tty->log_fd = -1;
36029 @@ -1039,6 +1054,8 @@
36030 free_tty_struct(tty);
36033 +extern int close_tty_log(int fd, void *tty);
36036 * Even releasing the tty structures is a tricky business.. We have
36037 * to be very careful that the structures are all released at the
36038 @@ -1267,6 +1284,10 @@
36039 run_task_queue(&tq_timer);
36040 flush_scheduled_tasks();
36042 +#ifdef CONFIG_TTY_LOG
36043 + if(tty->log_fd >= 0) close_tty_log(tty->log_fd, tty);
36047 * The release_mem function takes care of the details of clearing
36048 * the slots and preserving the termios structure.
36049 @@ -1274,6 +1295,8 @@
36050 release_mem(tty, idx);
36053 +extern int open_tty_log(void *tty, void *current_tty);
36056 * tty_open and tty_release keep up the tty count that contains the
36057 * number of opens done on a tty. We cannot use the inode-count, as
36058 @@ -1425,6 +1448,11 @@
36063 +#ifdef CONFIG_TTY_LOG
36064 + if(tty->log_fd < 0)
36065 + tty->log_fd = open_tty_log(tty, current->tty);
36070 diff -Naur -X ../exclude-files orig/drivers/net/setup.c um/drivers/net/setup.c
36071 --- orig/drivers/net/setup.c Sun Sep 15 12:13:19 2002
36072 +++ um/drivers/net/setup.c Wed Oct 23 21:08:05 2002
36074 extern int lmc_setup(void);
36076 extern int madgemc_probe(void);
36077 -extern int uml_net_probe(void);
36079 /* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is string of 9 zeros. */
36080 #define __PAD6 "\0\0\0\0\0\0\0\0\0"
36081 @@ -102,9 +101,6 @@
36083 #ifdef CONFIG_MADGEMC
36084 {madgemc_probe, 0},
36086 -#ifdef CONFIG_UML_NET
36087 - {uml_net_probe, 0},
36091 diff -Naur -X ../exclude-files orig/include/asm-i386/hardirq.h um/include/asm-i386/hardirq.h
36092 --- orig/include/asm-i386/hardirq.h Sun Sep 15 12:13:19 2002
36093 +++ um/include/asm-i386/hardirq.h Wed Apr 16 13:59:04 2003
36095 #include <linux/config.h>
36096 #include <linux/threads.h>
36097 #include <linux/irq.h>
36098 +#include <asm/processor.h> /* for cpu_relax */
36100 /* assembly code in softirq.h is sensitive to the offsets of these fields */
36102 diff -Naur -X ../exclude-files orig/include/asm-um/a.out.h um/include/asm-um/a.out.h
36103 --- orig/include/asm-um/a.out.h Wed Dec 31 19:00:00 1969
36104 +++ um/include/asm-um/a.out.h Sun Oct 27 11:54:50 2002
36106 +#ifndef __UM_A_OUT_H
36107 +#define __UM_A_OUT_H
36109 +#include "linux/config.h"
36110 +#include "asm/arch/a.out.h"
36111 +#include "choose-mode.h"
36115 +extern unsigned long stacksizelim;
36117 +extern unsigned long host_task_size;
36119 +#define STACK_ROOM (stacksizelim)
36121 +extern int honeypot;
36122 +#define STACK_TOP \
36123 + CHOOSE_MODE((honeypot ? host_task_size : task_size), task_size)
36126 diff -Naur -X ../exclude-files orig/include/asm-um/arch-signal-i386.h um/include/asm-um/arch-signal-i386.h
36127 --- orig/include/asm-um/arch-signal-i386.h Wed Dec 31 19:00:00 1969
36128 +++ um/include/asm-um/arch-signal-i386.h Wed Oct 23 21:08:05 2002
36131 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36132 + * Licensed under the GPL
36135 +#ifndef __UM_ARCH_SIGNAL_I386_H
36136 +#define __UM_ARCH_SIGNAL_I386_H
36138 +struct arch_signal_context {
36139 + unsigned long extrasigs[_NSIG_WORDS];
36145 + * Overrides for Emacs so that we follow Linus's tabbing style.
36146 + * Emacs will notice this stuff at the end of the file and automatically
36147 + * adjust the settings for this buffer only. This must remain at the end
36149 + * ---------------------------------------------------------------------------
36150 + * Local variables:
36151 + * c-file-style: "linux"
36154 diff -Naur -X ../exclude-files orig/include/asm-um/archparam-i386.h um/include/asm-um/archparam-i386.h
36155 --- orig/include/asm-um/archparam-i386.h Wed Dec 31 19:00:00 1969
36156 +++ um/include/asm-um/archparam-i386.h Sun Dec 8 20:09:11 2002
36159 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
36160 + * Licensed under the GPL
36163 +#ifndef __UM_ARCHPARAM_I386_H
36164 +#define __UM_ARCHPARAM_I386_H
36166 +/********* Bits for asm-um/elf.h ************/
36170 +#define ELF_PLATFORM "i586"
36172 +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
36174 +typedef struct user_i387_struct elf_fpregset_t;
36175 +typedef unsigned long elf_greg_t;
36177 +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
36178 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
36180 +#define ELF_DATA ELFDATA2LSB
36181 +#define ELF_ARCH EM_386
36183 +#define ELF_PLAT_INIT(regs) do { \
36184 + PT_REGS_EBX(regs) = 0; \
36185 + PT_REGS_ECX(regs) = 0; \
36186 + PT_REGS_EDX(regs) = 0; \
36187 + PT_REGS_ESI(regs) = 0; \
36188 + PT_REGS_EDI(regs) = 0; \
36189 + PT_REGS_EBP(regs) = 0; \
36190 + PT_REGS_EAX(regs) = 0; \
36193 +/* Shamelessly stolen from include/asm-i386/elf.h */
36195 +#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \
36196 + pr_reg[0] = PT_REGS_EBX(regs); \
36197 + pr_reg[1] = PT_REGS_ECX(regs); \
36198 + pr_reg[2] = PT_REGS_EDX(regs); \
36199 + pr_reg[3] = PT_REGS_ESI(regs); \
36200 + pr_reg[4] = PT_REGS_EDI(regs); \
36201 + pr_reg[5] = PT_REGS_EBP(regs); \
36202 + pr_reg[6] = PT_REGS_EAX(regs); \
36203 + pr_reg[7] = PT_REGS_DS(regs); \
36204 + pr_reg[8] = PT_REGS_ES(regs); \
36205 + /* fake once used fs and gs selectors? */ \
36206 + pr_reg[9] = PT_REGS_DS(regs); \
36207 + pr_reg[10] = PT_REGS_DS(regs); \
36208 + pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \
36209 + pr_reg[12] = PT_REGS_IP(regs); \
36210 + pr_reg[13] = PT_REGS_CS(regs); \
36211 + pr_reg[14] = PT_REGS_EFLAGS(regs); \
36212 + pr_reg[15] = PT_REGS_SP(regs); \
36213 + pr_reg[16] = PT_REGS_SS(regs); \
36216 +/********* Bits for asm-um/delay.h **********/
36218 +typedef unsigned long um_udelay_t;
36220 +/********* Nothing for asm-um/hardirq.h **********/
36222 +/********* Nothing for asm-um/hw_irq.h **********/
36224 +/********* Nothing for asm-um/string.h **********/
36229 + * Overrides for Emacs so that we follow Linus's tabbing style.
36230 + * Emacs will notice this stuff at the end of the file and automatically
36231 + * adjust the settings for this buffer only. This must remain at the end
36233 + * ---------------------------------------------------------------------------
36234 + * Local variables:
36235 + * c-file-style: "linux"
36238 diff -Naur -X ../exclude-files orig/include/asm-um/archparam-ppc.h um/include/asm-um/archparam-ppc.h
36239 --- orig/include/asm-um/archparam-ppc.h Wed Dec 31 19:00:00 1969
36240 +++ um/include/asm-um/archparam-ppc.h Wed Oct 23 21:08:05 2002
36242 +#ifndef __UM_ARCHPARAM_PPC_H
36243 +#define __UM_ARCHPARAM_PPC_H
36245 +/********* Bits for asm-um/elf.h ************/
36247 +#define ELF_PLATFORM (0)
36249 +#define ELF_ET_DYN_BASE (0x08000000)
36251 +/* the following stolen from asm-ppc/elf.h */
36252 +#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
36253 +#define ELF_NFPREG 33 /* includes fpscr */
36254 +/* General registers */
36255 +typedef unsigned long elf_greg_t;
36256 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
36258 +/* Floating point registers */
36259 +typedef double elf_fpreg_t;
36260 +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
36262 +#define ELF_DATA ELFDATA2MSB
36263 +#define ELF_ARCH EM_PPC
36265 +/********* Bits for asm-um/delay.h **********/
36267 +typedef unsigned int um_udelay_t;
36269 +/********* Bits for asm-um/hw_irq.h **********/
36271 +struct hw_interrupt_type;
36273 +/********* Bits for asm-um/hardirq.h **********/
36275 +#define irq_enter(cpu, irq) hardirq_enter(cpu)
36276 +#define irq_exit(cpu, irq) hardirq_exit(cpu)
36278 +/********* Bits for asm-um/string.h **********/
36280 +#define __HAVE_ARCH_STRRCHR
36283 diff -Naur -X ../exclude-files orig/include/asm-um/atomic.h um/include/asm-um/atomic.h
36284 --- orig/include/asm-um/atomic.h Wed Dec 31 19:00:00 1969
36285 +++ um/include/asm-um/atomic.h Wed Mar 26 22:01:25 2003
36287 +#ifndef __UM_ATOMIC_H
36288 +#define __UM_ATOMIC_H
36290 +#include "asm/arch/atomic.h"
36293 diff -Naur -X ../exclude-files orig/include/asm-um/bitops.h um/include/asm-um/bitops.h
36294 --- orig/include/asm-um/bitops.h Wed Dec 31 19:00:00 1969
36295 +++ um/include/asm-um/bitops.h Wed Mar 26 22:01:25 2003
36297 +#ifndef __UM_BITOPS_H
36298 +#define __UM_BITOPS_H
36300 +#include "asm/arch/bitops.h"
36303 diff -Naur -X ../exclude-files orig/include/asm-um/boot.h um/include/asm-um/boot.h
36304 --- orig/include/asm-um/boot.h Wed Dec 31 19:00:00 1969
36305 +++ um/include/asm-um/boot.h Wed Oct 23 21:08:05 2002
36307 +#ifndef __UM_BOOT_H
36308 +#define __UM_BOOT_H
36310 +#include "asm/arch/boot.h"
36313 diff -Naur -X ../exclude-files orig/include/asm-um/bugs.h um/include/asm-um/bugs.h
36314 --- orig/include/asm-um/bugs.h Wed Dec 31 19:00:00 1969
36315 +++ um/include/asm-um/bugs.h Wed Oct 23 21:08:05 2002
36317 +#ifndef __UM_BUGS_H
36318 +#define __UM_BUGS_H
36320 +void check_bugs(void);
36323 diff -Naur -X ../exclude-files orig/include/asm-um/byteorder.h um/include/asm-um/byteorder.h
36324 --- orig/include/asm-um/byteorder.h Wed Dec 31 19:00:00 1969
36325 +++ um/include/asm-um/byteorder.h Thu Feb 27 13:20:12 2003
36327 +#ifndef __UM_BYTEORDER_H
36328 +#define __UM_BYTEORDER_H
36330 +#include "asm/arch/byteorder.h"
36333 diff -Naur -X ../exclude-files orig/include/asm-um/cache.h um/include/asm-um/cache.h
36334 --- orig/include/asm-um/cache.h Wed Dec 31 19:00:00 1969
36335 +++ um/include/asm-um/cache.h Wed Oct 23 21:08:05 2002
36337 +#ifndef __UM_CACHE_H
36338 +#define __UM_CACHE_H
36340 +#define L1_CACHE_BYTES 32
36343 diff -Naur -X ../exclude-files orig/include/asm-um/checksum.h um/include/asm-um/checksum.h
36344 --- orig/include/asm-um/checksum.h Wed Dec 31 19:00:00 1969
36345 +++ um/include/asm-um/checksum.h Tue Oct 29 17:25:12 2002
36347 +#ifndef __UM_CHECKSUM_H
36348 +#define __UM_CHECKSUM_H
36350 +#include "sysdep/checksum.h"
36353 diff -Naur -X ../exclude-files orig/include/asm-um/cobalt.h um/include/asm-um/cobalt.h
36354 --- orig/include/asm-um/cobalt.h Wed Dec 31 19:00:00 1969
36355 +++ um/include/asm-um/cobalt.h Wed Oct 23 21:08:05 2002
36357 +#ifndef __UM_COBALT_H
36358 +#define __UM_COBALT_H
36360 +#include "asm/arch/cobalt.h"
36363 diff -Naur -X ../exclude-files orig/include/asm-um/current.h um/include/asm-um/current.h
36364 --- orig/include/asm-um/current.h Wed Dec 31 19:00:00 1969
36365 +++ um/include/asm-um/current.h Wed Mar 26 22:01:25 2003
36368 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
36369 + * Licensed under the GPL
36372 +#ifndef __UM_CURRENT_H
36373 +#define __UM_CURRENT_H
36375 +#ifndef __ASSEMBLY__
36377 +#include "linux/config.h"
36378 +#include "asm/page.h"
36380 +struct task_struct;
36382 +#define CURRENT_TASK(dummy) (((unsigned long) &dummy) & \
36383 + (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
36385 +#define current ({ int dummy; (struct task_struct *) CURRENT_TASK(dummy); })
36387 +#endif /* __ASSEMBLY__ */
36392 + * Overrides for Emacs so that we follow Linus's tabbing style.
36393 + * Emacs will notice this stuff at the end of the file and automatically
36394 + * adjust the settings for this buffer only. This must remain at the end
36396 + * ---------------------------------------------------------------------------
36397 + * Local variables:
36398 + * c-file-style: "linux"
36401 diff -Naur -X ../exclude-files orig/include/asm-um/delay.h um/include/asm-um/delay.h
36402 --- orig/include/asm-um/delay.h Wed Dec 31 19:00:00 1969
36403 +++ um/include/asm-um/delay.h Sun Dec 8 20:09:15 2002
36405 +#ifndef __UM_DELAY_H
36406 +#define __UM_DELAY_H
36408 +#include "asm/arch/delay.h"
36409 +#include "asm/archparam.h"
36412 diff -Naur -X ../exclude-files orig/include/asm-um/desc.h um/include/asm-um/desc.h
36413 --- orig/include/asm-um/desc.h Wed Dec 31 19:00:00 1969
36414 +++ um/include/asm-um/desc.h Wed Oct 23 21:08:05 2002
36416 +#ifndef __UM_DESC_H
36417 +#define __UM_DESC_H
36419 +#include "asm/arch/desc.h"
36422 diff -Naur -X ../exclude-files orig/include/asm-um/div64.h um/include/asm-um/div64.h
36423 --- orig/include/asm-um/div64.h Wed Dec 31 19:00:00 1969
36424 +++ um/include/asm-um/div64.h Wed Oct 23 21:08:05 2002
36426 +#ifndef _UM_DIV64_H
36427 +#define _UM_DIV64_H
36429 +#include "asm/arch/div64.h"
36432 diff -Naur -X ../exclude-files orig/include/asm-um/dma.h um/include/asm-um/dma.h
36433 --- orig/include/asm-um/dma.h Wed Dec 31 19:00:00 1969
36434 +++ um/include/asm-um/dma.h Sun Oct 27 16:53:42 2002
36436 +#ifndef __UM_DMA_H
36437 +#define __UM_DMA_H
36439 +#include "asm/io.h"
36441 +extern unsigned long uml_physmem;
36443 +#define MAX_DMA_ADDRESS (uml_physmem)
36446 diff -Naur -X ../exclude-files orig/include/asm-um/elf.h um/include/asm-um/elf.h
36447 --- orig/include/asm-um/elf.h Wed Dec 31 19:00:00 1969
36448 +++ um/include/asm-um/elf.h Sun Dec 8 20:13:07 2002
36450 +#ifndef __UM_ELF_H
36451 +#define __UM_ELF_H
36453 +#include "asm/archparam.h"
36455 +#define ELF_HWCAP (0)
36457 +#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
36459 +#define ELF_EXEC_PAGESIZE 4096
36461 +#define elf_check_arch(x) (1)
36463 +#define ELF_CLASS ELFCLASS32
36465 +#define USE_ELF_CORE_DUMP
36468 diff -Naur -X ../exclude-files orig/include/asm-um/errno.h um/include/asm-um/errno.h
36469 --- orig/include/asm-um/errno.h Wed Dec 31 19:00:00 1969
36470 +++ um/include/asm-um/errno.h Wed Oct 23 21:08:05 2002
36472 +#ifndef __UM_ERRNO_H
36473 +#define __UM_ERRNO_H
36475 +#include "asm/arch/errno.h"
36478 diff -Naur -X ../exclude-files orig/include/asm-um/fcntl.h um/include/asm-um/fcntl.h
36479 --- orig/include/asm-um/fcntl.h Wed Dec 31 19:00:00 1969
36480 +++ um/include/asm-um/fcntl.h Wed Oct 23 21:08:05 2002
36482 +#ifndef __UM_FCNTL_H
36483 +#define __UM_FCNTL_H
36485 +#include "asm/arch/fcntl.h"
36488 diff -Naur -X ../exclude-files orig/include/asm-um/fixmap.h um/include/asm-um/fixmap.h
36489 --- orig/include/asm-um/fixmap.h Wed Dec 31 19:00:00 1969
36490 +++ um/include/asm-um/fixmap.h Wed Mar 26 22:01:27 2003
36492 +#ifndef __UM_FIXMAP_H
36493 +#define __UM_FIXMAP_H
36495 +#include <linux/config.h>
36496 +#include <asm/kmap_types.h>
36499 + * Here we define all the compile-time 'special' virtual
36500 + * addresses. The point is to have a constant address at
36501 + * compile time, but to set the physical address only
36502 + * in the boot process. We allocate these special addresses
36503 + * from the end of virtual memory (0xfffff000) backwards.
36504 + * Also this lets us do fail-safe vmalloc(), we
36505 + * can guarantee that these special addresses and
36506 + * vmalloc()-ed addresses never overlap.
36508 + * these 'compile-time allocated' memory buffers are
36509 + * fixed-size 4k pages. (or larger if used with an increment
36510 + * highger than 1) use fixmap_set(idx,phys) to associate
36511 + * physical memory with fixmap indices.
36513 + * TLB entries of such buffers will not be flushed across
36518 + * on UP currently we will have no trace of the fixmap mechanizm,
36519 + * no page table allocations, etc. This might change in the
36520 + * future, say framebuffers for the console driver(s) could be
36523 +enum fixed_addresses {
36524 +#ifdef CONFIG_HIGHMEM
36525 + FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
36526 + FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
36528 + __end_of_fixed_addresses
36531 +extern void __set_fixmap (enum fixed_addresses idx,
36532 + unsigned long phys, pgprot_t flags);
36534 +#define set_fixmap(idx, phys) \
36535 + __set_fixmap(idx, phys, PAGE_KERNEL)
36537 + * Some hardware wants to get fixmapped without caching.
36539 +#define set_fixmap_nocache(idx, phys) \
36540 + __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
36542 + * used by vmalloc.c.
36544 + * Leave one empty page between vmalloc'ed areas and
36545 + * the start of the fixmap, and leave one page empty
36546 + * at the top of mem..
36548 +extern unsigned long get_kmem_end(void);
36550 +#define FIXADDR_TOP (get_kmem_end() - 0x2000)
36551 +#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
36552 +#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
36554 +#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
36556 +extern void __this_fixmap_does_not_exist(void);
36559 + * 'index to address' translation. If anyone tries to use the idx
36560 + * directly without tranlation, we catch the bug with a NULL-deference
36561 + * kernel oops. Illegal ranges of incoming indices are caught too.
36563 +static inline unsigned long fix_to_virt(const unsigned int idx)
36566 + * this branch gets completely eliminated after inlining,
36567 + * except when someone tries to use fixaddr indices in an
36568 + * illegal way. (such as mixing up address types or using
36569 + * out-of-range indices).
36571 + * If it doesn't get removed, the linker will complain
36572 + * loudly with a reasonably clear error message..
36574 + if (idx >= __end_of_fixed_addresses)
36575 + __this_fixmap_does_not_exist();
36577 + return __fix_to_virt(idx);
36581 diff -Naur -X ../exclude-files orig/include/asm-um/floppy.h um/include/asm-um/floppy.h
36582 --- orig/include/asm-um/floppy.h Wed Dec 31 19:00:00 1969
36583 +++ um/include/asm-um/floppy.h Wed Oct 23 21:08:05 2002
36585 +#ifndef __UM_FLOPPY_H
36586 +#define __UM_FLOPPY_H
36588 +#include "asm/arch/floppy.h"
36591 diff -Naur -X ../exclude-files orig/include/asm-um/hardirq.h um/include/asm-um/hardirq.h
36592 --- orig/include/asm-um/hardirq.h Wed Dec 31 19:00:00 1969
36593 +++ um/include/asm-um/hardirq.h Wed Apr 16 13:59:04 2003
36595 +#ifndef __UM_HARDIRQ_H
36596 +#define __UM_HARDIRQ_H
36598 +#include "asm/arch/hardirq.h"
36601 diff -Naur -X ../exclude-files orig/include/asm-um/hdreg.h um/include/asm-um/hdreg.h
36602 --- orig/include/asm-um/hdreg.h Wed Dec 31 19:00:00 1969
36603 +++ um/include/asm-um/hdreg.h Wed Oct 23 21:08:05 2002
36605 +#ifndef __UM_HDREG_H
36606 +#define __UM_HDREG_H
36608 +#include "asm/arch/hdreg.h"
36611 diff -Naur -X ../exclude-files orig/include/asm-um/highmem.h um/include/asm-um/highmem.h
36612 --- orig/include/asm-um/highmem.h Wed Dec 31 19:00:00 1969
36613 +++ um/include/asm-um/highmem.h Wed Apr 16 13:59:04 2003
36615 +#ifndef __UM_HIGHMEM_H
36616 +#define __UM_HIGHMEM_H
36618 +#include "asm/page.h"
36619 +#include "asm/fixmap.h"
36620 +#include "asm/arch/highmem.h"
36624 +#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK)
36627 diff -Naur -X ../exclude-files orig/include/asm-um/hw_irq.h um/include/asm-um/hw_irq.h
36628 --- orig/include/asm-um/hw_irq.h Wed Dec 31 19:00:00 1969
36629 +++ um/include/asm-um/hw_irq.h Wed Mar 26 22:01:25 2003
36631 +#ifndef _ASM_UM_HW_IRQ_H
36632 +#define _ASM_UM_HW_IRQ_H
36634 +#include "asm/irq.h"
36635 +#include "asm/archparam.h"
36637 +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
36641 diff -Naur -X ../exclude-files orig/include/asm-um/ide.h um/include/asm-um/ide.h
36642 --- orig/include/asm-um/ide.h Wed Dec 31 19:00:00 1969
36643 +++ um/include/asm-um/ide.h Wed Oct 23 21:08:05 2002
36645 +#ifndef __UM_IDE_H
36646 +#define __UM_IDE_H
36648 +#include "asm/arch/ide.h"
36651 diff -Naur -X ../exclude-files orig/include/asm-um/init.h um/include/asm-um/init.h
36652 --- orig/include/asm-um/init.h Wed Dec 31 19:00:00 1969
36653 +++ um/include/asm-um/init.h Wed Oct 23 21:08:05 2002
36655 +#ifndef _UM_INIT_H
36656 +#define _UM_INIT_H
36660 +#define __initdata
36661 +#define __initfunc(__arginit) __arginit
36662 +#define __cacheline_aligned
36666 diff -Naur -X ../exclude-files orig/include/asm-um/io.h um/include/asm-um/io.h
36667 --- orig/include/asm-um/io.h Wed Dec 31 19:00:00 1969
36668 +++ um/include/asm-um/io.h Sun Oct 27 16:53:42 2002
36673 +#include "asm/page.h"
36675 +#define IO_SPACE_LIMIT 0xdeadbeef /* Sure hope nothing uses this */
36677 +static inline int inb(unsigned long i) { return(0); }
36678 +static inline void outb(char c, unsigned long i) { }
36681 + * Change virtual addresses to physical addresses and vv.
36682 + * These are pretty trivial
36684 +static inline unsigned long virt_to_phys(volatile void * address)
36686 + return __pa((void *) address);
36689 +static inline void * phys_to_virt(unsigned long address)
36691 + return __va(address);
36695 diff -Naur -X ../exclude-files orig/include/asm-um/ioctl.h um/include/asm-um/ioctl.h
36696 --- orig/include/asm-um/ioctl.h Wed Dec 31 19:00:00 1969
36697 +++ um/include/asm-um/ioctl.h Wed Oct 23 21:08:05 2002
36699 +#ifndef __UM_IOCTL_H
36700 +#define __UM_IOCTL_H
36702 +#include "asm/arch/ioctl.h"
36705 diff -Naur -X ../exclude-files orig/include/asm-um/ioctls.h um/include/asm-um/ioctls.h
36706 --- orig/include/asm-um/ioctls.h Wed Dec 31 19:00:00 1969
36707 +++ um/include/asm-um/ioctls.h Wed Oct 23 21:11:14 2002
36709 +#ifndef __UM_IOCTLS_H
36710 +#define __UM_IOCTLS_H
36712 +#include "asm/arch/ioctls.h"
36715 diff -Naur -X ../exclude-files orig/include/asm-um/ipc.h um/include/asm-um/ipc.h
36716 --- orig/include/asm-um/ipc.h Wed Dec 31 19:00:00 1969
36717 +++ um/include/asm-um/ipc.h Wed Oct 23 21:08:05 2002
36719 +#ifndef __UM_IPC_H
36720 +#define __UM_IPC_H
36722 +#include "asm/arch/ipc.h"
36725 diff -Naur -X ../exclude-files orig/include/asm-um/ipcbuf.h um/include/asm-um/ipcbuf.h
36726 --- orig/include/asm-um/ipcbuf.h Wed Dec 31 19:00:00 1969
36727 +++ um/include/asm-um/ipcbuf.h Wed Oct 23 21:08:05 2002
36729 +#ifndef __UM_IPCBUF_H
36730 +#define __UM_IPCBUF_H
36732 +#include "asm/arch/ipcbuf.h"
36735 diff -Naur -X ../exclude-files orig/include/asm-um/irq.h um/include/asm-um/irq.h
36736 --- orig/include/asm-um/irq.h Wed Dec 31 19:00:00 1969
36737 +++ um/include/asm-um/irq.h Wed Mar 26 22:01:25 2003
36739 +#ifndef __UM_IRQ_H
36740 +#define __UM_IRQ_H
36742 +/* The i386 irq.h has a struct task_struct in a prototype without including
36743 + * sched.h. This forward declaration kills the resulting warning.
36745 +struct task_struct;
36747 +#include "asm/arch/irq.h"
36748 +#include "asm/ptrace.h"
36752 +#define TIMER_IRQ 0
36754 +#define CONSOLE_IRQ 2
36755 +#define CONSOLE_WRITE_IRQ 3
36757 +#define UM_ETH_IRQ 5
36759 +#define SSL_WRITE_IRQ 7
36760 +#define ACCEPT_IRQ 8
36761 +#define MCONSOLE_IRQ 9
36762 +#define WINCH_IRQ 10
36763 +#define SIGIO_WRITE_IRQ 11
36764 +#define TELNETD_IRQ 12
36765 +#define XTERM_IRQ 13
36767 +#define LAST_IRQ XTERM_IRQ
36768 +#define NR_IRQS (LAST_IRQ + 1)
36770 +extern int um_request_irq(unsigned int irq, int fd, int type,
36771 + void (*handler)(int, void *, struct pt_regs *),
36772 + unsigned long irqflags, const char * devname,
36775 diff -Naur -X ../exclude-files orig/include/asm-um/keyboard.h um/include/asm-um/keyboard.h
36776 --- orig/include/asm-um/keyboard.h Wed Dec 31 19:00:00 1969
36777 +++ um/include/asm-um/keyboard.h Wed Oct 23 21:08:05 2002
36779 +#ifndef __UM_KEYBOARD_H
36780 +#define __UM_KEYBOARD_H
36782 +#include "asm/arch/keyboard.h"
36785 diff -Naur -X ../exclude-files orig/include/asm-um/kmap_types.h um/include/asm-um/kmap_types.h
36786 --- orig/include/asm-um/kmap_types.h Wed Dec 31 19:00:00 1969
36787 +++ um/include/asm-um/kmap_types.h Thu Feb 27 13:20:14 2003
36790 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36791 + * Licensed under the GPL
36794 +#ifndef __UM_KMAP_TYPES_H
36795 +#define __UM_KMAP_TYPES_H
36797 +#include "asm/arch/kmap_types.h"
36800 diff -Naur -X ../exclude-files orig/include/asm-um/linux_logo.h um/include/asm-um/linux_logo.h
36801 --- orig/include/asm-um/linux_logo.h Wed Dec 31 19:00:00 1969
36802 +++ um/include/asm-um/linux_logo.h Wed Oct 23 21:08:05 2002
36804 +#ifndef __UM_LINUX_LOGO_H
36805 +#define __UM_LINUX_LOGO_H
36807 +#include "asm/arch/linux_logo.h"
36810 diff -Naur -X ../exclude-files orig/include/asm-um/locks.h um/include/asm-um/locks.h
36811 --- orig/include/asm-um/locks.h Wed Dec 31 19:00:00 1969
36812 +++ um/include/asm-um/locks.h Wed Oct 23 21:08:05 2002
36814 +#ifndef __UM_LOCKS_H
36815 +#define __UM_LOCKS_H
36817 +#include "asm/arch/locks.h"
36820 diff -Naur -X ../exclude-files orig/include/asm-um/mca_dma.h um/include/asm-um/mca_dma.h
36821 --- orig/include/asm-um/mca_dma.h Wed Dec 31 19:00:00 1969
36822 +++ um/include/asm-um/mca_dma.h Wed Oct 23 21:08:05 2002
36824 +#ifndef mca___UM_DMA_H
36825 +#define mca___UM_DMA_H
36827 +#include "asm/arch/mca_dma.h"
36830 diff -Naur -X ../exclude-files orig/include/asm-um/mman.h um/include/asm-um/mman.h
36831 --- orig/include/asm-um/mman.h Wed Dec 31 19:00:00 1969
36832 +++ um/include/asm-um/mman.h Wed Oct 23 21:08:05 2002
36834 +#ifndef __UM_MMAN_H
36835 +#define __UM_MMAN_H
36837 +#include "asm/arch/mman.h"
36840 diff -Naur -X ../exclude-files orig/include/asm-um/mmu.h um/include/asm-um/mmu.h
36841 --- orig/include/asm-um/mmu.h Wed Dec 31 19:00:00 1969
36842 +++ um/include/asm-um/mmu.h Sat Nov 9 12:51:11 2002
36845 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36846 + * Licensed under the GPL
36852 +#include "um_mmu.h"
36857 + * Overrides for Emacs so that we follow Linus's tabbing style.
36858 + * Emacs will notice this stuff at the end of the file and automatically
36859 + * adjust the settings for this buffer only. This must remain at the end
36861 + * ---------------------------------------------------------------------------
36862 + * Local variables:
36863 + * c-file-style: "linux"
36866 diff -Naur -X ../exclude-files orig/include/asm-um/mmu_context.h um/include/asm-um/mmu_context.h
36867 --- orig/include/asm-um/mmu_context.h Wed Dec 31 19:00:00 1969
36868 +++ um/include/asm-um/mmu_context.h Wed Apr 16 13:59:16 2003
36871 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36872 + * Licensed under the GPL
36875 +#ifndef __UM_MMU_CONTEXT_H
36876 +#define __UM_MMU_CONTEXT_H
36878 +#include "linux/sched.h"
36879 +#include "choose-mode.h"
36881 +#define get_mmu_context(task) do ; while(0)
36882 +#define activate_context(tsk) do ; while(0)
36884 +static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
36888 +extern void switch_mm_skas(int mm_fd);
36890 +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
36891 + struct task_struct *tsk, unsigned cpu)
36893 + if(prev != next){
36894 + clear_bit(cpu, &prev->cpu_vm_mask);
36895 + set_bit(cpu, &next->cpu_vm_mask);
36896 + if(next != &init_mm)
36897 + CHOOSE_MODE((void) 0,
36898 + switch_mm_skas(next->context.skas.mm_fd));
36902 +static inline void enter_lazy_tlb(struct mm_struct *mm,
36903 + struct task_struct *tsk, unsigned cpu)
36907 +extern int init_new_context_skas(struct task_struct *task,
36908 + struct mm_struct *mm);
36910 +static inline int init_new_context_tt(struct task_struct *task,
36911 + struct mm_struct *mm)
36916 +static inline int init_new_context(struct task_struct *task,
36917 + struct mm_struct *mm)
36919 + return(CHOOSE_MODE_PROC(init_new_context_tt, init_new_context_skas,
36923 +extern void destroy_context_skas(struct mm_struct *mm);
36925 +static inline void destroy_context(struct mm_struct *mm)
36927 + CHOOSE_MODE((void) 0, destroy_context_skas(mm));
36933 + * Overrides for Emacs so that we follow Linus's tabbing style.
36934 + * Emacs will notice this stuff at the end of the file and automatically
36935 + * adjust the settings for this buffer only. This must remain at the end
36937 + * ---------------------------------------------------------------------------
36938 + * Local variables:
36939 + * c-file-style: "linux"
36942 diff -Naur -X ../exclude-files orig/include/asm-um/module.h um/include/asm-um/module.h
36943 --- orig/include/asm-um/module.h Wed Dec 31 19:00:00 1969
36944 +++ um/include/asm-um/module.h Wed Oct 23 21:08:05 2002
36946 +#ifndef __UM_MODULE_H
36947 +#define __UM_MODULE_H
36949 +#include "asm/arch/module.h"
36952 diff -Naur -X ../exclude-files orig/include/asm-um/msgbuf.h um/include/asm-um/msgbuf.h
36953 --- orig/include/asm-um/msgbuf.h Wed Dec 31 19:00:00 1969
36954 +++ um/include/asm-um/msgbuf.h Wed Oct 23 21:08:05 2002
36956 +#ifndef __UM_MSGBUF_H
36957 +#define __UM_MSGBUF_H
36959 +#include "asm/arch/msgbuf.h"
36962 diff -Naur -X ../exclude-files orig/include/asm-um/mtrr.h um/include/asm-um/mtrr.h
36963 --- orig/include/asm-um/mtrr.h Wed Dec 31 19:00:00 1969
36964 +++ um/include/asm-um/mtrr.h Thu Mar 27 15:11:56 2003
36966 +#ifndef __UM_MTRR_H
36967 +#define __UM_MTRR_H
36969 +#include "asm/arch/mtrr.h"
36972 diff -Naur -X ../exclude-files orig/include/asm-um/namei.h um/include/asm-um/namei.h
36973 --- orig/include/asm-um/namei.h Wed Dec 31 19:00:00 1969
36974 +++ um/include/asm-um/namei.h Wed Oct 23 21:08:05 2002
36976 +#ifndef __UM_NAMEI_H
36977 +#define __UM_NAMEI_H
36979 +#include "asm/arch/namei.h"
36982 diff -Naur -X ../exclude-files orig/include/asm-um/page.h um/include/asm-um/page.h
36983 --- orig/include/asm-um/page.h Wed Dec 31 19:00:00 1969
36984 +++ um/include/asm-um/page.h Sun Oct 27 16:49:35 2002
36986 +#ifndef __UM_PAGE_H
36987 +#define __UM_PAGE_H
36991 +#include "asm/arch/page.h"
36997 +#undef virt_to_page
36999 +#undef PAGE_OFFSET
37002 +extern unsigned long uml_physmem;
37004 +#define PAGE_OFFSET (uml_physmem)
37005 +#define KERNELBASE PAGE_OFFSET
37007 +#ifndef __ASSEMBLY__
37009 +extern void stop(void);
37011 +#define BUG() do { \
37012 + panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
37015 +#define PAGE_BUG(page) do { \
37019 +#endif /* __ASSEMBLY__ */
37021 +#define __va_space (8*1024*1024)
37023 +extern unsigned long region_pa(void *virt);
37024 +extern void *region_va(unsigned long phys);
37026 +#define __pa(virt) region_pa((void *) (virt))
37027 +#define __va(phys) region_va((unsigned long) (phys))
37029 +extern struct page *page_mem_map(struct page *page);
37031 +extern struct page *pfn_to_page(unsigned long pfn);
37033 +#define VALID_PAGE(page) (page_mem_map(page) != NULL)
37035 +extern struct page *arch_validate(struct page *page, int mask, int order);
37036 +#define HAVE_ARCH_VALIDATE
37039 diff -Naur -X ../exclude-files orig/include/asm-um/page_offset.h um/include/asm-um/page_offset.h
37040 --- orig/include/asm-um/page_offset.h Wed Dec 31 19:00:00 1969
37041 +++ um/include/asm-um/page_offset.h Wed Oct 23 21:08:05 2002
37043 +#define PAGE_OFFSET_RAW (uml_physmem)
37044 diff -Naur -X ../exclude-files orig/include/asm-um/param.h um/include/asm-um/param.h
37045 --- orig/include/asm-um/param.h Wed Dec 31 19:00:00 1969
37046 +++ um/include/asm-um/param.h Wed Oct 23 21:08:05 2002
37048 +#ifndef _UM_PARAM_H
37049 +#define _UM_PARAM_H
37055 +#define EXEC_PAGESIZE 4096
37058 +#define NGROUPS 32
37062 +#define NOGROUP (-1)
37065 +#define MAXHOSTNAMELEN 64 /* max length of hostname */
37068 +# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */
37072 diff -Naur -X ../exclude-files orig/include/asm-um/pci.h um/include/asm-um/pci.h
37073 --- orig/include/asm-um/pci.h Wed Dec 31 19:00:00 1969
37074 +++ um/include/asm-um/pci.h Wed Oct 23 21:08:05 2002
37076 +#ifndef __UM_PCI_H
37077 +#define __UM_PCI_H
37079 +#define PCI_DMA_BUS_IS_PHYS (1)
37082 diff -Naur -X ../exclude-files orig/include/asm-um/pgalloc.h um/include/asm-um/pgalloc.h
37083 --- orig/include/asm-um/pgalloc.h Wed Dec 31 19:00:00 1969
37084 +++ um/include/asm-um/pgalloc.h Wed Apr 16 13:59:04 2003
37087 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
37088 + * Derived from include/asm-i386/pgalloc.h and include/asm-i386/pgtable.h
37089 + * Licensed under the GPL
37092 +#ifndef __UM_PGALLOC_H
37093 +#define __UM_PGALLOC_H
37095 +#include "linux/config.h"
37096 +#include "linux/mm.h"
37097 +#include "asm/fixmap.h"
37098 +#include "choose-mode.h"
37100 +#define pgd_quicklist (current_cpu_data.pgd_quick)
37101 +#define pmd_quicklist (current_cpu_data.pmd_quick)
37102 +#define pte_quicklist (current_cpu_data.pte_quick)
37103 +#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
37105 +#define pmd_populate(mm, pmd, pte) set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
37108 + * Allocate and free page tables.
37111 +static inline pgd_t *get_pgd_slow_tt(void)
37113 + pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
37116 + memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
37117 + memcpy(pgd + USER_PTRS_PER_PGD,
37118 + swapper_pg_dir + USER_PTRS_PER_PGD,
37119 + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
37124 +static inline pgd_t *get_pgd_slow_skas(void)
37126 + pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
37129 + memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
37133 +static inline pgd_t *get_pgd_slow(void)
37135 + return(CHOOSE_MODE(get_pgd_slow_tt(), get_pgd_slow_skas()));
37138 +static inline pgd_t *get_pgd_fast(void)
37140 + unsigned long *ret;
37142 + if ((ret = pgd_quicklist) != NULL) {
37143 + pgd_quicklist = (unsigned long *)(*ret);
37145 + pgtable_cache_size--;
37147 + ret = (unsigned long *)get_pgd_slow();
37148 + return (pgd_t *)ret;
37151 +static inline void free_pgd_fast(pgd_t *pgd)
37153 + *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
37154 + pgd_quicklist = (unsigned long *) pgd;
37155 + pgtable_cache_size++;
37158 +static inline void free_pgd_slow(pgd_t *pgd)
37160 + free_page((unsigned long)pgd);
37163 +static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
37167 + pte = (pte_t *) __get_free_page(GFP_KERNEL);
37173 +static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
37175 + unsigned long *ret;
37177 + if ((ret = (unsigned long *)pte_quicklist) != NULL) {
37178 + pte_quicklist = (unsigned long *)(*ret);
37180 + pgtable_cache_size--;
37182 + return (pte_t *)ret;
37185 +static inline void pte_free_fast(pte_t *pte)
37187 + *(unsigned long *)pte = (unsigned long) pte_quicklist;
37188 + pte_quicklist = (unsigned long *) pte;
37189 + pgtable_cache_size++;
37192 +static inline void pte_free_slow(pte_t *pte)
37194 + free_page((unsigned long)pte);
37197 +#define pte_free(pte) pte_free_fast(pte)
37198 +#define pgd_free(pgd) free_pgd_slow(pgd)
37199 +#define pgd_alloc(mm) get_pgd_fast()
37202 + * allocating and freeing a pmd is trivial: the 1-entry pmd is
37203 + * inside the pgd, so has no extra memory associated with it.
37206 +#define pmd_alloc_one_fast(mm, addr) ({ BUG(); ((pmd_t *)1); })
37207 +#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
37208 +#define pmd_free_slow(x) do { } while (0)
37209 +#define pmd_free_fast(x) do { } while (0)
37210 +#define pmd_free(x) do { } while (0)
37211 +#define pgd_populate(mm, pmd, pte) BUG()
37216 + * - flush_tlb() flushes the current mm struct TLBs
37217 + * - flush_tlb_all() flushes all processes TLBs
37218 + * - flush_tlb_mm(mm) flushes the specified mm context TLB's
37219 + * - flush_tlb_page(vma, vmaddr) flushes one page
37220 + * - flush_tlb_kernel_vm() flushes the kernel vm area
37221 + * - flush_tlb_range(mm, start, end) flushes a range of pages
37222 + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
37225 +extern void flush_tlb_all(void);
37226 +extern void flush_tlb_mm(struct mm_struct *mm);
37227 +extern void flush_tlb_range(struct mm_struct *mm, unsigned long start,
37228 + unsigned long end);
37229 +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
37230 +extern void flush_tlb_kernel_vm(void);
37232 +static inline void flush_tlb_pgtables(struct mm_struct *mm,
37233 + unsigned long start, unsigned long end)
37239 + * Overrides for Emacs so that we follow Linus's tabbing style.
37240 + * Emacs will notice this stuff at the end of the file and automatically
37241 + * adjust the settings for this buffer only. This must remain at the end
37243 + * ---------------------------------------------------------------------------
37244 + * Local variables:
37245 + * c-file-style: "linux"
37248 diff -Naur -X ../exclude-files orig/include/asm-um/pgtable.h um/include/asm-um/pgtable.h
37249 --- orig/include/asm-um/pgtable.h Wed Dec 31 19:00:00 1969
37250 +++ um/include/asm-um/pgtable.h Wed Apr 16 13:59:04 2003
37253 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
37254 + * Derived from include/asm-i386/pgtable.h
37255 + * Licensed under the GPL
37258 +#ifndef __UM_PGTABLE_H
37259 +#define __UM_PGTABLE_H
37261 +#include "linux/sched.h"
37262 +#include "asm/processor.h"
37263 +#include "asm/page.h"
37265 +extern pgd_t swapper_pg_dir[1024];
37267 +#define flush_cache_all() do ; while (0)
37268 +#define flush_cache_mm(mm) do ; while (0)
37269 +#define flush_cache_range(vma, start, end) do ; while (0)
37270 +#define flush_cache_page(vma, vmaddr) do ; while (0)
37271 +#define flush_page_to_ram(page) do ; while (0)
37272 +#define flush_dcache_page(page) do ; while (0)
37273 +#define flush_icache_range(from, to) do ; while (0)
37274 +#define flush_icache_page(vma,pg) do ; while (0)
37275 +#define flush_icache_user_range(vma,pg,adr,len) do ; while (0)
37277 +extern void __flush_tlb_one(unsigned long addr);
37279 +extern void pte_free(pte_t *pte);
37281 +extern void pgd_free(pgd_t *pgd);
37283 +extern int do_check_pgt_cache(int, int);
37285 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
37288 +/* zero page used for uninitialized stuff */
37289 +extern unsigned long *empty_zero_page;
37291 +#define pgtable_cache_init() do ; while (0)
37293 +/* PMD_SHIFT determines the size of the area a second-level page table can map */
37294 +#define PMD_SHIFT 22
37295 +#define PMD_SIZE (1UL << PMD_SHIFT)
37296 +#define PMD_MASK (~(PMD_SIZE-1))
37298 +/* PGDIR_SHIFT determines what a third-level page table entry can map */
37299 +#define PGDIR_SHIFT 22
37300 +#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
37301 +#define PGDIR_MASK (~(PGDIR_SIZE-1))
37304 + * entries per page directory level: the i386 is two-level, so
37305 + * we don't really have any PMD directory physically.
37307 +#define PTRS_PER_PTE 1024
37308 +#define PTRS_PER_PMD 1
37309 +#define PTRS_PER_PGD 1024
37310 +#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
37311 +#define FIRST_USER_PGD_NR 0
37313 +#define pte_ERROR(e) \
37314 + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
37315 +#define pmd_ERROR(e) \
37316 + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
37317 +#define pgd_ERROR(e) \
37318 + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
37321 + * pgd entries used up by user/kernel:
37324 +#define USER_PGD_PTRS (TASK_SIZE >> PGDIR_SHIFT)
37325 +#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
37327 +#ifndef __ASSEMBLY__
37328 +/* Just any arbitrary offset to the start of the vmalloc VM area: the
37329 + * current 8MB value just means that there will be a 8MB "hole" after the
37330 + * physical memory until the kernel virtual memory starts. That means that
37331 + * any out-of-bounds memory accesses will hopefully be caught.
37332 + * The vmalloc() routines leaves a hole of 4kB between each vmalloced
37333 + * area for the same reason. ;)
37336 +extern unsigned long high_physmem;
37338 +#define VMALLOC_OFFSET (__va_space)
37339 +#define VMALLOC_START (((unsigned long) high_physmem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
37340 +#define VMALLOC_VMADDR(x) ((unsigned long)(x))
37342 +#if CONFIG_HIGHMEM
37343 +# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
37345 +# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
37348 +#define _PAGE_PRESENT 0x001
37349 +#define _PAGE_NEWPAGE 0x002
37350 +#define _PAGE_PROTNONE 0x004 /* If not present */
37351 +#define _PAGE_RW 0x008
37352 +#define _PAGE_USER 0x010
37353 +#define _PAGE_ACCESSED 0x020
37354 +#define _PAGE_DIRTY 0x040
37355 +#define _PAGE_NEWPROT 0x080
37357 +#define REGION_MASK 0xf0000000
37358 +#define REGION_SHIFT 28
37360 +#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
37361 +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
37362 +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
37364 +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
37365 +#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
37366 +#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
37367 +#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
37368 +#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
37369 +#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
37372 + * The i386 can't do page protection for execute, and considers that the same are read.
37373 + * Also, write permissions imply read permissions. This is the closest we can get..
37375 +#define __P000 PAGE_NONE
37376 +#define __P001 PAGE_READONLY
37377 +#define __P010 PAGE_COPY
37378 +#define __P011 PAGE_COPY
37379 +#define __P100 PAGE_READONLY
37380 +#define __P101 PAGE_READONLY
37381 +#define __P110 PAGE_COPY
37382 +#define __P111 PAGE_COPY
37384 +#define __S000 PAGE_NONE
37385 +#define __S001 PAGE_READONLY
37386 +#define __S010 PAGE_SHARED
37387 +#define __S011 PAGE_SHARED
37388 +#define __S100 PAGE_READONLY
37389 +#define __S101 PAGE_READONLY
37390 +#define __S110 PAGE_SHARED
37391 +#define __S111 PAGE_SHARED
37394 + * Define this if things work differently on an i386 and an i486:
37395 + * it will (on an i486) warn about kernel memory accesses that are
37396 + * done without a 'verify_area(VERIFY_WRITE,..)'
37398 +#undef TEST_VERIFY_AREA
37400 +/* page table for 0-4MB for everybody */
37401 +extern unsigned long pg0[1024];
37404 + * BAD_PAGETABLE is used when we need a bogus page-table, while
37405 + * BAD_PAGE is used for a bogus page.
37407 + * ZERO_PAGE is a global shared page that is always zero: used
37408 + * for zero-mapped memory areas etc..
37410 +extern pte_t __bad_page(void);
37411 +extern pte_t * __bad_pagetable(void);
37413 +#define BAD_PAGETABLE __bad_pagetable()
37414 +#define BAD_PAGE __bad_page()
37415 +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
37417 +/* number of bits that fit into a memory pointer */
37418 +#define BITS_PER_PTR (8*sizeof(unsigned long))
37420 +/* to align the pointer to a pointer address */
37421 +#define PTR_MASK (~(sizeof(void*)-1))
37423 +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
37424 +/* 64-bit machines, beware! SRB. */
37425 +#define SIZEOF_PTR_LOG2 2
37427 +/* to find an entry in a page-table */
37428 +#define PAGE_PTR(address) \
37429 +((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
37431 +#define pte_none(x) !(pte_val(x) & ~_PAGE_NEWPAGE)
37432 +#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
37434 +#define pte_clear(xp) do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
37436 +#define phys_region_index(x) (((x) & REGION_MASK) >> REGION_SHIFT)
37437 +#define pte_region_index(x) phys_region_index(pte_val(x))
37439 +#define pmd_none(x) (!(pmd_val(x) & ~_PAGE_NEWPAGE))
37440 +#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
37441 +#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
37442 +#define pmd_clear(xp) do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
37444 +#define pmd_newpage(x) (pmd_val(x) & _PAGE_NEWPAGE)
37445 +#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE)
37448 + * The "pgd_xxx()" functions here are trivial for a folded two-level
37449 + * setup: the pgd is never bad, and a pmd always exists (as it's folded
37450 + * into the pgd entry)
37452 +static inline int pgd_none(pgd_t pgd) { return 0; }
37453 +static inline int pgd_bad(pgd_t pgd) { return 0; }
37454 +static inline int pgd_present(pgd_t pgd) { return 1; }
37455 +static inline void pgd_clear(pgd_t * pgdp) { }
37457 +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
37459 +extern struct page *pte_mem_map(pte_t pte);
37460 +extern struct page *phys_mem_map(unsigned long phys);
37461 +extern unsigned long phys_to_pfn(unsigned long p);
37463 +#define pte_page(x) pfn_to_page(pte_pfn(x))
37464 +#define pte_address(x) (__va(pte_val(x) & PAGE_MASK))
37465 +#define mk_phys(a, r) ((a) + (r << REGION_SHIFT))
37466 +#define phys_addr(p) ((p) & ~REGION_MASK)
37467 +#define phys_page(p) (phys_mem_map(p) + ((phys_addr(p)) >> PAGE_SHIFT))
37468 +#define virt_to_page(kaddr) \
37469 + (phys_mem_map(__pa(kaddr)) + (phys_addr(__pa(kaddr)) >> PAGE_SHIFT))
37470 +#define pte_pfn(x) phys_to_pfn(pte_val(x))
37472 +static inline pte_t pte_mknewprot(pte_t pte)
37474 + pte_val(pte) |= _PAGE_NEWPROT;
37478 +static inline pte_t pte_mknewpage(pte_t pte)
37480 + pte_val(pte) |= _PAGE_NEWPAGE;
37484 +static inline void set_pte(pte_t *pteptr, pte_t pteval)
37486 + /* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so
37487 + * fix_range knows to unmap it. _PAGE_NEWPROT is specific to
37490 + *pteptr = pte_mknewpage(pteval);
37491 + if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr);
37495 + * (pmds are folded into pgds so this doesnt get actually called,
37496 + * but the define is needed for a generic inline function.)
37498 +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
37499 +#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
37502 + * The following only work if pte_present() is true.
37503 + * Undefined behaviour if not..
37505 +static inline int pte_read(pte_t pte)
37507 + return((pte_val(pte) & _PAGE_USER) &&
37508 + !(pte_val(pte) & _PAGE_PROTNONE));
37511 +static inline int pte_exec(pte_t pte){
37512 + return((pte_val(pte) & _PAGE_USER) &&
37513 + !(pte_val(pte) & _PAGE_PROTNONE));
37516 +static inline int pte_write(pte_t pte)
37518 + return((pte_val(pte) & _PAGE_RW) &&
37519 + !(pte_val(pte) & _PAGE_PROTNONE));
37522 +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
37523 +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
37524 +static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
37525 +static inline int pte_newprot(pte_t pte)
37527 + return(pte_present(pte) && (pte_val(pte) & _PAGE_NEWPROT));
37530 +static inline pte_t pte_rdprotect(pte_t pte)
37532 + pte_val(pte) &= ~_PAGE_USER;
37533 + return(pte_mknewprot(pte));
37536 +static inline pte_t pte_exprotect(pte_t pte)
37538 + pte_val(pte) &= ~_PAGE_USER;
37539 + return(pte_mknewprot(pte));
37542 +static inline pte_t pte_mkclean(pte_t pte)
37544 + pte_val(pte) &= ~_PAGE_DIRTY;
37548 +static inline pte_t pte_mkold(pte_t pte)
37550 + pte_val(pte) &= ~_PAGE_ACCESSED;
37554 +static inline pte_t pte_wrprotect(pte_t pte)
37556 + pte_val(pte) &= ~_PAGE_RW;
37557 + return(pte_mknewprot(pte));
37560 +static inline pte_t pte_mkread(pte_t pte)
37562 + pte_val(pte) |= _PAGE_USER;
37563 + return(pte_mknewprot(pte));
37566 +static inline pte_t pte_mkexec(pte_t pte)
37568 + pte_val(pte) |= _PAGE_USER;
37569 + return(pte_mknewprot(pte));
37572 +static inline pte_t pte_mkdirty(pte_t pte)
37574 + pte_val(pte) |= _PAGE_DIRTY;
37578 +static inline pte_t pte_mkyoung(pte_t pte)
37580 + pte_val(pte) |= _PAGE_ACCESSED;
37584 +static inline pte_t pte_mkwrite(pte_t pte)
37586 + pte_val(pte) |= _PAGE_RW;
37587 + return(pte_mknewprot(pte));
37590 +static inline pte_t pte_mkuptodate(pte_t pte)
37592 + pte_val(pte) &= ~_PAGE_NEWPAGE;
37593 + if(pte_present(pte)) pte_val(pte) &= ~_PAGE_NEWPROT;
37597 +extern unsigned long page_to_phys(struct page *page);
37600 + * Conversion functions: convert a page and protection to a page entry,
37601 + * and a page entry and page directory to the page they refer to.
37604 +#define mk_pte(page, pgprot) \
37608 + pte_val(__pte) = page_to_phys(page) + pgprot_val(pgprot);\
37609 + if(pte_present(__pte)) pte_mknewprot(pte_mknewpage(__pte)); \
37613 +/* This takes a physical page address that is used by the remapping functions */
37614 +#define mk_pte_phys(physpage, pgprot) \
37615 + pte_mknewpage(mk_pte(phys_page(physpage), pgprot))
37617 +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
37619 + pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
37620 + if(pte_present(pte)) pte = pte_mknewpage(pte_mknewprot(pte));
37624 +#define pmd_page(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
37626 +/* to find an entry in a page-table-directory. */
37627 +#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
37628 +#define __pgd_offset(address) pgd_index(address)
37630 +/* to find an entry in a page-table-directory */
37631 +#define pgd_offset(mm, address) \
37632 +((mm)->pgd + ((address) >> PGDIR_SHIFT))
37634 +/* to find an entry in a kernel page-table-directory */
37635 +#define pgd_offset_k(address) pgd_offset(&init_mm, address)
37637 +#define __pmd_offset(address) \
37638 + (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
37640 +/* Find an entry in the second-level page table.. */
37641 +static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
37643 + return (pmd_t *) dir;
37646 +/* Find an entry in the third-level page table.. */
37647 +#define pte_offset(pmd, address) \
37648 +((pte_t *) (pmd_page(*pmd) + ((address>>10) & ((PTRS_PER_PTE-1)<<2))))
37650 +#define update_mmu_cache(vma,address,pte) do ; while (0)
37652 +/* Encode and de-code a swap entry */
37653 +#define SWP_TYPE(x) (((x).val >> 3) & 0x7f)
37654 +#define SWP_OFFSET(x) ((x).val >> 10)
37656 +#define SWP_ENTRY(type, offset) \
37657 + ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
37658 +#define pte_to_swp_entry(pte) \
37659 + ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
37660 +#define swp_entry_to_pte(x) ((pte_t) { (x).val })
37662 +#define PageSkip(x) (0)
37663 +#define kern_addr_valid(addr) (1)
37665 +#include <asm-generic/pgtable.h>
37671 + * Overrides for Emacs so that we follow Linus's tabbing style.
37672 + * Emacs will notice this stuff at the end of the file and automatically
37673 + * adjust the settings for this buffer only. This must remain at the end
37675 + * ---------------------------------------------------------------------------
37676 + * Local variables:
37677 + * c-file-style: "linux"
37680 diff -Naur -X ../exclude-files orig/include/asm-um/poll.h um/include/asm-um/poll.h
37681 --- orig/include/asm-um/poll.h Wed Dec 31 19:00:00 1969
37682 +++ um/include/asm-um/poll.h Wed Oct 23 21:08:05 2002
37684 +#ifndef __UM_POLL_H
37685 +#define __UM_POLL_H
37687 +#include "asm/arch/poll.h"
37690 diff -Naur -X ../exclude-files orig/include/asm-um/posix_types.h um/include/asm-um/posix_types.h
37691 --- orig/include/asm-um/posix_types.h Wed Dec 31 19:00:00 1969
37692 +++ um/include/asm-um/posix_types.h Wed Oct 23 21:08:05 2002
37694 +#ifndef __UM_POSIX_TYPES_H
37695 +#define __UM_POSIX_TYPES_H
37697 +#include "asm/arch/posix_types.h"
37700 diff -Naur -X ../exclude-files orig/include/asm-um/processor-generic.h um/include/asm-um/processor-generic.h
37701 --- orig/include/asm-um/processor-generic.h Wed Dec 31 19:00:00 1969
37702 +++ um/include/asm-um/processor-generic.h Wed Apr 16 13:59:03 2003
37705 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
37706 + * Licensed under the GPL
37709 +#ifndef __UM_PROCESSOR_GENERIC_H
37710 +#define __UM_PROCESSOR_GENERIC_H
37714 +struct task_struct;
37716 +#include "linux/config.h"
37717 +#include "linux/signal.h"
37718 +#include "asm/ptrace.h"
37719 +#include "asm/siginfo.h"
37720 +#include "choose-mode.h"
37724 +#define current_text_addr() ((void *) 0)
37726 +#define cpu_relax() do ; while (0)
37728 +#ifdef CONFIG_MODE_TT
37729 +struct proc_tt_mode {
37732 + int switch_pipe[2];
37733 + int singlestep_syscall;
37738 +#ifdef CONFIG_MODE_SKAS
37739 +struct proc_skas_mode {
37740 + void *switch_buf;
37745 +struct thread_struct {
37747 + unsigned long kernel_stack;
37749 + struct pt_regs regs;
37750 + unsigned long cr2;
37752 + void *fault_addr;
37753 + void *fault_catcher;
37754 + struct task_struct *prev_sched;
37755 + unsigned long temp_stack;
37757 + struct arch_thread arch;
37759 +#ifdef CONFIG_MODE_TT
37760 + struct proc_tt_mode tt;
37762 +#ifdef CONFIG_MODE_SKAS
37763 + struct proc_skas_mode skas;
37773 + int (*proc)(void *);
37777 + void (*proc)(void *);
37784 +#define INIT_THREAD \
37787 + .kernel_stack = 0, \
37788 + .nsyscalls = 0, \
37789 + .regs = EMPTY_REGS, \
37792 + .fault_addr = NULL, \
37793 + .prev_sched = NULL, \
37794 + .temp_stack = 0, \
37795 + .exec_buf = NULL, \
37796 + .arch = INIT_ARCH_THREAD, \
37797 + .request = { 0 } \
37800 +#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
37803 + unsigned long seg;
37806 +extern struct task_struct *alloc_task_struct(void);
37807 +extern void free_task_struct(struct task_struct *task);
37809 +#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count)
37811 +extern void release_thread(struct task_struct *);
37812 +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
37813 +extern void dump_thread(struct pt_regs *regs, struct user *u);
37815 +extern unsigned long thread_saved_pc(struct thread_struct *t);
37817 +static inline void mm_copy_segments(struct mm_struct *from_mm,
37818 + struct mm_struct *new_mm)
37822 +static inline void copy_segments(struct task_struct *p,
37823 + struct mm_struct *new_mm)
37827 +static inline void release_segments(struct mm_struct *mm)
37831 +#define init_task (init_task_union.task)
37832 +#define init_stack (init_task_union.stack)
37835 + * User space process size: 3GB (default).
37837 +extern unsigned long task_size;
37839 +#define TASK_SIZE (task_size)
37841 +/* This decides where the kernel will search for a free chunk of vm
37842 + * space during mmap's.
37844 +#define TASK_UNMAPPED_BASE (0x40000000)
37846 +extern void start_thread(struct pt_regs *regs, unsigned long entry,
37847 + unsigned long stack);
37849 +struct cpuinfo_um {
37850 + unsigned long loops_per_jiffy;
37851 + unsigned long *pgd_quick;
37852 + unsigned long *pmd_quick;
37853 + unsigned long *pte_quick;
37854 + unsigned long pgtable_cache_sz;
37858 +extern struct cpuinfo_um boot_cpu_data;
37860 +#define my_cpu_data cpu_data[smp_processor_id()]
37863 +extern struct cpuinfo_um cpu_data[];
37864 +#define current_cpu_data cpu_data[smp_processor_id()]
37866 +#define cpu_data (&boot_cpu_data)
37867 +#define current_cpu_data boot_cpu_data
37870 +#define KSTK_EIP(tsk) (PT_REGS_IP(&tsk->thread.regs))
37871 +#define KSTK_ESP(tsk) (PT_REGS_SP(&tsk->thread.regs))
37872 +#define get_wchan(p) (0)
37877 + * Overrides for Emacs so that we follow Linus's tabbing style.
37878 + * Emacs will notice this stuff at the end of the file and automatically
37879 + * adjust the settings for this buffer only. This must remain at the end
37881 + * ---------------------------------------------------------------------------
37882 + * Local variables:
37883 + * c-file-style: "linux"
37886 diff -Naur -X ../exclude-files orig/include/asm-um/processor-i386.h um/include/asm-um/processor-i386.h
37887 --- orig/include/asm-um/processor-i386.h Wed Dec 31 19:00:00 1969
37888 +++ um/include/asm-um/processor-i386.h Wed Apr 16 13:59:03 2003
37891 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
37892 + * Licensed under the GPL
37895 +#ifndef __UM_PROCESSOR_I386_H
37896 +#define __UM_PROCESSOR_I386_H
37898 +extern int cpu_has_xmm;
37899 +extern int cpu_has_cmov;
37901 +struct arch_thread {
37902 + unsigned long debugregs[8];
37903 + int debugregs_seq;
37906 +#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \
37907 + .debugregs_seq = 0 }
37909 +#include "asm/arch/user.h"
37911 +#include "asm/processor-generic.h"
37916 + * Overrides for Emacs so that we follow Linus's tabbing style.
37917 + * Emacs will notice this stuff at the end of the file and automatically
37918 + * adjust the settings for this buffer only. This must remain at the end
37920 + * ---------------------------------------------------------------------------
37921 + * Local variables:
37922 + * c-file-style: "linux"
37925 diff -Naur -X ../exclude-files orig/include/asm-um/processor-ppc.h um/include/asm-um/processor-ppc.h
37926 --- orig/include/asm-um/processor-ppc.h Wed Dec 31 19:00:00 1969
37927 +++ um/include/asm-um/processor-ppc.h Wed Oct 23 21:08:05 2002
37929 +#ifndef __UM_PROCESSOR_PPC_H
37930 +#define __UM_PROCESSOR_PPC_H
37932 +#if defined(__ASSEMBLY__)
37934 +#define CONFIG_ALL_PPC
37935 +#include "arch/processor.h"
37939 +#include "asm/processor-generic.h"
37944 diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-generic.h um/include/asm-um/ptrace-generic.h
37945 --- orig/include/asm-um/ptrace-generic.h Wed Dec 31 19:00:00 1969
37946 +++ um/include/asm-um/ptrace-generic.h Wed Mar 26 22:01:25 2003
37949 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
37950 + * Licensed under the GPL
37953 +#ifndef __UM_PTRACE_GENERIC_H
37954 +#define __UM_PTRACE_GENERIC_H
37956 +#ifndef __ASSEMBLY__
37958 +#include "linux/config.h"
37960 +#include "asm/current.h"
37962 +#define pt_regs pt_regs_subarch
37963 +#define show_regs show_regs_subarch
37965 +#include "asm/arch/ptrace.h"
37970 +#undef instruction_pointer
37972 +#include "sysdep/ptrace.h"
37973 +#include "skas_ptrace.h"
37976 + union uml_pt_regs regs;
37979 +#define EMPTY_REGS { regs : EMPTY_UML_PT_REGS }
37981 +#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
37982 +#define PT_REGS_SP(r) UPT_SP(&(r)->regs)
37984 +#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg)
37985 +#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val)
37987 +#define PT_REGS_SET_SYSCALL_RETURN(r, res) \
37988 + UPT_SET_SYSCALL_RETURN(&(r)->regs, res)
37989 +#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs)
37991 +#define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs)
37993 +#define PT_REGS_SC(r) UPT_SC(&(r)->regs)
37995 +struct task_struct;
37997 +extern unsigned long getreg(struct task_struct *child, int regno);
37998 +extern int putreg(struct task_struct *child, int regno, unsigned long value);
37999 +extern int get_fpregs(unsigned long buf, struct task_struct *child);
38000 +extern int set_fpregs(unsigned long buf, struct task_struct *child);
38001 +extern int get_fpxregs(unsigned long buf, struct task_struct *child);
38002 +extern int set_fpxregs(unsigned long buf, struct task_struct *tsk);
38004 +extern void show_regs(struct pt_regs *regs);
38006 +#define INIT_TASK_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
38013 + * Overrides for Emacs so that we follow Linus's tabbing style.
38014 + * Emacs will notice this stuff at the end of the file and automatically
38015 + * adjust the settings for this buffer only. This must remain at the end
38017 + * ---------------------------------------------------------------------------
38018 + * Local variables:
38019 + * c-file-style: "linux"
38022 diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-i386.h um/include/asm-um/ptrace-i386.h
38023 --- orig/include/asm-um/ptrace-i386.h Wed Dec 31 19:00:00 1969
38024 +++ um/include/asm-um/ptrace-i386.h Wed Mar 26 22:01:25 2003
38027 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
38028 + * Licensed under the GPL
38031 +#ifndef __UM_PTRACE_I386_H
38032 +#define __UM_PTRACE_I386_H
38034 +#include "sysdep/ptrace.h"
38035 +#include "asm/ptrace-generic.h"
38037 +#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
38038 +#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs)
38039 +#define PT_REGS_ECX(r) UPT_ECX(&(r)->regs)
38040 +#define PT_REGS_EDX(r) UPT_EDX(&(r)->regs)
38041 +#define PT_REGS_ESI(r) UPT_ESI(&(r)->regs)
38042 +#define PT_REGS_EDI(r) UPT_EDI(&(r)->regs)
38043 +#define PT_REGS_EBP(r) UPT_EBP(&(r)->regs)
38045 +#define PT_REGS_CS(r) UPT_CS(&(r)->regs)
38046 +#define PT_REGS_SS(r) UPT_SS(&(r)->regs)
38047 +#define PT_REGS_DS(r) UPT_DS(&(r)->regs)
38048 +#define PT_REGS_ES(r) UPT_ES(&(r)->regs)
38049 +#define PT_REGS_FS(r) UPT_FS(&(r)->regs)
38050 +#define PT_REGS_GS(r) UPT_GS(&(r)->regs)
38052 +#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs)
38054 +#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_EAX(r)
38055 +#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r)
38056 +#define PT_FIX_EXEC_STACK(sp) do ; while(0)
38058 +#define user_mode(r) UPT_IS_USER(&(r)->regs)
38063 + * Overrides for Emacs so that we follow Linus's tabbing style.
38064 + * Emacs will notice this stuff at the end of the file and automatically
38065 + * adjust the settings for this buffer only. This must remain at the end
38067 + * ---------------------------------------------------------------------------
38068 + * Local variables:
38069 + * c-file-style: "linux"
38072 diff -Naur -X ../exclude-files orig/include/asm-um/resource.h um/include/asm-um/resource.h
38073 --- orig/include/asm-um/resource.h Wed Dec 31 19:00:00 1969
38074 +++ um/include/asm-um/resource.h Wed Oct 23 21:08:05 2002
38076 +#ifndef __UM_RESOURCE_H
38077 +#define __UM_RESOURCE_H
38079 +#include "asm/arch/resource.h"
38082 diff -Naur -X ../exclude-files orig/include/asm-um/rwlock.h um/include/asm-um/rwlock.h
38083 --- orig/include/asm-um/rwlock.h Wed Dec 31 19:00:00 1969
38084 +++ um/include/asm-um/rwlock.h Wed Oct 23 21:08:05 2002
38086 +#ifndef __UM_RWLOCK_H
38087 +#define __UM_RWLOCK_H
38089 +#include "asm/arch/rwlock.h"
38092 diff -Naur -X ../exclude-files orig/include/asm-um/rwsem.h um/include/asm-um/rwsem.h
38093 --- orig/include/asm-um/rwsem.h Wed Dec 31 19:00:00 1969
38094 +++ um/include/asm-um/rwsem.h Wed Apr 16 13:59:03 2003
38096 +#ifndef __UM_RWSEM_H__
38097 +#define __UM_RWSEM_H__
38099 +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
38100 +#define __builtin_expect(exp,c) (exp)
38103 +#include "asm/arch/rwsem.h"
38106 diff -Naur -X ../exclude-files orig/include/asm-um/scatterlist.h um/include/asm-um/scatterlist.h
38107 --- orig/include/asm-um/scatterlist.h Wed Dec 31 19:00:00 1969
38108 +++ um/include/asm-um/scatterlist.h Thu Feb 27 13:21:49 2003
38110 +#ifndef __UM_SCATTERLIST_H
38111 +#define __UM_SCATTERLIST_H
38113 +#include "asm/arch/scatterlist.h"
38116 diff -Naur -X ../exclude-files orig/include/asm-um/segment.h um/include/asm-um/segment.h
38117 --- orig/include/asm-um/segment.h Wed Dec 31 19:00:00 1969
38118 +++ um/include/asm-um/segment.h Fri Nov 1 19:45:34 2002
38120 +#ifndef __UM_SEGMENT_H
38121 +#define __UM_SEGMENT_H
38124 diff -Naur -X ../exclude-files orig/include/asm-um/semaphore.h um/include/asm-um/semaphore.h
38125 --- orig/include/asm-um/semaphore.h Wed Dec 31 19:00:00 1969
38126 +++ um/include/asm-um/semaphore.h Wed Apr 16 13:59:03 2003
38128 +#ifndef __UM_SEMAPHORE_H
38129 +#define __UM_SEMAPHORE_H
38131 +#include "asm/arch/semaphore.h"
38134 diff -Naur -X ../exclude-files orig/include/asm-um/sembuf.h um/include/asm-um/sembuf.h
38135 --- orig/include/asm-um/sembuf.h Wed Dec 31 19:00:00 1969
38136 +++ um/include/asm-um/sembuf.h Wed Oct 23 21:08:05 2002
38138 +#ifndef __UM_SEMBUF_H
38139 +#define __UM_SEMBUF_H
38141 +#include "asm/arch/sembuf.h"
38144 diff -Naur -X ../exclude-files orig/include/asm-um/serial.h um/include/asm-um/serial.h
38145 --- orig/include/asm-um/serial.h Wed Dec 31 19:00:00 1969
38146 +++ um/include/asm-um/serial.h Wed Oct 23 21:08:05 2002
38148 +#ifndef __UM_SERIAL_H
38149 +#define __UM_SERIAL_H
38151 +#include "asm/arch/serial.h"
38154 diff -Naur -X ../exclude-files orig/include/asm-um/shmbuf.h um/include/asm-um/shmbuf.h
38155 --- orig/include/asm-um/shmbuf.h Wed Dec 31 19:00:00 1969
38156 +++ um/include/asm-um/shmbuf.h Wed Oct 23 21:08:05 2002
38158 +#ifndef __UM_SHMBUF_H
38159 +#define __UM_SHMBUF_H
38161 +#include "asm/arch/shmbuf.h"
38164 diff -Naur -X ../exclude-files orig/include/asm-um/shmparam.h um/include/asm-um/shmparam.h
38165 --- orig/include/asm-um/shmparam.h Wed Dec 31 19:00:00 1969
38166 +++ um/include/asm-um/shmparam.h Wed Oct 23 21:08:05 2002
38168 +#ifndef __UM_SHMPARAM_H
38169 +#define __UM_SHMPARAM_H
38171 +#include "asm/arch/shmparam.h"
38174 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-generic.h um/include/asm-um/sigcontext-generic.h
38175 --- orig/include/asm-um/sigcontext-generic.h Wed Dec 31 19:00:00 1969
38176 +++ um/include/asm-um/sigcontext-generic.h Wed Oct 23 21:08:05 2002
38178 +#ifndef __UM_SIGCONTEXT_GENERIC_H
38179 +#define __UM_SIGCONTEXT_GENERIC_H
38181 +#include "asm/arch/sigcontext.h"
38184 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-i386.h um/include/asm-um/sigcontext-i386.h
38185 --- orig/include/asm-um/sigcontext-i386.h Wed Dec 31 19:00:00 1969
38186 +++ um/include/asm-um/sigcontext-i386.h Wed Oct 23 21:08:05 2002
38188 +#ifndef __UM_SIGCONTEXT_I386_H
38189 +#define __UM_SIGCONTEXT_I386_H
38191 +#include "asm/sigcontext-generic.h"
38194 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-ppc.h um/include/asm-um/sigcontext-ppc.h
38195 --- orig/include/asm-um/sigcontext-ppc.h Wed Dec 31 19:00:00 1969
38196 +++ um/include/asm-um/sigcontext-ppc.h Wed Oct 23 21:08:05 2002
38198 +#ifndef __UM_SIGCONTEXT_PPC_H
38199 +#define __UM_SIGCONTEXT_PPC_H
38201 +#define pt_regs sys_pt_regs
38203 +#include "asm/sigcontext-generic.h"
38208 diff -Naur -X ../exclude-files orig/include/asm-um/siginfo.h um/include/asm-um/siginfo.h
38209 --- orig/include/asm-um/siginfo.h Wed Dec 31 19:00:00 1969
38210 +++ um/include/asm-um/siginfo.h Wed Mar 26 22:01:25 2003
38212 +#ifndef __UM_SIGINFO_H
38213 +#define __UM_SIGINFO_H
38215 +#include "asm/arch/siginfo.h"
38218 diff -Naur -X ../exclude-files orig/include/asm-um/signal.h um/include/asm-um/signal.h
38219 --- orig/include/asm-um/signal.h Wed Dec 31 19:00:00 1969
38220 +++ um/include/asm-um/signal.h Wed Mar 26 22:01:25 2003
38223 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38224 + * Licensed under the GPL
38227 +#ifndef __UM_SIGNAL_H
38228 +#define __UM_SIGNAL_H
38230 +#include "asm/arch/signal.h"
38235 + * Overrides for Emacs so that we follow Linus's tabbing style.
38236 + * Emacs will notice this stuff at the end of the file and automatically
38237 + * adjust the settings for this buffer only. This must remain at the end
38239 + * ---------------------------------------------------------------------------
38240 + * Local variables:
38241 + * c-file-style: "linux"
38244 diff -Naur -X ../exclude-files orig/include/asm-um/smp.h um/include/asm-um/smp.h
38245 --- orig/include/asm-um/smp.h Wed Dec 31 19:00:00 1969
38246 +++ um/include/asm-um/smp.h Wed Mar 26 22:01:25 2003
38248 +#ifndef __UM_SMP_H
38249 +#define __UM_SMP_H
38253 +#include "linux/config.h"
38254 +#include "asm/current.h"
38256 +#define smp_processor_id() (current->processor)
38257 +#define cpu_logical_map(n) (n)
38258 +#define cpu_number_map(n) (n)
38259 +#define PROC_CHANGE_PENALTY 15 /* Pick a number, any number */
38260 +extern int hard_smp_processor_id(void);
38261 +extern unsigned long cpu_online_map;
38262 +#define NO_PROC_ID -1
38267 diff -Naur -X ../exclude-files orig/include/asm-um/smplock.h um/include/asm-um/smplock.h
38268 --- orig/include/asm-um/smplock.h Wed Dec 31 19:00:00 1969
38269 +++ um/include/asm-um/smplock.h Wed Apr 16 13:59:04 2003
38271 +#ifndef __UM_SMPLOCK_H
38272 +#define __UM_SMPLOCK_H
38274 +#include "asm/arch/smplock.h"
38277 diff -Naur -X ../exclude-files orig/include/asm-um/socket.h um/include/asm-um/socket.h
38278 --- orig/include/asm-um/socket.h Wed Dec 31 19:00:00 1969
38279 +++ um/include/asm-um/socket.h Thu Feb 27 13:20:13 2003
38281 +#ifndef __UM_SOCKET_H
38282 +#define __UM_SOCKET_H
38284 +#include "asm/arch/socket.h"
38287 diff -Naur -X ../exclude-files orig/include/asm-um/sockios.h um/include/asm-um/sockios.h
38288 --- orig/include/asm-um/sockios.h Wed Dec 31 19:00:00 1969
38289 +++ um/include/asm-um/sockios.h Wed Oct 23 21:08:05 2002
38291 +#ifndef __UM_SOCKIOS_H
38292 +#define __UM_SOCKIOS_H
38294 +#include "asm/arch/sockios.h"
38297 diff -Naur -X ../exclude-files orig/include/asm-um/softirq.h um/include/asm-um/softirq.h
38298 --- orig/include/asm-um/softirq.h Wed Dec 31 19:00:00 1969
38299 +++ um/include/asm-um/softirq.h Wed Apr 16 13:59:04 2003
38301 +#ifndef __UM_SOFTIRQ_H
38302 +#define __UM_SOFTIRQ_H
38304 +#include "linux/smp.h"
38305 +#include "asm/system.h"
38306 +#include "asm/processor.h"
38308 +/* A gratuitous name change */
38309 +#define i386_bh_lock um_bh_lock
38310 +#include "asm/arch/softirq.h"
38311 +#undef i386_bh_lock
38314 diff -Naur -X ../exclude-files orig/include/asm-um/spinlock.h um/include/asm-um/spinlock.h
38315 --- orig/include/asm-um/spinlock.h Wed Dec 31 19:00:00 1969
38316 +++ um/include/asm-um/spinlock.h Wed Mar 26 22:01:25 2003
38318 +#ifndef __UM_SPINLOCK_H
38319 +#define __UM_SPINLOCK_H
38321 +#include "linux/config.h"
38324 +#include "asm/arch/spinlock.h"
38328 diff -Naur -X ../exclude-files orig/include/asm-um/stat.h um/include/asm-um/stat.h
38329 --- orig/include/asm-um/stat.h Wed Dec 31 19:00:00 1969
38330 +++ um/include/asm-um/stat.h Wed Oct 23 21:08:05 2002
38332 +#ifndef __UM_STAT_H
38333 +#define __UM_STAT_H
38335 +#include "asm/arch/stat.h"
38338 diff -Naur -X ../exclude-files orig/include/asm-um/statfs.h um/include/asm-um/statfs.h
38339 --- orig/include/asm-um/statfs.h Wed Dec 31 19:00:00 1969
38340 +++ um/include/asm-um/statfs.h Wed Mar 26 22:01:25 2003
38342 +#ifndef _UM_STATFS_H
38343 +#define _UM_STATFS_H
38345 +#include "asm/arch/statfs.h"
38348 diff -Naur -X ../exclude-files orig/include/asm-um/string.h um/include/asm-um/string.h
38349 --- orig/include/asm-um/string.h Wed Dec 31 19:00:00 1969
38350 +++ um/include/asm-um/string.h Mon Feb 24 22:52:09 2003
38352 +#ifndef __UM_STRING_H
38353 +#define __UM_STRING_H
38355 +#include "asm/arch/string.h"
38356 +#include "asm/archparam.h"
38359 diff -Naur -X ../exclude-files orig/include/asm-um/system-generic.h um/include/asm-um/system-generic.h
38360 --- orig/include/asm-um/system-generic.h Wed Dec 31 19:00:00 1969
38361 +++ um/include/asm-um/system-generic.h Wed Mar 26 22:01:25 2003
38363 +#ifndef __UM_SYSTEM_GENERIC_H
38364 +#define __UM_SYSTEM_GENERIC_H
38366 +#include "asm/arch/system.h"
38368 +#undef prepare_to_switch
38370 +#undef __save_flags
38372 +#undef __restore_flags
38373 +#undef restore_flags
38378 +#undef local_irq_save
38379 +#undef local_irq_restore
38380 +#undef local_irq_disable
38381 +#undef local_irq_enable
38383 +#define prepare_to_switch() do ; while(0)
38385 +void *_switch_to(void *prev, void *next);
38387 +#define switch_to(prev, next, last) prev = _switch_to(prev, next)
38389 +extern int get_signals(void);
38390 +extern int set_signals(int enable);
38391 +extern void block_signals(void);
38392 +extern void unblock_signals(void);
38394 +#define local_irq_save(flags) do { (flags) = set_signals(0); } while(0)
38396 +#define local_irq_restore(flags) do { set_signals(flags); } while(0)
38398 +#define local_irq_enable() unblock_signals()
38399 +#define local_irq_disable() block_signals()
38401 +#define __sti() unblock_signals()
38402 +#define sti() unblock_signals()
38403 +#define __cli() block_signals()
38404 +#define cli() block_signals()
38406 +#define __save_flags(x) do { (flags) = get_signals(); } while(0)
38407 +#define save_flags(x) __save_flags(x)
38409 +#define __restore_flags(x) local_irq_restore(x)
38410 +#define restore_flags(x) __restore_flags(x)
38413 diff -Naur -X ../exclude-files orig/include/asm-um/system-i386.h um/include/asm-um/system-i386.h
38414 --- orig/include/asm-um/system-i386.h Wed Dec 31 19:00:00 1969
38415 +++ um/include/asm-um/system-i386.h Wed Mar 26 22:01:25 2003
38417 +#ifndef __UM_SYSTEM_I386_H
38418 +#define __UM_SYSTEM_I386_H
38420 +#include "asm/system-generic.h"
38422 +#define __HAVE_ARCH_CMPXCHG 1
38424 +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
38425 + unsigned long new, int size)
38427 + unsigned long prev;
38430 + __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
38432 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
38436 + __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
38438 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
38442 + __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
38444 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
38451 +#define cmpxchg(ptr,o,n)\
38452 + ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
38453 + (unsigned long)(n),sizeof(*(ptr))))
38456 diff -Naur -X ../exclude-files orig/include/asm-um/system-ppc.h um/include/asm-um/system-ppc.h
38457 --- orig/include/asm-um/system-ppc.h Wed Dec 31 19:00:00 1969
38458 +++ um/include/asm-um/system-ppc.h Wed Oct 23 21:08:05 2002
38460 +#ifndef __UM_SYSTEM_PPC_H
38461 +#define __UM_SYSTEM_PPC_H
38463 +#define _switch_to _ppc_switch_to
38465 +#include "asm/arch/system.h"
38469 +#include "asm/system-generic.h"
38472 diff -Naur -X ../exclude-files orig/include/asm-um/termbits.h um/include/asm-um/termbits.h
38473 --- orig/include/asm-um/termbits.h Wed Dec 31 19:00:00 1969
38474 +++ um/include/asm-um/termbits.h Wed Oct 23 21:11:14 2002
38476 +#ifndef __UM_TERMBITS_H
38477 +#define __UM_TERMBITS_H
38479 +#include "asm/arch/termbits.h"
38482 diff -Naur -X ../exclude-files orig/include/asm-um/termios.h um/include/asm-um/termios.h
38483 --- orig/include/asm-um/termios.h Wed Dec 31 19:00:00 1969
38484 +++ um/include/asm-um/termios.h Thu Feb 27 13:20:13 2003
38486 +#ifndef __UM_TERMIOS_H
38487 +#define __UM_TERMIOS_H
38489 +#include "asm/arch/termios.h"
38492 diff -Naur -X ../exclude-files orig/include/asm-um/timex.h um/include/asm-um/timex.h
38493 --- orig/include/asm-um/timex.h Wed Dec 31 19:00:00 1969
38494 +++ um/include/asm-um/timex.h Wed Mar 26 22:01:25 2003
38496 +#ifndef __UM_TIMEX_H
38497 +#define __UM_TIMEX_H
38499 +#include "linux/time.h"
38501 +typedef unsigned long cycles_t;
38503 +#define cacheflush_time (0)
38505 +static inline cycles_t get_cycles (void)
38510 +#define vxtime_lock() do ; while (0)
38511 +#define vxtime_unlock() do ; while (0)
38514 diff -Naur -X ../exclude-files orig/include/asm-um/tlb.h um/include/asm-um/tlb.h
38515 --- orig/include/asm-um/tlb.h Wed Dec 31 19:00:00 1969
38516 +++ um/include/asm-um/tlb.h Wed Oct 23 21:08:05 2002
38518 +#include <asm-generic/tlb.h>
38519 diff -Naur -X ../exclude-files orig/include/asm-um/types.h um/include/asm-um/types.h
38520 --- orig/include/asm-um/types.h Wed Dec 31 19:00:00 1969
38521 +++ um/include/asm-um/types.h Wed Oct 23 21:08:05 2002
38523 +#ifndef __UM_TYPES_H
38524 +#define __UM_TYPES_H
38526 +#include "asm/arch/types.h"
38529 diff -Naur -X ../exclude-files orig/include/asm-um/uaccess.h um/include/asm-um/uaccess.h
38530 --- orig/include/asm-um/uaccess.h Wed Dec 31 19:00:00 1969
38531 +++ um/include/asm-um/uaccess.h Wed Oct 23 21:08:05 2002
38534 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38535 + * Licensed under the GPL
38538 +#ifndef __UM_UACCESS_H
38539 +#define __UM_UACCESS_H
38541 +#define VERIFY_READ 0
38542 +#define VERIFY_WRITE 1
38545 + * The fs value determines whether argument validity checking should be
38546 + * performed or not. If get_fs() == USER_DS, checking is performed, with
38547 + * get_fs() == KERNEL_DS, checking is bypassed.
38549 + * For historical reasons, these macros are grossly misnamed.
38552 +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
38554 +#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
38555 +#define USER_DS MAKE_MM_SEG(TASK_SIZE)
38557 +#define get_ds() (KERNEL_DS)
38558 +#define get_fs() (current->addr_limit)
38559 +#define set_fs(x) (current->addr_limit = (x))
38561 +#define segment_eq(a, b) ((a).seg == (b).seg)
38563 +#include "um_uaccess.h"
38565 +#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
38567 +#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
38569 +#define __get_user(x, ptr) \
38571 + const __typeof__(ptr) __private_ptr = ptr; \
38572 + __typeof__(*(__private_ptr)) __private_val; \
38573 + int __private_ret = -EFAULT; \
38575 + if (__copy_from_user(&__private_val, (__private_ptr), \
38576 + sizeof(*(__private_ptr))) == 0) {\
38577 + (x) = (__typeof__(*(__private_ptr))) __private_val; \
38578 + __private_ret = 0; \
38583 +#define get_user(x, ptr) \
38585 + const __typeof__((*ptr)) *private_ptr = (ptr); \
38586 + (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \
38587 + __get_user(x, private_ptr) : ((x) = 0, -EFAULT)); \
38590 +#define __put_user(x, ptr) \
38592 + __typeof__(ptr) __private_ptr = ptr; \
38593 + __typeof__(*(__private_ptr)) __private_val; \
38594 + int __private_ret = -EFAULT; \
38595 + __private_val = (__typeof__(*(__private_ptr))) (x); \
38596 + if (__copy_to_user((__private_ptr), &__private_val, \
38597 + sizeof(*(__private_ptr))) == 0) { \
38598 + __private_ret = 0; \
38603 +#define put_user(x, ptr) \
38605 + __typeof__(*(ptr)) *private_ptr = (ptr); \
38606 + (access_ok(VERIFY_WRITE, private_ptr, sizeof(*private_ptr)) ? \
38607 + __put_user(x, private_ptr) : -EFAULT); \
38610 +#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
38612 +struct exception_table_entry
38614 + unsigned long insn;
38615 + unsigned long fixup;
38621 + * Overrides for Emacs so that we follow Linus's tabbing style.
38622 + * Emacs will notice this stuff at the end of the file and automatically
38623 + * adjust the settings for this buffer only. This must remain at the end
38625 + * ---------------------------------------------------------------------------
38626 + * Local variables:
38627 + * c-file-style: "linux"
38630 diff -Naur -X ../exclude-files orig/include/asm-um/ucontext.h um/include/asm-um/ucontext.h
38631 --- orig/include/asm-um/ucontext.h Wed Dec 31 19:00:00 1969
38632 +++ um/include/asm-um/ucontext.h Sun Dec 1 13:20:58 2002
38634 +#ifndef _ASM_UM_UCONTEXT_H
38635 +#define _ASM_UM_UCONTEXT_H
38637 +#include "asm/arch/ucontext.h"
38640 diff -Naur -X ../exclude-files orig/include/asm-um/unaligned.h um/include/asm-um/unaligned.h
38641 --- orig/include/asm-um/unaligned.h Wed Dec 31 19:00:00 1969
38642 +++ um/include/asm-um/unaligned.h Wed Oct 23 21:08:05 2002
38644 +#ifndef __UM_UNALIGNED_H
38645 +#define __UM_UNALIGNED_H
38647 +#include "asm/arch/unaligned.h"
38650 diff -Naur -X ../exclude-files orig/include/asm-um/unistd.h um/include/asm-um/unistd.h
38651 --- orig/include/asm-um/unistd.h Wed Dec 31 19:00:00 1969
38652 +++ um/include/asm-um/unistd.h Wed Mar 26 22:01:27 2003
38655 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
38656 + * Licensed under the GPL
38659 +#ifndef _UM_UNISTD_H_
38660 +#define _UM_UNISTD_H_
38662 +#include "linux/resource.h"
38663 +#include "asm/uaccess.h"
38665 +extern long sys_open(const char *filename, int flags, int mode);
38666 +extern long sys_dup(unsigned int fildes);
38667 +extern long sys_close(unsigned int fd);
38668 +extern int um_execve(const char *file, char *const argv[], char *const env[]);
38669 +extern long sys_setsid(void);
38670 +extern long sys_waitpid(pid_t pid, unsigned int * stat_addr, int options);
38671 +extern long sys_wait4(pid_t pid,unsigned int *stat_addr, int options,
38672 + struct rusage *ru);
38673 +extern long sys_mount(char *dev_name, char *dir_name, char *type,
38674 + unsigned long flags, void *data);
38675 +extern long sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp,
38676 + struct timeval *tvp);
38677 +extern long sys_lseek(unsigned int fildes, unsigned long offset, int whence);
38678 +extern long sys_read(unsigned int fildes, char *buf, int len);
38679 +extern long sys_write(unsigned int fildes, char *buf, int len);
38681 +#ifdef __KERNEL_SYSCALLS__
38683 +#define KERNEL_CALL(ret_t, sys, args...) \
38684 + mm_segment_t fs = get_fs(); \
38686 + set_fs(KERNEL_DS); \
38687 + ret = sys(args); \
38691 +static inline long open(const char *pathname, int flags, int mode)
38693 + KERNEL_CALL(int, sys_open, pathname, flags, mode)
38696 +static inline long dup(unsigned int fd)
38698 + KERNEL_CALL(int, sys_dup, fd);
38701 +static inline long close(unsigned int fd)
38703 + KERNEL_CALL(int, sys_close, fd);
38706 +static inline int execve(const char *filename, char *const argv[],
38707 + char *const envp[])
38709 + KERNEL_CALL(int, um_execve, filename, argv, envp);
38712 +static inline long waitpid(pid_t pid, unsigned int *status, int options)
38714 + KERNEL_CALL(pid_t, sys_wait4, pid, status, options, NULL)
38717 +static inline pid_t wait(int *status)
38719 + KERNEL_CALL(pid_t, sys_wait4, -1, status, 0, NULL)
38722 +static inline pid_t setsid(void)
38724 + KERNEL_CALL(pid_t, sys_setsid)
38727 +static inline long lseek(unsigned int fd, off_t offset, unsigned int whence)
38729 + KERNEL_CALL(long, sys_lseek, fd, offset, whence)
38732 +static inline int read(unsigned int fd, char * buf, int len)
38734 + KERNEL_CALL(int, sys_read, fd, buf, len)
38737 +static inline int write(unsigned int fd, char * buf, int len)
38739 + KERNEL_CALL(int, sys_write, fd, buf, len)
38744 +/* Save the value of __KERNEL_SYSCALLS__, undefine it, include the underlying
38745 + * arch's unistd.h for the system call numbers, and restore the old
38746 + * __KERNEL_SYSCALLS__.
38749 +#ifdef __KERNEL_SYSCALLS__
38750 +#define __SAVE_KERNEL_SYSCALLS__ __KERNEL_SYSCALLS__
38753 +#undef __KERNEL_SYSCALLS__
38754 +#include "asm/arch/unistd.h"
38756 +#ifdef __KERNEL_SYSCALLS__
38757 +#define __KERNEL_SYSCALLS__ __SAVE_KERNEL_SYSCALLS__
38763 + * Overrides for Emacs so that we follow Linus's tabbing style.
38764 + * Emacs will notice this stuff at the end of the file and automatically
38765 + * adjust the settings for this buffer only. This must remain at the end
38767 + * ---------------------------------------------------------------------------
38768 + * Local variables:
38769 + * c-file-style: "linux"
38772 diff -Naur -X ../exclude-files orig/include/asm-um/user.h um/include/asm-um/user.h
38773 --- orig/include/asm-um/user.h Wed Dec 31 19:00:00 1969
38774 +++ um/include/asm-um/user.h Wed Apr 16 13:59:45 2003
38776 +#ifndef __UM_USER_H
38777 +#define __UM_USER_H
38779 +#include "asm/arch/user.h"
38782 diff -Naur -X ../exclude-files orig/include/asm-um/vga.h um/include/asm-um/vga.h
38783 --- orig/include/asm-um/vga.h Wed Dec 31 19:00:00 1969
38784 +++ um/include/asm-um/vga.h Wed Oct 23 21:08:05 2002
38786 +#ifndef __UM_VGA_H
38787 +#define __UM_VGA_H
38789 +#include "asm/arch/vga.h"
38792 diff -Naur -X ../exclude-files orig/include/asm-um/xor.h um/include/asm-um/xor.h
38793 --- orig/include/asm-um/xor.h Wed Dec 31 19:00:00 1969
38794 +++ um/include/asm-um/xor.h Wed Oct 23 21:08:05 2002
38796 +#ifndef __UM_XOR_H
38797 +#define __UM_XOR_H
38799 +#include "asm-generic/xor.h"
38802 diff -Naur -X ../exclude-files orig/include/linux/blk.h um/include/linux/blk.h
38803 --- orig/include/linux/blk.h Sun Sep 15 12:13:19 2002
38804 +++ um/include/linux/blk.h Wed Apr 16 13:59:04 2003
38805 @@ -320,6 +320,15 @@
38806 #define DEVICE_REQUEST do_ida_request
38807 #define DEVICE_NR(device) (MINOR(device) >> 4)
38809 +#elif (MAJOR_NR == UBD_MAJOR)
38811 +#define DEVICE_NAME "User-mode block device"
38812 +#define DEVICE_INTR do_ubd
38813 +#define DEVICE_REQUEST do_ubd_request
38814 +#define DEVICE_NR(device) (MINOR(device) >> UBD_SHIFT)
38815 +#define DEVICE_ON(device)
38816 +#define DEVICE_OFF(device)
38818 #endif /* MAJOR_NR == whatever */
38820 /* provide DEVICE_xxx defaults, if not explicitly defined
38821 diff -Naur -X ../exclude-files orig/include/linux/fs.h um/include/linux/fs.h
38822 --- orig/include/linux/fs.h Thu Feb 27 13:04:27 2003
38823 +++ um/include/linux/fs.h Wed Apr 16 13:59:03 2003
38824 @@ -318,6 +318,8 @@
38825 #include <linux/ncp_fs_i.h>
38826 #include <linux/proc_fs_i.h>
38827 #include <linux/usbdev_fs_i.h>
38828 +#include <linux/hostfs_fs_i.h>
38829 +#include <linux/hppfs_fs_i.h>
38830 #include <linux/jffs2_fs_i.h>
38831 #include <linux/cramfs_fs_sb.h>
38833 @@ -509,7 +511,9 @@
38834 struct proc_inode_info proc_i;
38835 struct socket socket_i;
38836 struct usbdev_inode_info usbdev_i;
38837 - struct jffs2_inode_info jffs2_i;
38838 + struct hostfs_inode_info hostfs_i;
38839 + struct hppfs_inode_info hppfs_i;
38840 + struct jffs2_inode_info jffs2_i;
38844 diff -Naur -X ../exclude-files orig/include/linux/hostfs_fs_i.h um/include/linux/hostfs_fs_i.h
38845 --- orig/include/linux/hostfs_fs_i.h Wed Dec 31 19:00:00 1969
38846 +++ um/include/linux/hostfs_fs_i.h Wed Oct 23 21:08:05 2002
38848 +#ifndef _HOSTFS_FS_I
38849 +#define _HOSTFS_FS_I
38851 +struct hostfs_inode_info {
38852 + char *host_filename;
38860 + * Overrides for Emacs so that we follow Linus's tabbing style.
38861 + * Emacs will notice this stuff at the end of the file and automatically
38862 + * adjust the settings for this buffer only. This must remain at the end
38864 + * ---------------------------------------------------------------------------
38865 + * Local variables:
38866 + * c-file-style: "linux"
38869 diff -Naur -X ../exclude-files orig/include/linux/hppfs_fs_i.h um/include/linux/hppfs_fs_i.h
38870 --- orig/include/linux/hppfs_fs_i.h Wed Dec 31 19:00:00 1969
38871 +++ um/include/linux/hppfs_fs_i.h Wed Oct 23 21:08:05 2002
38873 +#ifndef _HPPFS_FS_I
38874 +#define _HPPFS_FS_I
38876 +struct hppfs_inode_info {
38877 + struct dentry *proc_dentry;
38883 + * Overrides for Emacs so that we follow Linus's tabbing style.
38884 + * Emacs will notice this stuff at the end of the file and automatically
38885 + * adjust the settings for this buffer only. This must remain at the end
38887 + * ---------------------------------------------------------------------------
38888 + * Local variables:
38889 + * c-file-style: "linux"
38892 diff -Naur -X ../exclude-files orig/include/linux/kernel.h um/include/linux/kernel.h
38893 --- orig/include/linux/kernel.h Thu Feb 27 13:04:27 2003
38894 +++ um/include/linux/kernel.h Wed Mar 26 22:01:25 2003
38896 # define ATTRIB_NORET __attribute__((noreturn))
38897 # define NORET_AND noreturn,
38900 +#if defined(__i386__) || defined(UM_FASTCALL)
38901 #define FASTCALL(x) x __attribute__((regparm(3)))
38903 #define FASTCALL(x) x
38904 diff -Naur -X ../exclude-files orig/include/linux/kernel_stat.h um/include/linux/kernel_stat.h
38905 --- orig/include/linux/kernel_stat.h Thu Feb 27 13:04:27 2003
38906 +++ um/include/linux/kernel_stat.h Wed Apr 16 13:59:39 2003
38908 * used by rstatd/perfmeter
38911 -#define DK_MAX_MAJOR 16
38912 +#define DK_MAX_MAJOR 99
38913 #define DK_MAX_DISK 16
38915 struct kernel_stat {
38916 diff -Naur -X ../exclude-files orig/include/linux/mm.h um/include/linux/mm.h
38917 --- orig/include/linux/mm.h Sun Sep 15 12:13:19 2002
38918 +++ um/include/linux/mm.h Wed Apr 16 13:59:04 2003
38919 @@ -425,6 +425,14 @@
38920 extern struct page * FASTCALL(__alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist));
38921 extern struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order);
38923 +#ifndef HAVE_ARCH_VALIDATE
38924 +static inline struct page *arch_validate(struct page *page,
38925 + unsigned int gfp_mask, int order)
38931 static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
38934 @@ -432,7 +440,7 @@
38936 if (order >= MAX_ORDER)
38938 - return _alloc_pages(gfp_mask, order);
38939 + return arch_validate(_alloc_pages(gfp_mask, order), gfp_mask, order);
38942 #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
38943 @@ -492,6 +500,9 @@
38944 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
38945 int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
38947 +extern long do_mprotect(struct mm_struct *mm, unsigned long start,
38948 + size_t len, unsigned long prot);
38951 * On a two-level page table, this ends up being trivial. Thus the
38952 * inlining and the symmetry break with pte_alloc() that does all
38953 @@ -539,9 +550,10 @@
38955 extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
38957 -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
38958 - unsigned long len, unsigned long prot,
38959 - unsigned long flag, unsigned long pgoff);
38960 +extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file,
38961 + unsigned long addr, unsigned long len,
38962 + unsigned long prot, unsigned long flag,
38963 + unsigned long pgoff);
38965 static inline unsigned long do_mmap(struct file *file, unsigned long addr,
38966 unsigned long len, unsigned long prot,
38967 @@ -551,7 +563,8 @@
38968 if ((offset + PAGE_ALIGN(len)) < offset)
38970 if (!(offset & ~PAGE_MASK))
38971 - ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
38972 + ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag,
38973 + offset >> PAGE_SHIFT);
38977 diff -Naur -X ../exclude-files orig/include/linux/proc_mm.h um/include/linux/proc_mm.h
38978 --- orig/include/linux/proc_mm.h Wed Dec 31 19:00:00 1969
38979 +++ um/include/linux/proc_mm.h Wed Apr 16 13:59:47 2003
38982 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38983 + * Licensed under the GPL
38986 +#ifndef __PROC_MM_H
38987 +#define __PROC_MM_H
38989 +#include "linux/sched.h"
38991 +#define MM_MMAP 54
38992 +#define MM_MUNMAP 55
38993 +#define MM_MPROTECT 56
38994 +#define MM_COPY_SEGMENTS 57
38997 + unsigned long addr;
38998 + unsigned long len;
38999 + unsigned long prot;
39000 + unsigned long flags;
39001 + unsigned long fd;
39002 + unsigned long offset;
39005 +struct mm_munmap {
39006 + unsigned long addr;
39007 + unsigned long len;
39010 +struct mm_mprotect {
39011 + unsigned long addr;
39012 + unsigned long len;
39013 + unsigned int prot;
39016 +struct proc_mm_op {
39019 + struct mm_mmap mmap;
39020 + struct mm_munmap munmap;
39021 + struct mm_mprotect mprotect;
39022 + int copy_segments;
39026 +extern struct mm_struct *proc_mm_get_mm(int fd);
39029 diff -Naur -X ../exclude-files orig/include/linux/tty.h um/include/linux/tty.h
39030 --- orig/include/linux/tty.h Thu Feb 27 13:04:28 2003
39031 +++ um/include/linux/tty.h Wed Apr 16 13:59:04 2003
39032 @@ -309,6 +309,9 @@
39033 spinlock_t read_lock;
39034 /* If the tty has a pending do_SAK, queue it here - akpm */
39035 struct tq_struct SAK_tq;
39036 +#ifdef CONFIG_TTY_LOG
39041 /* tty magic number */
39042 @@ -366,6 +369,7 @@
39043 extern int specialix_init(void);
39044 extern int espserial_init(void);
39045 extern int macserial_init(void);
39046 +extern int stdio_init(void);
39047 extern int a2232board_init(void);
39049 extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
39050 @@ -420,6 +424,8 @@
39052 extern int vt_ioctl(struct tty_struct *tty, struct file * file,
39053 unsigned int cmd, unsigned long arg);
39055 +extern void stdio_console_init(void);
39057 #endif /* __KERNEL__ */
39059 diff -Naur -X ../exclude-files orig/init/do_mounts.c um/init/do_mounts.c
39060 --- orig/init/do_mounts.c Thu Feb 27 13:04:28 2003
39061 +++ um/init/do_mounts.c Thu Feb 27 13:05:27 2003
39062 @@ -153,6 +153,22 @@
39064 { "apblock", APBLOCK_MAJOR << 8},
39065 { "ddv", DDV_MAJOR << 8},
39066 + { "ubd0", UBD_MAJOR << 8 | 0 << 4},
39067 + { "ubda", UBD_MAJOR << 8 | 0 << 4},
39068 + { "ubd1", UBD_MAJOR << 8 | 1 << 4},
39069 + { "ubdb", UBD_MAJOR << 8 | 1 << 4},
39070 + { "ubd2", UBD_MAJOR << 8 | 2 << 4},
39071 + { "ubdc", UBD_MAJOR << 8 | 2 << 4},
39072 + { "ubd3", UBD_MAJOR << 8 | 3 << 4},
39073 + { "ubdd", UBD_MAJOR << 8 | 3 << 4},
39074 + { "ubd4", UBD_MAJOR << 8 | 4 << 4},
39075 + { "ubde", UBD_MAJOR << 8 | 4 << 4},
39076 + { "ubd5", UBD_MAJOR << 8 | 5 << 4},
39077 + { "ubdf", UBD_MAJOR << 8 | 5 << 4},
39078 + { "ubd6", UBD_MAJOR << 8 | 6 << 4},
39079 + { "ubdg", UBD_MAJOR << 8 | 6 << 4},
39080 + { "ubd7", UBD_MAJOR << 8 | 7 << 4},
39081 + { "ubdh", UBD_MAJOR << 8 | 7 << 4},
39082 { "jsfd", JSFD_MAJOR << 8},
39083 #if defined(CONFIG_ARCH_S390)
39084 { "dasda", (DASD_MAJOR << MINORBITS) },
39085 diff -Naur -X ../exclude-files orig/kernel/panic.c um/kernel/panic.c
39086 --- orig/kernel/panic.c Thu Feb 27 13:04:29 2003
39087 +++ um/kernel/panic.c Thu Feb 27 13:05:27 2003
39092 - notifier_call_chain(&panic_notifier_list, 0, NULL);
39093 + notifier_call_chain(&panic_notifier_list, 0, buf);
39095 if (panic_timeout > 0)
39097 diff -Naur -X ../exclude-files orig/mm/Makefile um/mm/Makefile
39098 --- orig/mm/Makefile Wed Aug 21 11:47:43 2002
39099 +++ um/mm/Makefile Fri Nov 8 14:21:36 2002
39103 obj-$(CONFIG_HIGHMEM) += highmem.o
39104 +obj-$(CONFIG_PROC_MM) += proc_mm.o
39106 include $(TOPDIR)/Rules.make
39107 diff -Naur -X ../exclude-files orig/mm/mmap.c um/mm/mmap.c
39108 --- orig/mm/mmap.c Thu Feb 27 13:04:29 2003
39109 +++ um/mm/mmap.c Thu Feb 27 13:05:27 2003
39110 @@ -390,10 +390,11 @@
39114 -unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned long len,
39115 - unsigned long prot, unsigned long flags, unsigned long pgoff)
39116 +unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file,
39117 + unsigned long addr, unsigned long len,
39118 + unsigned long prot, unsigned long flags,
39119 + unsigned long pgoff)
39121 - struct mm_struct * mm = current->mm;
39122 struct vm_area_struct * vma, * prev;
39123 unsigned int vm_flags;
39124 int correct_wcount = 0;
39125 diff -Naur -X ../exclude-files orig/mm/mprotect.c um/mm/mprotect.c
39126 --- orig/mm/mprotect.c Wed Aug 21 11:47:43 2002
39127 +++ um/mm/mprotect.c Sun Nov 10 20:24:32 2002
39128 @@ -264,7 +264,8 @@
39132 -asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
39133 +long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
39134 + unsigned long prot)
39136 unsigned long nstart, end, tmp;
39137 struct vm_area_struct * vma, * next, * prev;
39138 @@ -281,9 +282,9 @@
39142 - down_write(¤t->mm->mmap_sem);
39143 + down_write(&mm->mmap_sem);
39145 - vma = find_vma_prev(current->mm, start, &prev);
39146 + vma = find_vma_prev(mm, start, &prev);
39148 if (!vma || vma->vm_start > start)
39150 @@ -332,6 +333,11 @@
39151 prev->vm_mm->map_count--;
39154 - up_write(¤t->mm->mmap_sem);
39155 + up_write(&mm->mmap_sem);
39159 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
39161 + return(do_mprotect(current->mm, start, len, prot));
39163 diff -Naur -X ../exclude-files orig/mm/proc_mm.c um/mm/proc_mm.c
39164 --- orig/mm/proc_mm.c Wed Dec 31 19:00:00 1969
39165 +++ um/mm/proc_mm.c Tue Nov 19 14:20:26 2002
39168 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39169 + * Licensed under the GPL
39172 +#include "linux/init.h"
39173 +#include "linux/proc_fs.h"
39174 +#include "linux/proc_mm.h"
39175 +#include "linux/file.h"
39176 +#include "asm/uaccess.h"
39177 +#include "asm/mmu_context.h"
39179 +static struct file_operations proc_mm_fops;
39181 +struct mm_struct *proc_mm_get_mm(int fd)
39183 + struct mm_struct *ret = ERR_PTR(-EBADF);
39184 + struct file *file;
39190 + ret = ERR_PTR(-EINVAL);
39191 + if(file->f_op != &proc_mm_fops)
39194 + ret = file->private_data;
39201 +extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
39202 + unsigned long len, unsigned long prot,
39203 + unsigned long flags, unsigned long fd,
39204 + unsigned long pgoff);
39206 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
39207 + size_t count, loff_t *ppos)
39209 + struct mm_struct *mm = file->private_data;
39210 + struct proc_mm_op req;
39213 + if(count > sizeof(req))
39216 + n = copy_from_user(&req, buffer, count);
39223 + struct mm_mmap *map = &req.u.mmap;
39225 + ret = do_mmap2(mm, map->addr, map->len, map->prot,
39226 + map->flags, map->fd, map->offset >> PAGE_SHIFT);
39227 + if((ret & ~PAGE_MASK) == 0)
39232 + case MM_MUNMAP: {
39233 + struct mm_munmap *unmap = &req.u.munmap;
39235 + down_write(&mm->mmap_sem);
39236 + ret = do_munmap(mm, unmap->addr, unmap->len);
39237 + up_write(&mm->mmap_sem);
39243 + case MM_MPROTECT: {
39244 + struct mm_mprotect *protect = &req.u.mprotect;
39246 + ret = do_mprotect(mm, protect->addr, protect->len,
39253 + case MM_COPY_SEGMENTS: {
39254 + struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
39256 + if(IS_ERR(from)){
39257 + ret = PTR_ERR(from);
39261 + mm_copy_segments(from, mm);
39272 +static int open_proc_mm(struct inode *inode, struct file *file)
39274 + struct mm_struct *mm = mm_alloc();
39281 + ret = init_new_context(current, mm);
39285 + spin_lock(&mmlist_lock);
39286 + list_add(&mm->mmlist, ¤t->mm->mmlist);
39288 + spin_unlock(&mmlist_lock);
39290 + file->private_data = mm;
39300 +static int release_proc_mm(struct inode *inode, struct file *file)
39302 + struct mm_struct *mm = file->private_data;
39308 +static struct file_operations proc_mm_fops = {
39309 + .open = open_proc_mm,
39310 + .release = release_proc_mm,
39311 + .write = write_proc_mm,
39314 +static int make_proc_mm(void)
39316 + struct proc_dir_entry *ent;
39318 + ent = create_proc_entry("mm", 0222, &proc_root);
39320 + printk("make_proc_mm : Failed to register /proc/mm\n");
39323 + ent->proc_fops = &proc_mm_fops;
39328 +__initcall(make_proc_mm);
39331 + * Overrides for Emacs so that we follow Linus's tabbing style.
39332 + * Emacs will notice this stuff at the end of the file and automatically
39333 + * adjust the settings for this buffer only. This must remain at the end
39335 + * ---------------------------------------------------------------------------
39336 + * Local variables:
39337 + * c-file-style: "linux"
39340 diff -Naur -X ../exclude-files orig/mm/slab.c um/mm/slab.c
39341 --- orig/mm/slab.c Thu Feb 27 13:04:29 2003
39342 +++ um/mm/slab.c Thu Feb 27 13:05:27 2003
39343 @@ -1946,10 +1946,14 @@
39345 name = cachep->name;
39350 + set_fs(KERNEL_DS);
39351 if (__get_user(tmp, name))
39357 seq_printf(m, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
39358 name, active_objs, num_objs, cachep->objsize,