diff --git a/[refs] b/[refs]
index 78ec0fd8d981..a69235d41167 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 801c0be81454901e02c49abe12929c67e7d1cb55
+refs/heads/master: 10b614eaa847447c2c8646030728309d14bd2d05
diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile
index 1462ed86d40a..dc3154e49279 100644
--- a/trunk/Documentation/DocBook/Makefile
+++ b/trunk/Documentation/DocBook/Makefile
@@ -6,7 +6,7 @@
# To add a new book the only step required is to add the book to the
# list of DOCBOOKS.
-DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \
+DOCBOOKS := z8530book.xml mcabook.xml \
kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
procfs-guide.xml writing_usb_driver.xml networking.xml \
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
diff --git a/trunk/Documentation/DocBook/device-drivers.tmpl b/trunk/Documentation/DocBook/device-drivers.tmpl
deleted file mode 100644
index 94a20fe8fedf..000000000000
--- a/trunk/Documentation/DocBook/device-drivers.tmpl
+++ /dev/null
@@ -1,418 +0,0 @@
-
-
-
-
-
- Linux Device Drivers
-
-
-
- This documentation 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.
-
-
-
- This program is distributed in the hope that it will be
- useful, but WITHOUT ANY WARRANTY; without even the implied
- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
-
-
- You should have received a copy of the GNU General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
-
-
-
- For more details see the file COPYING in the source
- distribution of Linux.
-
-
-
-
-
-
-
- Driver Basics
- Driver Entry and Exit points
-!Iinclude/linux/init.h
-
-
- Atomic and pointer manipulation
-!Iarch/x86/include/asm/atomic_32.h
-!Iarch/x86/include/asm/unaligned.h
-
-
- Delaying, scheduling, and timer routines
-!Iinclude/linux/sched.h
-!Ekernel/sched.c
-!Ekernel/timer.c
-
- High-resolution timers
-!Iinclude/linux/ktime.h
-!Iinclude/linux/hrtimer.h
-!Ekernel/hrtimer.c
-
- Workqueues and Kevents
-!Ekernel/workqueue.c
-
- Internal Functions
-!Ikernel/exit.c
-!Ikernel/signal.c
-!Iinclude/linux/kthread.h
-!Ekernel/kthread.c
-
-
- Kernel objects manipulation
-
-!Elib/kobject.c
-
-
- Kernel utility functions
-!Iinclude/linux/kernel.h
-!Ekernel/printk.c
-!Ekernel/panic.c
-!Ekernel/sys.c
-!Ekernel/rcupdate.c
-
-
- Device Resource Management
-!Edrivers/base/devres.c
-
-
-
-
-
- Device drivers infrastructure
- Device Drivers Base
-
-!Edrivers/base/driver.c
-!Edrivers/base/core.c
-!Edrivers/base/class.c
-!Edrivers/base/firmware_class.c
-!Edrivers/base/transport_class.c
-
-!Edrivers/base/sys.c
-
-!Edrivers/base/platform.c
-!Edrivers/base/bus.c
-
- Device Drivers Power Management
-!Edrivers/base/power/main.c
-
- Device Drivers ACPI Support
-
-!Edrivers/acpi/scan.c
-!Idrivers/acpi/scan.c
-
-
- Device drivers PnP support
-!Idrivers/pnp/core.c
-
-!Edrivers/pnp/card.c
-!Idrivers/pnp/driver.c
-!Edrivers/pnp/manager.c
-!Edrivers/pnp/support.c
-
- Userspace IO devices
-!Edrivers/uio/uio.c
-!Iinclude/linux/uio_driver.h
-
-
-
-
- Parallel Port Devices
-!Iinclude/linux/parport.h
-!Edrivers/parport/ieee1284.c
-!Edrivers/parport/share.c
-!Idrivers/parport/daisy.c
-
-
-
- Message-based devices
- Fusion message devices
-!Edrivers/message/fusion/mptbase.c
-!Idrivers/message/fusion/mptbase.c
-!Edrivers/message/fusion/mptscsih.c
-!Idrivers/message/fusion/mptscsih.c
-!Idrivers/message/fusion/mptctl.c
-!Idrivers/message/fusion/mptspi.c
-!Idrivers/message/fusion/mptfc.c
-!Idrivers/message/fusion/mptlan.c
-
- I2O message devices
-!Iinclude/linux/i2o.h
-!Idrivers/message/i2o/core.h
-!Edrivers/message/i2o/iop.c
-!Idrivers/message/i2o/iop.c
-!Idrivers/message/i2o/config-osm.c
-!Edrivers/message/i2o/exec-osm.c
-!Idrivers/message/i2o/exec-osm.c
-!Idrivers/message/i2o/bus-osm.c
-!Edrivers/message/i2o/device.c
-!Idrivers/message/i2o/device.c
-!Idrivers/message/i2o/driver.c
-!Idrivers/message/i2o/pci.c
-!Idrivers/message/i2o/i2o_block.c
-!Idrivers/message/i2o/i2o_scsi.c
-!Idrivers/message/i2o/i2o_proc.c
-
-
-
-
- Sound Devices
-!Iinclude/sound/core.h
-!Esound/sound_core.c
-!Iinclude/sound/pcm.h
-!Esound/core/pcm.c
-!Esound/core/device.c
-!Esound/core/info.c
-!Esound/core/rawmidi.c
-!Esound/core/sound.c
-!Esound/core/memory.c
-!Esound/core/pcm_memory.c
-!Esound/core/init.c
-!Esound/core/isadma.c
-!Esound/core/control.c
-!Esound/core/pcm_lib.c
-!Esound/core/hwdep.c
-!Esound/core/pcm_native.c
-!Esound/core/memalloc.c
-
-
-
-
- 16x50 UART Driver
-!Iinclude/linux/serial_core.h
-!Edrivers/serial/serial_core.c
-!Edrivers/serial/8250.c
-
-
-
- Frame Buffer Library
-
-
- The frame buffer drivers depend heavily on four data structures.
- These structures are declared in include/linux/fb.h. They are
- fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs.
- The last three can be made available to and from userland.
-
-
-
- fb_info defines the current state of a particular video card.
- Inside fb_info, there exists a fb_ops structure which is a
- collection of needed functions to make fbdev and fbcon work.
- fb_info is only visible to the kernel.
-
-
-
- fb_var_screeninfo is used to describe the features of a video card
- that are user defined. With fb_var_screeninfo, things such as
- depth and the resolution may be defined.
-
-
-
- The next structure is fb_fix_screeninfo. This defines the
- properties of a card that are created when a mode is set and can't
- be changed otherwise. A good example of this is the start of the
- frame buffer memory. This "locks" the address of the frame buffer
- memory, so that it cannot be changed or moved.
-
-
-
- The last structure is fb_monospecs. In the old API, there was
- little importance for fb_monospecs. This allowed for forbidden things
- such as setting a mode of 800x600 on a fix frequency monitor. With
- the new API, fb_monospecs prevents such things, and if used
- correctly, can prevent a monitor from being cooked. fb_monospecs
- will not be useful until kernels 2.5.x.
-
-
- Frame Buffer Memory
-!Edrivers/video/fbmem.c
-
-
- Frame Buffer Colormap
-!Edrivers/video/fbcmap.c
-
-
- Frame Buffer Video Mode Database
-!Idrivers/video/modedb.c
-!Edrivers/video/modedb.c
-
- Frame Buffer Macintosh Video Mode Database
-!Edrivers/video/macmodes.c
-
- Frame Buffer Fonts
-
- Refer to the file drivers/video/console/fonts.c for more information.
-
-
-
-
-
-
- Input Subsystem
-!Iinclude/linux/input.h
-!Edrivers/input/input.c
-!Edrivers/input/ff-core.c
-!Edrivers/input/ff-memless.c
-
-
-
- Serial Peripheral Interface (SPI)
-
- SPI is the "Serial Peripheral Interface", widely used with
- embedded systems because it is a simple and efficient
- interface: basically a multiplexed shift register.
- Its three signal wires hold a clock (SCK, often in the range
- of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and
- a "Master In, Slave Out" (MISO) data line.
- SPI is a full duplex protocol; for each bit shifted out the
- MOSI line (one per clock) another is shifted in on the MISO line.
- Those bits are assembled into words of various sizes on the
- way to and from system memory.
- An additional chipselect line is usually active-low (nCS);
- four signals are normally used for each peripheral, plus
- sometimes an interrupt.
-
-
- The SPI bus facilities listed here provide a generalized
- interface to declare SPI busses and devices, manage them
- according to the standard Linux driver model, and perform
- input/output operations.
- At this time, only "master" side interfaces are supported,
- where Linux talks to SPI peripherals and does not implement
- such a peripheral itself.
- (Interfaces to support implementing SPI slaves would
- necessarily look different.)
-
-
- The programming interface is structured around two kinds of driver,
- and two kinds of device.
- A "Controller Driver" abstracts the controller hardware, which may
- be as simple as a set of GPIO pins or as complex as a pair of FIFOs
- connected to dual DMA engines on the other side of the SPI shift
- register (maximizing throughput). Such drivers bridge between
- whatever bus they sit on (often the platform bus) and SPI, and
- expose the SPI side of their device as a
- struct spi_master.
- SPI devices are children of that master, represented as a
- struct spi_device and manufactured from
- struct spi_board_info descriptors which
- are usually provided by board-specific initialization code.
- A struct spi_driver is called a
- "Protocol Driver", and is bound to a spi_device using normal
- driver model calls.
-
-
- The I/O model is a set of queued messages. Protocol drivers
- submit one or more struct spi_message
- objects, which are processed and completed asynchronously.
- (There are synchronous wrappers, however.) Messages are
- built from one or more struct spi_transfer
- objects, each of which wraps a full duplex SPI transfer.
- A variety of protocol tweaking options are needed, because
- different chips adopt very different policies for how they
- use the bits transferred with SPI.
-
-!Iinclude/linux/spi/spi.h
-!Fdrivers/spi/spi.c spi_register_board_info
-!Edrivers/spi/spi.c
-
-
-
- I2C and SMBus Subsystem
-
-
- I2C (or without fancy typography, "I2C")
- is an acronym for the "Inter-IC" bus, a simple bus protocol which is
- widely used where low data rate communications suffice.
- Since it's also a licensed trademark, some vendors use another
- name (such as "Two-Wire Interface", TWI) for the same bus.
- I2C only needs two signals (SCL for clock, SDA for data), conserving
- board real estate and minimizing signal quality issues.
- Most I2C devices use seven bit addresses, and bus speeds of up
- to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet
- found wide use.
- I2C is a multi-master bus; open drain signaling is used to
- arbitrate between masters, as well as to handshake and to
- synchronize clocks from slower clients.
-
-
-
- The Linux I2C programming interfaces support only the master
- side of bus interactions, not the slave side.
- The programming interface is structured around two kinds of driver,
- and two kinds of device.
- An I2C "Adapter Driver" abstracts the controller hardware; it binds
- to a physical device (perhaps a PCI device or platform_device) and
- exposes a struct i2c_adapter representing
- each I2C bus segment it manages.
- On each I2C bus segment will be I2C devices represented by a
- struct i2c_client. Those devices will
- be bound to a struct i2c_driver,
- which should follow the standard Linux driver model.
- (At this writing, a legacy model is more widely used.)
- There are functions to perform various I2C protocol operations; at
- this writing all such functions are usable only from task context.
-
-
-
- The System Management Bus (SMBus) is a sibling protocol. Most SMBus
- systems are also I2C conformant. The electrical constraints are
- tighter for SMBus, and it standardizes particular protocol messages
- and idioms. Controllers that support I2C can also support most
- SMBus operations, but SMBus controllers don't support all the protocol
- options that an I2C controller will.
- There are functions to perform various SMBus protocol operations,
- either using I2C primitives or by issuing SMBus commands to
- i2c_adapter devices which don't support those I2C operations.
-
-
-!Iinclude/linux/i2c.h
-!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info
-!Edrivers/i2c/i2c-core.c
-
-
-
diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl
index bc962cda6504..5818ff75786a 100644
--- a/trunk/Documentation/DocBook/kernel-api.tmpl
+++ b/trunk/Documentation/DocBook/kernel-api.tmpl
@@ -38,6 +38,58 @@
+
+ Driver Basics
+ Driver Entry and Exit points
+!Iinclude/linux/init.h
+
+
+ Atomic and pointer manipulation
+!Iarch/x86/include/asm/atomic_32.h
+!Iarch/x86/include/asm/unaligned.h
+
+
+ Delaying, scheduling, and timer routines
+!Iinclude/linux/sched.h
+!Ekernel/sched.c
+!Ekernel/timer.c
+
+ High-resolution timers
+!Iinclude/linux/ktime.h
+!Iinclude/linux/hrtimer.h
+!Ekernel/hrtimer.c
+
+ Workqueues and Kevents
+!Ekernel/workqueue.c
+
+ Internal Functions
+!Ikernel/exit.c
+!Ikernel/signal.c
+!Iinclude/linux/kthread.h
+!Ekernel/kthread.c
+
+
+ Kernel objects manipulation
+
+!Elib/kobject.c
+
+
+ Kernel utility functions
+!Iinclude/linux/kernel.h
+!Ekernel/printk.c
+!Ekernel/panic.c
+!Ekernel/sys.c
+!Ekernel/rcupdate.c
+
+
+ Device Resource Management
+!Edrivers/base/devres.c
+
+
+
+
Data Types
Doubly Linked Lists
@@ -246,6 +298,62 @@ X!Earch/x86/kernel/mca_32.c
!Ikernel/acct.c
+
+ Device drivers infrastructure
+ Device Drivers Base
+
+!Edrivers/base/driver.c
+!Edrivers/base/core.c
+!Edrivers/base/class.c
+!Edrivers/base/firmware_class.c
+!Edrivers/base/transport_class.c
+
+!Edrivers/base/sys.c
+
+!Edrivers/base/platform.c
+!Edrivers/base/bus.c
+
+ Device Drivers Power Management
+!Edrivers/base/power/main.c
+
+ Device Drivers ACPI Support
+
+!Edrivers/acpi/scan.c
+!Idrivers/acpi/scan.c
+
+
+ Device drivers PnP support
+!Idrivers/pnp/core.c
+
+!Edrivers/pnp/card.c
+!Idrivers/pnp/driver.c
+!Edrivers/pnp/manager.c
+!Edrivers/pnp/support.c
+
+ Userspace IO devices
+!Edrivers/uio/uio.c
+!Iinclude/linux/uio_driver.h
+
+
+
Block Devices
!Eblock/blk-core.c
@@ -273,6 +381,275 @@ X!Earch/x86/kernel/mca_32.c
!Edrivers/char/misc.c
+
+ Parallel Port Devices
+!Iinclude/linux/parport.h
+!Edrivers/parport/ieee1284.c
+!Edrivers/parport/share.c
+!Idrivers/parport/daisy.c
+
+
+
+ Message-based devices
+ Fusion message devices
+!Edrivers/message/fusion/mptbase.c
+!Idrivers/message/fusion/mptbase.c
+!Edrivers/message/fusion/mptscsih.c
+!Idrivers/message/fusion/mptscsih.c
+!Idrivers/message/fusion/mptctl.c
+!Idrivers/message/fusion/mptspi.c
+!Idrivers/message/fusion/mptfc.c
+!Idrivers/message/fusion/mptlan.c
+
+ I2O message devices
+!Iinclude/linux/i2o.h
+!Idrivers/message/i2o/core.h
+!Edrivers/message/i2o/iop.c
+!Idrivers/message/i2o/iop.c
+!Idrivers/message/i2o/config-osm.c
+!Edrivers/message/i2o/exec-osm.c
+!Idrivers/message/i2o/exec-osm.c
+!Idrivers/message/i2o/bus-osm.c
+!Edrivers/message/i2o/device.c
+!Idrivers/message/i2o/device.c
+!Idrivers/message/i2o/driver.c
+!Idrivers/message/i2o/pci.c
+!Idrivers/message/i2o/i2o_block.c
+!Idrivers/message/i2o/i2o_scsi.c
+!Idrivers/message/i2o/i2o_proc.c
+
+
+
+
+ Sound Devices
+!Iinclude/sound/core.h
+!Esound/sound_core.c
+!Iinclude/sound/pcm.h
+!Esound/core/pcm.c
+!Esound/core/device.c
+!Esound/core/info.c
+!Esound/core/rawmidi.c
+!Esound/core/sound.c
+!Esound/core/memory.c
+!Esound/core/pcm_memory.c
+!Esound/core/init.c
+!Esound/core/isadma.c
+!Esound/core/control.c
+!Esound/core/pcm_lib.c
+!Esound/core/hwdep.c
+!Esound/core/pcm_native.c
+!Esound/core/memalloc.c
+
+
+
+
+ 16x50 UART Driver
+!Iinclude/linux/serial_core.h
+!Edrivers/serial/serial_core.c
+!Edrivers/serial/8250.c
+
+
+
+ Frame Buffer Library
+
+
+ The frame buffer drivers depend heavily on four data structures.
+ These structures are declared in include/linux/fb.h. They are
+ fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs.
+ The last three can be made available to and from userland.
+
+
+
+ fb_info defines the current state of a particular video card.
+ Inside fb_info, there exists a fb_ops structure which is a
+ collection of needed functions to make fbdev and fbcon work.
+ fb_info is only visible to the kernel.
+
+
+
+ fb_var_screeninfo is used to describe the features of a video card
+ that are user defined. With fb_var_screeninfo, things such as
+ depth and the resolution may be defined.
+
+
+
+ The next structure is fb_fix_screeninfo. This defines the
+ properties of a card that are created when a mode is set and can't
+ be changed otherwise. A good example of this is the start of the
+ frame buffer memory. This "locks" the address of the frame buffer
+ memory, so that it cannot be changed or moved.
+
+
+
+ The last structure is fb_monospecs. In the old API, there was
+ little importance for fb_monospecs. This allowed for forbidden things
+ such as setting a mode of 800x600 on a fix frequency monitor. With
+ the new API, fb_monospecs prevents such things, and if used
+ correctly, can prevent a monitor from being cooked. fb_monospecs
+ will not be useful until kernels 2.5.x.
+
+
+ Frame Buffer Memory
+!Edrivers/video/fbmem.c
+
+
+ Frame Buffer Colormap
+!Edrivers/video/fbcmap.c
+
+
+ Frame Buffer Video Mode Database
+!Idrivers/video/modedb.c
+!Edrivers/video/modedb.c
+
+ Frame Buffer Macintosh Video Mode Database
+!Edrivers/video/macmodes.c
+
+ Frame Buffer Fonts
+
+ Refer to the file drivers/video/console/fonts.c for more information.
+
+
+
+
+
+
+ Input Subsystem
+!Iinclude/linux/input.h
+!Edrivers/input/input.c
+!Edrivers/input/ff-core.c
+!Edrivers/input/ff-memless.c
+
+
+
+ Serial Peripheral Interface (SPI)
+
+ SPI is the "Serial Peripheral Interface", widely used with
+ embedded systems because it is a simple and efficient
+ interface: basically a multiplexed shift register.
+ Its three signal wires hold a clock (SCK, often in the range
+ of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and
+ a "Master In, Slave Out" (MISO) data line.
+ SPI is a full duplex protocol; for each bit shifted out the
+ MOSI line (one per clock) another is shifted in on the MISO line.
+ Those bits are assembled into words of various sizes on the
+ way to and from system memory.
+ An additional chipselect line is usually active-low (nCS);
+ four signals are normally used for each peripheral, plus
+ sometimes an interrupt.
+
+
+ The SPI bus facilities listed here provide a generalized
+ interface to declare SPI busses and devices, manage them
+ according to the standard Linux driver model, and perform
+ input/output operations.
+ At this time, only "master" side interfaces are supported,
+ where Linux talks to SPI peripherals and does not implement
+ such a peripheral itself.
+ (Interfaces to support implementing SPI slaves would
+ necessarily look different.)
+
+
+ The programming interface is structured around two kinds of driver,
+ and two kinds of device.
+ A "Controller Driver" abstracts the controller hardware, which may
+ be as simple as a set of GPIO pins or as complex as a pair of FIFOs
+ connected to dual DMA engines on the other side of the SPI shift
+ register (maximizing throughput). Such drivers bridge between
+ whatever bus they sit on (often the platform bus) and SPI, and
+ expose the SPI side of their device as a
+ struct spi_master.
+ SPI devices are children of that master, represented as a
+ struct spi_device and manufactured from
+ struct spi_board_info descriptors which
+ are usually provided by board-specific initialization code.
+ A struct spi_driver is called a
+ "Protocol Driver", and is bound to a spi_device using normal
+ driver model calls.
+
+
+ The I/O model is a set of queued messages. Protocol drivers
+ submit one or more struct spi_message
+ objects, which are processed and completed asynchronously.
+ (There are synchronous wrappers, however.) Messages are
+ built from one or more struct spi_transfer
+ objects, each of which wraps a full duplex SPI transfer.
+ A variety of protocol tweaking options are needed, because
+ different chips adopt very different policies for how they
+ use the bits transferred with SPI.
+
+!Iinclude/linux/spi/spi.h
+!Fdrivers/spi/spi.c spi_register_board_info
+!Edrivers/spi/spi.c
+
+
+
+ I2C and SMBus Subsystem
+
+
+ I2C (or without fancy typography, "I2C")
+ is an acronym for the "Inter-IC" bus, a simple bus protocol which is
+ widely used where low data rate communications suffice.
+ Since it's also a licensed trademark, some vendors use another
+ name (such as "Two-Wire Interface", TWI) for the same bus.
+ I2C only needs two signals (SCL for clock, SDA for data), conserving
+ board real estate and minimizing signal quality issues.
+ Most I2C devices use seven bit addresses, and bus speeds of up
+ to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet
+ found wide use.
+ I2C is a multi-master bus; open drain signaling is used to
+ arbitrate between masters, as well as to handshake and to
+ synchronize clocks from slower clients.
+
+
+
+ The Linux I2C programming interfaces support only the master
+ side of bus interactions, not the slave side.
+ The programming interface is structured around two kinds of driver,
+ and two kinds of device.
+ An I2C "Adapter Driver" abstracts the controller hardware; it binds
+ to a physical device (perhaps a PCI device or platform_device) and
+ exposes a struct i2c_adapter representing
+ each I2C bus segment it manages.
+ On each I2C bus segment will be I2C devices represented by a
+ struct i2c_client. Those devices will
+ be bound to a struct i2c_driver,
+ which should follow the standard Linux driver model.
+ (At this writing, a legacy model is more widely used.)
+ There are functions to perform various I2C protocol operations; at
+ this writing all such functions are usable only from task context.
+
+
+
+ The System Management Bus (SMBus) is a sibling protocol. Most SMBus
+ systems are also I2C conformant. The electrical constraints are
+ tighter for SMBus, and it standardizes particular protocol messages
+ and idioms. Controllers that support I2C can also support most
+ SMBus operations, but SMBus controllers don't support all the protocol
+ options that an I2C controller will.
+ There are functions to perform various SMBus protocol operations,
+ either using I2C primitives or by issuing SMBus commands to
+ i2c_adapter devices which don't support those I2C operations.
+
+
+!Iinclude/linux/i2c.h
+!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info
+!Edrivers/i2c/i2c-core.c
+
+
Clock Framework
diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt
index f6d5d5b9b2b1..b182626739ea 100644
--- a/trunk/Documentation/kernel-parameters.txt
+++ b/trunk/Documentation/kernel-parameters.txt
@@ -114,7 +114,7 @@ In addition, the following text indicates that the option:
Parameters denoted with BOOT are actually interpreted by the boot
loader, and have no meaning to the kernel directly.
Do not modify the syntax of boot loader parameters without extreme
-need or coordination with .
+need or coordination with .
There are also arch-specific kernel-parameters not documented here.
See for example .
@@ -134,7 +134,7 @@ and is between 256 and 4096 characters. It is defined in the file
acpi= [HW,ACPI,X86-64,i386]
Advanced Configuration and Power Interface
- Format: { force | off | ht | strict | noirq | rsdt }
+ Format: { force | off | ht | strict | noirq }
force -- enable ACPI if default was off
off -- disable ACPI if default was on
noirq -- do not use ACPI for IRQ routing
@@ -2449,7 +2449,7 @@ and is between 256 and 4096 characters. It is defined in the file
See Documentation/fb/modedb.txt.
vga= [BOOT,X86-32] Select a particular video mode
- See Documentation/x86/boot.txt and
+ See Documentation/x86/i386/boot.txt and
Documentation/svga.txt.
Use vga=ask for menu.
This is actually a boot loader parameter; the value is
diff --git a/trunk/Makefile b/trunk/Makefile
index 27fb890a2bff..96628d0b48d2 100644
--- a/trunk/Makefile
+++ b/trunk/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 29
-EXTRAVERSION = -rc6
+EXTRAVERSION = -rc5
NAME = Erotic Pickled Herring
# *DOCUMENTATION*
diff --git a/trunk/arch/x86/boot/compressed/head_32.S b/trunk/arch/x86/boot/compressed/head_32.S
index 3a8a866fb2e2..29c5fbf08392 100644
--- a/trunk/arch/x86/boot/compressed/head_32.S
+++ b/trunk/arch/x86/boot/compressed/head_32.S
@@ -25,12 +25,14 @@
#include
#include
-#include
+#include
#include
#include
.section ".text.head","ax",@progbits
-ENTRY(startup_32)
+ .globl startup_32
+
+startup_32:
cld
/* test KEEP_SEGMENTS flag to see if the bootloader is asking
* us to not reload segments */
@@ -111,8 +113,6 @@ ENTRY(startup_32)
*/
leal relocated(%ebx), %eax
jmp *%eax
-ENDPROC(startup_32)
-
.section ".text"
relocated:
diff --git a/trunk/arch/x86/boot/compressed/head_64.S b/trunk/arch/x86/boot/compressed/head_64.S
index ed4a82948002..1d5dff4123e1 100644
--- a/trunk/arch/x86/boot/compressed/head_64.S
+++ b/trunk/arch/x86/boot/compressed/head_64.S
@@ -26,8 +26,8 @@
#include
#include
-#include
-#include
+#include
+#include
#include
#include
#include
@@ -35,7 +35,9 @@
.section ".text.head"
.code32
-ENTRY(startup_32)
+ .globl startup_32
+
+startup_32:
cld
/* test KEEP_SEGMENTS flag to see if the bootloader is asking
* us to not reload segments */
@@ -174,7 +176,6 @@ ENTRY(startup_32)
/* Jump from 32bit compatibility mode into 64bit mode. */
lret
-ENDPROC(startup_32)
no_longmode:
/* This isn't an x86-64 CPU so hang */
@@ -294,6 +295,7 @@ relocated:
call decompress_kernel
popq %rsi
+
/*
* Jump to the decompressed kernel.
*/
diff --git a/trunk/arch/x86/boot/copy.S b/trunk/arch/x86/boot/copy.S
index 11f272c6f5e9..ef50c84e8b4b 100644
--- a/trunk/arch/x86/boot/copy.S
+++ b/trunk/arch/x86/boot/copy.S
@@ -8,8 +8,6 @@
*
* ----------------------------------------------------------------------- */
-#include
-
/*
* Memory copy routines
*/
@@ -17,7 +15,9 @@
.code16gcc
.text
-GLOBAL(memcpy)
+ .globl memcpy
+ .type memcpy, @function
+memcpy:
pushw %si
pushw %di
movw %ax, %di
@@ -31,9 +31,11 @@ GLOBAL(memcpy)
popw %di
popw %si
ret
-ENDPROC(memcpy)
+ .size memcpy, .-memcpy
-GLOBAL(memset)
+ .globl memset
+ .type memset, @function
+memset:
pushw %di
movw %ax, %di
movzbl %dl, %eax
@@ -46,42 +48,52 @@ GLOBAL(memset)
rep; stosb
popw %di
ret
-ENDPROC(memset)
+ .size memset, .-memset
-GLOBAL(copy_from_fs)
+ .globl copy_from_fs
+ .type copy_from_fs, @function
+copy_from_fs:
pushw %ds
pushw %fs
popw %ds
call memcpy
popw %ds
ret
-ENDPROC(copy_from_fs)
+ .size copy_from_fs, .-copy_from_fs
-GLOBAL(copy_to_fs)
+ .globl copy_to_fs
+ .type copy_to_fs, @function
+copy_to_fs:
pushw %es
pushw %fs
popw %es
call memcpy
popw %es
ret
-ENDPROC(copy_to_fs)
+ .size copy_to_fs, .-copy_to_fs
#if 0 /* Not currently used, but can be enabled as needed */
-GLOBAL(copy_from_gs)
+
+ .globl copy_from_gs
+ .type copy_from_gs, @function
+copy_from_gs:
pushw %ds
pushw %gs
popw %ds
call memcpy
popw %ds
ret
-ENDPROC(copy_from_gs)
+ .size copy_from_gs, .-copy_from_gs
+ .globl copy_to_gs
-GLOBAL(copy_to_gs)
+ .type copy_to_gs, @function
+copy_to_gs:
pushw %es
pushw %gs
popw %es
call memcpy
popw %es
ret
-ENDPROC(copy_to_gs)
+ .size copy_to_gs, .-copy_to_gs
+
#endif
diff --git a/trunk/arch/x86/boot/header.S b/trunk/arch/x86/boot/header.S
index 7ccff4884a23..b993062e9a5f 100644
--- a/trunk/arch/x86/boot/header.S
+++ b/trunk/arch/x86/boot/header.S
@@ -19,7 +19,7 @@
#include
#include
#include
-#include
+#include
#include
#include "boot.h"
#include "offsets.h"
diff --git a/trunk/arch/x86/boot/pmjump.S b/trunk/arch/x86/boot/pmjump.S
index 019c17a75851..141b6e20ed31 100644
--- a/trunk/arch/x86/boot/pmjump.S
+++ b/trunk/arch/x86/boot/pmjump.S
@@ -15,15 +15,18 @@
#include
#include
#include
-#include
.text
+
+ .globl protected_mode_jump
+ .type protected_mode_jump, @function
+
.code16
/*
* void protected_mode_jump(u32 entrypoint, u32 bootparams);
*/
-GLOBAL(protected_mode_jump)
+protected_mode_jump:
movl %edx, %esi # Pointer to boot_params table
xorl %ebx, %ebx
@@ -44,10 +47,12 @@ GLOBAL(protected_mode_jump)
.byte 0x66, 0xea # ljmpl opcode
2: .long in_pm32 # offset
.word __BOOT_CS # segment
-ENDPROC(protected_mode_jump)
+
+ .size protected_mode_jump, .-protected_mode_jump
.code32
-GLOBAL(in_pm32)
+ .type in_pm32, @function
+in_pm32:
# Set up data segments for flat 32-bit mode
movl %ecx, %ds
movl %ecx, %es
@@ -73,4 +78,5 @@ GLOBAL(in_pm32)
lldt %cx
jmpl *%eax # Jump to the 32-bit entrypoint
-ENDPROC(in_pm32)
+
+ .size in_pm32, .-in_pm32
diff --git a/trunk/arch/x86/ia32/ia32_signal.c b/trunk/arch/x86/ia32/ia32_signal.c
index 588a7aa937e1..dd77ac0cac46 100644
--- a/trunk/arch/x86/ia32/ia32_signal.c
+++ b/trunk/arch/x86/ia32/ia32_signal.c
@@ -33,6 +33,8 @@
#include
#include
+#define DEBUG_SIG 0
+
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
#define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \
@@ -188,47 +190,42 @@ asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
/*
* Do a signal return; undo the signal stack.
*/
-#define loadsegment_gs(v) load_gs_index(v)
-#define loadsegment_fs(v) loadsegment(fs, v)
-#define loadsegment_ds(v) loadsegment(ds, v)
-#define loadsegment_es(v) loadsegment(es, v)
-
-#define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
-#define set_user_seg(seg, v) loadsegment_##seg(v)
-
#define COPY(x) { \
get_user_ex(regs->x, &sc->x); \
}
-#define GET_SEG(seg) ({ \
- unsigned short tmp; \
- get_user_ex(tmp, &sc->seg); \
- tmp; \
-})
-
-#define COPY_SEG_CPL3(seg) do { \
- regs->seg = GET_SEG(seg) | 3; \
-} while (0)
+#define COPY_SEG_CPL3(seg) { \
+ unsigned short tmp; \
+ get_user_ex(tmp, &sc->seg); \
+ regs->seg = tmp | 3; \
+}
#define RELOAD_SEG(seg) { \
- unsigned int pre = GET_SEG(seg); \
- unsigned int cur = get_user_seg(seg); \
+ unsigned int cur, pre; \
+ get_user_ex(pre, &sc->seg); \
+ savesegment(seg, cur); \
pre |= 3; \
if (pre != cur) \
- set_user_seg(seg, pre); \
+ loadsegment(seg, pre); \
}
static int ia32_restore_sigcontext(struct pt_regs *regs,
struct sigcontext_ia32 __user *sc,
unsigned int *pax)
{
- unsigned int tmpflags, err = 0;
+ unsigned int tmpflags, gs, oldgs, err = 0;
void __user *buf;
u32 tmp;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;
+#if DEBUG_SIG
+ printk(KERN_DEBUG "SIG restore_sigcontext: "
+ "sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
+ sc, sc->err, sc->ip, sc->cs, sc->flags);
+#endif
+
get_user_try {
/*
* Reload fs and gs if they have changed in the signal
@@ -236,7 +233,12 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
* the handler, but does not clobber them at least in the
* normal case.
*/
- RELOAD_SEG(gs);
+ get_user_ex(gs, &sc->gs);
+ gs |= 3;
+ savesegment(gs, oldgs);
+ if (gs != oldgs)
+ load_gs_index(gs);
+
RELOAD_SEG(fs);
RELOAD_SEG(ds);
RELOAD_SEG(es);
@@ -335,13 +337,17 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
void __user *fpstate,
struct pt_regs *regs, unsigned int mask)
{
- int err = 0;
+ int tmp, err = 0;
put_user_try {
- put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
- put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
- put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
- put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
+ savesegment(gs, tmp);
+ put_user_ex(tmp, (unsigned int __user *)&sc->gs);
+ savesegment(fs, tmp);
+ put_user_ex(tmp, (unsigned int __user *)&sc->fs);
+ savesegment(ds, tmp);
+ put_user_ex(tmp, (unsigned int __user *)&sc->ds);
+ savesegment(es, tmp);
+ put_user_ex(tmp, (unsigned int __user *)&sc->es);
put_user_ex(regs->di, &sc->di);
put_user_ex(regs->si, &sc->si);
@@ -482,6 +488,11 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
regs->cs = __USER32_CS;
regs->ss = __USER32_DS;
+#if DEBUG_SIG
+ printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
+ current->comm, current->pid, frame, regs->ip, frame->pretcode);
+#endif
+
return 0;
}
@@ -563,5 +574,10 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->cs = __USER32_CS;
regs->ss = __USER32_DS;
+#if DEBUG_SIG
+ printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
+ current->comm, current->pid, frame, regs->ip, frame->pretcode);
+#endif
+
return 0;
}
diff --git a/trunk/arch/x86/include/asm/io.h b/trunk/arch/x86/include/asm/io.h
index 683d0b4c00fc..4f8e820cf38f 100644
--- a/trunk/arch/x86/include/asm/io.h
+++ b/trunk/arch/x86/include/asm/io.h
@@ -124,15 +124,10 @@ static inline void *phys_to_virt(phys_addr_t address)
/*
* ISA I/O bus memory addresses are 1:1 with the physical address.
- * However, we truncate the address to unsigned int to avoid undesirable
- * promitions in legacy drivers.
*/
-static inline unsigned int isa_virt_to_bus(volatile void *address)
-{
- return (unsigned int)virt_to_phys(address);
-}
-#define isa_page_to_bus(page) ((unsigned int)page_to_phys(page))
-#define isa_bus_to_virt phys_to_virt
+#define isa_virt_to_bus (unsigned long)virt_to_phys
+#define isa_page_to_bus page_to_phys
+#define isa_bus_to_virt phys_to_virt
/*
* However PCI ones are not necessarily 1:1 and therefore these interfaces
diff --git a/trunk/arch/x86/include/asm/iomap.h b/trunk/arch/x86/include/asm/iomap.h
index bd46495ff7de..c1f06289b14b 100644
--- a/trunk/arch/x86/include/asm/iomap.h
+++ b/trunk/arch/x86/include/asm/iomap.h
@@ -23,12 +23,6 @@
#include
#include
-int
-reserve_io_memtype_wc(u64 base, unsigned long size, pgprot_t *prot);
-
-void
-free_io_memtype(u64 base, unsigned long size);
-
void *
iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot);
diff --git a/trunk/arch/x86/include/asm/irq_vectors.h b/trunk/arch/x86/include/asm/irq_vectors.h
index 8a285f356f8a..b07278c55e9e 100644
--- a/trunk/arch/x86/include/asm/irq_vectors.h
+++ b/trunk/arch/x86/include/asm/irq_vectors.h
@@ -128,7 +128,7 @@
#ifndef __ASSEMBLY__
static inline int invalid_vm86_irq(int irq)
{
- return irq < FIRST_VM86_IRQ || irq > LAST_VM86_IRQ;
+ return irq < 3 || irq > 15;
}
#endif
diff --git a/trunk/arch/x86/include/asm/linkage.h b/trunk/arch/x86/include/asm/linkage.h
index 9320e2a8a26a..5d98d0b68ffc 100644
--- a/trunk/arch/x86/include/asm/linkage.h
+++ b/trunk/arch/x86/include/asm/linkage.h
@@ -52,14 +52,70 @@
#endif
-#define GLOBAL(name) \
- .globl name; \
- name:
-
#ifdef CONFIG_X86_ALIGNMENT_16
#define __ALIGN .align 16,0x90
#define __ALIGN_STR ".align 16,0x90"
#endif
+/*
+ * to check ENTRY_X86/END_X86 and
+ * KPROBE_ENTRY_X86/KPROBE_END_X86
+ * unbalanced-missed-mixed appearance
+ */
+#define __set_entry_x86 .set ENTRY_X86_IN, 0
+#define __unset_entry_x86 .set ENTRY_X86_IN, 1
+#define __set_kprobe_x86 .set KPROBE_X86_IN, 0
+#define __unset_kprobe_x86 .set KPROBE_X86_IN, 1
+
+#define __macro_err_x86 .error "ENTRY_X86/KPROBE_X86 unbalanced,missed,mixed"
+
+#define __check_entry_x86 \
+ .ifdef ENTRY_X86_IN; \
+ .ifeq ENTRY_X86_IN; \
+ __macro_err_x86; \
+ .abort; \
+ .endif; \
+ .endif
+
+#define __check_kprobe_x86 \
+ .ifdef KPROBE_X86_IN; \
+ .ifeq KPROBE_X86_IN; \
+ __macro_err_x86; \
+ .abort; \
+ .endif; \
+ .endif
+
+#define __check_entry_kprobe_x86 \
+ __check_entry_x86; \
+ __check_kprobe_x86
+
+#define ENTRY_KPROBE_FINAL_X86 __check_entry_kprobe_x86
+
+#define ENTRY_X86(name) \
+ __check_entry_kprobe_x86; \
+ __set_entry_x86; \
+ .globl name; \
+ __ALIGN; \
+ name:
+
+#define END_X86(name) \
+ __unset_entry_x86; \
+ __check_entry_kprobe_x86; \
+ .size name, .-name
+
+#define KPROBE_ENTRY_X86(name) \
+ __check_entry_kprobe_x86; \
+ __set_kprobe_x86; \
+ .pushsection .kprobes.text, "ax"; \
+ .globl name; \
+ __ALIGN; \
+ name:
+
+#define KPROBE_END_X86(name) \
+ __unset_kprobe_x86; \
+ __check_entry_kprobe_x86; \
+ .size name, .-name; \
+ .popsection
+
#endif /* _ASM_X86_LINKAGE_H */
diff --git a/trunk/arch/x86/include/asm/page_32_types.h b/trunk/arch/x86/include/asm/page_32_types.h
index f1e4a79a6e41..b5486aaf36ec 100644
--- a/trunk/arch/x86/include/asm/page_32_types.h
+++ b/trunk/arch/x86/include/asm/page_32_types.h
@@ -33,10 +33,12 @@
/* 44=32+12, the limit we can fit into an unsigned long pfn */
#define __PHYSICAL_MASK_SHIFT 44
#define __VIRTUAL_MASK_SHIFT 32
+#define PAGETABLE_LEVELS 3
#else /* !CONFIG_X86_PAE */
#define __PHYSICAL_MASK_SHIFT 32
#define __VIRTUAL_MASK_SHIFT 32
+#define PAGETABLE_LEVELS 2
#endif /* CONFIG_X86_PAE */
#ifndef __ASSEMBLY__
diff --git a/trunk/arch/x86/include/asm/page_64_types.h b/trunk/arch/x86/include/asm/page_64_types.h
index d38c91b70248..bc73af3eda9c 100644
--- a/trunk/arch/x86/include/asm/page_64_types.h
+++ b/trunk/arch/x86/include/asm/page_64_types.h
@@ -1,6 +1,8 @@
#ifndef _ASM_X86_PAGE_64_DEFS_H
#define _ASM_X86_PAGE_64_DEFS_H
+#define PAGETABLE_LEVELS 4
+
#define THREAD_ORDER 1
#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER)
#define CURRENT_MASK (~(THREAD_SIZE - 1))
diff --git a/trunk/arch/x86/include/asm/page_types.h b/trunk/arch/x86/include/asm/page_types.h
index 2d625da6603c..2c52ff767584 100644
--- a/trunk/arch/x86/include/asm/page_types.h
+++ b/trunk/arch/x86/include/asm/page_types.h
@@ -16,6 +16,12 @@
(ie, 32-bit PAE). */
#define PHYSICAL_PAGE_MASK (((signed long)PAGE_MASK) & __PHYSICAL_MASK)
+/* PTE_PFN_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */
+#define PTE_PFN_MASK ((pteval_t)PHYSICAL_PAGE_MASK)
+
+/* PTE_FLAGS_MASK extracts the flags from a (pte|pmd|pud|pgd)val_t */
+#define PTE_FLAGS_MASK (~PTE_PFN_MASK)
+
#define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT)
#define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1))
diff --git a/trunk/arch/x86/include/asm/pat.h b/trunk/arch/x86/include/asm/pat.h
index b0e70056838e..9709fdff6615 100644
--- a/trunk/arch/x86/include/asm/pat.h
+++ b/trunk/arch/x86/include/asm/pat.h
@@ -15,7 +15,4 @@ extern int reserve_memtype(u64 start, u64 end,
unsigned long req_type, unsigned long *ret_type);
extern int free_memtype(u64 start, u64 end);
-extern int kernel_map_sync_memtype(u64 base, unsigned long size,
- unsigned long flag);
-
#endif /* _ASM_X86_PAT_H */
diff --git a/trunk/arch/x86/include/asm/pgtable-2level_types.h b/trunk/arch/x86/include/asm/pgtable-2level_types.h
index daacc23e3fb9..09ae67efcebd 100644
--- a/trunk/arch/x86/include/asm/pgtable-2level_types.h
+++ b/trunk/arch/x86/include/asm/pgtable-2level_types.h
@@ -17,7 +17,6 @@ typedef union {
#endif /* !__ASSEMBLY__ */
#define SHARED_KERNEL_PMD 0
-#define PAGETABLE_LEVELS 2
/*
* traditional i386 two-level paging structure:
@@ -26,7 +25,6 @@ typedef union {
#define PGDIR_SHIFT 22
#define PTRS_PER_PGD 1024
-
/*
* the i386 is two-level, so we don't really have any
* PMD directory physically.
diff --git a/trunk/arch/x86/include/asm/pgtable-3level_types.h b/trunk/arch/x86/include/asm/pgtable-3level_types.h
index 1bd5876c8649..bcc89625ebe5 100644
--- a/trunk/arch/x86/include/asm/pgtable-3level_types.h
+++ b/trunk/arch/x86/include/asm/pgtable-3level_types.h
@@ -24,8 +24,6 @@ typedef union {
#define SHARED_KERNEL_PMD 1
#endif
-#define PAGETABLE_LEVELS 3
-
/*
* PGDIR_SHIFT determines what a top-level page table entry can map
*/
diff --git a/trunk/arch/x86/include/asm/pgtable_64_types.h b/trunk/arch/x86/include/asm/pgtable_64_types.h
index fbf42b8e0383..2f59135c6f2a 100644
--- a/trunk/arch/x86/include/asm/pgtable_64_types.h
+++ b/trunk/arch/x86/include/asm/pgtable_64_types.h
@@ -18,7 +18,6 @@ typedef struct { pteval_t pte; } pte_t;
#endif /* !__ASSEMBLY__ */
#define SHARED_KERNEL_PMD 0
-#define PAGETABLE_LEVELS 4
/*
* PGDIR_SHIFT determines what a top-level page table entry can map
diff --git a/trunk/arch/x86/include/asm/pgtable_types.h b/trunk/arch/x86/include/asm/pgtable_types.h
index 4d258ad76a0f..9dafe87be2de 100644
--- a/trunk/arch/x86/include/asm/pgtable_types.h
+++ b/trunk/arch/x86/include/asm/pgtable_types.h
@@ -173,12 +173,6 @@
#include
-/* PTE_PFN_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */
-#define PTE_PFN_MASK ((pteval_t)PHYSICAL_PAGE_MASK)
-
-/* PTE_FLAGS_MASK extracts the flags from a (pte|pmd|pud|pgd)val_t */
-#define PTE_FLAGS_MASK (~PTE_PFN_MASK)
-
typedef struct pgprot { pgprotval_t pgprot; } pgprot_t;
typedef struct { pgdval_t pgd; } pgd_t;
diff --git a/trunk/arch/x86/include/asm/processor.h b/trunk/arch/x86/include/asm/processor.h
index c7a98f738210..dabab1a19ddd 100644
--- a/trunk/arch/x86/include/asm/processor.h
+++ b/trunk/arch/x86/include/asm/processor.h
@@ -403,6 +403,7 @@ DECLARE_PER_CPU(unsigned long, stack_canary);
#endif
#endif /* X86_64 */
+extern void print_cpu_info(struct cpuinfo_x86 *);
extern unsigned int xstate_size;
extern void free_thread_xstate(struct task_struct *);
extern struct kmem_cache *task_xstate_cachep;
@@ -861,7 +862,6 @@ static inline void spin_lock_prefetch(const void *x)
* User space process size: 3GB (default).
*/
#define TASK_SIZE PAGE_OFFSET
-#define TASK_SIZE_MAX TASK_SIZE
#define STACK_TOP TASK_SIZE
#define STACK_TOP_MAX STACK_TOP
@@ -921,7 +921,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
/*
* User space process size. 47bits minus one guard page.
*/
-#define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE)
+#define TASK_SIZE64 ((1UL << 47) - PAGE_SIZE)
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
@@ -930,12 +930,12 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
0xc0000000 : 0xFFFFe000)
#define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
- IA32_PAGE_OFFSET : TASK_SIZE_MAX)
+ IA32_PAGE_OFFSET : TASK_SIZE64)
#define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? \
- IA32_PAGE_OFFSET : TASK_SIZE_MAX)
+ IA32_PAGE_OFFSET : TASK_SIZE64)
#define STACK_TOP TASK_SIZE
-#define STACK_TOP_MAX TASK_SIZE_MAX
+#define STACK_TOP_MAX TASK_SIZE64
#define INIT_THREAD { \
.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \
diff --git a/trunk/arch/x86/include/asm/syscalls.h b/trunk/arch/x86/include/asm/syscalls.h
index 7043408f6904..258ef730aaa4 100644
--- a/trunk/arch/x86/include/asm/syscalls.h
+++ b/trunk/arch/x86/include/asm/syscalls.h
@@ -82,7 +82,7 @@ asmlinkage long sys_iopl(unsigned int, struct pt_regs *);
/* kernel/signal_64.c */
asmlinkage long sys_sigaltstack(const stack_t __user *, stack_t __user *,
struct pt_regs *);
-long sys_rt_sigreturn(struct pt_regs *);
+asmlinkage long sys_rt_sigreturn(struct pt_regs *);
/* kernel/sys_x86_64.c */
asmlinkage long sys_mmap(unsigned long, unsigned long, unsigned long,
diff --git a/trunk/arch/x86/include/asm/uaccess_64.h b/trunk/arch/x86/include/asm/uaccess_64.h
index 987a2c10fe20..84210c479fca 100644
--- a/trunk/arch/x86/include/asm/uaccess_64.h
+++ b/trunk/arch/x86/include/asm/uaccess_64.h
@@ -192,26 +192,14 @@ static inline int __copy_from_user_nocache(void *dst, const void __user *src,
unsigned size)
{
might_sleep();
- /*
- * In practice this limit means that large file write()s
- * which get chunked to 4K copies get handled via
- * non-temporal stores here. Smaller writes get handled
- * via regular __copy_from_user():
- */
- if (likely(size >= PAGE_SIZE))
- return __copy_user_nocache(dst, src, size, 1);
- else
- return __copy_from_user(dst, src, size);
+ return __copy_user_nocache(dst, src, size, 1);
}
static inline int __copy_from_user_inatomic_nocache(void *dst,
const void __user *src,
unsigned size)
{
- if (likely(size >= PAGE_SIZE))
- return __copy_user_nocache(dst, src, size, 0);
- else
- return __copy_from_user_inatomic(dst, src, size);
+ return __copy_user_nocache(dst, src, size, 0);
}
unsigned long
diff --git a/trunk/arch/x86/kernel/acpi/realmode/wakeup.S b/trunk/arch/x86/kernel/acpi/realmode/wakeup.S
index 580b4e296010..3355973b12ac 100644
--- a/trunk/arch/x86/kernel/acpi/realmode/wakeup.S
+++ b/trunk/arch/x86/kernel/acpi/realmode/wakeup.S
@@ -3,8 +3,8 @@
*/
#include
#include
-#include
-#include
+#include
+#include
#include
.code16
diff --git a/trunk/arch/x86/kernel/acpi/wakeup_32.S b/trunk/arch/x86/kernel/acpi/wakeup_32.S
index 8ded418b0593..a12e6a9fb659 100644
--- a/trunk/arch/x86/kernel/acpi/wakeup_32.S
+++ b/trunk/arch/x86/kernel/acpi/wakeup_32.S
@@ -1,7 +1,7 @@
.section .text.page_aligned
#include
#include
-#include
+#include
# Copyright 2003, 2008 Pavel Machek , distribute under GPLv2
diff --git a/trunk/arch/x86/kernel/acpi/wakeup_64.S b/trunk/arch/x86/kernel/acpi/wakeup_64.S
index 8ea5164cbd04..96258d9dc974 100644
--- a/trunk/arch/x86/kernel/acpi/wakeup_64.S
+++ b/trunk/arch/x86/kernel/acpi/wakeup_64.S
@@ -1,8 +1,8 @@
.text
#include
#include
-#include
-#include
+#include
+#include
#include
#include
diff --git a/trunk/arch/x86/kernel/apic/summit_32.c b/trunk/arch/x86/kernel/apic/summit_32.c
index cfe7b09015d8..d02f4385707c 100644
--- a/trunk/arch/x86/kernel/apic/summit_32.c
+++ b/trunk/arch/x86/kernel/apic/summit_32.c
@@ -303,12 +303,10 @@ static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
int cpu;
num_bits_set = cpus_weight(*cpumask);
- /* Return id to all */
if (num_bits_set >= nr_cpu_ids)
- return 0xFF;
+ return BAD_APICID;
/*
- * The cpus in the mask must all be on the apic cluster. If are not
- * on the same apicid cluster return default value of target_cpus():
+ * The cpus in the mask must all be on the apic cluster.
*/
cpu = first_cpu(*cpumask);
apicid = summit_cpu_to_logical_apicid(cpu);
@@ -318,9 +316,9 @@ static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
int new_apicid = summit_cpu_to_logical_apicid(cpu);
if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
- printk ("%s: Not a valid mask!\n", __func__);
+ printk("%s: Not a valid mask!\n", __func__);
- return 0xFF;
+ return BAD_APICID;
}
apicid = apicid | new_apicid;
cpus_found++;
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
index 41ab3f064cb1..c2f930d86640 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
@@ -204,12 +204,12 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
}
/* Enable Enhanced PowerSaver */
rdmsrl(MSR_IA32_MISC_ENABLE, val);
- if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
- val |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP;
+ if (!(val & 1 << 16)) {
+ val |= 1 << 16;
wrmsrl(MSR_IA32_MISC_ENABLE, val);
/* Can be locked at 0 */
rdmsrl(MSR_IA32_MISC_ENABLE, val);
- if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
+ if (!(val & 1 << 16)) {
printk(KERN_INFO "eps: Can't enable Enhanced PowerSaver\n");
return -ENODEV;
}
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
index c9f1fdc02830..f08998278a3a 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -390,14 +390,14 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
enable it if not. */
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
- if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
- l |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP;
+ if (!(l & (1<<16))) {
+ l |= (1<<16);
dprintk("trying to enable Enhanced SpeedStep (%x)\n", l);
wrmsr(MSR_IA32_MISC_ENABLE, l, h);
/* check to see if it stuck */
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
- if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
+ if (!(l & (1<<16))) {
printk(KERN_INFO PFX
"couldn't enable Enhanced SpeedStep\n");
return -ENODEV;
diff --git a/trunk/arch/x86/kernel/cpu/intel.c b/trunk/arch/x86/kernel/cpu/intel.c
index 25c559ba8d54..7aeef1d327b1 100644
--- a/trunk/arch/x86/kernel/cpu/intel.c
+++ b/trunk/arch/x86/kernel/cpu/intel.c
@@ -146,10 +146,10 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
*/
if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) {
rdmsr(MSR_IA32_MISC_ENABLE, lo, hi);
- if ((lo & MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE) == 0) {
+ if ((lo & (1<<9)) == 0) {
printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n");
printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n");
- lo |= MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE;
+ lo |= (1<<9); /* Disable hw prefetching */
wrmsr (MSR_IA32_MISC_ENABLE, lo, hi);
}
}
diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/trunk/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
index aa5e287c98e0..4b7d78cdc0a5 100644
--- a/trunk/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
+++ b/trunk/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
@@ -49,13 +49,13 @@ static void intel_init_thermal(struct cpuinfo_x86 *c)
*/
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
h = apic_read(APIC_LVTTHMR);
- if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
+ if ((l & (1 << 3)) && (h & APIC_DM_SMI)) {
printk(KERN_DEBUG
"CPU%d: Thermal monitoring handled by SMI\n", cpu);
return;
}
- if (cpu_has(c, X86_FEATURE_TM2) && (l & MSR_IA32_MISC_ENABLE_TM2))
+ if (cpu_has(c, X86_FEATURE_TM2) && (l & (1 << 13)))
tm2 = 1;
if (h & APIC_VECTOR_MASK) {
@@ -73,7 +73,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c)
wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03, h);
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
- wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h);
+ wrmsr(MSR_IA32_MISC_ENABLE, l | (1 << 3), h);
l = apic_read(APIC_LVTTHMR);
apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
diff --git a/trunk/arch/x86/kernel/cpu/mcheck/p4.c b/trunk/arch/x86/kernel/cpu/mcheck/p4.c
index f53bdcbaf382..9b60fce09f75 100644
--- a/trunk/arch/x86/kernel/cpu/mcheck/p4.c
+++ b/trunk/arch/x86/kernel/cpu/mcheck/p4.c
@@ -85,7 +85,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c)
*/
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
h = apic_read(APIC_LVTTHMR);
- if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) {
+ if ((l & (1<<3)) && (h & APIC_DM_SMI)) {
printk(KERN_DEBUG "CPU%d: Thermal monitoring handled by SMI\n",
cpu);
return; /* -EBUSY */
@@ -111,7 +111,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c)
vendor_thermal_interrupt = intel_thermal_interrupt;
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
- wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h);
+ wrmsr(MSR_IA32_MISC_ENABLE, l | (1<<3), h);
l = apic_read(APIC_LVTTHMR);
apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
diff --git a/trunk/arch/x86/kernel/efi_stub_32.S b/trunk/arch/x86/kernel/efi_stub_32.S
index fbe66e626c09..ef00bb77d7e4 100644
--- a/trunk/arch/x86/kernel/efi_stub_32.S
+++ b/trunk/arch/x86/kernel/efi_stub_32.S
@@ -6,7 +6,7 @@
*/
#include
-#include
+#include
/*
* efi_call_phys(void *, ...) is a function with variable parameters.
@@ -113,7 +113,6 @@ ENTRY(efi_call_phys)
movl (%edx), %ecx
pushl %ecx
ret
-ENDPROC(efi_call_phys)
.previous
.data
diff --git a/trunk/arch/x86/kernel/efi_stub_64.S b/trunk/arch/x86/kernel/efi_stub_64.S
index 4c07ccab8146..99b47d48c9f4 100644
--- a/trunk/arch/x86/kernel/efi_stub_64.S
+++ b/trunk/arch/x86/kernel/efi_stub_64.S
@@ -41,7 +41,6 @@ ENTRY(efi_call0)
addq $32, %rsp
RESTORE_XMM
ret
-ENDPROC(efi_call0)
ENTRY(efi_call1)
SAVE_XMM
@@ -51,7 +50,6 @@ ENTRY(efi_call1)
addq $32, %rsp
RESTORE_XMM
ret
-ENDPROC(efi_call1)
ENTRY(efi_call2)
SAVE_XMM
@@ -61,7 +59,6 @@ ENTRY(efi_call2)
addq $32, %rsp
RESTORE_XMM
ret
-ENDPROC(efi_call2)
ENTRY(efi_call3)
SAVE_XMM
@@ -72,7 +69,6 @@ ENTRY(efi_call3)
addq $32, %rsp
RESTORE_XMM
ret
-ENDPROC(efi_call3)
ENTRY(efi_call4)
SAVE_XMM
@@ -84,7 +80,6 @@ ENTRY(efi_call4)
addq $32, %rsp
RESTORE_XMM
ret
-ENDPROC(efi_call4)
ENTRY(efi_call5)
SAVE_XMM
@@ -97,7 +92,6 @@ ENTRY(efi_call5)
addq $48, %rsp
RESTORE_XMM
ret
-ENDPROC(efi_call5)
ENTRY(efi_call6)
SAVE_XMM
@@ -113,4 +107,3 @@ ENTRY(efi_call6)
addq $48, %rsp
RESTORE_XMM
ret
-ENDPROC(efi_call6)
diff --git a/trunk/arch/x86/kernel/entry_32.S b/trunk/arch/x86/kernel/entry_32.S
index 899e8938e79f..e99206831459 100644
--- a/trunk/arch/x86/kernel/entry_32.S
+++ b/trunk/arch/x86/kernel/entry_32.S
@@ -47,7 +47,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -1359,7 +1359,7 @@ nmi_espfix_stack:
CFI_ADJUST_CFA_OFFSET 4
pushl %esp
CFI_ADJUST_CFA_OFFSET 4
- addl $4, (%esp)
+ addw $4, (%esp)
/* copy the iret frame of 12 bytes */
.rept 3
pushl 16(%esp)
diff --git a/trunk/arch/x86/kernel/entry_64.S b/trunk/arch/x86/kernel/entry_64.S
index 83d1836b9467..fbcf96b295ff 100644
--- a/trunk/arch/x86/kernel/entry_64.S
+++ b/trunk/arch/x86/kernel/entry_64.S
@@ -48,7 +48,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -77,17 +77,20 @@ ENTRY(ftrace_caller)
movq 8(%rbp), %rsi
subq $MCOUNT_INSN_SIZE, %rdi
-GLOBAL(ftrace_call)
+.globl ftrace_call
+ftrace_call:
call ftrace_stub
MCOUNT_RESTORE_FRAME
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
-GLOBAL(ftrace_graph_call)
+.globl ftrace_graph_call
+ftrace_graph_call:
jmp ftrace_stub
#endif
-GLOBAL(ftrace_stub)
+.globl ftrace_stub
+ftrace_stub:
retq
END(ftrace_caller)
@@ -107,7 +110,8 @@ ENTRY(mcount)
jnz ftrace_graph_caller
#endif
-GLOBAL(ftrace_stub)
+.globl ftrace_stub
+ftrace_stub:
retq
trace:
@@ -144,7 +148,9 @@ ENTRY(ftrace_graph_caller)
retq
END(ftrace_graph_caller)
-GLOBAL(return_to_handler)
+
+.globl return_to_handler
+return_to_handler:
subq $80, %rsp
movq %rax, (%rsp)
@@ -182,7 +188,6 @@ GLOBAL(return_to_handler)
ENTRY(native_usergs_sysret64)
swapgs
sysretq
-ENDPROC(native_usergs_sysret64)
#endif /* CONFIG_PARAVIRT */
@@ -628,14 +633,16 @@ tracesys:
* Syscall return path ending with IRET.
* Has correct top of stack, but partial stack frame.
*/
-GLOBAL(int_ret_from_sys_call)
+ .globl int_ret_from_sys_call
+ .globl int_with_check
+int_ret_from_sys_call:
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
testl $3,CS-ARGOFFSET(%rsp)
je retint_restore_args
movl $_TIF_ALLWORK_MASK,%edi
/* edi: mask to check */
-GLOBAL(int_with_check)
+int_with_check:
LOCKDEP_SYS_EXIT_IRQ
GET_THREAD_INFO(%rcx)
movl TI_flags(%rcx),%edx
diff --git a/trunk/arch/x86/kernel/head_32.S b/trunk/arch/x86/kernel/head_32.S
index c32ca19d591a..2a0aad7718d5 100644
--- a/trunk/arch/x86/kernel/head_32.S
+++ b/trunk/arch/x86/kernel/head_32.S
@@ -11,8 +11,8 @@
#include
#include
#include
-#include
-#include
+#include
+#include
#include
#include
#include
diff --git a/trunk/arch/x86/kernel/head_64.S b/trunk/arch/x86/kernel/head_64.S
index 54b29bb24e71..2e648e3a5ea4 100644
--- a/trunk/arch/x86/kernel/head_64.S
+++ b/trunk/arch/x86/kernel/head_64.S
@@ -329,6 +329,8 @@ early_idt_ripmsg:
#endif /* CONFIG_EARLY_PRINTK */
.previous
+.balign PAGE_SIZE
+
#define NEXT_PAGE(name) \
.balign PAGE_SIZE; \
ENTRY(name)
@@ -417,7 +419,7 @@ ENTRY(phys_base)
.section .bss, "aw", @nobits
.align L1_CACHE_BYTES
ENTRY(idt_table)
- .skip IDT_ENTRIES * 16
+ .skip 256 * 16
.section .bss.page_aligned, "aw", @nobits
.align PAGE_SIZE
diff --git a/trunk/arch/x86/kernel/machine_kexec_32.c b/trunk/arch/x86/kernel/machine_kexec_32.c
index f5fc8c781a62..37f420018a41 100644
--- a/trunk/arch/x86/kernel/machine_kexec_32.c
+++ b/trunk/arch/x86/kernel/machine_kexec_32.c
@@ -121,7 +121,7 @@ static void machine_kexec_page_table_set_one(
static void machine_kexec_prepare_page_tables(struct kimage *image)
{
void *control_page;
- pmd_t *pmd = NULL;
+ pmd_t *pmd = 0;
control_page = page_address(image->control_code_page);
#ifdef CONFIG_X86_PAE
diff --git a/trunk/arch/x86/kernel/ptrace.c b/trunk/arch/x86/kernel/ptrace.c
index fb2159a5c817..d2f7cd5b2c83 100644
--- a/trunk/arch/x86/kernel/ptrace.c
+++ b/trunk/arch/x86/kernel/ptrace.c
@@ -268,7 +268,7 @@ static unsigned long debugreg_addr_limit(struct task_struct *task)
if (test_tsk_thread_flag(task, TIF_IA32))
return IA32_PAGE_OFFSET - 3;
#endif
- return TASK_SIZE_MAX - 7;
+ return TASK_SIZE64 - 7;
}
#endif /* CONFIG_X86_32 */
diff --git a/trunk/arch/x86/kernel/relocate_kernel_32.S b/trunk/arch/x86/kernel/relocate_kernel_32.S
index 2064d0aa8d28..a160f3119725 100644
--- a/trunk/arch/x86/kernel/relocate_kernel_32.S
+++ b/trunk/arch/x86/kernel/relocate_kernel_32.S
@@ -7,7 +7,7 @@
*/
#include
-#include
+#include
#include
#include
diff --git a/trunk/arch/x86/kernel/relocate_kernel_64.S b/trunk/arch/x86/kernel/relocate_kernel_64.S
index d32cfb27a479..b0bbdd4829c9 100644
--- a/trunk/arch/x86/kernel/relocate_kernel_64.S
+++ b/trunk/arch/x86/kernel/relocate_kernel_64.S
@@ -7,10 +7,10 @@
*/
#include
-#include
+#include
#include
#include
-#include
+#include
/*
* Must be relocatable PIC code callable as a C function
diff --git a/trunk/arch/x86/kernel/trampoline_32.S b/trunk/arch/x86/kernel/trampoline_32.S
index 66d874e5404c..d8ccc3c6552f 100644
--- a/trunk/arch/x86/kernel/trampoline_32.S
+++ b/trunk/arch/x86/kernel/trampoline_32.S
@@ -29,7 +29,7 @@
#include
#include
-#include
+#include
/* We can free up trampoline after bootup if cpu hotplug is not supported. */
#ifndef CONFIG_HOTPLUG_CPU
diff --git a/trunk/arch/x86/kernel/trampoline_64.S b/trunk/arch/x86/kernel/trampoline_64.S
index cddfb8d386b9..95a012a4664e 100644
--- a/trunk/arch/x86/kernel/trampoline_64.S
+++ b/trunk/arch/x86/kernel/trampoline_64.S
@@ -25,8 +25,8 @@
*/
#include
-#include
-#include
+#include
+#include
#include
#include
#include
diff --git a/trunk/arch/x86/kernel/traps.c b/trunk/arch/x86/kernel/traps.c
index c05430ac1b44..c8c0a7e530be 100644
--- a/trunk/arch/x86/kernel/traps.c
+++ b/trunk/arch/x86/kernel/traps.c
@@ -942,7 +942,7 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
info.si_signo = SIGILL;
info.si_errno = 0;
info.si_code = ILL_BADSTK;
- info.si_addr = NULL;
+ info.si_addr = 0;
if (notify_die(DIE_TRAP, "iret exception",
regs, error_code, 32, SIGILL) == NOTIFY_STOP)
return;
diff --git a/trunk/arch/x86/kernel/vmiclock_32.c b/trunk/arch/x86/kernel/vmiclock_32.c
index 33a788d5879c..49b4cd6707f9 100644
--- a/trunk/arch/x86/kernel/vmiclock_32.c
+++ b/trunk/arch/x86/kernel/vmiclock_32.c
@@ -287,7 +287,8 @@ static struct clocksource clocksource_vmi;
static cycle_t read_real_cycles(void)
{
cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL);
- return max(ret, clocksource_vmi.cycle_last);
+ return ret >= clocksource_vmi.cycle_last ?
+ ret : clocksource_vmi.cycle_last;
}
static struct clocksource clocksource_vmi = {
diff --git a/trunk/arch/x86/kernel/vmlinux_32.lds.S b/trunk/arch/x86/kernel/vmlinux_32.lds.S
index 0d860963f268..3eba7f7bac05 100644
--- a/trunk/arch/x86/kernel/vmlinux_32.lds.S
+++ b/trunk/arch/x86/kernel/vmlinux_32.lds.S
@@ -12,7 +12,7 @@
#include
#include
-#include
+#include
#include
#include
diff --git a/trunk/arch/x86/kernel/vmlinux_64.lds.S b/trunk/arch/x86/kernel/vmlinux_64.lds.S
index fbfced6f6800..087a7f2c639b 100644
--- a/trunk/arch/x86/kernel/vmlinux_64.lds.S
+++ b/trunk/arch/x86/kernel/vmlinux_64.lds.S
@@ -6,7 +6,7 @@
#include
#include
-#include
+#include
#undef i386 /* in case the preprocessor is a 32bit one */
diff --git a/trunk/arch/x86/lib/getuser.S b/trunk/arch/x86/lib/getuser.S
index 51f1504cddd9..ad374003742f 100644
--- a/trunk/arch/x86/lib/getuser.S
+++ b/trunk/arch/x86/lib/getuser.S
@@ -28,7 +28,7 @@
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/trunk/arch/x86/mm/fault.c b/trunk/arch/x86/mm/fault.c
index a03b7279efa0..29644175490f 100644
--- a/trunk/arch/x86/mm/fault.c
+++ b/trunk/arch/x86/mm/fault.c
@@ -1,79 +1,74 @@
/*
* Copyright (C) 1995 Linus Torvalds
- * Copyright (C) 2001, 2002 Andi Kleen, SuSE Labs.
- * Copyright (C) 2008-2009, Red Hat Inc., Ingo Molnar
+ * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs.
*/
-#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#include
-#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include /* For unblank_screen() */
#include
#include
-#include
-#include
+#include /* for max_low_pfn */
#include
-#include
-#include
-#include
-#include
-#include
#include
+#include
+#include
#include
-#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
#include
+#include
+#include
+#include
+#include
+#include
#include
+#include
#include
-#include
/*
- * Page fault error code bits:
- *
- * bit 0 == 0: no page found 1: protection fault
- * bit 1 == 0: read access 1: write access
- * bit 2 == 0: kernel-mode access 1: user-mode access
- * bit 3 == 1: use of reserved bit detected
- * bit 4 == 1: fault was an instruction fetch
+ * Page fault error code bits
+ * bit 0 == 0 means no page found, 1 means protection fault
+ * bit 1 == 0 means read, 1 means write
+ * bit 2 == 0 means kernel, 1 means user-mode
+ * bit 3 == 1 means use of reserved bit detected
+ * bit 4 == 1 means fault was an instruction fetch
*/
-enum x86_pf_error_code {
-
- PF_PROT = 1 << 0,
- PF_WRITE = 1 << 1,
- PF_USER = 1 << 2,
- PF_RSVD = 1 << 3,
- PF_INSTR = 1 << 4,
-};
+#define PF_PROT (1<<0)
+#define PF_WRITE (1<<1)
+#define PF_USER (1<<2)
+#define PF_RSVD (1<<3)
+#define PF_INSTR (1<<4)
-/*
- * Returns 0 if mmiotrace is disabled, or if the fault is not
- * handled by mmiotrace:
- */
static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr)
{
+#ifdef CONFIG_MMIOTRACE
if (unlikely(is_kmmio_active()))
if (kmmio_handler(regs, addr) == 1)
return -1;
+#endif
return 0;
}
static inline int notify_page_fault(struct pt_regs *regs)
{
+#ifdef CONFIG_KPROBES
int ret = 0;
/* kprobe_running() needs smp_processor_id() */
- if (kprobes_built_in() && !user_mode_vm(regs)) {
+ if (!user_mode_vm(regs)) {
preempt_disable();
if (kprobe_running() && kprobe_fault_handler(regs, 14))
ret = 1;
@@ -81,76 +76,29 @@ static inline int notify_page_fault(struct pt_regs *regs)
}
return ret;
+#else
+ return 0;
+#endif
}
/*
- * Prefetch quirks:
- *
- * 32-bit mode:
+ * X86_32
+ * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
+ * Check that here and ignore it.
*
- * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
- * Check that here and ignore it.
+ * X86_64
+ * Sometimes the CPU reports invalid exceptions on prefetch.
+ * Check that here and ignore it.
*
- * 64-bit mode:
- *
- * Sometimes the CPU reports invalid exceptions on prefetch.
- * Check that here and ignore it.
- *
- * Opcode checker based on code by Richard Brunner.
+ * Opcode checker based on code by Richard Brunner
*/
-static inline int
-check_prefetch_opcode(struct pt_regs *regs, unsigned char *instr,
- unsigned char opcode, int *prefetch)
-{
- unsigned char instr_hi = opcode & 0xf0;
- unsigned char instr_lo = opcode & 0x0f;
-
- switch (instr_hi) {
- case 0x20:
- case 0x30:
- /*
- * Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes.
- * In X86_64 long mode, the CPU will signal invalid
- * opcode if some of these prefixes are present so
- * X86_64 will never get here anyway
- */
- return ((instr_lo & 7) == 0x6);
-#ifdef CONFIG_X86_64
- case 0x40:
- /*
- * In AMD64 long mode 0x40..0x4F are valid REX prefixes
- * Need to figure out under what instruction mode the
- * instruction was issued. Could check the LDT for lm,
- * but for now it's good enough to assume that long
- * mode only uses well known segments or kernel.
- */
- return (!user_mode(regs)) || (regs->cs == __USER_CS);
-#endif
- case 0x60:
- /* 0x64 thru 0x67 are valid prefixes in all modes. */
- return (instr_lo & 0xC) == 0x4;
- case 0xF0:
- /* 0xF0, 0xF2, 0xF3 are valid prefixes in all modes. */
- return !instr_lo || (instr_lo>>1) == 1;
- case 0x00:
- /* Prefetch instruction is 0x0F0D or 0x0F18 */
- if (probe_kernel_address(instr, opcode))
- return 0;
-
- *prefetch = (instr_lo == 0xF) &&
- (opcode == 0x0D || opcode == 0x18);
- return 0;
- default:
- return 0;
- }
-}
-
-static int
-is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr)
+static int is_prefetch(struct pt_regs *regs, unsigned long error_code,
+ unsigned long addr)
{
- unsigned char *max_instr;
unsigned char *instr;
+ int scan_more = 1;
int prefetch = 0;
+ unsigned char *max_instr;
/*
* If it was a exec (instruction fetch) fault on NX page, then
@@ -159,170 +107,106 @@ is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr)
if (error_code & PF_INSTR)
return 0;
- instr = (void *)convert_ip_to_linear(current, regs);
+ instr = (unsigned char *)convert_ip_to_linear(current, regs);
max_instr = instr + 15;
if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE)
return 0;
- while (instr < max_instr) {
+ while (scan_more && instr < max_instr) {
unsigned char opcode;
+ unsigned char instr_hi;
+ unsigned char instr_lo;
if (probe_kernel_address(instr, opcode))
break;
+ instr_hi = opcode & 0xf0;
+ instr_lo = opcode & 0x0f;
instr++;
- if (!check_prefetch_opcode(regs, instr, opcode, &prefetch))
+ switch (instr_hi) {
+ case 0x20:
+ case 0x30:
+ /*
+ * Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes.
+ * In X86_64 long mode, the CPU will signal invalid
+ * opcode if some of these prefixes are present so
+ * X86_64 will never get here anyway
+ */
+ scan_more = ((instr_lo & 7) == 0x6);
break;
- }
- return prefetch;
-}
-
-static void
-force_sig_info_fault(int si_signo, int si_code, unsigned long address,
- struct task_struct *tsk)
-{
- siginfo_t info;
-
- info.si_signo = si_signo;
- info.si_errno = 0;
- info.si_code = si_code;
- info.si_addr = (void __user *)address;
-
- force_sig_info(si_signo, &info, tsk);
-}
-
-DEFINE_SPINLOCK(pgd_lock);
-LIST_HEAD(pgd_list);
-
-#ifdef CONFIG_X86_32
-static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
-{
- unsigned index = pgd_index(address);
- pgd_t *pgd_k;
- pud_t *pud, *pud_k;
- pmd_t *pmd, *pmd_k;
-
- pgd += index;
- pgd_k = init_mm.pgd + index;
-
- if (!pgd_present(*pgd_k))
- return NULL;
-
- /*
- * set_pgd(pgd, *pgd_k); here would be useless on PAE
- * and redundant with the set_pmd() on non-PAE. As would
- * set_pud.
- */
- pud = pud_offset(pgd, address);
- pud_k = pud_offset(pgd_k, address);
- if (!pud_present(*pud_k))
- return NULL;
-
- pmd = pmd_offset(pud, address);
- pmd_k = pmd_offset(pud_k, address);
- if (!pmd_present(*pmd_k))
- return NULL;
-
- if (!pmd_present(*pmd)) {
- set_pmd(pmd, *pmd_k);
- arch_flush_lazy_mmu_mode();
- } else {
- BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
- }
-
- return pmd_k;
-}
-
-void vmalloc_sync_all(void)
-{
- unsigned long address;
-
- if (SHARED_KERNEL_PMD)
- return;
-
- for (address = VMALLOC_START & PMD_MASK;
- address >= TASK_SIZE && address < FIXADDR_TOP;
- address += PMD_SIZE) {
-
- unsigned long flags;
- struct page *page;
+#ifdef CONFIG_X86_64
+ case 0x40:
+ /*
+ * In AMD64 long mode 0x40..0x4F are valid REX prefixes
+ * Need to figure out under what instruction mode the
+ * instruction was issued. Could check the LDT for lm,
+ * but for now it's good enough to assume that long
+ * mode only uses well known segments or kernel.
+ */
+ scan_more = (!user_mode(regs)) || (regs->cs == __USER_CS);
+ break;
+#endif
+ case 0x60:
+ /* 0x64 thru 0x67 are valid prefixes in all modes. */
+ scan_more = (instr_lo & 0xC) == 0x4;
+ break;
+ case 0xF0:
+ /* 0xF0, 0xF2, 0xF3 are valid prefixes in all modes. */
+ scan_more = !instr_lo || (instr_lo>>1) == 1;
+ break;
+ case 0x00:
+ /* Prefetch instruction is 0x0F0D or 0x0F18 */
+ scan_more = 0;
- spin_lock_irqsave(&pgd_lock, flags);
- list_for_each_entry(page, &pgd_list, lru) {
- if (!vmalloc_sync_one(page_address(page), address))
+ if (probe_kernel_address(instr, opcode))
break;
+ prefetch = (instr_lo == 0xF) &&
+ (opcode == 0x0D || opcode == 0x18);
+ break;
+ default:
+ scan_more = 0;
+ break;
}
- spin_unlock_irqrestore(&pgd_lock, flags);
}
+ return prefetch;
}
-/*
- * 32-bit:
- *
- * Handle a fault on the vmalloc or module mapping area
- */
-static noinline int vmalloc_fault(unsigned long address)
+static void force_sig_info_fault(int si_signo, int si_code,
+ unsigned long address, struct task_struct *tsk)
{
- unsigned long pgd_paddr;
- pmd_t *pmd_k;
- pte_t *pte_k;
-
- /* Make sure we are in vmalloc area: */
- if (!(address >= VMALLOC_START && address < VMALLOC_END))
- return -1;
-
- /*
- * Synchronize this task's top level page-table
- * with the 'reference' page table.
- *
- * Do _not_ use "current" here. We might be inside
- * an interrupt in the middle of a task switch..
- */
- pgd_paddr = read_cr3();
- pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
- if (!pmd_k)
- return -1;
-
- pte_k = pte_offset_kernel(pmd_k, address);
- if (!pte_present(*pte_k))
- return -1;
+ siginfo_t info;
- return 0;
+ info.si_signo = si_signo;
+ info.si_errno = 0;
+ info.si_code = si_code;
+ info.si_addr = (void __user *)address;
+ force_sig_info(si_signo, &info, tsk);
}
-/*
- * Did it hit the DOS screen memory VA from vm86 mode?
- */
-static inline void
-check_v8086_mode(struct pt_regs *regs, unsigned long address,
- struct task_struct *tsk)
+#ifdef CONFIG_X86_64
+static int bad_address(void *p)
{
- unsigned long bit;
-
- if (!v8086_mode(regs))
- return;
-
- bit = (address - 0xA0000) >> PAGE_SHIFT;
- if (bit < 32)
- tsk->thread.screen_bitmap |= 1 << bit;
+ unsigned long dummy;
+ return probe_kernel_address((unsigned long *)p, dummy);
}
+#endif
static void dump_pagetable(unsigned long address)
{
+#ifdef CONFIG_X86_32
__typeof__(pte_val(__pte(0))) page;
page = read_cr3();
page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT];
-
#ifdef CONFIG_X86_PAE
printk("*pdpt = %016Lx ", page);
if ((page >> PAGE_SHIFT) < max_low_pfn
&& page & _PAGE_PRESENT) {
page &= PAGE_MASK;
page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT)
- & (PTRS_PER_PMD - 1)];
+ & (PTRS_PER_PMD - 1)];
printk(KERN_CONT "*pde = %016Lx ", page);
page &= ~_PAGE_NX;
}
@@ -334,224 +218,123 @@ static void dump_pagetable(unsigned long address)
* We must not directly access the pte in the highpte
* case if the page table is located in highmem.
* And let's rather not kmap-atomic the pte, just in case
- * it's allocated already:
+ * it's allocated already.
*/
if ((page >> PAGE_SHIFT) < max_low_pfn
&& (page & _PAGE_PRESENT)
&& !(page & _PAGE_PSE)) {
-
page &= PAGE_MASK;
page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
- & (PTRS_PER_PTE - 1)];
+ & (PTRS_PER_PTE - 1)];
printk("*pte = %0*Lx ", sizeof(page)*2, (u64)page);
}
printk("\n");
-}
-
-#else /* CONFIG_X86_64: */
-
-void vmalloc_sync_all(void)
-{
- unsigned long address;
-
- for (address = VMALLOC_START & PGDIR_MASK; address <= VMALLOC_END;
- address += PGDIR_SIZE) {
-
- const pgd_t *pgd_ref = pgd_offset_k(address);
- unsigned long flags;
- struct page *page;
-
- if (pgd_none(*pgd_ref))
- continue;
-
- spin_lock_irqsave(&pgd_lock, flags);
- list_for_each_entry(page, &pgd_list, lru) {
- pgd_t *pgd;
- pgd = (pgd_t *)page_address(page) + pgd_index(address);
- if (pgd_none(*pgd))
- set_pgd(pgd, *pgd_ref);
- else
- BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
- }
- spin_unlock_irqrestore(&pgd_lock, flags);
- }
-}
-
-/*
- * 64-bit:
- *
- * Handle a fault on the vmalloc area
- *
- * This assumes no large pages in there.
- */
-static noinline int vmalloc_fault(unsigned long address)
-{
- pgd_t *pgd, *pgd_ref;
- pud_t *pud, *pud_ref;
- pmd_t *pmd, *pmd_ref;
- pte_t *pte, *pte_ref;
-
- /* Make sure we are in vmalloc area: */
- if (!(address >= VMALLOC_START && address < VMALLOC_END))
- return -1;
-
- /*
- * Copy kernel mappings over when needed. This can also
- * happen within a race in page table update. In the later
- * case just flush:
- */
- pgd = pgd_offset(current->active_mm, address);
- pgd_ref = pgd_offset_k(address);
- if (pgd_none(*pgd_ref))
- return -1;
+#else /* CONFIG_X86_64 */
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
- if (pgd_none(*pgd))
- set_pgd(pgd, *pgd_ref);
- else
- BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
+ pgd = (pgd_t *)read_cr3();
- /*
- * Below here mismatches are bugs because these lower tables
- * are shared:
- */
+ pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK);
+ pgd += pgd_index(address);
+ if (bad_address(pgd)) goto bad;
+ printk("PGD %lx ", pgd_val(*pgd));
+ if (!pgd_present(*pgd)) goto ret;
pud = pud_offset(pgd, address);
- pud_ref = pud_offset(pgd_ref, address);
- if (pud_none(*pud_ref))
- return -1;
-
- if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
- BUG();
+ if (bad_address(pud)) goto bad;
+ printk("PUD %lx ", pud_val(*pud));
+ if (!pud_present(*pud) || pud_large(*pud))
+ goto ret;
pmd = pmd_offset(pud, address);
- pmd_ref = pmd_offset(pud_ref, address);
- if (pmd_none(*pmd_ref))
- return -1;
-
- if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
- BUG();
-
- pte_ref = pte_offset_kernel(pmd_ref, address);
- if (!pte_present(*pte_ref))
- return -1;
+ if (bad_address(pmd)) goto bad;
+ printk("PMD %lx ", pmd_val(*pmd));
+ if (!pmd_present(*pmd) || pmd_large(*pmd)) goto ret;
pte = pte_offset_kernel(pmd, address);
-
- /*
- * Don't use pte_page here, because the mappings can point
- * outside mem_map, and the NUMA hash lookup cannot handle
- * that:
- */
- if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref))
- BUG();
-
- return 0;
-}
-
-static const char errata93_warning[] =
-KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"
-KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n"
-KERN_ERR "******* Please consider a BIOS update.\n"
-KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
-
-/*
- * No vm86 mode in 64-bit mode:
- */
-static inline void
-check_v8086_mode(struct pt_regs *regs, unsigned long address,
- struct task_struct *tsk)
-{
-}
-
-static int bad_address(void *p)
-{
- unsigned long dummy;
-
- return probe_kernel_address((unsigned long *)p, dummy);
+ if (bad_address(pte)) goto bad;
+ printk("PTE %lx", pte_val(*pte));
+ret:
+ printk("\n");
+ return;
+bad:
+ printk("BAD\n");
+#endif
}
-static void dump_pagetable(unsigned long address)
+#ifdef CONFIG_X86_32
+static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
{
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
-
- pgd = (pgd_t *)read_cr3();
-
- pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK);
+ unsigned index = pgd_index(address);
+ pgd_t *pgd_k;
+ pud_t *pud, *pud_k;
+ pmd_t *pmd, *pmd_k;
- pgd += pgd_index(address);
- if (bad_address(pgd))
- goto bad;
+ pgd += index;
+ pgd_k = init_mm.pgd + index;
- printk("PGD %lx ", pgd_val(*pgd));
+ if (!pgd_present(*pgd_k))
+ return NULL;
- if (!pgd_present(*pgd))
- goto out;
+ /*
+ * set_pgd(pgd, *pgd_k); here would be useless on PAE
+ * and redundant with the set_pmd() on non-PAE. As would
+ * set_pud.
+ */
pud = pud_offset(pgd, address);
- if (bad_address(pud))
- goto bad;
-
- printk("PUD %lx ", pud_val(*pud));
- if (!pud_present(*pud) || pud_large(*pud))
- goto out;
+ pud_k = pud_offset(pgd_k, address);
+ if (!pud_present(*pud_k))
+ return NULL;
pmd = pmd_offset(pud, address);
- if (bad_address(pmd))
- goto bad;
-
- printk("PMD %lx ", pmd_val(*pmd));
- if (!pmd_present(*pmd) || pmd_large(*pmd))
- goto out;
-
- pte = pte_offset_kernel(pmd, address);
- if (bad_address(pte))
- goto bad;
-
- printk("PTE %lx", pte_val(*pte));
-out:
- printk("\n");
- return;
-bad:
- printk("BAD\n");
+ pmd_k = pmd_offset(pud_k, address);
+ if (!pmd_present(*pmd_k))
+ return NULL;
+ if (!pmd_present(*pmd)) {
+ set_pmd(pmd, *pmd_k);
+ arch_flush_lazy_mmu_mode();
+ } else
+ BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
+ return pmd_k;
}
+#endif
-#endif /* CONFIG_X86_64 */
+#ifdef CONFIG_X86_64
+static const char errata93_warning[] =
+KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"
+KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n"
+KERN_ERR "******* Please consider a BIOS update.\n"
+KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
+#endif
-/*
- * Workaround for K8 erratum #93 & buggy BIOS.
- *
- * BIOS SMM functions are required to use a specific workaround
- * to avoid corruption of the 64bit RIP register on C stepping K8.
- *
- * A lot of BIOS that didn't get tested properly miss this.
- *
- * The OS sees this as a page fault with the upper 32bits of RIP cleared.
- * Try to work around it here.
- *
- * Note we only handle faults in kernel here.
- * Does nothing on 32-bit.
+/* Workaround for K8 erratum #93 & buggy BIOS.
+ BIOS SMM functions are required to use a specific workaround
+ to avoid corruption of the 64bit RIP register on C stepping K8.
+ A lot of BIOS that didn't get tested properly miss this.
+ The OS sees this as a page fault with the upper 32bits of RIP cleared.
+ Try to work around it here.
+ Note we only handle faults in kernel here.
+ Does nothing for X86_32
*/
static int is_errata93(struct pt_regs *regs, unsigned long address)
{
#ifdef CONFIG_X86_64
- static int once;
-
+ static int warned;
if (address != regs->ip)
return 0;
-
if ((address >> 32) != 0)
return 0;
-
address |= 0xffffffffUL << 32;
if ((address >= (u64)_stext && address <= (u64)_etext) ||
(address >= MODULES_VADDR && address <= MODULES_END)) {
- if (!once) {
+ if (!warned) {
printk(errata93_warning);
- once = 1;
+ warned = 1;
}
regs->ip = address;
return 1;
@@ -561,17 +344,16 @@ static int is_errata93(struct pt_regs *regs, unsigned long address)
}
/*
- * Work around K8 erratum #100 K8 in compat mode occasionally jumps
- * to illegal addresses >4GB.
- *
- * We catch this in the page fault handler because these addresses
- * are not reachable. Just detect this case and return. Any code
+ * Work around K8 erratum #100 K8 in compat mode occasionally jumps to illegal
+ * addresses >4GB. We catch this in the page fault handler because these
+ * addresses are not reachable. Just detect this case and return. Any code
* segment in LDT is compatibility mode.
*/
static int is_errata100(struct pt_regs *regs, unsigned long address)
{
#ifdef CONFIG_X86_64
- if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && (address >> 32))
+ if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
+ (address >> 32))
return 1;
#endif
return 0;
@@ -581,9 +363,8 @@ static int is_f00f_bug(struct pt_regs *regs, unsigned long address)
{
#ifdef CONFIG_X86_F00F_BUG
unsigned long nr;
-
/*
- * Pentium F0 0F C7 C8 bug workaround:
+ * Pentium F0 0F C7 C8 bug workaround.
*/
if (boot_cpu_data.f00f_bug) {
nr = (address - idt_descr.address) >> 3;
@@ -597,87 +378,80 @@ static int is_f00f_bug(struct pt_regs *regs, unsigned long address)
return 0;
}
-static const char nx_warning[] = KERN_CRIT
-"kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n";
-
-static void
-show_fault_oops(struct pt_regs *regs, unsigned long error_code,
- unsigned long address)
+static void show_fault_oops(struct pt_regs *regs, unsigned long error_code,
+ unsigned long address)
{
+#ifdef CONFIG_X86_32
if (!oops_may_print())
return;
+#endif
+#ifdef CONFIG_X86_PAE
if (error_code & PF_INSTR) {
unsigned int level;
-
pte_t *pte = lookup_address(address, &level);
if (pte && pte_present(*pte) && !pte_exec(*pte))
- printk(nx_warning, current_uid());
+ printk(KERN_CRIT "kernel tried to execute "
+ "NX-protected page - exploit attempt? "
+ "(uid: %d)\n", current_uid());
}
+#endif
printk(KERN_ALERT "BUG: unable to handle kernel ");
if (address < PAGE_SIZE)
printk(KERN_CONT "NULL pointer dereference");
else
printk(KERN_CONT "paging request");
-
printk(KERN_CONT " at %p\n", (void *) address);
printk(KERN_ALERT "IP:");
printk_address(regs->ip, 1);
-
dump_pagetable(address);
}
-static noinline void
-pgtable_bad(struct pt_regs *regs, unsigned long error_code,
- unsigned long address)
+#ifdef CONFIG_X86_64
+static noinline void pgtable_bad(struct pt_regs *regs,
+ unsigned long error_code, unsigned long address)
{
- struct task_struct *tsk;
- unsigned long flags;
- int sig;
-
- flags = oops_begin();
- tsk = current;
- sig = SIGKILL;
+ unsigned long flags = oops_begin();
+ int sig = SIGKILL;
+ struct task_struct *tsk = current;
printk(KERN_ALERT "%s: Corrupted page table at address %lx\n",
tsk->comm, address);
dump_pagetable(address);
-
- tsk->thread.cr2 = address;
- tsk->thread.trap_no = 14;
- tsk->thread.error_code = error_code;
-
+ tsk->thread.cr2 = address;
+ tsk->thread.trap_no = 14;
+ tsk->thread.error_code = error_code;
if (__die("Bad pagetable", regs, error_code))
sig = 0;
-
oops_end(flags, regs, sig);
}
+#endif
-static noinline void
-no_context(struct pt_regs *regs, unsigned long error_code,
- unsigned long address)
+static noinline void no_context(struct pt_regs *regs,
+ unsigned long error_code, unsigned long address)
{
struct task_struct *tsk = current;
unsigned long *stackend;
+
+#ifdef CONFIG_X86_64
unsigned long flags;
int sig;
+#endif
- /* Are we prepared to handle this kernel fault? */
+ /* Are we prepared to handle this kernel fault? */
if (fixup_exception(regs))
return;
/*
- * 32-bit:
- *
- * Valid to do another page fault here, because if this fault
- * had been triggered by is_prefetch fixup_exception would have
- * handled it.
+ * X86_32
+ * Valid to do another page fault here, because if this fault
+ * had been triggered by is_prefetch fixup_exception would have
+ * handled it.
*
- * 64-bit:
- *
- * Hall of shame of CPU/BIOS bugs.
+ * X86_64
+ * Hall of shame of CPU/BIOS bugs.
*/
if (is_prefetch(regs, error_code, address))
return;
@@ -687,70 +461,54 @@ no_context(struct pt_regs *regs, unsigned long error_code,
/*
* Oops. The kernel tried to access some bad page. We'll have to
- * terminate things with extreme prejudice:
+ * terminate things with extreme prejudice.
*/
+#ifdef CONFIG_X86_32
+ bust_spinlocks(1);
+#else
flags = oops_begin();
+#endif
show_fault_oops(regs, error_code, address);
- stackend = end_of_stack(tsk);
+ stackend = end_of_stack(tsk);
if (*stackend != STACK_END_MAGIC)
printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");
- tsk->thread.cr2 = address;
- tsk->thread.trap_no = 14;
- tsk->thread.error_code = error_code;
+ tsk->thread.cr2 = address;
+ tsk->thread.trap_no = 14;
+ tsk->thread.error_code = error_code;
+#ifdef CONFIG_X86_32
+ die("Oops", regs, error_code);
+ bust_spinlocks(0);
+ do_exit(SIGKILL);
+#else
sig = SIGKILL;
if (__die("Oops", regs, error_code))
sig = 0;
-
/* Executive summary in case the body of the oops scrolled away */
printk(KERN_EMERG "CR2: %016lx\n", address);
-
oops_end(flags, regs, sig);
+#endif
}
-/*
- * Print out info about fatal segfaults, if the show_unhandled_signals
- * sysctl is set:
- */
-static inline void
-show_signal_msg(struct pt_regs *regs, unsigned long error_code,
- unsigned long address, struct task_struct *tsk)
-{
- if (!unhandled_signal(tsk, SIGSEGV))
- return;
-
- if (!printk_ratelimit())
- return;
-
- printk(KERN_CONT "%s%s[%d]: segfault at %lx ip %p sp %p error %lx",
- task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
- tsk->comm, task_pid_nr(tsk), address,
- (void *)regs->ip, (void *)regs->sp, error_code);
-
- print_vma_addr(KERN_CONT " in ", regs->ip);
-
- printk(KERN_CONT "\n");
-}
-
-static void
-__bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
- unsigned long address, int si_code)
+static void __bad_area_nosemaphore(struct pt_regs *regs,
+ unsigned long error_code, unsigned long address,
+ int si_code)
{
struct task_struct *tsk = current;
/* User mode accesses just cause a SIGSEGV */
if (error_code & PF_USER) {
/*
- * It's possible to have interrupts off here:
+ * It's possible to have interrupts off here.
*/
local_irq_enable();
/*
* Valid to do another page fault here because this one came
- * from user space:
+ * from user space.
*/
if (is_prefetch(regs, error_code, address))
return;
@@ -758,16 +516,22 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
if (is_errata100(regs, address))
return;
- if (unlikely(show_unhandled_signals))
- show_signal_msg(regs, error_code, address, tsk);
-
- /* Kernel addresses are always protection faults: */
- tsk->thread.cr2 = address;
- tsk->thread.error_code = error_code | (address >= TASK_SIZE);
- tsk->thread.trap_no = 14;
+ if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
+ printk_ratelimit()) {
+ printk(
+ "%s%s[%d]: segfault at %lx ip %p sp %p error %lx",
+ task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
+ tsk->comm, task_pid_nr(tsk), address,
+ (void *) regs->ip, (void *) regs->sp, error_code);
+ print_vma_addr(" in ", regs->ip);
+ printk("\n");
+ }
+ tsk->thread.cr2 = address;
+ /* Kernel addresses are always protection faults */
+ tsk->thread.error_code = error_code | (address >= TASK_SIZE);
+ tsk->thread.trap_no = 14;
force_sig_info_fault(SIGSEGV, si_code, address, tsk);
-
return;
}
@@ -777,16 +541,15 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
no_context(regs, error_code, address);
}
-static noinline void
-bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
- unsigned long address)
+static noinline void bad_area_nosemaphore(struct pt_regs *regs,
+ unsigned long error_code, unsigned long address)
{
__bad_area_nosemaphore(regs, error_code, address, SEGV_MAPERR);
}
-static void
-__bad_area(struct pt_regs *regs, unsigned long error_code,
- unsigned long address, int si_code)
+static void __bad_area(struct pt_regs *regs,
+ unsigned long error_code, unsigned long address,
+ int si_code)
{
struct mm_struct *mm = current->mm;
@@ -799,75 +562,67 @@ __bad_area(struct pt_regs *regs, unsigned long error_code,
__bad_area_nosemaphore(regs, error_code, address, si_code);
}
-static noinline void
-bad_area(struct pt_regs *regs, unsigned long error_code, unsigned long address)
+static noinline void bad_area(struct pt_regs *regs,
+ unsigned long error_code, unsigned long address)
{
__bad_area(regs, error_code, address, SEGV_MAPERR);
}
-static noinline void
-bad_area_access_error(struct pt_regs *regs, unsigned long error_code,
- unsigned long address)
+static noinline void bad_area_access_error(struct pt_regs *regs,
+ unsigned long error_code, unsigned long address)
{
__bad_area(regs, error_code, address, SEGV_ACCERR);
}
/* TODO: fixup for "mm-invoke-oom-killer-from-page-fault.patch" */
-static void
-out_of_memory(struct pt_regs *regs, unsigned long error_code,
- unsigned long address)
+static void out_of_memory(struct pt_regs *regs,
+ unsigned long error_code, unsigned long address)
{
/*
* We ran out of memory, call the OOM killer, and return the userspace
- * (which will retry the fault, or kill us if we got oom-killed):
+ * (which will retry the fault, or kill us if we got oom-killed).
*/
up_read(¤t->mm->mmap_sem);
-
pagefault_out_of_memory();
}
-static void
-do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address)
+static void do_sigbus(struct pt_regs *regs,
+ unsigned long error_code, unsigned long address)
{
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
up_read(&mm->mmap_sem);
- /* Kernel mode? Handle exceptions or die: */
+ /* Kernel mode? Handle exceptions or die */
if (!(error_code & PF_USER))
no_context(regs, error_code, address);
-
- /* User-space => ok to do another page fault: */
+#ifdef CONFIG_X86_32
+ /* User space => ok to do another page fault */
if (is_prefetch(regs, error_code, address))
return;
-
- tsk->thread.cr2 = address;
- tsk->thread.error_code = error_code;
- tsk->thread.trap_no = 14;
-
+#endif
+ tsk->thread.cr2 = address;
+ tsk->thread.error_code = error_code;
+ tsk->thread.trap_no = 14;
force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
}
-static noinline void
-mm_fault_error(struct pt_regs *regs, unsigned long error_code,
- unsigned long address, unsigned int fault)
+static noinline void mm_fault_error(struct pt_regs *regs,
+ unsigned long error_code, unsigned long address, unsigned int fault)
{
- if (fault & VM_FAULT_OOM) {
+ if (fault & VM_FAULT_OOM)
out_of_memory(regs, error_code, address);
- } else {
- if (fault & VM_FAULT_SIGBUS)
- do_sigbus(regs, error_code, address);
- else
- BUG();
- }
+ else if (fault & VM_FAULT_SIGBUS)
+ do_sigbus(regs, error_code, address);
+ else
+ BUG();
}
static int spurious_fault_check(unsigned long error_code, pte_t *pte)
{
if ((error_code & PF_WRITE) && !pte_write(*pte))
return 0;
-
if ((error_code & PF_INSTR) && !pte_exec(*pte))
return 0;
@@ -875,25 +630,21 @@ static int spurious_fault_check(unsigned long error_code, pte_t *pte)
}
/*
- * Handle a spurious fault caused by a stale TLB entry.
- *
- * This allows us to lazily refresh the TLB when increasing the
- * permissions of a kernel page (RO -> RW or NX -> X). Doing it
- * eagerly is very expensive since that implies doing a full
- * cross-processor TLB flush, even if no stale TLB entries exist
- * on other processors.
- *
+ * Handle a spurious fault caused by a stale TLB entry. This allows
+ * us to lazily refresh the TLB when increasing the permissions of a
+ * kernel page (RO -> RW or NX -> X). Doing it eagerly is very
+ * expensive since that implies doing a full cross-processor TLB
+ * flush, even if no stale TLB entries exist on other processors.
* There are no security implications to leaving a stale TLB when
* increasing the permissions on a page.
*/
-static noinline int
-spurious_fault(unsigned long error_code, unsigned long address)
+static noinline int spurious_fault(unsigned long error_code,
+ unsigned long address)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
- int ret;
/* Reserved-bit violation or user access to kernel space? */
if (error_code & (PF_USER | PF_RSVD))
@@ -921,46 +672,123 @@ spurious_fault(unsigned long error_code, unsigned long address)
if (!pte_present(*pte))
return 0;
- ret = spurious_fault_check(error_code, pte);
- if (!ret)
- return 0;
+ return spurious_fault_check(error_code, pte);
+}
+
+/*
+ * X86_32
+ * Handle a fault on the vmalloc or module mapping area
+ *
+ * X86_64
+ * Handle a fault on the vmalloc area
+ *
+ * This assumes no large pages in there.
+ */
+static noinline int vmalloc_fault(unsigned long address)
+{
+#ifdef CONFIG_X86_32
+ unsigned long pgd_paddr;
+ pmd_t *pmd_k;
+ pte_t *pte_k;
+
+ /* Make sure we are in vmalloc area */
+ if (!(address >= VMALLOC_START && address < VMALLOC_END))
+ return -1;
/*
- * Make sure we have permissions in PMD.
- * If not, then there's a bug in the page tables:
+ * Synchronize this task's top level page-table
+ * with the 'reference' page table.
+ *
+ * Do _not_ use "current" here. We might be inside
+ * an interrupt in the middle of a task switch..
*/
- ret = spurious_fault_check(error_code, (pte_t *) pmd);
- WARN_ONCE(!ret, "PMD has incorrect permission bits\n");
+ pgd_paddr = read_cr3();
+ pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
+ if (!pmd_k)
+ return -1;
+ pte_k = pte_offset_kernel(pmd_k, address);
+ if (!pte_present(*pte_k))
+ return -1;
+ return 0;
+#else
+ pgd_t *pgd, *pgd_ref;
+ pud_t *pud, *pud_ref;
+ pmd_t *pmd, *pmd_ref;
+ pte_t *pte, *pte_ref;
- return ret;
+ /* Make sure we are in vmalloc area */
+ if (!(address >= VMALLOC_START && address < VMALLOC_END))
+ return -1;
+
+ /* Copy kernel mappings over when needed. This can also
+ happen within a race in page table update. In the later
+ case just flush. */
+
+ pgd = pgd_offset(current->active_mm, address);
+ pgd_ref = pgd_offset_k(address);
+ if (pgd_none(*pgd_ref))
+ return -1;
+ if (pgd_none(*pgd))
+ set_pgd(pgd, *pgd_ref);
+ else
+ BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
+
+ /* Below here mismatches are bugs because these lower tables
+ are shared */
+
+ pud = pud_offset(pgd, address);
+ pud_ref = pud_offset(pgd_ref, address);
+ if (pud_none(*pud_ref))
+ return -1;
+ if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
+ BUG();
+ pmd = pmd_offset(pud, address);
+ pmd_ref = pmd_offset(pud_ref, address);
+ if (pmd_none(*pmd_ref))
+ return -1;
+ if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
+ BUG();
+ pte_ref = pte_offset_kernel(pmd_ref, address);
+ if (!pte_present(*pte_ref))
+ return -1;
+ pte = pte_offset_kernel(pmd, address);
+ /* Don't use pte_page here, because the mappings can point
+ outside mem_map, and the NUMA hash lookup cannot handle
+ that. */
+ if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref))
+ BUG();
+ return 0;
+#endif
}
int show_unhandled_signals = 1;
-static inline int
-access_error(unsigned long error_code, int write, struct vm_area_struct *vma)
+static inline int access_error(unsigned long error_code, int write,
+ struct vm_area_struct *vma)
{
if (write) {
- /* write, present and write, not present: */
+ /* write, present and write, not present */
if (unlikely(!(vma->vm_flags & VM_WRITE)))
return 1;
- return 0;
- }
-
- /* read, present: */
- if (unlikely(error_code & PF_PROT))
- return 1;
-
- /* read, not present: */
- if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))))
+ } else if (unlikely(error_code & PF_PROT)) {
+ /* read, present */
return 1;
+ } else {
+ /* read, not present */
+ if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))))
+ return 1;
+ }
return 0;
}
static int fault_in_kernel_space(unsigned long address)
{
- return address >= TASK_SIZE_MAX;
+#ifdef CONFIG_X86_32
+ return address >= TASK_SIZE;
+#else /* !CONFIG_X86_32 */
+ return address >= TASK_SIZE64;
+#endif /* CONFIG_X86_32 */
}
/*
@@ -968,22 +796,23 @@ static int fault_in_kernel_space(unsigned long address)
* and the problem, and then passes it off to one of the appropriate
* routines.
*/
-dotraplinkage void __kprobes
-do_page_fault(struct pt_regs *regs, unsigned long error_code)
+#ifdef CONFIG_X86_64
+asmlinkage
+#endif
+void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
- struct vm_area_struct *vma;
- struct task_struct *tsk;
unsigned long address;
+ struct task_struct *tsk;
struct mm_struct *mm;
+ struct vm_area_struct *vma;
int write;
int fault;
tsk = current;
mm = tsk->mm;
-
prefetchw(&mm->mmap_sem);
- /* Get the faulting address: */
+ /* get the address */
address = read_cr2();
if (unlikely(kmmio_fault(regs, address)))
@@ -1007,23 +836,22 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
vmalloc_fault(address) >= 0)
return;
- /* Can handle a stale RO->RW TLB: */
+ /* Can handle a stale RO->RW TLB */
if (spurious_fault(error_code, address))
return;
- /* kprobes don't want to hook the spurious faults: */
+ /* kprobes don't want to hook the spurious faults. */
if (notify_page_fault(regs))
return;
/*
* Don't take the mm semaphore here. If we fixup a prefetch
- * fault we could otherwise deadlock:
+ * fault we could otherwise deadlock.
*/
bad_area_nosemaphore(regs, error_code, address);
-
return;
}
- /* kprobes don't want to hook the spurious faults: */
+ /* kprobes don't want to hook the spurious faults. */
if (unlikely(notify_page_fault(regs)))
return;
/*
@@ -1031,22 +859,22 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
* vmalloc fault has been handled.
*
* User-mode registers count as a user access even for any
- * potential system fault or CPU buglet:
+ * potential system fault or CPU buglet.
*/
if (user_mode_vm(regs)) {
local_irq_enable();
error_code |= PF_USER;
- } else {
- if (regs->flags & X86_EFLAGS_IF)
- local_irq_enable();
- }
+ } else if (regs->flags & X86_EFLAGS_IF)
+ local_irq_enable();
+#ifdef CONFIG_X86_64
if (unlikely(error_code & PF_RSVD))
pgtable_bad(regs, error_code, address);
+#endif
/*
- * If we're in an interrupt, have no user context or are running
- * in an atomic region then we must not take the fault:
+ * If we're in an interrupt, have no user context or are running in an
+ * atomic region then we must not take the fault.
*/
if (unlikely(in_atomic() || !mm)) {
bad_area_nosemaphore(regs, error_code, address);
@@ -1055,19 +883,19 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
/*
* When running in the kernel we expect faults to occur only to
- * addresses in user space. All other faults represent errors in
- * the kernel and should generate an OOPS. Unfortunately, in the
- * case of an erroneous fault occurring in a code path which already
- * holds mmap_sem we will deadlock attempting to validate the fault
- * against the address space. Luckily the kernel only validly
- * references user space from well defined areas of code, which are
- * listed in the exceptions table.
+ * addresses in user space. All other faults represent errors in the
+ * kernel and should generate an OOPS. Unfortunately, in the case of an
+ * erroneous fault occurring in a code path which already holds mmap_sem
+ * we will deadlock attempting to validate the fault against the
+ * address space. Luckily the kernel only validly references user
+ * space from well defined areas of code, which are listed in the
+ * exceptions table.
*
* As the vast majority of faults will be valid we will only perform
- * the source reference check when there is a possibility of a
- * deadlock. Attempt to lock the address space, if we cannot we then
- * validate the source. If this is invalid we can skip the address
- * space check, thus avoiding the deadlock:
+ * the source reference check when there is a possibility of a deadlock.
+ * Attempt to lock the address space, if we cannot we then validate the
+ * source. If this is invalid we can skip the address space check,
+ * thus avoiding the deadlock.
*/
if (unlikely(!down_read_trylock(&mm->mmap_sem))) {
if ((error_code & PF_USER) == 0 &&
@@ -1078,9 +906,8 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
down_read(&mm->mmap_sem);
} else {
/*
- * The above down_read_trylock() might have succeeded in
- * which case we'll have missed the might_sleep() from
- * down_read():
+ * The above down_read_trylock() might have succeeded in which
+ * case we'll have missed the might_sleep() from down_read().
*/
might_sleep();
}
@@ -1100,7 +927,7 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
/*
* Accessing the stack below %sp is always a bug.
* The large cushion allows instructions like enter
- * and pusha to work. ("enter $65535, $31" pushes
+ * and pusha to work. ("enter $65535,$31" pushes
* 32 pointers and then decrements %sp by 65535.)
*/
if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) {
@@ -1119,7 +946,6 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
*/
good_area:
write = error_code & PF_WRITE;
-
if (unlikely(access_error(error_code, write, vma))) {
bad_area_access_error(regs, error_code, address);
return;
@@ -1128,21 +954,75 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
/*
* If for any reason at all we couldn't handle the fault,
* make sure we exit gracefully rather than endlessly redo
- * the fault:
+ * the fault.
*/
fault = handle_mm_fault(mm, vma, address, write);
-
if (unlikely(fault & VM_FAULT_ERROR)) {
mm_fault_error(regs, error_code, address, fault);
return;
}
-
if (fault & VM_FAULT_MAJOR)
tsk->maj_flt++;
else
tsk->min_flt++;
- check_v8086_mode(regs, address, tsk);
-
+#ifdef CONFIG_X86_32
+ /*
+ * Did it hit the DOS screen memory VA from vm86 mode?
+ */
+ if (v8086_mode(regs)) {
+ unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT;
+ if (bit < 32)
+ tsk->thread.screen_bitmap |= 1 << bit;
+ }
+#endif
up_read(&mm->mmap_sem);
}
+
+DEFINE_SPINLOCK(pgd_lock);
+LIST_HEAD(pgd_list);
+
+void vmalloc_sync_all(void)
+{
+ unsigned long address;
+
+#ifdef CONFIG_X86_32
+ if (SHARED_KERNEL_PMD)
+ return;
+
+ for (address = VMALLOC_START & PMD_MASK;
+ address >= TASK_SIZE && address < FIXADDR_TOP;
+ address += PMD_SIZE) {
+ unsigned long flags;
+ struct page *page;
+
+ spin_lock_irqsave(&pgd_lock, flags);
+ list_for_each_entry(page, &pgd_list, lru) {
+ if (!vmalloc_sync_one(page_address(page),
+ address))
+ break;
+ }
+ spin_unlock_irqrestore(&pgd_lock, flags);
+ }
+#else /* CONFIG_X86_64 */
+ for (address = VMALLOC_START & PGDIR_MASK; address <= VMALLOC_END;
+ address += PGDIR_SIZE) {
+ const pgd_t *pgd_ref = pgd_offset_k(address);
+ unsigned long flags;
+ struct page *page;
+
+ if (pgd_none(*pgd_ref))
+ continue;
+ spin_lock_irqsave(&pgd_lock, flags);
+ list_for_each_entry(page, &pgd_list, lru) {
+ pgd_t *pgd;
+ pgd = (pgd_t *)page_address(page) + pgd_index(address);
+ if (pgd_none(*pgd))
+ set_pgd(pgd, *pgd_ref);
+ else
+ BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
+ }
+ spin_unlock_irqrestore(&pgd_lock, flags);
+ }
+#endif
+}
diff --git a/trunk/arch/x86/mm/iomap_32.c b/trunk/arch/x86/mm/iomap_32.c
index d5e28424622c..ca53224fc56c 100644
--- a/trunk/arch/x86/mm/iomap_32.c
+++ b/trunk/arch/x86/mm/iomap_32.c
@@ -20,64 +20,6 @@
#include
#include
-#ifdef CONFIG_X86_PAE
-static int
-is_io_mapping_possible(resource_size_t base, unsigned long size)
-{
- return 1;
-}
-#else
-static int
-is_io_mapping_possible(resource_size_t base, unsigned long size)
-{
- /* There is no way to map greater than 1 << 32 address without PAE */
- if (base + size > 0x100000000ULL)
- return 0;
-
- return 1;
-}
-#endif
-
-int
-reserve_io_memtype_wc(u64 base, unsigned long size, pgprot_t *prot)
-{
- unsigned long ret_flag;
-
- if (!is_io_mapping_possible(base, size))
- goto out_err;
-
- if (!pat_enabled) {
- *prot = pgprot_noncached(PAGE_KERNEL);
- return 0;
- }
-
- if (reserve_memtype(base, base + size, _PAGE_CACHE_WC, &ret_flag))
- goto out_err;
-
- if (ret_flag == _PAGE_CACHE_WB)
- goto out_free;
-
- if (kernel_map_sync_memtype(base, size, ret_flag))
- goto out_free;
-
- *prot = __pgprot(__PAGE_KERNEL | ret_flag);
- return 0;
-
-out_free:
- free_memtype(base, base + size);
-out_err:
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(reserve_io_memtype_wc);
-
-void
-free_io_memtype(u64 base, unsigned long size)
-{
- if (pat_enabled)
- free_memtype(base, base + size);
-}
-EXPORT_SYMBOL_GPL(free_io_memtype);
-
/* Map 'pfn' using fixed map 'type' and protections 'prot'
*/
void *
diff --git a/trunk/arch/x86/mm/numa_32.c b/trunk/arch/x86/mm/numa_32.c
index 3957cd6d6454..d1f7439d173c 100644
--- a/trunk/arch/x86/mm/numa_32.c
+++ b/trunk/arch/x86/mm/numa_32.c
@@ -194,7 +194,7 @@ void *alloc_remap(int nid, unsigned long size)
size = ALIGN(size, L1_CACHE_BYTES);
if (!allocation || (allocation + size) >= node_remap_end_vaddr[nid])
- return NULL;
+ return 0;
node_remap_alloc_vaddr[nid] += size;
memset(allocation, 0, size);
diff --git a/trunk/arch/x86/mm/pageattr.c b/trunk/arch/x86/mm/pageattr.c
index 8253bc97587e..7be47d1a97e4 100644
--- a/trunk/arch/x86/mm/pageattr.c
+++ b/trunk/arch/x86/mm/pageattr.c
@@ -482,13 +482,6 @@ static int split_large_page(pte_t *kpte, unsigned long address)
pbase = (pte_t *)page_address(base);
paravirt_alloc_pte(&init_mm, page_to_pfn(base));
ref_prot = pte_pgprot(pte_clrhuge(*kpte));
- /*
- * If we ever want to utilize the PAT bit, we need to
- * update this function to make sure it's converted from
- * bit 12 to bit 7 when we cross from the 2MB level to
- * the 4K level:
- */
- WARN_ON_ONCE(pgprot_val(ref_prot) & _PAGE_PAT_LARGE);
#ifdef CONFIG_X86_64
if (level == PG_LEVEL_1G) {
diff --git a/trunk/arch/x86/mm/pat.c b/trunk/arch/x86/mm/pat.c
index fdfedb65d45a..05f9aef6818a 100644
--- a/trunk/arch/x86/mm/pat.c
+++ b/trunk/arch/x86/mm/pat.c
@@ -633,33 +633,6 @@ void unmap_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
free_memtype(addr, addr + size);
}
-/*
- * Change the memory type for the physial address range in kernel identity
- * mapping space if that range is a part of identity map.
- */
-int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flags)
-{
- unsigned long id_sz;
-
- if (!pat_enabled || base >= __pa(high_memory))
- return 0;
-
- id_sz = (__pa(high_memory) < base + size) ?
- __pa(high_memory) - base :
- size;
-
- if (ioremap_change_attr((unsigned long)__va(base), id_sz, flags) < 0) {
- printk(KERN_INFO
- "%s:%d ioremap_change_attr failed %s "
- "for %Lx-%Lx\n",
- current->comm, current->pid,
- cattr_name(flags),
- base, (unsigned long long)(base + size));
- return -EINVAL;
- }
- return 0;
-}
-
/*
* Internal interface to reserve a range of physical memory with prot.
* Reserved non RAM regions only and after successful reserve_memtype,
@@ -669,7 +642,7 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
int strict_prot)
{
int is_ram = 0;
- int ret;
+ int id_sz, ret;
unsigned long flags;
unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK);
@@ -706,8 +679,23 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
flags);
}
- if (kernel_map_sync_memtype(paddr, size, flags) < 0) {
+ /* Need to keep identity mapping in sync */
+ if (paddr >= __pa(high_memory))
+ return 0;
+
+ id_sz = (__pa(high_memory) < paddr + size) ?
+ __pa(high_memory) - paddr :
+ size;
+
+ if (ioremap_change_attr((unsigned long)__va(paddr), id_sz, flags) < 0) {
free_memtype(paddr, paddr + size);
+ printk(KERN_ERR
+ "%s:%d reserve_pfn_range ioremap_change_attr failed %s "
+ "for %Lx-%Lx\n",
+ current->comm, current->pid,
+ cattr_name(flags),
+ (unsigned long long)paddr,
+ (unsigned long long)(paddr + size));
return -EINVAL;
}
return 0;
diff --git a/trunk/arch/x86/power/hibernate_asm_32.S b/trunk/arch/x86/power/hibernate_asm_32.S
index b641388d8286..d1e9b53f9d33 100644
--- a/trunk/arch/x86/power/hibernate_asm_32.S
+++ b/trunk/arch/x86/power/hibernate_asm_32.S
@@ -8,7 +8,7 @@
#include
#include
-#include
+#include
#include
#include
diff --git a/trunk/arch/x86/power/hibernate_asm_64.S b/trunk/arch/x86/power/hibernate_asm_64.S
index 9356547d8c01..000415947d93 100644
--- a/trunk/arch/x86/power/hibernate_asm_64.S
+++ b/trunk/arch/x86/power/hibernate_asm_64.S
@@ -18,7 +18,7 @@
.text
#include
#include
-#include
+#include
#include
#include
diff --git a/trunk/arch/x86/vdso/vma.c b/trunk/arch/x86/vdso/vma.c
index 7133cdf9098b..9c98cc6ba978 100644
--- a/trunk/arch/x86/vdso/vma.c
+++ b/trunk/arch/x86/vdso/vma.c
@@ -85,8 +85,8 @@ static unsigned long vdso_addr(unsigned long start, unsigned len)
unsigned long addr, end;
unsigned offset;
end = (start + PMD_SIZE - 1) & PMD_MASK;
- if (end >= TASK_SIZE_MAX)
- end = TASK_SIZE_MAX;
+ if (end >= TASK_SIZE64)
+ end = TASK_SIZE64;
end -= len;
/* This loses some more bits than a modulo, but is cheaper */
offset = get_random_int() & (PTRS_PER_PTE - 1);
diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c
index c52f4034c7fd..86497d5f44cd 100644
--- a/trunk/arch/x86/xen/enlighten.c
+++ b/trunk/arch/x86/xen/enlighten.c
@@ -940,9 +940,6 @@ asmlinkage void __init xen_start_kernel(void)
possible map and a non-dummy shared_info. */
per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
- local_irq_disable();
- early_boot_irqs_off();
-
xen_raw_console_write("mapping kernel into physical memory\n");
pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages);
diff --git a/trunk/arch/x86/xen/xen-head.S b/trunk/arch/x86/xen/xen-head.S
index 1a5ff24e29c0..63d49a523ed3 100644
--- a/trunk/arch/x86/xen/xen-head.S
+++ b/trunk/arch/x86/xen/xen-head.S
@@ -8,7 +8,7 @@
#include
#include
-#include
+#include
#include
#include
diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c
index 2b6c59028254..d1dd5160daa9 100644
--- a/trunk/drivers/acpi/osl.c
+++ b/trunk/drivers/acpi/osl.c
@@ -272,7 +272,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
}
EXPORT_SYMBOL_GPL(acpi_os_map_memory);
-void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
+void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
{
if (acpi_gbl_permanent_mmap)
iounmap(virt);
@@ -281,7 +281,7 @@ void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
}
EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
-void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
+void early_acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
{
if (!acpi_gbl_permanent_mmap)
__acpi_unmap_table(virt, size);
diff --git a/trunk/drivers/base/sys.c b/trunk/drivers/base/sys.c
index b428c8c4bc64..c98c31ec2f75 100644
--- a/trunk/drivers/base/sys.c
+++ b/trunk/drivers/base/sys.c
@@ -303,6 +303,7 @@ void sysdev_unregister(struct sys_device * sysdev)
* is guaranteed by virtue of the fact that child devices are registered
* after their parents.
*/
+
void sysdev_shutdown(void)
{
struct sysdev_class * cls;
@@ -362,6 +363,7 @@ static void __sysdev_resume(struct sys_device *dev)
* This is only called by the device PM core, so we let them handle
* all synchronization.
*/
+
int sysdev_suspend(pm_message_t state)
{
struct sysdev_class * cls;
@@ -430,7 +432,7 @@ int sysdev_suspend(pm_message_t state)
}
return ret;
}
-EXPORT_SYMBOL_GPL(sysdev_suspend);
+
/**
* sysdev_resume - Bring system devices back to life.
@@ -440,6 +442,7 @@ EXPORT_SYMBOL_GPL(sysdev_suspend);
*
* Note: Interrupts are disabled when called.
*/
+
int sysdev_resume(void)
{
struct sysdev_class * cls;
@@ -460,7 +463,7 @@ int sysdev_resume(void)
}
return 0;
}
-EXPORT_SYMBOL_GPL(sysdev_resume);
+
int __init system_bus_init(void)
{
diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c
index 6949c2d58f1d..81f1cff56fd5 100644
--- a/trunk/drivers/gpu/drm/i915/i915_dma.c
+++ b/trunk/drivers/gpu/drm/i915/i915_dma.c
@@ -202,7 +202,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
dev_priv->ring.map.flags = 0;
dev_priv->ring.map.mtrr = 0;
- drm_core_ioremap_wc(&dev_priv->ring.map, dev);
+ drm_core_ioremap(&dev_priv->ring.map, dev);
if (dev_priv->ring.map.handle == NULL) {
i915_dma_cleanup(dev);
@@ -1090,11 +1090,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
dev_priv->mm.gtt_mapping =
io_mapping_create_wc(dev->agp->base,
dev->agp->agp_info.aper_size * 1024*1024);
- if (dev_priv->mm.gtt_mapping == NULL) {
- ret = -EIO;
- goto out_rmmap;
- }
-
/* Set up a WC MTRR for non-PAT systems. This is more common than
* one would think, because the kernel disables PAT on first
* generation Core chips because WC PAT gets overridden by a UC
@@ -1127,7 +1122,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (!I915_NEED_GFX_HWS(dev)) {
ret = i915_init_phys_hws(dev);
if (ret != 0)
- goto out_iomapfree;
+ goto out_rmmap;
}
/* On the 945G/GM, the chipset reports the MSI capability on the
@@ -1166,8 +1161,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
return 0;
-out_iomapfree:
- io_mapping_free(dev_priv->mm.gtt_mapping);
out_rmmap:
iounmap(dev_priv->regs);
free_priv:
diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c
index 0692622ee2b3..a31cbdbc3c54 100644
--- a/trunk/drivers/gpu/drm/i915/i915_drv.c
+++ b/trunk/drivers/gpu/drm/i915/i915_drv.c
@@ -27,7 +27,6 @@
*
*/
-#include
#include "drmP.h"
#include "drm.h"
#include "i915_drm.h"
@@ -67,12 +66,6 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
i915_save_state(dev);
- /* If KMS is active, we do the leavevt stuff here */
- if (drm_core_check_feature(dev, DRIVER_MODESET) && i915_gem_idle(dev)) {
- dev_err(&dev->pdev->dev, "GEM idle failed, aborting suspend\n");
- return -EBUSY;
- }
-
intel_opregion_free(dev);
if (state.event == PM_EVENT_SUSPEND) {
@@ -86,9 +79,6 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
static int i915_resume(struct drm_device *dev)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
- int ret = 0;
-
pci_set_power_state(dev->pdev, PCI_D0);
pci_restore_state(dev->pdev);
if (pci_enable_device(dev->pdev))
@@ -99,18 +89,7 @@ static int i915_resume(struct drm_device *dev)
intel_opregion_init(dev);
- /* KMS EnterVT equivalent */
- if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- mutex_lock(&dev->struct_mutex);
- dev_priv->mm.suspended = 0;
-
- ret = i915_gem_init_ringbuffer(dev);
- if (ret != 0)
- ret = -1;
- mutex_unlock(&dev->struct_mutex);
- }
-
- return ret;
+ return 0;
}
static struct vm_operations_struct i915_gem_vm_ops = {
diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h
index 17fa40858d26..135a08f615cd 100644
--- a/trunk/drivers/gpu/drm/i915/i915_drv.h
+++ b/trunk/drivers/gpu/drm/i915/i915_drv.h
@@ -618,7 +618,6 @@ int i915_gem_init_ringbuffer(struct drm_device *dev);
void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
int i915_gem_do_init(struct drm_device *dev, unsigned long start,
unsigned long end);
-int i915_gem_idle(struct drm_device *dev);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
int write);
diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c
index 25b337438ca7..ac534c9a2f81 100644
--- a/trunk/drivers/gpu/drm/i915/i915_gem.c
+++ b/trunk/drivers/gpu/drm/i915/i915_gem.c
@@ -34,6 +34,10 @@
#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
+static void
+i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
+ uint32_t read_domains,
+ uint32_t write_domain);
static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
@@ -2017,28 +2021,30 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
* drm_agp_chipset_flush
*/
static void
-i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
+i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
+ uint32_t read_domains,
+ uint32_t write_domain)
{
struct drm_device *dev = obj->dev;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
uint32_t invalidate_domains = 0;
uint32_t flush_domains = 0;
- BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU);
- BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU);
+ BUG_ON(read_domains & I915_GEM_DOMAIN_CPU);
+ BUG_ON(write_domain == I915_GEM_DOMAIN_CPU);
#if WATCH_BUF
DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
__func__, obj,
- obj->read_domains, obj->pending_read_domains,
- obj->write_domain, obj->pending_write_domain);
+ obj->read_domains, read_domains,
+ obj->write_domain, write_domain);
#endif
/*
* If the object isn't moving to a new write domain,
* let the object stay in multiple read domains
*/
- if (obj->pending_write_domain == 0)
- obj->pending_read_domains |= obj->read_domains;
+ if (write_domain == 0)
+ read_domains |= obj->read_domains;
else
obj_priv->dirty = 1;
@@ -2048,17 +2054,15 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
* any read domains which differ from the old
* write domain
*/
- if (obj->write_domain &&
- obj->write_domain != obj->pending_read_domains) {
+ if (obj->write_domain && obj->write_domain != read_domains) {
flush_domains |= obj->write_domain;
- invalidate_domains |=
- obj->pending_read_domains & ~obj->write_domain;
+ invalidate_domains |= read_domains & ~obj->write_domain;
}
/*
* Invalidate any read caches which may have
* stale data. That is, any new read domains.
*/
- invalidate_domains |= obj->pending_read_domains & ~obj->read_domains;
+ invalidate_domains |= read_domains & ~obj->read_domains;
if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) {
#if WATCH_BUF
DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n",
@@ -2067,15 +2071,9 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
i915_gem_clflush_object(obj);
}
- /* The actual obj->write_domain will be updated with
- * pending_write_domain after we emit the accumulated flush for all
- * of our domain changes in execbuffers (which clears objects'
- * write_domains). So if we have a current write domain that we
- * aren't changing, set pending_write_domain to that.
- */
- if (flush_domains == 0 && obj->pending_write_domain == 0)
- obj->pending_write_domain = obj->write_domain;
- obj->read_domains = obj->pending_read_domains;
+ if ((write_domain | flush_domains) != 0)
+ obj->write_domain = write_domain;
+ obj->read_domains = read_domains;
dev->invalidate_domains |= invalidate_domains;
dev->flush_domains |= flush_domains;
@@ -2585,7 +2583,9 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_gem_object *obj = object_list[i];
/* Compute new gpu domains and update invalidate/flush */
- i915_gem_object_set_to_gpu_domain(obj);
+ i915_gem_object_set_to_gpu_domain(obj,
+ obj->pending_read_domains,
+ obj->pending_write_domain);
}
i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -2604,12 +2604,6 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
(void)i915_add_request(dev, dev->flush_domains);
}
- for (i = 0; i < args->buffer_count; i++) {
- struct drm_gem_object *obj = object_list[i];
-
- obj->write_domain = obj->pending_write_domain;
- }
-
i915_verify_inactive(dev, __FILE__, __LINE__);
#if WATCH_COHERENCY
@@ -2872,13 +2866,6 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
return -EBADF;
}
- /* Update the active list for the hardware's current position.
- * Otherwise this only updates on a delayed timer or when irqs are
- * actually unmasked, and our working set ends up being larger than
- * required.
- */
- i915_gem_retire_requests(dev);
-
obj_priv = obj->driver_private;
/* Don't count being on the flushing list against the object being
* done. Otherwise, a buffer left on the flushing list but not getting
@@ -2980,7 +2967,7 @@ i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head)
return 0;
}
-int
+static int
i915_gem_idle(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -3143,20 +3130,16 @@ static void
i915_gem_cleanup_hws(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_gem_object *obj;
- struct drm_i915_gem_object *obj_priv;
+ struct drm_gem_object *obj = dev_priv->hws_obj;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
if (dev_priv->hws_obj == NULL)
return;
- obj = dev_priv->hws_obj;
- obj_priv = obj->driver_private;
-
kunmap(obj_priv->page_list[0]);
i915_gem_object_unpin(obj);
drm_gem_object_unreference(obj);
dev_priv->hws_obj = NULL;
-
memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
dev_priv->hw_status_page = NULL;
diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c
index 65b635ce28c8..4d2baf7b00be 100644
--- a/trunk/drivers/gpu/drm/i915/intel_display.c
+++ b/trunk/drivers/gpu/drm/i915/intel_display.c
@@ -1008,7 +1008,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
temp = CURSOR_MODE_DISABLE;
addr = 0;
bo = NULL;
- mutex_lock(&dev->struct_mutex);
goto finish;
}
diff --git a/trunk/include/linux/io-mapping.h b/trunk/include/linux/io-mapping.h
index f1ed66c43787..82df31726a54 100644
--- a/trunk/include/linux/io-mapping.h
+++ b/trunk/include/linux/io-mapping.h
@@ -30,13 +30,10 @@
* See Documentation/io_mapping.txt
*/
-#ifdef CONFIG_HAVE_ATOMIC_IOMAP
+/* this struct isn't actually defined anywhere */
+struct io_mapping;
-struct io_mapping {
- resource_size_t base;
- unsigned long size;
- pgprot_t prot;
-};
+#ifdef CONFIG_HAVE_ATOMIC_IOMAP
/*
* For small address space machines, mapping large objects
@@ -46,42 +43,23 @@ struct io_mapping {
*/
static inline struct io_mapping *
-io_mapping_create_wc(resource_size_t base, unsigned long size)
+io_mapping_create_wc(unsigned long base, unsigned long size)
{
- struct io_mapping *iomap;
- pgprot_t prot;
-
- if (!reserve_io_memtype_wc(base, size, &prot))
- return NULL;
-
- iomap = kmalloc(sizeof(*iomap), GFP_KERNEL);
- if (!iomap)
- return NULL;
-
- iomap->base = base;
- iomap->size = size;
- iomap->prot = prot;
- return iomap;
+ return (struct io_mapping *) base;
}
static inline void
io_mapping_free(struct io_mapping *mapping)
{
- free_io_memtype(mapping->base, mapping->size);
- kfree(mapping);
}
/* Atomic map/unmap */
static inline void *
io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset)
{
- resource_size_t phys_addr;
- unsigned long pfn;
-
- BUG_ON(offset >= mapping->size);
- phys_addr = mapping->base + offset;
- pfn = (unsigned long) (phys_addr >> PAGE_SHIFT);
- return iomap_atomic_prot_pfn(pfn, KM_USER0, mapping->prot);
+ offset += (unsigned long) mapping;
+ return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0,
+ __pgprot(__PAGE_KERNEL_WC));
}
static inline void
@@ -93,9 +71,8 @@ io_mapping_unmap_atomic(void *vaddr)
static inline void *
io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset)
{
- BUG_ON(offset >= mapping->size);
- resource_size_t phys_addr = mapping->base + offset;
- return ioremap_wc(phys_addr, PAGE_SIZE);
+ offset += (unsigned long) mapping;
+ return ioremap_wc(offset, PAGE_SIZE);
}
static inline void
@@ -106,12 +83,9 @@ io_mapping_unmap(void *vaddr)
#else
-/* this struct isn't actually defined anywhere */
-struct io_mapping;
-
/* Create the io_mapping object*/
static inline struct io_mapping *
-io_mapping_create_wc(resource_size_t base, unsigned long size)
+io_mapping_create_wc(unsigned long base, unsigned long size)
{
return (struct io_mapping *) ioremap_wc(base, size);
}
diff --git a/trunk/include/linux/kprobes.h b/trunk/include/linux/kprobes.h
index 2ec6cc14a114..32851eef48f0 100644
--- a/trunk/include/linux/kprobes.h
+++ b/trunk/include/linux/kprobes.h
@@ -182,14 +182,6 @@ struct kprobe_blackpoint {
DECLARE_PER_CPU(struct kprobe *, current_kprobe);
DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
-/*
- * For #ifdef avoidance:
- */
-static inline int kprobes_built_in(void)
-{
- return 1;
-}
-
#ifdef CONFIG_KRETPROBES
extern void arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs);
@@ -279,16 +271,8 @@ void unregister_kretprobes(struct kretprobe **rps, int num);
void kprobe_flush_task(struct task_struct *tk);
void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
-#else /* !CONFIG_KPROBES: */
+#else /* CONFIG_KPROBES */
-static inline int kprobes_built_in(void)
-{
- return 0;
-}
-static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
-{
- return 0;
-}
static inline struct kprobe *get_kprobe(void *addr)
{
return NULL;
@@ -345,5 +329,5 @@ static inline void unregister_kretprobes(struct kretprobe **rps, int num)
static inline void kprobe_flush_task(struct task_struct *tk)
{
}
-#endif /* CONFIG_KPROBES */
-#endif /* _LINUX_KPROBES_H */
+#endif /* CONFIG_KPROBES */
+#endif /* _LINUX_KPROBES_H */
diff --git a/trunk/include/linux/mmiotrace.h b/trunk/include/linux/mmiotrace.h
index 3d1b7bde1283..139d7c88d9c9 100644
--- a/trunk/include/linux/mmiotrace.h
+++ b/trunk/include/linux/mmiotrace.h
@@ -1,5 +1,5 @@
-#ifndef _LINUX_MMIOTRACE_H
-#define _LINUX_MMIOTRACE_H
+#ifndef MMIOTRACE_H
+#define MMIOTRACE_H
#include
#include
@@ -13,34 +13,28 @@ typedef void (*kmmio_post_handler_t)(struct kmmio_probe *,
unsigned long condition, struct pt_regs *);
struct kmmio_probe {
- /* kmmio internal list: */
- struct list_head list;
- /* start location of the probe point: */
- unsigned long addr;
- /* length of the probe region: */
- unsigned long len;
- /* Called before addr is executed: */
- kmmio_pre_handler_t pre_handler;
- /* Called after addr is executed: */
- kmmio_post_handler_t post_handler;
- void *private;
+ struct list_head list; /* kmmio internal list */
+ unsigned long addr; /* start location of the probe point */
+ unsigned long len; /* length of the probe region */
+ kmmio_pre_handler_t pre_handler; /* Called before addr is executed. */
+ kmmio_post_handler_t post_handler; /* Called after addr is executed */
+ void *private;
};
-extern unsigned int kmmio_count;
-
-extern int register_kmmio_probe(struct kmmio_probe *p);
-extern void unregister_kmmio_probe(struct kmmio_probe *p);
-
-#ifdef CONFIG_MMIOTRACE
/* kmmio is active by some kmmio_probes? */
static inline int is_kmmio_active(void)
{
+ extern unsigned int kmmio_count;
return kmmio_count;
}
+extern int register_kmmio_probe(struct kmmio_probe *p);
+extern void unregister_kmmio_probe(struct kmmio_probe *p);
+
/* Called from page fault handler. */
extern int kmmio_handler(struct pt_regs *regs, unsigned long addr);
+#ifdef CONFIG_MMIOTRACE
/* Called from ioremap.c */
extern void mmiotrace_ioremap(resource_size_t offset, unsigned long size,
void __iomem *addr);
@@ -49,17 +43,7 @@ extern void mmiotrace_iounmap(volatile void __iomem *addr);
/* For anyone to insert markers. Remember trailing newline. */
extern int mmiotrace_printk(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
-#else /* !CONFIG_MMIOTRACE: */
-static inline int is_kmmio_active(void)
-{
- return 0;
-}
-
-static inline int kmmio_handler(struct pt_regs *regs, unsigned long addr)
-{
- return 0;
-}
-
+#else
static inline void mmiotrace_ioremap(resource_size_t offset,
unsigned long size, void __iomem *addr)
{
@@ -79,28 +63,28 @@ static inline int mmiotrace_printk(const char *fmt, ...)
#endif /* CONFIG_MMIOTRACE */
enum mm_io_opcode {
- MMIO_READ = 0x1, /* struct mmiotrace_rw */
- MMIO_WRITE = 0x2, /* struct mmiotrace_rw */
- MMIO_PROBE = 0x3, /* struct mmiotrace_map */
- MMIO_UNPROBE = 0x4, /* struct mmiotrace_map */
- MMIO_UNKNOWN_OP = 0x5, /* struct mmiotrace_rw */
+ MMIO_READ = 0x1, /* struct mmiotrace_rw */
+ MMIO_WRITE = 0x2, /* struct mmiotrace_rw */
+ MMIO_PROBE = 0x3, /* struct mmiotrace_map */
+ MMIO_UNPROBE = 0x4, /* struct mmiotrace_map */
+ MMIO_UNKNOWN_OP = 0x5, /* struct mmiotrace_rw */
};
struct mmiotrace_rw {
- resource_size_t phys; /* PCI address of register */
- unsigned long value;
- unsigned long pc; /* optional program counter */
- int map_id;
- unsigned char opcode; /* one of MMIO_{READ,WRITE,UNKNOWN_OP} */
- unsigned char width; /* size of register access in bytes */
+ resource_size_t phys; /* PCI address of register */
+ unsigned long value;
+ unsigned long pc; /* optional program counter */
+ int map_id;
+ unsigned char opcode; /* one of MMIO_{READ,WRITE,UNKNOWN_OP} */
+ unsigned char width; /* size of register access in bytes */
};
struct mmiotrace_map {
- resource_size_t phys; /* base address in PCI space */
- unsigned long virt; /* base virtual address */
- unsigned long len; /* mapping size */
- int map_id;
- unsigned char opcode; /* MMIO_PROBE or MMIO_UNPROBE */
+ resource_size_t phys; /* base address in PCI space */
+ unsigned long virt; /* base virtual address */
+ unsigned long len; /* mapping size */
+ int map_id;
+ unsigned char opcode; /* MMIO_PROBE or MMIO_UNPROBE */
};
/* in kernel/trace/trace_mmiotrace.c */
@@ -110,4 +94,4 @@ extern void mmio_trace_rw(struct mmiotrace_rw *rw);
extern void mmio_trace_mapping(struct mmiotrace_map *map);
extern int mmio_trace_printk(const char *fmt, va_list args);
-#endif /* _LINUX_MMIOTRACE_H */
+#endif /* MMIOTRACE_H */
diff --git a/trunk/net/ipv4/cipso_ipv4.c b/trunk/net/ipv4/cipso_ipv4.c
index 7bc992976d29..6bb2635b5ded 100644
--- a/trunk/net/ipv4/cipso_ipv4.c
+++ b/trunk/net/ipv4/cipso_ipv4.c
@@ -3,16 +3,11 @@
*
* This is an implementation of the CIPSO 2.2 protocol as specified in
* draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in
- * FIPS-188. While CIPSO never became a full IETF RFC standard many vendors
+ * FIPS-188, copies of both documents can be found in the Documentation
+ * directory. While CIPSO never became a full IETF RFC standard many vendors
* have chosen to adopt the protocol and over the years it has become a
* de-facto standard for labeled networking.
*
- * The CIPSO draft specification can be found in the kernel's Documentation
- * directory as well as the following URL:
- * http://netlabel.sourceforge.net/files/draft-ietf-cipso-ipsecurity-01.txt
- * The FIPS-188 specification can be found at the following URL:
- * http://www.itl.nist.gov/fipspubs/fip188.htm
- *
* Author: Paul Moore
*
*/
diff --git a/trunk/security/selinux/netlabel.c b/trunk/security/selinux/netlabel.c
index 3f4b26647386..f58701a7b728 100644
--- a/trunk/security/selinux/netlabel.c
+++ b/trunk/security/selinux/netlabel.c
@@ -490,10 +490,8 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,
lock_sock(sk);
rc = netlbl_sock_getattr(sk, &secattr);
release_sock(sk);
- if (rc == 0)
+ if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
rc = -EACCES;
- else if (rc == -ENOMSG)
- rc = 0;
netlbl_secattr_destroy(&secattr);
}