diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-02 09:45:39 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-02 09:45:39 -0700 |
commit | de0a5345a55b8dd5a4695181275df0e691176830 (patch) | |
tree | 17530e824f7f46ce0b1757657179fb5957a6add5 | |
parent | 994c0e992522c123298b4a91b72f5e67ba2d1123 (diff) | |
parent | 8535639810e578960233ad39def3ac2157b0c3ec (diff) | |
download | op-kernel-dev-de0a5345a55b8dd5a4695181275df0e691176830.zip op-kernel-dev-de0a5345a55b8dd5a4695181275df0e691176830.tar.gz |
Merge branch 'for-linus' of git://github.com/richardweinberger/linux
* 'for-linus' of git://github.com/richardweinberger/linux: (90 commits)
um: fix ubd cow size
um: Fix kmalloc argument order in um/vdso/vma.c
um: switch to use of drivers/Kconfig
UserModeLinux-HOWTO.txt: fix a typo
UserModeLinux-HOWTO.txt: remove ^H characters
um: we need sys/user.h only on i386
um: merge delay_{32,64}.c
um: distribute exports to where exported stuff is defined
um: kill system-um.h
um: generic ftrace.h will do...
um: segment.h is x86-only and needed only there
um: asm/pda.h is not needed anymore
um: hw_irq.h can go generic as well
um: switch to generic-y
um: clean Kconfig up a bit
um: a couple of missing dependencies...
um: kill useless argument of free_chan() and free_one_chan()
um: unify ptrace_user.h
um: unify KSTK_...
um: fix gcov build breakage
...
253 files changed, 1666 insertions, 3326 deletions
diff --git a/Documentation/virtual/uml/UserModeLinux-HOWTO.txt b/Documentation/virtual/uml/UserModeLinux-HOWTO.txt index 5d0fc8b..77dfecf 100644 --- a/Documentation/virtual/uml/UserModeLinux-HOWTO.txt +++ b/Documentation/virtual/uml/UserModeLinux-HOWTO.txt @@ -134,13 +134,13 @@ ______________________________________________________________________ - 11.. IInnttrroodduuccttiioonn + 1. Introduction Welcome to User Mode Linux. It's going to be fun. - 11..11.. HHooww iiss UUsseerr MMooddee LLiinnuuxx DDiiffffeerreenntt?? + 1.1. How is User Mode Linux Different? Normally, the Linux Kernel talks straight to your hardware (video card, keyboard, hard drives, etc), and any programs which run ask the @@ -181,7 +181,7 @@ - 11..22.. WWhhyy WWoouulldd II WWaanntt UUsseerr MMooddee LLiinnuuxx?? + 1.2. Why Would I Want User Mode Linux? 1. If User Mode Linux crashes, your host kernel is still fine. @@ -206,12 +206,12 @@ - 22.. CCoommppiilliinngg tthhee kkeerrnneell aanndd mmoodduulleess + 2. Compiling the kernel and modules - 22..11.. CCoommppiilliinngg tthhee kkeerrnneell + 2.1. Compiling the kernel Compiling the user mode kernel is just like compiling any other @@ -322,7 +322,7 @@ bug fixes and enhancements that have gone into subsequent releases. - 22..22.. CCoommppiilliinngg aanndd iinnssttaalllliinngg kkeerrnneell mmoodduulleess + 2.2. Compiling and installing kernel modules UML modules are built in the same way as the native kernel (with the exception of the 'ARCH=um' that you always need for UML): @@ -386,19 +386,19 @@ - 22..33.. CCoommppiilliinngg aanndd iinnssttaalllliinngg uummll__uuttiilliittiieess + 2.3. Compiling and installing uml_utilities Many features of the UML kernel require a user-space helper program, so a uml_utilities package is distributed separately from the kernel patch which provides these helpers. Included within this is: - +o port-helper - Used by consoles which connect to xterms or ports + o port-helper - Used by consoles which connect to xterms or ports - +o tunctl - Configuration tool to create and delete tap devices + o tunctl - Configuration tool to create and delete tap devices - +o uml_net - Setuid binary for automatic tap device configuration + o uml_net - Setuid binary for automatic tap device configuration - +o uml_switch - User-space virtual switch required for daemon + o uml_switch - User-space virtual switch required for daemon transport The uml_utilities tree is compiled with: @@ -423,11 +423,11 @@ - 33.. RRuunnnniinngg UUMMLL aanndd llooggggiinngg iinn + 3. Running UML and logging in - 33..11.. RRuunnnniinngg UUMMLL + 3.1. Running UML It runs on 2.2.15 or later, and all 2.4 kernels. @@ -454,7 +454,7 @@ - 33..22.. LLooggggiinngg iinn + 3.2. Logging in @@ -468,7 +468,7 @@ There are a couple of other ways to log in: - +o On a virtual console + o On a virtual console @@ -480,7 +480,7 @@ - +o Over the serial line + o Over the serial line In the boot output, find a line that looks like: @@ -503,7 +503,7 @@ - +o Over the net + o Over the net If the network is running, then you can telnet to the virtual @@ -514,13 +514,13 @@ down and the process will exit. - 33..33.. EExxaammpplleess + 3.3. Examples Here are some examples of UML in action: - +o A login session <http://user-mode-linux.sourceforge.net/login.html> + o A login session <http://user-mode-linux.sourceforge.net/login.html> - +o A virtual network <http://user-mode-linux.sourceforge.net/net.html> + o A virtual network <http://user-mode-linux.sourceforge.net/net.html> @@ -528,12 +528,12 @@ - 44.. UUMMLL oonn 22GG//22GG hhoossttss + 4. UML on 2G/2G hosts - 44..11.. IInnttrroodduuccttiioonn + 4.1. Introduction Most Linux machines are configured so that the kernel occupies the @@ -546,7 +546,7 @@ - 44..22.. TThhee pprroobblleemm + 4.2. The problem The prebuilt UML binaries on this site will not run on 2G/2G hosts @@ -558,7 +558,7 @@ - 44..33.. TThhee ssoolluuttiioonn + 4.3. The solution The fix for this is to rebuild UML from source after enabling @@ -576,7 +576,7 @@ - 55.. SSeettttiinngg uupp sseerriiaall lliinneess aanndd ccoonnssoolleess + 5. Setting up serial lines and consoles It is possible to attach UML serial lines and consoles to many types @@ -586,12 +586,12 @@ You can attach them to host ptys, ttys, file descriptors, and ports. This allows you to do things like - +o have a UML console appear on an unused host console, + o have a UML console appear on an unused host console, - +o hook two virtual machines together by having one attach to a pty + o hook two virtual machines together by having one attach to a pty and having the other attach to the corresponding tty - +o make a virtual machine accessible from the net by attaching a + o make a virtual machine accessible from the net by attaching a console to a port on the host. @@ -599,7 +599,7 @@ - 55..11.. SSppeecciiffyyiinngg tthhee ddeevviiccee + 5.1. Specifying the device Devices are specified with "con" or "ssl" (console or serial line, respectively), optionally with a device number if you are talking @@ -626,13 +626,13 @@ - 55..22.. SSppeecciiffyyiinngg tthhee cchhaannnneell + 5.2. Specifying the channel There are a number of different types of channels to attach a UML device to, each with a different way of specifying exactly what to attach to. - +o pseudo-terminals - device=pty pts terminals - device=pts + o pseudo-terminals - device=pty pts terminals - device=pts This will cause UML to allocate a free host pseudo-terminal for the @@ -640,20 +640,20 @@ log. You access it by attaching a terminal program to the corresponding tty: - +o screen /dev/pts/n + o screen /dev/pts/n - +o screen /dev/ttyxx + o screen /dev/ttyxx - +o minicom -o -p /dev/ttyxx - minicom seems not able to handle pts + o minicom -o -p /dev/ttyxx - minicom seems not able to handle pts devices - +o kermit - start it up, 'open' the device, then 'connect' + o kermit - start it up, 'open' the device, then 'connect' - +o terminals - device=tty:tty device file + o terminals - device=tty:tty device file This will make UML attach the device to the specified tty (i.e @@ -672,7 +672,7 @@ - +o xterms - device=xterm + o xterms - device=xterm UML will run an xterm and the device will be attached to it. @@ -681,7 +681,7 @@ - +o Port - device=port:port number + o Port - device=port:port number This will attach the UML devices to the specified host port. @@ -725,7 +725,7 @@ - +o already-existing file descriptors - device=file descriptor + o already-existing file descriptors - device=file descriptor If you set up a file descriptor on the UML command line, you can @@ -743,7 +743,7 @@ - +o Nothing - device=null + o Nothing - device=null This allows the device to be opened, in contrast to 'none', but @@ -754,7 +754,7 @@ - +o None - device=none + o None - device=none This causes the device to disappear. @@ -770,7 +770,7 @@ - will cause serial line 3 to accept input on the host's /dev/tty3 and + will cause serial line 3 to accept input on the host's /dev/tty2 and display output on an xterm. That's a silly example - the most common use of this syntax is to reattach the main console to stdin and stdout as shown above. @@ -785,7 +785,7 @@ - 55..33.. EExxaammpplleess + 5.3. Examples There are a number of interesting things you can do with this capability. @@ -838,7 +838,7 @@ prompt of the other virtual machine. - 66.. SSeettttiinngg uupp tthhee nneettwwoorrkk + 6. Setting up the network @@ -858,19 +858,19 @@ There are currently five transport types available for a UML virtual machine to exchange packets with other hosts: - +o ethertap + o ethertap - +o TUN/TAP + o TUN/TAP - +o Multicast + o Multicast - +o a switch daemon + o a switch daemon - +o slip + o slip - +o slirp + o slirp - +o pcap + o pcap The TUN/TAP, ethertap, slip, and slirp transports allow a UML instance to exchange packets with the host. They may be directed @@ -893,28 +893,28 @@ With so many host transports, which one should you use? Here's when you should use each one: - +o ethertap - if you want access to the host networking and it is + o ethertap - if you want access to the host networking and it is running 2.2 - +o TUN/TAP - if you want access to the host networking and it is + o TUN/TAP - if you want access to the host networking and it is running 2.4. Also, the TUN/TAP transport is able to use a preconfigured device, allowing it to avoid using the setuid uml_net helper, which is a security advantage. - +o Multicast - if you want a purely virtual network and you don't want + o Multicast - if you want a purely virtual network and you don't want to set up anything but the UML - +o a switch daemon - if you want a purely virtual network and you + o a switch daemon - if you want a purely virtual network and you don't mind running the daemon in order to get somewhat better performance - +o slip - there is no particular reason to run the slip backend unless + o slip - there is no particular reason to run the slip backend unless ethertap and TUN/TAP are just not available for some reason - +o slirp - if you don't have root access on the host to setup + o slirp - if you don't have root access on the host to setup networking, or if you don't want to allocate an IP to your UML - +o pcap - not much use for actual network connectivity, but great for + o pcap - not much use for actual network connectivity, but great for monitoring traffic on the host Ethertap is available on 2.4 and works fine. TUN/TAP is preferred @@ -926,7 +926,7 @@ exploit the helper's root privileges. - 66..11.. GGeenneerraall sseettuupp + 6.1. General setup First, you must have the virtual network enabled in your UML. If are running a prebuilt kernel from this site, everything is already @@ -995,7 +995,7 @@ - 66..22.. UUsseerrssppaaccee ddaaeemmoonnss + 6.2. Userspace daemons You will likely need the setuid helper, or the switch daemon, or both. They are both installed with the RPM and deb, so if you've installed @@ -1011,7 +1011,7 @@ - 66..33.. SSppeecciiffyyiinngg eetthheerrnneett aaddddrreesssseess + 6.3. Specifying ethernet addresses Below, you will see that the TUN/TAP, ethertap, and daemon interfaces allow you to specify hardware addresses for the virtual ethernet @@ -1023,11 +1023,11 @@ sufficient to guarantee a unique hardware address for the device. A couple of exceptions are: - +o Another set of virtual ethernet devices are on the same network and + o Another set of virtual ethernet devices are on the same network and they are assigned hardware addresses using a different scheme which may conflict with the UML IP address-based scheme - +o You aren't going to use the device for IP networking, so you don't + o You aren't going to use the device for IP networking, so you don't assign the device an IP address If you let the driver provide the hardware address, you should make @@ -1049,7 +1049,7 @@ - 66..44.. UUMMLL iinntteerrffaaccee sseettuupp + 6.4. UML interface setup Once the network devices have been described on the command line, you should boot UML and log in. @@ -1131,7 +1131,7 @@ - 66..55.. MMuullttiiccaasstt + 6.5. Multicast The simplest way to set up a virtual network between multiple UMLs is to use the mcast transport. This was written by Harald Welte and is @@ -1194,7 +1194,7 @@ - 66..66.. TTUUNN//TTAAPP wwiitthh tthhee uummll__nneett hheellppeerr + 6.6. TUN/TAP with the uml_net helper TUN/TAP is the preferred mechanism on 2.4 to exchange packets with the host. The TUN/TAP backend has been in UML since 2.4.9-3um. @@ -1247,10 +1247,10 @@ There are a couple potential problems with running the TUN/TAP transport on a 2.4 host kernel - +o TUN/TAP seems not to work on 2.4.3 and earlier. Upgrade the host + o TUN/TAP seems not to work on 2.4.3 and earlier. Upgrade the host kernel or use the ethertap transport. - +o With an upgraded kernel, TUN/TAP may fail with + o With an upgraded kernel, TUN/TAP may fail with File descriptor in bad state @@ -1269,7 +1269,7 @@ - 66..77.. TTUUNN//TTAAPP wwiitthh aa pprreeccoonnffiigguurreedd ttaapp ddeevviiccee + 6.7. TUN/TAP with a preconfigured tap device If you prefer not to have UML use uml_net (which is somewhat insecure), with UML 2.4.17-11, you can set up a TUN/TAP device @@ -1277,7 +1277,7 @@ there is no need for root assistance. Setting up the device is done as follows: - +o Create the device with tunctl (available from the UML utilities + o Create the device with tunctl (available from the UML utilities tarball) @@ -1291,7 +1291,7 @@ where uid is the user id or username that UML will be run as. This will tell you what device was created. - +o Configure the device IP (change IP addresses and device name to + o Configure the device IP (change IP addresses and device name to suit) @@ -1303,7 +1303,7 @@ - +o Set up routing and arping if desired - this is my recipe, there are + o Set up routing and arping if desired - this is my recipe, there are other ways of doing the same thing @@ -1338,7 +1338,7 @@ utility which reads the information from a config file and sets up devices at boot time. - +o Rather than using up two IPs and ARPing for one of them, you can + o Rather than using up two IPs and ARPing for one of them, you can also provide direct access to your LAN by the UML by using a bridge. @@ -1417,7 +1417,7 @@ Note that 'br0' should be setup using ifconfig with the existing IP address of eth0, as eth0 no longer has its own IP. - +o + o Also, the /dev/net/tun device must be writable by the user running @@ -1438,11 +1438,11 @@ devices and chgrp /dev/net/tun to that group with mode 664 or 660. - +o Once the device is set up, run UML with 'eth0=tuntap,device name' + o Once the device is set up, run UML with 'eth0=tuntap,device name' (i.e. 'eth0=tuntap,tap0') on the command line (or do it with the mconsole config command). - +o Bring the eth device up in UML and you're in business. + o Bring the eth device up in UML and you're in business. If you don't want that tap device any more, you can make it non- persistent with @@ -1465,7 +1465,7 @@ - 66..88.. EEtthheerrttaapp + 6.8. Ethertap Ethertap is the general mechanism on 2.2 for userspace processes to exchange packets with the kernel. @@ -1561,9 +1561,9 @@ - 66..99.. TThhee sswwiittcchh ddaaeemmoonn + 6.9. The switch daemon - NNoottee: This is the daemon formerly known as uml_router, but which was + Note: This is the daemon formerly known as uml_router, but which was renamed so the network weenies of the world would stop growling at me. @@ -1649,7 +1649,7 @@ - 66..1100.. SSlliipp + 6.10. Slip Slip is another, less general, mechanism for a process to communicate with the host networking. In contrast to the ethertap interface, @@ -1681,7 +1681,7 @@ - 66..1111.. SSlliirrpp + 6.11. Slirp slirp uses an external program, usually /usr/bin/slirp, to provide IP only networking connectivity through the host. This is similar to IP @@ -1737,7 +1737,7 @@ - 66..1122.. ppccaapp + 6.12. pcap The pcap transport is attached to a UML ethernet device on the command line or with uml_mconsole with the following syntax: @@ -1777,7 +1777,7 @@ - 66..1133.. SSeettttiinngg uupp tthhee hhoosstt yyoouurrsseellff + 6.13. Setting up the host yourself If you don't specify an address for the host side of the ethertap or slip device, UML won't do any setup on the host. So this is what is @@ -1785,7 +1785,7 @@ 192.168.0.251 and a UML-side IP of 192.168.0.250 - adjust to suit your own network): - +o The device needs to be configured with its IP address. Tap devices + o The device needs to be configured with its IP address. Tap devices are also configured with an mtu of 1484. Slip devices are configured with a point-to-point address pointing at the UML ip address. @@ -1805,7 +1805,7 @@ - +o If a tap device is being set up, a route is set to the UML IP. + o If a tap device is being set up, a route is set to the UML IP. UML# route add -host 192.168.0.250 gw 192.168.0.251 @@ -1814,7 +1814,7 @@ - +o To allow other hosts on your network to see the virtual machine, + o To allow other hosts on your network to see the virtual machine, proxy arp is set up for it. @@ -1824,7 +1824,7 @@ - +o Finally, the host is set up to route packets. + o Finally, the host is set up to route packets. host# echo 1 > /proc/sys/net/ipv4/ip_forward @@ -1838,12 +1838,12 @@ - 77.. SShhaarriinngg FFiilleessyysstteemmss bbeettwweeeenn VViirrttuuaall MMaacchhiinneess + 7. Sharing Filesystems between Virtual Machines - 77..11.. AA wwaarrnniinngg + 7.1. A warning Don't attempt to share filesystems simply by booting two UMLs from the same file. That's the same thing as booting two physical machines @@ -1851,7 +1851,7 @@ - 77..22.. UUssiinngg llaayyeerreedd bblloocckk ddeevviicceess + 7.2. Using layered block devices The way to share a filesystem between two virtual machines is to use the copy-on-write (COW) layering capability of the ubd block driver. @@ -1896,7 +1896,7 @@ - 77..33.. NNoottee!! + 7.3. Note! When checking the size of the COW file in order to see the gobs of space that you're saving, make sure you use 'ls -ls' to see the actual @@ -1926,7 +1926,7 @@ - 77..44.. AAnnootthheerr wwaarrnniinngg + 7.4. Another warning Once a filesystem is being used as a readonly backing file for a COW file, do not boot directly from it or modify it in any way. Doing so @@ -1952,7 +1952,7 @@ - 77..55.. uummll__mmoooo :: MMeerrggiinngg aa CCOOWW ffiillee wwiitthh iittss bbaacckkiinngg ffiillee + 7.5. uml_moo : Merging a COW file with its backing file Depending on how you use UML and COW devices, it may be advisable to merge the changes in the COW file into the backing file every once in @@ -2001,7 +2001,7 @@ - 88.. CCrreeaattiinngg ffiilleessyysstteemmss + 8. Creating filesystems You may want to create and mount new UML filesystems, either because @@ -2015,7 +2015,7 @@ should be easy to translate to the filesystem of your choice. - 88..11.. CCrreeaattee tthhee ffiilleessyysstteemm ffiillee + 8.1. Create the filesystem file dd is your friend. All you need to do is tell dd to create an empty file of the appropriate size. I usually make it sparse to save time @@ -2032,7 +2032,7 @@ - 88..22.. AAssssiiggnn tthhee ffiillee ttoo aa UUMMLL ddeevviiccee + 8.2. Assign the file to a UML device Add an argument like the following to the UML command line: @@ -2045,7 +2045,7 @@ - 88..33.. CCrreeaattiinngg aanndd mmoouunnttiinngg tthhee ffiilleessyysstteemm + 8.3. Creating and mounting the filesystem Make sure that the filesystem is available, either by being built into the kernel, or available as a module, then boot up UML and log in. If @@ -2096,7 +2096,7 @@ - 99.. HHoosstt ffiillee aacccceessss + 9. Host file access If you want to access files on the host machine from inside UML, you @@ -2112,7 +2112,7 @@ files contained in it just as you would on the host. - 99..11.. UUssiinngg hhoossttffss + 9.1. Using hostfs To begin with, make sure that hostfs is available inside the virtual machine with @@ -2151,7 +2151,7 @@ - 99..22.. hhoossttffss aass tthhee rroooott ffiilleessyysstteemm + 9.2. hostfs as the root filesystem It's possible to boot from a directory hierarchy on the host using hostfs rather than using the standard filesystem in a file. @@ -2194,20 +2194,20 @@ UML should then boot as it does normally. - 99..33.. BBuuiillddiinngg hhoossttffss + 9.3. Building hostfs If you need to build hostfs because it's not in your kernel, you have two choices: - +o Compiling hostfs into the kernel: + o Compiling hostfs into the kernel: Reconfigure the kernel and set the 'Host filesystem' option under - +o Compiling hostfs as a module: + o Compiling hostfs as a module: Reconfigure the kernel and set the 'Host filesystem' option under @@ -2228,7 +2228,7 @@ - 1100.. TThhee MMaannaaggeemmeenntt CCoonnssoollee + 10. The Management Console @@ -2240,15 +2240,15 @@ There are a number of things you can do with the mconsole interface: - +o get the kernel version + o get the kernel version - +o add and remove devices + o add and remove devices - +o halt or reboot the machine + o halt or reboot the machine - +o Send SysRq commands + o Send SysRq commands - +o Pause and resume the UML + o Pause and resume the UML You need the mconsole client (uml_mconsole) which is present in CVS @@ -2300,28 +2300,28 @@ You'll get a prompt, at which you can run one of these commands: - +o version + o version - +o halt + o halt - +o reboot + o reboot - +o config + o config - +o remove + o remove - +o sysrq + o sysrq - +o help + o help - +o cad + o cad - +o stop + o stop - +o go + o go - 1100..11.. vveerrssiioonn + 10.1. version This takes no arguments. It prints the UML version. @@ -2342,7 +2342,7 @@ - 1100..22.. hhaalltt aanndd rreebboooott + 10.2. halt and reboot These take no arguments. They shut the machine down immediately, with no syncing of disks and no clean shutdown of userspace. So, they are @@ -2357,7 +2357,7 @@ - 1100..33.. ccoonnffiigg + 10.3. config "config" adds a new device to the virtual machine. Currently the ubd and network drivers support this. It takes one argument, which is the @@ -2378,7 +2378,7 @@ - 1100..44.. rreemmoovvee + 10.4. remove "remove" deletes a device from the system. Its argument is just the name of the device to be removed. The device must be idle in whatever @@ -2397,7 +2397,7 @@ - 1100..55.. ssyyssrrqq + 10.5. sysrq This takes one argument, which is a single letter. It calls the generic kernel's SysRq driver, which does whatever is called for by @@ -2407,14 +2407,14 @@ - 1100..66.. hheellpp + 10.6. help "help" returns a string listing the valid commands and what each one does. - 1100..77.. ccaadd + 10.7. cad This invokes the Ctl-Alt-Del action on init. What exactly this ends up doing is up to /etc/inittab. Normally, it reboots the machine. @@ -2432,7 +2432,7 @@ - 1100..88.. ssttoopp + 10.8. stop This puts the UML in a loop reading mconsole requests until a 'go' mconsole command is received. This is very useful for making backups @@ -2448,7 +2448,7 @@ - 1100..99.. ggoo + 10.9. go This resumes a UML after being paused by a 'stop' command. Note that when the UML has resumed, TCP connections may have timed out and if @@ -2462,10 +2462,10 @@ - 1111.. KKeerrnneell ddeebbuuggggiinngg + 11. Kernel debugging - NNoottee:: The interface that makes debugging, as described here, possible + Note: The interface that makes debugging, as described here, possible is present in 2.4.0-test6 kernels and later. @@ -2485,7 +2485,7 @@ - 1111..11.. SSttaarrttiinngg tthhee kkeerrnneell uunnddeerr ggddbb + 11.1. Starting the kernel under gdb You can have the kernel running under the control of gdb from the beginning by putting 'debug' on the command line. You will get an @@ -2498,7 +2498,7 @@ There is a transcript of a debugging session here <debug- session.html> , with breakpoints being set in the scheduler and in an interrupt handler. - 1111..22.. EExxaammiinniinngg sslleeeeppiinngg pprroocceesssseess + 11.2. Examining sleeping processes Not every bug is evident in the currently running process. Sometimes, processes hang in the kernel when they shouldn't because they've @@ -2516,7 +2516,7 @@ Now what you do is this: - +o detach from the current thread + o detach from the current thread (UML gdb) det @@ -2525,7 +2525,7 @@ - +o attach to the thread you are interested in + o attach to the thread you are interested in (UML gdb) att <host pid> @@ -2534,7 +2534,7 @@ - +o look at its stack and anything else of interest + o look at its stack and anything else of interest (UML gdb) bt @@ -2545,7 +2545,7 @@ Note that you can't do anything at this point that requires that a process execute, e.g. calling a function - +o when you're done looking at that process, reattach to the current + o when you're done looking at that process, reattach to the current thread and continue it @@ -2569,12 +2569,12 @@ - 1111..33.. RRuunnnniinngg dddddd oonn UUMMLL + 11.3. Running ddd on UML ddd works on UML, but requires a special kludge. The process goes like this: - +o Start ddd + o Start ddd host% ddd linux @@ -2583,14 +2583,14 @@ - +o With ps, get the pid of the gdb that ddd started. You can ask the + o With ps, get the pid of the gdb that ddd started. You can ask the gdb to tell you, but for some reason that confuses things and causes a hang. - +o run UML with 'debug=parent gdb-pid=<pid>' added to the command line + o run UML with 'debug=parent gdb-pid=<pid>' added to the command line - it will just sit there after you hit return - +o type 'att 1' to the ddd gdb and you will see something like + o type 'att 1' to the ddd gdb and you will see something like 0xa013dc51 in __kill () @@ -2602,12 +2602,12 @@ - +o At this point, type 'c', UML will boot up, and you can use ddd just + o At this point, type 'c', UML will boot up, and you can use ddd just as you do on any other process. - 1111..44.. DDeebbuuggggiinngg mmoodduulleess + 11.4. Debugging modules gdb has support for debugging code which is dynamically loaded into the process. This support is what is needed to debug kernel modules @@ -2823,7 +2823,7 @@ - 1111..55.. AAttttaacchhiinngg ggddbb ttoo tthhee kkeerrnneell + 11.5. Attaching gdb to the kernel If you don't have the kernel running under gdb, you can attach gdb to it later by sending the tracing thread a SIGUSR1. The first line of @@ -2857,7 +2857,7 @@ - 1111..66.. UUssiinngg aalltteerrnnaattee ddeebbuuggggeerrss + 11.6. Using alternate debuggers UML has support for attaching to an already running debugger rather than starting gdb itself. This is present in CVS as of 17 Apr 2001. @@ -2886,7 +2886,7 @@ An example of an alternate debugger is strace. You can strace the actual kernel as follows: - +o Run the following in a shell + o Run the following in a shell host% @@ -2894,10 +2894,10 @@ - +o Run UML with 'debug' and 'gdb-pid=<pid>' with the pid printed out + o Run UML with 'debug' and 'gdb-pid=<pid>' with the pid printed out by the previous command - +o Hit return in the shell, and UML will start running, and strace + o Hit return in the shell, and UML will start running, and strace output will start accumulating in the output file. Note that this is different from running @@ -2917,9 +2917,9 @@ - 1122.. KKeerrnneell ddeebbuuggggiinngg eexxaammpplleess + 12. Kernel debugging examples - 1122..11.. TThhee ccaassee ooff tthhee hhuunngg ffsscckk + 12.1. The case of the hung fsck When booting up the kernel, fsck failed, and dropped me into a shell to fix things up. I ran fsck -y, which hung: @@ -3154,9 +3154,9 @@ The interesting things here are : - +o There are two segfaults on this stack (frames 9 and 14) + o There are two segfaults on this stack (frames 9 and 14) - +o The first faulting address (frame 11) is 0x50000800 + o The first faulting address (frame 11) is 0x50000800 (gdb) p (void *)1342179328 $16 = (void *) 0x50000800 @@ -3399,7 +3399,7 @@ on will be somewhat clearer. - 1122..22.. EEppiissooddee 22:: TThhee ccaassee ooff tthhee hhuunngg ffsscckk + 12.2. Episode 2: The case of the hung fsck After setting a trap in the SEGV handler for accesses to the signal thread's stack, I reran the kernel. @@ -3788,12 +3788,12 @@ - 1133.. WWhhaatt ttoo ddoo wwhheenn UUMMLL ddooeessnn''tt wwoorrkk + 13. What to do when UML doesn't work - 1133..11.. SSttrraannggee ccoommppiillaattiioonn eerrrroorrss wwhheenn yyoouu bbuuiilldd ffrroomm ssoouurrccee + 13.1. Strange compilation errors when you build from source As of test11, it is necessary to have "ARCH=um" in the environment or on the make command line for all steps in building UML, including @@ -3824,8 +3824,8 @@ - 1133..33.. AA vvaarriieettyy ooff ppaanniiccss aanndd hhaannggss wwiitthh //ttmmpp oonn aa rreeiisseerrffss ffiilleessyyss-- - tteemm + 13.3. A variety of panics and hangs with /tmp on a reiserfs filesys- + tem I saw this on reiserfs 3.5.21 and it seems to be fixed in 3.5.27. Panics preceded by @@ -3842,8 +3842,8 @@ - 1133..44.. TThhee ccoommppiillee ffaaiillss wwiitthh eerrrroorrss aabboouutt ccoonnfflliiccttiinngg ttyyppeess ffoorr - ''ooppeenn'',, ''dduupp'',, aanndd ''wwaaiittppiidd'' + 13.4. The compile fails with errors about conflicting types for + 'open', 'dup', and 'waitpid' This happens when you build in /usr/src/linux. The UML build makes the include/asm link point to include/asm-um. /usr/include/asm points @@ -3854,14 +3854,14 @@ - 1133..55.. UUMMLL ddooeessnn''tt wwoorrkk wwhheenn //ttmmpp iiss aann NNFFSS ffiilleessyysstteemm + 13.5. UML doesn't work when /tmp is an NFS filesystem This seems to be a similar situation with the ReiserFS problem above. Some versions of NFS seems not to handle mmap correctly, which UML depends on. The workaround is have /tmp be a non-NFS directory. - 1133..66.. UUMMLL hhaannggss oonn bboooott wwhheenn ccoommppiilleedd wwiitthh ggpprrooff ssuuppppoorrtt + 13.6. UML hangs on boot when compiled with gprof support If you build UML with gprof support and, early in the boot, it does this @@ -3878,7 +3878,7 @@ - 1133..77.. ssyyssllooggdd ddiieess wwiitthh aa SSIIGGTTEERRMM oonn ssttaarrttuupp + 13.7. syslogd dies with a SIGTERM on startup The exact boot error depends on the distribution that you're booting, but Debian produces this: @@ -3897,17 +3897,17 @@ - 1133..88.. TTUUNN//TTAAPP nneettwwoorrkkiinngg ddooeessnn''tt wwoorrkk oonn aa 22..44 hhoosstt + 13.8. TUN/TAP networking doesn't work on a 2.4 host There are a couple of problems which were <http://www.geocrawler.com/lists/3/SourceForge/597/0/> name="pointed out"> by Tim Robinson <timro at trkr dot net> - +o It doesn't work on hosts running 2.4.7 (or thereabouts) or earlier. + o It doesn't work on hosts running 2.4.7 (or thereabouts) or earlier. The fix is to upgrade to something more recent and then read the next item. - +o If you see + o If you see File descriptor in bad state @@ -3921,8 +3921,8 @@ - 1133..99.. YYoouu ccaann nneettwwoorrkk ttoo tthhee hhoosstt bbuutt nnoott ttoo ootthheerr mmaacchhiinneess oonn tthhee - nneett + 13.9. You can network to the host but not to other machines on the + net If you can connect to the host, and the host can connect to UML, but you cannot connect to any other machines, then you may need to enable @@ -3972,7 +3972,7 @@ - 1133..1100.. II hhaavvee nnoo rroooott aanndd II wwaanntt ttoo ssccrreeaamm + 13.10. I have no root and I want to scream Thanks to Birgit Wahlich for telling me about this strange one. It turns out that there's a limit of six environment variables on the @@ -3987,7 +3987,7 @@ - 1133..1111.. UUMMLL bbuuiilldd ccoonnfflliicctt bbeettwweeeenn ppttrraaccee..hh aanndd uuccoonntteexxtt..hh + 13.11. UML build conflict between ptrace.h and ucontext.h On some older systems, /usr/include/asm/ptrace.h and /usr/include/sys/ucontext.h define the same names. So, when they're @@ -4007,7 +4007,7 @@ - 1133..1122.. TThhee UUMMLL BBooggooMMiippss iiss eexxaaccttllyy hhaallff tthhee hhoosstt''ss BBooggooMMiippss + 13.12. The UML BogoMips is exactly half the host's BogoMips On i386 kernels, there are two ways of running the loop that is used to calculate the BogoMips rating, using the TSC if it's there or using @@ -4019,7 +4019,7 @@ - 1133..1133.. WWhheenn yyoouu rruunn UUMMLL,, iitt iimmmmeeddiiaatteellyy sseeggffaauullttss + 13.13. When you run UML, it immediately segfaults If the host is configured with the 2G/2G address space split, that's why. See ``UML on 2G/2G hosts'' for the details on getting UML to @@ -4027,7 +4027,7 @@ - 1133..1144.. xxtteerrmmss aappppeeaarr,, tthheenn iimmmmeeddiiaatteellyy ddiissaappppeeaarr + 13.14. xterms appear, then immediately disappear If you're running an up to date kernel with an old release of uml_utilities, the port-helper program will not work properly, so @@ -4039,7 +4039,7 @@ - 1133..1155.. AAnnyy ootthheerr ppaanniicc,, hhaanngg,, oorr ssttrraannggee bbeehhaavviioorr + 13.15. Any other panic, hang, or strange behavior If you're seeing truly strange behavior, such as hangs or panics that happen in random places, or you try running the debugger to see what's @@ -4059,7 +4059,7 @@ If you want to be super-helpful, read ``Diagnosing Problems'' and follow the instructions contained therein. - 1144.. DDiiaaggnnoossiinngg PPrroobblleemmss + 14. Diagnosing Problems If you get UML to crash, hang, or otherwise misbehave, you should @@ -4078,7 +4078,7 @@ ``Kernel debugging'' UML first. - 1144..11.. CCaassee 11 :: NNoorrmmaall kkeerrnneell ppaanniiccss + 14.1. Case 1 : Normal kernel panics The most common case is for a normal thread to panic. To debug this, you will need to run it under the debugger (add 'debug' to the command @@ -4128,7 +4128,7 @@ to get that information from the faulting ip. - 1144..22.. CCaassee 22 :: TTrraacciinngg tthhrreeaadd ppaanniiccss + 14.2. Case 2 : Tracing thread panics The less common and more painful case is when the tracing thread panics. In this case, the kernel debugger will be useless because it @@ -4161,7 +4161,7 @@ backtrace in and wait for our crack debugging team to fix the problem. - 1144..33.. CCaassee 33 :: TTrraacciinngg tthhrreeaadd ppaanniiccss ccaauusseedd bbyy ootthheerr tthhrreeaaddss + 14.3. Case 3 : Tracing thread panics caused by other threads However, there are cases where the misbehavior of another thread caused the problem. The most common panic of this type is: @@ -4227,7 +4227,7 @@ - 1144..44.. CCaassee 44 :: HHaannggss + 14.4. Case 4 : Hangs Hangs seem to be fairly rare, but they sometimes happen. When a hang happens, we need a backtrace from the offending process. Run the @@ -4257,7 +4257,7 @@ - 1155.. TThhaannkkss + 15. Thanks A number of people have helped this project in various ways, and this @@ -4274,20 +4274,20 @@ bookkeeping lapses and I forget about contributions. - 1155..11.. CCooddee aanndd DDooccuummeennttaattiioonn + 15.1. Code and Documentation Rusty Russell <rusty at linuxcare.com.au> - - +o wrote the HOWTO <http://user-mode- + o wrote the HOWTO <http://user-mode- linux.sourceforge.net/UserModeLinux-HOWTO.html> - +o prodded me into making this project official and putting it on + o prodded me into making this project official and putting it on SourceForge - +o came up with the way cool UML logo <http://user-mode- + o came up with the way cool UML logo <http://user-mode- linux.sourceforge.net/uml-small.png> - +o redid the config process + o redid the config process Peter Moulder <reiter at netspace.net.au> - Fixed my config and build @@ -4296,18 +4296,18 @@ Bill Stearns <wstearns at pobox.com> - - +o HOWTO updates + o HOWTO updates - +o lots of bug reports + o lots of bug reports - +o lots of testing + o lots of testing - +o dedicated a box (uml.ists.dartmouth.edu) to support UML development + o dedicated a box (uml.ists.dartmouth.edu) to support UML development - +o wrote the mkrootfs script, which allows bootable filesystems of + o wrote the mkrootfs script, which allows bootable filesystems of RPM-based distributions to be cranked out - +o cranked out a large number of filesystems with said script + o cranked out a large number of filesystems with said script Jim Leu <jleu at mindspring.com> - Wrote the virtual ethernet driver @@ -4375,176 +4375,176 @@ David Coulson <http://davidcoulson.net> - - +o Set up the usermodelinux.org <http://usermodelinux.org> site, + o Set up the usermodelinux.org <http://usermodelinux.org> site, which is a great way of keeping the UML user community on top of UML goings-on. - +o Site documentation and updates + o Site documentation and updates - +o Nifty little UML management daemon UMLd + o Nifty little UML management daemon UMLd <http://uml.openconsultancy.com/umld/> - +o Lots of testing and bug reports + o Lots of testing and bug reports - 1155..22.. FFlluusshhiinngg oouutt bbuuggss + 15.2. Flushing out bugs - +o Yuri Pudgorodsky + o Yuri Pudgorodsky - +o Gerald Britton + o Gerald Britton - +o Ian Wehrman + o Ian Wehrman - +o Gord Lamb + o Gord Lamb - +o Eugene Koontz + o Eugene Koontz - +o John H. Hartman + o John H. Hartman - +o Anders Karlsson + o Anders Karlsson - +o Daniel Phillips + o Daniel Phillips - +o John Fremlin + o John Fremlin - +o Rainer Burgstaller + o Rainer Burgstaller - +o James Stevenson + o James Stevenson - +o Matt Clay + o Matt Clay - +o Cliff Jefferies + o Cliff Jefferies - +o Geoff Hoff + o Geoff Hoff - +o Lennert Buytenhek + o Lennert Buytenhek - +o Al Viro + o Al Viro - +o Frank Klingenhoefer + o Frank Klingenhoefer - +o Livio Baldini Soares + o Livio Baldini Soares - +o Jon Burgess + o Jon Burgess - +o Petru Paler + o Petru Paler - +o Paul + o Paul - +o Chris Reahard + o Chris Reahard - +o Sverker Nilsson + o Sverker Nilsson - +o Gong Su + o Gong Su - +o johan verrept + o johan verrept - +o Bjorn Eriksson + o Bjorn Eriksson - +o Lorenzo Allegrucci + o Lorenzo Allegrucci - +o Muli Ben-Yehuda + o Muli Ben-Yehuda - +o David Mansfield + o David Mansfield - +o Howard Goff + o Howard Goff - +o Mike Anderson + o Mike Anderson - +o John Byrne + o John Byrne - +o Sapan J. Batia + o Sapan J. Batia - +o Iris Huang + o Iris Huang - +o Jan Hudec + o Jan Hudec - +o Voluspa + o Voluspa - 1155..33.. BBuugglleettss aanndd cclleeaann--uuppss + 15.3. Buglets and clean-ups - +o Dave Zarzycki + o Dave Zarzycki - +o Adam Lazur + o Adam Lazur - +o Boria Feigin + o Boria Feigin - +o Brian J. Murrell + o Brian J. Murrell - +o JS + o JS - +o Roman Zippel + o Roman Zippel - +o Wil Cooley + o Wil Cooley - +o Ayelet Shemesh + o Ayelet Shemesh - +o Will Dyson + o Will Dyson - +o Sverker Nilsson + o Sverker Nilsson - +o dvorak + o dvorak - +o v.naga srinivas + o v.naga srinivas - +o Shlomi Fish + o Shlomi Fish - +o Roger Binns + o Roger Binns - +o johan verrept + o johan verrept - +o MrChuoi + o MrChuoi - +o Peter Cleve + o Peter Cleve - +o Vincent Guffens + o Vincent Guffens - +o Nathan Scott + o Nathan Scott - +o Patrick Caulfield + o Patrick Caulfield - +o jbearce + o jbearce - +o Catalin Marinas + o Catalin Marinas - +o Shane Spencer + o Shane Spencer - +o Zou Min + o Zou Min - +o Ryan Boder + o Ryan Boder - +o Lorenzo Colitti + o Lorenzo Colitti - +o Gwendal Grignou + o Gwendal Grignou - +o Andre' Breiler + o Andre' Breiler - +o Tsutomu Yasuda + o Tsutomu Yasuda - 1155..44.. CCaassee SSttuuddiieess + 15.4. Case Studies - +o Jon Wright + o Jon Wright - +o William McEwan + o William McEwan - +o Michael Richardson + o Michael Richardson - 1155..55.. OOtthheerr ccoonnttrriibbuuttiioonnss + 15.5. Other contributions Bill Carr <Bill.Carr at compaq.com> made the Red Hat mkrootfs script diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char index 70dabd1..b9d7c42 100644 --- a/arch/um/Kconfig.char +++ b/arch/um/Kconfig.char @@ -1,5 +1,4 @@ - -menu "Character Devices" +menu "UML Character Devices" config STDERR_CONSOLE bool "stderr console" @@ -105,92 +104,6 @@ config SSL_CHAN this if you expect the UML that you build to be run in environments which don't have a set of /dev/pty* devices. -config UNIX98_PTYS - bool "Unix98 PTY support" - help - A pseudo terminal (PTY) is a software device consisting of two - halves: a master and a slave. The slave device behaves identical to - a physical terminal; the master device is used by a process to - read data from and write data to the slave, thereby emulating a - terminal. Typical programs for the master side are telnet servers - and xterms. - - Linux has traditionally used the BSD-like names /dev/ptyxx for - masters and /dev/ttyxx for slaves of pseudo terminals. This scheme - has a number of problems. The GNU C library glibc 2.1 and later, - however, supports the Unix98 naming standard: in order to acquire a - pseudo terminal, a process opens /dev/ptmx; the number of the pseudo - terminal is then made available to the process and the pseudo - terminal slave can be accessed as /dev/pts/<number>. What was - traditionally /dev/ttyp2 will then be /dev/pts/2, for example. - - All modern Linux systems use the Unix98 ptys. Say Y unless - you're on an embedded system and want to conserve memory. - -config LEGACY_PTYS - bool "Legacy (BSD) PTY support" - default y - help - A pseudo terminal (PTY) is a software device consisting of two - halves: a master and a slave. The slave device behaves identical to - a physical terminal; the master device is used by a process to - read data from and write data to the slave, thereby emulating a - terminal. Typical programs for the master side are telnet servers - and xterms. - - Linux has traditionally used the BSD-like names /dev/ptyxx - for masters and /dev/ttyxx for slaves of pseudo - terminals. This scheme has a number of problems, including - security. This option enables these legacy devices; on most - systems, it is safe to say N. - -config RAW_DRIVER - tristate "RAW driver (/dev/raw/rawN)" - depends on BLOCK - help - The raw driver permits block devices to be bound to /dev/raw/rawN. - Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. - See the raw(8) manpage for more details. - - Applications should preferably open the device (eg /dev/hda1) - with the O_DIRECT flag. - -config MAX_RAW_DEVS - int "Maximum number of RAW devices to support (1-8192)" - depends on RAW_DRIVER - default "256" - help - The maximum number of RAW devices that are supported. - Default is 256. Increase this number in case you need lots of - raw devices. - -config LEGACY_PTY_COUNT - int "Maximum number of legacy PTY in use" - depends on LEGACY_PTYS - default "256" - help - The maximum number of legacy PTYs that can be used at any one time. - The default is 256, and should be more than enough. Embedded - systems may want to reduce this to save memory. - - When not in use, each legacy PTY occupies 12 bytes on 32-bit - architectures and 24 bytes on 64-bit architectures. - -config WATCHDOG - bool "Watchdog Timer Support" - -config WATCHDOG_NOWAYOUT - bool "Disable watchdog shutdown on close" - depends on WATCHDOG - -config SOFT_WATCHDOG - tristate "Software Watchdog" - depends on WATCHDOG - -config UML_WATCHDOG - tristate "UML watchdog" - depends on WATCHDOG - config UML_SOUND tristate "Sound support" help @@ -211,29 +124,4 @@ config HOSTAUDIO tristate default UML_SOUND -#It is selected elsewhere, so kconfig would warn without this. -config HW_RANDOM - tristate - default n - -config UML_RANDOM - tristate "Hardware random number generator" - help - This option enables UML's "hardware" random number generator. It - attaches itself to the host's /dev/random, supplying as much entropy - as the host has, rather than the small amount the UML gets from its - own drivers. It registers itself as a standard hardware random number - generator, major 10, minor 183, and the canonical device name is - /dev/hwrng. - The way to make use of this is to install the rng-tools package - (check your distro, or download from - http://sourceforge.net/projects/gkernel/). rngd periodically reads - /dev/hwrng and injects the entropy into /dev/random. - -config MMAPPER - tristate "iomem emulation driver" - help - This driver allows a host file to be used as emulated IO memory inside - UML. - endmenu diff --git a/arch/um/Kconfig.rest b/arch/um/Kconfig.rest index 0ccad0f..567eb5f 100644 --- a/arch/um/Kconfig.rest +++ b/arch/um/Kconfig.rest @@ -2,20 +2,14 @@ source "init/Kconfig" source "kernel/Kconfig.freezer" -source "drivers/block/Kconfig" - source "arch/um/Kconfig.char" -source "drivers/base/Kconfig" +source "drivers/Kconfig" source "net/Kconfig" source "arch/um/Kconfig.net" -source "drivers/net/Kconfig" - -source "drivers/connector/Kconfig" - source "fs/Kconfig" source "security/Kconfig" @@ -24,19 +18,4 @@ source "crypto/Kconfig" source "lib/Kconfig" -source "drivers/scsi/Kconfig" - -source "drivers/md/Kconfig" - -if BROKEN - source "drivers/mtd/Kconfig" -endif - -source "drivers/leds/Kconfig" - -#This is just to shut up some Kconfig warnings, so no prompt. -config INPUT - tristate - default n - source "arch/um/Kconfig.debug" diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um index b5e675e..70fd690 100644 --- a/arch/um/Kconfig.um +++ b/arch/um/Kconfig.um @@ -148,5 +148,11 @@ config KERNEL_STACK_ORDER be 1 << order pages. The default is OK unless you're running Valgrind on UML, in which case, set this to 3. +config MMAPPER + tristate "iomem emulation driver" + help + This driver allows a host file to be used as emulated IO memory inside + UML. + config NO_DMA def_bool y diff --git a/arch/um/Makefile b/arch/um/Makefile index c0f712c..7730af6 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -20,15 +20,27 @@ core-y += $(ARCH_DIR)/kernel/ \ MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include/shared/skas +HEADER_ARCH := $(SUBARCH) + +# Additional ARCH settings for x86 +ifeq ($(SUBARCH),i386) + HEADER_ARCH := x86 +endif +ifeq ($(SUBARCH),x86_64) + HEADER_ARCH := x86 +endif + +HOST_DIR := arch/$(HEADER_ARCH) + include $(srctree)/$(ARCH_DIR)/Makefile-skas +include $(srctree)/$(HOST_DIR)/Makefile.um + +core-y += $(HOST_DIR)/um/ SHARED_HEADERS := $(ARCH_DIR)/include/shared ARCH_INCLUDE := -I$(srctree)/$(SHARED_HEADERS) -ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH)/shared -ifneq ($(KBUILD_SRC),) -ARCH_INCLUDE += -I$(SHARED_HEADERS) -endif -KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH) +ARCH_INCLUDE += -I$(srctree)/$(HOST_DIR)/um/shared +KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/um # -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so # named - it's a common symbol in libpcap, so we get a binary which crashes. @@ -47,14 +59,12 @@ KBUILD_AFLAGS += $(ARCH_INCLUDE) USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\ $(patsubst -I%,,$(KBUILD_CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \ - $(filter -I%,$(CFLAGS)) -D_FILE_OFFSET_BITS=64 - -include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) + $(filter -I%,$(CFLAGS)) -D_FILE_OFFSET_BITS=64 -idirafter include #This will adjust *FLAGS accordingly to the platform. include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) -KBUILD_CPPFLAGS += -I$(srctree)/arch/$(HEADER_ARCH)/include +KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/include # -Derrno=kernel_errno - This turns all kernel references to errno into # kernel_errno to separate them from the libc errno. This allows -fno-common @@ -84,10 +94,9 @@ define archhelp echo ' find in the kernel root.' endef -KBUILD_KCONFIG := arch/um/Kconfig.$(HEADER_ARCH) +KBUILD_KCONFIG := $(HOST_DIR)/um/Kconfig -archprepare: $(SHARED_HEADERS)/user_constants.h -archprepare: $(SHARED_HEADERS)/kern_constants.h +archprepare: include/generated/user_constants.h LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib @@ -118,9 +127,7 @@ endef # When cleaning we don't include .config, so we don't include # TT or skas makefiles and don't clean skas_ptregs.h. -CLEAN_FILES += linux x.i gmon.out \ - $(SHARED_HEADERS)/user_constants.h \ - $(SHARED_HEADERS)/kern_constants.h +CLEAN_FILES += linux x.i gmon.out archclean: @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ @@ -128,8 +135,8 @@ archclean: # Generated files -$(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s: FORCE - $(Q)$(MAKE) $(build)=$(ARCH_DIR)/sys-$(SUBARCH) $@ +$(HOST_DIR)/um/user-offsets.s: FORCE + $(Q)$(MAKE) $(build)=$(HOST_DIR)/um $@ define filechk_gen-asm-offsets (set -e; \ @@ -144,11 +151,7 @@ define filechk_gen-asm-offsets echo ""; ) endef -$(SHARED_HEADERS)/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s +include/generated/user_constants.h: $(HOST_DIR)/um/user-offsets.s $(call filechk,gen-asm-offsets) -$(SHARED_HEADERS)/kern_constants.h: - $(Q)mkdir -p $(dir $@) - $(Q)echo '#include "../../../../include/generated/asm-offsets.h"' >$@ - -export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH DEV_NULL_PATH +export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS DEV_NULL_PATH diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 deleted file mode 100644 index a9cd7e7..0000000 --- a/arch/um/Makefile-x86_64 +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2003 - 2004 Pathscale, Inc -# Released under the GPL - -core-y += arch/um/sys-x86_64/ arch/x86/crypto/ -START := 0x60000000 - -_extra_flags_ = -fno-builtin -m64 - -KBUILD_CFLAGS += $(_extra_flags_) - -CHECKFLAGS += -m64 -D__x86_64__ -KBUILD_AFLAGS += -m64 -LDFLAGS += -m elf_x86_64 -KBUILD_CPPFLAGS += -m64 - -ELF_ARCH := i386:x86-64 -ELF_FORMAT := elf64-x86-64 -HEADER_ARCH := x86 - -# Not on all 64-bit distros /lib is a symlink to /lib64. PLD is an example. - -LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64 -LINK-y += -m64 - -# Do unit-at-a-time unconditionally on x86_64, following the host -KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time) diff --git a/arch/um/include/shared/chan_kern.h b/arch/um/drivers/chan.h index 1e65145..8df0fd90 100644 --- a/arch/um/include/shared/chan_kern.h +++ b/arch/um/drivers/chan.h @@ -6,9 +6,9 @@ #ifndef __CHAN_KERN_H__ #define __CHAN_KERN_H__ -#include "linux/tty.h" -#include "linux/list.h" -#include "linux/console.h" +#include <linux/tty.h> +#include <linux/list.h> +#include <linux/console.h> #include "chan_user.h" #include "line.h" diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index d4191fe..420e2c8 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -6,7 +6,7 @@ #include <linux/slab.h> #include <linux/tty.h> #include <linux/tty_flip.h> -#include "chan_kern.h" +#include "chan.h" #include "os.h" #ifdef CONFIG_NOCONFIG_CHAN @@ -358,11 +358,11 @@ int chan_window_size(struct list_head *chans, unsigned short *rows_out, return 0; } -static void free_one_chan(struct chan *chan, int delay_free_irq) +static void free_one_chan(struct chan *chan) { list_del(&chan->list); - close_one_chan(chan, delay_free_irq); + close_one_chan(chan, 0); if (chan->ops->free != NULL) (*chan->ops->free)(chan->data); @@ -372,14 +372,14 @@ static void free_one_chan(struct chan *chan, int delay_free_irq) kfree(chan); } -static void free_chan(struct list_head *chans, int delay_free_irq) +static void free_chan(struct list_head *chans) { struct list_head *ele, *next; struct chan *chan; list_for_each_safe(ele, next, chans) { chan = list_entry(ele, struct chan, list); - free_one_chan(chan, delay_free_irq); + free_one_chan(chan); } } @@ -547,7 +547,7 @@ int parse_chan_pair(char *str, struct line *line, int device, char *in, *out; if (!list_empty(chans)) { - free_chan(chans, 0); + free_chan(chans); INIT_LIST_HEAD(chans); } diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index cfeb3f4..f180813 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -11,10 +11,8 @@ #include <termios.h> #include <sys/ioctl.h> #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" void generic_close(int fd, void *unused) { @@ -283,7 +281,12 @@ void register_winch(int fd, struct tty_struct *tty) return; pid = tcgetpgrp(fd); - if (!is_skas_winch(pid, fd, tty) && (pid == -1)) { + if (is_skas_winch(pid, fd, tty)) { + register_winch_irq(-1, fd, -1, tty, 0); + return; + } + + if (pid == -1) { thread = winch_tramp(fd, tty, &thread_fd, &stack); if (thread < 0) return; diff --git a/arch/um/include/shared/chan_user.h b/arch/um/drivers/chan_user.h index 9b9ced8..9b9ced8 100644 --- a/arch/um/include/shared/chan_user.h +++ b/arch/um/drivers/chan_user.h diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index f5701fd..7f2ed0b 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -3,7 +3,6 @@ #include "kern_util.h" #include "os.h" -#include "user.h" #include "um_malloc.h" static inline void *cow_malloc(int size) diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index f8e85e0..a4fd7bc 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -17,7 +17,6 @@ #include "net_user.h" #include "os.h" #include "um_malloc.h" -#include "user.h" enum request_type { REQ_NEW_CONTROL }; diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c index f5a981a..5b81d25 100644 --- a/arch/um/drivers/fd.c +++ b/arch/um/drivers/fd.c @@ -9,10 +9,8 @@ #include <errno.h> #include <termios.h> #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" struct fd_chan { int fd; diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index 84dce3f..0345d62 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c @@ -7,7 +7,6 @@ #include <unistd.h> #include <errno.h> #include "os.h" -#include "user.h" struct dog_data { int stdin; diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 364c8a1..c1cf220 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -7,7 +7,7 @@ #include "linux/kd.h" #include "linux/sched.h" #include "linux/slab.h" -#include "chan_kern.h" +#include "chan.h" #include "irq_kern.h" #include "irq_user.h" #include "kern_util.h" diff --git a/arch/um/include/shared/line.h b/arch/um/drivers/line.h index 63df3ca..63df3ca 100644 --- a/arch/um/include/shared/line.h +++ b/arch/um/drivers/line.h diff --git a/arch/um/include/shared/mconsole.h b/arch/um/drivers/mconsole.h index c139ae1..c139ae1 100644 --- a/arch/um/include/shared/mconsole.h +++ b/arch/um/drivers/mconsole.h diff --git a/arch/um/include/shared/mconsole_kern.h b/arch/um/drivers/mconsole_kern.h index d2fe07e..d2fe07e 100644 --- a/arch/um/include/shared/mconsole_kern.h +++ b/arch/um/drivers/mconsole_kern.h diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index f8cf4c8..9920982 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c @@ -10,9 +10,7 @@ #include <sys/socket.h> #include <sys/uio.h> #include <sys/un.h> -#include "kern_constants.h" #include "mconsole.h" -#include "user.h" static struct mconsole_command commands[] = { /* diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 5201188..05090c3 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -12,10 +12,8 @@ #include <sys/socket.h> #include <sys/wait.h> #include "net_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" int tap_open_common(void *dev, char *gate_addr) { diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c index 5f90358..702a75b 100644 --- a/arch/um/drivers/pcap_user.c +++ b/arch/um/drivers/pcap_user.c @@ -9,9 +9,7 @@ #include <asm/types.h> #include "net_user.h" #include "pcap_user.h" -#include "kern_constants.h" #include "um_malloc.h" -#include "user.h" #define PCAP_FD(p) (*(int *)(p)) diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c index b49bf56..7b010b7 100644 --- a/arch/um/drivers/port_user.c +++ b/arch/um/drivers/port_user.c @@ -10,11 +10,9 @@ #include <unistd.h> #include <netinet/in.h> #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "port.h" #include "um_malloc.h" -#include "user.h" struct port_chan { int raw; diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index 1113911..cff2b75 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c @@ -12,10 +12,8 @@ #include <termios.h> #include <sys/stat.h> #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" struct pty_chan { void (*announce)(char *dev_name, int dev); diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index cbacfc4..932b4d6 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -11,12 +11,10 @@ #include <string.h> #include <sys/termios.h> #include <sys/wait.h> -#include "kern_constants.h" #include "net_user.h" #include "os.h" #include "slip.h" #include "um_malloc.h" -#include "user.h" static int slip_user_init(void *data, void *dev) { diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index a0ada8f..db4adb6 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c @@ -7,11 +7,9 @@ #include <errno.h> #include <string.h> #include <sys/wait.h> -#include "kern_constants.h" #include "net_user.h" #include "os.h" #include "slirp.h" -#include "user.h" static int slirp_user_init(void *data, void *dev) { diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index f1786e6..9d8c20a 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -12,10 +12,8 @@ #include "linux/console.h" #include "asm/termbits.h" #include "asm/irq.h" -#include "line.h" #include "ssl.h" -#include "chan_kern.h" -#include "kern.h" +#include "chan.h" #include "init.h" #include "irq_user.h" #include "mconsole_kern.h" diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 49266f6..088776f 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c @@ -20,8 +20,7 @@ #include "asm/current.h" #include "asm/irq.h" #include "stdio_console.h" -#include "line.h" -#include "chan_kern.h" +#include "chan.h" #include "irq_user.h" #include "mconsole_kern.h" #include "init.h" diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c index 495858a..a97391f 100644 --- a/arch/um/drivers/tty.c +++ b/arch/um/drivers/tty.c @@ -7,10 +7,8 @@ #include <fcntl.h> #include <termios.h> #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" struct tty_chan { char *dev; diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 620f5b7..944453a 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -46,7 +46,6 @@ #include "asm/tlbflush.h" #include "mem_user.h" #include "kern_util.h" -#include "kern.h" #include "mconsole_kern.h" #include "init.h" #include "irq_user.h" @@ -54,7 +53,6 @@ #include "ubd_user.h" #include "os.h" #include "mem.h" -#include "mem_kern.h" #include "cow.h" enum ubd_req { UBD_READ, UBD_WRITE }; @@ -513,8 +511,37 @@ __uml_exitcall(kill_io_thread); static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) { char *file; + int fd; + int err; + + __u32 version; + __u32 align; + char *backing_file; + time_t mtime; + unsigned long long size; + int sector_size; + int bitmap_offset; + + if (ubd_dev->file && ubd_dev->cow.file) { + file = ubd_dev->cow.file; + + goto out; + } - file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file; + fd = os_open_file(ubd_dev->file, global_openflags, 0); + if (fd < 0) + return fd; + + err = read_cow_header(file_reader, &fd, &version, &backing_file, \ + &mtime, &size, §or_size, &align, &bitmap_offset); + os_close_file(fd); + + if(err == -EINVAL) + file = ubd_dev->file; + else + file = backing_file; + +out: return os_file_size(file, size_out); } diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index b591bb9..007b94d 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -16,7 +16,6 @@ #include <sys/mman.h> #include <sys/param.h> #include "asm/types.h" -#include "user.h" #include "ubd_user.h" #include "os.h" #include "cow.h" diff --git a/arch/um/include/shared/ubd_user.h b/arch/um/drivers/ubd_user.h index 3845051..3845051 100644 --- a/arch/um/include/shared/ubd_user.h +++ b/arch/um/drivers/ubd_user.h diff --git a/arch/um/drivers/umcast_user.c b/arch/um/drivers/umcast_user.c index 59c56fd..010fa2d 100644 --- a/arch/um/drivers/umcast_user.c +++ b/arch/um/drivers/umcast_user.c @@ -15,11 +15,9 @@ #include <unistd.h> #include <errno.h> #include <netinet/in.h> -#include "kern_constants.h" #include "umcast.h" #include "net_user.h" #include "um_malloc.h" -#include "user.h" static struct sockaddr_in *new_addr(char *addr, unsigned short port) { diff --git a/arch/um/drivers/vde_user.c b/arch/um/drivers/vde_user.c index c5c4325..b8c2867 100644 --- a/arch/um/drivers/vde_user.c +++ b/arch/um/drivers/vde_user.c @@ -6,10 +6,8 @@ #include <stddef.h> #include <errno.h> #include <libvdeplug.h> -#include "kern_constants.h" #include "net_user.h" #include "um_malloc.h" -#include "user.h" #include "vde.h" static int vde_user_init(void *data, void *dev) diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index 2e1de57..969110e 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -11,10 +11,8 @@ #include <string.h> #include <termios.h> #include "chan_user.h" -#include "kern_constants.h" #include "os.h" #include "um_malloc.h" -#include "user.h" #include "xterm.h" struct xterm_chan { diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild new file mode 100644 index 0000000..451f451 --- /dev/null +++ b/arch/um/include/asm/Kbuild @@ -0,0 +1,3 @@ +generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h +generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h +generic-y += ftrace.h diff --git a/arch/um/include/asm/bug.h b/arch/um/include/asm/bug.h deleted file mode 100644 index 9e33b86..0000000 --- a/arch/um/include/asm/bug.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_BUG_H -#define __UM_BUG_H - -#include <asm-generic/bug.h> - -#endif diff --git a/arch/um/include/asm/checksum.h b/arch/um/include/asm/checksum.h deleted file mode 100644 index 5b50136..0000000 --- a/arch/um/include/asm/checksum.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_CHECKSUM_H -#define __UM_CHECKSUM_H - -#include "sysdep/checksum.h" - -#endif diff --git a/arch/um/include/asm/cputime.h b/arch/um/include/asm/cputime.h deleted file mode 100644 index c84acba..0000000 --- a/arch/um/include/asm/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_CPUTIME_H -#define __UM_CPUTIME_H - -#include <asm-generic/cputime.h> - -#endif /* __UM_CPUTIME_H */ diff --git a/arch/um/include/asm/device.h b/arch/um/include/asm/device.h deleted file mode 100644 index d8f9872..0000000 --- a/arch/um/include/asm/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include <asm-generic/device.h> - diff --git a/arch/um/include/asm/emergency-restart.h b/arch/um/include/asm/emergency-restart.h deleted file mode 100644 index 108d8c4..0000000 --- a/arch/um/include/asm/emergency-restart.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - -#include <asm-generic/emergency-restart.h> - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/arch/um/include/asm/ftrace.h b/arch/um/include/asm/ftrace.h deleted file mode 100644 index 40a8c17..0000000 --- a/arch/um/include/asm/ftrace.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/arch/um/include/asm/futex.h b/arch/um/include/asm/futex.h deleted file mode 100644 index 6a332a9..0000000 --- a/arch/um/include/asm/futex.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_FUTEX_H -#define _ASM_FUTEX_H - -#include <asm-generic/futex.h> - -#endif diff --git a/arch/um/include/asm/hardirq.h b/arch/um/include/asm/hardirq.h deleted file mode 100644 index fb3c05a..0000000 --- a/arch/um/include/asm/hardirq.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/hardirq.h> diff --git a/arch/um/include/asm/hw_irq.h b/arch/um/include/asm/hw_irq.h deleted file mode 100644 index 1cf84cf..0000000 --- a/arch/um/include/asm/hw_irq.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _ASM_UM_HW_IRQ_H -#define _ASM_UM_HW_IRQ_H - -#include "asm/irq.h" -#include "asm/archparam.h" - -#endif diff --git a/arch/um/include/asm/irq_regs.h b/arch/um/include/asm/irq_regs.h deleted file mode 100644 index 3dd9c0b..0000000 --- a/arch/um/include/asm/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/irq_regs.h> diff --git a/arch/um/include/asm/irqflags.h b/arch/um/include/asm/irqflags.h index 659b9ab..c780d8a 100644 --- a/arch/um/include/asm/irqflags.h +++ b/arch/um/include/asm/irqflags.h @@ -1,6 +1,42 @@ #ifndef __UM_IRQFLAGS_H #define __UM_IRQFLAGS_H -/* Empty for now */ +extern int get_signals(void); +extern int set_signals(int enable); +extern void block_signals(void); +extern void unblock_signals(void); + +static inline unsigned long arch_local_save_flags(void) +{ + return get_signals(); +} + +static inline void arch_local_irq_restore(unsigned long flags) +{ + set_signals(flags); +} + +static inline void arch_local_irq_enable(void) +{ + unblock_signals(); +} + +static inline void arch_local_irq_disable(void) +{ + block_signals(); +} + +static inline unsigned long arch_local_irq_save(void) +{ + unsigned long flags; + flags = arch_local_save_flags(); + arch_local_irq_disable(); + return flags; +} + +static inline bool arch_irqs_disabled(void) +{ + return arch_local_save_flags() == 0; +} #endif diff --git a/arch/um/include/asm/kdebug.h b/arch/um/include/asm/kdebug.h deleted file mode 100644 index 6ece1b0..0000000 --- a/arch/um/include/asm/kdebug.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/kdebug.h> diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h index cf259de..30509b9 100644 --- a/arch/um/include/asm/mmu.h +++ b/arch/um/include/asm/mmu.h @@ -1,12 +1,24 @@ /* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#ifndef __MMU_H -#define __MMU_H +#ifndef __ARCH_UM_MMU_H +#define __ARCH_UM_MMU_H -#include "um_mmu.h" +#include "mm_id.h" +#include <asm/mm_context.h> -#endif +typedef struct mm_context { + struct mm_id id; + struct uml_arch_mm_context arch; + struct page **stub_pages; +} mm_context_t; + +extern void __switch_mm(struct mm_id * mm_idp); +/* Avoid tangled inclusion with asm/ldt.h */ +extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm); +extern void free_ldt(struct mm_context *mm); + +#endif diff --git a/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h index 34d8130..591b3d8 100644 --- a/arch/um/include/asm/mmu_context.h +++ b/arch/um/include/asm/mmu_context.h @@ -6,15 +6,12 @@ #ifndef __UM_MMU_CONTEXT_H #define __UM_MMU_CONTEXT_H -#include "linux/sched.h" -#include "um_mmu.h" +#include <linux/sched.h> +#include <asm/mmu.h> extern void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm); extern void arch_exit_mmap(struct mm_struct *mm); -#define get_mmu_context(task) do ; while(0) -#define activate_context(tsk) do ; while(0) - #define deactivate_mm(tsk,mm) do { } while (0) extern void force_flush_all(void); diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h index 4cc9b6c..7cfc3ce 100644 --- a/arch/um/include/asm/page.h +++ b/arch/um/include/asm/page.h @@ -19,7 +19,7 @@ struct page; #include <linux/types.h> -#include <sysdep/vm-flags.h> +#include <asm/vm-flags.h> /* * These are used to make use of C type-checking.. diff --git a/arch/um/include/asm/page_offset.h b/arch/um/include/asm/page_offset.h deleted file mode 100644 index 1c168df..0000000 --- a/arch/um/include/asm/page_offset.h +++ /dev/null @@ -1 +0,0 @@ -#define PAGE_OFFSET_RAW (uml_physmem) diff --git a/arch/um/include/asm/pda.h b/arch/um/include/asm/pda.h deleted file mode 100644 index ddcd774..0000000 --- a/arch/um/include/asm/pda.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_PDA_X86_64_H -#define __UM_PDA_X86_64_H - -/* XXX */ -struct foo { - unsigned int __softirq_pending; - unsigned int __nmi_count; -}; - -extern struct foo me; - -#define read_pda(me) (&me) - -#endif - diff --git a/arch/um/include/asm/percpu.h b/arch/um/include/asm/percpu.h deleted file mode 100644 index efe7508..0000000 --- a/arch/um/include/asm/percpu.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_PERCPU_H -#define __UM_PERCPU_H - -#include <asm-generic/percpu.h> - -#endif /* __UM_PERCPU_H */ diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index 1a7d275..f605d3c 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h @@ -23,17 +23,10 @@ struct pt_regs { #define PT_REGS_IP(r) UPT_IP(&(r)->regs) #define PT_REGS_SP(r) UPT_SP(&(r)->regs) -#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg) -#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val) - -#define PT_REGS_SET_SYSCALL_RETURN(r, res) \ - UPT_SET_SYSCALL_RETURN(&(r)->regs, res) #define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs) #define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs) -#define PT_REGS_SC(r) UPT_SC(&(r)->regs) - #define instruction_pointer(regs) PT_REGS_IP(regs) struct task_struct; diff --git a/arch/um/include/asm/sections.h b/arch/um/include/asm/sections.h deleted file mode 100644 index 6b0231e..0000000 --- a/arch/um/include/asm/sections.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _UM_SECTIONS_H -#define _UM_SECTIONS_H - -/* nothing to see, move along */ -#include <asm-generic/sections.h> - -#endif diff --git a/arch/um/include/asm/system.h b/arch/um/include/asm/system.h deleted file mode 100644 index 68a90ec..0000000 --- a/arch/um/include/asm/system.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __UM_SYSTEM_GENERIC_H -#define __UM_SYSTEM_GENERIC_H - -#include "sysdep/system.h" - -extern int get_signals(void); -extern int set_signals(int enable); -extern void block_signals(void); -extern void unblock_signals(void); - -static inline unsigned long arch_local_save_flags(void) -{ - return get_signals(); -} - -static inline void arch_local_irq_restore(unsigned long flags) -{ - set_signals(flags); -} - -static inline void arch_local_irq_enable(void) -{ - unblock_signals(); -} - -static inline void arch_local_irq_disable(void) -{ - block_signals(); -} - -static inline unsigned long arch_local_irq_save(void) -{ - unsigned long flags; - flags = arch_local_save_flags(); - arch_local_irq_disable(); - return flags; -} - -static inline bool arch_irqs_disabled(void) -{ - return arch_local_save_flags() == 0; -} - -extern void *_switch_to(void *prev, void *next, void *last); -#define switch_to(prev, next, last) prev = _switch_to(prev, next, last) - -#endif diff --git a/arch/um/include/asm/topology.h b/arch/um/include/asm/topology.h deleted file mode 100644 index 0905e4f..0000000 --- a/arch/um/include/asm/topology.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_UM_TOPOLOGY_H -#define _ASM_UM_TOPOLOGY_H - -#include <asm-generic/topology.h> - -#endif diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h index b9a895d..3f22fbf 100644 --- a/arch/um/include/asm/uaccess.h +++ b/arch/um/include/asm/uaccess.h @@ -6,15 +6,15 @@ #ifndef __UM_UACCESS_H #define __UM_UACCESS_H -#include <asm/errno.h> -#include <asm/processor.h> - /* thread_info has a mm_segment_t in it, so put the definition up here */ typedef struct { unsigned long seg; } mm_segment_t; -#include "linux/thread_info.h" +#include <linux/thread_info.h> +#include <linux/errno.h> +#include <asm/processor.h> +#include <asm/elf.h> #define VERIFY_READ 0 #define VERIFY_WRITE 1 @@ -38,7 +38,86 @@ typedef struct { #define segment_eq(a, b) ((a).seg == (b).seg) -#include "um_uaccess.h" +#define __under_task_size(addr, size) \ + (((unsigned long) (addr) < TASK_SIZE) && \ + (((unsigned long) (addr) + (size)) < TASK_SIZE)) + +#define __access_ok_vsyscall(type, addr, size) \ + ((type == VERIFY_READ) && \ + ((unsigned long) (addr) >= FIXADDR_USER_START) && \ + ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ + ((unsigned long) (addr) + (size) >= (unsigned long)(addr))) + +#define __addr_range_nowrap(addr, size) \ + ((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) + +#define access_ok(type, addr, size) \ + (__addr_range_nowrap(addr, size) && \ + (__under_task_size(addr, size) || \ + __access_ok_vsyscall(type, addr, size) || \ + segment_eq(get_fs(), KERNEL_DS))) + +extern int copy_from_user(void *to, const void __user *from, int n); +extern int copy_to_user(void __user *to, const void *from, int n); + +/* + * strncpy_from_user: - Copy a NUL terminated string from userspace. + * @dst: Destination address, in kernel space. This buffer must be at + * least @count bytes long. + * @src: Source address, in user space. + * @count: Maximum number of bytes to copy, including the trailing NUL. + * + * Copies a NUL-terminated string from userspace to kernel space. + * + * On success, returns the length of the string (not including the trailing + * NUL). + * + * If access to userspace fails, returns -EFAULT (some data may have been + * copied). + * + * If @count is smaller than the length of the string, copies @count bytes + * and returns @count. + */ + +extern int strncpy_from_user(char *dst, const char __user *src, int count); + +/* + * __clear_user: - Zero a block of memory in user space, with less checking. + * @to: Destination address, in user space. + * @n: Number of bytes to zero. + * + * Zero a block of memory in user space. Caller must check + * the specified block with access_ok() before calling this function. + * + * Returns number of bytes that could not be cleared. + * On success, this will be zero. + */ +extern int __clear_user(void __user *mem, int len); + +/* + * clear_user: - Zero a block of memory in user space. + * @to: Destination address, in user space. + * @n: Number of bytes to zero. + * + * Zero a block of memory in user space. + * + * Returns number of bytes that could not be cleared. + * On success, this will be zero. + */ +extern int clear_user(void __user *mem, int len); + +/* + * strlen_user: - Get the size of a string in user space. + * @str: The string to measure. + * @n: The maximum valid length + * + * Get the size of a NUL-terminated string in user space. + * + * Returns the size of the string INCLUDING the terminating NUL. + * On exception, returns 0. + * If the string is too long, returns a value greater than @n. + */ +extern int strnlen_user(const void __user *str, int len); #define __copy_from_user(to, from, n) copy_from_user(to, from, n) diff --git a/arch/um/include/asm/xor.h b/arch/um/include/asm/xor.h deleted file mode 100644 index a19db3e..0000000 --- a/arch/um/include/asm/xor.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_XOR_H -#define __UM_XOR_H - -#include "asm-generic/xor.h" - -#endif diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index a92b678..896e166 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h @@ -6,7 +6,7 @@ #ifndef __START_H__ #define __START_H__ -#include "kern_constants.h" +#include <generated/asm-offsets.h> /* * Stolen from linux/const.h, which can't be directly included since diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h index 72009c7..d7fe563 100644 --- a/arch/um/include/shared/common-offsets.h +++ b/arch/um/include/shared/common-offsets.h @@ -2,7 +2,6 @@ DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); -OFFSET(HOST_TASK_REGS, task_struct, thread.regs); OFFSET(HOST_TASK_PID, task_struct, pid); DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); diff --git a/arch/um/include/shared/initrd.h b/arch/um/include/shared/initrd.h deleted file mode 100644 index 22673bc..0000000 --- a/arch/um/include/shared/initrd.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __INITRD_USER_H__ -#define __INITRD_USER_H__ - -extern int load_initrd(char *filename, void *buf, int size); - -#endif - diff --git a/arch/um/include/shared/kern.h b/arch/um/include/shared/kern.h index 4ce3fc6..6cd0124 100644 --- a/arch/um/include/shared/kern.h +++ b/arch/um/include/shared/kern.h @@ -13,28 +13,10 @@ * includes. */ -extern int errno; - -extern int clone(int (*proc)(void *), void *sp, int flags, void *data); -extern int sleep(int); extern int printf(const char *fmt, ...); -extern char *strerror(int errnum); -extern char *ptsname(int __fd); -extern int munmap(void *, int); extern void *sbrk(int increment); -extern void *malloc(int size); -extern void perror(char *err); -extern int kill(int pid, int sig); -extern int getuid(void); -extern int getgid(void); extern int pause(void); -extern int write(int, const void *, int); extern void exit(int); -extern int close(int); -extern int read(unsigned int, char *, int); -extern int pipe(int *); -extern int sched_yield(void); -extern int ptrace(int op, int pid, long addr, long data); #endif diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index 3c34122..0f14838 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h @@ -21,7 +21,6 @@ extern unsigned long alloc_stack(int order, int atomic); extern void free_stack(unsigned long stack, int order); extern int do_signal(void); -extern void copy_sc(struct uml_pt_regs *regs, void *from); extern void interrupt_end(void); extern void relay_signal(int sig, struct uml_pt_regs *regs); diff --git a/arch/um/include/shared/ldt.h b/arch/um/include/shared/ldt.h deleted file mode 100644 index a7f999a..0000000 --- a/arch/um/include/shared/ldt.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2004 Fujitsu Siemens Computers GmbH - * Licensed under the GPL - * - * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com> - */ - -#ifndef __ASM_LDT_H -#define __ASM_LDT_H - -#include <linux/mutex.h> -#include <sysdep/host_ldt.h> - -extern void ldt_host_info(void); - -#define LDT_PAGES_MAX \ - ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE) -#define LDT_ENTRIES_PER_PAGE \ - (PAGE_SIZE/LDT_ENTRY_SIZE) -#define LDT_DIRECT_ENTRIES \ - ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE) - -struct ldt_entry { - __u32 a; - __u32 b; -}; - -typedef struct uml_ldt { - int entry_count; - struct mutex lock; - union { - struct ldt_entry * pages[LDT_PAGES_MAX]; - struct ldt_entry entries[LDT_DIRECT_ENTRIES]; - } u; -} uml_ldt_t; - -#endif diff --git a/arch/um/include/shared/mem_kern.h b/arch/um/include/shared/mem_kern.h deleted file mode 100644 index 69be0fd..0000000 --- a/arch/um/include/shared/mem_kern.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __MEM_KERN_H__ -#define __MEM_KERN_H__ - -#include "linux/list.h" -#include "linux/types.h" - -struct remapper { - struct list_head list; - int (*proc)(int, unsigned long, int, __u64); -}; - -extern void register_remapper(struct remapper *info); - -#endif - diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 83c7c2e..89b686c1 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -10,7 +10,6 @@ #include "irq_user.h" #include "longjmp.h" #include "mm_id.h" -#include "sysdep/tls.h" #define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) @@ -203,12 +202,6 @@ extern int os_drop_memory(void *addr, int length); extern int can_drop_memory(void); extern void os_flush_stdout(void); -/* uaccess.c */ -extern unsigned long __do_user_copy(void *to, const void *from, int n, - void **fault_addr, jmp_buf **fault_catcher, - void (*op)(void *to, const void *from, - int n), int *faulted_out); - /* execvp.c */ extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); /* helper.c */ @@ -218,10 +211,6 @@ extern int run_helper_thread(int (*proc)(void *), void *arg, extern int helper_wait(int pid); -/* tls.c */ -extern int os_set_thread_area(user_desc_t *info, int pid); -extern int os_get_thread_area(user_desc_t *info, int pid); - /* umid.c */ extern int umid_file_name(char *name, char *buf, int len); extern int set_umid(char *name); @@ -231,7 +220,7 @@ extern char *get_umid(void); extern void timer_init(void); extern void set_sigstack(void *sig_stack, int size); extern void remove_sigstack(void); -extern void set_handler(int sig, void (*handler)(int), int flags, ...); +extern void set_handler(int sig); extern int change_sig(int signal, int on); extern void block_signals(void); extern void unblock_signals(void); diff --git a/arch/um/include/shared/process.h b/arch/um/include/shared/process.h deleted file mode 100644 index bb873a5..0000000 --- a/arch/um/include/shared/process.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __PROCESS_H__ -#define __PROCESS_H__ - -#include <signal.h> - -/* Copied from linux/compiler-gcc.h since we can't include it directly */ -#define barrier() __asm__ __volatile__("": : :"memory") - -extern void sig_handler(int sig, struct sigcontext *sc); -extern void alarm_handler(int sig, struct sigcontext *sc); - -#endif diff --git a/arch/um/include/shared/ptrace_user.h b/arch/um/include/shared/ptrace_user.h index 7fd8539..56b2f28 100644 --- a/arch/um/include/shared/ptrace_user.h +++ b/arch/um/include/shared/ptrace_user.h @@ -6,7 +6,8 @@ #ifndef __PTRACE_USER_H__ #define __PTRACE_USER_H__ -#include "sysdep/ptrace_user.h" +#include <sys/ptrace.h> +#include <sysdep/ptrace_user.h> extern int ptrace_getregs(long pid, unsigned long *regs_out); extern int ptrace_setregs(long pid, unsigned long *regs_in); diff --git a/arch/um/include/shared/skas_ptregs.h b/arch/um/include/shared/skas_ptregs.h deleted file mode 100644 index 73db19e..0000000 --- a/arch/um/include/shared/skas_ptregs.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __SKAS_PT_REGS_ -#define __SKAS_PT_REGS_ - -#include <user_constants.h> - -#endif diff --git a/arch/um/include/shared/syscall.h b/arch/um/include/shared/syscall.h deleted file mode 100644 index dda1df9..0000000 --- a/arch/um/include/shared/syscall.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SYSCALL_USER_H -#define __SYSCALL_USER_H - -extern int record_syscall_start(int syscall); -extern void record_syscall_end(int index, long result); - -#endif diff --git a/arch/um/include/shared/task.h b/arch/um/include/shared/task.h deleted file mode 100644 index 3fe726b..0000000 --- a/arch/um/include/shared/task.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __TASK_H -#define __TASK_H - -#include <kern_constants.h> - -#define TASK_REGS(task) ((struct uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS])) -#define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID])) - -#endif diff --git a/arch/um/include/shared/tlb.h b/arch/um/include/shared/tlb.h deleted file mode 100644 index ecd2265..0000000 --- a/arch/um/include/shared/tlb.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __TLB_H__ -#define __TLB_H__ - -#include "um_mmu.h" - -extern void force_flush_all(void); -extern int flush_tlb_kernel_range_common(unsigned long start, - unsigned long end); - -#endif diff --git a/arch/um/include/shared/um_malloc.h b/arch/um/include/shared/um_malloc.h index c554d70..6395fef 100644 --- a/arch/um/include/shared/um_malloc.h +++ b/arch/um/include/shared/um_malloc.h @@ -6,7 +6,7 @@ #ifndef __UM_MALLOC_H__ #define __UM_MALLOC_H__ -#include "kern_constants.h" +#include <generated/asm-offsets.h> extern void *uml_kmalloc(int size, int flags); extern void kfree(const void *ptr); diff --git a/arch/um/include/shared/um_mmu.h b/arch/um/include/shared/um_mmu.h deleted file mode 100644 index b1a7e47..0000000 --- a/arch/um/include/shared/um_mmu.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __ARCH_UM_MMU_H -#define __ARCH_UM_MMU_H - -#include "mm_id.h" -#include "ldt.h" - -typedef struct mm_context { - struct mm_id id; - struct uml_ldt ldt; - struct page **stub_pages; -} mm_context_t; - -extern void __switch_mm(struct mm_id * mm_idp); - -/* Avoid tangled inclusion with asm/ldt.h */ -extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm); -extern void free_ldt(struct mm_context *mm); - -#endif diff --git a/arch/um/include/shared/um_uaccess.h b/arch/um/include/shared/um_uaccess.h deleted file mode 100644 index 45c0499..0000000 --- a/arch/um/include/shared/um_uaccess.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __ARCH_UM_UACCESS_H -#define __ARCH_UM_UACCESS_H - -#include <asm/elf.h> -#include <asm/fixmap.h> -#include "sysdep/archsetjmp.h" - -#define __under_task_size(addr, size) \ - (((unsigned long) (addr) < TASK_SIZE) && \ - (((unsigned long) (addr) + (size)) < TASK_SIZE)) - -#define __access_ok_vsyscall(type, addr, size) \ - ((type == VERIFY_READ) && \ - ((unsigned long) (addr) >= FIXADDR_USER_START) && \ - ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ - ((unsigned long) (addr) + (size) >= (unsigned long)(addr))) - -#define __addr_range_nowrap(addr, size) \ - ((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) - -#define access_ok(type, addr, size) \ - (__addr_range_nowrap(addr, size) && \ - (__under_task_size(addr, size) || \ - __access_ok_vsyscall(type, addr, size) || \ - segment_eq(get_fs(), KERNEL_DS))) - -extern int copy_from_user(void *to, const void __user *from, int n); -extern int copy_to_user(void __user *to, const void *from, int n); - -extern int __do_copy_to_user(void *to, const void *from, int n, - void **fault_addr, jmp_buf **fault_catcher); - -/* - * strncpy_from_user: - Copy a NUL terminated string from userspace. - * @dst: Destination address, in kernel space. This buffer must be at - * least @count bytes long. - * @src: Source address, in user space. - * @count: Maximum number of bytes to copy, including the trailing NUL. - * - * Copies a NUL-terminated string from userspace to kernel space. - * - * On success, returns the length of the string (not including the trailing - * NUL). - * - * If access to userspace fails, returns -EFAULT (some data may have been - * copied). - * - * If @count is smaller than the length of the string, copies @count bytes - * and returns @count. - */ - -extern int strncpy_from_user(char *dst, const char __user *src, int count); - -/* - * __clear_user: - Zero a block of memory in user space, with less checking. - * @to: Destination address, in user space. - * @n: Number of bytes to zero. - * - * Zero a block of memory in user space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be cleared. - * On success, this will be zero. - */ -extern int __clear_user(void __user *mem, int len); - -/* - * clear_user: - Zero a block of memory in user space. - * @to: Destination address, in user space. - * @n: Number of bytes to zero. - * - * Zero a block of memory in user space. - * - * Returns number of bytes that could not be cleared. - * On success, this will be zero. - */ -extern int clear_user(void __user *mem, int len); - -/* - * strlen_user: - Get the size of a string in user space. - * @str: The string to measure. - * @n: The maximum valid length - * - * Get the size of a NUL-terminated string in user space. - * - * Returns the size of the string INCLUDING the terminating NUL. - * On exception, returns 0. - * If the string is too long, returns a value greater than @n. - */ -extern int strnlen_user(const void __user *str, int len); - -#endif diff --git a/arch/um/include/shared/user.h b/arch/um/include/shared/user.h index 293f7c7..4fa82c0 100644 --- a/arch/um/include/shared/user.h +++ b/arch/um/include/shared/user.h @@ -6,7 +6,7 @@ #ifndef __USER_H__ #define __USER_H__ -#include "kern_constants.h" +#include <generated/asm-offsets.h> /* * The usual definition - copied here because the kernel provides its own, @@ -36,10 +36,11 @@ static inline int printk(const char *fmt, ...) } #endif -extern void schedule(void); extern int in_aton(char *str); -extern int open_gdb_chan(void); extern size_t strlcpy(char *, const char *, size_t); extern size_t strlcat(char *, const char *, size_t); +/* Copied from linux/compiler-gcc.h since we can't include it directly */ +#define barrier() __asm__ __volatile__("": : :"memory") + #endif diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index c4491c1..bc49474 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -11,7 +11,7 @@ clean-files := obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \ physmem.o process.o ptrace.o reboot.o sigio.o \ - signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \ + signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o \ um_arch.o umid.o skas/ obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 939a4a6..6cade93 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -3,14 +3,15 @@ * Licensed under the GPL */ -#include "linux/stddef.h" -#include "linux/fs.h" -#include "linux/ptrace.h" -#include "linux/sched.h" -#include "linux/slab.h" -#include "asm/current.h" -#include "asm/processor.h" -#include "asm/uaccess.h" +#include <linux/stddef.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/ptrace.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <asm/current.h> +#include <asm/processor.h> +#include <asm/uaccess.h> #include "as-layout.h" #include "mem_user.h" #include "skas.h" @@ -41,6 +42,7 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; } +EXPORT_SYMBOL(start_thread); static long execve1(const char *file, const char __user *const __user *argv, diff --git a/arch/um/kernel/gmon_syms.c b/arch/um/kernel/gmon_syms.c index 72eccd2..e9bcf247 100644 --- a/arch/um/kernel/gmon_syms.c +++ b/arch/um/kernel/gmon_syms.c @@ -7,18 +7,3 @@ extern void __bb_init_func(void *) __attribute__((weak)); EXPORT_SYMBOL(__bb_init_func); - -/* - * This is defined (and referred to in profiling stub code) only by some GCC - * versions in libgcov. - * - * Since SuSE backported the fix, we cannot handle it depending on GCC version. - * So, unconditionally export it. But also give it a weak declaration, which - * will be overridden by any other one. - */ - -extern void __gcov_init(void *) __attribute__((weak)); -EXPORT_SYMBOL(__gcov_init); - -extern void __gcov_merge_add(void *) __attribute__((weak)); -EXPORT_SYMBOL(__gcov_merge_add); diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c index d386c75..10cc18f 100644 --- a/arch/um/kernel/initrd.c +++ b/arch/um/kernel/initrd.c @@ -7,12 +7,12 @@ #include "linux/bootmem.h" #include "linux/initrd.h" #include "asm/types.h" -#include "initrd.h" #include "init.h" #include "os.h" /* Changed by uml_initrd_setup, which is a setup */ static char *initrd __initdata = NULL; +static int load_initrd(char *filename, void *buf, int size); static int __init read_initrd(void) { @@ -62,7 +62,7 @@ __uml_setup("initrd=", uml_initrd_setup, " name of the file containing the image.\n\n" ); -int load_initrd(char *filename, void *buf, int size) +static int load_initrd(char *filename, void *buf, int size) { int fd, n; diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 9e485c7..71b8c94 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -258,6 +258,7 @@ void deactivate_fd(int fd, int irqnum) ignore_sigio_fd(fd); } +EXPORT_SYMBOL(deactivate_fd); /* * Called just before shutdown in order to provide a clean exec diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 0ae0dfc..e17bea0 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c @@ -3,33 +3,11 @@ * Licensed under the GPL */ -#include "linux/module.h" -#include "linux/syscalls.h" -#include "asm/tlbflush.h" -#include "asm/uaccess.h" -#include "as-layout.h" -#include "kern_util.h" -#include "mem_user.h" +#include <linux/module.h> #include "os.h" -EXPORT_SYMBOL(uml_physmem); EXPORT_SYMBOL(set_signals); EXPORT_SYMBOL(get_signals); -EXPORT_SYMBOL(kernel_thread); -EXPORT_SYMBOL(sys_waitpid); -EXPORT_SYMBOL(flush_tlb_range); - -EXPORT_SYMBOL(high_physmem); -EXPORT_SYMBOL(empty_zero_page); -EXPORT_SYMBOL(handle_page_fault); -EXPORT_SYMBOL(find_iomem); - -EXPORT_SYMBOL(strnlen_user); -EXPORT_SYMBOL(strncpy_from_user); -EXPORT_SYMBOL(copy_to_user); -EXPORT_SYMBOL(copy_from_user); -EXPORT_SYMBOL(clear_user); -EXPORT_SYMBOL(uml_strdup); EXPORT_SYMBOL(os_stat_fd); EXPORT_SYMBOL(os_stat_file); @@ -57,24 +35,10 @@ EXPORT_SYMBOL(os_connect_socket); EXPORT_SYMBOL(os_accept_connection); EXPORT_SYMBOL(os_rcv_fd); EXPORT_SYMBOL(run_helper); -EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(os_major); EXPORT_SYMBOL(os_minor); EXPORT_SYMBOL(os_makedev); EXPORT_SYMBOL(add_sigio_fd); EXPORT_SYMBOL(ignore_sigio_fd); -EXPORT_SYMBOL(deactivate_fd); EXPORT_SYMBOL(sigio_broken); - -#ifdef CONFIG_SMP - -/* required for SMP */ - -extern void __write_lock_failed(rwlock_t *rw); -EXPORT_SYMBOL(__write_lock_failed); - -extern void __read_lock_failed(rwlock_t *rw); -EXPORT_SYMBOL(__read_lock_failed); - -#endif diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 8137ccc..ebb86b2 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -4,6 +4,7 @@ */ #include <linux/stddef.h> +#include <linux/module.h> #include <linux/bootmem.h> #include <linux/highmem.h> #include <linux/mm.h> @@ -20,6 +21,7 @@ /* allocated in paging_init, zeroed in mem_init, and unchanged thereafter */ unsigned long *empty_zero_page = NULL; +EXPORT_SYMBOL(empty_zero_page); /* allocated in paging_init and unchanged thereafter */ static unsigned long *empty_bad_page = NULL; diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index a1a9090..f116db1 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -3,20 +3,22 @@ * Licensed under the GPL */ -#include "linux/bootmem.h" -#include "linux/mm.h" -#include "linux/pfn.h" -#include "asm/page.h" -#include "as-layout.h" -#include "init.h" -#include "kern.h" -#include "mem_user.h" -#include "os.h" +#include <linux/module.h> +#include <linux/bootmem.h> +#include <linux/mm.h> +#include <linux/pfn.h> +#include <asm/page.h> +#include <as-layout.h> +#include <init.h> +#include <kern.h> +#include <mem_user.h> +#include <os.h> static int physmem_fd = -1; /* Changed during early boot */ unsigned long high_physmem; +EXPORT_SYMBOL(high_physmem); extern unsigned long long physmem_size; @@ -184,6 +186,7 @@ unsigned long find_iomem(char *driver, unsigned long *len_out) return 0; } +EXPORT_SYMBOL(find_iomem); static int setup_iomem(void) { diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 21c1ae7..c533835 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -20,12 +20,12 @@ #include <linux/threads.h> #include <asm/current.h> #include <asm/pgtable.h> +#include <asm/mmu_context.h> #include <asm/uaccess.h> #include "as-layout.h" #include "kern_util.h" #include "os.h" #include "skas.h" -#include "tlb.h" /* * This is a per-cpu array. A processor only modifies its entry and it only @@ -78,6 +78,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) ¤t->thread.regs, 0, NULL, NULL); return pid; } +EXPORT_SYMBOL(kernel_thread); static inline void set_current(struct task_struct *task) { @@ -286,6 +287,7 @@ char *uml_strdup(const char *string) { return kstrdup(string, GFP_KERNEL); } +EXPORT_SYMBOL(uml_strdup); int copy_to_user_proc(void __user *to, void *from, int size) { diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c index b5c094c..e8b889d 100644 --- a/arch/um/kernel/signal.c +++ b/arch/um/kernel/signal.c @@ -11,7 +11,6 @@ #include <asm/unistd.h> #include "frame_kern.h" #include "kern_util.h" -#include <sysdep/sigcontext.h> EXPORT_SYMBOL(block_signals); EXPORT_SYMBOL(unblock_signals); diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c index 2c8583c..e1fd066 100644 --- a/arch/um/kernel/skas/clone.c +++ b/arch/um/kernel/skas/clone.c @@ -8,7 +8,6 @@ #include <asm/unistd.h> #include <sys/time.h> #include "as-layout.h" -#include "kern_constants.h" #include "ptrace_user.h" #include "stub-data.h" #include "sysdep/stub.h" diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index 6966342..9fefd92 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c @@ -6,6 +6,7 @@ #include <linux/err.h> #include <linux/highmem.h> #include <linux/mm.h> +#include <linux/module.h> #include <linux/sched.h> #include <asm/current.h> #include <asm/page.h> @@ -149,6 +150,7 @@ int copy_from_user(void *to, const void __user *from, int n) buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to): n; } +EXPORT_SYMBOL(copy_from_user); static int copy_chunk_to_user(unsigned long to, int len, void *arg) { @@ -170,6 +172,7 @@ int copy_to_user(void __user *to, const void *from, int n) buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) : n; } +EXPORT_SYMBOL(copy_to_user); static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) { @@ -204,6 +207,7 @@ int strncpy_from_user(char *dst, const char __user *src, int count) return -EFAULT; return strnlen(dst, count); } +EXPORT_SYMBOL(strncpy_from_user); static int clear_chunk(unsigned long addr, int len, void *unused) { @@ -226,6 +230,7 @@ int clear_user(void __user *mem, int len) return access_ok(VERIFY_WRITE, mem, len) ? buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len; } +EXPORT_SYMBOL(clear_user); static int strnlen_chunk(unsigned long str, int len, void *arg) { @@ -251,3 +256,4 @@ int strnlen_user(const void __user *str, int len) return count + 1; return -EFAULT; } +EXPORT_SYMBOL(strnlen_user); diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index d175d05..7f3d4d86 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -4,6 +4,7 @@ */ #include <linux/mm.h> +#include <linux/module.h> #include <linux/sched.h> #include <asm/pgtable.h> #include <asm/tlbflush.h> @@ -11,7 +12,6 @@ #include "mem_user.h" #include "os.h" #include "skas.h" -#include "tlb.h" struct host_vm_change { struct host_vm_op { @@ -287,7 +287,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, } } -int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) +static int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) { struct mm_struct *mm; pgd_t *pgd; @@ -499,6 +499,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, flush_tlb_kernel_range_common(start, end); else fix_range(vma->vm_mm, start, end, 0); } +EXPORT_SYMBOL(flush_tlb_range); void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, unsigned long end) diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 8c7b882..dafc947 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -6,6 +6,7 @@ #include <linux/mm.h> #include <linux/sched.h> #include <linux/hardirq.h> +#include <linux/module.h> #include <asm/current.h> #include <asm/pgtable.h> #include <asm/tlbflush.h> @@ -14,7 +15,6 @@ #include "kern_util.h" #include "os.h" #include "skas.h" -#include "sysdep/sigcontext.h" /* * Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by @@ -112,6 +112,7 @@ out_of_memory: pagefault_out_of_memory(); return 0; } +EXPORT_SYMBOL(handle_page_fault); static void show_segv_info(struct uml_pt_regs *regs) { diff --git a/arch/um/kernel/uaccess.c b/arch/um/kernel/uaccess.c deleted file mode 100644 index dd33f04..0000000 --- a/arch/um/kernel/uaccess.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk) - * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -/* - * These are here rather than tt/uaccess.c because skas mode needs them in - * order to do SIGBUS recovery when a tmpfs mount runs out of room. - */ - -#include <linux/string.h> -#include "os.h" - -static void __do_copy(void *to, const void *from, int n) -{ - memcpy(to, from, n); -} - - -int __do_copy_to_user(void *to, const void *from, int n, - void **fault_addr, jmp_buf **fault_catcher) -{ - unsigned long fault; - int faulted; - - fault = __do_user_copy(to, from, n, fault_addr, fault_catcher, - __do_copy, &faulted); - if (!faulted) - return 0; - else - return n - (fault - (unsigned long) to); -} diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 8d84250..ba00eae 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -102,6 +102,8 @@ const struct seq_operations cpuinfo_op = { /* Set in linux_main */ unsigned long uml_physmem; +EXPORT_SYMBOL(uml_physmem); + unsigned long uml_reserved; /* Also modified in mem_init */ unsigned long start_vm; unsigned long end_vm; diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index b33f4df..dd76410 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -4,14 +4,14 @@ # obj-y = aio.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ - registers.o sigio.o signal.o start_up.o time.o tty.o uaccess.o \ - umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/ + registers.o sigio.o signal.o start_up.o time.o tty.o \ + umid.o user_syms.o util.o drivers/ skas/ obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \ - tty.o tls.o uaccess.o umid.o util.o + tty.o umid.o util.o CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 57e3d46..c5d039e 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -11,10 +11,8 @@ #include <asm/unistd.h> #include "aio.h" #include "init.h" -#include "kern_constants.h" #include "kern_util.h" #include "os.h" -#include "user.h" struct aio_thread_req { enum aio_type type; diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index cc72cb2..db3d648 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -13,11 +13,9 @@ #include <sys/socket.h> #include <sys/wait.h> #include "etap.h" -#include "kern_constants.h" #include "os.h" #include "net_user.h" #include "um_malloc.h" -#include "user.h" #define MAX_PACKET ETH_MAX_PACKET diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index 2448be0..a2aacff 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -13,11 +13,9 @@ #include <sys/socket.h> #include <sys/wait.h> #include <sys/uio.h> -#include "kern_constants.h" #include "kern_util.h" #include "os.h" #include "tuntap.h" -#include "user.h" static int tuntap_user_init(void *data, void *dev) { diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 9533237..d895271 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c @@ -12,7 +12,6 @@ #include "init.h" #include "elf_user.h" #include "mem_user.h" -#include <kern_constants.h> typedef Elf32_auxv_t elf_auxv_t; diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 140e587..b049a63 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -13,9 +13,7 @@ #include <sys/socket.h> #include <sys/stat.h> #include <sys/un.h> -#include "kern_constants.h" #include "os.h" -#include "user.h" static void copy_stat(struct uml_stat *dst, const struct stat64 *src) { diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index feff22d..cf26c4a 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -10,11 +10,9 @@ #include <linux/limits.h> #include <sys/socket.h> #include <sys/wait.h> -#include "kern_constants.h" #include "kern_util.h" #include "os.h" #include "um_malloc.h" -#include "user.h" struct helper_data { void (*pre_exec)(void*); diff --git a/arch/um/os-Linux/internal.h b/arch/um/os-Linux/internal.h new file mode 100644 index 0000000..2c3c3ec --- /dev/null +++ b/arch/um/os-Linux/internal.h @@ -0,0 +1 @@ +void alarm_handler(int, mcontext_t *); diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index 0348b97..9a49908 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c @@ -9,11 +9,8 @@ #include <signal.h> #include <string.h> #include "irq_user.h" -#include "kern_constants.h" #include "os.h" -#include "process.h" #include "um_malloc.h" -#include "user.h" /* * Locked by irq_lock in arch/um/kernel/irq.c. Changed by os_create_pollfd diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 8471b81..7a86dd5 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -12,7 +12,6 @@ #include <sys/resource.h> #include "as-layout.h" #include "init.h" -#include "kern_constants.h" #include "kern_util.h" #include "os.h" #include "um_malloc.h" diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index 62878cf..8e421e1 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -14,9 +14,7 @@ #include <sys/mman.h> #include <sys/param.h> #include "init.h" -#include "kern_constants.h" #include "os.h" -#include "user.h" /* Modified by which_tmpdir, which is called during early boot */ static char *default_tmpdir = "/tmp"; diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 0c45dc8..307f173 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -13,12 +13,9 @@ #include <sys/wait.h> #include <asm/unistd.h> #include "init.h" -#include "kern_constants.h" #include "longjmp.h" #include "os.h" -#include "process.h" #include "skas_ptrace.h" -#include "user.h" #define ARBITRARY_ADDR -1 #define FAILURE_PID -1 @@ -237,21 +234,13 @@ out: void init_new_thread_signals(void) { - set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); - set_handler(SIGTRAP, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); - set_handler(SIGFPE, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); - set_handler(SIGILL, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); - set_handler(SIGBUS, (__sighandler_t) sig_handler, SA_ONSTACK, - SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); + set_handler(SIGSEGV); + set_handler(SIGTRAP); + set_handler(SIGFPE); + set_handler(SIGILL); + set_handler(SIGBUS); signal(SIGHUP, SIG_IGN); - - set_handler(SIGIO, (__sighandler_t) sig_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, - SIGVTALRM, -1); + set_handler(SIGIO); signal(SIGWINCH, SIG_IGN); signal(SIGTERM, SIG_DFL); } diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 63d299d..3c16121 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -11,14 +11,11 @@ #include <sched.h> #include <signal.h> #include <string.h> -#include "kern_constants.h" #include "kern_util.h" #include "init.h" #include "os.h" -#include "process.h" #include "sigio.h" #include "um_malloc.h" -#include "user.h" /* * Protected by sigio_lock(), also used by sigio_cleanup, which is an diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 6ae1807..2d22f1f 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -12,13 +12,7 @@ #include "as-layout.h" #include "kern_util.h" #include "os.h" -#include "process.h" -#include "sysdep/barrier.h" -#include "sysdep/sigcontext.h" -#include "user.h" - -/* Copied from linux/compiler-gcc.h since we can't include it directly */ -#define barrier() __asm__ __volatile__("": : :"memory") +#include "sysdep/mcontext.h" void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { [SIGTRAP] = relay_signal, @@ -30,7 +24,7 @@ void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { [SIGIO] = sigio_handler, [SIGVTALRM] = timer_handler }; -static void sig_handler_common(int sig, struct sigcontext *sc) +static void sig_handler_common(int sig, mcontext_t *mc) { struct uml_pt_regs r; int save_errno = errno; @@ -38,8 +32,8 @@ static void sig_handler_common(int sig, struct sigcontext *sc) r.is_user = 0; if (sig == SIGSEGV) { /* For segfaults, we want the data from the sigcontext. */ - copy_sc(&r, sc); - GET_FAULTINFO_FROM_SC(r.faultinfo, sc); + get_regs_from_mc(&r, mc); + GET_FAULTINFO_FROM_MC(r.faultinfo, mc); } /* enable signals if sig isn't IRQ signal */ @@ -66,7 +60,7 @@ static void sig_handler_common(int sig, struct sigcontext *sc) static int signals_enabled; static unsigned int signals_pending; -void sig_handler(int sig, struct sigcontext *sc) +void sig_handler(int sig, mcontext_t *mc) { int enabled; @@ -78,23 +72,23 @@ void sig_handler(int sig, struct sigcontext *sc) block_signals(); - sig_handler_common(sig, sc); + sig_handler_common(sig, mc); set_signals(enabled); } -static void real_alarm_handler(struct sigcontext *sc) +static void real_alarm_handler(mcontext_t *mc) { struct uml_pt_regs regs; - if (sc != NULL) - copy_sc(®s, sc); + if (mc != NULL) + get_regs_from_mc(®s, mc); regs.is_user = 0; unblock_signals(); timer_handler(SIGVTALRM, ®s); } -void alarm_handler(int sig, struct sigcontext *sc) +void alarm_handler(int sig, mcontext_t *mc) { int enabled; @@ -106,14 +100,13 @@ void alarm_handler(int sig, struct sigcontext *sc) block_signals(); - real_alarm_handler(sc); + real_alarm_handler(mc); set_signals(enabled); } void timer_init(void) { - set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, -1); + set_handler(SIGVTALRM); } void set_sigstack(void *sig_stack, int size) @@ -126,10 +119,23 @@ void set_sigstack(void *sig_stack, int size) panic("enabling signal stack failed, errno = %d\n", errno); } -static void (*handlers[_NSIG])(int sig, struct sigcontext *sc); +static void (*handlers[_NSIG])(int sig, mcontext_t *mc) = { + [SIGSEGV] = sig_handler, + [SIGBUS] = sig_handler, + [SIGILL] = sig_handler, + [SIGFPE] = sig_handler, + [SIGTRAP] = sig_handler, + + [SIGIO] = sig_handler, + [SIGWINCH] = sig_handler, + [SIGVTALRM] = alarm_handler +}; + -void handle_signal(int sig, struct sigcontext *sc) +static void hard_handler(int sig, siginfo_t *info, void *p) { + struct ucontext *uc = p; + mcontext_t *mc = &uc->uc_mcontext; unsigned long pending = 1UL << sig; do { @@ -155,7 +161,7 @@ void handle_signal(int sig, struct sigcontext *sc) while ((sig = ffs(pending)) != 0){ sig--; pending &= ~(1 << sig); - (*handlers[sig])(sig, sc); + (*handlers[sig])(sig, mc); } /* @@ -169,28 +175,26 @@ void handle_signal(int sig, struct sigcontext *sc) } while (pending); } -extern void hard_handler(int sig); - -void set_handler(int sig, void (*handler)(int), int flags, ...) +void set_handler(int sig) { struct sigaction action; - va_list ap; + int flags = SA_SIGINFO | SA_ONSTACK; sigset_t sig_mask; - int mask; - handlers[sig] = (void (*)(int, struct sigcontext *)) handler; - action.sa_handler = hard_handler; + action.sa_sigaction = hard_handler; + /* block irq ones */ sigemptyset(&action.sa_mask); - - va_start(ap, flags); - while ((mask = va_arg(ap, int)) != -1) - sigaddset(&action.sa_mask, mask); - va_end(ap); + sigaddset(&action.sa_mask, SIGVTALRM); + sigaddset(&action.sa_mask, SIGIO); + sigaddset(&action.sa_mask, SIGWINCH); if (sig == SIGSEGV) flags |= SA_NODEFER; + if (sigismember(&action.sa_mask, sig)) + flags |= SA_RESTART; /* if it's an irq signal */ + action.sa_flags = flags; action.sa_restorer = NULL; if (sigaction(sig, &action, NULL) < 0) diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index e771398..c0afff7 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -9,7 +9,6 @@ #include <string.h> #include <sys/mman.h> #include "init.h" -#include "kern_constants.h" #include "as-layout.h" #include "mm_id.h" #include "os.h" @@ -17,7 +16,6 @@ #include "ptrace_user.h" #include "registers.h" #include "skas.h" -#include "user.h" #include "sysdep/ptrace.h" #include "sysdep/stub.h" diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index dee0e8c..cd65727 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -9,31 +9,23 @@ #include <errno.h> #include <string.h> #include <sys/mman.h> -#include <sys/ptrace.h> #include <sys/wait.h> #include <asm/unistd.h> #include "as-layout.h" -#include "chan_user.h" -#include "kern_constants.h" +#include "init.h" #include "kern_util.h" #include "mem.h" #include "os.h" -#include "process.h" #include "proc_mm.h" #include "ptrace_user.h" #include "registers.h" #include "skas.h" #include "skas_ptrace.h" -#include "user.h" #include "sysdep/stub.h" int is_skas_winch(int pid, int fd, void *data) { - if (pid != getpgrp()) - return 0; - - register_winch_irq(-1, fd, -1, data, 0); - return 1; + return pid == getpgrp(); } static int ptrace_dump_regs(int pid) @@ -169,7 +161,7 @@ static void handle_trap(int pid, struct uml_pt_regs *regs, if (!local_using_sysemu) { - err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, + err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); if (err < 0) { printk(UM_KERN_ERR "handle_trap - nullifying syscall " @@ -257,8 +249,8 @@ static int userspace_tramp(void *stack) set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE); sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_ONSTACK | SA_NODEFER; - sa.sa_handler = (void *) v; + sa.sa_flags = SA_ONSTACK | SA_NODEFER | SA_SIGINFO; + sa.sa_sigaction = (void *) v; sa.sa_restorer = NULL; if (sigaction(SIGSEGV, &sa, NULL) < 0) { printk(UM_KERN_ERR "userspace_tramp - setting SIGSEGV " @@ -661,8 +653,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) { int n; - set_handler(SIGWINCH, (__sighandler_t) sig_handler, - SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGVTALRM, -1); + set_handler(SIGWINCH); /* * Can't use UML_SETJMP or UML_LONGJMP here because they save diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 02ee9ad..425162e 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -13,12 +13,10 @@ #include <signal.h> #include <string.h> #include <sys/mman.h> -#include <sys/ptrace.h> #include <sys/stat.h> #include <sys/wait.h> #include <asm/unistd.h> #include "init.h" -#include "kern_constants.h" #include "os.h" #include "mem_user.h" #include "ptrace_user.h" @@ -225,7 +223,7 @@ static void __init check_sysemu(void) goto fail; } - n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); if (n < 0) { non_fatal("check_sysemu : failed to modify system call " "return"); @@ -261,7 +259,7 @@ static void __init check_sysemu(void) "doesn't singlestep"); goto fail; } - n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); if (n < 0) fatal_perror("check_sysemu : failed to modify " @@ -317,10 +315,10 @@ static void __init check_ptrace(void) fatal("check_ptrace : expected (SIGTRAP|0x80), " "got status = %d", status); - syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET, + syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET, 0); if (syscall == __NR_getpid) { - n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getppid); if (n < 0) fatal_perror("check_ptrace : failed to modify " diff --git a/arch/um/os-Linux/sys-i386/signal.c b/arch/um/os-Linux/sys-i386/signal.c deleted file mode 100644 index f311609..0000000 --- a/arch/um/os-Linux/sys-i386/signal.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <signal.h> - -extern void handle_signal(int sig, struct sigcontext *sc); - -void hard_handler(int sig) -{ - handle_signal(sig, (struct sigcontext *) (&sig + 1)); -} diff --git a/arch/um/os-Linux/sys-x86_64/Makefile b/arch/um/os-Linux/sys-x86_64/Makefile deleted file mode 100644 index a44a47f..0000000 --- a/arch/um/os-Linux/sys-x86_64/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) -# Licensed under the GPL -# - -obj-y = registers.o prctl.o signal.o task_size.o - -USER_OBJS := $(obj-y) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c deleted file mode 100644 index 594d97a..0000000 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2006 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <errno.h> -#include <sys/ptrace.h> -#define __FRAME_OFFSETS -#include <asm/ptrace.h> -#include "kern_constants.h" -#include "longjmp.h" -#include "user.h" - -int save_fp_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -int restore_fp_registers(int pid, unsigned long *fp_regs) -{ - if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) - return -errno; - return 0; -} - -unsigned long get_thread_reg(int reg, jmp_buf *buf) -{ - switch (reg) { - case RIP: - return buf[0]->__rip; - case RSP: - return buf[0]->__rsp; - case RBP: - return buf[0]->__rbp; - default: - printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", - reg); - return 0; - } -} - -int get_fp_registers(int pid, unsigned long *regs) -{ - return save_fp_registers(pid, regs); -} - -int put_fp_registers(int pid, unsigned long *regs) -{ - return restore_fp_registers(pid, regs); -} diff --git a/arch/um/os-Linux/sys-x86_64/signal.c b/arch/um/os-Linux/sys-x86_64/signal.c deleted file mode 100644 index 82a3888..0000000 --- a/arch/um/os-Linux/sys-x86_64/signal.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <signal.h> - -extern void handle_signal(int sig, struct sigcontext *sc); - -void hard_handler(int sig) -{ - struct ucontext *uc; - asm("movq %%rdx, %0" : "=r" (uc)); - - handle_signal(sig, (struct sigcontext *) &uc->uc_mcontext); -} diff --git a/arch/um/os-Linux/sys-x86_64/task_size.c b/arch/um/os-Linux/sys-x86_64/task_size.c deleted file mode 100644 index 26a0dd1..0000000 --- a/arch/um/os-Linux/sys-x86_64/task_size.c +++ /dev/null @@ -1,5 +0,0 @@ -unsigned long os_get_top_address(unsigned long shift) -{ - /* The old value of CONFIG_TOP_ADDR */ - return 0x7fc0000000; -} diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 6e3359d..910499d 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -8,11 +8,9 @@ #include <signal.h> #include <time.h> #include <sys/time.h> -#include "kern_constants.h" #include "kern_util.h" #include "os.h" -#include "process.h" -#include "user.h" +#include "internal.h" int set_interval(void) { diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c deleted file mode 100644 index 73277801..0000000 --- a/arch/um/os-Linux/tls.c +++ /dev/null @@ -1,35 +0,0 @@ -#include <errno.h> -#include <sys/ptrace.h> -#include "sysdep/tls.h" - -/* TLS support - we basically rely on the host's one.*/ - -#ifndef PTRACE_GET_THREAD_AREA -#define PTRACE_GET_THREAD_AREA 25 -#endif - -#ifndef PTRACE_SET_THREAD_AREA -#define PTRACE_SET_THREAD_AREA 26 -#endif - -int os_set_thread_area(user_desc_t *info, int pid) -{ - int ret; - - ret = ptrace(PTRACE_SET_THREAD_AREA, pid, info->entry_number, - (unsigned long) info); - if (ret < 0) - ret = -errno; - return ret; -} - -int os_get_thread_area(user_desc_t *info, int pid) -{ - int ret; - - ret = ptrace(PTRACE_GET_THREAD_AREA, pid, info->entry_number, - (unsigned long) info); - if (ret < 0) - ret = -errno; - return ret; -} diff --git a/arch/um/os-Linux/tty.c b/arch/um/os-Linux/tty.c index b09ff66..dd12b99 100644 --- a/arch/um/os-Linux/tty.c +++ b/arch/um/os-Linux/tty.c @@ -7,10 +7,8 @@ #include <unistd.h> #include <errno.h> #include <fcntl.h> -#include "kern_constants.h" #include "kern_util.h" #include "os.h" -#include "user.h" struct grantpt_info { int fd; diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c deleted file mode 100644 index 087ed74..0000000 --- a/arch/um/os-Linux/uaccess.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk) - * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <stddef.h> -#include "longjmp.h" - -unsigned long __do_user_copy(void *to, const void *from, int n, - void **fault_addr, jmp_buf **fault_catcher, - void (*op)(void *to, const void *from, - int n), int *faulted_out) -{ - unsigned long *faddrp = (unsigned long *) fault_addr, ret; - - jmp_buf jbuf; - *fault_catcher = &jbuf; - if (UML_SETJMP(&jbuf) == 0) { - (*op)(to, from, n); - ret = 0; - *faulted_out = 0; - } - else { - ret = *faddrp; - *faulted_out = 1; - } - *fault_addr = NULL; - *fault_catcher = NULL; - return ret; -} - diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index a27defb..4832eb5 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c @@ -13,9 +13,7 @@ #include <unistd.h> #include <sys/stat.h> #include "init.h" -#include "kern_constants.h" #include "os.h" -#include "user.h" #define UML_DIR "~/.uml/" diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 5803b18..9e3b43b 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -13,9 +13,7 @@ #include <wait.h> #include <sys/mman.h> #include <sys/utsname.h> -#include "kern_constants.h" #include "os.h" -#include "user.h" void stack_protections(unsigned long address) { diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 61107b6..2eb2843 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -8,7 +8,7 @@ USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) $(USER_OBJS:.o=.%): \ - c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(basetarget).o) + c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include user.h $(CFLAGS_$(basetarget).o) $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF) @@ -25,8 +25,3 @@ $(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ define unprofile $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) endef - -ifdef subarch-obj-y -obj-y += subarch.o -subarch-y = $(addprefix ../../$(HEADER_ARCH)/,$(subarch-obj-y)) -endif diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile deleted file mode 100644 index 3923cfb..0000000 --- a/arch/um/sys-i386/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) -# - -obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ - ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ - sys_call_table.o tls.o atomic64_cx8_32.o mem.o - -obj-$(CONFIG_BINFMT_ELF) += elfcore.o - -subarch-obj-y = lib/string_32.o -subarch-obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += lib/rwsem.o -subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o -subarch-obj-$(CONFIG_MODULES) += kernel/module.o - -USER_OBJS := bugs.o ptrace_user.o fault.o - -USER_OBJS += user-offsets.s -extra-y += user-offsets.s - -UNPROFILE_OBJS := stub_segv.o -CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/sys-i386/asm/elf.h b/arch/um/sys-i386/asm/elf.h deleted file mode 100644 index 4230555..0000000 --- a/arch/um/sys-i386/asm/elf.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ -#ifndef __UM_ELF_I386_H -#define __UM_ELF_I386_H - -#include <asm/user.h> -#include "skas.h" - -#define R_386_NONE 0 -#define R_386_32 1 -#define R_386_PC32 2 -#define R_386_GOT32 3 -#define R_386_PLT32 4 -#define R_386_COPY 5 -#define R_386_GLOB_DAT 6 -#define R_386_JMP_SLOT 7 -#define R_386_RELATIVE 8 -#define R_386_GOTOFF 9 -#define R_386_GOTPC 10 -#define R_386_NUM 11 - -typedef unsigned long elf_greg_t; - -#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef struct user_i387_struct elf_fpregset_t; - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) \ - (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) - -#define ELF_CLASS ELFCLASS32 -#define ELF_DATA ELFDATA2LSB -#define ELF_ARCH EM_386 - -#define ELF_PLAT_INIT(regs, load_addr) do { \ - PT_REGS_EBX(regs) = 0; \ - PT_REGS_ECX(regs) = 0; \ - PT_REGS_EDX(regs) = 0; \ - PT_REGS_ESI(regs) = 0; \ - PT_REGS_EDI(regs) = 0; \ - PT_REGS_EBP(regs) = 0; \ - PT_REGS_EAX(regs) = 0; \ -} while (0) - -#define ELF_EXEC_PAGESIZE 4096 - -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) - -/* Shamelessly stolen from include/asm-i386/elf.h */ - -#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ - pr_reg[0] = PT_REGS_EBX(regs); \ - pr_reg[1] = PT_REGS_ECX(regs); \ - pr_reg[2] = PT_REGS_EDX(regs); \ - pr_reg[3] = PT_REGS_ESI(regs); \ - pr_reg[4] = PT_REGS_EDI(regs); \ - pr_reg[5] = PT_REGS_EBP(regs); \ - pr_reg[6] = PT_REGS_EAX(regs); \ - pr_reg[7] = PT_REGS_DS(regs); \ - pr_reg[8] = PT_REGS_ES(regs); \ - /* fake once used fs and gs selectors? */ \ - pr_reg[9] = PT_REGS_DS(regs); \ - pr_reg[10] = PT_REGS_DS(regs); \ - pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \ - pr_reg[12] = PT_REGS_IP(regs); \ - pr_reg[13] = PT_REGS_CS(regs); \ - pr_reg[14] = PT_REGS_EFLAGS(regs); \ - pr_reg[15] = PT_REGS_SP(regs); \ - pr_reg[16] = PT_REGS_SS(regs); \ -} while (0); - -#define task_pt_regs(t) (&(t)->thread.regs) - -struct task_struct; - -extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu); - -#define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu) - -extern long elf_aux_hwcap; -#define ELF_HWCAP (elf_aux_hwcap) - -extern char * elf_aux_platform; -#define ELF_PLATFORM (elf_aux_platform) - -#define SET_PERSONALITY(ex) do { } while (0) - -extern unsigned long vsyscall_ehdr; -extern unsigned long vsyscall_end; -extern unsigned long __kernel_vsyscall; - -#define VSYSCALL_BASE vsyscall_ehdr -#define VSYSCALL_END vsyscall_end - -/* - * This is the range that is readable by user mode, and things - * acting like user mode such as get_user_pages. - */ -#define FIXADDR_USER_START VSYSCALL_BASE -#define FIXADDR_USER_END VSYSCALL_END - -#define __HAVE_ARCH_GATE_AREA 1 - -/* - * Architecture-neutral AT_ values in 0-17, leave some room - * for more of them, start the x86-specific ones at 32. - */ -#define AT_SYSINFO 32 -#define AT_SYSINFO_EHDR 33 - -#define ARCH_DLINFO \ -do { \ - if ( vsyscall_ehdr ) { \ - NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall); \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr); \ - } \ -} while (0) - -#endif diff --git a/arch/um/sys-i386/asm/module.h b/arch/um/sys-i386/asm/module.h deleted file mode 100644 index 5ead4a0..0000000 --- a/arch/um/sys-i386/asm/module.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __UM_MODULE_I386_H -#define __UM_MODULE_I386_H - -/* UML is simple */ -struct mod_arch_specific -{ -}; - -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr - -#endif diff --git a/arch/um/sys-i386/atomic64_cx8_32.S b/arch/um/sys-i386/atomic64_cx8_32.S deleted file mode 100644 index 1e901d3..0000000 --- a/arch/um/sys-i386/atomic64_cx8_32.S +++ /dev/null @@ -1,225 +0,0 @@ -/* - * atomic64_t for 586+ - * - * Copied from arch/x86/lib/atomic64_cx8_32.S - * - * Copyright © 2010 Luca Barbieri - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include <linux/linkage.h> -#include <asm/alternative-asm.h> -#include <asm/dwarf2.h> - -.macro SAVE reg - pushl_cfi %\reg - CFI_REL_OFFSET \reg, 0 -.endm - -.macro RESTORE reg - popl_cfi %\reg - CFI_RESTORE \reg -.endm - -.macro read64 reg - movl %ebx, %eax - movl %ecx, %edx -/* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */ - LOCK_PREFIX - cmpxchg8b (\reg) -.endm - -ENTRY(atomic64_read_cx8) - CFI_STARTPROC - - read64 %ecx - ret - CFI_ENDPROC -ENDPROC(atomic64_read_cx8) - -ENTRY(atomic64_set_cx8) - CFI_STARTPROC - -1: -/* we don't need LOCK_PREFIX since aligned 64-bit writes - * are atomic on 586 and newer */ - cmpxchg8b (%esi) - jne 1b - - ret - CFI_ENDPROC -ENDPROC(atomic64_set_cx8) - -ENTRY(atomic64_xchg_cx8) - CFI_STARTPROC - - movl %ebx, %eax - movl %ecx, %edx -1: - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - - ret - CFI_ENDPROC -ENDPROC(atomic64_xchg_cx8) - -.macro addsub_return func ins insc -ENTRY(atomic64_\func\()_return_cx8) - CFI_STARTPROC - SAVE ebp - SAVE ebx - SAVE esi - SAVE edi - - movl %eax, %esi - movl %edx, %edi - movl %ecx, %ebp - - read64 %ebp -1: - movl %eax, %ebx - movl %edx, %ecx - \ins\()l %esi, %ebx - \insc\()l %edi, %ecx - LOCK_PREFIX - cmpxchg8b (%ebp) - jne 1b - -10: - movl %ebx, %eax - movl %ecx, %edx - RESTORE edi - RESTORE esi - RESTORE ebx - RESTORE ebp - ret - CFI_ENDPROC -ENDPROC(atomic64_\func\()_return_cx8) -.endm - -addsub_return add add adc -addsub_return sub sub sbb - -.macro incdec_return func ins insc -ENTRY(atomic64_\func\()_return_cx8) - CFI_STARTPROC - SAVE ebx - - read64 %esi -1: - movl %eax, %ebx - movl %edx, %ecx - \ins\()l $1, %ebx - \insc\()l $0, %ecx - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - -10: - movl %ebx, %eax - movl %ecx, %edx - RESTORE ebx - ret - CFI_ENDPROC -ENDPROC(atomic64_\func\()_return_cx8) -.endm - -incdec_return inc add adc -incdec_return dec sub sbb - -ENTRY(atomic64_dec_if_positive_cx8) - CFI_STARTPROC - SAVE ebx - - read64 %esi -1: - movl %eax, %ebx - movl %edx, %ecx - subl $1, %ebx - sbb $0, %ecx - js 2f - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - -2: - movl %ebx, %eax - movl %ecx, %edx - RESTORE ebx - ret - CFI_ENDPROC -ENDPROC(atomic64_dec_if_positive_cx8) - -ENTRY(atomic64_add_unless_cx8) - CFI_STARTPROC - SAVE ebp - SAVE ebx -/* these just push these two parameters on the stack */ - SAVE edi - SAVE esi - - movl %ecx, %ebp - movl %eax, %esi - movl %edx, %edi - - read64 %ebp -1: - cmpl %eax, 0(%esp) - je 4f -2: - movl %eax, %ebx - movl %edx, %ecx - addl %esi, %ebx - adcl %edi, %ecx - LOCK_PREFIX - cmpxchg8b (%ebp) - jne 1b - - movl $1, %eax -3: - addl $8, %esp - CFI_ADJUST_CFA_OFFSET -8 - RESTORE ebx - RESTORE ebp - ret -4: - cmpl %edx, 4(%esp) - jne 2b - xorl %eax, %eax - jmp 3b - CFI_ENDPROC -ENDPROC(atomic64_add_unless_cx8) - -ENTRY(atomic64_inc_not_zero_cx8) - CFI_STARTPROC - SAVE ebx - - read64 %esi -1: - testl %eax, %eax - je 4f -2: - movl %eax, %ebx - movl %edx, %ecx - addl $1, %ebx - adcl $0, %ecx - LOCK_PREFIX - cmpxchg8b (%esi) - jne 1b - - movl $1, %eax -3: - RESTORE ebx - ret -4: - testl %edx, %edx - jne 2b - jmp 3b - CFI_ENDPROC -ENDPROC(atomic64_inc_not_zero_cx8) diff --git a/arch/um/sys-i386/bug.c b/arch/um/sys-i386/bug.c deleted file mode 100644 index 8d4f273..0000000 --- a/arch/um/sys-i386/bug.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL V2 - */ - -#include <linux/uaccess.h> -#include <asm/errno.h> - -/* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because - * that's not relevant in skas mode. - */ - -int is_valid_bugaddr(unsigned long eip) -{ - unsigned short ud2; - - if (probe_kernel_address((unsigned short __user *)eip, ud2)) - return 0; - - return ud2 == 0x0b0f; -} diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c deleted file mode 100644 index bfbefd3..0000000 --- a/arch/um/sys-i386/ksyms.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "linux/module.h" -#include "asm/checksum.h" - -/* Networking helper routines. */ -EXPORT_SYMBOL(csum_partial); diff --git a/arch/um/sys-i386/shared/sysdep/barrier.h b/arch/um/sys-i386/shared/sysdep/barrier.h deleted file mode 100644 index b58d52c..0000000 --- a/arch/um/sys-i386/shared/sysdep/barrier.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __SYSDEP_I386_BARRIER_H -#define __SYSDEP_I386_BARRIER_H - -/* Copied from include/asm-i386 for use by userspace. i386 has the option - * of using mfence, but I'm just using this, which works everywhere, for now. - */ -#define mb() asm volatile("lock; addl $0,0(%esp)") - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/host_ldt.h b/arch/um/sys-i386/shared/sysdep/host_ldt.h deleted file mode 100644 index 0953cc4..0000000 --- a/arch/um/sys-i386/shared/sysdep/host_ldt.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __ASM_HOST_LDT_I386_H -#define __ASM_HOST_LDT_I386_H - -#include <asm/ldt.h> - -/* - * macros stolen from include/asm-i386/desc.h - */ -#define LDT_entry_a(info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) - -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - 0x7000) - -#define LDT_empty(info) (\ - (info)->base_addr == 0 && \ - (info)->limit == 0 && \ - (info)->contents == 0 && \ - (info)->read_exec_only == 1 && \ - (info)->seg_32bit == 0 && \ - (info)->limit_in_pages == 0 && \ - (info)->seg_not_present == 1 && \ - (info)->useable == 0 ) - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/ptrace_user.h b/arch/um/sys-i386/shared/sysdep/ptrace_user.h deleted file mode 100644 index ef56247..0000000 --- a/arch/um/sys-i386/shared/sysdep/ptrace_user.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_I386_PTRACE_USER_H__ -#define __SYSDEP_I386_PTRACE_USER_H__ - -#include <sys/ptrace.h> -#include <linux/ptrace.h> -#include <asm/ptrace.h> -#include "user_constants.h" - -#define PT_OFFSET(r) ((r) * sizeof(long)) - -#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX]) -#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX) - -#define PT_SYSCALL_ARG1_OFFSET PT_OFFSET(EBX) -#define PT_SYSCALL_ARG2_OFFSET PT_OFFSET(ECX) -#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX) -#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI) -#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI) -#define PT_SYSCALL_ARG6_OFFSET PT_OFFSET(EBP) - -#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX) - -#define REGS_SYSCALL_NR EAX /* This is used before a system call */ -#define REGS_SYSCALL_ARG1 EBX -#define REGS_SYSCALL_ARG2 ECX -#define REGS_SYSCALL_ARG3 EDX -#define REGS_SYSCALL_ARG4 ESI -#define REGS_SYSCALL_ARG5 EDI -#define REGS_SYSCALL_ARG6 EBP - -#define REGS_IP_INDEX EIP -#define REGS_SP_INDEX UESP - -#define PT_IP_OFFSET PT_OFFSET(EIP) -#define PT_IP(regs) ((regs)[EIP]) -#define PT_SP_OFFSET PT_OFFSET(UESP) -#define PT_SP(regs) ((regs)[UESP]) - -#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE) - -#ifndef FRAME_SIZE -#define FRAME_SIZE (17) -#endif - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/sc.h b/arch/um/sys-i386/shared/sysdep/sc.h deleted file mode 100644 index c57d178..0000000 --- a/arch/um/sys-i386/shared/sysdep/sc.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __SYSDEP_I386_SC_H -#define __SYSDEP_I386_SC_H - -#include <user_constants.h> - -#define SC_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (sc))[HOST_##field])) -#define SC_FP_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[HOST_##field])) -#define SC_FP_OFFSET_PTR(sc, field, type) \ - ((type *) &(((char *) (SC_FPSTATE(sc)))[HOST_##field])) - -#define SC_IP(sc) SC_OFFSET(sc, SC_IP) -#define SC_SP(sc) SC_OFFSET(sc, SC_SP) -#define SC_FS(sc) SC_OFFSET(sc, SC_FS) -#define SC_GS(sc) SC_OFFSET(sc, SC_GS) -#define SC_DS(sc) SC_OFFSET(sc, SC_DS) -#define SC_ES(sc) SC_OFFSET(sc, SC_ES) -#define SC_SS(sc) SC_OFFSET(sc, SC_SS) -#define SC_CS(sc) SC_OFFSET(sc, SC_CS) -#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS) -#define SC_EAX(sc) SC_OFFSET(sc, SC_EAX) -#define SC_EBX(sc) SC_OFFSET(sc, SC_EBX) -#define SC_ECX(sc) SC_OFFSET(sc, SC_ECX) -#define SC_EDX(sc) SC_OFFSET(sc, SC_EDX) -#define SC_EDI(sc) SC_OFFSET(sc, SC_EDI) -#define SC_ESI(sc) SC_OFFSET(sc, SC_ESI) -#define SC_EBP(sc) SC_OFFSET(sc, SC_EBP) -#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) -#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) -#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) -#define SC_FPSTATE(sc) SC_OFFSET(sc, SC_FPSTATE) -#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK) -#define SC_FP_CW(sc) SC_FP_OFFSET(sc, SC_FP_CW) -#define SC_FP_SW(sc) SC_FP_OFFSET(sc, SC_FP_SW) -#define SC_FP_TAG(sc) SC_FP_OFFSET(sc, SC_FP_TAG) -#define SC_FP_IPOFF(sc) SC_FP_OFFSET(sc, SC_FP_IPOFF) -#define SC_FP_CSSEL(sc) SC_FP_OFFSET(sc, SC_FP_CSSEL) -#define SC_FP_DATAOFF(sc) SC_FP_OFFSET(sc, SC_FP_DATAOFF) -#define SC_FP_DATASEL(sc) SC_FP_OFFSET(sc, SC_FP_DATASEL) -#define SC_FP_ST(sc) SC_FP_OFFSET_PTR(sc, SC_FP_ST, struct _fpstate) -#define SC_FXSR_ENV(sc) SC_FP_OFFSET_PTR(sc, SC_FXSR_ENV, void) - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/sigcontext.h b/arch/um/sys-i386/shared/sysdep/sigcontext.h deleted file mode 100644 index f583c87..0000000 --- a/arch/um/sys-i386/shared/sysdep/sigcontext.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __SYS_SIGCONTEXT_I386_H -#define __SYS_SIGCONTEXT_I386_H - -#include "sysdep/sc.h" - -#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) - -#define GET_FAULTINFO_FROM_SC(fi, sc) \ - { \ - (fi).cr2 = SC_CR2(sc); \ - (fi).error_code = SC_ERR(sc); \ - (fi).trap_no = SC_TRAPNO(sc); \ - } - -/* This is Page Fault */ -#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) - -/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ -#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) - -#endif diff --git a/arch/um/sys-i386/shared/sysdep/vm-flags.h b/arch/um/sys-i386/shared/sysdep/vm-flags.h deleted file mode 100644 index e0d24c5..0000000 --- a/arch/um/sys-i386/shared/sysdep/vm-flags.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL - */ - -#ifndef __VM_FLAGS_I386_H -#define __VM_FLAGS_I386_H - -#define VM_DATA_DEFAULT_FLAGS \ - (VM_READ | VM_WRITE | \ - ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -#endif diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c deleted file mode 100644 index 28ccf73..0000000 --- a/arch/um/sys-i386/stub_segv.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include "sysdep/stub.h" -#include "sysdep/sigcontext.h" - -void __attribute__ ((__section__ (".__syscall_stub"))) -stub_segv_handler(int sig) -{ - struct sigcontext *sc = (struct sigcontext *) (&sig + 1); - - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc); - - trap_myself(); -} diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c deleted file mode 100644 index 5f883bf..0000000 --- a/arch/um/sys-i386/user-offsets.c +++ /dev/null @@ -1,53 +0,0 @@ -#include <stdio.h> -#include <stddef.h> -#include <signal.h> -#include <sys/poll.h> -#include <sys/user.h> -#include <sys/mman.h> -#include <asm/ptrace.h> - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define DEFINE_LONGS(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) - -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); - -void foo(void) -{ - OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); - OFFSET(HOST_SC_ERR, sigcontext, err); - OFFSET(HOST_SC_CR2, sigcontext, cr2); - - DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct)); - DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct)); - - DEFINE(HOST_IP, EIP); - DEFINE(HOST_SP, UESP); - DEFINE(HOST_EFLAGS, EFL); - DEFINE(HOST_EAX, EAX); - DEFINE(HOST_EBX, EBX); - DEFINE(HOST_ECX, ECX); - DEFINE(HOST_EDX, EDX); - DEFINE(HOST_ESI, ESI); - DEFINE(HOST_EDI, EDI); - DEFINE(HOST_EBP, EBP); - DEFINE(HOST_CS, CS); - DEFINE(HOST_SS, SS); - DEFINE(HOST_DS, DS); - DEFINE(HOST_FS, FS); - DEFINE(HOST_ES, ES); - DEFINE(HOST_GS, GS); - DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); - - /* XXX Duplicated between i386 and x86_64 */ - DEFINE(UM_POLLIN, POLLIN); - DEFINE(UM_POLLPRI, POLLPRI); - DEFINE(UM_POLLOUT, POLLOUT); - - DEFINE(UM_PROT_READ, PROT_READ); - DEFINE(UM_PROT_WRITE, PROT_WRITE); - DEFINE(UM_PROT_EXEC, PROT_EXEC); -} diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile deleted file mode 100644 index bd4d1d3..0000000 --- a/arch/um/sys-x86_64/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright 2003 PathScale, Inc. -# -# Licensed under the GPL -# - -obj-y = bug.o bugs.o delay.o fault.o ldt.o ptrace.o ptrace_user.o mem.o \ - setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \ - sysrq.o ksyms.o tls.o - -obj-y += vdso/ - -subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \ - lib/rwsem.o -subarch-obj-$(CONFIG_MODULES) += kernel/module.o - -ldt-y = ../sys-i386/ldt.o - -USER_OBJS := ptrace_user.o - -USER_OBJS += user-offsets.s -extra-y += user-offsets.s - -UNPROFILE_OBJS := stub_segv.o -CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) - -include arch/um/scripts/Makefile.rules diff --git a/arch/um/sys-x86_64/asm/archparam.h b/arch/um/sys-x86_64/asm/archparam.h deleted file mode 100644 index 6c08366..0000000 --- a/arch/um/sys-x86_64/asm/archparam.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_ARCHPARAM_X86_64_H -#define __UM_ARCHPARAM_X86_64_H - - -/* No user-accessible fixmap addresses, i.e. vsyscall */ -#define FIXADDR_USER_START 0 -#define FIXADDR_USER_END 0 - -#endif - diff --git a/arch/um/sys-x86_64/asm/module.h b/arch/um/sys-x86_64/asm/module.h deleted file mode 100644 index 8eb79c2..0000000 --- a/arch/um/sys-x86_64/asm/module.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __UM_MODULE_X86_64_H -#define __UM_MODULE_X86_64_H - -/* UML is simple */ -struct mod_arch_specific -{ -}; - -#define Elf_Shdr Elf64_Shdr -#define Elf_Sym Elf64_Sym -#define Elf_Ehdr Elf64_Ehdr - -#endif - diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c deleted file mode 100644 index f3fe1a6..0000000 --- a/arch/um/sys-x86_64/delay.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2011 Richard Weinberger <richrd@nod.at> - * Mostly copied from arch/x86/lib/delay.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <asm/param.h> - -void __delay(unsigned long loops) -{ - asm volatile( - "test %0,%0\n" - "jz 3f\n" - "jmp 1f\n" - - ".align 16\n" - "1: jmp 2f\n" - - ".align 16\n" - "2: dec %0\n" - " jnz 2b\n" - "3: dec %0\n" - - : /* we don't need output */ - : "a" (loops) - ); -} -EXPORT_SYMBOL(__delay); - -inline void __const_udelay(unsigned long xloops) -{ - int d0; - - xloops *= 4; - asm("mull %%edx" - : "=d" (xloops), "=&a" (d0) - : "1" (xloops), "0" - (loops_per_jiffy * (HZ/4))); - - __delay(++xloops); -} -EXPORT_SYMBOL(__const_udelay); - -void __udelay(unsigned long usecs) -{ - __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ -} -EXPORT_SYMBOL(__udelay); - -void __ndelay(unsigned long nsecs) -{ - __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ -} -EXPORT_SYMBOL(__ndelay); diff --git a/arch/um/sys-x86_64/fault.c b/arch/um/sys-x86_64/fault.c deleted file mode 100644 index ce85117..0000000 --- a/arch/um/sys-x86_64/fault.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include "sysdep/ptrace.h" - -/* These two are from asm-um/uaccess.h and linux/module.h, check them. */ -struct exception_table_entry -{ - unsigned long insn; - unsigned long fixup; -}; - -const struct exception_table_entry *search_exception_tables(unsigned long add); - -int arch_fixup(unsigned long address, struct uml_pt_regs *regs) -{ - const struct exception_table_entry *fixup; - - fixup = search_exception_tables(address); - if (fixup != 0) { - UPT_IP(regs) = fixup->fixup; - return 1; - } - return 0; -} diff --git a/arch/um/sys-x86_64/ptrace_user.c b/arch/um/sys-x86_64/ptrace_user.c deleted file mode 100644 index c57a496..0000000 --- a/arch/um/sys-x86_64/ptrace_user.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#include <errno.h> -#include "ptrace_user.h" - -int ptrace_getregs(long pid, unsigned long *regs_out) -{ - if (ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0) - return -errno; - return(0); -} - -int ptrace_setregs(long pid, unsigned long *regs_out) -{ - if (ptrace(PTRACE_SETREGS, pid, 0, regs_out) < 0) - return -errno; - return(0); -} diff --git a/arch/um/sys-x86_64/shared/sysdep/barrier.h b/arch/um/sys-x86_64/shared/sysdep/barrier.h deleted file mode 100644 index 7b610be..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/barrier.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __SYSDEP_X86_64_BARRIER_H -#define __SYSDEP_X86_64_BARRIER_H - -/* Copied from include/asm-x86_64 for use by userspace. */ -#define mb() asm volatile("mfence":::"memory") - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/host_ldt.h b/arch/um/sys-x86_64/shared/sysdep/host_ldt.h deleted file mode 100644 index e8b1be1..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/host_ldt.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __ASM_HOST_LDT_X86_64_H -#define __ASM_HOST_LDT_X86_64_H - -#include <asm/ldt.h> - -/* - * macros stolen from include/asm-x86_64/desc.h - */ -#define LDT_entry_a(info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) - -/* Don't allow setting of the lm bit. It is useless anyways because - * 64bit system calls require __USER_CS. */ -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - /* ((info)->lm << 21) | */ \ - 0x7000) - -#define LDT_empty(info) (\ - (info)->base_addr == 0 && \ - (info)->limit == 0 && \ - (info)->contents == 0 && \ - (info)->read_exec_only == 1 && \ - (info)->seg_32bit == 0 && \ - (info)->limit_in_pages == 0 && \ - (info)->seg_not_present == 1 && \ - (info)->useable == 0 && \ - (info)->lm == 0) - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h b/arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h deleted file mode 100644 index a307237..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/kernel-offsets.h +++ /dev/null @@ -1,23 +0,0 @@ -#include <linux/stddef.h> -#include <linux/sched.h> -#include <linux/time.h> -#include <linux/elf.h> -#include <linux/crypto.h> -#include <asm/page.h> -#include <asm/mman.h> - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -#define DEFINE_STR1(x) #x -#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " DEFINE_STR1(val) " " #val: : ) - -#define BLANK() asm volatile("\n->" : : ) - -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); - -void foo(void) -{ -#include <common-offsets.h> -} diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h b/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h deleted file mode 100644 index 4dbccdb..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/ptrace_user.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_PTRACE_USER_H__ -#define __SYSDEP_X86_64_PTRACE_USER_H__ - -#define __FRAME_OFFSETS -#include <sys/ptrace.h> -#include <linux/ptrace.h> -#include <asm/ptrace.h> -#undef __FRAME_OFFSETS -#include "user_constants.h" - -#define PT_INDEX(off) ((off) / sizeof(unsigned long)) - -#define PT_SYSCALL_NR(regs) ((regs)[PT_INDEX(ORIG_RAX)]) -#define PT_SYSCALL_NR_OFFSET (ORIG_RAX) - -#define PT_SYSCALL_ARG1(regs) (((unsigned long *) (regs))[PT_INDEX(RDI)]) -#define PT_SYSCALL_ARG1_OFFSET (RDI) - -#define PT_SYSCALL_ARG2(regs) (((unsigned long *) (regs))[PT_INDEX(RSI)]) -#define PT_SYSCALL_ARG2_OFFSET (RSI) - -#define PT_SYSCALL_ARG3(regs) (((unsigned long *) (regs))[PT_INDEX(RDX)]) -#define PT_SYSCALL_ARG3_OFFSET (RDX) - -#define PT_SYSCALL_ARG4(regs) (((unsigned long *) (regs))[PT_INDEX(RCX)]) -#define PT_SYSCALL_ARG4_OFFSET (RCX) - -#define PT_SYSCALL_ARG5(regs) (((unsigned long *) (regs))[PT_INDEX(R8)]) -#define PT_SYSCALL_ARG5_OFFSET (R8) - -#define PT_SYSCALL_ARG6(regs) (((unsigned long *) (regs))[PT_INDEX(R9)]) -#define PT_SYSCALL_ARG6_OFFSET (R9) - -#define PT_SYSCALL_RET_OFFSET (RAX) - -#define PT_IP_OFFSET (RIP) -#define PT_IP(regs) ((regs)[PT_INDEX(RIP)]) - -#define PT_SP_OFFSET (RSP) -#define PT_SP(regs) ((regs)[PT_INDEX(RSP)]) - -#define PT_ORIG_RAX_OFFSET (ORIG_RAX) -#define PT_ORIG_RAX(regs) ((regs)[PT_INDEX(ORIG_RAX)]) - -/* - * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though - * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the - * 2.4 name and value for 2.4 host compatibility. - */ -#ifndef PTRACE_OLDSETOPTIONS -#define PTRACE_OLDSETOPTIONS 21 -#endif - -/* - * These are before the system call, so the system call number is RAX - * rather than ORIG_RAX, and arg4 is R10 rather than RCX - */ -#define REGS_SYSCALL_NR PT_INDEX(RAX) -#define REGS_SYSCALL_ARG1 PT_INDEX(RDI) -#define REGS_SYSCALL_ARG2 PT_INDEX(RSI) -#define REGS_SYSCALL_ARG3 PT_INDEX(RDX) -#define REGS_SYSCALL_ARG4 PT_INDEX(R10) -#define REGS_SYSCALL_ARG5 PT_INDEX(R8) -#define REGS_SYSCALL_ARG6 PT_INDEX(R9) - -#define REGS_IP_INDEX PT_INDEX(RIP) -#define REGS_SP_INDEX PT_INDEX(RSP) - -#define FP_SIZE (HOST_FP_SIZE) - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/sc.h b/arch/um/sys-x86_64/shared/sysdep/sc.h deleted file mode 100644 index 8aee45b..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/sc.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __SYSDEP_X86_64_SC_H -#define __SYSDEP_X86_64_SC_H - -/* Copyright (C) 2003 - 2004 PathScale, Inc - * Released under the GPL - */ - -#include <user_constants.h> - -#define SC_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (sc))[HOST_##field])) - -#define SC_RBX(sc) SC_OFFSET(sc, SC_RBX) -#define SC_RCX(sc) SC_OFFSET(sc, SC_RCX) -#define SC_RDX(sc) SC_OFFSET(sc, SC_RDX) -#define SC_RSI(sc) SC_OFFSET(sc, SC_RSI) -#define SC_RDI(sc) SC_OFFSET(sc, SC_RDI) -#define SC_RBP(sc) SC_OFFSET(sc, SC_RBP) -#define SC_RAX(sc) SC_OFFSET(sc, SC_RAX) -#define SC_R8(sc) SC_OFFSET(sc, SC_R8) -#define SC_R9(sc) SC_OFFSET(sc, SC_R9) -#define SC_R10(sc) SC_OFFSET(sc, SC_R10) -#define SC_R11(sc) SC_OFFSET(sc, SC_R11) -#define SC_R12(sc) SC_OFFSET(sc, SC_R12) -#define SC_R13(sc) SC_OFFSET(sc, SC_R13) -#define SC_R14(sc) SC_OFFSET(sc, SC_R14) -#define SC_R15(sc) SC_OFFSET(sc, SC_R15) -#define SC_IP(sc) SC_OFFSET(sc, SC_IP) -#define SC_SP(sc) SC_OFFSET(sc, SC_SP) -#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) -#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) -#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) -#define SC_CS(sc) SC_OFFSET(sc, SC_CS) -#define SC_FS(sc) SC_OFFSET(sc, SC_FS) -#define SC_GS(sc) SC_OFFSET(sc, SC_GS) -#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS) -#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK) -#define SC_SS(sc) SC_OFFSET(sc, SC_SS) -#if 0 -#define SC_ORIG_RAX(sc) SC_OFFSET(sc, SC_ORIG_RAX) -#define SC_DS(sc) SC_OFFSET(sc, SC_DS) -#define SC_ES(sc) SC_OFFSET(sc, SC_ES) -#endif - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/sigcontext.h b/arch/um/sys-x86_64/shared/sysdep/sigcontext.h deleted file mode 100644 index 0155133..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/sigcontext.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_SIGCONTEXT_H -#define __SYSDEP_X86_64_SIGCONTEXT_H - -#include <sysdep/sc.h> - -#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) - -#define GET_FAULTINFO_FROM_SC(fi, sc) \ - { \ - (fi).cr2 = SC_CR2(sc); \ - (fi).error_code = SC_ERR(sc); \ - (fi).trap_no = SC_TRAPNO(sc); \ - } - -/* This is Page Fault */ -#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) - -/* No broken SKAS API, which doesn't pass trap_no, here. */ -#define SEGV_MAYBE_FIXABLE(fi) 0 - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h b/arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h deleted file mode 100644 index 95db4be7..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/skas_ptrace.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_SKAS_PTRACE_H -#define __SYSDEP_X86_64_SKAS_PTRACE_H - -struct ptrace_faultinfo { - int is_write; - unsigned long addr; -}; - -struct ptrace_ldt { - int func; - void *ptr; - unsigned long bytecount; -}; - -#define PTRACE_LDT 54 - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/system.h b/arch/um/sys-x86_64/shared/sysdep/system.h deleted file mode 100644 index d1b93c4..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/system.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef _ASM_X86_SYSTEM_H_ -#define _ASM_X86_SYSTEM_H_ - -#include <asm/asm.h> -#include <asm/segment.h> -#include <asm/cpufeature.h> -#include <asm/cmpxchg.h> -#include <asm/nops.h> - -#include <linux/kernel.h> -#include <linux/irqflags.h> - -/* entries in ARCH_DLINFO: */ -#ifdef CONFIG_IA32_EMULATION -# define AT_VECTOR_SIZE_ARCH 2 -#else -# define AT_VECTOR_SIZE_ARCH 1 -#endif - -extern unsigned long arch_align_stack(unsigned long sp); - -void default_idle(void); - -/* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. - */ -#ifdef CONFIG_X86_32 -/* - * Some non-Intel clones support out of order store. wmb() ceases to be a - * nop for these. - */ -#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) -#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) -#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) -#else -#define mb() asm volatile("mfence":::"memory") -#define rmb() asm volatile("lfence":::"memory") -#define wmb() asm volatile("sfence" ::: "memory") -#endif - -/** - * read_barrier_depends - Flush all pending reads that subsequents reads - * depend on. - * - * No data-dependent reads from memory-like regions are ever reordered - * over this barrier. All reads preceding this primitive are guaranteed - * to access memory (but not necessarily other CPUs' caches) before any - * reads following this primitive that depend on the data return by - * any of the preceding reads. This primitive is much lighter weight than - * rmb() on most CPUs, and is never heavier weight than is - * rmb(). - * - * These ordering constraints are respected by both the local CPU - * and the compiler. - * - * Ordering is not guaranteed by anything other than these primitives, - * not even by data dependencies. See the documentation for - * memory_barrier() for examples and URLs to more information. - * - * For example, the following code would force ordering (the initial - * value of "a" is zero, "b" is one, and "p" is "&a"): - * - * <programlisting> - * CPU 0 CPU 1 - * - * b = 2; - * memory_barrier(); - * p = &b; q = p; - * read_barrier_depends(); - * d = *q; - * </programlisting> - * - * because the read of "*q" depends on the read of "p" and these - * two reads are separated by a read_barrier_depends(). However, - * the following code, with the same initial values for "a" and "b": - * - * <programlisting> - * CPU 0 CPU 1 - * - * a = 2; - * memory_barrier(); - * b = 3; y = b; - * read_barrier_depends(); - * x = a; - * </programlisting> - * - * does not enforce ordering, since there is no data dependency between - * the read of "a" and the read of "b". Therefore, on some CPUs, such - * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() - * in cases like this where there are no data dependencies. - **/ - -#define read_barrier_depends() do { } while (0) - -#ifdef CONFIG_SMP -#define smp_mb() mb() -#ifdef CONFIG_X86_PPRO_FENCE -# define smp_rmb() rmb() -#else -# define smp_rmb() barrier() -#endif -#ifdef CONFIG_X86_OOSTORE -# define smp_wmb() wmb() -#else -# define smp_wmb() barrier() -#endif -#define smp_read_barrier_depends() read_barrier_depends() -#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while (0) -#define set_mb(var, value) do { var = value; barrier(); } while (0) -#endif - -/* - * Stop RDTSC speculation. This is needed when you need to use RDTSC - * (or get_cycles or vread that possibly accesses the TSC) in a defined - * code region. - * - * (Could use an alternative three way for this if there was one.) - */ -static inline void rdtsc_barrier(void) -{ - alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); - alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); -} - -#endif diff --git a/arch/um/sys-x86_64/shared/sysdep/tls.h b/arch/um/sys-x86_64/shared/sysdep/tls.h deleted file mode 100644 index 18c000d..0000000 --- a/arch/um/sys-x86_64/shared/sysdep/tls.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _SYSDEP_TLS_H -#define _SYSDEP_TLS_H - -# ifndef __KERNEL__ - -/* Change name to avoid conflicts with the original one from <asm/ldt.h>, which - * may be named user_desc (but in 2.4 and in header matching its API was named - * modify_ldt_ldt_s). */ - -typedef struct um_dup_user_desc { - unsigned int entry_number; - unsigned int base_addr; - unsigned int limit; - unsigned int seg_32bit:1; - unsigned int contents:2; - unsigned int read_exec_only:1; - unsigned int limit_in_pages:1; - unsigned int seg_not_present:1; - unsigned int useable:1; - unsigned int lm:1; -} user_desc_t; - -# else /* __KERNEL__ */ - -# include <ldt.h> -typedef struct user_desc user_desc_t; - -# endif /* __KERNEL__ */ -#endif /* _SYSDEP_TLS_H */ diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c deleted file mode 100644 index b6b65c7..0000000 --- a/arch/um/sys-x86_64/signal.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (C) 2003 PathScale, Inc. - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#include <linux/personality.h> -#include <linux/ptrace.h> -#include <linux/kernel.h> -#include <asm/unistd.h> -#include <asm/uaccess.h> -#include <asm/ucontext.h> -#include "frame_kern.h" -#include "skas.h" - -void copy_sc(struct uml_pt_regs *regs, void *from) -{ - struct sigcontext *sc = from; - -#define GETREG(regs, regno, sc, regname) \ - (regs)->gp[(regno) / sizeof(unsigned long)] = (sc)->regname - - GETREG(regs, R8, sc, r8); - GETREG(regs, R9, sc, r9); - GETREG(regs, R10, sc, r10); - GETREG(regs, R11, sc, r11); - GETREG(regs, R12, sc, r12); - GETREG(regs, R13, sc, r13); - GETREG(regs, R14, sc, r14); - GETREG(regs, R15, sc, r15); - GETREG(regs, RDI, sc, di); - GETREG(regs, RSI, sc, si); - GETREG(regs, RBP, sc, bp); - GETREG(regs, RBX, sc, bx); - GETREG(regs, RDX, sc, dx); - GETREG(regs, RAX, sc, ax); - GETREG(regs, RCX, sc, cx); - GETREG(regs, RSP, sc, sp); - GETREG(regs, RIP, sc, ip); - GETREG(regs, EFLAGS, sc, flags); - GETREG(regs, CS, sc, cs); - -#undef GETREG -} - -static int copy_sc_from_user(struct pt_regs *regs, - struct sigcontext __user *from, - struct _fpstate __user *fpp) -{ - struct user_i387_struct fp; - int err = 0; - -#define GETREG(regs, regno, sc, regname) \ - __get_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \ - &(sc)->regname) - - err |= GETREG(regs, R8, from, r8); - err |= GETREG(regs, R9, from, r9); - err |= GETREG(regs, R10, from, r10); - err |= GETREG(regs, R11, from, r11); - err |= GETREG(regs, R12, from, r12); - err |= GETREG(regs, R13, from, r13); - err |= GETREG(regs, R14, from, r14); - err |= GETREG(regs, R15, from, r15); - err |= GETREG(regs, RDI, from, di); - err |= GETREG(regs, RSI, from, si); - err |= GETREG(regs, RBP, from, bp); - err |= GETREG(regs, RBX, from, bx); - err |= GETREG(regs, RDX, from, dx); - err |= GETREG(regs, RAX, from, ax); - err |= GETREG(regs, RCX, from, cx); - err |= GETREG(regs, RSP, from, sp); - err |= GETREG(regs, RIP, from, ip); - err |= GETREG(regs, EFLAGS, from, flags); - err |= GETREG(regs, CS, from, cs); - if (err) - return 1; - -#undef GETREG - - err = copy_from_user(&fp, fpp, sizeof(struct user_i387_struct)); - if (err) - return 1; - - err = restore_fp_registers(userspace_pid[current_thread_info()->cpu], - (unsigned long *) &fp); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - " - "restore_fp_registers failed, errno = %d\n", - -err); - return 1; - } - - return 0; -} - -static int copy_sc_to_user(struct sigcontext __user *to, - struct _fpstate __user *to_fp, struct pt_regs *regs, - unsigned long mask, unsigned long sp) -{ - struct faultinfo * fi = ¤t->thread.arch.faultinfo; - struct user_i387_struct fp; - int err = 0; - - err |= __put_user(0, &to->gs); - err |= __put_user(0, &to->fs); - -#define PUTREG(regs, regno, sc, regname) \ - __put_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \ - &(sc)->regname) - - err |= PUTREG(regs, RDI, to, di); - err |= PUTREG(regs, RSI, to, si); - err |= PUTREG(regs, RBP, to, bp); - /* - * Must use original RSP, which is passed in, rather than what's in - * the pt_regs, because that's already been updated to point at the - * signal frame. - */ - err |= __put_user(sp, &to->sp); - err |= PUTREG(regs, RBX, to, bx); - err |= PUTREG(regs, RDX, to, dx); - err |= PUTREG(regs, RCX, to, cx); - err |= PUTREG(regs, RAX, to, ax); - err |= PUTREG(regs, R8, to, r8); - err |= PUTREG(regs, R9, to, r9); - err |= PUTREG(regs, R10, to, r10); - err |= PUTREG(regs, R11, to, r11); - err |= PUTREG(regs, R12, to, r12); - err |= PUTREG(regs, R13, to, r13); - err |= PUTREG(regs, R14, to, r14); - err |= PUTREG(regs, R15, to, r15); - err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */ - - err |= __put_user(fi->cr2, &to->cr2); - err |= __put_user(fi->error_code, &to->err); - err |= __put_user(fi->trap_no, &to->trapno); - - err |= PUTREG(regs, RIP, to, ip); - err |= PUTREG(regs, EFLAGS, to, flags); -#undef PUTREG - - err |= __put_user(mask, &to->oldmask); - if (err) - return 1; - - err = save_fp_registers(userspace_pid[current_thread_info()->cpu], - (unsigned long *) &fp); - if (err < 0) { - printk(KERN_ERR "copy_sc_from_user - restore_fp_registers " - "failed, errno = %d\n", -err); - return 1; - } - - if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct))) - return 1; - - return err; -} - -struct rt_sigframe -{ - char __user *pretcode; - struct ucontext uc; - struct siginfo info; - struct _fpstate fpstate; -}; - -int setup_signal_stack_si(unsigned long stack_top, int sig, - struct k_sigaction *ka, struct pt_regs * regs, - siginfo_t *info, sigset_t *set) -{ - struct rt_sigframe __user *frame; - unsigned long save_sp = PT_REGS_RSP(regs); - int err = 0; - struct task_struct *me = current; - - frame = (struct rt_sigframe __user *) - round_down(stack_top - sizeof(struct rt_sigframe), 16); - /* Subtract 128 for a red zone and 8 for proper alignment */ - frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8); - - if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) - goto out; - - if (ka->sa.sa_flags & SA_SIGINFO) { - err |= copy_siginfo_to_user(&frame->info, info); - if (err) - goto out; - } - - /* - * Update SP now because the page fault handler refuses to extend - * the stack if the faulting address is too far below the current - * SP, which frame now certainly is. If there's an error, the original - * value is restored on the way out. - * When writing the sigcontext to the stack, we have to write the - * original value, so that's passed to copy_sc_to_user, which does - * the right thing with it. - */ - PT_REGS_RSP(regs) = (unsigned long) frame; - - /* Create the ucontext. */ - err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(0, &frame->uc.uc_link); - err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); - err |= __put_user(sas_ss_flags(save_sp), - &frame->uc.uc_stack.ss_flags); - err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs, - set->sig[0], save_sp); - err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate); - if (sizeof(*set) == 16) { - __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); - __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); - } - else - err |= __copy_to_user(&frame->uc.uc_sigmask, set, - sizeof(*set)); - - /* - * Set up to return from userspace. If provided, use a stub - * already in userspace. - */ - /* x86-64 should always use SA_RESTORER. */ - if (ka->sa.sa_flags & SA_RESTORER) - err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); - else - /* could use a vstub here */ - goto restore_sp; - - if (err) - goto restore_sp; - - /* Set up registers for signal handler */ - { - struct exec_domain *ed = current_thread_info()->exec_domain; - if (unlikely(ed && ed->signal_invmap && sig < 32)) - sig = ed->signal_invmap[sig]; - } - - PT_REGS_RDI(regs) = sig; - /* In case the signal handler was declared without prototypes */ - PT_REGS_RAX(regs) = 0; - - /* - * This also works for non SA_SIGINFO handlers because they expect the - * next argument after the signal number on the stack. - */ - PT_REGS_RSI(regs) = (unsigned long) &frame->info; - PT_REGS_RDX(regs) = (unsigned long) &frame->uc; - PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler; - out: - return err; - -restore_sp: - PT_REGS_RSP(regs) = save_sp; - return err; -} - -long sys_rt_sigreturn(struct pt_regs *regs) -{ - unsigned long sp = PT_REGS_SP(¤t->thread.regs); - struct rt_sigframe __user *frame = - (struct rt_sigframe __user *)(sp - 8); - struct ucontext __user *uc = &frame->uc; - sigset_t set; - - if (copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) - goto segfault; - - sigdelsetmask(&set, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext, - &frame->fpstate)) - goto segfault; - - /* Avoid ERESTART handling */ - PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return PT_REGS_SYSCALL_RET(¤t->thread.regs); - - segfault: - force_sig(SIGSEGV, current); - return 0; -} diff --git a/arch/um/Makefile-i386 b/arch/x86/Makefile.um index 302cbe5..36ddec6 100644 --- a/arch/um/Makefile-i386 +++ b/arch/x86/Makefile.um @@ -1,14 +1,11 @@ -core-y += arch/um/sys-i386/ arch/x86/crypto/ - -TOP_ADDR := $(CONFIG_TOP_ADDR) +core-y += arch/x86/crypto/ +ifeq ($(CONFIG_X86_32),y) START := 0x8048000 LDFLAGS += -m elf_i386 -ELF_ARCH := $(SUBARCH) -ELF_FORMAT := elf32-$(SUBARCH) -OBJCOPYFLAGS := -O binary -R .note -R .comment -S -HEADER_ARCH := x86 +ELF_ARCH := i386 +ELF_FORMAT := elf32-i386 CHECKFLAGS += -D__i386__ ifeq ("$(origin SUBARCH)", "command line") @@ -16,9 +13,8 @@ ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)") KBUILD_CFLAGS += $(call cc-option,-m32) KBUILD_AFLAGS += $(call cc-option,-m32) LINK-y += $(call cc-option,-m32) -UML_OBJCOPYFLAGS += -F $(ELF_FORMAT) -export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS +export LDFLAGS endif endif @@ -40,3 +36,26 @@ KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \ else echo $(call cc-option,-funit-at-a-time); fi ;) KBUILD_CFLAGS += $(cflags-y) + +else + +START := 0x60000000 + +KBUILD_CFLAGS += -fno-builtin -m64 + +CHECKFLAGS += -m64 -D__x86_64__ +KBUILD_AFLAGS += -m64 +LDFLAGS += -m elf_x86_64 +KBUILD_CPPFLAGS += -m64 + +ELF_ARCH := i386:x86-64 +ELF_FORMAT := elf64-x86-64 + +# Not on all 64-bit distros /lib is a symlink to /lib64. PLD is an example. + +LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64 +LINK-y += -m64 + +# Do unit-at-a-time unconditionally on x86_64, following the host +KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time) +endif diff --git a/arch/um/Kconfig.x86 b/arch/x86/um/Kconfig index 21bebe6..21bebe6 100644 --- a/arch/um/Kconfig.x86 +++ b/arch/x86/um/Kconfig diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile new file mode 100644 index 0000000..8fb5840 --- /dev/null +++ b/arch/x86/um/Makefile @@ -0,0 +1,45 @@ +# +# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) +# + +ifeq ($(CONFIG_X86_32),y) + BITS := 32 +else + BITS := 64 +endif + +obj-y = bug.o bugs_$(BITS).o delay.o fault.o ksyms.o ldt.o \ + ptrace_$(BITS).o ptrace_user.o setjmp_$(BITS).o signal.o \ + stub_$(BITS).o stub_segv.o syscalls_$(BITS).o \ + sys_call_table_$(BITS).o sysrq_$(BITS).o tls_$(BITS).o \ + mem_$(BITS).o subarch.o os-$(OS)/ + +ifeq ($(CONFIG_X86_32),y) + +obj-y += checksum_32.o +obj-$(CONFIG_BINFMT_ELF) += elfcore.o + +subarch-y = ../lib/string_32.o ../lib/atomic64_32.o ../lib/atomic64_cx8_32.o +subarch-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += ../lib/rwsem.o +subarch-$(CONFIG_HIGHMEM) += ../mm/highmem_32.o + +else + +obj-y += vdso/ + +subarch-y = ../lib/csum-partial_64.o ../lib/memcpy_64.o ../lib/thunk_64.o \ + ../lib/rwsem.o + +endif + +subarch-$(CONFIG_MODULES) += ../kernel/module.o + +USER_OBJS := bugs_$(BITS).o ptrace_user.o fault.o + +extra-y += user-offsets.s +$(obj)/user-offsets.s: c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) + +UNPROFILE_OBJS := stub_segv.o +CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) + +include arch/um/scripts/Makefile.rules diff --git a/arch/um/include/asm/apic.h b/arch/x86/um/asm/apic.h index 876dee8..876dee8 100644 --- a/arch/um/include/asm/apic.h +++ b/arch/x86/um/asm/apic.h diff --git a/arch/um/include/asm/arch_hweight.h b/arch/x86/um/asm/arch_hweight.h index c656cf4..c656cf4 100644 --- a/arch/um/include/asm/arch_hweight.h +++ b/arch/x86/um/asm/arch_hweight.h diff --git a/arch/um/sys-i386/asm/archparam.h b/arch/x86/um/asm/archparam.h index 2a18a88..c17cf68 100644 --- a/arch/um/sys-i386/asm/archparam.h +++ b/arch/x86/um/asm/archparam.h @@ -1,10 +1,13 @@ /* * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) + * Copyright 2003 PathScale, Inc. * Licensed under the GPL */ -#ifndef __UM_ARCHPARAM_I386_H -#define __UM_ARCHPARAM_I386_H +#ifndef __UM_ARCHPARAM_H +#define __UM_ARCHPARAM_H + +#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_PAE #define LAST_PKMAP 512 @@ -14,3 +17,4 @@ #endif +#endif diff --git a/arch/x86/um/asm/checksum.h b/arch/x86/um/asm/checksum.h new file mode 100644 index 0000000..b6efe23 --- /dev/null +++ b/arch/x86/um/asm/checksum.h @@ -0,0 +1,10 @@ +#ifndef __UM_CHECKSUM_H +#define __UM_CHECKSUM_H + +#ifdef CONFIG_X86_32 +# include "checksum_32.h" +#else +# include "checksum_64.h" +#endif + +#endif diff --git a/arch/um/sys-i386/shared/sysdep/checksum.h b/arch/x86/um/asm/checksum_32.h index ed47445..caab742 100644 --- a/arch/um/sys-i386/shared/sysdep/checksum.h +++ b/arch/x86/um/asm/checksum_32.h @@ -1,4 +1,4 @@ -/* +/* * Licensed under the GPL */ diff --git a/arch/um/sys-x86_64/shared/sysdep/checksum.h b/arch/x86/um/asm/checksum_64.h index a5be903..a5be903 100644 --- a/arch/um/sys-x86_64/shared/sysdep/checksum.h +++ b/arch/x86/um/asm/checksum_64.h diff --git a/arch/um/include/asm/desc.h b/arch/x86/um/asm/desc.h index 4ec34a5..4ec34a5 100644 --- a/arch/um/include/asm/desc.h +++ b/arch/x86/um/asm/desc.h diff --git a/arch/um/sys-x86_64/asm/elf.h b/arch/x86/um/asm/elf.h index 11a2bfb..f3b0633 100644 --- a/arch/um/sys-x86_64/asm/elf.h +++ b/arch/x86/um/asm/elf.h @@ -1,15 +1,103 @@ /* - * Copyright 2003 PathScale, Inc. - * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ -#ifndef __UM_ELF_X86_64_H -#define __UM_ELF_X86_64_H +#ifndef __UM_ELF_X86_H +#define __UM_ELF_X86_H #include <asm/user.h> #include "skas.h" +#ifdef CONFIG_X86_32 + +#define R_386_NONE 0 +#define R_386_32 1 +#define R_386_PC32 2 +#define R_386_GOT32 3 +#define R_386_PLT32 4 +#define R_386_COPY 5 +#define R_386_GLOB_DAT 6 +#define R_386_JMP_SLOT 7 +#define R_386_RELATIVE 8 +#define R_386_GOTOFF 9 +#define R_386_GOTPC 10 +#define R_386_NUM 11 + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) \ + (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) + +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2LSB +#define ELF_ARCH EM_386 + +#define ELF_PLAT_INIT(regs, load_addr) do { \ + PT_REGS_EBX(regs) = 0; \ + PT_REGS_ECX(regs) = 0; \ + PT_REGS_EDX(regs) = 0; \ + PT_REGS_ESI(regs) = 0; \ + PT_REGS_EDI(regs) = 0; \ + PT_REGS_EBP(regs) = 0; \ + PT_REGS_EAX(regs) = 0; \ +} while (0) + +/* Shamelessly stolen from include/asm-i386/elf.h */ + +#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ + pr_reg[0] = PT_REGS_EBX(regs); \ + pr_reg[1] = PT_REGS_ECX(regs); \ + pr_reg[2] = PT_REGS_EDX(regs); \ + pr_reg[3] = PT_REGS_ESI(regs); \ + pr_reg[4] = PT_REGS_EDI(regs); \ + pr_reg[5] = PT_REGS_EBP(regs); \ + pr_reg[6] = PT_REGS_EAX(regs); \ + pr_reg[7] = PT_REGS_DS(regs); \ + pr_reg[8] = PT_REGS_ES(regs); \ + /* fake once used fs and gs selectors? */ \ + pr_reg[9] = PT_REGS_DS(regs); \ + pr_reg[10] = PT_REGS_DS(regs); \ + pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \ + pr_reg[12] = PT_REGS_IP(regs); \ + pr_reg[13] = PT_REGS_CS(regs); \ + pr_reg[14] = PT_REGS_EFLAGS(regs); \ + pr_reg[15] = PT_REGS_SP(regs); \ + pr_reg[16] = PT_REGS_SS(regs); \ +} while (0); + +extern char * elf_aux_platform; +#define ELF_PLATFORM (elf_aux_platform) + +extern unsigned long vsyscall_ehdr; +extern unsigned long vsyscall_end; +extern unsigned long __kernel_vsyscall; + +/* + * This is the range that is readable by user mode, and things + * acting like user mode such as get_user_pages. + */ +#define FIXADDR_USER_START vsyscall_ehdr +#define FIXADDR_USER_END vsyscall_end + + +/* + * Architecture-neutral AT_ values in 0-17, leave some room + * for more of them, start the x86-specific ones at 32. + */ +#define AT_SYSINFO 32 +#define AT_SYSINFO_EHDR 33 + +#define ARCH_DLINFO \ +do { \ + if ( vsyscall_ehdr ) { \ + NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall); \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr); \ + } \ +} while (0) + +#else + /* x86-64 relocation types, taken from asm-x86_64/elf.h */ #define R_X86_64_NONE 0 /* No reloc */ #define R_X86_64_64 1 /* Direct 64 bit */ @@ -31,13 +119,6 @@ #define R_X86_64_NUM 16 -typedef unsigned long elf_greg_t; - -#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef struct user_i387_struct elf_fpregset_t; - /* * This is used to ensure we don't load something for the wrong architecture. */ @@ -95,6 +176,30 @@ typedef struct user_i387_struct elf_fpregset_t; (pr_reg)[25] = 0; \ (pr_reg)[26] = 0; +#define ELF_PLATFORM "x86_64" + +/* No user-accessible fixmap addresses, i.e. vsyscall */ +#define FIXADDR_USER_START 0 +#define FIXADDR_USER_END 0 + +#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 +struct linux_binprm; +extern int arch_setup_additional_pages(struct linux_binprm *bprm, + int uses_interp); + +extern unsigned long um_vdso_addr; +#define AT_SYSINFO_EHDR 33 +#define ARCH_DLINFO NEW_AUX_ENT(AT_SYSINFO_EHDR, um_vdso_addr) + +#endif + +typedef unsigned long elf_greg_t; + +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef struct user_i387_struct elf_fpregset_t; + #define task_pt_regs(t) (&(t)->thread.regs) struct task_struct; @@ -103,11 +208,6 @@ extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu); #define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu) -#ifdef TIF_IA32 /* XXX */ -#error XXX, indeed - clear_thread_flag(TIF_IA32); -#endif - #define ELF_EXEC_PAGESIZE 4096 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) @@ -115,18 +215,7 @@ extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu); extern long elf_aux_hwcap; #define ELF_HWCAP (elf_aux_hwcap) -#define ELF_PLATFORM "x86_64" - #define SET_PERSONALITY(ex) do ; while(0) - #define __HAVE_ARCH_GATE_AREA 1 -#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 -struct linux_binprm; -extern int arch_setup_additional_pages(struct linux_binprm *bprm, - int uses_interp); - -extern unsigned long um_vdso_addr; -#define AT_SYSINFO_EHDR 33 -#define ARCH_DLINFO NEW_AUX_ENT(AT_SYSINFO_EHDR, um_vdso_addr) #endif diff --git a/arch/um/include/asm/irq_vectors.h b/arch/x86/um/asm/irq_vectors.h index 272a81e..272a81e 100644 --- a/arch/um/include/asm/irq_vectors.h +++ b/arch/x86/um/asm/irq_vectors.h diff --git a/arch/x86/um/asm/mm_context.h b/arch/x86/um/asm/mm_context.h new file mode 100644 index 0000000..4a73d63 --- /dev/null +++ b/arch/x86/um/asm/mm_context.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2004 Fujitsu Siemens Computers GmbH + * Licensed under the GPL + * + * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com> + */ + +#ifndef __ASM_LDT_H +#define __ASM_LDT_H + +#include <linux/mutex.h> +#include <asm/ldt.h> + +extern void ldt_host_info(void); + +#define LDT_PAGES_MAX \ + ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE) +#define LDT_ENTRIES_PER_PAGE \ + (PAGE_SIZE/LDT_ENTRY_SIZE) +#define LDT_DIRECT_ENTRIES \ + ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE) + +struct ldt_entry { + __u32 a; + __u32 b; +}; + +typedef struct uml_ldt { + int entry_count; + struct mutex lock; + union { + struct ldt_entry * pages[LDT_PAGES_MAX]; + struct ldt_entry entries[LDT_DIRECT_ENTRIES]; + } u; +} uml_ldt_t; + +#define LDT_entry_a(info) \ + ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) + +#define LDT_entry_b(info) \ + (((info)->base_addr & 0xff000000) | \ + (((info)->base_addr & 0x00ff0000) >> 16) | \ + ((info)->limit & 0xf0000) | \ + (((info)->read_exec_only ^ 1) << 9) | \ + ((info)->contents << 10) | \ + (((info)->seg_not_present ^ 1) << 15) | \ + ((info)->seg_32bit << 22) | \ + ((info)->limit_in_pages << 23) | \ + ((info)->useable << 20) | \ + 0x7000) + +#define _LDT_empty(info) (\ + (info)->base_addr == 0 && \ + (info)->limit == 0 && \ + (info)->contents == 0 && \ + (info)->read_exec_only == 1 && \ + (info)->seg_32bit == 0 && \ + (info)->limit_in_pages == 0 && \ + (info)->seg_not_present == 1 && \ + (info)->useable == 0 ) + +#ifdef CONFIG_X86_64 +#define LDT_empty(info) (_LDT_empty(info) && ((info)->lm == 0)) +#else +#define LDT_empty(info) (_LDT_empty(info)) +#endif + +struct uml_arch_mm_context { + uml_ldt_t ldt; +}; + +#endif diff --git a/arch/x86/um/asm/module.h b/arch/x86/um/asm/module.h new file mode 100644 index 0000000..61af80e --- /dev/null +++ b/arch/x86/um/asm/module.h @@ -0,0 +1,23 @@ +#ifndef __UM_MODULE_H +#define __UM_MODULE_H + +/* UML is simple */ +struct mod_arch_specific +{ +}; + +#ifdef CONFIG_X86_32 + +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr + +#else + +#define Elf_Shdr Elf64_Shdr +#define Elf_Sym Elf64_Sym +#define Elf_Ehdr Elf64_Ehdr + +#endif + +#endif diff --git a/arch/x86/um/asm/processor.h b/arch/x86/um/asm/processor.h new file mode 100644 index 0000000..118c143 --- /dev/null +++ b/arch/x86/um/asm/processor.h @@ -0,0 +1,22 @@ +#ifndef __UM_PROCESSOR_H +#define __UM_PROCESSOR_H + +/* include faultinfo structure */ +#include <sysdep/faultinfo.h> + +#ifdef CONFIG_X86_32 +# include "processor_32.h" +#else +# include "processor_64.h" +#endif + +#define KSTK_EIP(tsk) KSTK_REG(tsk, HOST_IP) +#define KSTK_ESP(tsk) KSTK_REG(tsk, HOST_IP) +#define KSTK_EBP(tsk) KSTK_REG(tsk, HOST_BP) + +#define ARCH_IS_STACKGROW(address) \ + (address + 65536 + 32 * sizeof(unsigned long) >= UPT_SP(¤t->thread.regs.regs)) + +#include <asm/processor-generic.h> + +#endif diff --git a/arch/um/sys-i386/asm/processor.h b/arch/x86/um/asm/processor_32.h index 82a9061..018f732 100644 --- a/arch/um/sys-i386/asm/processor.h +++ b/arch/x86/um/asm/processor_32.h @@ -6,15 +6,12 @@ #ifndef __UM_PROCESSOR_I386_H #define __UM_PROCESSOR_I386_H -#include "linux/string.h" -#include <sysdep/host_ldt.h> -#include "asm/segment.h" +#include <linux/string.h> +#include <asm/segment.h> +#include <asm/ldt.h> extern int host_has_cmov; -/* include faultinfo structure */ -#include "sysdep/faultinfo.h" - struct uml_tls_struct { struct user_desc tls; unsigned flushed:1; @@ -66,13 +63,4 @@ static inline void rep_nop(void) #define current_text_addr() \ ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; }) -#define ARCH_IS_STACKGROW(address) \ - (address + 32 >= UPT_SP(¤t->thread.regs.regs)) - -#define KSTK_EIP(tsk) KSTK_REG(tsk, EIP) -#define KSTK_ESP(tsk) KSTK_REG(tsk, UESP) -#define KSTK_EBP(tsk) KSTK_REG(tsk, EBP) - -#include "asm/processor-generic.h" - #endif diff --git a/arch/um/sys-x86_64/asm/processor.h b/arch/x86/um/asm/processor_64.h index 875a26a..61de92d 100644 --- a/arch/um/sys-x86_64/asm/processor.h +++ b/arch/x86/um/asm/processor_64.h @@ -7,9 +7,6 @@ #ifndef __UM_PROCESSOR_X86_64_H #define __UM_PROCESSOR_X86_64_H -/* include faultinfo structure */ -#include "sysdep/faultinfo.h" - struct arch_thread { unsigned long debugregs[8]; int debugregs_seq; @@ -45,12 +42,4 @@ static inline void arch_copy_thread(struct arch_thread *from, #define current_text_addr() \ ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; }) -#define ARCH_IS_STACKGROW(address) \ - (address + 128 >= UPT_SP(¤t->thread.regs.regs)) - -#define KSTK_EIP(tsk) KSTK_REG(tsk, RIP) -#define KSTK_ESP(tsk) KSTK_REG(tsk, RSP) - -#include "asm/processor-generic.h" - #endif diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h new file mode 100644 index 0000000..c8aca8c --- /dev/null +++ b/arch/x86/um/asm/ptrace.h @@ -0,0 +1,5 @@ +#ifdef CONFIG_X86_32 +# include "ptrace_32.h" +#else +# include "ptrace_64.h" +#endif diff --git a/arch/um/sys-i386/asm/ptrace.h b/arch/x86/um/asm/ptrace_32.h index 5d2a591..5d2a591 100644 --- a/arch/um/sys-i386/asm/ptrace.h +++ b/arch/x86/um/asm/ptrace_32.h diff --git a/arch/um/sys-x86_64/asm/ptrace.h b/arch/x86/um/asm/ptrace_64.h index 83d8c47..706a0d8 100644 --- a/arch/um/sys-x86_64/asm/ptrace.h +++ b/arch/x86/um/asm/ptrace_64.h @@ -40,7 +40,7 @@ #define PT_REGS_ORIG_RAX(r) UPT_ORIG_RAX(&(r)->regs) #define PT_REGS_RIP(r) UPT_IP(&(r)->regs) -#define PT_REGS_RSP(r) UPT_SP(&(r)->regs) +#define PT_REGS_SP(r) UPT_SP(&(r)->regs) #define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs) diff --git a/arch/um/include/asm/required-features.h b/arch/x86/um/asm/required-features.h index dfb967b..dfb967b 100644 --- a/arch/um/include/asm/required-features.h +++ b/arch/x86/um/asm/required-features.h diff --git a/arch/um/include/asm/segment.h b/arch/x86/um/asm/segment.h index 45183fc..45183fc 100644 --- a/arch/um/include/asm/segment.h +++ b/arch/x86/um/asm/segment.h diff --git a/arch/um/sys-i386/shared/sysdep/system.h b/arch/x86/um/asm/system.h index d1b93c4..a459fd9 100644 --- a/arch/um/sys-i386/shared/sysdep/system.h +++ b/arch/x86/um/asm/system.h @@ -129,4 +129,7 @@ static inline void rdtsc_barrier(void) alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); } +extern void *_switch_to(void *prev, void *next, void *last); +#define switch_to(prev, next, last) prev = _switch_to(prev, next, last) + #endif diff --git a/arch/um/sys-x86_64/shared/sysdep/vm-flags.h b/arch/x86/um/asm/vm-flags.h index 3978e55..7c297e9 100644 --- a/arch/um/sys-x86_64/shared/sysdep/vm-flags.h +++ b/arch/x86/um/asm/vm-flags.h @@ -4,8 +4,17 @@ * Licensed under the GPL */ -#ifndef __VM_FLAGS_X86_64_H -#define __VM_FLAGS_X86_64_H +#ifndef __VM_FLAGS_X86_H +#define __VM_FLAGS_X86_H + +#ifdef CONFIG_X86_32 + +#define VM_DATA_DEFAULT_FLAGS \ + (VM_READ | VM_WRITE | \ + ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#else #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) @@ -13,3 +22,4 @@ VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) #endif +#endif diff --git a/arch/um/sys-x86_64/bug.c b/arch/x86/um/bug.c index e8034e3..e8034e3 100644 --- a/arch/um/sys-x86_64/bug.c +++ b/arch/x86/um/bug.c diff --git a/arch/um/sys-i386/bugs.c b/arch/x86/um/bugs_32.c index 2c6d0d7..a1fba5f 100644 --- a/arch/um/sys-i386/bugs.c +++ b/arch/x86/um/bugs_32.c @@ -4,17 +4,17 @@ */ #include <signal.h> -#include "kern_constants.h" #include "kern_util.h" #include "longjmp.h" -#include "task.h" -#include "user.h" #include "sysdep/ptrace.h" +#include <generated/asm-offsets.h> /* Set during early boot */ static int host_has_cmov = 1; static jmp_buf cmov_test_return; +#define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID])) + static void cmov_sigill_test_handler(int sig) { host_has_cmov = 0; diff --git a/arch/um/sys-x86_64/bugs.c b/arch/x86/um/bugs_64.c index 44e02ba..44e02ba 100644 --- a/arch/um/sys-x86_64/bugs.c +++ b/arch/x86/um/bugs_64.c diff --git a/arch/um/sys-i386/checksum.S b/arch/x86/um/checksum_32.S index f058d2f..f058d2f 100644 --- a/arch/um/sys-i386/checksum.S +++ b/arch/x86/um/checksum_32.S diff --git a/arch/um/sys-i386/delay.c b/arch/x86/um/delay.c index f3fe1a6..f3fe1a6 100644 --- a/arch/um/sys-i386/delay.c +++ b/arch/x86/um/delay.c diff --git a/arch/um/sys-i386/elfcore.c b/arch/x86/um/elfcore.c index 6bb49b6..6bb49b6 100644 --- a/arch/um/sys-i386/elfcore.c +++ b/arch/x86/um/elfcore.c diff --git a/arch/um/sys-i386/fault.c b/arch/x86/um/fault.c index d670f68..d670f68 100644 --- a/arch/um/sys-i386/fault.c +++ b/arch/x86/um/fault.c diff --git a/arch/um/sys-x86_64/ksyms.c b/arch/x86/um/ksyms.c index 1db2fce..2e8f43e 100644 --- a/arch/um/sys-x86_64/ksyms.c +++ b/arch/x86/um/ksyms.c @@ -2,10 +2,12 @@ #include <asm/string.h> #include <asm/checksum.h> +#ifndef CONFIG_X86_32 /*XXX: we need them because they would be exported by x86_64 */ #if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 EXPORT_SYMBOL(memcpy); #else EXPORT_SYMBOL(__memcpy); #endif +#endif EXPORT_SYMBOL(csum_partial); diff --git a/arch/um/sys-i386/ldt.c b/arch/x86/um/ldt.c index 3f2bf20..26b0e39 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/x86/um/ldt.c @@ -137,7 +137,7 @@ static int read_ldt(void __user * ptr, unsigned long bytecount) { int i, err = 0; unsigned long size; - uml_ldt_t * ldt = ¤t->mm->context.ldt; + uml_ldt_t *ldt = ¤t->mm->context.arch.ldt; if (!ldt->entry_count) goto out; @@ -205,7 +205,7 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount) static int write_ldt(void __user * ptr, unsigned long bytecount, int func) { - uml_ldt_t * ldt = ¤t->mm->context.ldt; + uml_ldt_t *ldt = ¤t->mm->context.arch.ldt; struct mm_id * mm_idp = ¤t->mm->context.id; int i, err; struct user_desc ldt_info; @@ -397,7 +397,7 @@ long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm) if (!ptrace_ldt) - mutex_init(&new_mm->ldt.lock); + mutex_init(&new_mm->arch.ldt.lock); if (!from_mm) { memset(&desc, 0, sizeof(desc)); @@ -429,7 +429,7 @@ long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm) break; } } - new_mm->ldt.entry_count = 0; + new_mm->arch.ldt.entry_count = 0; goto out; } @@ -457,26 +457,26 @@ long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm) * i.e., we have to use the stub for modify_ldt, which * can't handle the big read buffer of up to 64kB. */ - mutex_lock(&from_mm->ldt.lock); - if (from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES) - memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries, - sizeof(new_mm->ldt.u.entries)); + mutex_lock(&from_mm->arch.ldt.lock); + if (from_mm->arch.ldt.entry_count <= LDT_DIRECT_ENTRIES) + memcpy(new_mm->arch.ldt.u.entries, from_mm->arch.ldt.u.entries, + sizeof(new_mm->arch.ldt.u.entries)); else { - i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; + i = from_mm->arch.ldt.entry_count / LDT_ENTRIES_PER_PAGE; while (i-->0) { page = __get_free_page(GFP_KERNEL|__GFP_ZERO); if (!page) { err = -ENOMEM; break; } - new_mm->ldt.u.pages[i] = + new_mm->arch.ldt.u.pages[i] = (struct ldt_entry *) page; - memcpy(new_mm->ldt.u.pages[i], - from_mm->ldt.u.pages[i], PAGE_SIZE); + memcpy(new_mm->arch.ldt.u.pages[i], + from_mm->arch.ldt.u.pages[i], PAGE_SIZE); } } - new_mm->ldt.entry_count = from_mm->ldt.entry_count; - mutex_unlock(&from_mm->ldt.lock); + new_mm->arch.ldt.entry_count = from_mm->arch.ldt.entry_count; + mutex_unlock(&from_mm->arch.ldt.lock); } out: @@ -488,12 +488,12 @@ void free_ldt(struct mm_context *mm) { int i; - if (!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES) { - i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; + if (!ptrace_ldt && mm->arch.ldt.entry_count > LDT_DIRECT_ENTRIES) { + i = mm->arch.ldt.entry_count / LDT_ENTRIES_PER_PAGE; while (i-- > 0) - free_page((long) mm->ldt.u.pages[i]); + free_page((long) mm->arch.ldt.u.pages[i]); } - mm->ldt.entry_count = 0; + mm->arch.ldt.entry_count = 0; } int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) diff --git a/arch/um/sys-i386/mem.c b/arch/x86/um/mem_32.c index 639900a..639900a 100644 --- a/arch/um/sys-i386/mem.c +++ b/arch/x86/um/mem_32.c diff --git a/arch/um/sys-x86_64/mem.c b/arch/x86/um/mem_64.c index 5465187..5465187 100644 --- a/arch/um/sys-x86_64/mem.c +++ b/arch/x86/um/mem_64.c diff --git a/arch/um/os-Linux/sys-i386/Makefile b/arch/x86/um/os-Linux/Makefile index b4bc6ac..253bfb8 100644 --- a/arch/um/os-Linux/sys-i386/Makefile +++ b/arch/x86/um/os-Linux/Makefile @@ -3,7 +3,10 @@ # Licensed under the GPL # -obj-y = registers.o signal.o task_size.o tls.o +obj-y = registers.o task_size.o mcontext.o + +obj-$(CONFIG_X86_32) += tls.o +obj-$(CONFIG_64BIT) += prctl.o USER_OBJS := $(obj-y) diff --git a/arch/x86/um/os-Linux/mcontext.c b/arch/x86/um/os-Linux/mcontext.c new file mode 100644 index 0000000..1d33d72 --- /dev/null +++ b/arch/x86/um/os-Linux/mcontext.c @@ -0,0 +1,31 @@ +#include <sys/ucontext.h> +#define __FRAME_OFFSETS +#include <asm/ptrace.h> +#include <sysdep/ptrace.h> + +void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc) +{ +#ifdef __i386__ +#define COPY2(X,Y) regs->gp[X] = mc->gregs[REG_##Y] +#define COPY(X) regs->gp[X] = mc->gregs[REG_##X] +#define COPY_SEG(X) regs->gp[X] = mc->gregs[REG_##X] & 0xffff; +#define COPY_SEG_CPL3(X) regs->gp[X] = (mc->gregs[REG_##X] & 0xffff) | 3; + COPY_SEG(GS); COPY_SEG(FS); COPY_SEG(ES); COPY_SEG(DS); + COPY(EDI); COPY(ESI); COPY(EBP); + COPY2(UESP, ESP); /* sic */ + COPY(EBX); COPY(EDX); COPY(ECX); COPY(EAX); + COPY(EIP); COPY_SEG_CPL3(CS); COPY(EFL); COPY_SEG_CPL3(SS); +#else +#define COPY2(X,Y) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##Y] +#define COPY(X) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##X] + COPY(R8); COPY(R9); COPY(R10); COPY(R11); + COPY(R12); COPY(R13); COPY(R14); COPY(R15); + COPY(RDI); COPY(RSI); COPY(RBP); COPY(RBX); + COPY(RDX); COPY(RAX); COPY(RCX); COPY(RSP); + COPY(RIP); + COPY2(EFLAGS, EFL); + COPY2(CS, CSGSFS); + regs->gp[CS / sizeof(unsigned long)] &= 0xffff; + regs->gp[CS / sizeof(unsigned long)] |= 3; +#endif +} diff --git a/arch/um/os-Linux/sys-x86_64/prctl.c b/arch/x86/um/os-Linux/prctl.c index 9d34edd..9d34edd 100644 --- a/arch/um/os-Linux/sys-x86_64/prctl.c +++ b/arch/x86/um/os-Linux/prctl.c diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/x86/um/os-Linux/registers.c index 229f7a5..0cdbb86 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/x86/um/os-Linux/registers.c @@ -6,10 +6,10 @@ #include <errno.h> #include <sys/ptrace.h> +#ifdef __i386__ #include <sys/user.h> -#include "kern_constants.h" +#endif #include "longjmp.h" -#include "user.h" #include "sysdep/ptrace_user.h" int save_fp_registers(int pid, unsigned long *fp_regs) @@ -26,6 +26,8 @@ int restore_fp_registers(int pid, unsigned long *fp_regs) return 0; } +#ifdef __i386__ +int have_fpx_regs = 1; int save_fpx_registers(int pid, unsigned long *fp_regs) { if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0) @@ -40,24 +42,6 @@ int restore_fpx_registers(int pid, unsigned long *fp_regs) return 0; } -unsigned long get_thread_reg(int reg, jmp_buf *buf) -{ - switch (reg) { - case EIP: - return buf[0]->__eip; - case UESP: - return buf[0]->__esp; - case EBP: - return buf[0]->__ebp; - default: - printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", - reg); - return 0; - } -} - -int have_fpx_regs = 1; - int get_fp_registers(int pid, unsigned long *regs) { if (have_fpx_regs) @@ -89,3 +73,41 @@ void arch_init_registers(int pid) have_fpx_regs = 0; } +#else + +int get_fp_registers(int pid, unsigned long *regs) +{ + return save_fp_registers(pid, regs); +} + +int put_fp_registers(int pid, unsigned long *regs) +{ + return restore_fp_registers(pid, regs); +} + +#endif + +unsigned long get_thread_reg(int reg, jmp_buf *buf) +{ + switch (reg) { +#ifdef __i386__ + case HOST_IP: + return buf[0]->__eip; + case HOST_SP: + return buf[0]->__esp; + case HOST_BP: + return buf[0]->__ebp; +#else + case HOST_IP: + return buf[0]->__rip; + case HOST_SP: + return buf[0]->__rsp; + case HOST_BP: + return buf[0]->__rbp; +#endif + default: + printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n", + reg); + return 0; + } +} diff --git a/arch/um/os-Linux/sys-i386/task_size.c b/arch/x86/um/os-Linux/task_size.c index be04c1e..efb16c5 100644 --- a/arch/um/os-Linux/sys-i386/task_size.c +++ b/arch/x86/um/os-Linux/task_size.c @@ -3,7 +3,8 @@ #include <signal.h> #include <sys/mman.h> #include "longjmp.h" -#include "kern_constants.h" + +#ifdef __i386__ static jmp_buf buf; @@ -137,3 +138,13 @@ out: return top; } + +#else + +unsigned long os_get_top_address(void) +{ + /* The old value of CONFIG_TOP_ADDR */ + return 0x7fc0000000; +} + +#endif diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/x86/um/os-Linux/tls.c index 32ed41e..82276b6 100644 --- a/arch/um/os-Linux/sys-i386/tls.c +++ b/arch/x86/um/os-Linux/tls.c @@ -1,16 +1,25 @@ #include <errno.h> #include <linux/unistd.h> +#include <sys/ptrace.h> #include <sys/syscall.h> #include <unistd.h> #include "sysdep/tls.h" -#include "user.h" + +#ifndef PTRACE_GET_THREAD_AREA +#define PTRACE_GET_THREAD_AREA 25 +#endif + +#ifndef PTRACE_SET_THREAD_AREA +#define PTRACE_SET_THREAD_AREA 26 +#endif /* Checks whether host supports TLS, and sets *tls_min according to the value * valid on the host. * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */ -void check_host_supports_tls(int *supports_tls, int *tls_min) { +void check_host_supports_tls(int *supports_tls, int *tls_min) +{ /* Values for x86 and x86_64.*/ int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64}; int i; @@ -34,3 +43,25 @@ void check_host_supports_tls(int *supports_tls, int *tls_min) { *supports_tls = 0; } + +int os_set_thread_area(user_desc_t *info, int pid) +{ + int ret; + + ret = ptrace(PTRACE_SET_THREAD_AREA, pid, info->entry_number, + (unsigned long) info); + if (ret < 0) + ret = -errno; + return ret; +} + +int os_get_thread_area(user_desc_t *info, int pid) +{ + int ret; + + ret = ptrace(PTRACE_GET_THREAD_AREA, pid, info->entry_number, + (unsigned long) info); + if (ret < 0) + ret = -errno; + return ret; +} diff --git a/arch/um/sys-i386/ptrace.c b/arch/x86/um/ptrace_32.c index 3375c27..3b949daa 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/x86/um/ptrace_32.c @@ -50,20 +50,47 @@ int is_syscall(unsigned long addr) /* 1 = access 0 = no access */ #define FLAG_MASK 0x00044dd5 +static const int reg_offsets[] = { + [EBX] = HOST_BX, + [ECX] = HOST_CX, + [EDX] = HOST_DX, + [ESI] = HOST_SI, + [EDI] = HOST_DI, + [EBP] = HOST_BP, + [EAX] = HOST_AX, + [DS] = HOST_DS, + [ES] = HOST_ES, + [FS] = HOST_FS, + [GS] = HOST_GS, + [EIP] = HOST_IP, + [CS] = HOST_CS, + [EFL] = HOST_EFLAGS, + [UESP] = HOST_SP, + [SS] = HOST_SS, +}; + int putreg(struct task_struct *child, int regno, unsigned long value) { regno >>= 2; switch (regno) { + case EBX: + case ECX: + case EDX: + case ESI: + case EDI: + case EBP: + case EAX: + case EIP: + case UESP: + break; case FS: if (value && (value & 3) != 3) return -EIO; - PT_REGS_FS(&child->thread.regs) = value; - return 0; + break; case GS: if (value && (value & 3) != 3) return -EIO; - PT_REGS_GS(&child->thread.regs) = value; - return 0; + break; case DS: case ES: if (value && (value & 3) != 3) @@ -78,10 +105,15 @@ int putreg(struct task_struct *child, int regno, unsigned long value) break; case EFL: value &= FLAG_MASK; - value |= PT_REGS_EFLAGS(&child->thread.regs); - break; + child->thread.regs.regs.gp[HOST_EFLAGS] |= value; + return 0; + case ORIG_EAX: + child->thread.regs.regs.syscall = value; + return 0; + default : + panic("Bad register in putreg() : %d\n", regno); } - PT_REGS_SET(&child->thread.regs, regno, value); + child->thread.regs.regs.gp[reg_offsets[regno]] = value; return 0; } @@ -106,22 +138,35 @@ int poke_user(struct task_struct *child, long addr, long data) unsigned long getreg(struct task_struct *child, int regno) { - unsigned long retval = ~0UL; + unsigned long mask = ~0UL; regno >>= 2; switch (regno) { + case ORIG_EAX: + return child->thread.regs.regs.syscall; case FS: case GS: case DS: case ES: case SS: case CS: - retval = 0xffff; - /* fall through */ + mask = 0xffff; + break; + case EIP: + case UESP: + case EAX: + case EBX: + case ECX: + case EDX: + case ESI: + case EDI: + case EBP: + case EFL: + break; default: - retval &= PT_REG(&child->thread.regs, regno); + panic("Bad register in getreg() : %d\n", regno); } - return retval; + return mask & child->thread.regs.regs.gp[reg_offsets[regno]]; } /* read the word at location addr in the USER area. */ diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/x86/um/ptrace_64.c index 4005506..3b52bf0 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/x86/um/ptrace_64.c @@ -18,10 +18,39 @@ */ #define FLAG_MASK 0x44dd5UL -int putreg(struct task_struct *child, int regno, unsigned long value) +static const int reg_offsets[] = { - unsigned long tmp; + [R8 >> 3] = HOST_R8, + [R9 >> 3] = HOST_R9, + [R10 >> 3] = HOST_R10, + [R11 >> 3] = HOST_R11, + [R12 >> 3] = HOST_R12, + [R13 >> 3] = HOST_R13, + [R14 >> 3] = HOST_R14, + [R15 >> 3] = HOST_R15, + [RIP >> 3] = HOST_IP, + [RSP >> 3] = HOST_SP, + [RAX >> 3] = HOST_AX, + [RBX >> 3] = HOST_BX, + [RCX >> 3] = HOST_CX, + [RDX >> 3] = HOST_DX, + [RSI >> 3] = HOST_SI, + [RDI >> 3] = HOST_DI, + [RBP >> 3] = HOST_BP, + [CS >> 3] = HOST_CS, + [SS >> 3] = HOST_SS, + [FS_BASE >> 3] = HOST_FS_BASE, + [GS_BASE >> 3] = HOST_GS_BASE, + [DS >> 3] = HOST_DS, + [ES >> 3] = HOST_ES, + [FS >> 3] = HOST_FS, + [GS >> 3] = HOST_GS, + [EFLAGS >> 3] = HOST_EFLAGS, + [ORIG_RAX >> 3] = HOST_ORIG_AX, +}; +int putreg(struct task_struct *child, int regno, unsigned long value) +{ #ifdef TIF_IA32 /* * Some code in the 64bit emulation may not be 64bit clean. @@ -31,6 +60,26 @@ int putreg(struct task_struct *child, int regno, unsigned long value) value &= 0xffffffff; #endif switch (regno) { + case R8: + case R9: + case R10: + case R11: + case R12: + case R13: + case R14: + case R15: + case RIP: + case RSP: + case RAX: + case RBX: + case RCX: + case RDX: + case RSI: + case RDI: + case RBP: + case ORIG_RAX: + break; + case FS: case GS: case DS: @@ -50,12 +99,14 @@ int putreg(struct task_struct *child, int regno, unsigned long value) case EFLAGS: value &= FLAG_MASK; - tmp = PT_REGS_EFLAGS(&child->thread.regs) & ~FLAG_MASK; - value |= tmp; - break; + child->thread.regs.regs.gp[HOST_EFLAGS] |= value; + return 0; + + default: + panic("Bad register in putreg(): %d\n", regno); } - PT_REGS_SET(&child->thread.regs, regno, value); + child->thread.regs.regs.gp[reg_offsets[regno >> 3]] = value; return 0; } @@ -80,24 +131,46 @@ int poke_user(struct task_struct *child, long addr, long data) unsigned long getreg(struct task_struct *child, int regno) { - unsigned long retval = ~0UL; + unsigned long mask = ~0UL; +#ifdef TIF_IA32 + if (test_tsk_thread_flag(child, TIF_IA32)) + mask = 0xffffffff; +#endif switch (regno) { + case R8: + case R9: + case R10: + case R11: + case R12: + case R13: + case R14: + case R15: + case RIP: + case RSP: + case RAX: + case RBX: + case RCX: + case RDX: + case RSI: + case RDI: + case RBP: + case ORIG_RAX: + case EFLAGS: + case FS_BASE: + case GS_BASE: + break; case FS: case GS: case DS: case ES: case SS: case CS: - retval = 0xffff; - /* fall through */ + mask = 0xffff; + break; default: - retval &= PT_REG(&child->thread.regs, regno); -#ifdef TIF_IA32 - if (test_tsk_thread_flag(child, TIF_IA32)) - retval &= 0xffffffff; -#endif + panic("Bad register in getreg: %d\n", regno); } - return retval; + return mask & child->thread.regs.regs.gp[reg_offsets[regno >> 3]]; } int peek_user(struct task_struct *child, long addr, long data) diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/x86/um/ptrace_user.c index 0b10c3e..3960ca1 100644 --- a/arch/um/sys-i386/ptrace_user.c +++ b/arch/x86/um/ptrace_user.c @@ -4,7 +4,7 @@ */ #include <errno.h> -#include <sys/ptrace.h> +#include "ptrace_user.h" int ptrace_getregs(long pid, unsigned long *regs_out) { diff --git a/arch/um/sys-i386/setjmp.S b/arch/x86/um/setjmp_32.S index b766792..b766792 100644 --- a/arch/um/sys-i386/setjmp.S +++ b/arch/x86/um/setjmp_32.S diff --git a/arch/um/sys-x86_64/setjmp.S b/arch/x86/um/setjmp_64.S index 45f547b..45f547b 100644 --- a/arch/um/sys-x86_64/setjmp.S +++ b/arch/x86/um/setjmp_64.S diff --git a/arch/x86/um/shared/sysdep/archsetjmp.h b/arch/x86/um/shared/sysdep/archsetjmp.h new file mode 100644 index 0000000..ff7766d --- /dev/null +++ b/arch/x86/um/shared/sysdep/archsetjmp.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "archsetjmp_32.h" +#else +#include "archsetjmp_64.h" +#endif diff --git a/arch/um/sys-i386/shared/sysdep/archsetjmp.h b/arch/x86/um/shared/sysdep/archsetjmp_32.h index 0f31208..0f31208 100644 --- a/arch/um/sys-i386/shared/sysdep/archsetjmp.h +++ b/arch/x86/um/shared/sysdep/archsetjmp_32.h diff --git a/arch/um/sys-x86_64/shared/sysdep/archsetjmp.h b/arch/x86/um/shared/sysdep/archsetjmp_64.h index 2af8f12..2af8f12 100644 --- a/arch/um/sys-x86_64/shared/sysdep/archsetjmp.h +++ b/arch/x86/um/shared/sysdep/archsetjmp_64.h diff --git a/arch/x86/um/shared/sysdep/faultinfo.h b/arch/x86/um/shared/sysdep/faultinfo.h new file mode 100644 index 0000000..862ecb1 --- /dev/null +++ b/arch/x86/um/shared/sysdep/faultinfo.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "faultinfo_32.h" +#else +#include "faultinfo_64.h" +#endif diff --git a/arch/um/sys-i386/shared/sysdep/faultinfo.h b/arch/x86/um/shared/sysdep/faultinfo_32.h index db437cc..a26086b 100644 --- a/arch/um/sys-i386/shared/sysdep/faultinfo.h +++ b/arch/x86/um/shared/sysdep/faultinfo_32.h @@ -24,6 +24,12 @@ struct faultinfo { #define FAULT_WRITE(fi) ((fi).error_code & 2) #define FAULT_ADDRESS(fi) ((fi).cr2) +/* This is Page Fault */ +#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) + +/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ +#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) + #define PTRACE_FULL_FAULTINFO 0 #endif diff --git a/arch/um/sys-x86_64/shared/sysdep/faultinfo.h b/arch/x86/um/shared/sysdep/faultinfo_64.h index cb917b0..f811cbe 100644 --- a/arch/um/sys-x86_64/shared/sysdep/faultinfo.h +++ b/arch/x86/um/shared/sysdep/faultinfo_64.h @@ -24,6 +24,12 @@ struct faultinfo { #define FAULT_WRITE(fi) ((fi).error_code & 2) #define FAULT_ADDRESS(fi) ((fi).cr2) +/* This is Page Fault */ +#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) + +/* No broken SKAS API, which doesn't pass trap_no, here. */ +#define SEGV_MAYBE_FIXABLE(fi) 0 + #define PTRACE_FULL_FAULTINFO 1 #endif diff --git a/arch/um/sys-i386/shared/sysdep/kernel-offsets.h b/arch/x86/um/shared/sysdep/kernel-offsets.h index 5868526..5868526 100644 --- a/arch/um/sys-i386/shared/sysdep/kernel-offsets.h +++ b/arch/x86/um/shared/sysdep/kernel-offsets.h diff --git a/arch/x86/um/shared/sysdep/mcontext.h b/arch/x86/um/shared/sysdep/mcontext.h new file mode 100644 index 0000000..b724c54 --- /dev/null +++ b/arch/x86/um/shared/sysdep/mcontext.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#ifndef __SYS_SIGCONTEXT_X86_H +#define __SYS_SIGCONTEXT_X86_H + +extern void get_regs_from_mc(struct uml_pt_regs *, mcontext_t *); + +#ifdef __i386__ + +#define GET_FAULTINFO_FROM_MC(fi, mc) \ + { \ + (fi).cr2 = (mc)->cr2; \ + (fi).error_code = (mc)->gregs[REG_ERR]; \ + (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ + } + +#else + +#define GET_FAULTINFO_FROM_MC(fi, mc) \ + { \ + (fi).cr2 = (mc)->gregs[REG_CR2]; \ + (fi).error_code = (mc)->gregs[REG_ERR]; \ + (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ + } + +#endif + +#endif diff --git a/arch/x86/um/shared/sysdep/ptrace.h b/arch/x86/um/shared/sysdep/ptrace.h new file mode 100644 index 0000000..711b162 --- /dev/null +++ b/arch/x86/um/shared/sysdep/ptrace.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "ptrace_32.h" +#else +#include "ptrace_64.h" +#endif diff --git a/arch/um/sys-i386/shared/sysdep/ptrace.h b/arch/x86/um/shared/sysdep/ptrace_32.h index c398a50..befd1df 100644 --- a/arch/um/sys-i386/shared/sysdep/ptrace.h +++ b/arch/x86/um/shared/sysdep/ptrace_32.h @@ -6,7 +6,7 @@ #ifndef __SYSDEP_I386_PTRACE_H #define __SYSDEP_I386_PTRACE_H -#include "user_constants.h" +#include <generated/user_constants.h> #include "sysdep/faultinfo.h" #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) @@ -24,18 +24,16 @@ void set_using_sysemu(int value); int get_using_sysemu(void); extern int sysemu_supported; -#include "skas_ptregs.h" - #define REGS_IP(r) ((r)[HOST_IP]) #define REGS_SP(r) ((r)[HOST_SP]) #define REGS_EFLAGS(r) ((r)[HOST_EFLAGS]) -#define REGS_EAX(r) ((r)[HOST_EAX]) -#define REGS_EBX(r) ((r)[HOST_EBX]) -#define REGS_ECX(r) ((r)[HOST_ECX]) -#define REGS_EDX(r) ((r)[HOST_EDX]) -#define REGS_ESI(r) ((r)[HOST_ESI]) -#define REGS_EDI(r) ((r)[HOST_EDI]) -#define REGS_EBP(r) ((r)[HOST_EBP]) +#define REGS_EAX(r) ((r)[HOST_AX]) +#define REGS_EBX(r) ((r)[HOST_BX]) +#define REGS_ECX(r) ((r)[HOST_CX]) +#define REGS_EDX(r) ((r)[HOST_DX]) +#define REGS_ESI(r) ((r)[HOST_SI]) +#define REGS_EDI(r) ((r)[HOST_DI]) +#define REGS_EBP(r) ((r)[HOST_BP]) #define REGS_CS(r) ((r)[HOST_CS]) #define REGS_SS(r) ((r)[HOST_SS]) #define REGS_DS(r) ((r)[HOST_DS]) @@ -45,6 +43,7 @@ extern int sysemu_supported; #define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res) +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) #define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) #ifndef PTRACE_SYSEMU_SINGLESTEP @@ -102,62 +101,6 @@ struct syscall_args { UPT_SYSCALL_ARG5(r), \ UPT_SYSCALL_ARG6(r) } } ) -#define UPT_REG(regs, reg) \ - ({ unsigned long val; \ - switch(reg){ \ - case EIP: val = UPT_IP(regs); break; \ - case UESP: val = UPT_SP(regs); break; \ - case EAX: val = UPT_EAX(regs); break; \ - case EBX: val = UPT_EBX(regs); break; \ - case ECX: val = UPT_ECX(regs); break; \ - case EDX: val = UPT_EDX(regs); break; \ - case ESI: val = UPT_ESI(regs); break; \ - case EDI: val = UPT_EDI(regs); break; \ - case EBP: val = UPT_EBP(regs); break; \ - case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \ - case CS: val = UPT_CS(regs); break; \ - case SS: val = UPT_SS(regs); break; \ - case DS: val = UPT_DS(regs); break; \ - case ES: val = UPT_ES(regs); break; \ - case FS: val = UPT_FS(regs); break; \ - case GS: val = UPT_GS(regs); break; \ - case EFL: val = UPT_EFLAGS(regs); break; \ - default : \ - panic("Bad register in UPT_REG : %d\n", reg); \ - val = -1; \ - } \ - val; \ - }) - -#define UPT_SET(regs, reg, val) \ - do { \ - switch(reg){ \ - case EIP: UPT_IP(regs) = val; break; \ - case UESP: UPT_SP(regs) = val; break; \ - case EAX: UPT_EAX(regs) = val; break; \ - case EBX: UPT_EBX(regs) = val; break; \ - case ECX: UPT_ECX(regs) = val; break; \ - case EDX: UPT_EDX(regs) = val; break; \ - case ESI: UPT_ESI(regs) = val; break; \ - case EDI: UPT_EDI(regs) = val; break; \ - case EBP: UPT_EBP(regs) = val; break; \ - case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \ - case CS: UPT_CS(regs) = val; break; \ - case SS: UPT_SS(regs) = val; break; \ - case DS: UPT_DS(regs) = val; break; \ - case ES: UPT_ES(regs) = val; break; \ - case FS: UPT_FS(regs) = val; break; \ - case GS: UPT_GS(regs) = val; break; \ - case EFL: UPT_EFLAGS(regs) = val; break; \ - default : \ - panic("Bad register in UPT_SET : %d\n", reg); \ - break; \ - } \ - } while (0) - -#define UPT_SET_SYSCALL_RETURN(r, res) \ - REGS_SET_SYSCALL_RETURN((r)->regs, (res)) - #define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) #define UPT_ORIG_SYSCALL(r) UPT_EAX(r) diff --git a/arch/um/sys-x86_64/shared/sysdep/ptrace.h b/arch/x86/um/shared/sysdep/ptrace_64.h index 8ee8f8e..031edc5 100644 --- a/arch/um/sys-x86_64/shared/sysdep/ptrace.h +++ b/arch/x86/um/shared/sysdep/ptrace_64.h @@ -8,24 +8,22 @@ #ifndef __SYSDEP_X86_64_PTRACE_H #define __SYSDEP_X86_64_PTRACE_H -#include "user_constants.h" +#include <generated/user_constants.h> #include "sysdep/faultinfo.h" #define MAX_REG_OFFSET (UM_FRAME_SIZE) #define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) -#include "skas_ptregs.h" - #define REGS_IP(r) ((r)[HOST_IP]) #define REGS_SP(r) ((r)[HOST_SP]) -#define REGS_RBX(r) ((r)[HOST_RBX]) -#define REGS_RCX(r) ((r)[HOST_RCX]) -#define REGS_RDX(r) ((r)[HOST_RDX]) -#define REGS_RSI(r) ((r)[HOST_RSI]) -#define REGS_RDI(r) ((r)[HOST_RDI]) -#define REGS_RBP(r) ((r)[HOST_RBP]) -#define REGS_RAX(r) ((r)[HOST_RAX]) +#define REGS_RBX(r) ((r)[HOST_BX]) +#define REGS_RCX(r) ((r)[HOST_CX]) +#define REGS_RDX(r) ((r)[HOST_DX]) +#define REGS_RSI(r) ((r)[HOST_SI]) +#define REGS_RDI(r) ((r)[HOST_DI]) +#define REGS_RBP(r) ((r)[HOST_BP]) +#define REGS_RAX(r) ((r)[HOST_AX]) #define REGS_R8(r) ((r)[HOST_R8]) #define REGS_R9(r) ((r)[HOST_R9]) #define REGS_R10(r) ((r)[HOST_R10]) @@ -67,14 +65,13 @@ #define REGS_FS(r) ((r)[HOST_FS]) #define REGS_GS(r) ((r)[HOST_GS]) -#define REGS_ORIG_RAX(r) ((r)[HOST_ORIG_RAX]) +#define REGS_ORIG_RAX(r) ((r)[HOST_ORIG_AX]) #define REGS_SET_SYSCALL_RETURN(r, res) REGS_RAX(r) = (res) +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) #define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) -#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type) - #define REGS_FAULT_ADDR(r) ((r)->fault_addr) #define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type) @@ -149,88 +146,8 @@ struct syscall_args { UPT_SYSCALL_ARG5(r), \ UPT_SYSCALL_ARG6(r) } } ) -#define UPT_REG(regs, reg) \ - ({ unsigned long val; \ - switch(reg){ \ - case R8: val = UPT_R8(regs); break; \ - case R9: val = UPT_R9(regs); break; \ - case R10: val = UPT_R10(regs); break; \ - case R11: val = UPT_R11(regs); break; \ - case R12: val = UPT_R12(regs); break; \ - case R13: val = UPT_R13(regs); break; \ - case R14: val = UPT_R14(regs); break; \ - case R15: val = UPT_R15(regs); break; \ - case RIP: val = UPT_IP(regs); break; \ - case RSP: val = UPT_SP(regs); break; \ - case RAX: val = UPT_RAX(regs); break; \ - case RBX: val = UPT_RBX(regs); break; \ - case RCX: val = UPT_RCX(regs); break; \ - case RDX: val = UPT_RDX(regs); break; \ - case RSI: val = UPT_RSI(regs); break; \ - case RDI: val = UPT_RDI(regs); break; \ - case RBP: val = UPT_RBP(regs); break; \ - case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \ - case CS: val = UPT_CS(regs); break; \ - case SS: val = UPT_SS(regs); break; \ - case FS_BASE: val = UPT_FS_BASE(regs); break; \ - case GS_BASE: val = UPT_GS_BASE(regs); break; \ - case DS: val = UPT_DS(regs); break; \ - case ES: val = UPT_ES(regs); break; \ - case FS : val = UPT_FS (regs); break; \ - case GS: val = UPT_GS(regs); break; \ - case EFLAGS: val = UPT_EFLAGS(regs); break; \ - default : \ - panic("Bad register in UPT_REG : %d\n", reg); \ - val = -1; \ - } \ - val; \ - }) - - -#define UPT_SET(regs, reg, val) \ - ({ unsigned long __upt_val = val; \ - switch(reg){ \ - case R8: UPT_R8(regs) = __upt_val; break; \ - case R9: UPT_R9(regs) = __upt_val; break; \ - case R10: UPT_R10(regs) = __upt_val; break; \ - case R11: UPT_R11(regs) = __upt_val; break; \ - case R12: UPT_R12(regs) = __upt_val; break; \ - case R13: UPT_R13(regs) = __upt_val; break; \ - case R14: UPT_R14(regs) = __upt_val; break; \ - case R15: UPT_R15(regs) = __upt_val; break; \ - case RIP: UPT_IP(regs) = __upt_val; break; \ - case RSP: UPT_SP(regs) = __upt_val; break; \ - case RAX: UPT_RAX(regs) = __upt_val; break; \ - case RBX: UPT_RBX(regs) = __upt_val; break; \ - case RCX: UPT_RCX(regs) = __upt_val; break; \ - case RDX: UPT_RDX(regs) = __upt_val; break; \ - case RSI: UPT_RSI(regs) = __upt_val; break; \ - case RDI: UPT_RDI(regs) = __upt_val; break; \ - case RBP: UPT_RBP(regs) = __upt_val; break; \ - case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ - case CS: UPT_CS(regs) = __upt_val; break; \ - case SS: UPT_SS(regs) = __upt_val; break; \ - case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \ - case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \ - case DS: UPT_DS(regs) = __upt_val; break; \ - case ES: UPT_ES(regs) = __upt_val; break; \ - case FS: UPT_FS(regs) = __upt_val; break; \ - case GS: UPT_GS(regs) = __upt_val; break; \ - case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \ - default : \ - panic("Bad register in UPT_SET : %d\n", reg); \ - break; \ - } \ - __upt_val; \ - }) - -#define UPT_SET_SYSCALL_RETURN(r, res) \ - REGS_SET_SYSCALL_RETURN((r)->regs, (res)) - #define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp) -#define UPT_SEGV_IS_FIXABLE(r) REGS_SEGV_IS_FIXABLE(&r->skas) - #define UPT_FAULTINFO(r) (&(r)->faultinfo) static inline void arch_init_registers(int pid) diff --git a/arch/x86/um/shared/sysdep/ptrace_user.h b/arch/x86/um/shared/sysdep/ptrace_user.h new file mode 100644 index 0000000..16cd6b5 --- /dev/null +++ b/arch/x86/um/shared/sysdep/ptrace_user.h @@ -0,0 +1,27 @@ +#include <generated/user_constants.h> + +#define PT_OFFSET(r) ((r) * sizeof(long)) + +#define PT_SYSCALL_NR(regs) ((regs)[HOST_ORIG_AX]) +#define PT_SYSCALL_NR_OFFSET PT_OFFSET(HOST_ORIG_AX) + +#define PT_SYSCALL_RET_OFFSET PT_OFFSET(HOST_AX) + +#define REGS_IP_INDEX HOST_IP +#define REGS_SP_INDEX HOST_SP + +#ifdef __i386__ +#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE) +#else +#define FP_SIZE HOST_FP_SIZE + +/* + * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though + * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the + * 2.4 name and value for 2.4 host compatibility. + */ +#ifndef PTRACE_OLDSETOPTIONS +#define PTRACE_OLDSETOPTIONS 21 +#endif + +#endif diff --git a/arch/um/sys-i386/shared/sysdep/skas_ptrace.h b/arch/x86/um/shared/sysdep/skas_ptrace.h index e27b8a7..453febe 100644 --- a/arch/um/sys-i386/shared/sysdep/skas_ptrace.h +++ b/arch/x86/um/shared/sysdep/skas_ptrace.h @@ -3,8 +3,8 @@ * Licensed under the GPL */ -#ifndef __SYSDEP_I386_SKAS_PTRACE_H -#define __SYSDEP_I386_SKAS_PTRACE_H +#ifndef __SYSDEP_X86_SKAS_PTRACE_H +#define __SYSDEP_X86_SKAS_PTRACE_H struct ptrace_faultinfo { int is_write; diff --git a/arch/x86/um/shared/sysdep/stub.h b/arch/x86/um/shared/sysdep/stub.h new file mode 100644 index 0000000..bd161e3 --- /dev/null +++ b/arch/x86/um/shared/sysdep/stub.h @@ -0,0 +1,14 @@ +#include <asm/unistd.h> +#include <sys/mman.h> +#include <signal.h> +#include "as-layout.h" +#include "stub-data.h" + +#ifdef __i386__ +#include "stub_32.h" +#else +#include "stub_64.h" +#endif + +extern void stub_segv_handler(int, siginfo_t *, void *); +extern void stub_clone_handler(void); diff --git a/arch/um/sys-i386/shared/sysdep/stub.h b/arch/x86/um/shared/sysdep/stub_32.h index 977dedd..51fd256 100644 --- a/arch/um/sys-i386/shared/sysdep/stub.h +++ b/arch/x86/um/shared/sysdep/stub_32.h @@ -6,15 +6,7 @@ #ifndef __SYSDEP_STUB_H #define __SYSDEP_STUB_H -#include <sys/mman.h> #include <asm/ptrace.h> -#include <asm/unistd.h> -#include "as-layout.h" -#include "stub-data.h" -#include "kern_constants.h" - -extern void stub_segv_handler(int sig); -extern void stub_clone_handler(void); #define STUB_SYSCALL_RET EAX #define STUB_MMAP_NR __NR_mmap2 diff --git a/arch/um/sys-x86_64/shared/sysdep/stub.h b/arch/x86/um/shared/sysdep/stub_64.h index 3432aa2..994df93 100644 --- a/arch/um/sys-x86_64/shared/sysdep/stub.h +++ b/arch/x86/um/shared/sysdep/stub_64.h @@ -6,15 +6,7 @@ #ifndef __SYSDEP_STUB_H #define __SYSDEP_STUB_H -#include <sys/mman.h> -#include <asm/unistd.h> #include <sysdep/ptrace_user.h> -#include "as-layout.h" -#include "stub-data.h" -#include "kern_constants.h" - -extern void stub_segv_handler(int sig); -extern void stub_clone_handler(void); #define STUB_SYSCALL_RET PT_INDEX(RAX) #define STUB_MMAP_NR __NR_mmap diff --git a/arch/x86/um/shared/sysdep/syscalls.h b/arch/x86/um/shared/sysdep/syscalls.h new file mode 100644 index 0000000..bd9a89b --- /dev/null +++ b/arch/x86/um/shared/sysdep/syscalls.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "syscalls_32.h" +#else +#include "syscalls_64.h" +#endif diff --git a/arch/um/sys-i386/shared/sysdep/syscalls.h b/arch/x86/um/shared/sysdep/syscalls_32.h index 05cb796..05cb796 100644 --- a/arch/um/sys-i386/shared/sysdep/syscalls.h +++ b/arch/x86/um/shared/sysdep/syscalls_32.h diff --git a/arch/um/sys-x86_64/shared/sysdep/syscalls.h b/arch/x86/um/shared/sysdep/syscalls_64.h index 7cfb0b08..8a7d5e1 100644 --- a/arch/um/sys-x86_64/shared/sysdep/syscalls.h +++ b/arch/x86/um/shared/sysdep/syscalls_64.h @@ -9,7 +9,6 @@ #include <linux/msg.h> #include <linux/shm.h> -#include <kern_constants.h> typedef long syscall_handler_t(void); diff --git a/arch/um/sys-i386/shared/sysdep/tls.h b/arch/x86/um/shared/sysdep/tls.h index 3455075..27cce00 100644 --- a/arch/um/sys-i386/shared/sysdep/tls.h +++ b/arch/x86/um/shared/sysdep/tls.h @@ -17,16 +17,23 @@ typedef struct um_dup_user_desc { unsigned int limit_in_pages:1; unsigned int seg_not_present:1; unsigned int useable:1; +#ifdef __x86_64__ + unsigned int lm:1; +#endif } user_desc_t; # else /* __KERNEL__ */ -# include <ldt.h> typedef struct user_desc user_desc_t; # endif /* __KERNEL__ */ +extern int os_set_thread_area(user_desc_t *info, int pid); +extern int os_get_thread_area(user_desc_t *info, int pid); + +#ifdef __i386__ #define GDT_ENTRY_TLS_MIN_I386 6 #define GDT_ENTRY_TLS_MIN_X86_64 12 +#endif #endif /* _SYSDEP_TLS_H */ diff --git a/arch/um/sys-i386/signal.c b/arch/x86/um/signal.c index 89a4662..4883b95 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/x86/um/signal.c @@ -1,36 +1,20 @@ /* - * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Copyright (C) 2003 PathScale, Inc. + * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */ + +#include <linux/personality.h> #include <linux/ptrace.h> +#include <linux/kernel.h> #include <asm/unistd.h> #include <asm/uaccess.h> #include <asm/ucontext.h> #include "frame_kern.h" #include "skas.h" -void copy_sc(struct uml_pt_regs *regs, void *from) -{ - struct sigcontext *sc = from; - - REGS_GS(regs->gp) = sc->gs; - REGS_FS(regs->gp) = sc->fs; - REGS_ES(regs->gp) = sc->es; - REGS_DS(regs->gp) = sc->ds; - REGS_EDI(regs->gp) = sc->di; - REGS_ESI(regs->gp) = sc->si; - REGS_EBP(regs->gp) = sc->bp; - REGS_SP(regs->gp) = sc->sp; - REGS_EBX(regs->gp) = sc->bx; - REGS_EDX(regs->gp) = sc->dx; - REGS_ECX(regs->gp) = sc->cx; - REGS_EAX(regs->gp) = sc->ax; - REGS_IP(regs->gp) = sc->ip; - REGS_CS(regs->gp) = sc->cs; - REGS_EFLAGS(regs->gp) = sc->flags; - REGS_SS(regs->gp) = sc->ss; -} +#ifdef CONFIG_X86_32 /* * FPU tag word conversions. @@ -164,6 +148,8 @@ static int convert_fxsr_from_user(struct user_fxsr_struct *fxsave, extern int have_fpx_regs; +#endif + static int copy_sc_from_user(struct pt_regs *regs, struct sigcontext __user *from) { @@ -174,8 +160,45 @@ static int copy_sc_from_user(struct pt_regs *regs, if (err) return err; +#define GETREG(regno, regname) regs->regs.gp[HOST_##regno] = sc.regname + +#ifdef CONFIG_X86_32 + GETREG(GS, gs); + GETREG(FS, fs); + GETREG(ES, es); + GETREG(DS, ds); +#endif + GETREG(DI, di); + GETREG(SI, si); + GETREG(BP, bp); + GETREG(SP, sp); + GETREG(BX, bx); + GETREG(DX, dx); + GETREG(CX, cx); + GETREG(AX, ax); + GETREG(IP, ip); + +#ifdef CONFIG_X86_64 + GETREG(R8, r8); + GETREG(R9, r9); + GETREG(R10, r10); + GETREG(R11, r11); + GETREG(R12, r12); + GETREG(R13, r13); + GETREG(R14, r14); + GETREG(R15, r15); +#endif + + GETREG(CS, cs); + GETREG(EFLAGS, flags); +#ifdef CONFIG_X86_32 + GETREG(SS, ss); +#endif + +#undef GETREG + pid = userspace_pid[current_thread_info()->cpu]; - copy_sc(®s->regs, &sc); +#ifdef CONFIG_X86_32 if (have_fpx_regs) { struct user_fxsr_struct fpx; @@ -196,8 +219,9 @@ static int copy_sc_from_user(struct pt_regs *regs, -err); return 1; } - } - else { + } else +#endif + { struct user_i387_struct fp; err = copy_from_user(&fp, sc.fpstate, @@ -213,43 +237,66 @@ static int copy_sc_from_user(struct pt_regs *regs, return 1; } } - return 0; } static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *to_fp, struct pt_regs *regs, - unsigned long sp) + unsigned long mask) { struct sigcontext sc; struct faultinfo * fi = ¤t->thread.arch.faultinfo; int err, pid; + memset(&sc, 0, sizeof(struct sigcontext)); + +#define PUTREG(regno, regname) sc.regname = regs->regs.gp[HOST_##regno] + +#ifdef CONFIG_X86_32 + PUTREG(GS, gs); + PUTREG(FS, fs); + PUTREG(ES, es); + PUTREG(DS, ds); +#endif + PUTREG(DI, di); + PUTREG(SI, si); + PUTREG(BP, bp); + PUTREG(SP, sp); + PUTREG(BX, bx); + PUTREG(DX, dx); + PUTREG(CX, cx); + PUTREG(AX, ax); +#ifdef CONFIG_X86_64 + PUTREG(R8, r8); + PUTREG(R9, r9); + PUTREG(R10, r10); + PUTREG(R11, r11); + PUTREG(R12, r12); + PUTREG(R13, r13); + PUTREG(R14, r14); + PUTREG(R15, r15); +#endif - sc.gs = REGS_GS(regs->regs.gp); - sc.fs = REGS_FS(regs->regs.gp); - sc.es = REGS_ES(regs->regs.gp); - sc.ds = REGS_DS(regs->regs.gp); - sc.di = REGS_EDI(regs->regs.gp); - sc.si = REGS_ESI(regs->regs.gp); - sc.bp = REGS_EBP(regs->regs.gp); - sc.sp = sp; - sc.bx = REGS_EBX(regs->regs.gp); - sc.dx = REGS_EDX(regs->regs.gp); - sc.cx = REGS_ECX(regs->regs.gp); - sc.ax = REGS_EAX(regs->regs.gp); - sc.ip = REGS_IP(regs->regs.gp); - sc.cs = REGS_CS(regs->regs.gp); - sc.flags = REGS_EFLAGS(regs->regs.gp); - sc.sp_at_signal = regs->regs.gp[UESP]; - sc.ss = regs->regs.gp[SS]; sc.cr2 = fi->cr2; sc.err = fi->error_code; sc.trapno = fi->trap_no; - - to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); + PUTREG(IP, ip); + PUTREG(CS, cs); + PUTREG(EFLAGS, flags); +#ifdef CONFIG_X86_32 + PUTREG(SP, sp_at_signal); + PUTREG(SS, ss); +#endif +#undef PUTREG + sc.oldmask = mask; sc.fpstate = to_fp; + err = copy_to_user(to, &sc, sizeof(struct sigcontext)); + if (err) + return 1; + pid = userspace_pid[current_thread_info()->cpu]; + +#ifdef CONFIG_X86_32 if (have_fpx_regs) { struct user_fxsr_struct fpx; @@ -272,8 +319,9 @@ static int copy_sc_to_user(struct sigcontext __user *to, if (copy_to_user(&to_fp->_fxsr_env[0], &fpx, sizeof(struct user_fxsr_struct))) return 1; - } - else { + } else +#endif + { struct user_i387_struct fp; err = save_fp_registers(pid, (unsigned long *) &fp); @@ -281,9 +329,10 @@ static int copy_sc_to_user(struct sigcontext __user *to, return 1; } - return copy_to_user(to, &sc, sizeof(sc)); + return 0; } +#ifdef CONFIG_X86_32 static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp, sigset_t *set, unsigned long sp) @@ -293,7 +342,7 @@ static int copy_ucontext_to_user(struct ucontext __user *uc, err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp); err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags); err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size); - err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs, sp); + err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs, 0); err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); return err; } @@ -326,7 +375,6 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig, { struct sigframe __user *frame; void __user *restorer; - unsigned long save_sp = PT_REGS_SP(regs); int err = 0; /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */ @@ -339,20 +387,9 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig, if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; - /* Update SP now because the page fault handler refuses to extend - * the stack if the faulting address is too far below the current - * SP, which frame now certainly is. If there's an error, the original - * value is restored on the way out. - * When writing the sigcontext to the stack, we have to write the - * original value, so that's passed to copy_sc_to_user, which does - * the right thing with it. - */ - PT_REGS_SP(regs) = (unsigned long) frame; - err |= __put_user(restorer, &frame->pretcode); err |= __put_user(sig, &frame->sig); - err |= copy_sc_to_user(&frame->sc, NULL, regs, save_sp); - err |= __put_user(mask->sig[0], &frame->sc.oldmask); + err |= copy_sc_to_user(&frame->sc, &frame->fpstate, regs, mask->sig[0]); if (_NSIG_WORDS > 1) err |= __copy_to_user(&frame->extramask, &mask->sig[1], sizeof(frame->extramask)); @@ -369,7 +406,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig, err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); if (err) - goto err; + return err; PT_REGS_SP(regs) = (unsigned long) frame; PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; @@ -380,10 +417,6 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig, if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) ptrace_notify(SIGTRAP); return 0; - -err: - PT_REGS_SP(regs) = save_sp; - return err; } int setup_signal_stack_si(unsigned long stack_top, int sig, @@ -392,7 +425,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, { struct rt_sigframe __user *frame; void __user *restorer; - unsigned long save_sp = PT_REGS_SP(regs); int err = 0; stack_top &= -8UL; @@ -404,16 +436,13 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; - /* See comment above about why this is here */ - PT_REGS_SP(regs) = (unsigned long) frame; - err |= __put_user(restorer, &frame->pretcode); err |= __put_user(sig, &frame->sig); err |= __put_user(&frame->info, &frame->pinfo); err |= __put_user(&frame->uc, &frame->puc); err |= copy_siginfo_to_user(&frame->info, info); err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask, - save_sp); + PT_REGS_SP(regs)); /* * This is movl $,%eax ; int $0x80 @@ -427,8 +456,9 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); if (err) - goto err; + return err; + PT_REGS_SP(regs) = (unsigned long) frame; PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; PT_REGS_EAX(regs) = (unsigned long) sig; PT_REGS_EDX(regs) = (unsigned long) &frame->info; @@ -437,13 +467,9 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) ptrace_notify(SIGTRAP); return 0; - -err: - PT_REGS_SP(regs) = save_sp; - return err; } -long sys_sigreturn(struct pt_regs regs) +long sys_sigreturn(struct pt_regs *regs) { unsigned long sp = PT_REGS_SP(¤t->thread.regs); struct sigframe __user *frame = (struct sigframe __user *)(sp - 8); @@ -458,11 +484,7 @@ long sys_sigreturn(struct pt_regs regs) goto segfault; sigdelsetmask(&set, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); if (copy_sc_from_user(¤t->thread.regs, sc)) goto segfault; @@ -476,24 +498,107 @@ long sys_sigreturn(struct pt_regs regs) return 0; } -long sys_rt_sigreturn(struct pt_regs regs) +#else + +struct rt_sigframe +{ + char __user *pretcode; + struct ucontext uc; + struct siginfo info; + struct _fpstate fpstate; +}; + +int setup_signal_stack_si(unsigned long stack_top, int sig, + struct k_sigaction *ka, struct pt_regs * regs, + siginfo_t *info, sigset_t *set) +{ + struct rt_sigframe __user *frame; + int err = 0; + struct task_struct *me = current; + + frame = (struct rt_sigframe __user *) + round_down(stack_top - sizeof(struct rt_sigframe), 16); + /* Subtract 128 for a red zone and 8 for proper alignment */ + frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8); + + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + goto out; + + if (ka->sa.sa_flags & SA_SIGINFO) { + err |= copy_siginfo_to_user(&frame->info, info); + if (err) + goto out; + } + + /* Create the ucontext. */ + err |= __put_user(0, &frame->uc.uc_flags); + err |= __put_user(0, &frame->uc.uc_link); + err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(PT_REGS_SP(regs)), + &frame->uc.uc_stack.ss_flags); + err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs, + set->sig[0]); + err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate); + if (sizeof(*set) == 16) { + __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); + __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); + } + else + err |= __copy_to_user(&frame->uc.uc_sigmask, set, + sizeof(*set)); + + /* + * Set up to return from userspace. If provided, use a stub + * already in userspace. + */ + /* x86-64 should always use SA_RESTORER. */ + if (ka->sa.sa_flags & SA_RESTORER) + err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); + else + /* could use a vstub here */ + return err; + + if (err) + return err; + + /* Set up registers for signal handler */ + { + struct exec_domain *ed = current_thread_info()->exec_domain; + if (unlikely(ed && ed->signal_invmap && sig < 32)) + sig = ed->signal_invmap[sig]; + } + + PT_REGS_SP(regs) = (unsigned long) frame; + PT_REGS_RDI(regs) = sig; + /* In case the signal handler was declared without prototypes */ + PT_REGS_RAX(regs) = 0; + + /* + * This also works for non SA_SIGINFO handlers because they expect the + * next argument after the signal number on the stack. + */ + PT_REGS_RSI(regs) = (unsigned long) &frame->info; + PT_REGS_RDX(regs) = (unsigned long) &frame->uc; + PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler; + out: + return err; +} +#endif + +long sys_rt_sigreturn(struct pt_regs *regs) { unsigned long sp = PT_REGS_SP(¤t->thread.regs); struct rt_sigframe __user *frame = - (struct rt_sigframe __user *) (sp - 4); - sigset_t set; + (struct rt_sigframe __user *)(sp - sizeof(long)); struct ucontext __user *uc = &frame->uc; - int sig_size = _NSIG_WORDS * sizeof(unsigned long); + sigset_t set; - if (copy_from_user(&set, &uc->uc_sigmask, sig_size)) + if (copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) goto segfault; sigdelsetmask(&set, ~_BLOCKABLE); - - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); if (copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext)) goto segfault; @@ -506,3 +611,14 @@ long sys_rt_sigreturn(struct pt_regs regs) force_sig(SIGSEGV, current); return 0; } + +#ifdef CONFIG_X86_32 +long ptregs_sigreturn(void) +{ + return sys_sigreturn(NULL); +} +long ptregs_rt_sigreturn(void) +{ + return sys_rt_sigreturn(NULL); +} +#endif diff --git a/arch/um/sys-i386/stub.S b/arch/x86/um/stub_32.S index 54a36ec..54a36ec 100644 --- a/arch/um/sys-i386/stub.S +++ b/arch/x86/um/stub_32.S diff --git a/arch/um/sys-x86_64/stub.S b/arch/x86/um/stub_64.S index 20e4a96..20e4a96 100644 --- a/arch/um/sys-x86_64/stub.S +++ b/arch/x86/um/stub_64.S diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/x86/um/stub_segv.c index ced051a..b7450bd 100644 --- a/arch/um/sys-x86_64/stub_segv.c +++ b/arch/x86/um/stub_segv.c @@ -3,19 +3,16 @@ * Licensed under the GPL */ -#include <signal.h> -#include "as-layout.h" #include "sysdep/stub.h" #include "sysdep/faultinfo.h" -#include "sysdep/sigcontext.h" +#include "sysdep/mcontext.h" void __attribute__ ((__section__ (".__syscall_stub"))) -stub_segv_handler(int sig) +stub_segv_handler(int sig, siginfo_t *info, void *p) { - struct ucontext *uc; + struct ucontext *uc = p; - __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :); - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), + GET_FAULTINFO_FROM_MC(*((struct faultinfo *) STUB_DATA), &uc->uc_mcontext); trap_myself(); } diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/x86/um/sys_call_table_32.S index de274071..a7ca80d 100644 --- a/arch/um/sys-i386/sys_call_table.S +++ b/arch/x86/um/sys_call_table_32.S @@ -13,16 +13,14 @@ #define ptregs_execve sys_execve #define ptregs_iopl sys_iopl #define ptregs_vm86old sys_vm86old -#define ptregs_sigreturn sys_sigreturn #define ptregs_clone sys_clone #define ptregs_vm86 sys_vm86 -#define ptregs_rt_sigreturn sys_rt_sigreturn #define ptregs_sigaltstack sys_sigaltstack #define ptregs_vfork sys_vfork .section .rodata,"a" -#include "../../x86/kernel/syscall_table_32.S" +#include "../kernel/syscall_table_32.S" ENTRY(syscall_table_size) .long .-sys_call_table diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/x86/um/sys_call_table_64.c index 47d469e..99522f7 100644 --- a/arch/um/sys-x86_64/syscall_table.c +++ b/arch/x86/um/sys_call_table_64.c @@ -6,7 +6,6 @@ #include <linux/linkage.h> #include <linux/sys.h> #include <linux/cache.h> -#include <kern_constants.h> #define __NO_STUBS @@ -59,7 +58,7 @@ extern void sys_ni_syscall(void); */ sys_call_ptr_t sys_call_table[] __cacheline_aligned = { -#include "../../x86/include/asm/unistd_64.h" +#include <asm/unistd_64.h> }; int syscall_table_size = sizeof(sys_call_table); diff --git a/arch/um/sys-i386/syscalls.c b/arch/x86/um/syscalls_32.c index 70ca357..70ca357 100644 --- a/arch/um/sys-i386/syscalls.c +++ b/arch/x86/um/syscalls_32.c diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/x86/um/syscalls_64.c index f3d82bb..f3d82bb 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/x86/um/syscalls_64.c diff --git a/arch/um/sys-i386/sysrq.c b/arch/x86/um/sysrq_32.c index 171b3e9..171b3e9 100644 --- a/arch/um/sys-i386/sysrq.c +++ b/arch/x86/um/sysrq_32.c diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/x86/um/sysrq_64.c index f4f82be..e891343 100644 --- a/arch/um/sys-x86_64/sysrq.c +++ b/arch/x86/um/sysrq_64.c @@ -20,7 +20,7 @@ void __show_regs(struct pt_regs *regs) current->comm, print_tainted(), init_utsname()->release); printk(KERN_INFO "RIP: %04lx:[<%016lx>]\n", PT_REGS_CS(regs) & 0xffff, PT_REGS_RIP(regs)); - printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs), + printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_SP(regs), PT_REGS_EFLAGS(regs)); printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n", PT_REGS_RAX(regs), PT_REGS_RBX(regs), PT_REGS_RCX(regs)); diff --git a/arch/um/sys-i386/tls.c b/arch/x86/um/tls_32.c index c6c7131..c6c7131 100644 --- a/arch/um/sys-i386/tls.c +++ b/arch/x86/um/tls_32.c diff --git a/arch/um/sys-x86_64/tls.c b/arch/x86/um/tls_64.c index f7ba462..f7ba462 100644 --- a/arch/um/sys-x86_64/tls.c +++ b/arch/x86/um/tls_64.c diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/x86/um/user-offsets.c index 9735854..ca49be8 100644 --- a/arch/um/sys-x86_64/user-offsets.c +++ b/arch/x86/um/user-offsets.c @@ -9,28 +9,43 @@ #include <asm/types.h> #define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) + asm volatile("\n->" #sym " %0 " #val : : "i" (val)) #define DEFINE_LONGS(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) - -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); + asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) void foo(void) { - OFFSET(HOST_SC_CR2, sigcontext, cr2); - OFFSET(HOST_SC_ERR, sigcontext, err); - OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); +#ifdef __i386__ + DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct)); + DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct)); + DEFINE(HOST_IP, EIP); + DEFINE(HOST_SP, UESP); + DEFINE(HOST_EFLAGS, EFL); + DEFINE(HOST_AX, EAX); + DEFINE(HOST_BX, EBX); + DEFINE(HOST_CX, ECX); + DEFINE(HOST_DX, EDX); + DEFINE(HOST_SI, ESI); + DEFINE(HOST_DI, EDI); + DEFINE(HOST_BP, EBP); + DEFINE(HOST_CS, CS); + DEFINE(HOST_SS, SS); + DEFINE(HOST_DS, DS); + DEFINE(HOST_FS, FS); + DEFINE(HOST_ES, ES); + DEFINE(HOST_GS, GS); + DEFINE(HOST_ORIG_AX, ORIG_EAX); +#else DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); - DEFINE_LONGS(HOST_RBX, RBX); - DEFINE_LONGS(HOST_RCX, RCX); - DEFINE_LONGS(HOST_RDI, RDI); - DEFINE_LONGS(HOST_RSI, RSI); - DEFINE_LONGS(HOST_RDX, RDX); - DEFINE_LONGS(HOST_RBP, RBP); - DEFINE_LONGS(HOST_RAX, RAX); + DEFINE_LONGS(HOST_BX, RBX); + DEFINE_LONGS(HOST_CX, RCX); + DEFINE_LONGS(HOST_DI, RDI); + DEFINE_LONGS(HOST_SI, RSI); + DEFINE_LONGS(HOST_DX, RDX); + DEFINE_LONGS(HOST_BP, RBP); + DEFINE_LONGS(HOST_AX, RAX); DEFINE_LONGS(HOST_R8, R8); DEFINE_LONGS(HOST_R9, R9); DEFINE_LONGS(HOST_R10, R10); @@ -39,7 +54,7 @@ void foo(void) DEFINE_LONGS(HOST_R13, R13); DEFINE_LONGS(HOST_R14, R14); DEFINE_LONGS(HOST_R15, R15); - DEFINE_LONGS(HOST_ORIG_RAX, ORIG_RAX); + DEFINE_LONGS(HOST_ORIG_AX, ORIG_RAX); DEFINE_LONGS(HOST_CS, CS); DEFINE_LONGS(HOST_SS, SS); DEFINE_LONGS(HOST_EFLAGS, EFLAGS); @@ -52,9 +67,9 @@ void foo(void) DEFINE_LONGS(HOST_IP, RIP); DEFINE_LONGS(HOST_SP, RSP); - DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); +#endif - /* XXX Duplicated between i386 and x86_64 */ + DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); DEFINE(UM_POLLIN, POLLIN); DEFINE(UM_POLLPRI, POLLPRI); DEFINE(UM_POLLOUT, POLLOUT); diff --git a/arch/um/sys-x86_64/vdso/Makefile b/arch/x86/um/vdso/Makefile index 5dffe6d..6c803ca 100644 --- a/arch/um/sys-x86_64/vdso/Makefile +++ b/arch/x86/um/vdso/Makefile @@ -46,8 +46,8 @@ $(vobjs): KBUILD_CFLAGS += $(CFL) # # vDSO code runs in userspace and -pg doesn't help with profiling anyway. # -CFLAGS_REMOVE_vdso-note.o = -pg -CFLAGS_REMOVE_um_vdso.o = -pg +CFLAGS_REMOVE_vdso-note.o = -pg -fprofile-arcs -ftest-coverage +CFLAGS_REMOVE_um_vdso.o = -pg -fprofile-arcs -ftest-coverage targets += vdso-syms.lds obj-$(VDSO64-y) += vdso-syms.lds diff --git a/arch/um/sys-x86_64/vdso/checkundef.sh b/arch/x86/um/vdso/checkundef.sh index 7ee90a9..7ee90a9 100644 --- a/arch/um/sys-x86_64/vdso/checkundef.sh +++ b/arch/x86/um/vdso/checkundef.sh diff --git a/arch/um/sys-x86_64/vdso/um_vdso.c b/arch/x86/um/vdso/um_vdso.c index 7c441b5..7c441b5 100644 --- a/arch/um/sys-x86_64/vdso/um_vdso.c +++ b/arch/x86/um/vdso/um_vdso.c diff --git a/arch/um/sys-x86_64/vdso/vdso-layout.lds.S b/arch/x86/um/vdso/vdso-layout.lds.S index 634a2cf..634a2cf 100644 --- a/arch/um/sys-x86_64/vdso/vdso-layout.lds.S +++ b/arch/x86/um/vdso/vdso-layout.lds.S diff --git a/arch/um/sys-x86_64/vdso/vdso-note.S b/arch/x86/um/vdso/vdso-note.S index 79a071e..79a071e 100644 --- a/arch/um/sys-x86_64/vdso/vdso-note.S +++ b/arch/x86/um/vdso/vdso-note.S diff --git a/arch/um/sys-x86_64/vdso/vdso.S b/arch/x86/um/vdso/vdso.S index ec82c16..1cb468a 100644 --- a/arch/um/sys-x86_64/vdso/vdso.S +++ b/arch/x86/um/vdso/vdso.S @@ -4,7 +4,7 @@ __INITDATA .globl vdso_start, vdso_end vdso_start: - .incbin "arch/um/sys-x86_64/vdso/vdso.so" + .incbin "arch/x86/um/vdso/vdso.so" vdso_end: __FINIT diff --git a/arch/um/sys-x86_64/vdso/vdso.lds.S b/arch/x86/um/vdso/vdso.lds.S index b96b267..b96b267 100644 --- a/arch/um/sys-x86_64/vdso/vdso.lds.S +++ b/arch/x86/um/vdso/vdso.lds.S diff --git a/arch/um/sys-x86_64/vdso/vma.c b/arch/x86/um/vdso/vma.c index 9495c8d..91f4ec9 100644 --- a/arch/um/sys-x86_64/vdso/vma.c +++ b/arch/x86/um/vdso/vma.c @@ -28,7 +28,7 @@ static int __init init_vdso(void) um_vdso_addr = task_size - PAGE_SIZE; - vdsop = kmalloc(GFP_KERNEL, sizeof(struct page *)); + vdsop = kmalloc(sizeof(struct page *), GFP_KERNEL); if (!vdsop) goto oom; diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 423fd56..4364303 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -298,7 +298,7 @@ if RTC_LIB=n config RTC tristate "Enhanced Real Time Clock Support (legacy PC RTC driver)" depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV \ - && !ARM && !SUPERH && !S390 && !AVR32 && !BLACKFIN + && !ARM && !SUPERH && !S390 && !AVR32 && !BLACKFIN && !UML ---help--- If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you @@ -346,7 +346,7 @@ config JS_RTC config GEN_RTC tristate "Generic /dev/rtc emulation" - depends on RTC!=y && !IA64 && !ARM && !M32R && !MIPS && !SPARC && !FRV && !S390 && !SUPERH && !AVR32 && !BLACKFIN + depends on RTC!=y && !IA64 && !ARM && !M32R && !MIPS && !SPARC && !FRV && !S390 && !SUPERH && !AVR32 && !BLACKFIN && !UML ---help--- If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you @@ -490,7 +490,7 @@ config SCx200_GPIO config PC8736x_GPIO tristate "NatSemi PC8736x GPIO Support" - depends on X86_32 + depends on X86_32 && !UML default SCx200_GPIO # mostly N select NSC_GPIO # needed for support routines help diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index e013587..0689bf6 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -235,3 +235,18 @@ config HW_RANDOM_PPC4XX module will be called ppc4xx-rng. If unsure, say N. + +config UML_RANDOM + depends on UML + tristate "Hardware random number generator" + help + This option enables UML's "hardware" random number generator. It + attaches itself to the host's /dev/random, supplying as much entropy + as the host has, rather than the small amount the UML gets from its + own drivers. It registers itself as a standard hardware random number + generator, major 10, minor 183, and the canonical device name is + /dev/hwrng. + The way to make use of this is to install the rng-tools package + (check your distro, or download from + http://sourceforge.net/projects/gkernel/). rngd periodically reads + /dev/hwrng and injects the entropy into /dev/random. diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index a1f68af..f228615 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -170,7 +170,7 @@ static const struct tty_operations ttyprintk_ops = { .ioctl = tpk_ioctl, }; -struct tty_port_operations null_ops = { }; +static struct tty_port_operations null_ops = { }; static struct tty_driver *ttyprintk_driver; diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 23e82e46..001b147 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -3,7 +3,7 @@ # menu "Input device support" - depends on !S390 + depends on !S390 && !UML config INPUT tristate "Generic input layer (needed for keyboard, mouse, ...)" if EXPERT diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig index 4fb6016..a233ed5 100644 --- a/drivers/isdn/Kconfig +++ b/drivers/isdn/Kconfig @@ -5,7 +5,7 @@ menuconfig ISDN bool "ISDN support" depends on NET - depends on !S390 + depends on !S390 && !UML ---help--- ISDN ("Integrated Services Digital Network", called RNIS in France) is a fully digital telephone service that can be used for voice and diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index 0735488..0960224 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig @@ -1,6 +1,6 @@ menuconfig ATH_COMMON tristate "Atheros Wireless Cards" - depends on CFG80211 + depends on CFG80211 && (!UML || BROKEN) ---help--- This will enable the support for the Atheros wireless drivers. ath5k, ath9k, ath9k_htc and ar9170 drivers share some common code, this option diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index 45e1476..d6c42e6 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig @@ -12,7 +12,7 @@ config RTL8192CE config RTL8192SE tristate "Realtek RTL8192SE/RTL8191SE PCIe Wireless Network Adapter" - depends on MAC80211 && EXPERIMENTAL + depends on MAC80211 && EXPERIMENTAL && PCI select FW_LOADER select RTLWIFI ---help--- @@ -23,7 +23,7 @@ config RTL8192SE config RTL8192DE tristate "Realtek RTL8192DE/RTL8188DE PCIe Wireless Network Adapter" - depends on MAC80211 && EXPERIMENTAL + depends on MAC80211 && EXPERIMENTAL && PCI select FW_LOADER select RTLWIFI ---help--- diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 57de051..9f88641 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -70,6 +70,7 @@ config BATTERY_DS2760 config BATTERY_DS2780 tristate "DS2780 battery driver" + depends on HAS_IOMEM select W1 select W1_SLAVE_DS2780 help diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 5a538fc..53eb4e5 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -8,7 +8,7 @@ config RTC_LIB menuconfig RTC_CLASS bool "Real Time Clock" default n - depends on !S390 + depends on !S390 && !UML select RTC_LIB help Generic RTC class support. If you say yes here, you will diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index 8816f53..b3d1741 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -1,6 +1,6 @@ config VT bool "Virtual terminal" if EXPERT - depends on !S390 + depends on !S390 && !UML select INPUT default y ---help--- diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 86b0735..64c6752 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -726,7 +726,7 @@ config SBC8360_WDT config SBC7240_WDT tristate "SBC Nano 7240 Watchdog Timer" - depends on X86_32 + depends on X86_32 && !UML ---help--- This is the driver for the hardware watchdog found on the IEI single board computers EPIC Nano 7240 (and likely others). This @@ -1174,6 +1174,10 @@ config XEN_WDT by Xen 4.0 and newer. The watchdog timeout period is normally one minute but can be changed with a boot-time parameter. +config UML_WATCHDOG + tristate "UML watchdog" + depends on UML + # # ISA-based Watchdog Cards # diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c index d51a9838..dd7bc38 100644 --- a/fs/hostfs/hostfs_user.c +++ b/fs/hostfs/hostfs_user.c @@ -16,7 +16,6 @@ #include <sys/vfs.h> #include "hostfs.h" #include "os.h" -#include "user.h" #include <utime.h> static void stat64_to_hostfs(const struct stat64 *buf, struct hostfs_stat *p) diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 19c053b..4f554f20 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -9,7 +9,7 @@ config IMA select CRYPTO_HMAC select CRYPTO_MD5 select CRYPTO_SHA1 - select TCG_TPM if !S390 + select TCG_TPM if !S390 && !UML select TCG_TIS if TCG_TPM help The Trusted Computing Group(TCG) runtime Integrity diff --git a/sound/Kconfig b/sound/Kconfig index 1fef141..261a03c 100644 --- a/sound/Kconfig +++ b/sound/Kconfig @@ -59,7 +59,7 @@ config SOUND_OSS_CORE_PRECLAIM source "sound/oss/dmasound/Kconfig" -if !M68K +if !M68K && !UML menuconfig SND tristate "Advanced Linux Sound Architecture" |