diff --git a/[refs] b/[refs]
index 44e4892048bd..e703b8bdacff 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 598357eba6a55d27ddc7ead80ebb83fe1aad9b83
+refs/heads/master: 23e117fa44429cc054cb27d5621d64e4ced91e52
diff --git a/trunk/Documentation/DocBook/libata.tmpl b/trunk/Documentation/DocBook/libata.tmpl
index ff3e5bec1c24..ba9975771503 100644
--- a/trunk/Documentation/DocBook/libata.tmpl
+++ b/trunk/Documentation/DocBook/libata.tmpl
@@ -107,6 +107,10 @@ void (*dev_config) (struct ata_port *, struct ata_device *);
issue of SET FEATURES - XFER MODE, and prior to operation.
+ Called by ata_device_add() after ata_dev_identify() determines
+ a device is present.
+
+
This entry may be specified as NULL in ata_port_operations.
@@ -150,8 +154,8 @@ unsigned int (*mode_filter) (struct ata_port *, struct ata_device *, unsigned in
Taskfile read/write
-void (*sff_tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
-void (*sff_tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
+void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
+void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
@@ -160,35 +164,36 @@ void (*sff_tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
hardware registers / DMA buffers, to obtain the current set of
taskfile register values.
Most drivers for taskfile-based hardware (PIO or MMIO) use
- ata_sff_tf_load() and ata_sff_tf_read() for these hooks.
+ ata_tf_load() and ata_tf_read() for these hooks.
PIO data read/write
-void (*sff_data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
+void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
All bmdma-style drivers must implement this hook. This is the low-level
operation that actually copies the data bytes during a PIO data
transfer.
-Typically the driver will choose one of ata_sff_data_xfer_noirq(),
-ata_sff_data_xfer(), or ata_sff_data_xfer32().
+Typically the driver
+will choose one of ata_pio_data_xfer_noirq(), ata_pio_data_xfer(), or
+ata_mmio_data_xfer().
ATA command execute
-void (*sff_exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
+void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
causes an ATA command, previously loaded with
->tf_load(), to be initiated in hardware.
- Most drivers for taskfile-based hardware use ata_sff_exec_command()
+ Most drivers for taskfile-based hardware use ata_exec_command()
for this hook.
@@ -213,8 +218,8 @@ command.
Read specific ATA shadow registers
-u8 (*sff_check_status)(struct ata_port *ap);
-u8 (*sff_check_altstatus)(struct ata_port *ap);
+u8 (*check_status)(struct ata_port *ap);
+u8 (*check_altstatus)(struct ata_port *ap);
@@ -222,14 +227,20 @@ u8 (*sff_check_altstatus)(struct ata_port *ap);
hardware. On some hardware, reading the Status register has
the side effect of clearing the interrupt condition.
Most drivers for taskfile-based hardware use
- ata_sff_check_status() for this hook.
+ ata_check_status() for this hook.
+
+
+ Note that because this is called from ata_device_add(), at
+ least a dummy function that clears device interrupts must be
+ provided for all drivers, even if the controller doesn't
+ actually have a taskfile status register.
Select ATA device on bus
-void (*sff_dev_select)(struct ata_port *ap, unsigned int device);
+void (*dev_select)(struct ata_port *ap, unsigned int device);
@@ -240,7 +251,9 @@ void (*sff_dev_select)(struct ata_port *ap, unsigned int device);
Most drivers for taskfile-based hardware use
- ata_sff_dev_select() for this hook.
+ ata_std_dev_select() for this hook. Controllers which do not
+ support second drives on a port (such as SATA contollers) will
+ use ata_noop_dev_select().
@@ -428,13 +441,13 @@ void (*irq_clear) (struct ata_port *);
to struct ata_host_set.
- Most legacy IDE drivers use ata_sff_interrupt() for the
+ Most legacy IDE drivers use ata_interrupt() for the
irq_handler hook, which scans all ports in the host_set,
determines which queued command was active (if any), and calls
- ata_sff_host_intr(ap,qc).
+ ata_host_intr(ap,qc).
- Most legacy IDE drivers use ata_sff_irq_clear() for the
+ Most legacy IDE drivers use ata_bmdma_irq_clear() for the
irq_clear() hook, which simply clears the interrupt and error
flags in the DMA status register.
@@ -483,6 +496,10 @@ void (*host_stop) (struct ata_host_set *host_set);
data from port at this time.
+ Many drivers use ata_port_stop() as this hook, which frees the
+ PRD table.
+
+
->host_stop() is called after all ->port_stop() calls
have completed. The hook must finalize hardware shutdown, release DMA
and other resources, etc.
diff --git a/trunk/Documentation/RCU/stallwarn.txt b/trunk/Documentation/RCU/stallwarn.txt
index 44c6dcc93d6d..1423d2570d78 100644
--- a/trunk/Documentation/RCU/stallwarn.txt
+++ b/trunk/Documentation/RCU/stallwarn.txt
@@ -3,79 +3,35 @@ Using RCU's CPU Stall Detector
The CONFIG_RCU_CPU_STALL_DETECTOR kernel config parameter enables
RCU's CPU stall detector, which detects conditions that unduly delay
RCU grace periods. The stall detector's idea of what constitutes
-"unduly delayed" is controlled by a set of C preprocessor macros:
+"unduly delayed" is controlled by a pair of C preprocessor macros:
RCU_SECONDS_TILL_STALL_CHECK
This macro defines the period of time that RCU will wait from
the beginning of a grace period until it issues an RCU CPU
- stall warning. This time period is normally ten seconds.
+ stall warning. It is normally ten seconds.
RCU_SECONDS_TILL_STALL_RECHECK
This macro defines the period of time that RCU will wait after
- issuing a stall warning until it issues another stall warning
- for the same stall. This time period is normally set to thirty
- seconds.
+ issuing a stall warning until it issues another stall warning.
+ It is normally set to thirty seconds.
RCU_STALL_RAT_DELAY
- The CPU stall detector tries to make the offending CPU print its
- own warnings, as this often gives better-quality stack traces.
- However, if the offending CPU does not detect its own stall in
- the number of jiffies specified by RCU_STALL_RAT_DELAY, then
- some other CPU will complain. This delay is normally set to
- two jiffies.
+ The CPU stall detector tries to make the offending CPU rat on itself,
+ as this often gives better-quality stack traces. However, if
+ the offending CPU does not detect its own stall in the number
+ of jiffies specified by RCU_STALL_RAT_DELAY, then other CPUs will
+ complain. This is normally set to two jiffies.
-When a CPU detects that it is stalling, it will print a message similar
-to the following:
-
-INFO: rcu_sched_state detected stall on CPU 5 (t=2500 jiffies)
-
-This message indicates that CPU 5 detected that it was causing a stall,
-and that the stall was affecting RCU-sched. This message will normally be
-followed by a stack dump of the offending CPU. On TREE_RCU kernel builds,
-RCU and RCU-sched are implemented by the same underlying mechanism,
-while on TREE_PREEMPT_RCU kernel builds, RCU is instead implemented
-by rcu_preempt_state.
-
-On the other hand, if the offending CPU fails to print out a stall-warning
-message quickly enough, some other CPU will print a message similar to
-the following:
-
-INFO: rcu_bh_state detected stalls on CPUs/tasks: { 3 5 } (detected by 2, 2502 jiffies)
-
-This message indicates that CPU 2 detected that CPUs 3 and 5 were both
-causing stalls, and that the stall was affecting RCU-bh. This message
-will normally be followed by stack dumps for each CPU. Please note that
-TREE_PREEMPT_RCU builds can be stalled by tasks as well as by CPUs,
-and that the tasks will be indicated by PID, for example, "P3421".
-It is even possible for a rcu_preempt_state stall to be caused by both
-CPUs -and- tasks, in which case the offending CPUs and tasks will all
-be called out in the list.
-
-Finally, if the grace period ends just as the stall warning starts
-printing, there will be a spurious stall-warning message:
-
-INFO: rcu_bh_state detected stalls on CPUs/tasks: { } (detected by 4, 2502 jiffies)
-
-This is rare, but does happen from time to time in real life.
-
-So your kernel printed an RCU CPU stall warning. The next question is
-"What caused it?" The following problems can result in RCU CPU stall
-warnings:
+The following problems can result in an RCU CPU stall warning:
o A CPU looping in an RCU read-side critical section.
-o A CPU looping with interrupts disabled. This condition can
- result in RCU-sched and RCU-bh stalls.
+o A CPU looping with interrupts disabled.
-o A CPU looping with preemption disabled. This condition can
- result in RCU-sched stalls and, if ksoftirqd is in use, RCU-bh
- stalls.
-
-o A CPU looping with bottom halves disabled. This condition can
- result in RCU-sched and RCU-bh stalls.
+o A CPU looping with preemption disabled.
o For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel
without invoking schedule().
@@ -83,24 +39,20 @@ o For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel
o A bug in the RCU implementation.
o A hardware failure. This is quite unlikely, but has occurred
- at least once in real life. A CPU failed in a running system,
+ at least once in a former life. A CPU failed in a running system,
becoming unresponsive, but not causing an immediate crash.
This resulted in a series of RCU CPU stall warnings, eventually
leading the realization that the CPU had failed.
-The RCU, RCU-sched, and RCU-bh implementations have CPU stall
-warning. SRCU does not have its own CPU stall warnings, but its
-calls to synchronize_sched() will result in RCU-sched detecting
-RCU-sched-related CPU stalls. Please note that RCU only detects
-CPU stalls when there is a grace period in progress. No grace period,
-no CPU stall warnings.
-
-To diagnose the cause of the stall, inspect the stack traces.
-The offending function will usually be near the top of the stack.
-If you have a series of stall warnings from a single extended stall,
-comparing the stack traces can often help determine where the stall
-is occurring, which will usually be in the function nearest the top of
-that portion of the stack which remains the same from trace to trace.
-If you can reliably trigger the stall, ftrace can be quite helpful.
+The RCU, RCU-sched, and RCU-bh implementations have CPU stall warning.
+SRCU does not do so directly, but its calls to synchronize_sched() will
+result in RCU-sched detecting any CPU stalls that might be occurring.
+
+To diagnose the cause of the stall, inspect the stack traces. The offending
+function will usually be near the top of the stack. If you have a series
+of stall warnings from a single extended stall, comparing the stack traces
+can often help determine where the stall is occurring, which will usually
+be in the function nearest the top of the stack that stays the same from
+trace to trace.
RCU bugs can often be debugged with the help of CONFIG_RCU_TRACE.
diff --git a/trunk/Documentation/RCU/trace.txt b/trunk/Documentation/RCU/trace.txt
index efd8cc95c06b..8608fd85e921 100644
--- a/trunk/Documentation/RCU/trace.txt
+++ b/trunk/Documentation/RCU/trace.txt
@@ -256,23 +256,23 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
The output of "cat rcu/rcu_pending" looks as follows:
rcu_sched:
- 0 np=255892 qsp=53936 rpq=85 cbr=0 cng=14417 gpc=10033 gps=24320 nf=6445 nn=146741
- 1 np=261224 qsp=54638 rpq=33 cbr=0 cng=25723 gpc=16310 gps=2849 nf=5912 nn=155792
- 2 np=237496 qsp=49664 rpq=23 cbr=0 cng=2762 gpc=45478 gps=1762 nf=1201 nn=136629
- 3 np=236249 qsp=48766 rpq=98 cbr=0 cng=286 gpc=48049 gps=1218 nf=207 nn=137723
- 4 np=221310 qsp=46850 rpq=7 cbr=0 cng=26 gpc=43161 gps=4634 nf=3529 nn=123110
- 5 np=237332 qsp=48449 rpq=9 cbr=0 cng=54 gpc=47920 gps=3252 nf=201 nn=137456
- 6 np=219995 qsp=46718 rpq=12 cbr=0 cng=50 gpc=42098 gps=6093 nf=4202 nn=120834
- 7 np=249893 qsp=49390 rpq=42 cbr=0 cng=72 gpc=38400 gps=17102 nf=41 nn=144888
+ 0 np=255892 qsp=53936 cbr=0 cng=14417 gpc=10033 gps=24320 nf=6445 nn=146741
+ 1 np=261224 qsp=54638 cbr=0 cng=25723 gpc=16310 gps=2849 nf=5912 nn=155792
+ 2 np=237496 qsp=49664 cbr=0 cng=2762 gpc=45478 gps=1762 nf=1201 nn=136629
+ 3 np=236249 qsp=48766 cbr=0 cng=286 gpc=48049 gps=1218 nf=207 nn=137723
+ 4 np=221310 qsp=46850 cbr=0 cng=26 gpc=43161 gps=4634 nf=3529 nn=123110
+ 5 np=237332 qsp=48449 cbr=0 cng=54 gpc=47920 gps=3252 nf=201 nn=137456
+ 6 np=219995 qsp=46718 cbr=0 cng=50 gpc=42098 gps=6093 nf=4202 nn=120834
+ 7 np=249893 qsp=49390 cbr=0 cng=72 gpc=38400 gps=17102 nf=41 nn=144888
rcu_bh:
- 0 np=146741 qsp=1419 rpq=6 cbr=0 cng=6 gpc=0 gps=0 nf=2 nn=145314
- 1 np=155792 qsp=12597 rpq=3 cbr=0 cng=0 gpc=4 gps=8 nf=3 nn=143180
- 2 np=136629 qsp=18680 rpq=1 cbr=0 cng=0 gpc=7 gps=6 nf=0 nn=117936
- 3 np=137723 qsp=2843 rpq=0 cbr=0 cng=0 gpc=10 gps=7 nf=0 nn=134863
- 4 np=123110 qsp=12433 rpq=0 cbr=0 cng=0 gpc=4 gps=2 nf=0 nn=110671
- 5 np=137456 qsp=4210 rpq=1 cbr=0 cng=0 gpc=6 gps=5 nf=0 nn=133235
- 6 np=120834 qsp=9902 rpq=2 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
- 7 np=144888 qsp=26336 rpq=0 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
+ 0 np=146741 qsp=1419 cbr=0 cng=6 gpc=0 gps=0 nf=2 nn=145314
+ 1 np=155792 qsp=12597 cbr=0 cng=0 gpc=4 gps=8 nf=3 nn=143180
+ 2 np=136629 qsp=18680 cbr=0 cng=0 gpc=7 gps=6 nf=0 nn=117936
+ 3 np=137723 qsp=2843 cbr=0 cng=0 gpc=10 gps=7 nf=0 nn=134863
+ 4 np=123110 qsp=12433 cbr=0 cng=0 gpc=4 gps=2 nf=0 nn=110671
+ 5 np=137456 qsp=4210 cbr=0 cng=0 gpc=6 gps=5 nf=0 nn=133235
+ 6 np=120834 qsp=9902 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
+ 7 np=144888 qsp=26336 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
As always, this is once again split into "rcu_sched" and "rcu_bh"
portions, with CONFIG_TREE_PREEMPT_RCU kernels having an additional
@@ -284,9 +284,6 @@ o "np" is the number of times that __rcu_pending() has been invoked
o "qsp" is the number of times that the RCU was waiting for a
quiescent state from this CPU.
-o "rpq" is the number of times that the CPU had passed through
- a quiescent state, but not yet reported it to RCU.
-
o "cbr" is the number of times that this CPU had RCU callbacks
that had passed through a grace period, and were thus ready
to be invoked.
diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt
index 05df0b7514b6..ed511af0f79a 100644
--- a/trunk/Documentation/feature-removal-schedule.txt
+++ b/trunk/Documentation/feature-removal-schedule.txt
@@ -589,26 +589,3 @@ Why: Useful in 2003, implementation is a hack.
Generally invoked by accident today.
Seen as doing more harm than good.
Who: Len Brown
-
-----------------------------
-
-What: video4linux /dev/vtx teletext API support
-When: 2.6.35
-Files: drivers/media/video/saa5246a.c drivers/media/video/saa5249.c
- include/linux/videotext.h
-Why: The vtx device nodes have been superseded by vbi device nodes
- for many years. No applications exist that use the vtx support.
- Of the two i2c drivers that actually support this API the saa5249
- has been impossible to use for a year now and no known hardware
- that supports this device exists. The saa5246a is theoretically
- supported by the old mxb boards, but it never actually worked.
-
- In summary: there is no hardware that can use this API and there
- are no applications actually implementing this API.
-
- The vtx support still reserves minors 192-223 and we would really
- like to reuse those for upcoming new functionality. In the unlikely
- event that new hardware appears that wants to use the functionality
- provided by the vtx API, then that functionality should be build
- around the sliced VBI API instead.
-Who: Hans Verkuil
diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt
index 1e359b62c40a..a4f30faa4f1f 100644
--- a/trunk/Documentation/filesystems/proc.txt
+++ b/trunk/Documentation/filesystems/proc.txt
@@ -316,7 +316,7 @@ address perms offset dev inode pathname
08049000-0804a000 rw-p 00001000 03:00 8312 /opt/test
0804a000-0806b000 rw-p 00000000 00:00 0 [heap]
a7cb1000-a7cb2000 ---p 00000000 00:00 0
-a7cb2000-a7eb2000 rw-p 00000000 00:00 0
+a7cb2000-a7eb2000 rw-p 00000000 00:00 0 [threadstack:001ff4b4]
a7eb2000-a7eb3000 ---p 00000000 00:00 0
a7eb3000-a7ed5000 rw-p 00000000 00:00 0
a7ed5000-a8008000 r-xp 00000000 03:00 4222 /lib/libc.so.6
@@ -352,6 +352,7 @@ is not associated with a file:
[stack] = the stack of the main process
[vdso] = the "virtual dynamic shared object",
the kernel system call handler
+ [threadstack:xxxxxxxx] = the stack of the thread, xxxxxxxx is the stack size
or if empty, the mapping is anonymous.
diff --git a/trunk/Documentation/i2c/writing-clients b/trunk/Documentation/i2c/writing-clients
index 5ebf5af1d716..3219ee0dbfef 100644
--- a/trunk/Documentation/i2c/writing-clients
+++ b/trunk/Documentation/i2c/writing-clients
@@ -74,11 +74,6 @@ structure at all. You should use this to keep device-specific data.
/* retrieve the value */
void *i2c_get_clientdata(const struct i2c_client *client);
-Note that starting with kernel 2.6.34, you don't have to set the `data' field
-to NULL in remove() or if probe() failed anymore. The i2c-core does this
-automatically on these occasions. Those are also the only times the core will
-touch this field.
-
Accessing the client
====================
diff --git a/trunk/Documentation/input/elantech.txt b/trunk/Documentation/input/elantech.txt
index 56941ae1f5db..a10c3b6ba7c4 100644
--- a/trunk/Documentation/input/elantech.txt
+++ b/trunk/Documentation/input/elantech.txt
@@ -333,14 +333,14 @@ byte 0:
byte 1:
bit 7 6 5 4 3 2 1 0
- . . . . . x10 x9 x8
+ x15 x14 x13 x12 x11 x10 x9 x8
byte 2:
bit 7 6 5 4 3 2 1 0
x7 x6 x5 x4 x4 x2 x1 x0
- x10..x0 = absolute x value (horizontal)
+ x15..x0 = absolute x value (horizontal)
byte 3:
@@ -350,14 +350,14 @@ byte 3:
byte 4:
bit 7 6 5 4 3 2 1 0
- . . . . . . y9 y8
+ y15 y14 y13 y12 y11 y10 y8 y8
byte 5:
bit 7 6 5 4 3 2 1 0
y7 y6 y5 y4 y3 y2 y1 y0
- y9..y0 = absolute y value (vertical)
+ y15..y0 = absolute y value (vertical)
4.2.2 Two finger touch
diff --git a/trunk/Documentation/intel_txt.txt b/trunk/Documentation/intel_txt.txt
index 87c8990dbbd9..f40a1f030019 100644
--- a/trunk/Documentation/intel_txt.txt
+++ b/trunk/Documentation/intel_txt.txt
@@ -161,15 +161,13 @@ o In order to put a system into any of the sleep states after a TXT
has been restored, it will restore the TPM PCRs and then
transfer control back to the kernel's S3 resume vector.
In order to preserve system integrity across S3, the kernel
- provides tboot with a set of memory ranges (RAM and RESERVED_KERN
- in the e820 table, but not any memory that BIOS might alter over
- the S3 transition) that tboot will calculate a MAC (message
- authentication code) over and then seal with the TPM. On resume
- and once the measured environment has been re-established, tboot
- will re-calculate the MAC and verify it against the sealed value.
- Tboot's policy determines what happens if the verification fails.
- Note that the c/s 194 of tboot which has the new MAC code supports
- this.
+ provides tboot with a set of memory ranges (kernel
+ code/data/bss, S3 resume code, and AP trampoline) that tboot
+ will calculate a MAC (message authentication code) over and then
+ seal with the TPM. On resume and once the measured environment
+ has been re-established, tboot will re-calculate the MAC and
+ verify it against the sealed value. Tboot's policy determines
+ what happens if the verification fails.
That's pretty much it for TXT support.
diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt
index 567b7a8eb878..907010cea9ad 100644
--- a/trunk/Documentation/kernel-parameters.txt
+++ b/trunk/Documentation/kernel-parameters.txt
@@ -324,8 +324,6 @@ and is between 256 and 4096 characters. It is defined in the file
they are unmapped. Otherwise they are
flushed before they will be reused, which
is a lot of faster
- off - do not initialize any AMD IOMMU found in
- the system
amijoy.map= [HW,JOY] Amiga joystick support
Map of devices attached to JOY0DAT and JOY1DAT
diff --git a/trunk/Documentation/kprobes.txt b/trunk/Documentation/kprobes.txt
index 61c291cddf18..2f9115c0ae62 100644
--- a/trunk/Documentation/kprobes.txt
+++ b/trunk/Documentation/kprobes.txt
@@ -165,8 +165,8 @@ the user entry_handler invocation is also skipped.
1.4 How Does Jump Optimization Work?
-If your kernel is built with CONFIG_OPTPROBES=y (currently this flag
-is automatically set 'y' on x86/x86-64, non-preemptive kernel) and
+If you configured your kernel with CONFIG_OPTPROBES=y (currently
+this option is supported on x86/x86-64, non-preemptive kernel) and
the "debug.kprobes_optimization" kernel parameter is set to 1 (see
sysctl(8)), Kprobes tries to reduce probe-hit overhead by using a jump
instruction instead of a breakpoint instruction at each probepoint.
@@ -271,6 +271,8 @@ tweak the kernel's execution path, you need to suppress optimization,
using one of the following techniques:
- Specify an empty function for the kprobe's post_handler or break_handler.
or
+- Config CONFIG_OPTPROBES=n.
+ or
- Execute 'sysctl -w debug.kprobes_optimization=n'
2. Architectures Supported
@@ -305,6 +307,10 @@ it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO),
so you can use "objdump -d -l vmlinux" to see the source-to-object
code mapping.
+If you want to reduce probing overhead, set "Kprobes jump optimization
+support" (CONFIG_OPTPROBES) to "y". You can find this option under the
+"Kprobes" line.
+
4. API Reference
The Kprobes API includes a "register" function and an "unregister"
diff --git a/trunk/Documentation/rbtree.txt b/trunk/Documentation/rbtree.txt
index 221f38be98f4..aae8355d3166 100644
--- a/trunk/Documentation/rbtree.txt
+++ b/trunk/Documentation/rbtree.txt
@@ -190,61 +190,3 @@ Example:
for (node = rb_first(&mytree); node; node = rb_next(node))
printk("key=%s\n", rb_entry(node, struct mytype, node)->keystring);
-Support for Augmented rbtrees
------------------------------
-
-Augmented rbtree is an rbtree with "some" additional data stored in each node.
-This data can be used to augment some new functionality to rbtree.
-Augmented rbtree is an optional feature built on top of basic rbtree
-infrastructure. rbtree user who wants this feature will have an augment
-callback function in rb_root initialized.
-
-This callback function will be called from rbtree core routines whenever
-a node has a change in one or both of its children. It is the responsibility
-of the callback function to recalculate the additional data that is in the
-rb node using new children information. Note that if this new additional
-data affects the parent node's additional data, then callback function has
-to handle it and do the recursive updates.
-
-
-Interval tree is an example of augmented rb tree. Reference -
-"Introduction to Algorithms" by Cormen, Leiserson, Rivest and Stein.
-More details about interval trees:
-
-Classical rbtree has a single key and it cannot be directly used to store
-interval ranges like [lo:hi] and do a quick lookup for any overlap with a new
-lo:hi or to find whether there is an exact match for a new lo:hi.
-
-However, rbtree can be augmented to store such interval ranges in a structured
-way making it possible to do efficient lookup and exact match.
-
-This "extra information" stored in each node is the maximum hi
-(max_hi) value among all the nodes that are its descendents. This
-information can be maintained at each node just be looking at the node
-and its immediate children. And this will be used in O(log n) lookup
-for lowest match (lowest start address among all possible matches)
-with something like:
-
-find_lowest_match(lo, hi, node)
-{
- lowest_match = NULL;
- while (node) {
- if (max_hi(node->left) > lo) {
- // Lowest overlap if any must be on left side
- node = node->left;
- } else if (overlap(lo, hi, node)) {
- lowest_match = node;
- break;
- } else if (lo > node->lo) {
- // Lowest overlap if any must be on right side
- node = node->right;
- } else {
- break;
- }
- }
- return lowest_match;
-}
-
-Finding exact match will be to first find lowest match and then to follow
-successor nodes looking for exact match, until the start of a node is beyond
-the hi value we are looking for.
diff --git a/trunk/Documentation/spi/spidev_test.c b/trunk/Documentation/spi/spidev_test.c
index 16feda901469..10abd3773e49 100644
--- a/trunk/Documentation/spi/spidev_test.c
+++ b/trunk/Documentation/spi/spidev_test.c
@@ -58,7 +58,7 @@ static void transfer(int fd)
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
- if (ret < 1)
+ if (ret == 1)
pabort("can't send spi message");
for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
diff --git a/trunk/Documentation/trace/kprobetrace.txt b/trunk/Documentation/trace/kprobetrace.txt
index ec94748ae65b..a9100b28eb84 100644
--- a/trunk/Documentation/trace/kprobetrace.txt
+++ b/trunk/Documentation/trace/kprobetrace.txt
@@ -40,9 +40,7 @@ Synopsis of kprobe_events
$stack : Fetch stack address.
$retval : Fetch return value.(*)
+|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**)
- NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
- FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
- (u8/u16/u32/u64/s8/s16/s32/s64) are supported.
+ NAME=FETCHARG: Set NAME as the argument name of FETCHARG.
(*) only for return probe.
(**) this is useful for fetching a field of data structures.
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index 3d2651bffadd..d5b0b1b6dc52 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -2953,17 +2953,6 @@ S: Odd Fixes
F: Documentation/networking/README.ipw2200
F: drivers/net/wireless/ipw2x00/ipw2200.*
-INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT)
-M: Joseph Cihula
-M: Shane Wang
-L: tboot-devel@lists.sourceforge.net
-W: http://tboot.sourceforge.net
-T: Mercurial http://www.bughost.org/repos.hg/tboot.hg
-S: Supported
-F: Documentation/intel_txt.txt
-F: include/linux/tboot.h
-F: arch/x86/kernel/tboot.c
-
INTEL WIRELESS WIMAX CONNECTION 2400
M: Inaky Perez-Gonzalez
M: linux-wimax@intel.com
@@ -4176,7 +4165,6 @@ OPROFILE
M: Robert Richter
L: oprofile-list@lists.sf.net
S: Maintained
-F: arch/*/include/asm/oprofile*.h
F: arch/*/oprofile/
F: drivers/oprofile/
F: include/linux/oprofile.h
@@ -4365,13 +4353,13 @@ M: Paul Mackerras
M: Ingo Molnar
M: Arnaldo Carvalho de Melo
S: Supported
-F: kernel/perf_event*.c
+F: kernel/perf_event.c
F: include/linux/perf_event.h
-F: arch/*/kernel/perf_event*.c
-F: arch/*/kernel/*/perf_event*.c
-F: arch/*/kernel/*/*/perf_event*.c
+F: arch/*/kernel/perf_event.c
+F: arch/*/kernel/*/perf_event.c
+F: arch/*/kernel/*/*/perf_event.c
F: arch/*/include/asm/perf_event.h
-F: arch/*/lib/perf_event*.c
+F: arch/*/lib/perf_event.c
F: arch/*/kernel/perf_callchain.c
F: tools/perf/
@@ -5504,7 +5492,7 @@ S: Maintained
F: drivers/mmc/host/tmio_mmc.*
TMPFS (SHMEM FILESYSTEM)
-M: Hugh Dickins
+M: Hugh Dickins
L: linux-mm@kvack.org
S: Maintained
F: include/linux/shmem_fs.h
diff --git a/trunk/Makefile b/trunk/Makefile
index ebc8225f7a96..5f05f8cbeda4 100644
--- a/trunk/Makefile
+++ b/trunk/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 34
-EXTRAVERSION =
+EXTRAVERSION = -rc6
NAME = Sheep on Meth
# *DOCUMENTATION*
diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig
index acda512da2e2..e5eb1337a537 100644
--- a/trunk/arch/Kconfig
+++ b/trunk/arch/Kconfig
@@ -42,10 +42,15 @@ config KPROBES
If in doubt, say "N".
config OPTPROBES
- def_bool y
- depends on KPROBES && HAVE_OPTPROBES
+ bool "Kprobes jump optimization support (EXPERIMENTAL)"
+ default y
+ depends on KPROBES
depends on !PREEMPT
+ depends on HAVE_OPTPROBES
select KALLSYMS_ALL
+ help
+ This option will allow kprobes to optimize breakpoint to
+ a jump for reducing its overhead.
config HAVE_EFFICIENT_UNALIGNED_ACCESS
bool
@@ -137,17 +142,6 @@ config HAVE_HW_BREAKPOINT
bool
depends on PERF_EVENTS
-config HAVE_MIXED_BREAKPOINTS_REGS
- bool
- depends on HAVE_HW_BREAKPOINT
- help
- Depending on the arch implementation of hardware breakpoints,
- some of them have separate registers for data and instruction
- breakpoints addresses, others have mixed registers to store
- them but define the access type in a control register.
- Select this option if your arch implements breakpoints under the
- latter fashion.
-
config HAVE_USER_RETURN_NOTIFIER
bool
diff --git a/trunk/arch/alpha/include/asm/atomic.h b/trunk/arch/alpha/include/asm/atomic.h
index e756d04b6cd5..610dff44d94b 100644
--- a/trunk/arch/alpha/include/asm/atomic.h
+++ b/trunk/arch/alpha/include/asm/atomic.h
@@ -17,8 +17,8 @@
#define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
#define ATOMIC64_INIT(i) ( (atomic64_t) { (i) } )
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
-#define atomic64_read(v) (*(volatile long *)&(v)->counter)
+#define atomic_read(v) ((v)->counter + 0)
+#define atomic64_read(v) ((v)->counter + 0)
#define atomic_set(v,i) ((v)->counter = (i))
#define atomic64_set(v,i) ((v)->counter = (i))
diff --git a/trunk/arch/alpha/include/asm/bitops.h b/trunk/arch/alpha/include/asm/bitops.h
index 296da1d5ed57..15f3ae25c511 100644
--- a/trunk/arch/alpha/include/asm/bitops.h
+++ b/trunk/arch/alpha/include/asm/bitops.h
@@ -405,31 +405,29 @@ static inline int fls(int x)
#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
/* Whee. EV67 can calculate it directly. */
-static inline unsigned long __arch_hweight64(unsigned long w)
+static inline unsigned long hweight64(unsigned long w)
{
return __kernel_ctpop(w);
}
-static inline unsigned int __arch_weight32(unsigned int w)
+static inline unsigned int hweight32(unsigned int w)
{
- return __arch_hweight64(w);
+ return hweight64(w);
}
-static inline unsigned int __arch_hweight16(unsigned int w)
+static inline unsigned int hweight16(unsigned int w)
{
- return __arch_hweight64(w & 0xffff);
+ return hweight64(w & 0xffff);
}
-static inline unsigned int __arch_hweight8(unsigned int w)
+static inline unsigned int hweight8(unsigned int w)
{
- return __arch_hweight64(w & 0xff);
+ return hweight64(w & 0xff);
}
#else
-#include
+#include
#endif
-#include
-
#endif /* __KERNEL__ */
#include
diff --git a/trunk/arch/arm/boot/compressed/head.S b/trunk/arch/arm/boot/compressed/head.S
index c5191b1532e8..6ab6b337a913 100644
--- a/trunk/arch/arm/boot/compressed/head.S
+++ b/trunk/arch/arm/boot/compressed/head.S
@@ -685,8 +685,8 @@ proc_types:
W(b) __armv4_mmu_cache_off
W(b) __armv4_mmu_cache_flush
- .word 0x56056900
- .word 0xffffff00 @ PXA9xx
+ .word 0x56056930
+ .word 0xff0ffff0 @ PXA935
W(b) __armv4_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv4_mmu_cache_flush
@@ -697,6 +697,12 @@ proc_types:
W(b) __armv4_mmu_cache_off
W(b) __armv5tej_mmu_cache_flush
+ .word 0x56056930
+ .word 0xff0ffff0 @ PXA935
+ W(b) __armv4_mmu_cache_on
+ W(b) __armv4_mmu_cache_off
+ W(b) __armv4_mmu_cache_flush
+
.word 0x56050000 @ Feroceon
.word 0xff0f0000
W(b) __armv4_mmu_cache_on
diff --git a/trunk/arch/arm/configs/imote2_defconfig b/trunk/arch/arm/configs/imote2_defconfig
index 21f2bff8a363..95d2becfc664 100644
--- a/trunk/arch/arm/configs/imote2_defconfig
+++ b/trunk/arch/arm/configs/imote2_defconfig
@@ -1,14 +1,13 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.34-rc2
-# Thu Apr 8 14:49:08 2010
+# Linux kernel version: 2.6.33-rc8
+# Sat Feb 13 21:48:53 2010
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_HAVE_PROC_CPU=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -20,7 +19,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_ARCH_HAS_CPUFREQ=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_ARCH_MTD_XIP=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_VECTORS_BASE=0xffff0000
@@ -62,6 +60,11 @@ CONFIG_RCU_FANOUT=32
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -94,14 +97,10 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_PERF_USE_VMALLOC=y
#
# Kernel Performance Events And Counters
#
-# CONFIG_PERF_EVENTS is not set
-# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_COMPAT_BRK is not set
CONFIG_SLAB=y
@@ -185,7 +184,6 @@ CONFIG_MMU=y
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_BCMRING is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_GEMINI is not set
# CONFIG_ARCH_EBSA110 is not set
@@ -195,6 +193,7 @@ CONFIG_MMU=y
# CONFIG_ARCH_STMP3XXX is not set
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
@@ -211,26 +210,21 @@ CONFIG_MMU=y
# CONFIG_ARCH_KS8695 is not set
# CONFIG_ARCH_NS9XXX is not set
# CONFIG_ARCH_W90X900 is not set
-# CONFIG_ARCH_NUC93X is not set
# CONFIG_ARCH_PNX4008 is not set
CONFIG_ARCH_PXA=y
# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_SHMOBILE is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_S5P6440 is not set
-# CONFIG_ARCH_S5P6442 is not set
# CONFIG_ARCH_S5PC1XX is not set
-# CONFIG_ARCH_S5PV210 is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
# CONFIG_ARCH_U300 is not set
-# CONFIG_ARCH_U8500 is not set
-# CONFIG_ARCH_NOMADIK is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
#
# Intel PXA2xx/PXA3xx Implementations
@@ -259,7 +253,6 @@ CONFIG_ARCH_PXA=y
# CONFIG_MACH_EM_X270 is not set
# CONFIG_MACH_EXEDA is not set
# CONFIG_MACH_CM_X300 is not set
-# CONFIG_MACH_CAPC7117 is not set
# CONFIG_ARCH_GUMSTIX is not set
CONFIG_MACH_INTELMOTE2=y
# CONFIG_MACH_STARGATE2 is not set
@@ -282,11 +275,7 @@ CONFIG_MACH_INTELMOTE2=y
# CONFIG_PXA_EZX is not set
# CONFIG_MACH_MP900C is not set
# CONFIG_ARCH_PXA_PALM is not set
-# CONFIG_MACH_RAUMFELD_RC is not set
-# CONFIG_MACH_RAUMFELD_CONNECTOR is not set
-# CONFIG_MACH_RAUMFELD_SPEAKER is not set
# CONFIG_PXA_SHARPSL is not set
-# CONFIG_MACH_ICONTROL is not set
# CONFIG_ARCH_PXA_ESERIES is not set
CONFIG_PXA27x=y
CONFIG_PXA_SSP=y
@@ -313,7 +302,6 @@ CONFIG_ARM_THUMB=y
CONFIG_ARM_L1_CACHE_SHIFT=5
CONFIG_IWMMXT=y
CONFIG_XSCALE_PMU=y
-CONFIG_CPU_HAS_PMU=y
CONFIG_COMMON_CLKDEV=y
#
@@ -364,7 +352,7 @@ CONFIG_ALIGNMENT_TRAP=y
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=jffs2 console=ttyS2,115200 mem=32M"
+CONFIG_CMDLINE="console=tty1 root=/dev/mmcblk0p2 rootfstype=ext2 rootdelay=3 ip=192.168.0.202:192.168.0.200:192.168.0.200:255.255.255.0 debug"
# CONFIG_XIP_KERNEL is not set
CONFIG_KEXEC=y
CONFIG_ATAGS_PROC=y
@@ -372,8 +360,24 @@ CONFIG_ATAGS_PROC=y
#
# CPU Power Management
#
-# CONFIG_CPU_FREQ is not set
-# CONFIG_CPU_IDLE is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
#
# Floating point emulation
@@ -405,7 +409,6 @@ CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_APM_EMULATION=y
CONFIG_PM_RUNTIME=y
-CONFIG_PM_OPS=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
@@ -413,6 +416,7 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
@@ -502,7 +506,6 @@ CONFIG_NF_CT_NETLINK=m
CONFIG_NETFILTER_XTABLES=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
-# CONFIG_NETFILTER_XT_TARGET_CT is not set
# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
CONFIG_NETFILTER_XT_TARGET_HL=m
CONFIG_NETFILTER_XT_TARGET_LED=m
@@ -619,7 +622,6 @@ CONFIG_IP6_NF_RAW=m
# CONFIG_ATM is not set
CONFIG_STP=m
CONFIG_BRIDGE=m
-# CONFIG_BRIDGE_IGMP_SNOOPING is not set
# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
@@ -644,7 +646,32 @@ CONFIG_NET_CLS_ROUTE=y
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
-# CONFIG_BT is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+# CONFIG_BT_HCIUART_BCSP is not set
+# CONFIG_BT_HCIUART_LL is not set
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+# CONFIG_BT_ATH3K is not set
# CONFIG_AF_RXRPC is not set
CONFIG_FIB_RULES=y
# CONFIG_WIRELESS is not set
@@ -660,8 +687,7 @@ CONFIG_FIB_RULES=y
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=m
@@ -677,9 +703,9 @@ CONFIG_MTD=y
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_AFS_PARTS=y
-CONFIG_MTD_AR7_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
#
# User Modules And Translation Layers
@@ -786,7 +812,6 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
-CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -940,7 +965,6 @@ CONFIG_SERIAL_PXA=y
CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_TIMBERDALE is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
@@ -969,7 +993,6 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_PXA=y
# CONFIG_I2C_PXA_SLAVE is not set
# CONFIG_I2C_SIMTEC is not set
-# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
@@ -983,9 +1006,15 @@ CONFIG_I2C_PXA=y
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
CONFIG_SPI=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y
@@ -1017,12 +1046,10 @@ CONFIG_GPIO_SYSFS=y
#
# Memory mapped GPIO expanders:
#
-# CONFIG_GPIO_IT8761E is not set
#
# I2C GPIO expanders:
#
-# CONFIG_GPIO_MAX7300 is not set
# CONFIG_GPIO_MAX732X is not set
# CONFIG_GPIO_PCA953X is not set
# CONFIG_GPIO_PCF857X is not set
@@ -1066,12 +1093,10 @@ CONFIG_SSB_POSSIBLE=y
# Multifunction device drivers
#
# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_88PM860X is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_MFD_ASIC3 is not set
# CONFIG_HTC_EGPIO is not set
# CONFIG_HTC_PASIC3 is not set
-# CONFIG_HTC_I2CPLD is not set
# CONFIG_TPS65010 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
@@ -1080,25 +1105,22 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TC6393XB is not set
CONFIG_PMIC_DA903X=y
# CONFIG_PMIC_ADP5520 is not set
-# CONFIG_MFD_MAX8925 is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X is not set
# CONFIG_MFD_WM8350_I2C is not set
-# CONFIG_MFD_WM8994 is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_MFD_MC13783 is not set
# CONFIG_AB3100_CORE is not set
# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_88PM8607 is not set
# CONFIG_AB4500_CORE is not set
CONFIG_REGULATOR=y
CONFIG_REGULATOR_DEBUG=y
-# CONFIG_REGULATOR_DUMMY is not set
# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
CONFIG_REGULATOR_USERSPACE_CONSUMER=y
# CONFIG_REGULATOR_BQ24022 is not set
# CONFIG_REGULATOR_MAX1586 is not set
-# CONFIG_REGULATOR_MAX8649 is not set
# CONFIG_REGULATOR_MAX8660 is not set
CONFIG_REGULATOR_DA903X=y
# CONFIG_REGULATOR_LP3971 is not set
@@ -1196,7 +1218,6 @@ CONFIG_VIDEO_IR_I2C=y
# CONFIG_VIDEO_SAA7191 is not set
# CONFIG_VIDEO_TVP514X is not set
# CONFIG_VIDEO_TVP5150 is not set
-# CONFIG_VIDEO_TVP7002 is not set
# CONFIG_VIDEO_VPX3220 is not set
#
@@ -1243,7 +1264,15 @@ CONFIG_SOC_CAMERA_MT9M111=y
CONFIG_VIDEO_PXA27x=y
# CONFIG_VIDEO_SH_MOBILE_CEU is not set
# CONFIG_V4L_USB_DRIVERS is not set
-# CONFIG_RADIO_ADAPTERS is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_I2C_SI4713 is not set
+# CONFIG_RADIO_SI4713 is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_RADIO_SI470X is not set
+# CONFIG_USB_MR800 is not set
+CONFIG_RADIO_TEA5764=y
+CONFIG_RADIO_TEA5764_XTAL=y
+# CONFIG_RADIO_TEF6862 is not set
# CONFIG_DAB is not set
#
@@ -1369,6 +1398,8 @@ CONFIG_HID=y
#
# Special HID drivers
#
+CONFIG_HID_APPLE=m
+# CONFIG_HID_WACOM is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1446,6 +1477,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -1457,6 +1489,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
CONFIG_USB_GADGET=y
# CONFIG_USB_GADGET_DEBUG is not set
# CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -1496,7 +1529,6 @@ CONFIG_USB_ETH=y
# CONFIG_USB_MIDI_GADGET is not set
# CONFIG_USB_G_PRINTER is not set
# CONFIG_USB_CDC_COMPOSITE is not set
-# CONFIG_USB_G_NOKIA is not set
# CONFIG_USB_G_MULTI is not set
#
@@ -1523,6 +1555,8 @@ CONFIG_SDIO_UART=m
#
CONFIG_MMC_PXA=y
# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
CONFIG_MMC_SPI=y
# CONFIG_MEMSTICK is not set
CONFIG_NEW_LEDS=y
@@ -1540,11 +1574,11 @@ CONFIG_LEDS_LP3944=y
# CONFIG_LEDS_REGULATOR is not set
# CONFIG_LEDS_BD2802 is not set
# CONFIG_LEDS_LT3593 is not set
-CONFIG_LEDS_TRIGGERS=y
#
# LED Triggers
#
+CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
@@ -1622,7 +1656,7 @@ CONFIG_RTC_INTF_DEV=y
# on-CPU RTC drivers
#
# CONFIG_RTC_DRV_SA1100 is not set
-CONFIG_RTC_DRV_PXA=y
+# CONFIG_RTC_DRV_PXA is not set
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
@@ -1647,10 +1681,19 @@ CONFIG_EXT3_FS_XATTR=y
CONFIG_JBD=m
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=m
-# CONFIG_REISERFS_FS is not set
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
# CONFIG_NILFS2_FS is not set
@@ -1673,7 +1716,9 @@ CONFIG_CUSE=m
#
# CD-ROM/DVD Filesystems
#
-# CONFIG_ISO9660_FS is not set
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
# CONFIG_UDF_FS is not set
#
@@ -1705,14 +1750,12 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS=m
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
-CONFIG_JFFS2_FS_WBUF_VERIFY=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_JFFS2_FS_POSIX_ACL=y
-CONFIG_JFFS2_FS_SECURITY=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_LZO=y
@@ -1722,7 +1765,6 @@ CONFIG_JFFS2_RUBIN=y
CONFIG_JFFS2_CMODE_PRIORITY=y
# CONFIG_JFFS2_CMODE_SIZE is not set
# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
-# CONFIG_LOGFS is not set
CONFIG_CRAMFS=m
CONFIG_SQUASHFS=m
# CONFIG_SQUASHFS_EMBEDDED is not set
@@ -1760,7 +1802,6 @@ CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_CEPH_FS is not set
CONFIG_CIFS=m
CONFIG_CIFS_STATS=y
# CONFIG_CIFS_STATS2 is not set
@@ -1854,7 +1895,6 @@ CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
-# CONFIG_PROVE_RCU is not set
CONFIG_LOCKDEP=y
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_LOCKDEP is not set
@@ -1878,7 +1918,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
-# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -2022,9 +2061,9 @@ CONFIG_CRC32=y
CONFIG_CRC7=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_LZMA=y
@@ -2036,4 +2075,3 @@ CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_NLATTR=y
-CONFIG_GENERIC_ATOMIC64=y
diff --git a/trunk/arch/arm/include/asm/atomic.h b/trunk/arch/arm/include/asm/atomic.h
index a0162fa94564..e8ddec2cb158 100644
--- a/trunk/arch/arm/include/asm/atomic.h
+++ b/trunk/arch/arm/include/asm/atomic.h
@@ -24,7 +24,7 @@
* strex/ldrex monitor on some implementations. The reason we can use it for
* atomic_set() is the clrex or dummy strex done on every exception return.
*/
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
#define atomic_set(v,i) (((v)->counter) = (i))
#if __LINUX_ARM_ARCH__ >= 6
diff --git a/trunk/arch/arm/include/asm/cacheflush.h b/trunk/arch/arm/include/asm/cacheflush.h
index 4656a24058d2..0d08d4170b64 100644
--- a/trunk/arch/arm/include/asm/cacheflush.h
+++ b/trunk/arch/arm/include/asm/cacheflush.h
@@ -371,10 +371,6 @@ static inline void __flush_icache_all(void)
#ifdef CONFIG_ARM_ERRATA_411920
extern void v6_icache_inval_all(void);
v6_icache_inval_all();
-#elif defined(CONFIG_SMP) && __LINUX_ARM_ARCH__ >= 7
- asm("mcr p15, 0, %0, c7, c1, 0 @ invalidate I-cache inner shareable\n"
- :
- : "r" (0));
#else
asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
:
diff --git a/trunk/arch/arm/include/asm/elf.h b/trunk/arch/arm/include/asm/elf.h
index 51662feb9f1d..bff056489cc1 100644
--- a/trunk/arch/arm/include/asm/elf.h
+++ b/trunk/arch/arm/include/asm/elf.h
@@ -9,8 +9,6 @@
#include
#include
-struct task_struct;
-
typedef unsigned long elf_greg_t;
typedef unsigned long elf_freg_t[3];
diff --git a/trunk/arch/arm/include/asm/smp_twd.h b/trunk/arch/arm/include/asm/smp_twd.h
index 634f357be6bb..7be0978b2625 100644
--- a/trunk/arch/arm/include/asm/smp_twd.h
+++ b/trunk/arch/arm/include/asm/smp_twd.h
@@ -1,23 +1,6 @@
#ifndef __ASMARM_SMP_TWD_H
#define __ASMARM_SMP_TWD_H
-#define TWD_TIMER_LOAD 0x00
-#define TWD_TIMER_COUNTER 0x04
-#define TWD_TIMER_CONTROL 0x08
-#define TWD_TIMER_INTSTAT 0x0C
-
-#define TWD_WDOG_LOAD 0x20
-#define TWD_WDOG_COUNTER 0x24
-#define TWD_WDOG_CONTROL 0x28
-#define TWD_WDOG_INTSTAT 0x2C
-#define TWD_WDOG_RESETSTAT 0x30
-#define TWD_WDOG_DISABLE 0x34
-
-#define TWD_TIMER_CONTROL_ENABLE (1 << 0)
-#define TWD_TIMER_CONTROL_ONESHOT (0 << 1)
-#define TWD_TIMER_CONTROL_PERIODIC (1 << 1)
-#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2)
-
struct clock_event_device;
extern void __iomem *twd_base;
diff --git a/trunk/arch/arm/include/asm/tlbflush.h b/trunk/arch/arm/include/asm/tlbflush.h
index bd863d8608cd..e085e2c545eb 100644
--- a/trunk/arch/arm/include/asm/tlbflush.h
+++ b/trunk/arch/arm/include/asm/tlbflush.h
@@ -46,9 +46,6 @@
#define TLB_V7_UIS_FULL (1 << 20)
#define TLB_V7_UIS_ASID (1 << 21)
-/* Inner Shareable BTB operation (ARMv7 MP extensions) */
-#define TLB_V7_IS_BTB (1 << 22)
-
#define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */
#define TLB_DCLEAN (1 << 30)
#define TLB_WB (1 << 31)
@@ -186,7 +183,7 @@
#endif
#ifdef CONFIG_SMP
-#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
+#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID)
#else
#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
@@ -342,12 +339,6 @@ static inline void local_flush_tlb_all(void)
dsb();
isb();
}
- if (tlb_flag(TLB_V7_IS_BTB)) {
- /* flush the branch target cache */
- asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
- dsb();
- isb();
- }
}
static inline void local_flush_tlb_mm(struct mm_struct *mm)
@@ -385,12 +376,6 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
dsb();
}
- if (tlb_flag(TLB_V7_IS_BTB)) {
- /* flush the branch target cache */
- asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
- dsb();
- isb();
- }
}
static inline void
@@ -431,12 +416,6 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
dsb();
}
- if (tlb_flag(TLB_V7_IS_BTB)) {
- /* flush the branch target cache */
- asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
- dsb();
- isb();
- }
}
static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
@@ -475,12 +454,6 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
dsb();
isb();
}
- if (tlb_flag(TLB_V7_IS_BTB)) {
- /* flush the branch target cache */
- asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
- dsb();
- isb();
- }
}
/*
diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S
index 7ee48e7f8f31..e6a0fb0f392e 100644
--- a/trunk/arch/arm/kernel/entry-armv.S
+++ b/trunk/arch/arm/kernel/entry-armv.S
@@ -676,10 +676,10 @@ do_fpe:
* lr = unrecognised FP instruction return address
*/
- .pushsection .data
+ .data
ENTRY(fp_enter)
.word no_fp
- .popsection
+ .text
ENTRY(no_fp)
mov pc, lr
diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c
index a01194e583ff..577543f3857f 100644
--- a/trunk/arch/arm/kernel/smp.c
+++ b/trunk/arch/arm/kernel/smp.c
@@ -86,12 +86,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
return PTR_ERR(idle);
}
ci->idle = idle;
- } else {
- /*
- * Since this idle thread is being re-used, call
- * init_idle() to reinitialize the thread structure.
- */
- init_idle(idle, cpu);
}
/*
diff --git a/trunk/arch/arm/kernel/smp_twd.c b/trunk/arch/arm/kernel/smp_twd.c
index 7c5f0c024db7..ea02a7b1c244 100644
--- a/trunk/arch/arm/kernel/smp_twd.c
+++ b/trunk/arch/arm/kernel/smp_twd.c
@@ -21,6 +21,23 @@
#include
#include
+#define TWD_TIMER_LOAD 0x00
+#define TWD_TIMER_COUNTER 0x04
+#define TWD_TIMER_CONTROL 0x08
+#define TWD_TIMER_INTSTAT 0x0C
+
+#define TWD_WDOG_LOAD 0x20
+#define TWD_WDOG_COUNTER 0x24
+#define TWD_WDOG_CONTROL 0x28
+#define TWD_WDOG_INTSTAT 0x2C
+#define TWD_WDOG_RESETSTAT 0x30
+#define TWD_WDOG_DISABLE 0x34
+
+#define TWD_TIMER_CONTROL_ENABLE (1 << 0)
+#define TWD_TIMER_CONTROL_ONESHOT (0 << 1)
+#define TWD_TIMER_CONTROL_PERIODIC (1 << 1)
+#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2)
+
/* set up by the platform code */
void __iomem *twd_base;
diff --git a/trunk/arch/arm/lib/clear_user.S b/trunk/arch/arm/lib/clear_user.S
index 14a0d988c82c..5e3f99620c04 100644
--- a/trunk/arch/arm/lib/clear_user.S
+++ b/trunk/arch/arm/lib/clear_user.S
@@ -45,7 +45,6 @@ USER( strnebt r2, [r0])
mov r0, #0
ldmfd sp!, {r1, pc}
ENDPROC(__clear_user)
-ENDPROC(__clear_user_std)
.pushsection .fixup,"ax"
.align 0
diff --git a/trunk/arch/arm/lib/copy_to_user.S b/trunk/arch/arm/lib/copy_to_user.S
index d066df686e17..027b69bdbad1 100644
--- a/trunk/arch/arm/lib/copy_to_user.S
+++ b/trunk/arch/arm/lib/copy_to_user.S
@@ -93,7 +93,6 @@ WEAK(__copy_to_user)
#include "copy_template.S"
ENDPROC(__copy_to_user)
-ENDPROC(__copy_to_user_std)
.pushsection .fixup,"ax"
.align 0
diff --git a/trunk/arch/arm/mach-davinci/da830.c b/trunk/arch/arm/mach-davinci/da830.c
index e8cb982f5e8e..122e61a9f505 100644
--- a/trunk/arch/arm/mach-davinci/da830.c
+++ b/trunk/arch/arm/mach-davinci/da830.c
@@ -410,7 +410,7 @@ static struct clk_lookup da830_clks[] = {
CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
CLK("davinci-mcasp.2", NULL, &mcasp2_clk),
- CLK(NULL, "usb20", &usb20_clk),
+ CLK("musb_hdrc", NULL, &usb20_clk),
CLK(NULL, "aemif", &aemif_clk),
CLK(NULL, "aintc", &aintc_clk),
CLK(NULL, "secu_mgr", &secu_mgr_clk),
diff --git a/trunk/arch/arm/mach-mx5/clock-mx51.c b/trunk/arch/arm/mach-mx5/clock-mx51.c
index 1ee6ce4087b8..8f85f73b83a8 100644
--- a/trunk/arch/arm/mach-mx5/clock-mx51.c
+++ b/trunk/arch/arm/mach-mx5/clock-mx51.c
@@ -16,7 +16,6 @@
#include
#include
-#include
#include
#include
diff --git a/trunk/arch/arm/mach-pxa/include/mach/colibri.h b/trunk/arch/arm/mach-pxa/include/mach/colibri.h
index 5f2ba8d9015c..811743c56147 100644
--- a/trunk/arch/arm/mach-pxa/include/mach/colibri.h
+++ b/trunk/arch/arm/mach-pxa/include/mach/colibri.h
@@ -2,7 +2,6 @@
#define _COLIBRI_H_
#include
-#include
/*
* common settings for all modules
diff --git a/trunk/arch/arm/mach-pxa/include/mach/hardware.h b/trunk/arch/arm/mach-pxa/include/mach/hardware.h
index 3d8d8cb09685..7515757d6911 100644
--- a/trunk/arch/arm/mach-pxa/include/mach/hardware.h
+++ b/trunk/arch/arm/mach-pxa/include/mach/hardware.h
@@ -202,7 +202,7 @@
#define __cpu_is_pxa950(id) \
({ \
unsigned int _id = (id) >> 4 & 0xfff; \
- _id == 0x697; \
+ id == 0x697; \
})
#else
#define __cpu_is_pxa950(id) (0)
diff --git a/trunk/arch/arm/mach-pxa/include/mach/regs-u2d.h b/trunk/arch/arm/mach-pxa/include/mach/regs-u2d.h
index c15c0c57de08..44b0b20b69a4 100644
--- a/trunk/arch/arm/mach-pxa/include/mach/regs-u2d.h
+++ b/trunk/arch/arm/mach-pxa/include/mach/regs-u2d.h
@@ -166,8 +166,7 @@
#define U2DMACSR_BUSERRTYPE (7 << 10) /* PX Bus Error Type */
#define U2DMACSR_EORINTR (1 << 9) /* End Of Receive */
#define U2DMACSR_REQPEND (1 << 8) /* Request Pending */
-#define U2DMACSR_RASINTR (1 << 4) /* Request After Channel Stopped (read / write 1 clear) */
-#define U2DMACSR_STOPINTR (1 << 3) /* Stop Interrupt (read only) */
+#define U2DMACSR_RASINTR (1 << 4) /* Request After Channel Stopped (read / write 1 clear) */#define U2DMACSR_STOPINTR (1 << 3) /* Stop Interrupt (read only) */
#define U2DMACSR_ENDINTR (1 << 2) /* End Interrupt (read / write 1 clear) */
#define U2DMACSR_STARTINTR (1 << 1) /* Start Interrupt (read / write 1 clear) */
#define U2DMACSR_BUSERRINTR (1 << 0) /* Bus Error Interrupt (read / write 1 clear) */
diff --git a/trunk/arch/arm/mach-pxa/raumfeld.c b/trunk/arch/arm/mach-pxa/raumfeld.c
index d12667bd9ebe..44bb675e47f1 100644
--- a/trunk/arch/arm/mach-pxa/raumfeld.c
+++ b/trunk/arch/arm/mach-pxa/raumfeld.c
@@ -983,7 +983,7 @@ static void __init raumfeld_common_init(void)
int i;
for (i = 0; i < ARRAY_SIZE(gpio_keys_button); i++)
- if (!strcmp(gpio_keys_button[i].desc, "on_off button"))
+ if (!strcmp(gpio_keys_button[i].desc, "on/off button"))
gpio_keys_button[i].active_low = 1;
}
@@ -1009,7 +1009,8 @@ static void __init raumfeld_common_init(void)
gpio_direction_output(GPIO_W2W_PDN, 0);
/* this can be used to switch off the device */
- ret = gpio_request(GPIO_SHUTDOWN_SUPPLY, "supply shutdown");
+ ret = gpio_request(GPIO_SHUTDOWN_SUPPLY,
+ "supply shutdown");
if (ret < 0)
pr_warning("Unable to request GPIO_SHUTDOWN_SUPPLY\n");
else
diff --git a/trunk/arch/arm/mach-pxa/spitz.c b/trunk/arch/arm/mach-pxa/spitz.c
index 01bdd7500df4..19b5109d9808 100644
--- a/trunk/arch/arm/mach-pxa/spitz.c
+++ b/trunk/arch/arm/mach-pxa/spitz.c
@@ -363,7 +363,7 @@ static struct gpio_keys_button spitz_gpio_keys[] = {
.type = EV_PWR,
.code = KEY_SUSPEND,
.gpio = SPITZ_GPIO_ON_KEY,
- .desc = "On Off",
+ .desc = "On/Off",
.wakeup = 1,
},
/* Two buttons detecting the lid state */
diff --git a/trunk/arch/arm/mach-pxa/viper.c b/trunk/arch/arm/mach-pxa/viper.c
index e90114a7e246..9e0c5c3988a1 100644
--- a/trunk/arch/arm/mach-pxa/viper.c
+++ b/trunk/arch/arm/mach-pxa/viper.c
@@ -34,7 +34,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -455,7 +454,7 @@ static struct i2c_gpio_platform_data i2c_bus_data = {
.sda_pin = VIPER_RTC_I2C_SDA_GPIO,
.scl_pin = VIPER_RTC_I2C_SCL_GPIO,
.udelay = 10,
- .timeout = HZ,
+ .timeout = 100,
};
static struct platform_device i2c_bus_device = {
@@ -780,7 +779,7 @@ static void __init viper_tpm_init(void)
.sda_pin = VIPER_TPM_I2C_SDA_GPIO,
.scl_pin = VIPER_TPM_I2C_SCL_GPIO,
.udelay = 10,
- .timeout = HZ,
+ .timeout = 100,
};
char *errstr;
diff --git a/trunk/arch/arm/mach-sa1100/Kconfig b/trunk/arch/arm/mach-sa1100/Kconfig
index fd4c52b7ccb6..b17d52f7cc48 100644
--- a/trunk/arch/arm/mach-sa1100/Kconfig
+++ b/trunk/arch/arm/mach-sa1100/Kconfig
@@ -57,7 +57,7 @@ config SA1100_COLLIE
config SA1100_H3100
bool "Compaq iPAQ H3100"
select HTC_EGPIO
- select CPU_FREQ_SA1110
+ select CPU_FREQ_SA1100
help
Say Y here if you intend to run this kernel on the Compaq iPAQ
H3100 handheld computer. Information about this machine and the
@@ -68,7 +68,7 @@ config SA1100_H3100
config SA1100_H3600
bool "Compaq iPAQ H3600/H3700"
select HTC_EGPIO
- select CPU_FREQ_SA1110
+ select CPU_FREQ_SA1100
help
Say Y here if you intend to run this kernel on the Compaq iPAQ
H3600 handheld computer. Information about this machine and the
diff --git a/trunk/arch/arm/mach-sa1100/cpu-sa1110.c b/trunk/arch/arm/mach-sa1100/cpu-sa1110.c
index 7252874d328b..63b32b68b296 100644
--- a/trunk/arch/arm/mach-sa1100/cpu-sa1110.c
+++ b/trunk/arch/arm/mach-sa1100/cpu-sa1110.c
@@ -363,9 +363,6 @@ static int __init sa1110_clk_init(void)
struct sdram_params *sdram;
const char *name = sdram_name;
- if (!cpu_is_sa1110())
- return -ENODEV;
-
if (!name[0]) {
if (machine_is_assabet())
name = "TC59SM716-CL3";
diff --git a/trunk/arch/arm/mm/cache-v6.S b/trunk/arch/arm/mm/cache-v6.S
index e46ecd847138..9d89c67a1cc3 100644
--- a/trunk/arch/arm/mm/cache-v6.S
+++ b/trunk/arch/arm/mm/cache-v6.S
@@ -211,9 +211,6 @@ v6_dma_inv_range:
mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line
#endif
1:
-#ifdef CONFIG_SMP
- str r0, [r0] @ write for ownership
-#endif
#ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c6, 1 @ invalidate D line
#else
@@ -234,9 +231,6 @@ v6_dma_inv_range:
v6_dma_clean_range:
bic r0, r0, #D_CACHE_LINE_SIZE - 1
1:
-#ifdef CONFIG_SMP
- ldr r2, [r0] @ read for ownership
-#endif
#ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c10, 1 @ clean D line
#else
@@ -257,10 +251,6 @@ v6_dma_clean_range:
ENTRY(v6_dma_flush_range)
bic r0, r0, #D_CACHE_LINE_SIZE - 1
1:
-#ifdef CONFIG_SMP
- ldr r2, [r0] @ read for ownership
- str r2, [r0] @ write for ownership
-#endif
#ifdef HARVARD_CACHE
mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
#else
@@ -283,9 +273,7 @@ ENTRY(v6_dma_map_area)
add r1, r1, r0
teq r2, #DMA_FROM_DEVICE
beq v6_dma_inv_range
- teq r2, #DMA_TO_DEVICE
- beq v6_dma_clean_range
- b v6_dma_flush_range
+ b v6_dma_clean_range
ENDPROC(v6_dma_map_area)
/*
@@ -295,6 +283,9 @@ ENDPROC(v6_dma_map_area)
* - dir - DMA direction
*/
ENTRY(v6_dma_unmap_area)
+ add r1, r1, r0
+ teq r2, #DMA_TO_DEVICE
+ bne v6_dma_inv_range
mov pc, lr
ENDPROC(v6_dma_unmap_area)
diff --git a/trunk/arch/arm/mm/cache-v7.S b/trunk/arch/arm/mm/cache-v7.S
index 06a90dcfc60a..bcd64f265870 100644
--- a/trunk/arch/arm/mm/cache-v7.S
+++ b/trunk/arch/arm/mm/cache-v7.S
@@ -167,11 +167,7 @@ ENTRY(v7_coherent_user_range)
cmp r0, r1
blo 1b
mov r0, #0
-#ifdef CONFIG_SMP
- mcr p15, 0, r0, c7, c1, 6 @ invalidate BTB Inner Shareable
-#else
mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB
-#endif
dsb
isb
mov pc, lr
diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c
index 0ed29bfeba1c..83db12a68d56 100644
--- a/trunk/arch/arm/mm/init.c
+++ b/trunk/arch/arm/mm/init.c
@@ -86,6 +86,9 @@ void show_mem(void)
printk("Mem-info:\n");
show_free_areas();
for_each_online_node(node) {
+ pg_data_t *n = NODE_DATA(node);
+ struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn;
+
for_each_nodebank (i,mi,node) {
struct membank *bank = &mi->bank[i];
unsigned int pfn1, pfn2;
@@ -94,8 +97,8 @@ void show_mem(void)
pfn1 = bank_pfn_start(bank);
pfn2 = bank_pfn_end(bank);
- page = pfn_to_page(pfn1);
- end = pfn_to_page(pfn2 - 1) + 1;
+ page = map + pfn1;
+ end = map + pfn2;
do {
total++;
@@ -600,6 +603,9 @@ void __init mem_init(void)
reserved_pages = free_pages = 0;
for_each_online_node(node) {
+ pg_data_t *n = NODE_DATA(node);
+ struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn;
+
for_each_nodebank(i, &meminfo, node) {
struct membank *bank = &meminfo.bank[i];
unsigned int pfn1, pfn2;
@@ -608,8 +614,8 @@ void __init mem_init(void)
pfn1 = bank_pfn_start(bank);
pfn2 = bank_pfn_end(bank);
- page = pfn_to_page(pfn1);
- end = pfn_to_page(pfn2 - 1) + 1;
+ page = map + pfn1;
+ end = map + pfn2;
do {
if (PageReserved(page))
diff --git a/trunk/arch/arm/mm/nommu.c b/trunk/arch/arm/mm/nommu.c
index 33b327379f07..9bfeb6b9509a 100644
--- a/trunk/arch/arm/mm/nommu.c
+++ b/trunk/arch/arm/mm/nommu.c
@@ -65,15 +65,6 @@ void flush_dcache_page(struct page *page)
}
EXPORT_SYMBOL(flush_dcache_page);
-void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
- unsigned long uaddr, void *dst, const void *src,
- unsigned long len)
-{
- memcpy(dst, src, len);
- if (vma->vm_flags & VM_EXEC)
- __cpuc_coherent_user_range(uaddr, uaddr + len);
-}
-
void __iomem *__arm_ioremap_pfn(unsigned long pfn, unsigned long offset,
size_t size, unsigned int mtype)
{
@@ -96,8 +87,8 @@ void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
}
EXPORT_SYMBOL(__arm_ioremap);
-void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size,
- unsigned int mtype, void *caller)
+void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
+ unsigned int mtype, void *caller)
{
return __arm_ioremap(phys_addr, size, mtype);
}
diff --git a/trunk/arch/arm/mm/tlb-v7.S b/trunk/arch/arm/mm/tlb-v7.S
index f3f288a9546d..0cb1848bd876 100644
--- a/trunk/arch/arm/mm/tlb-v7.S
+++ b/trunk/arch/arm/mm/tlb-v7.S
@@ -50,11 +50,7 @@ ENTRY(v7wbi_flush_user_tlb_range)
cmp r0, r1
blo 1b
mov ip, #0
-#ifdef CONFIG_SMP
- mcr p15, 0, ip, c7, c1, 6 @ flush BTAC/BTB Inner Shareable
-#else
mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB
-#endif
dsb
mov pc, lr
ENDPROC(v7wbi_flush_user_tlb_range)
@@ -83,11 +79,7 @@ ENTRY(v7wbi_flush_kern_tlb_range)
cmp r0, r1
blo 1b
mov r2, #0
-#ifdef CONFIG_SMP
- mcr p15, 0, r2, c7, c1, 6 @ flush BTAC/BTB Inner Shareable
-#else
mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
-#endif
dsb
isb
mov pc, lr
diff --git a/trunk/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h b/trunk/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h
index 7c4870bd5a21..07be8ad7ec37 100644
--- a/trunk/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h
+++ b/trunk/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h
@@ -31,13 +31,7 @@
#define DMA_MODE_WRITE 1
#define DMA_MODE_MASK 1
-#define MX1_DMA_REG(offset) MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR + (offset))
-
-/* DMA Interrupt Mask Register */
-#define MX1_DMA_DIMR MX1_DMA_REG(0x08)
-
-/* Channel Control Register */
-#define MX1_DMA_CCR(x) MX1_DMA_REG(0x8c + ((x) << 6))
+#define DMA_BASE IO_ADDRESS(DMA_BASE_ADDR)
#define IMX_DMA_MEMSIZE_32 (0 << 4)
#define IMX_DMA_MEMSIZE_8 (1 << 4)
diff --git a/trunk/arch/arm/plat-omap/include/plat/usb.h b/trunk/arch/arm/plat-omap/include/plat/usb.h
index 876ca8d5e927..568578db93b6 100644
--- a/trunk/arch/arm/plat-omap/include/plat/usb.h
+++ b/trunk/arch/arm/plat-omap/include/plat/usb.h
@@ -46,7 +46,7 @@ struct ehci_hcd_omap_platform_data {
struct omap_musb_board_data {
u8 interface_type;
u8 mode;
- u16 power;
+ u8 power;
};
enum musb_interface {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI};
diff --git a/trunk/arch/arm/plat-pxa/dma.c b/trunk/arch/arm/plat-pxa/dma.c
index 2d3c19d7c7b1..742350e0f2a7 100644
--- a/trunk/arch/arm/plat-pxa/dma.c
+++ b/trunk/arch/arm/plat-pxa/dma.c
@@ -245,7 +245,7 @@ static void pxa_dma_init_debugfs(void)
dbgfs_chan = kmalloc(sizeof(*dbgfs_state) * num_dma_channels,
GFP_KERNEL);
- if (!dbgfs_chan)
+ if (!dbgfs_state)
goto err_alloc;
chandir = debugfs_create_dir("channels", dbgfs_root);
diff --git a/trunk/arch/arm/tools/mach-types b/trunk/arch/arm/tools/mach-types
index 8f10d24ae625..1536f1784cac 100644
--- a/trunk/arch/arm/tools/mach-types
+++ b/trunk/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
#
# http://www.arm.linux.org.uk/developer/machines/?action=new
#
-# Last update: Sat May 1 10:36:42 2010
+# Last update: Sat Mar 20 15:35:41 2010
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -2749,58 +2749,3 @@ stamp9g45 MACH_STAMP9G45 STAMP9G45 2761
h6053 MACH_H6053 H6053 2762
smint01 MACH_SMINT01 SMINT01 2763
prtlvt2 MACH_PRTLVT2 PRTLVT2 2764
-ap420 MACH_AP420 AP420 2765
-htcshift MACH_HTCSHIFT HTCSHIFT 2766
-davinci_dm365_fc MACH_DAVINCI_DM365_FC DAVINCI_DM365_FC 2767
-msm8x55_surf MACH_MSM8X55_SURF MSM8X55_SURF 2768
-msm8x55_ffa MACH_MSM8X55_FFA MSM8X55_FFA 2769
-esl_vamana MACH_ESL_VAMANA ESL_VAMANA 2770
-sbc35 MACH_SBC35 SBC35 2771
-mpx6446 MACH_MPX6446 MPX6446 2772
-oreo_controller MACH_OREO_CONTROLLER OREO_CONTROLLER 2773
-kopin_models MACH_KOPIN_MODELS KOPIN_MODELS 2774
-ttc_vision2 MACH_TTC_VISION2 TTC_VISION2 2775
-cns3420vb MACH_CNS3420VB CNS3420VB 2776
-lpc2 MACH_LPC2 LPC2 2777
-olympus MACH_OLYMPUS OLYMPUS 2778
-vortex MACH_VORTEX VORTEX 2779
-s5pc200 MACH_S5PC200 S5PC200 2780
-ecucore_9263 MACH_ECUCORE_9263 ECUCORE_9263 2781
-smdkc200 MACH_SMDKC200 SMDKC200 2782
-emsiso_sx27 MACH_EMSISO_SX27 EMSISO_SX27 2783
-apx_som9g45_ek MACH_APX_SOM9G45_EK APX_SOM9G45_EK 2784
-songshan MACH_SONGSHAN SONGSHAN 2785
-tianshan MACH_TIANSHAN TIANSHAN 2786
-vpx500 MACH_VPX500 VPX500 2787
-am3517sam MACH_AM3517SAM AM3517SAM 2788
-skat91_sim508 MACH_SKAT91_SIM508 SKAT91_SIM508 2789
-skat91_s3e MACH_SKAT91_S3E SKAT91_S3E 2790
-omap4_panda MACH_OMAP4_PANDA OMAP4_PANDA 2791
-df7220 MACH_DF7220 DF7220 2792
-nemini MACH_NEMINI NEMINI 2793
-t8200 MACH_T8200 T8200 2794
-apf51 MACH_APF51 APF51 2795
-dr_rc_unit MACH_DR_RC_UNIT DR_RC_UNIT 2796
-bordeaux MACH_BORDEAUX BORDEAUX 2797
-catania_b MACH_CATANIA_B CATANIA_B 2798
-mx51_ocean MACH_MX51_OCEAN MX51_OCEAN 2799
-ti8168evm MACH_TI8168EVM TI8168EVM 2800
-neocoreomap MACH_NEOCOREOMAP NEOCOREOMAP 2801
-withings_wbp MACH_WITHINGS_WBP WITHINGS_WBP 2802
-dbps MACH_DBPS DBPS 2803
-sbc9261 MACH_SBC9261 SBC9261 2804
-pcbfp0001 MACH_PCBFP0001 PCBFP0001 2805
-speedy MACH_SPEEDY SPEEDY 2806
-chrysaor MACH_CHRYSAOR CHRYSAOR 2807
-tango MACH_TANGO TANGO 2808
-synology_dsx11 MACH_SYNOLOGY_DSX11 SYNOLOGY_DSX11 2809
-hanlin_v3ext MACH_HANLIN_V3EXT HANLIN_V3EXT 2810
-hanlin_v5 MACH_HANLIN_V5 HANLIN_V5 2811
-hanlin_v3plus MACH_HANLIN_V3PLUS HANLIN_V3PLUS 2812
-iriver_story MACH_IRIVER_STORY IRIVER_STORY 2813
-irex_iliad MACH_IREX_ILIAD IREX_ILIAD 2814
-irex_dr1000 MACH_IREX_DR1000 IREX_DR1000 2815
-teton_bga MACH_TETON_BGA TETON_BGA 2816
-snapper9g45 MACH_SNAPPER9G45 SNAPPER9G45 2817
-tam3517 MACH_TAM3517 TAM3517 2818
-pdc100 MACH_PDC100 PDC100 2819
diff --git a/trunk/arch/avr32/include/asm/atomic.h b/trunk/arch/avr32/include/asm/atomic.h
index bbce6a1c6bb6..b131c27ddf57 100644
--- a/trunk/arch/avr32/include/asm/atomic.h
+++ b/trunk/arch/avr32/include/asm/atomic.h
@@ -19,7 +19,7 @@
#define ATOMIC_INIT(i) { (i) }
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
#define atomic_set(v, i) (((v)->counter) = i)
/*
diff --git a/trunk/arch/cris/include/asm/atomic.h b/trunk/arch/cris/include/asm/atomic.h
index 88dc9b9c4ba0..a6aca819e9f3 100644
--- a/trunk/arch/cris/include/asm/atomic.h
+++ b/trunk/arch/cris/include/asm/atomic.h
@@ -15,7 +15,7 @@
#define ATOMIC_INIT(i) { (i) }
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
#define atomic_set(v,i) (((v)->counter) = (i))
/* These should be written in asm but we do it in C for now. */
diff --git a/trunk/arch/frv/include/asm/atomic.h b/trunk/arch/frv/include/asm/atomic.h
index fae32c7fdcb6..00a57af79afc 100644
--- a/trunk/arch/frv/include/asm/atomic.h
+++ b/trunk/arch/frv/include/asm/atomic.h
@@ -36,7 +36,7 @@
#define smp_mb__after_atomic_inc() barrier()
#define ATOMIC_INIT(i) { (i) }
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
#define atomic_set(v, i) (((v)->counter) = (i))
#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
diff --git a/trunk/arch/h8300/include/asm/atomic.h b/trunk/arch/h8300/include/asm/atomic.h
index e936804b7508..33c8c0fa9583 100644
--- a/trunk/arch/h8300/include/asm/atomic.h
+++ b/trunk/arch/h8300/include/asm/atomic.h
@@ -10,7 +10,7 @@
#define ATOMIC_INIT(i) { (i) }
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
#define atomic_set(v, i) (((v)->counter) = i)
#include
diff --git a/trunk/arch/ia64/include/asm/atomic.h b/trunk/arch/ia64/include/asm/atomic.h
index 4e1948447a00..88405cb0832a 100644
--- a/trunk/arch/ia64/include/asm/atomic.h
+++ b/trunk/arch/ia64/include/asm/atomic.h
@@ -21,8 +21,8 @@
#define ATOMIC_INIT(i) ((atomic_t) { (i) })
#define ATOMIC64_INIT(i) ((atomic64_t) { (i) })
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
-#define atomic64_read(v) (*(volatile long *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
+#define atomic64_read(v) ((v)->counter)
#define atomic_set(v,i) (((v)->counter) = (i))
#define atomic64_set(v,i) (((v)->counter) = (i))
diff --git a/trunk/arch/ia64/include/asm/bitops.h b/trunk/arch/ia64/include/asm/bitops.h
index 9da3df6f1a52..6ebc229a1c51 100644
--- a/trunk/arch/ia64/include/asm/bitops.h
+++ b/trunk/arch/ia64/include/asm/bitops.h
@@ -437,18 +437,17 @@ __fls (unsigned long x)
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
*/
-static __inline__ unsigned long __arch_hweight64(unsigned long x)
+static __inline__ unsigned long
+hweight64 (unsigned long x)
{
unsigned long result;
result = ia64_popcnt(x);
return result;
}
-#define __arch_hweight32(x) ((unsigned int) __arch_hweight64((x) & 0xfffffffful))
-#define __arch_hweight16(x) ((unsigned int) __arch_hweight64((x) & 0xfffful))
-#define __arch_hweight8(x) ((unsigned int) __arch_hweight64((x) & 0xfful))
-
-#include
+#define hweight32(x) (unsigned int) hweight64((x) & 0xfffffffful)
+#define hweight16(x) (unsigned int) hweight64((x) & 0xfffful)
+#define hweight8(x) (unsigned int) hweight64((x) & 0xfful)
#endif /* __KERNEL__ */
diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c
index c6c90f39f4d9..4d1a7e9314cf 100644
--- a/trunk/arch/ia64/kernel/acpi.c
+++ b/trunk/arch/ia64/kernel/acpi.c
@@ -785,14 +785,6 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
return 0;
}
-int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
-{
- if (isa_irq >= 16)
- return -1;
- *gsi = isa_irq;
- return 0;
-}
-
/*
* ACPI based hotplug CPU support
*/
diff --git a/trunk/arch/m32r/include/asm/atomic.h b/trunk/arch/m32r/include/asm/atomic.h
index d44a51e5271b..63f0cf0f50dd 100644
--- a/trunk/arch/m32r/include/asm/atomic.h
+++ b/trunk/arch/m32r/include/asm/atomic.h
@@ -26,7 +26,7 @@
*
* Atomically reads the value of @v.
*/
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
/**
* atomic_set - set atomic variable
diff --git a/trunk/arch/m68k/amiga/Makefile b/trunk/arch/m68k/amiga/Makefile
index 11dd30b16b3b..6a0d7650f980 100644
--- a/trunk/arch/m68k/amiga/Makefile
+++ b/trunk/arch/m68k/amiga/Makefile
@@ -2,6 +2,6 @@
# Makefile for Linux arch/m68k/amiga source directory
#
-obj-y := config.o amiints.o cia.o chipram.o amisound.o platform.o
+obj-y := config.o amiints.o cia.o chipram.o amisound.o
obj-$(CONFIG_AMIGA_PCMCIA) += pcmcia.o
diff --git a/trunk/arch/m68k/amiga/platform.c b/trunk/arch/m68k/amiga/platform.c
deleted file mode 100644
index 38f18bf14737..000000000000
--- a/trunk/arch/m68k/amiga/platform.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2007-2009 Geert Uytterhoeven
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-#include
-#include
-#include
-
-#include
-
-
-#ifdef CONFIG_ZORRO
-
-static const struct resource zorro_resources[] __initconst = {
- /* Zorro II regions (on Zorro II/III) */
- {
- .name = "Zorro II exp",
- .start = 0x00e80000,
- .end = 0x00efffff,
- .flags = IORESOURCE_MEM,
- }, {
- .name = "Zorro II mem",
- .start = 0x00200000,
- .end = 0x009fffff,
- .flags = IORESOURCE_MEM,
- },
- /* Zorro III regions (on Zorro III only) */
- {
- .name = "Zorro III exp",
- .start = 0xff000000,
- .end = 0xffffffff,
- .flags = IORESOURCE_MEM,
- }, {
- .name = "Zorro III cfg",
- .start = 0x40000000,
- .end = 0x7fffffff,
- .flags = IORESOURCE_MEM,
- }
-};
-
-
-static int __init amiga_init_bus(void)
-{
- if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
- return -ENODEV;
-
- platform_device_register_simple("amiga-zorro", -1, zorro_resources,
- AMIGAHW_PRESENT(ZORRO3) ? 4 : 2);
- return 0;
-}
-
-subsys_initcall(amiga_init_bus);
-
-#endif /* CONFIG_ZORRO */
-
-
-static int __init amiga_init_devices(void)
-{
- if (!MACH_IS_AMIGA)
- return -ENODEV;
-
- /* video hardware */
- if (AMIGAHW_PRESENT(AMI_VIDEO))
- platform_device_register_simple("amiga-video", -1, NULL, 0);
-
-
- /* sound hardware */
- if (AMIGAHW_PRESENT(AMI_AUDIO))
- platform_device_register_simple("amiga-audio", -1, NULL, 0);
-
-
- /* storage interfaces */
- if (AMIGAHW_PRESENT(AMI_FLOPPY))
- platform_device_register_simple("amiga-floppy", -1, NULL, 0);
-
- return 0;
-}
-
-device_initcall(amiga_init_devices);
diff --git a/trunk/arch/m68k/bvme6000/rtc.c b/trunk/arch/m68k/bvme6000/rtc.c
index cb8617bb194b..b46ea1714a89 100644
--- a/trunk/arch/m68k/bvme6000/rtc.c
+++ b/trunk/arch/m68k/bvme6000/rtc.c
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -34,9 +35,10 @@
static unsigned char days_in_mo[] =
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-static atomic_t rtc_status = ATOMIC_INIT(1);
+static char rtc_status;
-static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg)
{
volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
unsigned char msr;
@@ -130,20 +132,29 @@ static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
/*
- * We enforce only one user at a time here with the open/close.
+ * We enforce only one user at a time here with the open/close.
+ * Also clear the previous interrupt data on an open, and clean
+ * up things on a close.
*/
+
static int rtc_open(struct inode *inode, struct file *file)
{
- if (!atomic_dec_and_test(&rtc_status)) {
- atomic_inc(&rtc_status);
+ lock_kernel();
+ if(rtc_status) {
+ unlock_kernel();
return -EBUSY;
}
+
+ rtc_status = 1;
+ unlock_kernel();
return 0;
}
static int rtc_release(struct inode *inode, struct file *file)
{
- atomic_inc(&rtc_status);
+ lock_kernel();
+ rtc_status = 0;
+ unlock_kernel();
return 0;
}
@@ -152,9 +163,9 @@ static int rtc_release(struct inode *inode, struct file *file)
*/
static const struct file_operations rtc_fops = {
- .unlocked_ioctl = rtc_ioctl,
- .open = rtc_open,
- .release = rtc_release,
+ .ioctl = rtc_ioctl,
+ .open = rtc_open,
+ .release = rtc_release,
};
static struct miscdevice rtc_dev = {
diff --git a/trunk/arch/m68k/hp300/time.h b/trunk/arch/m68k/hp300/time.h
index 7b98242960de..f5b3d098b0f5 100644
--- a/trunk/arch/m68k/hp300/time.h
+++ b/trunk/arch/m68k/hp300/time.h
@@ -1,2 +1,4 @@
extern void hp300_sched_init(irq_handler_t vector);
-extern unsigned long hp300_gettimeoffset(void);
+extern unsigned long hp300_gettimeoffset (void);
+
+
diff --git a/trunk/arch/m68k/include/asm/atomic_mm.h b/trunk/arch/m68k/include/asm/atomic_mm.h
index 6a223b3f7e74..d9d2ed647435 100644
--- a/trunk/arch/m68k/include/asm/atomic_mm.h
+++ b/trunk/arch/m68k/include/asm/atomic_mm.h
@@ -15,7 +15,7 @@
#define ATOMIC_INIT(i) { (i) }
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
#define atomic_set(v, i) (((v)->counter) = i)
static inline void atomic_add(int i, atomic_t *v)
diff --git a/trunk/arch/m68k/include/asm/atomic_no.h b/trunk/arch/m68k/include/asm/atomic_no.h
index 289310c63a8a..5674cb9449bd 100644
--- a/trunk/arch/m68k/include/asm/atomic_no.h
+++ b/trunk/arch/m68k/include/asm/atomic_no.h
@@ -15,7 +15,7 @@
#define ATOMIC_INIT(i) { (i) }
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
#define atomic_set(v, i) (((v)->counter) = i)
static __inline__ void atomic_add(int i, atomic_t *v)
diff --git a/trunk/arch/m68k/include/asm/bitops_mm.h b/trunk/arch/m68k/include/asm/bitops_mm.h
index b4ecdaada520..9bde784e7bad 100644
--- a/trunk/arch/m68k/include/asm/bitops_mm.h
+++ b/trunk/arch/m68k/include/asm/bitops_mm.h
@@ -365,10 +365,6 @@ static inline int minix_test_bit(int nr, const void *vaddr)
#define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr) ^ 24, (unsigned long *)(addr))
#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr))
#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr))
-#define ext2_find_next_zero_bit(addr, size, offset) \
- generic_find_next_zero_le_bit((unsigned long *)addr, size, offset)
-#define ext2_find_next_bit(addr, size, offset) \
- generic_find_next_le_bit((unsigned long *)addr, size, offset)
static inline int ext2_test_bit(int nr, const void *vaddr)
{
@@ -398,9 +394,10 @@ static inline int ext2_find_first_zero_bit(const void *vaddr, unsigned size)
return (p - addr) * 32 + res;
}
-static inline unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
- unsigned long size, unsigned long offset)
+static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size,
+ unsigned offset)
{
+ const unsigned long *addr = vaddr;
const unsigned long *p = addr + (offset >> 5);
int bit = offset & 31UL, res;
@@ -440,9 +437,10 @@ static inline int ext2_find_first_bit(const void *vaddr, unsigned size)
return (p - addr) * 32 + res;
}
-static inline unsigned long generic_find_next_le_bit(const unsigned long *addr,
- unsigned long size, unsigned long offset)
+static inline int ext2_find_next_bit(const void *vaddr, unsigned size,
+ unsigned offset)
{
+ const unsigned long *addr = vaddr;
const unsigned long *p = addr + (offset >> 5);
int bit = offset & 31UL, res;
diff --git a/trunk/arch/m68k/include/asm/param.h b/trunk/arch/m68k/include/asm/param.h
index 36265ccf5c7b..85c41b75aa78 100644
--- a/trunk/arch/m68k/include/asm/param.h
+++ b/trunk/arch/m68k/include/asm/param.h
@@ -1,12 +1,26 @@
#ifndef _M68K_PARAM_H
#define _M68K_PARAM_H
+#ifdef __KERNEL__
+# define HZ CONFIG_HZ /* Internal kernel timer frequency */
+# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
+# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
+#endif
+
+#ifndef HZ
+#define HZ 100
+#endif
+
#ifdef __uClinux__
#define EXEC_PAGESIZE 4096
#else
#define EXEC_PAGESIZE 8192
#endif
-#include
+#ifndef NOGROUP
+#define NOGROUP (-1)
+#endif
+
+#define MAXHOSTNAMELEN 64 /* max length of hostname */
#endif /* _M68K_PARAM_H */
diff --git a/trunk/arch/m68k/kernel/traps.c b/trunk/arch/m68k/kernel/traps.c
index ada4f4cca811..aacd6d17b833 100644
--- a/trunk/arch/m68k/kernel/traps.c
+++ b/trunk/arch/m68k/kernel/traps.c
@@ -455,7 +455,7 @@ static inline void access_error040(struct frame *fp)
if (do_page_fault(&fp->ptregs, addr, errorcode)) {
#ifdef DEBUG
- printk("do_page_fault() !=0\n");
+ printk("do_page_fault() !=0 \n");
#endif
if (user_mode(&fp->ptregs)){
/* delay writebacks after signal delivery */
diff --git a/trunk/arch/m68k/mac/config.c b/trunk/arch/m68k/mac/config.c
index 1c16b1baf8db..0356da9bf763 100644
--- a/trunk/arch/m68k/mac/config.c
+++ b/trunk/arch/m68k/mac/config.c
@@ -148,7 +148,7 @@ static void mac_cache_card_flush(int writeback)
void __init config_mac(void)
{
if (!MACH_IS_MAC)
- printk(KERN_ERR "ERROR: no Mac, but config_mac() called!!\n");
+ printk(KERN_ERR "ERROR: no Mac, but config_mac() called!! \n");
mach_sched_init = mac_sched_init;
mach_init_IRQ = mac_init_IRQ;
@@ -867,7 +867,7 @@ static void __init mac_identify(void)
*/
iop_preinit();
- printk(KERN_INFO "Detected Macintosh model: %d\n", model);
+ printk(KERN_INFO "Detected Macintosh model: %d \n", model);
/*
* Report booter data:
@@ -878,12 +878,12 @@ static void __init mac_identify(void)
mac_bi_data.videoaddr, mac_bi_data.videorow,
mac_bi_data.videodepth, mac_bi_data.dimensions & 0xFFFF,
mac_bi_data.dimensions >> 16);
- printk(KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx\n",
+ printk(KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx \n",
mac_bi_data.videological, mac_orig_videoaddr,
mac_bi_data.sccbase);
- printk(KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx\n",
+ printk(KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx \n",
mac_bi_data.boottime, mac_bi_data.gmtbias);
- printk(KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx\n",
+ printk(KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx \n",
mac_bi_data.id, mac_bi_data.cpuid, mac_bi_data.memsize);
iop_init();
diff --git a/trunk/arch/m68k/mm/fault.c b/trunk/arch/m68k/mm/fault.c
index a96394a0333d..d0e35cf99fc6 100644
--- a/trunk/arch/m68k/mm/fault.c
+++ b/trunk/arch/m68k/mm/fault.c
@@ -154,6 +154,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
* the fault.
*/
+ survive:
fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
#ifdef DEBUG
printk("handle_mm_fault returns %d\n",fault);
@@ -179,10 +180,15 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (!user_mode(regs))
- goto no_context;
- pagefault_out_of_memory();
- return 0;
+ if (is_global_init(current)) {
+ yield();
+ down_read(&mm->mmap_sem);
+ goto survive;
+ }
+
+ printk("VM: killing process %s\n", current->comm);
+ if (user_mode(regs))
+ do_group_exit(SIGKILL);
no_context:
current->thread.signo = SIGBUS;
diff --git a/trunk/arch/m68k/mvme16x/rtc.c b/trunk/arch/m68k/mvme16x/rtc.c
index 11ac6f63967a..8da9c250d3e1 100644
--- a/trunk/arch/m68k/mvme16x/rtc.c
+++ b/trunk/arch/m68k/mvme16x/rtc.c
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -35,7 +36,8 @@ static const unsigned char days_in_mo[] =
static atomic_t rtc_ready = ATOMIC_INIT(1);
-static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg)
{
volatile MK48T08ptr_t rtc = (MK48T08ptr_t)MVME_RTC_BASE;
unsigned long flags;
@@ -118,15 +120,22 @@ static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
/*
- * We enforce only one user at a time here with the open/close.
+ * We enforce only one user at a time here with the open/close.
+ * Also clear the previous interrupt data on an open, and clean
+ * up things on a close.
*/
+
static int rtc_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
if( !atomic_dec_and_test(&rtc_ready) )
{
atomic_inc( &rtc_ready );
+ unlock_kernel();
return -EBUSY;
}
+ unlock_kernel();
+
return 0;
}
@@ -141,9 +150,9 @@ static int rtc_release(struct inode *inode, struct file *file)
*/
static const struct file_operations rtc_fops = {
- .unlocked_ioctl = rtc_ioctl,
- .open = rtc_open,
- .release = rtc_release,
+ .ioctl = rtc_ioctl,
+ .open = rtc_open,
+ .release = rtc_release,
};
static struct miscdevice rtc_dev=
diff --git a/trunk/arch/m68k/q40/config.c b/trunk/arch/m68k/q40/config.c
index ad10fecec2fe..31ab3f08bbda 100644
--- a/trunk/arch/m68k/q40/config.c
+++ b/trunk/arch/m68k/q40/config.c
@@ -126,7 +126,7 @@ static void q40_reset(void)
{
halted = 1;
printk("\n\n*******************************************\n"
- "Called q40_reset : press the RESET button!!\n"
+ "Called q40_reset : press the RESET button!! \n"
"*******************************************\n");
Q40_LED_ON();
while (1)
diff --git a/trunk/arch/microblaze/configs/mmu_defconfig b/trunk/arch/microblaze/configs/mmu_defconfig
index 3c91cf6192c6..6fced1fe3bf0 100644
--- a/trunk/arch/microblaze/configs/mmu_defconfig
+++ b/trunk/arch/microblaze/configs/mmu_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.34-rc6
-# Thu May 6 11:22:14 2010
+# Linux kernel version: 2.6.33-rc6
+# Wed Feb 3 10:02:59 2010
#
CONFIG_MICROBLAZE=y
# CONFIG_SWAP is not set
@@ -22,6 +22,8 @@ CONFIG_GENERIC_CSUM=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_PCI is not set
+CONFIG_NO_DMA=y
CONFIG_DTC=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -54,6 +56,7 @@ CONFIG_RCU_FANOUT=32
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -103,8 +106,6 @@ CONFIG_SLAB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -244,20 +245,13 @@ CONFIG_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
-
-#
-# Bus Options
-#
-# CONFIG_PCI is not set
-# CONFIG_PCI_DOMAINS is not set
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
@@ -347,9 +341,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
-CONFIG_OF_FLATTREE=y
CONFIG_OF_DEVICE=y
-CONFIG_OF_MDIO=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_COW_COMMON is not set
@@ -378,7 +370,6 @@ CONFIG_MISC_DEVICES=y
#
# SCSI device support
#
-CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -392,30 +383,9 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_QSEMI_PHY is not set
-# CONFIG_LXT_PHY is not set
-# CONFIG_CICADA_PHY is not set
-# CONFIG_VITESSE_PHY is not set
-# CONFIG_SMSC_PHY is not set
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_STE10XP is not set
-# CONFIG_LSI_ET1011C_PHY is not set
-# CONFIG_MICREL_PHY is not set
-# CONFIG_FIXED_PHY is not set
-# CONFIG_MDIO_BITBANG is not set
+# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
-# CONFIG_ETHOC is not set
# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
@@ -424,7 +394,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
# CONFIG_KS8851_MLL is not set
CONFIG_XILINX_EMACLITE=y
@@ -475,7 +444,6 @@ CONFIG_SERIAL_UARTLITE=y
CONFIG_SERIAL_UARTLITE_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -503,12 +471,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -540,7 +502,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
@@ -611,7 +572,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-# CONFIG_LOGFS is not set
# CONFIG_CRAMFS is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -635,7 +595,6 @@ CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
-# CONFIG_CEPH_FS is not set
CONFIG_CIFS=y
CONFIG_CIFS_STATS=y
CONFIG_CIFS_STATS2=y
@@ -737,7 +696,6 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_OBJECTS is not set
CONFIG_DEBUG_SLAB=y
# CONFIG_DEBUG_SLAB_LEAK is not set
-# CONFIG_DEBUG_KMEMLEAK is not set
CONFIG_DEBUG_SPINLOCK=y
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
@@ -783,7 +741,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_EARLY_PRINTK=y
# CONFIG_HEART_BEAT is not set
@@ -905,6 +862,5 @@ CONFIG_ZLIB_INFLATE=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
CONFIG_HAVE_LMB=y
CONFIG_NLATTR=y
diff --git a/trunk/arch/microblaze/configs/nommu_defconfig b/trunk/arch/microblaze/configs/nommu_defconfig
index dd3a494257f4..ce2da535246a 100644
--- a/trunk/arch/microblaze/configs/nommu_defconfig
+++ b/trunk/arch/microblaze/configs/nommu_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.34-rc6
-# Thu May 6 11:25:12 2010
+# Linux kernel version: 2.6.33-rc6
+# Wed Feb 3 10:03:21 2010
#
CONFIG_MICROBLAZE=y
# CONFIG_SWAP is not set
@@ -22,6 +22,8 @@ CONFIG_GENERIC_CSUM=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_PCI is not set
+CONFIG_NO_DMA=y
CONFIG_DTC=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
@@ -56,6 +58,7 @@ CONFIG_RCU_FANOUT=32
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -93,8 +96,6 @@ CONFIG_SLAB=y
# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
# CONFIG_PROFILING is not set
CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DMA_API_DEBUG=y
#
# GCOV-based kernel profiling
@@ -208,14 +209,11 @@ CONFIG_PROC_DEVICETREE=y
#
# Advanced setup
#
-# CONFIG_ADVANCED_OPTIONS is not set
#
# Default settings for advanced configuration options are used
#
-CONFIG_LOWMEM_SIZE=0x30000000
CONFIG_KERNEL_START=0x90000000
-CONFIG_TASK_SIZE=0x80000000
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -237,20 +235,13 @@ CONFIG_BINFMT_FLAT=y
# CONFIG_BINFMT_SHARED_FLAT is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
-
-#
-# Bus Options
-#
-# CONFIG_PCI is not set
-# CONFIG_PCI_DOMAINS is not set
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
@@ -422,7 +413,6 @@ CONFIG_MTD_UCLINUX=y
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
-CONFIG_OF_FLATTREE=y
CONFIG_OF_DEVICE=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
@@ -452,7 +442,6 @@ CONFIG_MISC_DEVICES=y
#
# SCSI device support
#
-CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -469,7 +458,6 @@ CONFIG_NETDEVICES=y
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
-# CONFIG_ETHOC is not set
# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
@@ -478,7 +466,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
# CONFIG_KS8851_MLL is not set
# CONFIG_XILINX_EMACLITE is not set
@@ -529,7 +516,6 @@ CONFIG_SERIAL_UARTLITE=y
CONFIG_SERIAL_UARTLITE_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -558,12 +544,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -613,7 +593,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
@@ -682,7 +661,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
-# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -711,7 +689,6 @@ CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
-# CONFIG_CEPH_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
@@ -756,7 +733,6 @@ CONFIG_DEBUG_OBJECTS_TIMERS=y
# CONFIG_DEBUG_OBJECTS_WORK is not set
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -782,7 +758,6 @@ CONFIG_DEBUG_SG=y
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
-# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -807,7 +782,6 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_EARLY_PRINTK=y
# CONFIG_HEART_BEAT is not set
@@ -927,6 +901,5 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_ZLIB_INFLATE=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
CONFIG_HAVE_LMB=y
CONFIG_NLATTR=y
diff --git a/trunk/arch/microblaze/include/asm/cache.h b/trunk/arch/microblaze/include/asm/cache.h
index 4efe96a036f7..e52210891d78 100644
--- a/trunk/arch/microblaze/include/asm/cache.h
+++ b/trunk/arch/microblaze/include/asm/cache.h
@@ -15,7 +15,7 @@
#include
-#define L1_CACHE_SHIFT 5
+#define L1_CACHE_SHIFT 2
/* word-granular cache in microblaze */
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
diff --git a/trunk/arch/microblaze/include/asm/dma.h b/trunk/arch/microblaze/include/asm/dma.h
index 0d73d0c6de37..08c073badf19 100644
--- a/trunk/arch/microblaze/include/asm/dma.h
+++ b/trunk/arch/microblaze/include/asm/dma.h
@@ -18,10 +18,4 @@
#define MAX_DMA_ADDRESS (CONFIG_KERNEL_START + memory_size - 1)
#endif
-#ifdef CONFIG_PCI
-extern int isa_dma_bridge_buggy;
-#else
-#define isa_dma_bridge_buggy (0)
-#endif
-
#endif /* _ASM_MICROBLAZE_DMA_H */
diff --git a/trunk/arch/microblaze/include/asm/exceptions.h b/trunk/arch/microblaze/include/asm/exceptions.h
index 4c7b5d037c88..90731df9e574 100644
--- a/trunk/arch/microblaze/include/asm/exceptions.h
+++ b/trunk/arch/microblaze/include/asm/exceptions.h
@@ -64,6 +64,12 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
void die(const char *str, struct pt_regs *fp, long err);
void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr);
+#ifdef CONFIG_MMU
+void __bug(const char *file, int line, void *data);
+int bad_trap(int trap_num, struct pt_regs *regs);
+int debug_trap(struct pt_regs *regs);
+#endif /* CONFIG_MMU */
+
#if defined(CONFIG_KGDB)
void (*debugger)(struct pt_regs *regs);
int (*debugger_bpt)(struct pt_regs *regs);
diff --git a/trunk/arch/microblaze/include/asm/io.h b/trunk/arch/microblaze/include/asm/io.h
index 00b5398d08c7..e45a6eea92e0 100644
--- a/trunk/arch/microblaze/include/asm/io.h
+++ b/trunk/arch/microblaze/include/asm/io.h
@@ -139,6 +139,8 @@ static inline void writel(unsigned int v, volatile void __iomem *addr)
#ifdef CONFIG_MMU
+#define mm_ptov(addr) ((void *)__phys_to_virt(addr))
+#define mm_vtop(addr) ((unsigned long)__virt_to_phys(addr))
#define phys_to_virt(addr) ((void *)__phys_to_virt(addr))
#define virt_to_phys(addr) ((unsigned long)__virt_to_phys(addr))
#define virt_to_bus(addr) ((unsigned long)__virt_to_phys(addr))
diff --git a/trunk/arch/microblaze/include/asm/page.h b/trunk/arch/microblaze/include/asm/page.h
index de493f86d28f..2dd1d04129e0 100644
--- a/trunk/arch/microblaze/include/asm/page.h
+++ b/trunk/arch/microblaze/include/asm/page.h
@@ -31,9 +31,6 @@
#ifndef __ASSEMBLY__
-/* MS be sure that SLAB allocates aligned objects */
-#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES
-
#define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
#define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1)))
@@ -73,7 +70,14 @@ typedef unsigned long pte_basic_t;
#endif /* CONFIG_MMU */
-# define copy_page(to, from) memcpy((to), (from), PAGE_SIZE)
+# ifndef CONFIG_MMU
+# define copy_page(to, from) memcpy((to), (from), PAGE_SIZE)
+# define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
+# define free_user_page(page, addr) free_page(addr)
+# else /* CONFIG_MMU */
+extern void copy_page(void *to, void *from);
+# endif /* CONFIG_MMU */
+
# define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE)
# define clear_user_page(pgaddr, vaddr, page) memset((pgaddr), 0, PAGE_SIZE)
diff --git a/trunk/arch/microblaze/include/asm/pci.h b/trunk/arch/microblaze/include/asm/pci.h
index 5a388eeeb28f..bdd65aaee30d 100644
--- a/trunk/arch/microblaze/include/asm/pci.h
+++ b/trunk/arch/microblaze/include/asm/pci.h
@@ -94,6 +94,14 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
#define HAVE_PCI_LEGACY 1
+/* pci_unmap_{page,single} is a nop so... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME) (0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
+#define pci_unmap_len(PTR, LEN_NAME) (0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
+
/* The PCI address space does equal the physical memory
* address space (no IOMMU). The IDE and SCSI device layers use
* this boolean for bounce buffer decisions.
diff --git a/trunk/arch/microblaze/include/asm/pgalloc.h b/trunk/arch/microblaze/include/asm/pgalloc.h
index c614a893f8a3..f44b0d696fe2 100644
--- a/trunk/arch/microblaze/include/asm/pgalloc.h
+++ b/trunk/arch/microblaze/include/asm/pgalloc.h
@@ -108,7 +108,21 @@ extern inline void free_pgd_slow(pgd_t *pgd)
#define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); })
#define pmd_alloc_one(mm, address) ({ BUG(); ((pmd_t *)2); })
-extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+ unsigned long address)
+{
+ pte_t *pte;
+ extern void *early_get_page(void);
+ if (mem_init_done) {
+ pte = (pte_t *)__get_free_page(GFP_KERNEL |
+ __GFP_REPEAT | __GFP_ZERO);
+ } else {
+ pte = (pte_t *)early_get_page();
+ if (pte)
+ clear_page(pte);
+ }
+ return pte;
+}
static inline struct page *pte_alloc_one(struct mm_struct *mm,
unsigned long address)
diff --git a/trunk/arch/microblaze/include/asm/pgtable.h b/trunk/arch/microblaze/include/asm/pgtable.h
index ca2d92871545..dd2bb60651c7 100644
--- a/trunk/arch/microblaze/include/asm/pgtable.h
+++ b/trunk/arch/microblaze/include/asm/pgtable.h
@@ -511,6 +511,15 @@ static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+/*
+ * When flushing the tlb entry for a page, we also need to flush the hash
+ * table entry. flush_hash_page is assembler (for speed) in hashtable.S.
+ */
+extern int flush_hash_page(unsigned context, unsigned long va, pte_t *ptep);
+
+/* Add an HPTE to the hash table */
+extern void add_hash_page(unsigned context, unsigned long va, pte_t *ptep);
+
/*
* Encode and decode a swap entry.
* Note that the bits we use in a PTE for representing a swap entry
@@ -524,7 +533,15 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 2 })
#define __swp_entry_to_pte(x) ((pte_t) { (x).val << 2 })
+
+/* CONFIG_APUS */
+/* For virtual address to physical address conversion */
+extern void cache_clear(__u32 addr, int length);
+extern void cache_push(__u32 addr, int length);
+extern int mm_end_of_chunk(unsigned long addr, int len);
extern unsigned long iopa(unsigned long addr);
+/* extern unsigned long mm_ptov(unsigned long addr) \
+ __attribute__ ((const)); TBD */
/* Values for nocacheflag and cmode */
/* These are not used by the APUS kernel_map, but prevents
@@ -535,6 +552,18 @@ extern unsigned long iopa(unsigned long addr);
#define IOMAP_NOCACHE_NONSER 2
#define IOMAP_NO_COPYBACK 3
+/*
+ * Map some physical address range into the kernel address space.
+ */
+extern unsigned long kernel_map(unsigned long paddr, unsigned long size,
+ int nocacheflag, unsigned long *memavailp);
+
+/*
+ * Set cache mode of (kernel space) address range.
+ */
+extern void kernel_set_cachemode(unsigned long address, unsigned long size,
+ unsigned int cmode);
+
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
#define kern_addr_valid(addr) (1)
@@ -548,6 +577,10 @@ extern unsigned long iopa(unsigned long addr);
void do_page_fault(struct pt_regs *regs, unsigned long address,
unsigned long error_code);
+void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
+ unsigned int size, int flags);
+
+void __init adjust_total_lowmem(void);
void mapin_ram(void);
int map_page(unsigned long va, phys_addr_t pa, int flags);
@@ -568,7 +601,7 @@ void __init *early_get_page(void);
extern unsigned long ioremap_bot, ioremap_base;
void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
-void consistent_free(size_t size, void *vaddr);
+void consistent_free(void *vaddr);
void consistent_sync(void *vaddr, size_t size, int direction);
void consistent_sync_page(struct page *page, unsigned long offset,
size_t size, int direction);
diff --git a/trunk/arch/microblaze/include/asm/uaccess.h b/trunk/arch/microblaze/include/asm/uaccess.h
index 26460d15b338..446bec29b142 100644
--- a/trunk/arch/microblaze/include/asm/uaccess.h
+++ b/trunk/arch/microblaze/include/asm/uaccess.h
@@ -182,39 +182,6 @@ extern long __user_bad(void);
* Returns zero on success, or -EFAULT on error.
* On error, the variable @x is set to zero.
*/
-#define get_user(x, ptr) \
- __get_user_check((x), (ptr), sizeof(*(ptr)))
-
-#define __get_user_check(x, ptr, size) \
-({ \
- unsigned long __gu_val = 0; \
- const typeof(*(ptr)) __user *__gu_addr = (ptr); \
- int __gu_err = 0; \
- \
- if (access_ok(VERIFY_READ, __gu_addr, size)) { \
- switch (size) { \
- case 1: \
- __get_user_asm("lbu", __gu_addr, __gu_val, \
- __gu_err); \
- break; \
- case 2: \
- __get_user_asm("lhu", __gu_addr, __gu_val, \
- __gu_err); \
- break; \
- case 4: \
- __get_user_asm("lw", __gu_addr, __gu_val, \
- __gu_err); \
- break; \
- default: \
- __gu_err = __user_bad(); \
- break; \
- } \
- } else { \
- __gu_err = -EFAULT; \
- } \
- x = (typeof(*(ptr)))__gu_val; \
- __gu_err; \
-})
#define __get_user(x, ptr) \
({ \
@@ -239,6 +206,12 @@ extern long __user_bad(void);
})
+#define get_user(x, ptr) \
+({ \
+ access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) \
+ ? __get_user((x), (ptr)) : -EFAULT; \
+})
+
#define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \
({ \
__asm__ __volatile__ ( \
@@ -293,42 +266,6 @@ extern long __user_bad(void);
*
* Returns zero on success, or -EFAULT on error.
*/
-#define put_user(x, ptr) \
- __put_user_check((x), (ptr), sizeof(*(ptr)))
-
-#define __put_user_check(x, ptr, size) \
-({ \
- typeof(*(ptr)) __pu_val; \
- typeof(*(ptr)) __user *__pu_addr = (ptr); \
- int __pu_err = 0; \
- \
- __pu_val = (x); \
- if (access_ok(VERIFY_WRITE, __pu_addr, size)) { \
- switch (size) { \
- case 1: \
- __put_user_asm("sb", __pu_addr, __pu_val, \
- __pu_err); \
- break; \
- case 2: \
- __put_user_asm("sh", __pu_addr, __pu_val, \
- __pu_err); \
- break; \
- case 4: \
- __put_user_asm("sw", __pu_addr, __pu_val, \
- __pu_err); \
- break; \
- case 8: \
- __put_user_asm_8(__pu_addr, __pu_val, __pu_err);\
- break; \
- default: \
- __pu_err = __user_bad(); \
- break; \
- } \
- } else { \
- __pu_err = -EFAULT; \
- } \
- __pu_err; \
-})
#define __put_user(x, ptr) \
({ \
@@ -353,6 +290,18 @@ extern long __user_bad(void);
__gu_err; \
})
+#ifndef CONFIG_MMU
+
+#define put_user(x, ptr) __put_user((x), (ptr))
+
+#else /* CONFIG_MMU */
+
+#define put_user(x, ptr) \
+({ \
+ access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) \
+ ? __put_user((x), (ptr)) : -EFAULT; \
+})
+#endif /* CONFIG_MMU */
/* copy_to_from_user */
#define __copy_from_user(to, from, n) \
diff --git a/trunk/arch/microblaze/kernel/asm-offsets.c b/trunk/arch/microblaze/kernel/asm-offsets.c
index c1b459c97571..0071260a672c 100644
--- a/trunk/arch/microblaze/kernel/asm-offsets.c
+++ b/trunk/arch/microblaze/kernel/asm-offsets.c
@@ -16,7 +16,6 @@
#include
#include
#include
-#include
int main(int argc, char *argv[])
{
diff --git a/trunk/arch/microblaze/kernel/cpu/cache.c b/trunk/arch/microblaze/kernel/cpu/cache.c
index 109876e8d643..f04d8a86dead 100644
--- a/trunk/arch/microblaze/kernel/cpu/cache.c
+++ b/trunk/arch/microblaze/kernel/cpu/cache.c
@@ -96,16 +96,13 @@ static inline void __disable_dcache_nomsr(void)
}
-/* Helper macro for computing the limits of cache range loops
- *
- * End address can be unaligned which is OK for C implementation.
- * ASM implementation align it in ASM macros
- */
+/* Helper macro for computing the limits of cache range loops */
#define CACHE_LOOP_LIMITS(start, end, cache_line_length, cache_size) \
do { \
int align = ~(cache_line_length - 1); \
end = min(start + cache_size, end); \
start &= align; \
+ end = ((end & align) + cache_line_length); \
} while (0);
/*
@@ -114,9 +111,9 @@ do { \
*/
#define CACHE_ALL_LOOP(cache_size, line_length, op) \
do { \
- unsigned int len = cache_size - line_length; \
+ unsigned int len = cache_size; \
int step = -line_length; \
- WARN_ON(step >= 0); \
+ BUG_ON(step >= 0); \
\
__asm__ __volatile__ (" 1: " #op " %0, r0; \
bgtid %0, 1b; \
@@ -125,22 +122,26 @@ do { \
: "memory"); \
} while (0);
-/* Used for wdc.flush/clear which can use rB for offset which is not possible
- * to use for simple wdc or wic.
- *
- * start address is cache aligned
- * end address is not aligned, if end is aligned then I have to substract
- * cacheline length because I can't flush/invalidate the next cacheline.
- * If is not, I align it because I will flush/invalidate whole line.
- */
+
+#define CACHE_ALL_LOOP2(cache_size, line_length, op) \
+do { \
+ unsigned int len = cache_size; \
+ int step = -line_length; \
+ BUG_ON(step >= 0); \
+ \
+ __asm__ __volatile__ (" 1: " #op " r0, %0; \
+ bgtid %0, 1b; \
+ addk %0, %0, %1; \
+ " : : "r" (len), "r" (step) \
+ : "memory"); \
+} while (0);
+
+/* for wdc.flush/clear */
#define CACHE_RANGE_LOOP_2(start, end, line_length, op) \
do { \
int step = -line_length; \
- int align = ~(line_length - 1); \
- int count; \
- end = ((end & align) == end) ? end - line_length : end & align; \
- count = end - start; \
- WARN_ON(count < 0); \
+ int count = end - start; \
+ BUG_ON(count <= 0); \
\
__asm__ __volatile__ (" 1: " #op " %0, %1; \
bgtid %1, 1b; \
@@ -153,9 +154,7 @@ do { \
#define CACHE_RANGE_LOOP_1(start, end, line_length, op) \
do { \
int volatile temp; \
- int align = ~(line_length - 1); \
- end = ((end & align) == end) ? end - line_length : end & align; \
- WARN_ON(end - start < 0); \
+ BUG_ON(end - start <= 0); \
\
__asm__ __volatile__ (" 1: " #op " %1, r0; \
cmpu %0, %1, %2; \
@@ -361,12 +360,8 @@ static void __invalidate_dcache_all_noirq_wt(void)
#endif
}
-/* FIXME It is blindly invalidation as is expected
- * but can't be called on noMMU in microblaze_cache_init below
- *
- * MS: noMMU kernel won't boot if simple wdc is used
- * The reason should be that there are discared data which kernel needs
- */
+/* FIXME this is weird - should be only wdc but not work
+ * MS: I am getting bus errors and other weird things */
static void __invalidate_dcache_all_wb(void)
{
#ifndef ASM_LOOP
@@ -374,12 +369,12 @@ static void __invalidate_dcache_all_wb(void)
#endif
pr_debug("%s\n", __func__);
#ifdef ASM_LOOP
- CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
- wdc)
+ CACHE_ALL_LOOP2(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
+ wdc.clear)
#else
for (i = 0; i < cpuinfo.dcache_size;
i += cpuinfo.dcache_line_length)
- __asm__ __volatile__ ("wdc %0, r0;" \
+ __asm__ __volatile__ ("wdc.clear %0, r0;" \
: : "r" (i));
#endif
}
@@ -398,7 +393,7 @@ static void __invalidate_dcache_range_wb(unsigned long start,
#ifdef ASM_LOOP
CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.clear);
#else
- for (i = start; i < end; i += cpuinfo.dcache_line_length)
+ for (i = start; i < end; i += cpuinfo.icache_line_length)
__asm__ __volatile__ ("wdc.clear %0, r0;" \
: : "r" (i));
#endif
@@ -418,7 +413,7 @@ static void __invalidate_dcache_range_nomsr_wt(unsigned long start,
#ifdef ASM_LOOP
CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
#else
- for (i = start; i < end; i += cpuinfo.dcache_line_length)
+ for (i = start; i < end; i += cpuinfo.icache_line_length)
__asm__ __volatile__ ("wdc %0, r0;" \
: : "r" (i));
#endif
@@ -442,7 +437,7 @@ static void __invalidate_dcache_range_msr_irq_wt(unsigned long start,
#ifdef ASM_LOOP
CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
#else
- for (i = start; i < end; i += cpuinfo.dcache_line_length)
+ for (i = start; i < end; i += cpuinfo.icache_line_length)
__asm__ __volatile__ ("wdc %0, r0;" \
: : "r" (i));
#endif
@@ -470,7 +465,7 @@ static void __invalidate_dcache_range_nomsr_irq(unsigned long start,
#ifdef ASM_LOOP
CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
#else
- for (i = start; i < end; i += cpuinfo.dcache_line_length)
+ for (i = start; i < end; i += cpuinfo.icache_line_length)
__asm__ __volatile__ ("wdc %0, r0;" \
: : "r" (i));
#endif
@@ -509,7 +504,7 @@ static void __flush_dcache_range_wb(unsigned long start, unsigned long end)
#ifdef ASM_LOOP
CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.flush);
#else
- for (i = start; i < end; i += cpuinfo.dcache_line_length)
+ for (i = start; i < end; i += cpuinfo.icache_line_length)
__asm__ __volatile__ ("wdc.flush %0, r0;" \
: : "r" (i));
#endif
@@ -655,11 +650,7 @@ void microblaze_cache_init(void)
}
}
}
-/* FIXME Invalidation is done in U-BOOT
- * WT cache: Data is already written to main memory
- * WB cache: Discard data on noMMU which caused that kernel doesn't boot
- */
- /* invalidate_dcache(); */
+ invalidate_dcache();
enable_dcache();
invalidate_icache();
diff --git a/trunk/arch/microblaze/kernel/cpu/mb.c b/trunk/arch/microblaze/kernel/cpu/mb.c
index 4216eb1eaa32..0c912b2a8e03 100644
--- a/trunk/arch/microblaze/kernel/cpu/mb.c
+++ b/trunk/arch/microblaze/kernel/cpu/mb.c
@@ -98,17 +98,15 @@ static int show_cpuinfo(struct seq_file *m, void *v)
if (cpuinfo.use_icache)
count += seq_printf(m,
- "Icache:\t\t%ukB\tline length:\t%dB\n",
- cpuinfo.icache_size >> 10,
- cpuinfo.icache_line_length);
+ "Icache:\t\t%ukB\n",
+ cpuinfo.icache_size >> 10);
else
count += seq_printf(m, "Icache:\t\tno\n");
if (cpuinfo.use_dcache) {
count += seq_printf(m,
- "Dcache:\t\t%ukB\tline length:\t%dB\n",
- cpuinfo.dcache_size >> 10,
- cpuinfo.dcache_line_length);
+ "Dcache:\t\t%ukB\n",
+ cpuinfo.dcache_size >> 10);
if (cpuinfo.dcache_wb)
count += seq_printf(m, "\t\twrite-back\n");
else
diff --git a/trunk/arch/microblaze/kernel/dma.c b/trunk/arch/microblaze/kernel/dma.c
index 9dcd90b5df55..ce72dd4967cf 100644
--- a/trunk/arch/microblaze/kernel/dma.c
+++ b/trunk/arch/microblaze/kernel/dma.c
@@ -74,7 +74,7 @@ static void dma_direct_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
#ifdef NOT_COHERENT_CACHE
- consistent_free(size, vaddr);
+ consistent_free(vaddr);
#else
free_pages((unsigned long)vaddr, get_order(size));
#endif
diff --git a/trunk/arch/microblaze/kernel/entry-nommu.S b/trunk/arch/microblaze/kernel/entry-nommu.S
index 8cc18cd2cce6..391d6197fc3b 100644
--- a/trunk/arch/microblaze/kernel/entry-nommu.S
+++ b/trunk/arch/microblaze/kernel/entry-nommu.S
@@ -476,8 +476,6 @@ ENTRY(ret_from_fork)
nop
work_pending:
- enable_irq
-
andi r11, r19, _TIF_NEED_RESCHED
beqi r11, 1f
bralid r15, schedule
diff --git a/trunk/arch/microblaze/kernel/exceptions.c b/trunk/arch/microblaze/kernel/exceptions.c
index 02cbdfe5aa8d..d9f70f83097f 100644
--- a/trunk/arch/microblaze/kernel/exceptions.c
+++ b/trunk/arch/microblaze/kernel/exceptions.c
@@ -121,7 +121,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
}
printk(KERN_WARNING "Divide by zero exception " \
"in kernel mode.\n");
- die("Divide by zero exception", regs, SIGBUS);
+ die("Divide by exception", regs, SIGBUS);
break;
case MICROBLAZE_FPU_EXCEPTION:
pr_debug(KERN_WARNING "FPU exception\n");
diff --git a/trunk/arch/microblaze/kernel/head.S b/trunk/arch/microblaze/kernel/head.S
index 1bf739888260..da6a5f5dc766 100644
--- a/trunk/arch/microblaze/kernel/head.S
+++ b/trunk/arch/microblaze/kernel/head.S
@@ -28,7 +28,6 @@
* for more details.
*/
-#include
#include
#include
#include
@@ -50,7 +49,7 @@ swapper_pg_dir:
#endif /* CONFIG_MMU */
- __HEAD
+ .text
ENTRY(_start)
#if CONFIG_KERNEL_BASE_ADDR == 0
brai TOPHYS(real_start)
diff --git a/trunk/arch/microblaze/kernel/irq.c b/trunk/arch/microblaze/kernel/irq.c
index 8f120aca123d..6f39e2c001f3 100644
--- a/trunk/arch/microblaze/kernel/irq.c
+++ b/trunk/arch/microblaze/kernel/irq.c
@@ -9,7 +9,6 @@
*/
#include
-#include
#include
#include
#include
@@ -33,7 +32,7 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
static u32 concurrent_irq;
-void __irq_entry do_IRQ(struct pt_regs *regs)
+void do_IRQ(struct pt_regs *regs)
{
unsigned int irq;
struct pt_regs *old_regs = set_irq_regs(regs);
diff --git a/trunk/arch/microblaze/kernel/microblaze_ksyms.c b/trunk/arch/microblaze/kernel/microblaze_ksyms.c
index ff85f7718035..bc4dcb7d3861 100644
--- a/trunk/arch/microblaze/kernel/microblaze_ksyms.c
+++ b/trunk/arch/microblaze/kernel/microblaze_ksyms.c
@@ -52,14 +52,3 @@ EXPORT_SYMBOL_GPL(_ebss);
extern void _mcount(void);
EXPORT_SYMBOL(_mcount);
#endif
-
-/*
- * Assembly functions that may be used (directly or indirectly) by modules
- */
-EXPORT_SYMBOL(__copy_tofrom_user);
-EXPORT_SYMBOL(__strncpy_user);
-
-#ifdef CONFIG_OPT_LIB_ASM
-EXPORT_SYMBOL(memcpy);
-EXPORT_SYMBOL(memmove);
-#endif
diff --git a/trunk/arch/microblaze/kernel/misc.S b/trunk/arch/microblaze/kernel/misc.S
index 0fb5fc6c1fc2..7cf86498326c 100644
--- a/trunk/arch/microblaze/kernel/misc.S
+++ b/trunk/arch/microblaze/kernel/misc.S
@@ -93,3 +93,39 @@ early_console_reg_tlb_alloc:
nop
.size early_console_reg_tlb_alloc, . - early_console_reg_tlb_alloc
+
+/*
+ * Copy a whole page (4096 bytes).
+ */
+#define COPY_16_BYTES \
+ lwi r7, r6, 0; \
+ lwi r8, r6, 4; \
+ lwi r9, r6, 8; \
+ lwi r10, r6, 12; \
+ swi r7, r5, 0; \
+ swi r8, r5, 4; \
+ swi r9, r5, 8; \
+ swi r10, r5, 12
+
+
+/* FIXME DCACHE_LINE_BYTES (CONFIG_XILINX_MICROBLAZE0_DCACHE_LINE_LEN * 4)*/
+#define DCACHE_LINE_BYTES (4 * 4)
+
+.globl copy_page;
+.type copy_page, @function
+.align 4;
+copy_page:
+ ori r11, r0, (PAGE_SIZE/DCACHE_LINE_BYTES) - 1
+_copy_page_loop:
+ COPY_16_BYTES
+#if DCACHE_LINE_BYTES >= 32
+ COPY_16_BYTES
+#endif
+ addik r6, r6, DCACHE_LINE_BYTES
+ addik r5, r5, DCACHE_LINE_BYTES
+ bneid r11, _copy_page_loop
+ addik r11, r11, -1
+ rtsd r15, 8
+ nop
+
+ .size copy_page, . - copy_page
diff --git a/trunk/arch/microblaze/kernel/module.c b/trunk/arch/microblaze/kernel/module.c
index 0e73f6606547..cbecf110dc30 100644
--- a/trunk/arch/microblaze/kernel/module.c
+++ b/trunk/arch/microblaze/kernel/module.c
@@ -16,7 +16,6 @@
#include
#include
-#include
void *module_alloc(unsigned long size)
{
@@ -152,7 +151,6 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
struct module *module)
{
- flush_dcache();
return 0;
}
diff --git a/trunk/arch/microblaze/kernel/traps.c b/trunk/arch/microblaze/kernel/traps.c
index 75e49202a5ed..5e4570ef515c 100644
--- a/trunk/arch/microblaze/kernel/traps.c
+++ b/trunk/arch/microblaze/kernel/traps.c
@@ -95,3 +95,37 @@ void dump_stack(void)
show_stack(NULL, NULL);
}
EXPORT_SYMBOL(dump_stack);
+
+#ifdef CONFIG_MMU
+void __bug(const char *file, int line, void *data)
+{
+ if (data)
+ printk(KERN_CRIT "kernel BUG at %s:%d (data = %p)!\n",
+ file, line, data);
+ else
+ printk(KERN_CRIT "kernel BUG at %s:%d!\n", file, line);
+
+ machine_halt();
+}
+
+int bad_trap(int trap_num, struct pt_regs *regs)
+{
+ printk(KERN_CRIT
+ "unimplemented trap %d called at 0x%08lx, pid %d!\n",
+ trap_num, regs->pc, current->pid);
+ return -ENOSYS;
+}
+
+int debug_trap(struct pt_regs *regs)
+{
+ int i;
+ printk(KERN_CRIT "debug trap\n");
+ for (i = 0; i < 32; i++) {
+ /* printk("r%i:%08X\t",i,regs->gpr[i]); */
+ if ((i % 4) == 3)
+ printk(KERN_CRIT "\n");
+ }
+ printk(KERN_CRIT "pc:%08lX\tmsr:%08lX\n", regs->pc, regs->msr);
+ return -ENOSYS;
+}
+#endif
diff --git a/trunk/arch/microblaze/kernel/vmlinux.lds.S b/trunk/arch/microblaze/kernel/vmlinux.lds.S
index db72d7124602..5ef619aad634 100644
--- a/trunk/arch/microblaze/kernel/vmlinux.lds.S
+++ b/trunk/arch/microblaze/kernel/vmlinux.lds.S
@@ -24,8 +24,7 @@ SECTIONS {
.text : AT(ADDR(.text) - LOAD_OFFSET) {
_text = . ;
_stext = . ;
- HEAD_TEXT
- TEXT_TEXT
+ *(.text .text.*)
*(.fixup)
EXIT_TEXT
EXIT_CALL
diff --git a/trunk/arch/microblaze/mm/consistent.c b/trunk/arch/microblaze/mm/consistent.c
index 5a59dad62bd2..f956e24fe49c 100644
--- a/trunk/arch/microblaze/mm/consistent.c
+++ b/trunk/arch/microblaze/mm/consistent.c
@@ -42,12 +42,11 @@
#include
#include
#include
-#include
#ifndef CONFIG_MMU
+
/* I have to use dcache values because I can't relate on ram size */
-# define UNCACHED_SHADOW_MASK (cpuinfo.dcache_high - cpuinfo.dcache_base + 1)
-#endif
+#define UNCACHED_SHADOW_MASK (cpuinfo.dcache_high - cpuinfo.dcache_base + 1)
/*
* Consistent memory allocators. Used for DMA devices that want to
@@ -61,151 +60,144 @@
*/
void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
{
- unsigned long order, vaddr;
- void *ret;
- unsigned int i, err = 0;
- struct page *page, *end;
-
-#ifdef CONFIG_MMU
- phys_addr_t pa;
- struct vm_struct *area;
- unsigned long va;
-#endif
+ struct page *page, *end, *free;
+ unsigned long order;
+ void *ret, *virt;
if (in_interrupt())
BUG();
- /* Only allocate page size areas. */
size = PAGE_ALIGN(size);
order = get_order(size);
- vaddr = __get_free_pages(gfp, order);
- if (!vaddr)
- return NULL;
+ page = alloc_pages(gfp, order);
+ if (!page)
+ goto no_page;
- /*
- * we need to ensure that there are no cachelines in use,
- * or worse dirty in this area.
- */
- flush_dcache_range(virt_to_phys((void *)vaddr),
- virt_to_phys((void *)vaddr) + size);
+ /* We could do with a page_to_phys and page_to_bus here. */
+ virt = page_address(page);
+ ret = ioremap(virt_to_phys(virt), size);
+ if (!ret)
+ goto no_remap;
-#ifndef CONFIG_MMU
- ret = (void *)vaddr;
/*
* Here's the magic! Note if the uncached shadow is not implemented,
* it's up to the calling code to also test that condition and make
* other arranegments, such as manually flushing the cache and so on.
*/
-# ifdef CONFIG_XILINX_UNCACHED_SHADOW
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
ret = (void *)((unsigned) ret | UNCACHED_SHADOW_MASK);
-# endif
- if ((unsigned int)ret > cpuinfo.dcache_base &&
- (unsigned int)ret < cpuinfo.dcache_high)
- printk(KERN_WARNING
- "ERROR: Your cache coherent area is CACHED!!!\n");
-
+#endif
/* dma_handle is same as physical (shadowed) address */
*dma_handle = (dma_addr_t)ret;
+
+ /*
+ * free wasted pages. We skip the first page since we know
+ * that it will have count = 1 and won't require freeing.
+ * We also mark the pages in use as reserved so that
+ * remap_page_range works.
+ */
+ page = virt_to_page(virt);
+ free = page + (size >> PAGE_SHIFT);
+ end = page + (1 << order);
+
+ for (; page < end; page++) {
+ init_page_count(page);
+ if (page >= free)
+ __free_page(page);
+ else
+ SetPageReserved(page);
+ }
+
+ return ret;
+no_remap:
+ __free_pages(page, order);
+no_page:
+ return NULL;
+}
+
#else
+
+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
+{
+ int order, err, i;
+ unsigned long page, va, flags;
+ phys_addr_t pa;
+ struct vm_struct *area;
+ void *ret;
+
+ if (in_interrupt())
+ BUG();
+
+ /* Only allocate page size areas. */
+ size = PAGE_ALIGN(size);
+ order = get_order(size);
+
+ page = __get_free_pages(gfp, order);
+ if (!page) {
+ BUG();
+ return NULL;
+ }
+
+ /*
+ * we need to ensure that there are no cachelines in use,
+ * or worse dirty in this area.
+ */
+ flush_dcache_range(virt_to_phys(page), virt_to_phys(page) + size);
+
/* Allocate some common virtual space to map the new pages. */
area = get_vm_area(size, VM_ALLOC);
- if (!area) {
- free_pages(vaddr, order);
+ if (area == NULL) {
+ free_pages(page, order);
return NULL;
}
va = (unsigned long) area->addr;
ret = (void *)va;
/* This gives us the real physical address of the first page. */
- *dma_handle = pa = virt_to_bus((void *)vaddr);
-#endif
+ *dma_handle = pa = virt_to_bus((void *)page);
+
+ /* MS: This is the whole magic - use cache inhibit pages */
+ flags = _PAGE_KERNEL | _PAGE_NO_CACHE;
/*
- * free wasted pages. We skip the first page since we know
- * that it will have count = 1 and won't require freeing.
- * We also mark the pages in use as reserved so that
- * remap_page_range works.
+ * Set refcount=1 on all pages in an order>0
+ * allocation so that vfree() will actually
+ * free all pages that were allocated.
*/
- page = virt_to_page(vaddr);
- end = page + (1 << order);
-
- split_page(page, order);
-
- for (i = 0; i < size && err == 0; i += PAGE_SIZE) {
-#ifdef CONFIG_MMU
- /* MS: This is the whole magic - use cache inhibit pages */
- err = map_page(va + i, pa + i, _PAGE_KERNEL | _PAGE_NO_CACHE);
-#endif
-
- SetPageReserved(page);
- page++;
+ if (order > 0) {
+ struct page *rpage = virt_to_page(page);
+ for (i = 1; i < (1 << order); i++)
+ init_page_count(rpage+i);
}
- /* Free the otherwise unused pages. */
- while (page < end) {
- __free_page(page);
- page++;
- }
+ err = 0;
+ for (i = 0; i < size && err == 0; i += PAGE_SIZE)
+ err = map_page(va+i, pa+i, flags);
if (err) {
- free_pages(vaddr, order);
+ vfree((void *)va);
return NULL;
}
return ret;
}
+#endif /* CONFIG_MMU */
EXPORT_SYMBOL(consistent_alloc);
/*
* free page(s) as defined by the above mapping.
*/
-void consistent_free(size_t size, void *vaddr)
+void consistent_free(void *vaddr)
{
- struct page *page;
-
if (in_interrupt())
BUG();
- size = PAGE_ALIGN(size);
-
-#ifndef CONFIG_MMU
/* Clear SHADOW_MASK bit in address, and free as per usual */
-# ifdef CONFIG_XILINX_UNCACHED_SHADOW
+#ifdef CONFIG_XILINX_UNCACHED_SHADOW
vaddr = (void *)((unsigned)vaddr & ~UNCACHED_SHADOW_MASK);
-# endif
- page = virt_to_page(vaddr);
-
- do {
- ClearPageReserved(page);
- __free_page(page);
- page++;
- } while (size -= PAGE_SIZE);
-#else
- do {
- pte_t *ptep;
- unsigned long pfn;
-
- ptep = pte_offset_kernel(pmd_offset(pgd_offset_k(
- (unsigned int)vaddr),
- (unsigned int)vaddr),
- (unsigned int)vaddr);
- if (!pte_none(*ptep) && pte_present(*ptep)) {
- pfn = pte_pfn(*ptep);
- pte_clear(&init_mm, (unsigned int)vaddr, ptep);
- if (pfn_valid(pfn)) {
- page = pfn_to_page(pfn);
-
- ClearPageReserved(page);
- __free_page(page);
- }
- }
- vaddr += PAGE_SIZE;
- } while (size -= PAGE_SIZE);
-
- /* flush tlb */
- flush_tlb_all();
#endif
+ vfree(vaddr);
}
EXPORT_SYMBOL(consistent_free);
@@ -229,7 +221,7 @@ void consistent_sync(void *vaddr, size_t size, int direction)
case PCI_DMA_NONE:
BUG();
case PCI_DMA_FROMDEVICE: /* invalidate only */
- invalidate_dcache_range(start, end);
+ flush_dcache_range(start, end);
break;
case PCI_DMA_TODEVICE: /* writeback only */
flush_dcache_range(start, end);
diff --git a/trunk/arch/microblaze/mm/fault.c b/trunk/arch/microblaze/mm/fault.c
index bab922993185..7af87f4b2c2c 100644
--- a/trunk/arch/microblaze/mm/fault.c
+++ b/trunk/arch/microblaze/mm/fault.c
@@ -273,11 +273,16 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
* us unable to handle the page fault gracefully.
*/
out_of_memory:
+ if (current->pid == 1) {
+ yield();
+ down_read(&mm->mmap_sem);
+ goto survive;
+ }
up_read(&mm->mmap_sem);
- if (!user_mode(regs))
- bad_page_fault(regs, address, SIGKILL);
- else
- pagefault_out_of_memory();
+ printk(KERN_WARNING "VM: killing process %s\n", current->comm);
+ if (user_mode(regs))
+ do_exit(SIGKILL);
+ bad_page_fault(regs, address, SIGKILL);
return;
do_sigbus:
diff --git a/trunk/arch/microblaze/mm/init.c b/trunk/arch/microblaze/mm/init.c
index cca3579d4268..f42c2dde8b1c 100644
--- a/trunk/arch/microblaze/mm/init.c
+++ b/trunk/arch/microblaze/mm/init.c
@@ -47,7 +47,6 @@ unsigned long memory_start;
EXPORT_SYMBOL(memory_start);
unsigned long memory_end; /* due to mm/nommu.c */
unsigned long memory_size;
-EXPORT_SYMBOL(memory_size);
/*
* paging_init() sets up the page tables - in fact we've already done this.
diff --git a/trunk/arch/microblaze/mm/pgtable.c b/trunk/arch/microblaze/mm/pgtable.c
index 59bf2335a4ce..d31312cde6ea 100644
--- a/trunk/arch/microblaze/mm/pgtable.c
+++ b/trunk/arch/microblaze/mm/pgtable.c
@@ -42,7 +42,6 @@
unsigned long ioremap_base;
unsigned long ioremap_bot;
-EXPORT_SYMBOL(ioremap_bot);
/* The maximum lowmem defaults to 768Mb, but this can be configured to
* another value.
@@ -162,6 +161,24 @@ int map_page(unsigned long va, phys_addr_t pa, int flags)
return err;
}
+void __init adjust_total_lowmem(void)
+{
+/* TBD */
+#if 0
+ unsigned long max_low_mem = MAX_LOW_MEM;
+
+ if (total_lowmem > max_low_mem) {
+ total_lowmem = max_low_mem;
+#ifndef CONFIG_HIGHMEM
+ printk(KERN_INFO "Warning, memory limited to %ld Mb, use "
+ "CONFIG_HIGHMEM to reach %ld Mb\n",
+ max_low_mem >> 20, total_memory >> 20);
+ total_memory = total_lowmem;
+#endif /* CONFIG_HIGHMEM */
+ }
+#endif
+}
+
/*
* Map in all of physical memory starting at CONFIG_KERNEL_START.
*/
@@ -189,6 +206,24 @@ void __init mapin_ram(void)
/* is x a power of 2? */
#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
+/*
+ * Set up a mapping for a block of I/O.
+ * virt, phys, size must all be page-aligned.
+ * This should only be called before ioremap is called.
+ */
+void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
+ unsigned int size, int flags)
+{
+ int i;
+
+ if (virt > CONFIG_KERNEL_START && virt < ioremap_bot)
+ ioremap_bot = ioremap_base = virt;
+
+ /* Put it in the page tables. */
+ for (i = 0; i < size; i += PAGE_SIZE)
+ map_page(virt + i, phys + i, flags);
+}
+
/* Scan the real Linux page tables and return a PTE pointer for
* a virtual address in a context.
* Returns true (1) if PTE was found, zero otherwise. The pointer to
@@ -239,18 +274,3 @@ unsigned long iopa(unsigned long addr)
return pa;
}
-
-__init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
- unsigned long address)
-{
- pte_t *pte;
- if (mem_init_done) {
- pte = (pte_t *)__get_free_page(GFP_KERNEL |
- __GFP_REPEAT | __GFP_ZERO);
- } else {
- pte = (pte_t *)early_get_page();
- if (pte)
- clear_page(pte);
- }
- return pte;
-}
diff --git a/trunk/arch/microblaze/pci/pci-common.c b/trunk/arch/microblaze/pci/pci-common.c
index 9cb782b8e036..740bb32ec57e 100644
--- a/trunk/arch/microblaze/pci/pci-common.c
+++ b/trunk/arch/microblaze/pci/pci-common.c
@@ -1025,7 +1025,7 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
struct pci_dev *dev = bus->self;
- pci_bus_for_each_resource(bus, res, i) {
+ for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
res = bus->resource[i];
if (!res)
continue;
@@ -1131,20 +1131,21 @@ static int skip_isa_ioresource_align(struct pci_dev *dev)
* but we want to try to avoid allocating at 0x2900-0x2bff
* which might have be mirrored at 0x0100-0x03ff..
*/
-resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+void pcibios_align_resource(void *data, struct resource *res,
resource_size_t size, resource_size_t align)
{
struct pci_dev *dev = data;
- resource_size_t start = res->start;
if (res->flags & IORESOURCE_IO) {
+ resource_size_t start = res->start;
+
if (skip_isa_ioresource_align(dev))
- return start;
- if (start & 0x300)
+ return;
+ if (start & 0x300) {
start = (start + 0x3ff) & ~0x3ff;
+ res->start = start;
+ }
}
-
- return start;
}
EXPORT_SYMBOL(pcibios_align_resource);
@@ -1227,7 +1228,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
pci_domain_nr(bus), bus->number);
- pci_bus_for_each_resource(bus, res, i) {
+ for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
res = bus->resource[i];
if (!res || !res->flags
|| res->start > res->end || res->parent)
@@ -1507,7 +1508,7 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus)
pci_bus_add_devices(bus);
/* Fixup EEH */
- /* eeh_add_device_tree_late(bus); */
+ eeh_add_device_tree_late(bus);
}
EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);
diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig
index 7e6fd1cbd3f8..29e86923d1bf 100644
--- a/trunk/arch/mips/Kconfig
+++ b/trunk/arch/mips/Kconfig
@@ -49,7 +49,7 @@ config AR7
family: TNETD7100, 7200 and 7300.
config BCM47XX
- bool "Broadcom BCM47XX based boards"
+ bool "BCM47XX based boards"
select CEVT_R4K
select CSRC_R4K
select DMA_NONCOHERENT
@@ -509,7 +509,6 @@ config SIBYTE_SWARM
bool "Sibyte BCM91250A-SWARM"
select BOOT_ELF32
select DMA_COHERENT
- select HAVE_PATA_PLATFORM
select NR_CPUS_DEFAULT_2
select SIBYTE_SB1250
select SWAP_IO_SPACE
@@ -524,7 +523,6 @@ config SIBYTE_LITTLESUR
depends on EXPERIMENTAL
select BOOT_ELF32
select DMA_COHERENT
- select HAVE_PATA_PLATFORM
select NR_CPUS_DEFAULT_2
select SIBYTE_SB1250
select SWAP_IO_SPACE
@@ -1307,33 +1305,6 @@ config CPU_CAVIUM_OCTEON
endchoice
-if CPU_LOONGSON2F
-config CPU_NOP_WORKAROUNDS
- bool
-
-config CPU_JUMP_WORKAROUNDS
- bool
-
-config CPU_LOONGSON2F_WORKAROUNDS
- bool "Loongson 2F Workarounds"
- default y
- select CPU_NOP_WORKAROUNDS
- select CPU_JUMP_WORKAROUNDS
- help
- Loongson 2F01 / 2F02 processors have the NOP & JUMP issues which
- require workarounds. Without workarounds the system may hang
- unexpectedly. For more information please refer to the gas
- -mfix-loongson2f-nop and -mfix-loongson2f-jump options.
-
- Loongson 2F03 and later have fixed these issues and no workarounds
- are needed. The workarounds have no significant side effect on them
- but may decrease the performance of the system so this option should
- be disabled unless the kernel is intended to be run on 2F01 or 2F02
- systems.
-
- If unsure, please say Y.
-endif # CPU_LOONGSON2F
-
config SYS_SUPPORTS_ZBOOT
bool
select HAVE_KERNEL_GZIP
diff --git a/trunk/arch/mips/Makefile b/trunk/arch/mips/Makefile
index 0b9c01add0a0..2f2eac233322 100644
--- a/trunk/arch/mips/Makefile
+++ b/trunk/arch/mips/Makefile
@@ -136,19 +136,6 @@ cflags-$(CONFIG_CPU_LOONGSON2E) += \
$(call cc-option,-march=loongson2e,-march=r4600)
cflags-$(CONFIG_CPU_LOONGSON2F) += \
$(call cc-option,-march=loongson2f,-march=r4600)
-# enable the workarounds for loongson2f
-ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
- ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),)
- $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop)
- else
- cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop
- endif
- ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),)
- $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump)
- else
- cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump
- endif
-endif
cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
-Wa,-mips32 -Wa,--trap
diff --git a/trunk/arch/mips/alchemy/devboards/db1200/setup.c b/trunk/arch/mips/alchemy/devboards/db1200/setup.c
index 887619547553..be7e92ea01f3 100644
--- a/trunk/arch/mips/alchemy/devboards/db1200/setup.c
+++ b/trunk/arch/mips/alchemy/devboards/db1200/setup.c
@@ -66,16 +66,12 @@ static int __init db1200_arch_init(void)
set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
- /* insert/eject pairs: one of both is always screaming. To avoid
- * issues they must not be automatically enabled when initially
- * requested.
+ /* do not autoenable these: CPLD has broken edge int handling,
+ * and the CD handler setup requires manual enabling to work
+ * around that.
*/
irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
- irq_to_desc(DB1200_PC0_INSERT_INT)->status |= IRQ_NOAUTOEN;
- irq_to_desc(DB1200_PC0_EJECT_INT)->status |= IRQ_NOAUTOEN;
- irq_to_desc(DB1200_PC1_INSERT_INT)->status |= IRQ_NOAUTOEN;
- irq_to_desc(DB1200_PC1_EJECT_INT)->status |= IRQ_NOAUTOEN;
return 0;
}
diff --git a/trunk/arch/mips/configs/bcm63xx_defconfig b/trunk/arch/mips/configs/bcm63xx_defconfig
index 6389ca0fdc6c..7fee0273c829 100644
--- a/trunk/arch/mips/configs/bcm63xx_defconfig
+++ b/trunk/arch/mips/configs/bcm63xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.34-rc2
-# Tue Mar 23 10:36:32 2010
+# Linux kernel version: 2.6.30-rc6
+# Sun May 31 20:17:18 2009
#
CONFIG_MIPS=y
@@ -9,14 +9,13 @@ CONFIG_MIPS=y
# Machine selection
#
# CONFIG_MACH_ALCHEMY is not set
-# CONFIG_AR7 is not set
# CONFIG_BCM47XX is not set
CONFIG_BCM63XX=y
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MACH_JAZZ is not set
# CONFIG_LASAT is not set
-# CONFIG_MACH_LOONGSON is not set
+# CONFIG_LEMOTE_FULONG is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SIM is not set
# CONFIG_NEC_MARKEINS is not set
@@ -27,7 +26,6 @@ CONFIG_BCM63XX=y
# CONFIG_PNX8550_STB810 is not set
# CONFIG_PMC_MSP is not set
# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_POWERTV is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP28 is not set
@@ -47,17 +45,13 @@ CONFIG_BCM63XX=y
# CONFIG_WR_PPMC is not set
# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
-# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
#
# CPU support
#
-CONFIG_BCM63XX_CPU_6338=y
-CONFIG_BCM63XX_CPU_6345=y
CONFIG_BCM63XX_CPU_6348=y
CONFIG_BCM63XX_CPU_6358=y
CONFIG_BOARD_BCM963XX=y
-CONFIG_LOONGSON_UART_BASE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -75,8 +69,10 @@ CONFIG_CEVT_R4K=y
CONFIG_CSRC_R4K_LIB=y
CONFIG_CSRC_R4K=y
CONFIG_DMA_NONCOHERENT=y
-CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_HOTPLUG_CPU is not set
# CONFIG_NO_IOPORT is not set
CONFIG_GENERIC_GPIO=y
CONFIG_CPU_BIG_ENDIAN=y
@@ -89,8 +85,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_LOONGSON2E is not set
-# CONFIG_CPU_LOONGSON2F is not set
+# CONFIG_CPU_LOONGSON2 is not set
CONFIG_CPU_MIPS32_R1=y
# CONFIG_CPU_MIPS32_R2 is not set
# CONFIG_CPU_MIPS64_R1 is not set
@@ -133,7 +128,7 @@ CONFIG_CPU_HAS_PREFETCH=y
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
@@ -151,8 +146,9 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
-# CONFIG_KSM is not set
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
# CONFIG_HIGH_RES_TIMERS is not set
@@ -174,7 +170,6 @@ CONFIG_PREEMPT_NONE=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -194,12 +189,15 @@ CONFIG_LOCALVERSION=""
#
# RCU Subsystem
#
+CONFIG_CLASSIC_RCU=y
# CONFIG_TREE_RCU is not set
-# CONFIG_TREE_PREEMPT_RCU is not set
-CONFIG_TINY_RCU=y
+# CONFIG_PREEMPT_RCU is not set
# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -207,11 +205,11 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -225,10 +223,6 @@ CONFIG_BASE_FULL=y
# CONFIG_EVENTFD is not set
# CONFIG_SHMEM is not set
# CONFIG_AIO is not set
-
-#
-# Kernel Performance Events And Counters
-#
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_PCI_QUIRKS=y
# CONFIG_SLUB_DEBUG is not set
@@ -237,17 +231,14 @@ CONFIG_COMPAT_BRK=y
CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
-
-#
-# GCOV-based kernel profiling
-#
# CONFIG_SLOW_WORK is not set
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
-CONFIG_LBDAF=y
+# CONFIG_LBD is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -255,41 +246,14 @@ CONFIG_LBDAF=y
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_INLINE_SPIN_TRYLOCK is not set
-# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK is not set
-# CONFIG_INLINE_SPIN_LOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
-CONFIG_INLINE_SPIN_UNLOCK=y
-# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
-CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
-# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_READ_TRYLOCK is not set
-# CONFIG_INLINE_READ_LOCK is not set
-# CONFIG_INLINE_READ_LOCK_BH is not set
-# CONFIG_INLINE_READ_LOCK_IRQ is not set
-# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
-CONFIG_INLINE_READ_UNLOCK=y
-# CONFIG_INLINE_READ_UNLOCK_BH is not set
-CONFIG_INLINE_READ_UNLOCK_IRQ=y
-# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_WRITE_TRYLOCK is not set
-# CONFIG_INLINE_WRITE_LOCK is not set
-# CONFIG_INLINE_WRITE_LOCK_BH is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
-CONFIG_INLINE_WRITE_UNLOCK=y
-# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
-CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
-# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
-# CONFIG_MUTEX_SPIN_ON_OWNER is not set
# CONFIG_FREEZER is not set
#
@@ -299,12 +263,15 @@ CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
CONFIG_MMU=y
CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=y
CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
CONFIG_CARDBUS=y
#
@@ -328,7 +295,6 @@ CONFIG_TRAD_SIGNALS=y
#
# Power management options
#
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PM is not set
CONFIG_NET=y
@@ -367,7 +333,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
-# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -382,7 +347,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
-# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -395,27 +359,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-CONFIG_WIRELESS=y
-CONFIG_WEXT_CORE=y
-CONFIG_WEXT_PROC=y
-CONFIG_CFG80211=y
-CONFIG_NL80211_TESTMODE=y
-# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
-# CONFIG_CFG80211_REG_DEBUG is not set
-CONFIG_CFG80211_DEFAULT_PS=y
-# CONFIG_CFG80211_INTERNAL_REGDB is not set
-CONFIG_CFG80211_WEXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
-# CONFIG_LIB80211 is not set
-CONFIG_MAC80211=y
-# CONFIG_MAC80211_RC_PID is not set
-CONFIG_MAC80211_RC_MINSTREL=y
-# CONFIG_MAC80211_RC_DEFAULT_PID is not set
-CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
-CONFIG_MAC80211_RC_DEFAULT="minstrel"
-# CONFIG_MAC80211_MESH is not set
-CONFIG_MAC80211_LEDS=y
-# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIRELESS is not set
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -527,7 +471,6 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
-CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
@@ -541,16 +484,13 @@ CONFIG_SCSI_MOD=y
#
#
-# You can enable one or both FireWire driver stacks.
-#
-
-#
-# The newer stack is recommended.
+# Enable only one of the two stacks, unless you know what you are doing
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -589,7 +529,6 @@ CONFIG_MII=y
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
# CONFIG_ETHOC is not set
-# CONFIG_SMSC911X is not set
# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
@@ -602,48 +541,17 @@ CONFIG_MII=y
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
-# CONFIG_KS8842 is not set
-# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
CONFIG_BCM63XX_ENET=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
-CONFIG_WLAN=y
-# CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_LIBERTAS_THINFIRM is not set
-# CONFIG_ATMEL is not set
-# CONFIG_AT76C50X_USB is not set
-# CONFIG_AIRO_CS is not set
-# CONFIG_PCMCIA_WL3501 is not set
-# CONFIG_PRISM54 is not set
-# CONFIG_USB_ZD1201 is not set
-# CONFIG_USB_NET_RNDIS_WLAN is not set
-# CONFIG_RTL8180 is not set
-# CONFIG_RTL8187 is not set
-# CONFIG_ADM8211 is not set
-# CONFIG_MAC80211_HWSIM is not set
-# CONFIG_MWL8K is not set
-# CONFIG_ATH_COMMON is not set
-CONFIG_B43=y
-CONFIG_B43_PCI_AUTOSELECT=y
-CONFIG_B43_PCICORE_AUTOSELECT=y
-# CONFIG_B43_PCMCIA is not set
-CONFIG_B43_PIO=y
-# CONFIG_B43_PHY_LP is not set
-CONFIG_B43_LEDS=y
-# CONFIG_B43_DEBUG is not set
-# CONFIG_B43LEGACY is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2200 is not set
-# CONFIG_IWLWIFI is not set
-# CONFIG_LIBERTAS is not set
-# CONFIG_HERMES is not set
-# CONFIG_P54_COMMON is not set
-# CONFIG_RT2X00 is not set
-# CONFIG_WL12XX is not set
-# CONFIG_ZD1211RW is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -666,7 +574,6 @@ CONFIG_B43_LEDS=y
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_VMXNET3 is not set
# CONFIG_ISDN is not set
# CONFIG_PHONE is not set
@@ -700,7 +607,6 @@ CONFIG_B43_LEDS=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
-# CONFIG_SERIAL_TIMBERDALE is not set
CONFIG_SERIAL_BCM63XX=y
CONFIG_SERIAL_BCM63XX_CONSOLE=y
# CONFIG_UNIX98_PTYS is not set
@@ -723,11 +629,6 @@ CONFIG_LEGACY_PTY_COUNT=256
CONFIG_DEVPORT=y
# CONFIG_I2C is not set
# CONFIG_SPI is not set
-
-#
-# PPS support
-#
-# CONFIG_PPS is not set
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_GPIOLIB=y
# CONFIG_GPIO_SYSFS is not set
@@ -735,8 +636,6 @@ CONFIG_GPIOLIB=y
#
# Memory mapped GPIO expanders:
#
-# CONFIG_GPIO_IT8761E is not set
-# CONFIG_GPIO_SCH is not set
#
# I2C GPIO expanders:
@@ -745,21 +644,16 @@ CONFIG_GPIOLIB=y
#
# PCI GPIO expanders:
#
-# CONFIG_GPIO_CS5535 is not set
# CONFIG_GPIO_BT8XX is not set
-# CONFIG_GPIO_LANGWELL is not set
#
# SPI GPIO expanders:
#
-
-#
-# AC97 GPIO expanders:
-#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -768,16 +662,15 @@ CONFIG_SSB_POSSIBLE=y
#
CONFIG_SSB=y
CONFIG_SSB_SPROM=y
-CONFIG_SSB_BLOCKIO=y
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
-CONFIG_SSB_B43_PCI_BRIDGE=y
+# CONFIG_SSB_B43_PCI_BRIDGE is not set
CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
# CONFIG_SSB_PCMCIAHOST is not set
# CONFIG_SSB_SILENT is not set
# CONFIG_SSB_DEBUG is not set
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
-CONFIG_SSB_DRIVER_PCICORE=y
+# CONFIG_SSB_DRIVER_PCICORE is not set
# CONFIG_SSB_DRIVER_MIPS is not set
#
@@ -787,15 +680,27 @@ CONFIG_SSB_DRIVER_PCICORE=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_TIMBERDALE is not set
-# CONFIG_LPC_SCH is not set
# CONFIG_REGULATOR is not set
-# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
#
# Graphics support
#
-# CONFIG_VGA_ARB is not set
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -805,7 +710,11 @@ CONFIG_SSB_DRIVER_PCICORE=y
#
# Display device support
#
-# CONFIG_DISPLAY_SUPPORT is not set
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
# CONFIG_SOUND is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
@@ -832,14 +741,13 @@ CONFIG_USB=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
-# CONFIG_USB_XHCI_HCD is not set
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
-# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_HCD_SSB is not set
CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
@@ -888,6 +796,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -898,8 +807,8 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
#
@@ -910,29 +819,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-
-#
-# LED drivers
-#
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_GPIO_PLATFORM=y
-# CONFIG_LEDS_LT3593 is not set
-CONFIG_LEDS_TRIGGERS=y
-
-#
-# LED Triggers
-#
-CONFIG_LEDS_TRIGGER_TIMER=y
-# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
-# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
-CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-
-#
-# iptables trigger is under Netfilter config (LED target)
-#
+# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
CONFIG_RTC_LIB=y
@@ -940,10 +827,6 @@ CONFIG_RTC_LIB=y
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
-
-#
-# TI VLYNQ
-#
# CONFIG_STAGING is not set
#
@@ -955,16 +838,12 @@ CONFIG_RTC_LIB=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_FILE_LOCKING is not set
# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
-# CONFIG_NILFS2_FS is not set
-# CONFIG_FILE_LOCKING is not set
-CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
-CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
@@ -996,6 +875,8 @@ CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
CONFIG_MISC_FILESYSTEMS=y
@@ -1007,7 +888,6 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
-# CONFIG_LOGFS is not set
# CONFIG_CRAMFS is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1018,6 +898,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
#
@@ -1025,46 +906,7 @@ CONFIG_MISC_FILESYSTEMS=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
+# CONFIG_NLS is not set
# CONFIG_DLM is not set
#
@@ -1076,23 +918,29 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
-# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_TRACING_SUPPORT=y
-# CONFIG_FTRACE is not set
+
+#
+# Tracers
+#
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_EARLY_PRINTK=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="console=ttyS0,115200"
# CONFIG_CMDLINE_OVERRIDE is not set
@@ -1103,108 +951,8 @@ CONFIG_CMDLINE="console=ttyS0,115200"
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
-# CONFIG_DEFAULT_SECURITY_SELINUX is not set
-# CONFIG_DEFAULT_SECURITY_SMACK is not set
-# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
-CONFIG_DEFAULT_SECURITY_DAC=y
-CONFIG_DEFAULT_SECURITY=""
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-# CONFIG_CRYPTO_FIPS is not set
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_ALGAPI2=y
-CONFIG_CRYPTO_AEAD2=y
-CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_BLKCIPHER2=y
-CONFIG_CRYPTO_HASH2=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_PCOMP=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_MANAGER2=y
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-CONFIG_CRYPTO_WORKQUEUE=y
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_SEQIV is not set
-
-#
-# Block modes
-#
-# CONFIG_CRYPTO_CBC is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-CONFIG_CRYPTO_ECB=y
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_VMAC is not set
-
-#
-# Digest
-#
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_GHASH is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
-
-#
-# Ciphers
-#
-CONFIG_CRYPTO_AES=y
-# CONFIG_CRYPTO_ANUBIS is not set
-CONFIG_CRYPTO_ARC4=y
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_SALSA20 is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-
-#
-# Compression
-#
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_LZO is not set
-
-#
-# Random Number Generation
-#
-CONFIG_CRYPTO_ANSI_CPRNG=y
-# CONFIG_CRYPTO_HW is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
# CONFIG_BINARY_PRINTF is not set
#
diff --git a/trunk/arch/mips/include/asm/atomic.h b/trunk/arch/mips/include/asm/atomic.h
index 59dc0c7ef733..519197ede089 100644
--- a/trunk/arch/mips/include/asm/atomic.h
+++ b/trunk/arch/mips/include/asm/atomic.h
@@ -29,7 +29,7 @@
*
* Atomically reads the value of @v.
*/
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
/*
* atomic_set - set atomic variable
@@ -410,7 +410,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
* @v: pointer of type atomic64_t
*
*/
-#define atomic64_read(v) (*(volatile long *)&(v)->counter)
+#define atomic64_read(v) ((v)->counter)
/*
* atomic64_set - set atomic variable
diff --git a/trunk/arch/mips/include/asm/cmpxchg.h b/trunk/arch/mips/include/asm/cmpxchg.h
index 2d28017e95d0..ed9aaaaf0749 100644
--- a/trunk/arch/mips/include/asm/cmpxchg.h
+++ b/trunk/arch/mips/include/asm/cmpxchg.h
@@ -16,7 +16,7 @@
({ \
__typeof(*(m)) __ret; \
\
- if (kernel_uses_llsc && R10000_LLSC_WAR) { \
+ if (kernel_uses_llsc && R10000_LLSC_WAR) { \
__asm__ __volatile__( \
" .set push \n" \
" .set noat \n" \
diff --git a/trunk/arch/mips/include/asm/i8253.h b/trunk/arch/mips/include/asm/i8253.h
index 48bb82372994..032ca73f181b 100644
--- a/trunk/arch/mips/include/asm/i8253.h
+++ b/trunk/arch/mips/include/asm/i8253.h
@@ -12,7 +12,7 @@
#define PIT_CH0 0x40
#define PIT_CH2 0x42
-extern raw_spinlock_t i8253_lock;
+extern spinlock_t i8253_lock;
extern void setup_pit_timer(void);
diff --git a/trunk/arch/mips/include/asm/mach-loongson/loongson.h b/trunk/arch/mips/include/asm/mach-loongson/loongson.h
index fcdbe3a4ce1f..1cf7b1401ee4 100644
--- a/trunk/arch/mips/include/asm/mach-loongson/loongson.h
+++ b/trunk/arch/mips/include/asm/mach-loongson/loongson.h
@@ -307,7 +307,7 @@ extern unsigned long _loongson_addrwincfg_base;
*/
#define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\
s##_WIN##w##_BASE = (src); \
- s##_WIN##w##_MMAP = (dst) | ADDRWIN_MAP_DST_##d; \
+ s##_WIN##w##_MMAP = (src) | ADDRWIN_MAP_DST_##d; \
s##_WIN##w##_MASK = ~(size-1); \
} while (0)
diff --git a/trunk/arch/mips/include/asm/mipsregs.h b/trunk/arch/mips/include/asm/mipsregs.h
index c6e3c93ce7c7..49382d5e891a 100644
--- a/trunk/arch/mips/include/asm/mipsregs.h
+++ b/trunk/arch/mips/include/asm/mipsregs.h
@@ -134,12 +134,6 @@
#define FPU_CSR_COND6 0x40000000 /* $fcc6 */
#define FPU_CSR_COND7 0x80000000 /* $fcc7 */
-/*
- * Bits 18 - 20 of the FPU Status Register will be read as 0,
- * and should be written as zero.
- */
-#define FPU_CSR_RSVD 0x001c0000
-
/*
* X the exception cause indicator
* E the exception enable
@@ -167,8 +161,7 @@
#define FPU_CSR_UDF_S 0x00000008
#define FPU_CSR_INE_S 0x00000004
-/* Bits 0 and 1 of FPU Status Register specify the rounding mode */
-#define FPU_CSR_RM 0x00000003
+/* rounding mode */
#define FPU_CSR_RN 0x0 /* nearest */
#define FPU_CSR_RZ 0x1 /* towards zero */
#define FPU_CSR_RU 0x2 /* towards +Infinity */
diff --git a/trunk/arch/mips/include/asm/pgtable-64.h b/trunk/arch/mips/include/asm/pgtable-64.h
index 1be4b0fa30da..26dc69d792a6 100644
--- a/trunk/arch/mips/include/asm/pgtable-64.h
+++ b/trunk/arch/mips/include/asm/pgtable-64.h
@@ -120,14 +120,9 @@
#endif
#define FIRST_USER_ADDRESS 0UL
-/*
- * TLB refill handlers also map the vmalloc area into xuseg. Avoid
- * the first couple of pages so NULL pointer dereferences will still
- * reliably trap.
- */
-#define VMALLOC_START (MAP_BASE + (2 * PAGE_SIZE))
+#define VMALLOC_START MAP_BASE
#define VMALLOC_END \
- (MAP_BASE + \
+ (VMALLOC_START + \
min(PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, \
(1UL << cpu_vmbits)) - (1UL << 32))
diff --git a/trunk/arch/mips/include/asm/ptrace.h b/trunk/arch/mips/include/asm/ptrace.h
index cdc6a46efd98..ce47118e52b7 100644
--- a/trunk/arch/mips/include/asm/ptrace.h
+++ b/trunk/arch/mips/include/asm/ptrace.h
@@ -142,9 +142,9 @@ extern int ptrace_set_watch_regs(struct task_struct *child,
extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit);
-extern NORET_TYPE void die(const char *, struct pt_regs *) ATTRIB_NORET;
+extern NORET_TYPE void die(const char *, const struct pt_regs *) ATTRIB_NORET;
-static inline void die_if_kernel(const char *str, struct pt_regs *regs)
+static inline void die_if_kernel(const char *str, const struct pt_regs *regs)
{
if (unlikely(!user_mode(regs)))
die(str, regs);
diff --git a/trunk/arch/mips/include/asm/stackframe.h b/trunk/arch/mips/include/asm/stackframe.h
index 58730c5ce4bf..c8419129e770 100644
--- a/trunk/arch/mips/include/asm/stackframe.h
+++ b/trunk/arch/mips/include/asm/stackframe.h
@@ -121,7 +121,7 @@
.endm
#else
.macro get_saved_sp /* Uniprocessor variation */
-#ifdef CONFIG_CPU_JUMP_WORKAROUNDS
+#ifdef CONFIG_CPU_LOONGSON2F
/*
* Clear BTB (branch target buffer), forbid RAS (return address
* stack) to workaround the Out-of-order Issue in Loongson2F
diff --git a/trunk/arch/mips/include/asm/uasm.h b/trunk/arch/mips/include/asm/uasm.h
index 697e40c06497..11a8b5252549 100644
--- a/trunk/arch/mips/include/asm/uasm.h
+++ b/trunk/arch/mips/include/asm/uasm.h
@@ -167,24 +167,6 @@ static inline void __cpuinit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
#define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1)
#define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3)
-static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1,
- unsigned int a2, unsigned int a3)
-{
- if (a3 < 32)
- uasm_i_dsrl(p, a1, a2, a3);
- else
- uasm_i_dsrl32(p, a1, a2, a3 - 32);
-}
-
-static inline void uasm_i_dsll_safe(u32 **p, unsigned int a1,
- unsigned int a2, unsigned int a3)
-{
- if (a3 < 32)
- uasm_i_dsll(p, a1, a2, a3);
- else
- uasm_i_dsll32(p, a1, a2, a3 - 32);
-}
-
/* Handle relocations. */
struct uasm_reloc {
u32 *addr;
diff --git a/trunk/arch/mips/jazz/setup.c b/trunk/arch/mips/jazz/setup.c
index 0d0f054a02f4..7043f6b9ff3c 100644
--- a/trunk/arch/mips/jazz/setup.c
+++ b/trunk/arch/mips/jazz/setup.c
@@ -76,9 +76,15 @@ void __init plat_mem_setup(void)
#ifdef CONFIG_VT
screen_info = (struct screen_info) {
- .orig_video_cols = 160,
- .orig_video_lines = 64,
- .orig_video_points = 16,
+ 0, 0, /* orig-x, orig-y */
+ 0, /* unused */
+ 0, /* orig_video_page */
+ 0, /* orig_video_mode */
+ 160, /* orig_video_cols */
+ 0, 0, 0, /* unused, ega_bx, unused */
+ 64, /* orig_video_lines */
+ 0, /* orig_video_isVGA */
+ 16 /* orig_video_points */
};
#endif
diff --git a/trunk/arch/mips/kernel/i8253.c b/trunk/arch/mips/kernel/i8253.c
index 94794062a177..ed5c441615e4 100644
--- a/trunk/arch/mips/kernel/i8253.c
+++ b/trunk/arch/mips/kernel/i8253.c
@@ -15,7 +15,7 @@
#include
#include
-DEFINE_RAW_SPINLOCK(i8253_lock);
+DEFINE_SPINLOCK(i8253_lock);
EXPORT_SYMBOL(i8253_lock);
/*
@@ -26,7 +26,7 @@ EXPORT_SYMBOL(i8253_lock);
static void init_pit_timer(enum clock_event_mode mode,
struct clock_event_device *evt)
{
- raw_spin_lock(&i8253_lock);
+ spin_lock(&i8253_lock);
switch(mode) {
case CLOCK_EVT_MODE_PERIODIC:
@@ -55,7 +55,7 @@ static void init_pit_timer(enum clock_event_mode mode,
/* Nothing to do here */
break;
}
- raw_spin_unlock(&i8253_lock);
+ spin_unlock(&i8253_lock);
}
/*
@@ -65,10 +65,10 @@ static void init_pit_timer(enum clock_event_mode mode,
*/
static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
{
- raw_spin_lock(&i8253_lock);
+ spin_lock(&i8253_lock);
outb_p(delta & 0xff , PIT_CH0); /* LSB */
outb(delta >> 8 , PIT_CH0); /* MSB */
- raw_spin_unlock(&i8253_lock);
+ spin_unlock(&i8253_lock);
return 0;
}
@@ -137,7 +137,7 @@ static cycle_t pit_read(struct clocksource *cs)
static int old_count;
static u32 old_jifs;
- raw_spin_lock_irqsave(&i8253_lock, flags);
+ spin_lock_irqsave(&i8253_lock, flags);
/*
* Although our caller may have the read side of xtime_lock,
* this is now a seqlock, and we are cheating in this routine
@@ -183,7 +183,7 @@ static cycle_t pit_read(struct clocksource *cs)
old_count = count;
old_jifs = jifs;
- raw_spin_unlock_irqrestore(&i8253_lock, flags);
+ spin_unlock_irqrestore(&i8253_lock, flags);
count = (LATCH - 1) - count;
diff --git a/trunk/arch/mips/kernel/scall64-n32.S b/trunk/arch/mips/kernel/scall64-n32.S
index a5297e2a353a..44337ba03717 100644
--- a/trunk/arch/mips/kernel/scall64-n32.S
+++ b/trunk/arch/mips/kernel/scall64-n32.S
@@ -385,7 +385,7 @@ EXPORT(sysn32_call_table)
PTR sys_fchmodat
PTR sys_faccessat
PTR compat_sys_pselect6
- PTR compat_sys_ppoll /* 6265 */
+ PTR sys_ppoll /* 6265 */
PTR sys_unshare
PTR sys_splice
PTR sys_sync_file_range
diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c
index d612c6dcb746..1a4dd657ccb9 100644
--- a/trunk/arch/mips/kernel/traps.c
+++ b/trunk/arch/mips/kernel/traps.c
@@ -352,10 +352,9 @@ void show_registers(const struct pt_regs *regs)
static DEFINE_SPINLOCK(die_lock);
-void __noreturn die(const char * str, struct pt_regs * regs)
+void __noreturn die(const char * str, const struct pt_regs * regs)
{
static int die_counter;
- int sig = SIGSEGV;
#ifdef CONFIG_MIPS_MT_SMTC
unsigned long dvpret = dvpe();
#endif /* CONFIG_MIPS_MT_SMTC */
@@ -366,10 +365,6 @@ void __noreturn die(const char * str, struct pt_regs * regs)
#ifdef CONFIG_MIPS_MT_SMTC
mips_mt_regdump(dvpret);
#endif /* CONFIG_MIPS_MT_SMTC */
-
- if (notify_die(DIE_OOPS, str, regs, 0, current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
- sig = 0;
-
printk("%s[#%d]:\n", str, ++die_counter);
show_registers(regs);
add_taint(TAINT_DIE);
@@ -384,7 +379,7 @@ void __noreturn die(const char * str, struct pt_regs * regs)
panic("Fatal exception");
}
- do_exit(sig);
+ do_exit(SIGSEGV);
}
extern struct exception_table_entry __start___dbe_table[];
@@ -1562,7 +1557,12 @@ static char panic_null_cerr[] __cpuinitdata =
void __cpuinit set_uncached_handler(unsigned long offset, void *addr,
unsigned long size)
{
- unsigned long uncached_ebase = CKSEG1ADDR(ebase);
+#ifdef CONFIG_32BIT
+ unsigned long uncached_ebase = KSEG1ADDR(ebase);
+#endif
+#ifdef CONFIG_64BIT
+ unsigned long uncached_ebase = TO_UNCAC(ebase);
+#endif
if (!addr)
panic(panic_null_cerr);
diff --git a/trunk/arch/mips/loongson/common/machtype.c b/trunk/arch/mips/loongson/common/machtype.c
index 81fbe6b73f91..853f184b793e 100644
--- a/trunk/arch/mips/loongson/common/machtype.c
+++ b/trunk/arch/mips/loongson/common/machtype.c
@@ -24,7 +24,7 @@ static const char *system_types[] = {
[MACH_LEMOTE_FL2F] "lemote-fuloong-2f-box",
[MACH_LEMOTE_ML2F7] "lemote-mengloong-2f-7inches",
[MACH_LEMOTE_YL2F89] "lemote-yeeloong-2f-8.9inches",
- [MACH_DEXXON_GDIUM2F10] "dexxon-gdium-2f",
+ [MACH_DEXXON_GDIUM2F10] "dexxon-gidum-2f-10inches",
[MACH_LEMOTE_NAS] "lemote-nas-2f",
[MACH_LEMOTE_LL2F] "lemote-lynloong-2f",
[MACH_LOONGSON_END] NULL,
diff --git a/trunk/arch/mips/loongson/common/mem.c b/trunk/arch/mips/loongson/common/mem.c
index 30eba6001205..ec2f7964a0b0 100644
--- a/trunk/arch/mips/loongson/common/mem.c
+++ b/trunk/arch/mips/loongson/common/mem.c
@@ -75,7 +75,7 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long end = offset + size;
if (__uncached_access(file, offset)) {
- if (uca_start && (offset >= uca_start) &&
+ if (((uca_start && offset) >= uca_start) &&
(end <= uca_end))
return __pgprot((pgprot_val(vma_prot) &
~_CACHE_MASK) |
@@ -96,7 +96,7 @@ static int __init find_vga_mem_init(void)
return 0;
for_each_pci_dev(dev) {
- if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+ if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
r = &dev->resource[idx];
if (!r->start && r->end)
diff --git a/trunk/arch/mips/loongson/common/reset.c b/trunk/arch/mips/loongson/common/reset.c
index 9e10d6225d9b..4bd9c18b07a5 100644
--- a/trunk/arch/mips/loongson/common/reset.c
+++ b/trunk/arch/mips/loongson/common/reset.c
@@ -16,31 +16,13 @@
#include
-static inline void loongson_reboot(void)
-{
-#ifndef CONFIG_CPU_JUMP_WORKAROUNDS
- ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
-#else
- void (*func)(void);
-
- func = (void *)ioremap_nocache(LOONGSON_BOOT_BASE, 4);
-
- __asm__ __volatile__(
- " .set noat \n"
- " jr %[func] \n"
- " .set at \n"
- : /* No outputs */
- : [func] "r" (func));
-#endif
-}
-
static void loongson_restart(char *command)
{
/* do preparation for reboot */
mach_prepare_reboot();
/* reboot via jumping to boot base address */
- loongson_reboot();
+ ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
}
static void loongson_poweroff(void)
diff --git a/trunk/arch/mips/loongson/common/setup.c b/trunk/arch/mips/loongson/common/setup.c
index 27d826bc7103..4cd2aa9a342c 100644
--- a/trunk/arch/mips/loongson/common/setup.c
+++ b/trunk/arch/mips/loongson/common/setup.c
@@ -41,12 +41,15 @@ void __init plat_mem_setup(void)
conswitchp = &vga_con;
screen_info = (struct screen_info) {
- .orig_x = 0,
- .orig_y = 25,
- .orig_video_cols = 80,
- .orig_video_lines = 25,
- .orig_video_isVGA = VIDEO_TYPE_VGAC,
- .orig_video_points = 16,
+ 0, 25, /* orig-x, orig-y */
+ 0, /* unused */
+ 0, /* orig-video-page */
+ 0, /* orig-video-mode */
+ 80, /* orig-video-cols */
+ 0, 0, 0, /* ega_ax, ega_bx, ega_cx */
+ 25, /* orig-video-lines */
+ VIDEO_TYPE_VGAC, /* orig-video-isVGA */
+ 16 /* orig-video-points */
};
#elif defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &dummy_con;
diff --git a/trunk/arch/mips/loongson/lemote-2f/irq.c b/trunk/arch/mips/loongson/lemote-2f/irq.c
index 1d8b4d28a058..882dfcd42c00 100644
--- a/trunk/arch/mips/loongson/lemote-2f/irq.c
+++ b/trunk/arch/mips/loongson/lemote-2f/irq.c
@@ -79,7 +79,7 @@ void mach_irq_dispatch(unsigned int pending)
if (pending & CAUSEF_IP7)
do_IRQ(LOONGSON_TIMER_IRQ);
else if (pending & CAUSEF_IP6) { /* North Bridge, Perf counter */
-#if defined(CONFIG_OPROFILE) || defined(CONFIG_OPROFILE_MODULE)
+#ifdef CONFIG_OPROFILE
do_IRQ(LOONGSON2_PERFCNT_IRQ);
#endif
bonito_irqdispatch();
diff --git a/trunk/arch/mips/math-emu/cp1emu.c b/trunk/arch/mips/math-emu/cp1emu.c
index f2338d1c0b48..8f2f8e9d8b21 100644
--- a/trunk/arch/mips/math-emu/cp1emu.c
+++ b/trunk/arch/mips/math-emu/cp1emu.c
@@ -78,9 +78,6 @@ DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
#define FPCREG_RID 0 /* $0 = revision id */
#define FPCREG_CSR 31 /* $31 = csr */
-/* Determine rounding mode from the RM bits of the FCSR */
-#define modeindex(v) ((v) & FPU_CSR_RM)
-
/* Convert Mips rounding mode (0..3) to IEEE library modes. */
static const unsigned char ieee_rm[4] = {
[FPU_CSR_RN] = IEEE754_RN,
@@ -387,14 +384,10 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
(void *) (xcp->cp0_epc),
MIPSInst_RT(ir), value);
#endif
-
- /*
- * Don't write reserved bits,
- * and convert to ieee library modes
- */
- ctx->fcr31 = (value &
- ~(FPU_CSR_RSVD | FPU_CSR_RM)) |
- ieee_rm[modeindex(value)];
+ value &= (FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
+ ctx->fcr31 &= ~(FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
+ /* convert to ieee library modes */
+ ctx->fcr31 |= (value & ~0x3) | ieee_rm[value & 0x3];
}
if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
return SIGFPE;
diff --git a/trunk/arch/mips/mm/tlbex.c b/trunk/arch/mips/mm/tlbex.c
index 86f004dc8355..d1f68aadbc4c 100644
--- a/trunk/arch/mips/mm/tlbex.c
+++ b/trunk/arch/mips/mm/tlbex.c
@@ -31,16 +31,6 @@
#include
#include
-/*
- * TLB load/store/modify handlers.
- *
- * Only the fastpath gets synthesized at runtime, the slowpath for
- * do_page_fault remains normal asm.
- */
-extern void tlb_do_page_fault_0(void);
-extern void tlb_do_page_fault_1(void);
-
-
static inline int r45k_bvahwbug(void)
{
/* XXX: We should probe for the presence of this bug, but we don't. */
@@ -93,7 +83,6 @@ enum label_id {
label_nopage_tlbm,
label_smp_pgtable_change,
label_r3000_write_probe_fail,
- label_large_segbits_fault,
#ifdef CONFIG_HUGETLB_PAGE
label_tlb_huge_update,
#endif
@@ -112,7 +101,6 @@ UASM_L_LA(_nopage_tlbs)
UASM_L_LA(_nopage_tlbm)
UASM_L_LA(_smp_pgtable_change)
UASM_L_LA(_r3000_write_probe_fail)
-UASM_L_LA(_large_segbits_fault)
#ifdef CONFIG_HUGETLB_PAGE
UASM_L_LA(_tlb_huge_update)
#endif
@@ -169,10 +157,6 @@ static u32 tlb_handler[128] __cpuinitdata;
static struct uasm_label labels[128] __cpuinitdata;
static struct uasm_reloc relocs[128] __cpuinitdata;
-#ifdef CONFIG_64BIT
-static int check_for_high_segbits __cpuinitdata;
-#endif
-
#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
/*
* CONFIG_MIPS_PGD_C0_CONTEXT implies 64 bit and lack of pgd_current,
@@ -424,7 +408,7 @@ static __cpuinit __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
} else {
#ifdef CONFIG_64BIT_PHYS_ADDR
- uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL));
+ uasm_i_dsrl(p, reg, reg, ilog2(_PAGE_GLOBAL));
#else
UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL));
#endif
@@ -548,24 +532,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
* The vmalloc handling is not in the hotpath.
*/
uasm_i_dmfc0(p, tmp, C0_BADVADDR);
-
- if (check_for_high_segbits) {
- /*
- * The kernel currently implicitely assumes that the
- * MIPS SEGBITS parameter for the processor is
- * (PGDIR_SHIFT+PGDIR_BITS) or less, and will never
- * allocate virtual addresses outside the maximum
- * range for SEGBITS = (PGDIR_SHIFT+PGDIR_BITS). But
- * that doesn't prevent user code from accessing the
- * higher xuseg addresses. Here, we make sure that
- * everything but the lower xuseg addresses goes down
- * the module_alloc/vmalloc path.
- */
- uasm_i_dsrl_safe(p, ptr, tmp, PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
- uasm_il_bnez(p, r, ptr, label_vmalloc);
- } else {
- uasm_il_bltz(p, r, tmp, label_vmalloc);
- }
+ uasm_il_bltz(p, r, tmp, label_vmalloc);
/* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
@@ -582,14 +549,14 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
* SMTC uses TCBind value as "CPU" index
*/
uasm_i_mfc0(p, ptr, C0_TCBIND);
- uasm_i_dsrl_safe(p, ptr, ptr, 19);
+ uasm_i_dsrl(p, ptr, ptr, 19);
# else
/*
* 64 bit SMP running in XKPHYS has smp_processor_id() << 3
* stored in CONTEXT.
*/
uasm_i_dmfc0(p, ptr, C0_CONTEXT);
- uasm_i_dsrl_safe(p, ptr, ptr, 23);
+ uasm_i_dsrl(p, ptr, ptr, 23);
# endif
UASM_i_LA_mostly(p, tmp, pgdc);
uasm_i_daddu(p, ptr, ptr, tmp);
@@ -602,78 +569,44 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
uasm_l_vmalloc_done(l, *p);
- /* get pgd offset in bytes */
- uasm_i_dsrl_safe(p, tmp, tmp, PGDIR_SHIFT - 3);
+ if (PGDIR_SHIFT - 3 < 32) /* get pgd offset in bytes */
+ uasm_i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3);
+ else
+ uasm_i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32);
uasm_i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
uasm_i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
#ifndef __PAGETABLE_PMD_FOLDED
uasm_i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
uasm_i_ld(p, ptr, 0, ptr); /* get pmd pointer */
- uasm_i_dsrl_safe(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
+ uasm_i_dsrl(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
uasm_i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3);
uasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */
#endif
}
-enum vmalloc64_mode {not_refill, refill};
/*
* BVADDR is the faulting address, PTR is scratch.
* PTR will hold the pgd for vmalloc.
*/
static void __cpuinit
build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
- unsigned int bvaddr, unsigned int ptr,
- enum vmalloc64_mode mode)
+ unsigned int bvaddr, unsigned int ptr)
{
long swpd = (long)swapper_pg_dir;
- int single_insn_swpd;
- int did_vmalloc_branch = 0;
-
- single_insn_swpd = uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd);
uasm_l_vmalloc(l, *p);
- if (mode == refill && check_for_high_segbits) {
- if (single_insn_swpd) {
- uasm_il_bltz(p, r, bvaddr, label_vmalloc_done);
- uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
- did_vmalloc_branch = 1;
- /* fall through */
- } else {
- uasm_il_bgez(p, r, bvaddr, label_large_segbits_fault);
- }
- }
- if (!did_vmalloc_branch) {
- if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
- uasm_il_b(p, r, label_vmalloc_done);
- uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
- } else {
- UASM_i_LA_mostly(p, ptr, swpd);
- uasm_il_b(p, r, label_vmalloc_done);
- if (uasm_in_compat_space_p(swpd))
- uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(swpd));
- else
- uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
- }
- }
- if (mode == refill && check_for_high_segbits) {
- uasm_l_large_segbits_fault(l, *p);
- /*
- * We get here if we are an xsseg address, or if we are
- * an xuseg address above (PGDIR_SHIFT+PGDIR_BITS) boundary.
- *
- * Ignoring xsseg (assume disabled so would generate
- * (address errors?), the only remaining possibility
- * is the upper xuseg addresses. On processors with
- * TLB_SEGBITS <= PGDIR_SHIFT+PGDIR_BITS, these
- * addresses would have taken an address error. We try
- * to mimic that here by taking a load/istream page
- * fault.
- */
- UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0);
- uasm_i_jr(p, ptr);
- uasm_i_nop(p);
+ if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
+ uasm_il_b(p, r, label_vmalloc_done);
+ uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
+ } else {
+ UASM_i_LA_mostly(p, ptr, swpd);
+ uasm_il_b(p, r, label_vmalloc_done);
+ if (uasm_in_compat_space_p(swpd))
+ uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(swpd));
+ else
+ uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
}
}
@@ -787,9 +720,9 @@ static void __cpuinit build_update_entries(u32 **p, unsigned int tmp,
UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
} else {
- uasm_i_dsrl_safe(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
+ uasm_i_dsrl(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
- uasm_i_dsrl_safe(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
+ uasm_i_dsrl(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
}
UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
} else {
@@ -860,9 +793,9 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
uasm_i_dmfc0(&p, K0, C0_BADVADDR);
uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
uasm_i_xor(&p, K0, K0, K1);
- uasm_i_dsrl_safe(&p, K1, K0, 62);
- uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
- uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
+ uasm_i_dsrl32(&p, K1, K0, 62 - 32);
+ uasm_i_dsrl(&p, K0, K0, 12 + 1);
+ uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32);
uasm_i_or(&p, K0, K0, K1);
uasm_il_bnez(&p, &r, K0, label_leave);
/* No need for uasm_i_nop */
@@ -892,7 +825,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
#endif
#ifdef CONFIG_64BIT
- build_get_pgd_vmalloc64(&p, &l, &r, K0, K1, refill);
+ build_get_pgd_vmalloc64(&p, &l, &r, K0, K1);
#endif
/*
@@ -1001,6 +934,15 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
dump_handler((u32 *)ebase, 64);
}
+/*
+ * TLB load/store/modify handlers.
+ *
+ * Only the fastpath gets synthesized at runtime, the slowpath for
+ * do_page_fault remains normal asm.
+ */
+extern void tlb_do_page_fault_0(void);
+extern void tlb_do_page_fault_1(void);
+
/*
* 128 instructions for the fastpath handler is generous and should
* never be exceeded.
@@ -1360,7 +1302,7 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l,
uasm_i_eret(p); /* return from trap */
#ifdef CONFIG_64BIT
- build_get_pgd_vmalloc64(p, l, r, tmp, ptr, not_refill);
+ build_get_pgd_vmalloc64(p, l, r, tmp, ptr);
#endif
}
@@ -1380,9 +1322,9 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
uasm_i_dmfc0(&p, K0, C0_BADVADDR);
uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
uasm_i_xor(&p, K0, K0, K1);
- uasm_i_dsrl_safe(&p, K1, K0, 62);
- uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
- uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
+ uasm_i_dsrl32(&p, K1, K0, 62 - 32);
+ uasm_i_dsrl(&p, K0, K0, 12 + 1);
+ uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32);
uasm_i_or(&p, K0, K0, K1);
uasm_il_bnez(&p, &r, K0, label_leave);
/* No need for uasm_i_nop */
@@ -1584,10 +1526,6 @@ void __cpuinit build_tlb_refill_handler(void)
*/
static int run_once = 0;
-#ifdef CONFIG_64BIT
- check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
-#endif
-
switch (current_cpu_type()) {
case CPU_R2000:
case CPU_R3000:
diff --git a/trunk/arch/mips/nxp/pnx8550/common/reset.c b/trunk/arch/mips/nxp/pnx8550/common/reset.c
index fadd8744a6bc..76bc3ec634ee 100644
--- a/trunk/arch/mips/nxp/pnx8550/common/reset.c
+++ b/trunk/arch/mips/nxp/pnx8550/common/reset.c
@@ -20,8 +20,6 @@
* Reset the PNX8550 board.
*
*/
-#include
-
#include
#include
diff --git a/trunk/arch/mips/oprofile/op_model_loongson2.c b/trunk/arch/mips/oprofile/op_model_loongson2.c
index fa3bf661ae29..29e2326b6257 100644
--- a/trunk/arch/mips/oprofile/op_model_loongson2.c
+++ b/trunk/arch/mips/oprofile/op_model_loongson2.c
@@ -122,7 +122,7 @@ static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id)
*/
/* Check whether the irq belongs to me */
- enabled = read_c0_perfctrl() & LOONGSON2_PERFCNT_INT_EN;
+ enabled = read_c0_perfcnt() & LOONGSON2_PERFCNT_INT_EN;
if (!enabled)
return IRQ_NONE;
enabled = reg.cnt1_enabled | reg.cnt2_enabled;
diff --git a/trunk/arch/mips/pci/pci-sb1250.c b/trunk/arch/mips/pci/pci-sb1250.c
index 1711e8e101bc..ada24e6f951f 100644
--- a/trunk/arch/mips/pci/pci-sb1250.c
+++ b/trunk/arch/mips/pci/pci-sb1250.c
@@ -37,7 +37,6 @@
#include
#include
#include
-#include
#include
@@ -255,7 +254,7 @@ static int __init sb1250_pcibios_init(void)
* XXX ehs: Should this happen in PCI Device mode?
*/
io_map_base = ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 1024 * 1024);
- sb1250_controller.io_map_base = (unsigned long)io_map_base;
+ sb1250_controller.io_map_base = io_map_base;
set_io_port_base((unsigned long)io_map_base);
#ifdef CONFIG_SIBYTE_HAS_LDT
diff --git a/trunk/arch/mips/sgi-ip22/ip22-berr.c b/trunk/arch/mips/sgi-ip22/ip22-berr.c
index 911d3999c0c7..de6a0cc32fea 100644
--- a/trunk/arch/mips/sgi-ip22/ip22-berr.c
+++ b/trunk/arch/mips/sgi-ip22/ip22-berr.c
@@ -89,7 +89,7 @@ static void print_buserr(void)
void ip22_be_interrupt(int irq)
{
const int field = 2 * sizeof(unsigned long);
- struct pt_regs *regs = get_irq_regs();
+ const struct pt_regs *regs = get_irq_regs();
save_and_clear_buserr();
print_buserr();
diff --git a/trunk/arch/mips/sgi-ip22/ip28-berr.c b/trunk/arch/mips/sgi-ip22/ip28-berr.c
index 88c684e05a3d..30e12e2ec4b5 100644
--- a/trunk/arch/mips/sgi-ip22/ip28-berr.c
+++ b/trunk/arch/mips/sgi-ip22/ip28-berr.c
@@ -453,7 +453,7 @@ static int ip28_be_interrupt(const struct pt_regs *regs)
void ip22_be_interrupt(int irq)
{
- struct pt_regs *regs = get_irq_regs();
+ const struct pt_regs *regs = get_irq_regs();
count_be_interrupt++;
diff --git a/trunk/arch/mips/sibyte/swarm/setup.c b/trunk/arch/mips/sibyte/swarm/setup.c
index c308989fc464..5277aac96b0f 100644
--- a/trunk/arch/mips/sibyte/swarm/setup.c
+++ b/trunk/arch/mips/sibyte/swarm/setup.c
@@ -145,14 +145,15 @@ void __init plat_mem_setup(void)
#ifdef CONFIG_VT
screen_info = (struct screen_info) {
- .orig_video_page = 52,
- .orig_video_mode = 3,
- .orig_video_cols = 80,
- .flags = 12,
- .orig_video_ega_bx = 3,
- .orig_video_lines = 25,
- .orig_video_isVGA = 0x22,
- .orig_video_points = 16,
+ 0, 0, /* orig-x, orig-y */
+ 0, /* unused */
+ 52, /* orig_video_page */
+ 3, /* orig_video_mode */
+ 80, /* orig_video_cols */
+ 4626, 3, 9, /* unused, ega_bx, unused */
+ 25, /* orig_video_lines */
+ 0x22, /* orig_video_isVGA */
+ 16 /* orig_video_points */
};
/* XXXKW for CFE, get lines/cols from environment */
#endif
diff --git a/trunk/arch/mn10300/include/asm/atomic.h b/trunk/arch/mn10300/include/asm/atomic.h
index e41222d6c2fd..5bf5be9566de 100644
--- a/trunk/arch/mn10300/include/asm/atomic.h
+++ b/trunk/arch/mn10300/include/asm/atomic.h
@@ -31,7 +31,7 @@
* Atomically reads the value of @v. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
/**
* atomic_set - set atomic variable
diff --git a/trunk/arch/parisc/include/asm/atomic.h b/trunk/arch/parisc/include/asm/atomic.h
index f81955934aeb..716634d1f546 100644
--- a/trunk/arch/parisc/include/asm/atomic.h
+++ b/trunk/arch/parisc/include/asm/atomic.h
@@ -189,7 +189,7 @@ static __inline__ void atomic_set(atomic_t *v, int i)
static __inline__ int atomic_read(const atomic_t *v)
{
- return (*(volatile int *)&(v)->counter);
+ return v->counter;
}
/* exported interface */
@@ -286,7 +286,7 @@ atomic64_set(atomic64_t *v, s64 i)
static __inline__ s64
atomic64_read(const atomic64_t *v)
{
- return (*(volatile long *)&(v)->counter);
+ return v->counter;
}
#define atomic64_add(i,v) ((void)(__atomic64_add_return( ((s64)(i)),(v))))
diff --git a/trunk/arch/powerpc/include/asm/hw_irq.h b/trunk/arch/powerpc/include/asm/hw_irq.h
index bd100fcf40d0..9f4c9d4f5803 100644
--- a/trunk/arch/powerpc/include/asm/hw_irq.h
+++ b/trunk/arch/powerpc/include/asm/hw_irq.h
@@ -130,5 +130,43 @@ static inline int irqs_disabled_flags(unsigned long flags)
*/
struct irq_chip;
+#ifdef CONFIG_PERF_EVENTS
+
+#ifdef CONFIG_PPC64
+static inline unsigned long test_perf_event_pending(void)
+{
+ unsigned long x;
+
+ asm volatile("lbz %0,%1(13)"
+ : "=r" (x)
+ : "i" (offsetof(struct paca_struct, perf_event_pending)));
+ return x;
+}
+
+static inline void set_perf_event_pending(void)
+{
+ asm volatile("stb %0,%1(13)" : :
+ "r" (1),
+ "i" (offsetof(struct paca_struct, perf_event_pending)));
+}
+
+static inline void clear_perf_event_pending(void)
+{
+ asm volatile("stb %0,%1(13)" : :
+ "r" (0),
+ "i" (offsetof(struct paca_struct, perf_event_pending)));
+}
+#endif /* CONFIG_PPC64 */
+
+#else /* CONFIG_PERF_EVENTS */
+
+static inline unsigned long test_perf_event_pending(void)
+{
+ return 0;
+}
+
+static inline void clear_perf_event_pending(void) {}
+#endif /* CONFIG_PERF_EVENTS */
+
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_HW_IRQ_H */
diff --git a/trunk/arch/powerpc/kernel/asm-offsets.c b/trunk/arch/powerpc/kernel/asm-offsets.c
index c09138d150d4..957ceb7059c5 100644
--- a/trunk/arch/powerpc/kernel/asm-offsets.c
+++ b/trunk/arch/powerpc/kernel/asm-offsets.c
@@ -133,6 +133,7 @@ int main(void)
DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr));
DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
+ DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_event_pending));
DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
#ifdef CONFIG_PPC_MM_SLICES
DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
diff --git a/trunk/arch/powerpc/kernel/dma-swiotlb.c b/trunk/arch/powerpc/kernel/dma-swiotlb.c
index 4ff4da2c238b..59c928564a03 100644
--- a/trunk/arch/powerpc/kernel/dma-swiotlb.c
+++ b/trunk/arch/powerpc/kernel/dma-swiotlb.c
@@ -1,8 +1,7 @@
/*
* Contains routines needed to support swiotlb for ppc.
*
- * Copyright (C) 2009-2010 Freescale Semiconductor, Inc.
- * Author: Becky Bruce
+ * Copyright (C) 2009 Becky Bruce, Freescale Semiconductor
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -71,7 +70,7 @@ static int ppc_swiotlb_bus_notify(struct notifier_block *nb,
sd->max_direct_dma_addr = 0;
/* May need to bounce if the device can't address all of DRAM */
- if ((dma_get_mask(dev) + 1) < lmb_end_of_DRAM())
+ if (dma_get_mask(dev) < lmb_end_of_DRAM())
set_dma_ops(dev, &swiotlb_dma_ops);
return NOTIFY_DONE;
diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S
index 42e9d908914a..07109d843787 100644
--- a/trunk/arch/powerpc/kernel/entry_64.S
+++ b/trunk/arch/powerpc/kernel/entry_64.S
@@ -556,6 +556,15 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
2:
TRACE_AND_RESTORE_IRQ(r5);
+#ifdef CONFIG_PERF_EVENTS
+ /* check paca->perf_event_pending if we're enabling ints */
+ lbz r3,PACAPERFPEND(r13)
+ and. r3,r3,r5
+ beq 27f
+ bl .perf_event_do_pending
+27:
+#endif /* CONFIG_PERF_EVENTS */
+
/* extract EE bit and use it to restore paca->hard_enabled */
ld r3,_MSR(r1)
rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c
index 066bd31551d5..64f6f2031c22 100644
--- a/trunk/arch/powerpc/kernel/irq.c
+++ b/trunk/arch/powerpc/kernel/irq.c
@@ -53,6 +53,7 @@
#include
#include
#include
+#include
#include
#include
@@ -144,6 +145,11 @@ notrace void raw_local_irq_restore(unsigned long en)
}
#endif /* CONFIG_PPC_STD_MMU_64 */
+ if (test_perf_event_pending()) {
+ clear_perf_event_pending();
+ perf_event_do_pending();
+ }
+
/*
* if (get_paca()->hard_enabled) return;
* But again we need to take care that gcc gets hard_enabled directly
diff --git a/trunk/arch/powerpc/kernel/perf_event.c b/trunk/arch/powerpc/kernel/perf_event.c
index 43b83c35cf54..08460a2e9f41 100644
--- a/trunk/arch/powerpc/kernel/perf_event.c
+++ b/trunk/arch/powerpc/kernel/perf_event.c
@@ -35,9 +35,6 @@ struct cpu_hw_events {
u64 alternatives[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
unsigned long amasks[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
unsigned long avalues[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
-
- unsigned int group_flag;
- int n_txn_start;
};
DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
@@ -721,6 +718,66 @@ static int collect_events(struct perf_event *group, int max_count,
return n;
}
+static void event_sched_in(struct perf_event *event)
+{
+ event->state = PERF_EVENT_STATE_ACTIVE;
+ event->oncpu = smp_processor_id();
+ event->tstamp_running += event->ctx->time - event->tstamp_stopped;
+ if (is_software_event(event))
+ event->pmu->enable(event);
+}
+
+/*
+ * Called to enable a whole group of events.
+ * Returns 1 if the group was enabled, or -EAGAIN if it could not be.
+ * Assumes the caller has disabled interrupts and has
+ * frozen the PMU with hw_perf_save_disable.
+ */
+int hw_perf_group_sched_in(struct perf_event *group_leader,
+ struct perf_cpu_context *cpuctx,
+ struct perf_event_context *ctx)
+{
+ struct cpu_hw_events *cpuhw;
+ long i, n, n0;
+ struct perf_event *sub;
+
+ if (!ppmu)
+ return 0;
+ cpuhw = &__get_cpu_var(cpu_hw_events);
+ n0 = cpuhw->n_events;
+ n = collect_events(group_leader, ppmu->n_counter - n0,
+ &cpuhw->event[n0], &cpuhw->events[n0],
+ &cpuhw->flags[n0]);
+ if (n < 0)
+ return -EAGAIN;
+ if (check_excludes(cpuhw->event, cpuhw->flags, n0, n))
+ return -EAGAIN;
+ i = power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n + n0);
+ if (i < 0)
+ return -EAGAIN;
+ cpuhw->n_events = n0 + n;
+ cpuhw->n_added += n;
+
+ /*
+ * OK, this group can go on; update event states etc.,
+ * and enable any software events
+ */
+ for (i = n0; i < n0 + n; ++i)
+ cpuhw->event[i]->hw.config = cpuhw->events[i];
+ cpuctx->active_oncpu += n;
+ n = 1;
+ event_sched_in(group_leader);
+ list_for_each_entry(sub, &group_leader->sibling_list, group_entry) {
+ if (sub->state != PERF_EVENT_STATE_OFF) {
+ event_sched_in(sub);
+ ++n;
+ }
+ }
+ ctx->nr_active += n;
+
+ return 1;
+}
+
/*
* Add a event to the PMU.
* If all events are not already frozen, then we disable and
@@ -748,22 +805,12 @@ static int power_pmu_enable(struct perf_event *event)
cpuhw->event[n0] = event;
cpuhw->events[n0] = event->hw.config;
cpuhw->flags[n0] = event->hw.event_base;
-
- /*
- * If group events scheduling transaction was started,
- * skip the schedulability test here, it will be peformed
- * at commit time(->commit_txn) as a whole
- */
- if (cpuhw->group_flag & PERF_EVENT_TXN_STARTED)
- goto nocheck;
-
if (check_excludes(cpuhw->event, cpuhw->flags, n0, 1))
goto out;
if (power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n0 + 1))
goto out;
- event->hw.config = cpuhw->events[n0];
-nocheck:
+ event->hw.config = cpuhw->events[n0];
++cpuhw->n_events;
++cpuhw->n_added;
@@ -849,65 +896,11 @@ static void power_pmu_unthrottle(struct perf_event *event)
local_irq_restore(flags);
}
-/*
- * Start group events scheduling transaction
- * Set the flag to make pmu::enable() not perform the
- * schedulability test, it will be performed at commit time
- */
-void power_pmu_start_txn(const struct pmu *pmu)
-{
- struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
-
- cpuhw->group_flag |= PERF_EVENT_TXN_STARTED;
- cpuhw->n_txn_start = cpuhw->n_events;
-}
-
-/*
- * Stop group events scheduling transaction
- * Clear the flag and pmu::enable() will perform the
- * schedulability test.
- */
-void power_pmu_cancel_txn(const struct pmu *pmu)
-{
- struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
-
- cpuhw->group_flag &= ~PERF_EVENT_TXN_STARTED;
-}
-
-/*
- * Commit group events scheduling transaction
- * Perform the group schedulability test as a whole
- * Return 0 if success
- */
-int power_pmu_commit_txn(const struct pmu *pmu)
-{
- struct cpu_hw_events *cpuhw;
- long i, n;
-
- if (!ppmu)
- return -EAGAIN;
- cpuhw = &__get_cpu_var(cpu_hw_events);
- n = cpuhw->n_events;
- if (check_excludes(cpuhw->event, cpuhw->flags, 0, n))
- return -EAGAIN;
- i = power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n);
- if (i < 0)
- return -EAGAIN;
-
- for (i = cpuhw->n_txn_start; i < n; ++i)
- cpuhw->event[i]->hw.config = cpuhw->events[i];
-
- return 0;
-}
-
struct pmu power_pmu = {
.enable = power_pmu_enable,
.disable = power_pmu_disable,
.read = power_pmu_read,
.unthrottle = power_pmu_unthrottle,
- .start_txn = power_pmu_start_txn,
- .cancel_txn = power_pmu_cancel_txn,
- .commit_txn = power_pmu_commit_txn,
};
/*
diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c
index 0441bbdadbd1..1b16b9a3e49a 100644
--- a/trunk/arch/powerpc/kernel/time.c
+++ b/trunk/arch/powerpc/kernel/time.c
@@ -532,60 +532,25 @@ void __init iSeries_time_init_early(void)
}
#endif /* CONFIG_PPC_ISERIES */
-#ifdef CONFIG_PERF_EVENTS
-
-/*
- * 64-bit uses a byte in the PACA, 32-bit uses a per-cpu variable...
- */
-#ifdef CONFIG_PPC64
-static inline unsigned long test_perf_event_pending(void)
-{
- unsigned long x;
-
- asm volatile("lbz %0,%1(13)"
- : "=r" (x)
- : "i" (offsetof(struct paca_struct, perf_event_pending)));
- return x;
-}
-
-static inline void set_perf_event_pending_flag(void)
-{
- asm volatile("stb %0,%1(13)" : :
- "r" (1),
- "i" (offsetof(struct paca_struct, perf_event_pending)));
-}
-
-static inline void clear_perf_event_pending(void)
-{
- asm volatile("stb %0,%1(13)" : :
- "r" (0),
- "i" (offsetof(struct paca_struct, perf_event_pending)));
-}
-
-#else /* 32-bit */
-
+#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_PPC32)
DEFINE_PER_CPU(u8, perf_event_pending);
-#define set_perf_event_pending_flag() __get_cpu_var(perf_event_pending) = 1
-#define test_perf_event_pending() __get_cpu_var(perf_event_pending)
-#define clear_perf_event_pending() __get_cpu_var(perf_event_pending) = 0
-
-#endif /* 32 vs 64 bit */
-
void set_perf_event_pending(void)
{
- preempt_disable();
- set_perf_event_pending_flag();
+ get_cpu_var(perf_event_pending) = 1;
set_dec(1);
- preempt_enable();
+ put_cpu_var(perf_event_pending);
}
-#else /* CONFIG_PERF_EVENTS */
+#define test_perf_event_pending() __get_cpu_var(perf_event_pending)
+#define clear_perf_event_pending() __get_cpu_var(perf_event_pending) = 0
+
+#else /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */
#define test_perf_event_pending() 0
#define clear_perf_event_pending()
-#endif /* CONFIG_PERF_EVENTS */
+#endif /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */
/*
* For iSeries shared processors, we have to let the hypervisor
@@ -617,6 +582,10 @@ void timer_interrupt(struct pt_regs * regs)
set_dec(DECREMENTER_MAX);
#ifdef CONFIG_PPC32
+ if (test_perf_event_pending()) {
+ clear_perf_event_pending();
+ perf_event_do_pending();
+ }
if (atomic_read(&ppc_n_lost_interrupts) != 0)
do_IRQ(regs);
#endif
@@ -635,11 +604,6 @@ void timer_interrupt(struct pt_regs * regs)
calculate_steal_time();
- if (test_perf_event_pending()) {
- clear_perf_event_pending();
- perf_event_do_pending();
- }
-
#ifdef CONFIG_PPC_ISERIES
if (firmware_has_feature(FW_FEATURE_ISERIES))
get_lppaca()->int_dword.fields.decr_int = 0;
diff --git a/trunk/arch/powerpc/kvm/44x_tlb.c b/trunk/arch/powerpc/kvm/44x_tlb.c
index 812312542e50..2570fcc7665d 100644
--- a/trunk/arch/powerpc/kvm/44x_tlb.c
+++ b/trunk/arch/powerpc/kvm/44x_tlb.c
@@ -440,7 +440,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
unsigned int gtlb_index;
gtlb_index = kvmppc_get_gpr(vcpu, ra);
- if (gtlb_index >= KVM44x_GUEST_TLB_SIZE) {
+ if (gtlb_index > KVM44x_GUEST_TLB_SIZE) {
printk("%s: index %d\n", __func__, gtlb_index);
kvmppc_dump_vcpu(vcpu);
return EMULATE_FAIL;
diff --git a/trunk/arch/s390/kernel/head31.S b/trunk/arch/s390/kernel/head31.S
index b8f8dc126102..1bbcc499d455 100644
--- a/trunk/arch/s390/kernel/head31.S
+++ b/trunk/arch/s390/kernel/head31.S
@@ -82,7 +82,7 @@ startup_continue:
_ehead:
#ifdef CONFIG_SHARED_KERNEL
- .org 0x100000 - 0x11000 # head.o ends at 0x11000
+ .org 0x100000
#endif
#
diff --git a/trunk/arch/s390/kernel/head64.S b/trunk/arch/s390/kernel/head64.S
index cdef68717416..1f70970de0aa 100644
--- a/trunk/arch/s390/kernel/head64.S
+++ b/trunk/arch/s390/kernel/head64.S
@@ -80,7 +80,7 @@ startup_continue:
_ehead:
#ifdef CONFIG_SHARED_KERNEL
- .org 0x100000 - 0x11000 # head.o ends at 0x11000
+ .org 0x100000
#endif
#
diff --git a/trunk/arch/s390/kernel/ptrace.c b/trunk/arch/s390/kernel/ptrace.c
index 9f654da4cecc..33fdc5a79764 100644
--- a/trunk/arch/s390/kernel/ptrace.c
+++ b/trunk/arch/s390/kernel/ptrace.c
@@ -640,7 +640,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
{
- long ret = 0;
+ long ret;
/* Do the secure computing check first. */
secure_computing(regs->gprs[2]);
@@ -649,6 +649,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
* The sysc_tracesys code in entry.S stored the system
* call number to gprs[2].
*/
+ ret = regs->gprs[2];
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
(tracehook_report_syscall_entry(regs) ||
regs->gprs[2] >= NR_syscalls)) {
@@ -670,7 +671,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
regs->gprs[2], regs->orig_gpr2,
regs->gprs[3], regs->gprs[4],
regs->gprs[5]);
- return ret ?: regs->gprs[2];
+ return ret;
}
asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig
index e6d8ab5cfa9d..8d90564c2bcf 100644
--- a/trunk/arch/sh/Kconfig
+++ b/trunk/arch/sh/Kconfig
@@ -44,7 +44,6 @@ config SUPERH32
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_ARCH_KGDB
select HAVE_HW_BREAKPOINT
- select HAVE_MIXED_BREAKPOINTS_REGS
select PERF_EVENTS if HAVE_HW_BREAKPOINT
select ARCH_HIBERNATION_POSSIBLE if MMU
diff --git a/trunk/arch/sh/configs/rts7751r2d1_defconfig b/trunk/arch/sh/configs/rts7751r2d1_defconfig
index dba024d72a89..fba1f62d56e7 100644
--- a/trunk/arch/sh/configs/rts7751r2d1_defconfig
+++ b/trunk/arch/sh/configs/rts7751r2d1_defconfig
@@ -877,7 +877,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
#
# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=2
+CONFIG_SERIAL_SH_SCI_NR_UARTS=1
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
diff --git a/trunk/arch/sh/configs/rts7751r2dplus_defconfig b/trunk/arch/sh/configs/rts7751r2dplus_defconfig
index 6d511d06cbf6..a8d538f06e67 100644
--- a/trunk/arch/sh/configs/rts7751r2dplus_defconfig
+++ b/trunk/arch/sh/configs/rts7751r2dplus_defconfig
@@ -963,7 +963,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
#
# CONFIG_SERIAL_MAX3100 is not set
CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=2
+CONFIG_SERIAL_SH_SCI_NR_UARTS=1
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
diff --git a/trunk/arch/sh/drivers/pci/pci-sh7751.c b/trunk/arch/sh/drivers/pci/pci-sh7751.c
index f98141b3b7d7..17811e5d287b 100644
--- a/trunk/arch/sh/drivers/pci/pci-sh7751.c
+++ b/trunk/arch/sh/drivers/pci/pci-sh7751.c
@@ -17,7 +17,6 @@
#include
#include "pci-sh4.h"
#include
-#include
static int __init __area_sdram_check(struct pci_channel *chan,
unsigned int area)
@@ -48,8 +47,8 @@ static int __init __area_sdram_check(struct pci_channel *chan,
static struct resource sh7751_pci_resources[] = {
{
.name = "SH7751_IO",
- .start = 0x1000,
- .end = SZ_4M - 1,
+ .start = SH7751_PCI_IO_BASE,
+ .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
.flags = IORESOURCE_IO
}, {
.name = "SH7751_mem",
diff --git a/trunk/arch/sh/include/asm/atomic.h b/trunk/arch/sh/include/asm/atomic.h
index c7983124d99d..275a448ae8c2 100644
--- a/trunk/arch/sh/include/asm/atomic.h
+++ b/trunk/arch/sh/include/asm/atomic.h
@@ -13,7 +13,7 @@
#define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
#define atomic_set(v,i) ((v)->counter = (i))
#if defined(CONFIG_GUSA_RB)
diff --git a/trunk/arch/sh/include/asm/hw_breakpoint.h b/trunk/arch/sh/include/asm/hw_breakpoint.h
index e14cad96798f..965dd780d51b 100644
--- a/trunk/arch/sh/include/asm/hw_breakpoint.h
+++ b/trunk/arch/sh/include/asm/hw_breakpoint.h
@@ -46,14 +46,10 @@ struct pmu;
/* Maximum number of UBC channels */
#define HBP_NUM 2
-static inline int hw_breakpoint_slots(int type)
-{
- return HBP_NUM;
-}
-
/* arch/sh/kernel/hw_breakpoint.c */
-extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
-extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int arch_check_va_in_userspace(unsigned long va, u16 hbp_len);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
+ struct task_struct *tsk);
extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
unsigned long val, void *data);
diff --git a/trunk/arch/sh/include/cpu-sh4/cpu/dma-register.h b/trunk/arch/sh/include/cpu-sh4/cpu/dma-register.h
index de2359533994..55f9fec082d4 100644
--- a/trunk/arch/sh/include/cpu-sh4/cpu/dma-register.h
+++ b/trunk/arch/sh/include/cpu-sh4/cpu/dma-register.h
@@ -76,7 +76,7 @@ enum {
}
#define TS_INDEX2VAL(i) ((((i) & 3) << CHCR_TS_LOW_SHIFT) | \
- (((i) & 0xc) << CHCR_TS_HIGH_SHIFT))
+ ((((i) >> 2) & 3) << CHCR_TS_HIGH_SHIFT))
#else /* CONFIG_CPU_SH4A */
diff --git a/trunk/arch/sh/kernel/hw_breakpoint.c b/trunk/arch/sh/kernel/hw_breakpoint.c
index 1f2cf6229862..675eea7785d9 100644
--- a/trunk/arch/sh/kernel/hw_breakpoint.c
+++ b/trunk/arch/sh/kernel/hw_breakpoint.c
@@ -119,17 +119,26 @@ static int get_hbp_len(u16 hbp_len)
return len_in_bytes;
}
+/*
+ * Check for virtual address in user space.
+ */
+int arch_check_va_in_userspace(unsigned long va, u16 hbp_len)
+{
+ unsigned int len;
+
+ len = get_hbp_len(hbp_len);
+
+ return (va <= TASK_SIZE - len);
+}
+
/*
* Check for virtual address in kernel space.
*/
-int arch_check_bp_in_kernelspace(struct perf_event *bp)
+static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
{
unsigned int len;
- unsigned long va;
- struct arch_hw_breakpoint *info = counter_arch_bp(bp);
- va = info->address;
- len = get_hbp_len(info->len);
+ len = get_hbp_len(hbp_len);
return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
}
@@ -217,7 +226,8 @@ static int arch_build_bp_info(struct perf_event *bp)
/*
* Validate the arch-specific HW Breakpoint register settings
*/
-int arch_validate_hwbkpt_settings(struct perf_event *bp)
+int arch_validate_hwbkpt_settings(struct perf_event *bp,
+ struct task_struct *tsk)
{
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
unsigned int align;
@@ -260,6 +270,15 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
if (info->address & align)
return -EINVAL;
+ /* Check that the virtual address is in the proper range */
+ if (tsk) {
+ if (!arch_check_va_in_userspace(info->address, info->len))
+ return -EFAULT;
+ } else {
+ if (!arch_check_va_in_kernelspace(info->address, info->len))
+ return -EFAULT;
+ }
+
return 0;
}
@@ -344,7 +363,8 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)
perf_bp_event(bp, args->regs);
/* Deliver the signal to userspace */
- if (!arch_check_bp_in_kernelspace(bp)) {
+ if (arch_check_va_in_userspace(bp->attr.bp_addr,
+ bp->attr.bp_len)) {
siginfo_t info;
info.si_signo = args->signr;
diff --git a/trunk/arch/sh/kernel/ptrace_32.c b/trunk/arch/sh/kernel/ptrace_32.c
index d4104ce9fe53..7759a9a93211 100644
--- a/trunk/arch/sh/kernel/ptrace_32.c
+++ b/trunk/arch/sh/kernel/ptrace_32.c
@@ -85,7 +85,7 @@ static int set_single_step(struct task_struct *tsk, unsigned long addr)
bp = thread->ptrace_bps[0];
if (!bp) {
- ptrace_breakpoint_init(&attr);
+ hw_breakpoint_init(&attr);
attr.bp_addr = addr;
attr.bp_len = HW_BREAKPOINT_LEN_2;
diff --git a/trunk/arch/sparc/include/asm/atomic_32.h b/trunk/arch/sparc/include/asm/atomic_32.h
index 7ae128b19d3f..f0d343c3b956 100644
--- a/trunk/arch/sparc/include/asm/atomic_32.h
+++ b/trunk/arch/sparc/include/asm/atomic_32.h
@@ -25,7 +25,7 @@ extern int atomic_cmpxchg(atomic_t *, int, int);
extern int atomic_add_unless(atomic_t *, int, int);
extern void atomic_set(atomic_t *, int);
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
#define atomic_add(i, v) ((void)__atomic_add_return( (int)(i), (v)))
#define atomic_sub(i, v) ((void)__atomic_add_return(-(int)(i), (v)))
diff --git a/trunk/arch/sparc/include/asm/atomic_64.h b/trunk/arch/sparc/include/asm/atomic_64.h
index 2050ca02c423..f2e48009989e 100644
--- a/trunk/arch/sparc/include/asm/atomic_64.h
+++ b/trunk/arch/sparc/include/asm/atomic_64.h
@@ -13,8 +13,8 @@
#define ATOMIC_INIT(i) { (i) }
#define ATOMIC64_INIT(i) { (i) }
-#define atomic_read(v) (*(volatile int *)&(v)->counter)
-#define atomic64_read(v) (*(volatile long *)&(v)->counter)
+#define atomic_read(v) ((v)->counter)
+#define atomic64_read(v) ((v)->counter)
#define atomic_set(v, i) (((v)->counter) = i)
#define atomic64_set(v, i) (((v)->counter) = i)
diff --git a/trunk/arch/sparc/include/asm/bitops_64.h b/trunk/arch/sparc/include/asm/bitops_64.h
index 766121a67a24..e72ac9cdfb98 100644
--- a/trunk/arch/sparc/include/asm/bitops_64.h
+++ b/trunk/arch/sparc/include/asm/bitops_64.h
@@ -44,7 +44,7 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr);
#ifdef ULTRA_HAS_POPULATION_COUNT
-static inline unsigned int __arch_hweight64(unsigned long w)
+static inline unsigned int hweight64(unsigned long w)
{
unsigned int res;
@@ -52,7 +52,7 @@ static inline unsigned int __arch_hweight64(unsigned long w)
return res;
}
-static inline unsigned int __arch_hweight32(unsigned int w)
+static inline unsigned int hweight32(unsigned int w)
{
unsigned int res;
@@ -60,7 +60,7 @@ static inline unsigned int __arch_hweight32(unsigned int w)
return res;
}
-static inline unsigned int __arch_hweight16(unsigned int w)
+static inline unsigned int hweight16(unsigned int w)
{
unsigned int res;
@@ -68,7 +68,7 @@ static inline unsigned int __arch_hweight16(unsigned int w)
return res;
}
-static inline unsigned int __arch_hweight8(unsigned int w)
+static inline unsigned int hweight8(unsigned int w)
{
unsigned int res;
@@ -78,10 +78,9 @@ static inline unsigned int __arch_hweight8(unsigned int w)
#else
-#include
+#include
#endif
-#include
#include
#endif /* __KERNEL__ */
diff --git a/trunk/arch/sparc/kernel/perf_event.c b/trunk/arch/sparc/kernel/perf_event.c
index cf4ce263ff81..e2771939341d 100644
--- a/trunk/arch/sparc/kernel/perf_event.c
+++ b/trunk/arch/sparc/kernel/perf_event.c
@@ -91,8 +91,6 @@ struct cpu_hw_events {
/* Enabled/disable state. */
int enabled;
-
- unsigned int group_flag;
};
DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, };
@@ -982,6 +980,53 @@ static int collect_events(struct perf_event *group, int max_count,
return n;
}
+static void event_sched_in(struct perf_event *event)
+{
+ event->state = PERF_EVENT_STATE_ACTIVE;
+ event->oncpu = smp_processor_id();
+ event->tstamp_running += event->ctx->time - event->tstamp_stopped;
+ if (is_software_event(event))
+ event->pmu->enable(event);
+}
+
+int hw_perf_group_sched_in(struct perf_event *group_leader,
+ struct perf_cpu_context *cpuctx,
+ struct perf_event_context *ctx)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct perf_event *sub;
+ int n0, n;
+
+ if (!sparc_pmu)
+ return 0;
+
+ n0 = cpuc->n_events;
+ n = collect_events(group_leader, perf_max_events - n0,
+ &cpuc->event[n0], &cpuc->events[n0],
+ &cpuc->current_idx[n0]);
+ if (n < 0)
+ return -EAGAIN;
+ if (check_excludes(cpuc->event, n0, n))
+ return -EINVAL;
+ if (sparc_check_constraints(cpuc->event, cpuc->events, n + n0))
+ return -EAGAIN;
+ cpuc->n_events = n0 + n;
+ cpuc->n_added += n;
+
+ cpuctx->active_oncpu += n;
+ n = 1;
+ event_sched_in(group_leader);
+ list_for_each_entry(sub, &group_leader->sibling_list, group_entry) {
+ if (sub->state != PERF_EVENT_STATE_OFF) {
+ event_sched_in(sub);
+ n++;
+ }
+ }
+ ctx->nr_active += n;
+
+ return 1;
+}
+
static int sparc_pmu_enable(struct perf_event *event)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
@@ -999,20 +1044,11 @@ static int sparc_pmu_enable(struct perf_event *event)
cpuc->events[n0] = event->hw.event_base;
cpuc->current_idx[n0] = PIC_NO_INDEX;
- /*
- * If group events scheduling transaction was started,
- * skip the schedulability test here, it will be peformed
- * at commit time(->commit_txn) as a whole
- */
- if (cpuc->group_flag & PERF_EVENT_TXN_STARTED)
- goto nocheck;
-
if (check_excludes(cpuc->event, n0, 1))
goto out;
if (sparc_check_constraints(cpuc->event, cpuc->events, n0 + 1))
goto out;
-nocheck:
cpuc->n_events++;
cpuc->n_added++;
@@ -1092,61 +1128,11 @@ static int __hw_perf_event_init(struct perf_event *event)
return 0;
}
-/*
- * Start group events scheduling transaction
- * Set the flag to make pmu::enable() not perform the
- * schedulability test, it will be performed at commit time
- */
-static void sparc_pmu_start_txn(const struct pmu *pmu)
-{
- struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
-
- cpuhw->group_flag |= PERF_EVENT_TXN_STARTED;
-}
-
-/*
- * Stop group events scheduling transaction
- * Clear the flag and pmu::enable() will perform the
- * schedulability test.
- */
-static void sparc_pmu_cancel_txn(const struct pmu *pmu)
-{
- struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
-
- cpuhw->group_flag &= ~PERF_EVENT_TXN_STARTED;
-}
-
-/*
- * Commit group events scheduling transaction
- * Perform the group schedulability test as a whole
- * Return 0 if success
- */
-static int sparc_pmu_commit_txn(const struct pmu *pmu)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- int n;
-
- if (!sparc_pmu)
- return -EINVAL;
-
- cpuc = &__get_cpu_var(cpu_hw_events);
- n = cpuc->n_events;
- if (check_excludes(cpuc->event, 0, n))
- return -EINVAL;
- if (sparc_check_constraints(cpuc->event, cpuc->events, n))
- return -EAGAIN;
-
- return 0;
-}
-
static const struct pmu pmu = {
.enable = sparc_pmu_enable,
.disable = sparc_pmu_disable,
.read = sparc_pmu_read,
.unthrottle = sparc_pmu_unthrottle,
- .start_txn = sparc_pmu_start_txn,
- .cancel_txn = sparc_pmu_cancel_txn,
- .commit_txn = sparc_pmu_commit_txn,
};
const struct pmu *hw_perf_event_init(struct perf_event *event)
diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig
index a2d3a5fbeeda..9458685902bd 100644
--- a/trunk/arch/x86/Kconfig
+++ b/trunk/arch/x86/Kconfig
@@ -53,15 +53,11 @@ config X86
select HAVE_KERNEL_LZMA
select HAVE_KERNEL_LZO
select HAVE_HW_BREAKPOINT
- select HAVE_MIXED_BREAKPOINTS_REGS
select PERF_EVENTS
select ANON_INODES
select HAVE_ARCH_KMEMCHECK
select HAVE_USER_RETURN_NOTIFIER
-config INSTRUCTION_DECODER
- def_bool (KPROBES || PERF_EVENTS)
-
config OUTPUT_FORMAT
string
default "elf32-i386" if X86_32
@@ -201,17 +197,20 @@ config HAVE_INTEL_TXT
# Use the generic interrupt handling code in kernel/irq/:
config GENERIC_HARDIRQS
- def_bool y
+ bool
+ default y
config GENERIC_HARDIRQS_NO__DO_IRQ
def_bool y
config GENERIC_IRQ_PROBE
- def_bool y
+ bool
+ default y
config GENERIC_PENDING_IRQ
- def_bool y
+ bool
depends on GENERIC_HARDIRQS && SMP
+ default y
config USE_GENERIC_SMP_HELPERS
def_bool y
@@ -226,22 +225,19 @@ config X86_64_SMP
depends on X86_64 && SMP
config X86_HT
- def_bool y
+ bool
depends on SMP
+ default y
config X86_TRAMPOLINE
- def_bool y
+ bool
depends on SMP || (64BIT && ACPI_SLEEP)
+ default y
config X86_32_LAZY_GS
def_bool y
depends on X86_32 && !CC_STACKPROTECTOR
-config ARCH_HWEIGHT_CFLAGS
- string
- default "-fcall-saved-ecx -fcall-saved-edx" if X86_32
- default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64
-
config KTIME_SCALAR
def_bool X86_32
source "init/Kconfig"
@@ -451,7 +447,7 @@ config X86_NUMAQ
firmware with - send email to .
config X86_SUPPORTS_MEMORY_FAILURE
- def_bool y
+ bool
# MCE code calls memory_failure():
depends on X86_MCE
# On 32-bit this adds too big of NODES_SHIFT and we run out of page flags:
@@ -459,6 +455,7 @@ config X86_SUPPORTS_MEMORY_FAILURE
# On 32-bit SPARSEMEM adds too big of SECTIONS_WIDTH:
depends on X86_64 || !SPARSEMEM
select ARCH_SUPPORTS_MEMORY_FAILURE
+ default y
config X86_VISWS
bool "SGI 320/540 (Visual Workstation)"
@@ -573,6 +570,7 @@ config PARAVIRT_SPINLOCKS
config PARAVIRT_CLOCK
bool
+ default n
endif
@@ -751,6 +749,7 @@ config MAXSMP
bool "Configure Maximum number of SMP Processors and NUMA Nodes"
depends on X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL
select CPUMASK_OFFSTACK
+ default n
---help---
Configure maximum number of CPUS and NUMA Nodes for this architecture.
If unsure, say N.
@@ -830,6 +829,7 @@ config X86_VISWS_APIC
config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
bool "Reroute for broken boot IRQs"
+ default n
depends on X86_IO_APIC
---help---
This option enables a workaround that fixes a source of
@@ -876,8 +876,9 @@ config X86_MCE_AMD
the DRAM Error Threshold.
config X86_ANCIENT_MCE
- bool "Support for old Pentium 5 / WinChip machine checks"
+ def_bool n
depends on X86_32 && X86_MCE
+ prompt "Support for old Pentium 5 / WinChip machine checks"
---help---
Include support for machine check handling on old Pentium 5 or WinChip
systems. These typically need to be enabled explicitely on the command
@@ -885,7 +886,8 @@ config X86_ANCIENT_MCE
config X86_MCE_THRESHOLD
depends on X86_MCE_AMD || X86_MCE_INTEL
- def_bool y
+ bool
+ default y
config X86_MCE_INJECT
depends on X86_MCE
@@ -1024,8 +1026,8 @@ config X86_CPUID
choice
prompt "High Memory Support"
+ default HIGHMEM4G if !X86_NUMAQ
default HIGHMEM64G if X86_NUMAQ
- default HIGHMEM4G
depends on X86_32
config NOHIGHMEM
@@ -1283,7 +1285,7 @@ source "mm/Kconfig"
config HIGHPTE
bool "Allocate 3rd-level pagetables from highmem"
- depends on HIGHMEM
+ depends on X86_32 && (HIGHMEM4G || HIGHMEM64G)
---help---
The VM uses one page table entry for each page of physical memory.
For systems with a lot of RAM, this can be wasteful of precious
@@ -1367,7 +1369,8 @@ config MATH_EMULATION
kernel, it won't hurt.
config MTRR
- def_bool y
+ bool
+ default y
prompt "MTRR (Memory Type Range Register) support" if EMBEDDED
---help---
On Intel P6 family processors (Pentium Pro, Pentium II and later)
@@ -1433,7 +1436,8 @@ config MTRR_SANITIZER_SPARE_REG_NR_DEFAULT
mtrr_spare_reg_nr=N on the kernel command line.
config X86_PAT
- def_bool y
+ bool
+ default y
prompt "x86 PAT support" if EMBEDDED
depends on MTRR
---help---
@@ -1601,7 +1605,8 @@ config X86_NEED_RELOCS
depends on X86_32 && RELOCATABLE
config PHYSICAL_ALIGN
- hex "Alignment value to which kernel should be aligned" if X86_32
+ hex
+ prompt "Alignment value to which kernel should be aligned" if X86_32
default "0x1000000"
range 0x2000 0x1000000
---help---
@@ -1648,6 +1653,7 @@ config COMPAT_VDSO
config CMDLINE_BOOL
bool "Built-in kernel command line"
+ default n
---help---
Allow for specifying boot arguments to the kernel at
build time. On some systems (e.g. embedded ones), it is
@@ -1681,6 +1687,7 @@ config CMDLINE
config CMDLINE_OVERRIDE
bool "Built-in command line overrides boot loader arguments"
+ default n
depends on CMDLINE_BOOL
---help---
Set this option to 'Y' to have the kernel ignore the boot loader
@@ -1716,7 +1723,8 @@ source "drivers/acpi/Kconfig"
source "drivers/sfi/Kconfig"
config X86_APM_BOOT
- def_bool y
+ bool
+ default y
depends on APM || APM_MODULE
menuconfig APM
@@ -1945,7 +1953,8 @@ config DMAR_DEFAULT_ON
experimental.
config DMAR_BROKEN_GFX_WA
- bool "Workaround broken graphics drivers (going away soon)"
+ def_bool n
+ prompt "Workaround broken graphics drivers (going away soon)"
depends on DMAR && BROKEN
---help---
Current Graphics drivers tend to use physical address
@@ -2043,6 +2052,7 @@ config SCx200HR_TIMER
config OLPC
bool "One Laptop Per Child support"
select GPIOLIB
+ default n
---help---
Add support for detecting the unique features of the OLPC
XO hardware.
diff --git a/trunk/arch/x86/Kconfig.cpu b/trunk/arch/x86/Kconfig.cpu
index 2ac9069890cd..a19829374e6a 100644
--- a/trunk/arch/x86/Kconfig.cpu
+++ b/trunk/arch/x86/Kconfig.cpu
@@ -338,10 +338,6 @@ config X86_F00F_BUG
def_bool y
depends on M586MMX || M586TSC || M586 || M486 || M386
-config X86_INVD_BUG
- def_bool y
- depends on M486 || M386
-
config X86_WP_WORKS_OK
def_bool y
depends on !M386
@@ -506,3 +502,23 @@ config CPU_SUP_UMC_32
CPU might render the kernel unbootable.
If unsure, say N.
+
+config X86_DS
+ def_bool X86_PTRACE_BTS
+ depends on X86_DEBUGCTLMSR
+ select HAVE_HW_BRANCH_TRACER
+
+config X86_PTRACE_BTS
+ bool "Branch Trace Store"
+ default y
+ depends on X86_DEBUGCTLMSR
+ depends on BROKEN
+ ---help---
+ This adds a ptrace interface to the hardware's branch trace store.
+
+ Debuggers may use it to collect an execution trace of the debugged
+ application in order to answer the question 'how did I get here?'.
+ Debuggers may trace user mode as well as kernel mode.
+
+ Say Y unless there is no application development on this machine
+ and you want to save a small amount of code size.
diff --git a/trunk/arch/x86/Kconfig.debug b/trunk/arch/x86/Kconfig.debug
index 75085080b63e..bc01e3ebfeb2 100644
--- a/trunk/arch/x86/Kconfig.debug
+++ b/trunk/arch/x86/Kconfig.debug
@@ -45,6 +45,7 @@ config EARLY_PRINTK
config EARLY_PRINTK_DBGP
bool "Early printk via EHCI debug port"
+ default n
depends on EARLY_PRINTK && PCI
---help---
Write kernel log output directly into the EHCI debug port.
@@ -75,6 +76,7 @@ config DEBUG_PER_CPU_MAPS
bool "Debug access to per_cpu maps"
depends on DEBUG_KERNEL
depends on SMP
+ default n
---help---
Say Y to verify that the per_cpu map being accessed has
been setup. Adds a fair amount of code to kernel memory
@@ -172,6 +174,15 @@ config IOMMU_LEAK
Add a simple leak tracer to the IOMMU code. This is useful when you
are debugging a buggy device driver that leaks IOMMU mappings.
+config X86_DS_SELFTEST
+ bool "DS selftest"
+ default y
+ depends on DEBUG_KERNEL
+ depends on X86_DS
+ ---help---
+ Perform Debug Store selftests at boot time.
+ If in doubt, say "N".
+
config HAVE_MMIOTRACE_SUPPORT
def_bool y
diff --git a/trunk/arch/x86/Makefile b/trunk/arch/x86/Makefile
index 8aa1b59b9074..0a43dc515e4c 100644
--- a/trunk/arch/x86/Makefile
+++ b/trunk/arch/x86/Makefile
@@ -95,9 +95,8 @@ sp-$(CONFIG_X86_64) := rsp
cfi := $(call as-instr,.cfi_startproc\n.cfi_rel_offset $(sp-y)$(comma)0\n.cfi_endproc,-DCONFIG_AS_CFI=1)
# is .cfi_signal_frame supported too?
cfi-sigframe := $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1)
-cfi-sections := $(call as-instr,.cfi_sections .debug_frame,-DCONFIG_AS_CFI_SECTIONS=1)
-KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections)
-KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections)
+KBUILD_AFLAGS += $(cfi) $(cfi-sigframe)
+KBUILD_CFLAGS += $(cfi) $(cfi-sigframe)
LDFLAGS := -m elf_$(UTS_MACHINE)
diff --git a/trunk/arch/x86/include/asm/alternative-asm.h b/trunk/arch/x86/include/asm/alternative-asm.h
index a63a68be1cce..b97f786a48d5 100644
--- a/trunk/arch/x86/include/asm/alternative-asm.h
+++ b/trunk/arch/x86/include/asm/alternative-asm.h
@@ -6,8 +6,8 @@
.macro LOCK_PREFIX
1: lock
.section .smp_locks,"a"
- .balign 4
- .long 1b - .
+ _ASM_ALIGN
+ _ASM_PTR 1b
.previous
.endm
#else
diff --git a/trunk/arch/x86/include/asm/alternative.h b/trunk/arch/x86/include/asm/alternative.h
index 03b6bb5394a0..b09ec55650b3 100644
--- a/trunk/arch/x86/include/asm/alternative.h
+++ b/trunk/arch/x86/include/asm/alternative.h
@@ -28,20 +28,20 @@
*/
#ifdef CONFIG_SMP
-#define LOCK_PREFIX_HERE \
+#define LOCK_PREFIX \
".section .smp_locks,\"a\"\n" \
- ".balign 4\n" \
- ".long 671f - .\n" /* offset */ \
+ _ASM_ALIGN "\n" \
+ _ASM_PTR "661f\n" /* address */ \
".previous\n" \
- "671:"
-
-#define LOCK_PREFIX LOCK_PREFIX_HERE "\n\tlock; "
+ "661:\n\tlock; "
#else /* ! CONFIG_SMP */
-#define LOCK_PREFIX_HERE ""
#define LOCK_PREFIX ""
#endif
+/* This must be included *after* the definition of LOCK_PREFIX */
+#include
+
struct alt_instr {
u8 *instr; /* original instruction */
u8 *replacement;
@@ -95,12 +95,6 @@ static inline int alternatives_text_reserved(void *start, void *end)
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
".previous"
-/*
- * This must be included *after* the definition of ALTERNATIVE due to
- *
- */
-#include
-
/*
* Alternative instructions for different CPU types or capabilities.
*
diff --git a/trunk/arch/x86/include/asm/amd_iommu_types.h b/trunk/arch/x86/include/asm/amd_iommu_types.h
index 7014e88bc779..86a0ff0aeac7 100644
--- a/trunk/arch/x86/include/asm/amd_iommu_types.h
+++ b/trunk/arch/x86/include/asm/amd_iommu_types.h
@@ -174,40 +174,6 @@
(~((1ULL << (12 + ((lvl) * 9))) - 1)))
#define PM_ALIGNED(lvl, addr) ((PM_MAP_MASK(lvl) & (addr)) == (addr))
-/*
- * Returns the page table level to use for a given page size
- * Pagesize is expected to be a power-of-two
- */
-#define PAGE_SIZE_LEVEL(pagesize) \
- ((__ffs(pagesize) - 12) / 9)
-/*
- * Returns the number of ptes to use for a given page size
- * Pagesize is expected to be a power-of-two
- */
-#define PAGE_SIZE_PTE_COUNT(pagesize) \
- (1ULL << ((__ffs(pagesize) - 12) % 9))
-
-/*
- * Aligns a given io-virtual address to a given page size
- * Pagesize is expected to be a power-of-two
- */
-#define PAGE_SIZE_ALIGN(address, pagesize) \
- ((address) & ~((pagesize) - 1))
-/*
- * Creates an IOMMU PTE for an address an a given pagesize
- * The PTE has no permission bits set
- * Pagesize is expected to be a power-of-two larger than 4096
- */
-#define PAGE_SIZE_PTE(address, pagesize) \
- (((address) | ((pagesize) - 1)) & \
- (~(pagesize >> 1)) & PM_ADDR_MASK)
-
-/*
- * Takes a PTE value with mode=0x07 and returns the page size it maps
- */
-#define PTE_PAGE_SIZE(pte) \
- (1ULL << (1 + ffz(((pte) | 0xfffULL))))
-
#define IOMMU_PTE_P (1ULL << 0)
#define IOMMU_PTE_TV (1ULL << 1)
#define IOMMU_PTE_U (1ULL << 59)
diff --git a/trunk/arch/x86/include/asm/apic.h b/trunk/arch/x86/include/asm/apic.h
index 1fa03e04ae44..b4ac2cdcb64f 100644
--- a/trunk/arch/x86/include/asm/apic.h
+++ b/trunk/arch/x86/include/asm/apic.h
@@ -373,7 +373,6 @@ extern atomic_t init_deasserted;
extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
#endif
-#ifdef CONFIG_X86_LOCAL_APIC
static inline u32 apic_read(u32 reg)
{
return apic->read(reg);
@@ -404,19 +403,10 @@ static inline u32 safe_apic_wait_icr_idle(void)
return apic->safe_wait_icr_idle();
}
-#else /* CONFIG_X86_LOCAL_APIC */
-
-static inline u32 apic_read(u32 reg) { return 0; }
-static inline void apic_write(u32 reg, u32 val) { }
-static inline u64 apic_icr_read(void) { return 0; }
-static inline void apic_icr_write(u32 low, u32 high) { }
-static inline void apic_wait_icr_idle(void) { }
-static inline u32 safe_apic_wait_icr_idle(void) { return 0; }
-
-#endif /* CONFIG_X86_LOCAL_APIC */
static inline void ack_APIC_irq(void)
{
+#ifdef CONFIG_X86_LOCAL_APIC
/*
* ack_APIC_irq() actually gets compiled as a single instruction
* ... yummie.
@@ -424,6 +414,7 @@ static inline void ack_APIC_irq(void)
/* Docs say use 0 for future compatibility */
apic_write(APIC_EOI, 0);
+#endif
}
static inline unsigned default_get_apic_id(unsigned long x)
diff --git a/trunk/arch/x86/include/asm/arch_hweight.h b/trunk/arch/x86/include/asm/arch_hweight.h
deleted file mode 100644
index 9686c3d9ff73..000000000000
--- a/trunk/arch/x86/include/asm/arch_hweight.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef _ASM_X86_HWEIGHT_H
-#define _ASM_X86_HWEIGHT_H
-
-#ifdef CONFIG_64BIT
-/* popcnt %edi, %eax -- redundant REX prefix for alignment */
-#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7"
-/* popcnt %rdi, %rax */
-#define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7"
-#define REG_IN "D"
-#define REG_OUT "a"
-#else
-/* popcnt %eax, %eax */
-#define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc0"
-#define REG_IN "a"
-#define REG_OUT "a"
-#endif
-
-/*
- * __sw_hweightXX are called from within the alternatives below
- * and callee-clobbered registers need to be taken care of. See
- * ARCH_HWEIGHT_CFLAGS in for the respective
- * compiler switches.
- */
-static inline unsigned int __arch_hweight32(unsigned int w)
-{
- unsigned int res = 0;
-
- asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT)
- : "="REG_OUT (res)
- : REG_IN (w));
-
- return res;
-}
-
-static inline unsigned int __arch_hweight16(unsigned int w)
-{
- return __arch_hweight32(w & 0xffff);
-}
-
-static inline unsigned int __arch_hweight8(unsigned int w)
-{
- return __arch_hweight32(w & 0xff);
-}
-
-static inline unsigned long __arch_hweight64(__u64 w)
-{
- unsigned long res = 0;
-
-#ifdef CONFIG_X86_32
- return __arch_hweight32((u32)w) +
- __arch_hweight32((u32)(w >> 32));
-#else
- asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)
- : "="REG_OUT (res)
- : REG_IN (w));
-#endif /* CONFIG_X86_32 */
-
- return res;
-}
-
-#endif
diff --git a/trunk/arch/x86/include/asm/atomic.h b/trunk/arch/x86/include/asm/atomic.h
index 952a826ac4e5..8f8217b9bdac 100644
--- a/trunk/arch/x86/include/asm/atomic.h
+++ b/trunk/arch/x86/include/asm/atomic.h
@@ -22,7 +22,7 @@
*/
static inline int atomic_read(const atomic_t *v)
{
- return (*(volatile int *)&(v)->counter);
+ return v->counter;
}
/**
@@ -246,29 +246,6 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
-/*
- * atomic_dec_if_positive - decrement by 1 if old value positive
- * @v: pointer of type atomic_t
- *
- * The function returns the old value of *v minus 1, even if
- * the atomic variable, v, was not decremented.
- */
-static inline int atomic_dec_if_positive(atomic_t *v)
-{
- int c, old, dec;
- c = atomic_read(v);
- for (;;) {
- dec = c - 1;
- if (unlikely(dec < 0))
- break;
- old = atomic_cmpxchg((v), c, dec);
- if (likely(old == c))
- break;
- c = old;
- }
- return dec;
-}
-
/**
* atomic_inc_short - increment of a short integer
* @v: pointer to type int
diff --git a/trunk/arch/x86/include/asm/atomic64_32.h b/trunk/arch/x86/include/asm/atomic64_32.h
index 2a934aa19a43..03027bf28de5 100644
--- a/trunk/arch/x86/include/asm/atomic64_32.h
+++ b/trunk/arch/x86/include/asm/atomic64_32.h
@@ -14,193 +14,109 @@ typedef struct {
#define ATOMIC64_INIT(val) { (val) }
-#ifdef CONFIG_X86_CMPXCHG64
-#define ATOMIC64_ALTERNATIVE_(f, g) "call atomic64_" #g "_cx8"
-#else
-#define ATOMIC64_ALTERNATIVE_(f, g) ALTERNATIVE("call atomic64_" #f "_386", "call atomic64_" #g "_cx8", X86_FEATURE_CX8)
-#endif
-
-#define ATOMIC64_ALTERNATIVE(f) ATOMIC64_ALTERNATIVE_(f, f)
-
-/**
- * atomic64_cmpxchg - cmpxchg atomic64 variable
- * @p: pointer to type atomic64_t
- * @o: expected value
- * @n: new value
- *
- * Atomically sets @v to @n if it was equal to @o and returns
- * the old value.
- */
-
-static inline long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n)
-{
- return cmpxchg64(&v->counter, o, n);
-}
+extern u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val);
/**
* atomic64_xchg - xchg atomic64 variable
- * @v: pointer to type atomic64_t
- * @n: value to assign
+ * @ptr: pointer to type atomic64_t
+ * @new_val: value to assign
*
- * Atomically xchgs the value of @v to @n and returns
+ * Atomically xchgs the value of @ptr to @new_val and returns
* the old value.
*/
-static inline long long atomic64_xchg(atomic64_t *v, long long n)
-{
- long long o;
- unsigned high = (unsigned)(n >> 32);
- unsigned low = (unsigned)n;
- asm volatile(ATOMIC64_ALTERNATIVE(xchg)
- : "=A" (o), "+b" (low), "+c" (high)
- : "S" (v)
- : "memory"
- );
- return o;
-}
+extern u64 atomic64_xchg(atomic64_t *ptr, u64 new_val);
/**
* atomic64_set - set atomic64 variable
- * @v: pointer to type atomic64_t
- * @n: value to assign
+ * @ptr: pointer to type atomic64_t
+ * @new_val: value to assign
*
- * Atomically sets the value of @v to @n.
+ * Atomically sets the value of @ptr to @new_val.
*/
-static inline void atomic64_set(atomic64_t *v, long long i)
-{
- unsigned high = (unsigned)(i >> 32);
- unsigned low = (unsigned)i;
- asm volatile(ATOMIC64_ALTERNATIVE(set)
- : "+b" (low), "+c" (high)
- : "S" (v)
- : "eax", "edx", "memory"
- );
-}
+extern void atomic64_set(atomic64_t *ptr, u64 new_val);
/**
* atomic64_read - read atomic64 variable
- * @v: pointer to type atomic64_t
+ * @ptr: pointer to type atomic64_t
*
- * Atomically reads the value of @v and returns it.
+ * Atomically reads the value of @ptr and returns it.
*/
-static inline long long atomic64_read(atomic64_t *v)
+static inline u64 atomic64_read(atomic64_t *ptr)
{
- long long r;
- asm volatile(ATOMIC64_ALTERNATIVE(read)
- : "=A" (r), "+c" (v)
- : : "memory"
- );
- return r;
- }
+ u64 res;
+
+ /*
+ * Note, we inline this atomic64_t primitive because
+ * it only clobbers EAX/EDX and leaves the others
+ * untouched. We also (somewhat subtly) rely on the
+ * fact that cmpxchg8b returns the current 64-bit value
+ * of the memory location we are touching:
+ */
+ asm volatile(
+ "mov %%ebx, %%eax\n\t"
+ "mov %%ecx, %%edx\n\t"
+ LOCK_PREFIX "cmpxchg8b %1\n"
+ : "=&A" (res)
+ : "m" (*ptr)
+ );
+
+ return res;
+}
+
+extern u64 atomic64_read(atomic64_t *ptr);
/**
* atomic64_add_return - add and return
- * @i: integer value to add
- * @v: pointer to type atomic64_t
+ * @delta: integer value to add
+ * @ptr: pointer to type atomic64_t
*
- * Atomically adds @i to @v and returns @i + *@v
+ * Atomically adds @delta to @ptr and returns @delta + *@ptr
*/
-static inline long long atomic64_add_return(long long i, atomic64_t *v)
-{
- asm volatile(ATOMIC64_ALTERNATIVE(add_return)
- : "+A" (i), "+c" (v)
- : : "memory"
- );
- return i;
-}
+extern u64 atomic64_add_return(u64 delta, atomic64_t *ptr);
/*
* Other variants with different arithmetic operators:
*/
-static inline long long atomic64_sub_return(long long i, atomic64_t *v)
-{
- asm volatile(ATOMIC64_ALTERNATIVE(sub_return)
- : "+A" (i), "+c" (v)
- : : "memory"
- );
- return i;
-}
-
-static inline long long atomic64_inc_return(atomic64_t *v)
-{
- long long a;
- asm volatile(ATOMIC64_ALTERNATIVE(inc_return)
- : "=A" (a)
- : "S" (v)
- : "memory", "ecx"
- );
- return a;
-}
-
-static inline long long atomic64_dec_return(atomic64_t *v)
-{
- long long a;
- asm volatile(ATOMIC64_ALTERNATIVE(dec_return)
- : "=A" (a)
- : "S" (v)
- : "memory", "ecx"
- );
- return a;
-}
+extern u64 atomic64_sub_return(u64 delta, atomic64_t *ptr);
+extern u64 atomic64_inc_return(atomic64_t *ptr);
+extern u64 atomic64_dec_return(atomic64_t *ptr);
/**
* atomic64_add - add integer to atomic64 variable
- * @i: integer value to add
- * @v: pointer to type atomic64_t
+ * @delta: integer value to add
+ * @ptr: pointer to type atomic64_t
*
- * Atomically adds @i to @v.
+ * Atomically adds @delta to @ptr.
*/
-static inline long long atomic64_add(long long i, atomic64_t *v)
-{
- asm volatile(ATOMIC64_ALTERNATIVE_(add, add_return)
- : "+A" (i), "+c" (v)
- : : "memory"
- );
- return i;
-}
+extern void atomic64_add(u64 delta, atomic64_t *ptr);
/**
* atomic64_sub - subtract the atomic64 variable
- * @i: integer value to subtract
- * @v: pointer to type atomic64_t
+ * @delta: integer value to subtract
+ * @ptr: pointer to type atomic64_t
*
- * Atomically subtracts @i from @v.
+ * Atomically subtracts @delta from @ptr.
*/
-static inline long long atomic64_sub(long long i, atomic64_t *v)
-{
- asm volatile(ATOMIC64_ALTERNATIVE_(sub, sub_return)
- : "+A" (i), "+c" (v)
- : : "memory"
- );
- return i;
-}
+extern void atomic64_sub(u64 delta, atomic64_t *ptr);
/**
* atomic64_sub_and_test - subtract value from variable and test result
- * @i: integer value to subtract
- * @v: pointer to type atomic64_t
- *
- * Atomically subtracts @i from @v and returns
+ * @delta: integer value to subtract
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically subtracts @delta from @ptr and returns
* true if the result is zero, or false for all
* other cases.
*/
-static inline int atomic64_sub_and_test(long long i, atomic64_t *v)
-{
- return atomic64_sub_return(i, v) == 0;
-}
+extern int atomic64_sub_and_test(u64 delta, atomic64_t *ptr);
/**
* atomic64_inc - increment atomic64 variable
- * @v: pointer to type atomic64_t
+ * @ptr: pointer to type atomic64_t
*
- * Atomically increments @v by 1.
+ * Atomically increments @ptr by 1.
*/
-static inline void atomic64_inc(atomic64_t *v)
-{
- asm volatile(ATOMIC64_ALTERNATIVE_(inc, inc_return)
- : : "S" (v)
- : "memory", "eax", "ecx", "edx"
- );
-}
+extern void atomic64_inc(atomic64_t *ptr);
/**
* atomic64_dec - decrement atomic64 variable
@@ -208,97 +124,37 @@ static inline void atomic64_inc(atomic64_t *v)
*
* Atomically decrements @ptr by 1.
*/
-static inline void atomic64_dec(atomic64_t *v)
-{
- asm volatile(ATOMIC64_ALTERNATIVE_(dec, dec_return)
- : : "S" (v)
- : "memory", "eax", "ecx", "edx"
- );
-}
+extern void atomic64_dec(atomic64_t *ptr);
/**
* atomic64_dec_and_test - decrement and test
- * @v: pointer to type atomic64_t
+ * @ptr: pointer to type atomic64_t
*
- * Atomically decrements @v by 1 and
+ * Atomically decrements @ptr by 1 and
* returns true if the result is 0, or false for all other
* cases.
*/
-static inline int atomic64_dec_and_test(atomic64_t *v)
-{
- return atomic64_dec_return(v) == 0;
-}
+extern int atomic64_dec_and_test(atomic64_t *ptr);
/**
* atomic64_inc_and_test - increment and test
- * @v: pointer to type atomic64_t
+ * @ptr: pointer to type atomic64_t
*
- * Atomically increments @v by 1
+ * Atomically increments @ptr by 1
* and returns true if the result is zero, or false for all
* other cases.
*/
-static inline int atomic64_inc_and_test(atomic64_t *v)
-{
- return atomic64_inc_return(v) == 0;
-}
+extern int atomic64_inc_and_test(atomic64_t *ptr);
/**
* atomic64_add_negative - add and test if negative
- * @i: integer value to add
- * @v: pointer to type atomic64_t
+ * @delta: integer value to add
+ * @ptr: pointer to type atomic64_t
*
- * Atomically adds @i to @v and returns true
+ * Atomically adds @delta to @ptr and returns true
* if the result is negative, or false when
* result is greater than or equal to zero.
*/
-static inline int atomic64_add_negative(long long i, atomic64_t *v)
-{
- return atomic64_add_return(i, v) < 0;
-}
-
-/**
- * atomic64_add_unless - add unless the number is a given value
- * @v: pointer of type atomic64_t
- * @a: the amount to add to v...
- * @u: ...unless v is equal to u.
- *
- * Atomically adds @a to @v, so long as it was not @u.
- * Returns non-zero if @v was not @u, and zero otherwise.
- */
-static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
-{
- unsigned low = (unsigned)u;
- unsigned high = (unsigned)(u >> 32);
- asm volatile(ATOMIC64_ALTERNATIVE(add_unless) "\n\t"
- : "+A" (a), "+c" (v), "+S" (low), "+D" (high)
- : : "memory");
- return (int)a;
-}
-
-
-static inline int atomic64_inc_not_zero(atomic64_t *v)
-{
- int r;
- asm volatile(ATOMIC64_ALTERNATIVE(inc_not_zero)
- : "=a" (r)
- : "S" (v)
- : "ecx", "edx", "memory"
- );
- return r;
-}
-
-static inline long long atomic64_dec_if_positive(atomic64_t *v)
-{
- long long r;
- asm volatile(ATOMIC64_ALTERNATIVE(dec_if_positive)
- : "=A" (r)
- : "S" (v)
- : "ecx", "memory"
- );
- return r;
-}
-
-#undef ATOMIC64_ALTERNATIVE
-#undef ATOMIC64_ALTERNATIVE_
+extern int atomic64_add_negative(u64 delta, atomic64_t *ptr);
#endif /* _ASM_X86_ATOMIC64_32_H */
diff --git a/trunk/arch/x86/include/asm/atomic64_64.h b/trunk/arch/x86/include/asm/atomic64_64.h
index 49fd1ea22951..51c5b4056929 100644
--- a/trunk/arch/x86/include/asm/atomic64_64.h
+++ b/trunk/arch/x86/include/asm/atomic64_64.h
@@ -18,7 +18,7 @@
*/
static inline long atomic64_read(const atomic64_t *v)
{
- return (*(volatile long *)&(v)->counter);
+ return v->counter;
}
/**
@@ -221,27 +221,4 @@ static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
-/*
- * atomic64_dec_if_positive - decrement by 1 if old value positive
- * @v: pointer of type atomic_t
- *
- * The function returns the old value of *v minus 1, even if
- * the atomic variable, v, was not decremented.
- */
-static inline long atomic64_dec_if_positive(atomic64_t *v)
-{
- long c, old, dec;
- c = atomic64_read(v);
- for (;;) {
- dec = c - 1;
- if (unlikely(dec < 0))
- break;
- old = atomic64_cmpxchg((v), c, dec);
- if (likely(old == c))
- break;
- c = old;
- }
- return dec;
-}
-
#endif /* _ASM_X86_ATOMIC64_64_H */
diff --git a/trunk/arch/x86/include/asm/bitops.h b/trunk/arch/x86/include/asm/bitops.h
index 545776efeb16..02b47a603fc8 100644
--- a/trunk/arch/x86/include/asm/bitops.h
+++ b/trunk/arch/x86/include/asm/bitops.h
@@ -444,9 +444,7 @@ static inline int fls(int x)
#define ARCH_HAS_FAST_MULTIPLIER 1
-#include
-
-#include
+#include
#endif /* __KERNEL__ */
diff --git a/trunk/arch/x86/include/asm/boot.h b/trunk/arch/x86/include/asm/boot.h
index 3b62ab56c7a0..7a1065958ba9 100644
--- a/trunk/arch/x86/include/asm/boot.h
+++ b/trunk/arch/x86/include/asm/boot.h
@@ -24,7 +24,7 @@
#define MIN_KERNEL_ALIGN (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2)
#if (CONFIG_PHYSICAL_ALIGN & (CONFIG_PHYSICAL_ALIGN-1)) || \
- (CONFIG_PHYSICAL_ALIGN < MIN_KERNEL_ALIGN)
+ (CONFIG_PHYSICAL_ALIGN < (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2))
#error "Invalid value for CONFIG_PHYSICAL_ALIGN"
#endif
diff --git a/trunk/arch/x86/include/asm/cacheflush.h b/trunk/arch/x86/include/asm/cacheflush.h
index c70068d05f70..634c40a739a6 100644
--- a/trunk/arch/x86/include/asm/cacheflush.h
+++ b/trunk/arch/x86/include/asm/cacheflush.h
@@ -44,6 +44,9 @@ static inline void copy_from_user_page(struct vm_area_struct *vma,
memcpy(dst, src, len);
}
+#define PG_WC PG_arch_1
+PAGEFLAG(WC, WC)
+
#ifdef CONFIG_X86_PAT
/*
* X86 PAT uses page flags WC and Uncached together to keep track of
@@ -52,24 +55,16 @@ static inline void copy_from_user_page(struct vm_area_struct *vma,
* _PAGE_CACHE_UC_MINUS and fourth state where page's memory type has not
* been changed from its default (value of -1 used to denote this).
* Note we do not support _PAGE_CACHE_UC here.
+ *
+ * Caller must hold memtype_lock for atomicity.
*/
-
-#define _PGMT_DEFAULT 0
-#define _PGMT_WC (1UL << PG_arch_1)
-#define _PGMT_UC_MINUS (1UL << PG_uncached)
-#define _PGMT_WB (1UL << PG_uncached | 1UL << PG_arch_1)
-#define _PGMT_MASK (1UL << PG_uncached | 1UL << PG_arch_1)
-#define _PGMT_CLEAR_MASK (~_PGMT_MASK)
-
static inline unsigned long get_page_memtype(struct page *pg)
{
- unsigned long pg_flags = pg->flags & _PGMT_MASK;
-
- if (pg_flags == _PGMT_DEFAULT)
+ if (!PageUncached(pg) && !PageWC(pg))
return -1;
- else if (pg_flags == _PGMT_WC)
+ else if (!PageUncached(pg) && PageWC(pg))
return _PAGE_CACHE_WC;
- else if (pg_flags == _PGMT_UC_MINUS)
+ else if (PageUncached(pg) && !PageWC(pg))
return _PAGE_CACHE_UC_MINUS;
else
return _PAGE_CACHE_WB;
@@ -77,26 +72,25 @@ static inline unsigned long get_page_memtype(struct page *pg)
static inline void set_page_memtype(struct page *pg, unsigned long memtype)
{
- unsigned long memtype_flags = _PGMT_DEFAULT;
- unsigned long old_flags;
- unsigned long new_flags;
-
switch (memtype) {
case _PAGE_CACHE_WC:
- memtype_flags = _PGMT_WC;
+ ClearPageUncached(pg);
+ SetPageWC(pg);
break;
case _PAGE_CACHE_UC_MINUS:
- memtype_flags = _PGMT_UC_MINUS;
+ SetPageUncached(pg);
+ ClearPageWC(pg);
break;
case _PAGE_CACHE_WB:
- memtype_flags = _PGMT_WB;
+ SetPageUncached(pg);
+ SetPageWC(pg);
+ break;
+ default:
+ case -1:
+ ClearPageUncached(pg);
+ ClearPageWC(pg);
break;
}
-
- do {
- old_flags = pg->flags;
- new_flags = (old_flags & _PGMT_CLEAR_MASK) | memtype_flags;
- } while (cmpxchg(&pg->flags, old_flags, new_flags) != old_flags);
}
#else
static inline unsigned long get_page_memtype(struct page *pg) { return -1; }
diff --git a/trunk/arch/x86/include/asm/cmpxchg_32.h b/trunk/arch/x86/include/asm/cmpxchg_32.h
index 8859e12dd3cf..ffb9bb6b6c37 100644
--- a/trunk/arch/x86/include/asm/cmpxchg_32.h
+++ b/trunk/arch/x86/include/asm/cmpxchg_32.h
@@ -271,8 +271,7 @@ extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
__typeof__(*(ptr)) __ret; \
__typeof__(*(ptr)) __old = (o); \
__typeof__(*(ptr)) __new = (n); \
- alternative_io(LOCK_PREFIX_HERE \
- "call cmpxchg8b_emu", \
+ alternative_io("call cmpxchg8b_emu", \
"lock; cmpxchg8b (%%esi)" , \
X86_FEATURE_CX8, \
"=A" (__ret), \
diff --git a/trunk/arch/x86/include/asm/cpufeature.h b/trunk/arch/x86/include/asm/cpufeature.h
index dca9c545f44e..0cd82d068613 100644
--- a/trunk/arch/x86/include/asm/cpufeature.h
+++ b/trunk/arch/x86/include/asm/cpufeature.h
@@ -161,7 +161,6 @@
*/
#define X86_FEATURE_IDA (7*32+ 0) /* Intel Dynamic Acceleration */
#define X86_FEATURE_ARAT (7*32+ 1) /* Always Running APIC Timer */
-#define X86_FEATURE_CPB (7*32+ 2) /* AMD Core Performance Boost */
/* Virtualization flags: Linux defined */
#define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */
@@ -176,7 +175,6 @@
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
-#include
#include
extern const char * const x86_cap_flags[NCAPINTS*32];
@@ -285,62 +283,6 @@ extern const char * const x86_power_flags[32];
#endif /* CONFIG_X86_64 */
-/*
- * Static testing of CPU features. Used the same as boot_cpu_has().
- * These are only valid after alternatives have run, but will statically
- * patch the target code for additional performance.
- *
- */
-static __always_inline __pure bool __static_cpu_has(u8 bit)
-{
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
- asm goto("1: jmp %l[t_no]\n"
- "2:\n"
- ".section .altinstructions,\"a\"\n"
- _ASM_ALIGN "\n"
- _ASM_PTR "1b\n"
- _ASM_PTR "0\n" /* no replacement */
- " .byte %P0\n" /* feature bit */
- " .byte 2b - 1b\n" /* source len */
- " .byte 0\n" /* replacement len */
- " .byte 0xff + 0 - (2b-1b)\n" /* padding */
- ".previous\n"
- : : "i" (bit) : : t_no);
- return true;
- t_no:
- return false;
-#else
- u8 flag;
- /* Open-coded due to __stringify() in ALTERNATIVE() */
- asm volatile("1: movb $0,%0\n"
- "2:\n"
- ".section .altinstructions,\"a\"\n"
- _ASM_ALIGN "\n"
- _ASM_PTR "1b\n"
- _ASM_PTR "3f\n"
- " .byte %P1\n" /* feature bit */
- " .byte 2b - 1b\n" /* source len */
- " .byte 4f - 3f\n" /* replacement len */
- " .byte 0xff + (4f-3f) - (2b-1b)\n" /* padding */
- ".previous\n"
- ".section .altinstr_replacement,\"ax\"\n"
- "3: movb $1,%0\n"
- "4:\n"
- ".previous\n"
- : "=qm" (flag) : "i" (bit));
- return flag;
-#endif
-}
-
-#define static_cpu_has(bit) \
-( \
- __builtin_constant_p(boot_cpu_has(bit)) ? \
- boot_cpu_has(bit) : \
- (__builtin_constant_p(bit) && !((bit) & ~0xff)) ? \
- __static_cpu_has(bit) : \
- boot_cpu_has(bit) \
-)
-
#endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */
#endif /* _ASM_X86_CPUFEATURE_H */
diff --git a/trunk/arch/x86/include/asm/ds.h b/trunk/arch/x86/include/asm/ds.h
new file mode 100644
index 000000000000..70dac199b093
--- /dev/null
+++ b/trunk/arch/x86/include/asm/ds.h
@@ -0,0 +1,302 @@
+/*
+ * Debug Store (DS) support
+ *
+ * This provides a low-level interface to the hardware's Debug Store
+ * feature that is used for branch trace store (BTS) and
+ * precise-event based sampling (PEBS).
+ *
+ * It manages:
+ * - DS and BTS hardware configuration
+ * - buffer overflow handling (to be done)
+ * - buffer access
+ *
+ * It does not do:
+ * - security checking (is the caller allowed to trace the task)
+ * - buffer allocation (memory accounting)
+ *
+ *
+ * Copyright (C) 2007-2009 Intel Corporation.
+ * Markus Metzger , 2007-2009
+ */
+
+#ifndef _ASM_X86_DS_H
+#define _ASM_X86_DS_H
+
+
+#include
+#include
+#include
+
+
+#ifdef CONFIG_X86_DS
+
+struct task_struct;
+struct ds_context;
+struct ds_tracer;
+struct bts_tracer;
+struct pebs_tracer;
+
+typedef void (*bts_ovfl_callback_t)(struct bts_tracer *);
+typedef void (*pebs_ovfl_callback_t)(struct pebs_tracer *);
+
+
+/*
+ * A list of features plus corresponding macros to talk about them in
+ * the ds_request function's flags parameter.
+ *
+ * We use the enum to index an array of corresponding control bits;
+ * we use the macro to index a flags bit-vector.
+ */
+enum ds_feature {
+ dsf_bts = 0,
+ dsf_bts_kernel,
+#define BTS_KERNEL (1 << dsf_bts_kernel)
+ /* trace kernel-mode branches */
+
+ dsf_bts_user,
+#define BTS_USER (1 << dsf_bts_user)
+ /* trace user-mode branches */
+
+ dsf_bts_overflow,
+ dsf_bts_max,
+ dsf_pebs = dsf_bts_max,
+
+ dsf_pebs_max,
+ dsf_ctl_max = dsf_pebs_max,
+ dsf_bts_timestamps = dsf_ctl_max,
+#define BTS_TIMESTAMPS (1 << dsf_bts_timestamps)
+ /* add timestamps into BTS trace */
+
+#define BTS_USER_FLAGS (BTS_KERNEL | BTS_USER | BTS_TIMESTAMPS)
+};
+
+
+/*
+ * Request BTS or PEBS
+ *
+ * Due to alignement constraints, the actual buffer may be slightly
+ * smaller than the requested or provided buffer.
+ *
+ * Returns a pointer to a tracer structure on success, or
+ * ERR_PTR(errcode) on failure.
+ *
+ * The interrupt threshold is independent from the overflow callback
+ * to allow users to use their own overflow interrupt handling mechanism.
+ *
+ * The function might sleep.
+ *
+ * task: the task to request recording for
+ * cpu: the cpu to request recording for
+ * base: the base pointer for the (non-pageable) buffer;
+ * size: the size of the provided buffer in bytes
+ * ovfl: pointer to a function to be called on buffer overflow;
+ * NULL if cyclic buffer requested
+ * th: the interrupt threshold in records from the end of the buffer;
+ * -1 if no interrupt threshold is requested.
+ * flags: a bit-mask of the above flags
+ */
+extern struct bts_tracer *ds_request_bts_task(struct task_struct *task,
+ void *base, size_t size,
+ bts_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags);
+extern struct bts_tracer *ds_request_bts_cpu(int cpu, void *base, size_t size,
+ bts_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags);
+extern struct pebs_tracer *ds_request_pebs_task(struct task_struct *task,
+ void *base, size_t size,
+ pebs_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags);
+extern struct pebs_tracer *ds_request_pebs_cpu(int cpu,
+ void *base, size_t size,
+ pebs_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags);
+
+/*
+ * Release BTS or PEBS resources
+ * Suspend and resume BTS or PEBS tracing
+ *
+ * Must be called with irq's enabled.
+ *
+ * tracer: the tracer handle returned from ds_request_~()
+ */
+extern void ds_release_bts(struct bts_tracer *tracer);
+extern void ds_suspend_bts(struct bts_tracer *tracer);
+extern void ds_resume_bts(struct bts_tracer *tracer);
+extern void ds_release_pebs(struct pebs_tracer *tracer);
+extern void ds_suspend_pebs(struct pebs_tracer *tracer);
+extern void ds_resume_pebs(struct pebs_tracer *tracer);
+
+/*
+ * Release BTS or PEBS resources
+ * Suspend and resume BTS or PEBS tracing
+ *
+ * Cpu tracers must call this on the traced cpu.
+ * Task tracers must call ds_release_~_noirq() for themselves.
+ *
+ * May be called with irq's disabled.
+ *
+ * Returns 0 if successful;
+ * -EPERM if the cpu tracer does not trace the current cpu.
+ * -EPERM if the task tracer does not trace itself.
+ *
+ * tracer: the tracer handle returned from ds_request_~()
+ */
+extern int ds_release_bts_noirq(struct bts_tracer *tracer);
+extern int ds_suspend_bts_noirq(struct bts_tracer *tracer);
+extern int ds_resume_bts_noirq(struct bts_tracer *tracer);
+extern int ds_release_pebs_noirq(struct pebs_tracer *tracer);
+extern int ds_suspend_pebs_noirq(struct pebs_tracer *tracer);
+extern int ds_resume_pebs_noirq(struct pebs_tracer *tracer);
+
+
+/*
+ * The raw DS buffer state as it is used for BTS and PEBS recording.
+ *
+ * This is the low-level, arch-dependent interface for working
+ * directly on the raw trace data.
+ */
+struct ds_trace {
+ /* the number of bts/pebs records */
+ size_t n;
+ /* the size of a bts/pebs record in bytes */
+ size_t size;
+ /* pointers into the raw buffer:
+ - to the first entry */
+ void *begin;
+ /* - one beyond the last entry */
+ void *end;
+ /* - one beyond the newest entry */
+ void *top;
+ /* - the interrupt threshold */
+ void *ith;
+ /* flags given on ds_request() */
+ unsigned int flags;
+};
+
+/*
+ * An arch-independent view on branch trace data.
+ */
+enum bts_qualifier {
+ bts_invalid,
+#define BTS_INVALID bts_invalid
+
+ bts_branch,
+#define BTS_BRANCH bts_branch
+
+ bts_task_arrives,
+#define BTS_TASK_ARRIVES bts_task_arrives
+
+ bts_task_departs,
+#define BTS_TASK_DEPARTS bts_task_departs
+
+ bts_qual_bit_size = 4,
+ bts_qual_max = (1 << bts_qual_bit_size),
+};
+
+struct bts_struct {
+ __u64 qualifier;
+ union {
+ /* BTS_BRANCH */
+ struct {
+ __u64 from;
+ __u64 to;
+ } lbr;
+ /* BTS_TASK_ARRIVES or BTS_TASK_DEPARTS */
+ struct {
+ __u64 clock;
+ pid_t pid;
+ } event;
+ } variant;
+};
+
+
+/*
+ * The BTS state.
+ *
+ * This gives access to the raw DS state and adds functions to provide
+ * an arch-independent view of the BTS data.
+ */
+struct bts_trace {
+ struct ds_trace ds;
+
+ int (*read)(struct bts_tracer *tracer, const void *at,
+ struct bts_struct *out);
+ int (*write)(struct bts_tracer *tracer, const struct bts_struct *in);
+};
+
+
+/*
+ * The PEBS state.
+ *
+ * This gives access to the raw DS state and the PEBS-specific counter
+ * reset value.
+ */
+struct pebs_trace {
+ struct ds_trace ds;
+
+ /* the number of valid counters in the below array */
+ unsigned int counters;
+
+#define MAX_PEBS_COUNTERS 4
+ /* the counter reset value */
+ unsigned long long counter_reset[MAX_PEBS_COUNTERS];
+};
+
+
+/*
+ * Read the BTS or PEBS trace.
+ *
+ * Returns a view on the trace collected for the parameter tracer.
+ *
+ * The view remains valid as long as the traced task is not running or
+ * the tracer is suspended.
+ * Writes into the trace buffer are not reflected.
+ *
+ * tracer: the tracer handle returned from ds_request_~()
+ */
+extern const struct bts_trace *ds_read_bts(struct bts_tracer *tracer);
+extern const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer);
+
+
+/*
+ * Reset the write pointer of the BTS/PEBS buffer.
+ *
+ * Returns 0 on success; -Eerrno on error
+ *
+ * tracer: the tracer handle returned from ds_request_~()
+ */
+extern int ds_reset_bts(struct bts_tracer *tracer);
+extern int ds_reset_pebs(struct pebs_tracer *tracer);
+
+/*
+ * Set the PEBS counter reset value.
+ *
+ * Returns 0 on success; -Eerrno on error
+ *
+ * tracer: the tracer handle returned from ds_request_pebs()
+ * counter: the index of the counter
+ * value: the new counter reset value
+ */
+extern int ds_set_pebs_reset(struct pebs_tracer *tracer,
+ unsigned int counter, u64 value);
+
+/*
+ * Initialization
+ */
+struct cpuinfo_x86;
+extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *);
+
+/*
+ * Context switch work
+ */
+extern void ds_switch_to(struct task_struct *prev, struct task_struct *next);
+
+#else /* CONFIG_X86_DS */
+
+struct cpuinfo_x86;
+static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {}
+static inline void ds_switch_to(struct task_struct *prev,
+ struct task_struct *next) {}
+
+#endif /* CONFIG_X86_DS */
+#endif /* _ASM_X86_DS_H */
diff --git a/trunk/arch/x86/include/asm/dwarf2.h b/trunk/arch/x86/include/asm/dwarf2.h
index 733f7e91e7a9..ae6253ab9029 100644
--- a/trunk/arch/x86/include/asm/dwarf2.h
+++ b/trunk/arch/x86/include/asm/dwarf2.h
@@ -34,18 +34,6 @@
#define CFI_SIGNAL_FRAME
#endif
-#if defined(CONFIG_AS_CFI_SECTIONS) && defined(__ASSEMBLY__)
- /*
- * Emit CFI data in .debug_frame sections, not .eh_frame sections.
- * The latter we currently just discard since we don't do DWARF
- * unwinding at runtime. So only the offline DWARF information is
- * useful to anyone. Note we should not use this directive if this
- * file is used in the vDSO assembly, or if vmlinux.lds.S gets
- * changed so it doesn't discard .eh_frame.
- */
- .cfi_sections .debug_frame
-#endif
-
#else
/*
diff --git a/trunk/arch/x86/include/asm/e820.h b/trunk/arch/x86/include/asm/e820.h
index ec8a52d14ab1..0e22296790d3 100644
--- a/trunk/arch/x86/include/asm/e820.h
+++ b/trunk/arch/x86/include/asm/e820.h
@@ -45,12 +45,7 @@
#define E820_NVS 4
#define E820_UNUSABLE 5
-/*
- * reserved RAM used by kernel itself
- * if CONFIG_INTEL_TXT is enabled, memory of this type will be
- * included in the S3 integrity calculation and so should not include
- * any memory that BIOS might alter over the S3 transition
- */
+/* reserved RAM used by kernel itself */
#define E820_RESERVED_KERN 128
#ifndef __ASSEMBLY__
diff --git a/trunk/arch/x86/include/asm/hardirq.h b/trunk/arch/x86/include/asm/hardirq.h
index aeab29aee617..0f8576427cfe 100644
--- a/trunk/arch/x86/include/asm/hardirq.h
+++ b/trunk/arch/x86/include/asm/hardirq.h
@@ -35,7 +35,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
#define __ARCH_IRQ_STAT
-#define inc_irq_stat(member) percpu_inc(irq_stat.member)
+#define inc_irq_stat(member) percpu_add(irq_stat.member, 1)
#define local_softirq_pending() percpu_read(irq_stat.__softirq_pending)
diff --git a/trunk/arch/x86/include/asm/hw_breakpoint.h b/trunk/arch/x86/include/asm/hw_breakpoint.h
index 942255310e6a..2a1bd8f4f23a 100644
--- a/trunk/arch/x86/include/asm/hw_breakpoint.h
+++ b/trunk/arch/x86/include/asm/hw_breakpoint.h
@@ -41,16 +41,12 @@ struct arch_hw_breakpoint {
/* Total number of available HW breakpoint registers */
#define HBP_NUM 4
-static inline int hw_breakpoint_slots(int type)
-{
- return HBP_NUM;
-}
-
struct perf_event;
struct pmu;
-extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
-extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int arch_check_va_in_userspace(unsigned long va, u8 hbp_len);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
+ struct task_struct *tsk);
extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
unsigned long val, void *data);
diff --git a/trunk/arch/x86/include/asm/hyperv.h b/trunk/arch/x86/include/asm/hyperv.h
index 5df477ac3af7..e153a2b3889a 100644
--- a/trunk/arch/x86/include/asm/hyperv.h
+++ b/trunk/arch/x86/include/asm/hyperv.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_HYPERV_H
-#define _ASM_X86_HYPERV_H
+#ifndef _ASM_X86_KVM_HYPERV_H
+#define _ASM_X86_KVM_HYPERV_H
#include
@@ -14,10 +14,6 @@
#define HYPERV_CPUID_ENLIGHTMENT_INFO 0x40000004
#define HYPERV_CPUID_IMPLEMENT_LIMITS 0x40000005
-#define HYPERV_HYPERVISOR_PRESENT_BIT 0x80000000
-#define HYPERV_CPUID_MIN 0x40000005
-#define HYPERV_CPUID_MAX 0x4000ffff
-
/*
* Feature identification. EAX indicates which features are available
* to the partition based upon the current partition privileges.
@@ -133,9 +129,6 @@
/* MSR used to provide vcpu index */
#define HV_X64_MSR_VP_INDEX 0x40000002
-/* MSR used to read the per-partition time reference counter */
-#define HV_X64_MSR_TIME_REF_COUNT 0x40000020
-
/* Define the virtual APIC registers */
#define HV_X64_MSR_EOI 0x40000070
#define HV_X64_MSR_ICR 0x40000071
diff --git a/trunk/arch/x86/include/asm/hypervisor.h b/trunk/arch/x86/include/asm/hypervisor.h
index 70abda7058c8..b78c0941e422 100644
--- a/trunk/arch/x86/include/asm/hypervisor.h
+++ b/trunk/arch/x86/include/asm/hypervisor.h
@@ -17,33 +17,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
-#ifndef _ASM_X86_HYPERVISOR_H
-#define _ASM_X86_HYPERVISOR_H
+#ifndef ASM_X86__HYPERVISOR_H
+#define ASM_X86__HYPERVISOR_H
extern void init_hypervisor(struct cpuinfo_x86 *c);
extern void init_hypervisor_platform(void);
-/*
- * x86 hypervisor information
- */
-struct hypervisor_x86 {
- /* Hypervisor name */
- const char *name;
-
- /* Detection routine */
- bool (*detect)(void);
-
- /* Adjust CPU feature bits (run once per CPU) */
- void (*set_cpu_features)(struct cpuinfo_x86 *);
-
- /* Platform setup (run once per boot) */
- void (*init_platform)(void);
-};
-
-extern const struct hypervisor_x86 *x86_hyper;
-
-/* Recognized hypervisors */
-extern const struct hypervisor_x86 x86_hyper_vmware;
-extern const struct hypervisor_x86 x86_hyper_ms_hyperv;
-
#endif
diff --git a/trunk/arch/x86/include/asm/i387.h b/trunk/arch/x86/include/asm/i387.h
index c991b3a7b904..da2930924501 100644
--- a/trunk/arch/x86/include/asm/i387.h
+++ b/trunk/arch/x86/include/asm/i387.h
@@ -16,9 +16,7 @@
#include
#include
#include
-#include
#include
-#include
#include
#include
#include
@@ -58,11 +56,6 @@ extern int restore_i387_xstate_ia32(void __user *buf);
#define X87_FSW_ES (1 << 7) /* Exception Summary */
-static __always_inline __pure bool use_xsave(void)
-{
- return static_cpu_has(X86_FEATURE_XSAVE);
-}
-
#ifdef CONFIG_X86_64
/* Ignore delayed exceptions from user space */
@@ -98,15 +91,15 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
values. The kernel data segment can be sometimes 0 and sometimes
new user value. Both should be ok.
Use the PDA as safe address because it should be already in L1. */
-static inline void fpu_clear(struct fpu *fpu)
+static inline void clear_fpu_state(struct task_struct *tsk)
{
- struct xsave_struct *xstate = &fpu->state->xsave;
- struct i387_fxsave_struct *fx = &fpu->state->fxsave;
+ struct xsave_struct *xstate = &tsk->thread.xstate->xsave;
+ struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
/*
* xsave header may indicate the init state of the FP.
*/
- if (use_xsave() &&
+ if ((task_thread_info(tsk)->status & TS_XSAVE) &&
!(xstate->xsave_hdr.xstate_bv & XSTATE_FP))
return;
@@ -118,11 +111,6 @@ static inline void fpu_clear(struct fpu *fpu)
X86_FEATURE_FXSAVE_LEAK);
}
-static inline void clear_fpu_state(struct task_struct *tsk)
-{
- fpu_clear(&tsk->thread.fpu);
-}
-
static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
{
int err;
@@ -147,7 +135,7 @@ static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
return err;
}
-static inline void fpu_fxsave(struct fpu *fpu)
+static inline void fxsave(struct task_struct *tsk)
{
/* Using "rex64; fxsave %0" is broken because, if the memory operand
uses any extended registers for addressing, a second REX prefix
@@ -157,45 +145,42 @@ static inline void fpu_fxsave(struct fpu *fpu)
/* Using "fxsaveq %0" would be the ideal choice, but is only supported
starting with gas 2.16. */
__asm__ __volatile__("fxsaveq %0"
- : "=m" (fpu->state->fxsave));
+ : "=m" (tsk->thread.xstate->fxsave));
#elif 0
/* Using, as a workaround, the properly prefixed form below isn't
accepted by any binutils version so far released, complaining that
the same type of prefix is used twice if an extended register is
needed for addressing (fix submitted to mainline 2005-11-21). */
__asm__ __volatile__("rex64/fxsave %0"
- : "=m" (fpu->state->fxsave));
+ : "=m" (tsk->thread.xstate->fxsave));
#else
/* This, however, we can work around by forcing the compiler to select
an addressing mode that doesn't require extended registers. */
__asm__ __volatile__("rex64/fxsave (%1)"
- : "=m" (fpu->state->fxsave)
- : "cdaSDb" (&fpu->state->fxsave));
+ : "=m" (tsk->thread.xstate->fxsave)
+ : "cdaSDb" (&tsk->thread.xstate->fxsave));
#endif
}
-static inline void fpu_save_init(struct fpu *fpu)
+static inline void __save_init_fpu(struct task_struct *tsk)
{
- if (use_xsave())
- fpu_xsave(fpu);
+ if (task_thread_info(tsk)->status & TS_XSAVE)
+ xsave(tsk);
else
- fpu_fxsave(fpu);
-
- fpu_clear(fpu);
-}
+ fxsave(tsk);
-static inline void __save_init_fpu(struct task_struct *tsk)
-{
- fpu_save_init(&tsk->thread.fpu);
+ clear_fpu_state(tsk);
task_thread_info(tsk)->status &= ~TS_USEDFPU;
}
#else /* CONFIG_X86_32 */
#ifdef CONFIG_MATH_EMULATION
-extern void finit_soft_fpu(struct i387_soft_struct *soft);
+extern void finit_task(struct task_struct *tsk);
#else
-static inline void finit_soft_fpu(struct i387_soft_struct *soft) {}
+static inline void finit_task(struct task_struct *tsk)
+{
+}
#endif
static inline void tolerant_fwait(void)
@@ -231,13 +216,13 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
/*
* These must be called with preempt disabled
*/
-static inline void fpu_save_init(struct fpu *fpu)
+static inline void __save_init_fpu(struct task_struct *tsk)
{
- if (use_xsave()) {
- struct xsave_struct *xstate = &fpu->state->xsave;
- struct i387_fxsave_struct *fx = &fpu->state->fxsave;
+ if (task_thread_info(tsk)->status & TS_XSAVE) {
+ struct xsave_struct *xstate = &tsk->thread.xstate->xsave;
+ struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
- fpu_xsave(fpu);
+ xsave(tsk);
/*
* xsave header may indicate the init state of the FP.
@@ -261,8 +246,8 @@ static inline void fpu_save_init(struct fpu *fpu)
"fxsave %[fx]\n"
"bt $7,%[fsw] ; jnc 1f ; fnclex\n1:",
X86_FEATURE_FXSR,
- [fx] "m" (fpu->state->fxsave),
- [fsw] "m" (fpu->state->fxsave.swd) : "memory");
+ [fx] "m" (tsk->thread.xstate->fxsave),
+ [fsw] "m" (tsk->thread.xstate->fxsave.swd) : "memory");
clear_state:
/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
is pending. Clear the x87 state here by setting it to fixed
@@ -274,34 +259,17 @@ static inline void fpu_save_init(struct fpu *fpu)
X86_FEATURE_FXSAVE_LEAK,
[addr] "m" (safe_address));
end:
- ;
-}
-
-static inline void __save_init_fpu(struct task_struct *tsk)
-{
- fpu_save_init(&tsk->thread.fpu);
task_thread_info(tsk)->status &= ~TS_USEDFPU;
}
-
#endif /* CONFIG_X86_64 */
-static inline int fpu_fxrstor_checking(struct fpu *fpu)
-{
- return fxrstor_checking(&fpu->state->fxsave);
-}
-
-static inline int fpu_restore_checking(struct fpu *fpu)
-{
- if (use_xsave())
- return fpu_xrstor_checking(fpu);
- else
- return fpu_fxrstor_checking(fpu);
-}
-
static inline int restore_fpu_checking(struct task_struct *tsk)
{
- return fpu_restore_checking(&tsk->thread.fpu);
+ if (task_thread_info(tsk)->status & TS_XSAVE)
+ return xrstor_checking(&tsk->thread.xstate->xsave);
+ else
+ return fxrstor_checking(&tsk->thread.xstate->fxsave);
}
/*
@@ -429,59 +397,30 @@ static inline void clear_fpu(struct task_struct *tsk)
static inline unsigned short get_fpu_cwd(struct task_struct *tsk)
{
if (cpu_has_fxsr) {
- return tsk->thread.fpu.state->fxsave.cwd;
+ return tsk->thread.xstate->fxsave.cwd;
} else {
- return (unsigned short)tsk->thread.fpu.state->fsave.cwd;
+ return (unsigned short)tsk->thread.xstate->fsave.cwd;
}
}
static inline unsigned short get_fpu_swd(struct task_struct *tsk)
{
if (cpu_has_fxsr) {
- return tsk->thread.fpu.state->fxsave.swd;
+ return tsk->thread.xstate->fxsave.swd;
} else {
- return (unsigned short)tsk->thread.fpu.state->fsave.swd;
+ return (unsigned short)tsk->thread.xstate->fsave.swd;
}
}
static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk)
{
if (cpu_has_xmm) {
- return tsk->thread.fpu.state->fxsave.mxcsr;
+ return tsk->thread.xstate->fxsave.mxcsr;
} else {
return MXCSR_DEFAULT;
}
}
-static bool fpu_allocated(struct fpu *fpu)
-{
- return fpu->state != NULL;
-}
-
-static inline int fpu_alloc(struct fpu *fpu)
-{
- if (fpu_allocated(fpu))
- return 0;
- fpu->state = kmem_cache_alloc(task_xstate_cachep, GFP_KERNEL);
- if (!fpu->state)
- return -ENOMEM;
- WARN_ON((unsigned long)fpu->state & 15);
- return 0;
-}
-
-static inline void fpu_free(struct fpu *fpu)
-{
- if (fpu->state) {
- kmem_cache_free(task_xstate_cachep, fpu->state);
- fpu->state = NULL;
- }
-}
-
-static inline void fpu_copy(struct fpu *dst, struct fpu *src)
-{
- memcpy(dst->state, src->state, xstate_size);
-}
-
#endif /* __ASSEMBLY__ */
#define PSHUFB_XMM5_XMM0 .byte 0x66, 0x0f, 0x38, 0x00, 0xc5
diff --git a/trunk/arch/x86/include/asm/i8253.h b/trunk/arch/x86/include/asm/i8253.h
index fc1f579fb965..1edbf89680fd 100644
--- a/trunk/arch/x86/include/asm/i8253.h
+++ b/trunk/arch/x86/include/asm/i8253.h
@@ -6,7 +6,7 @@
#define PIT_CH0 0x40
#define PIT_CH2 0x42
-extern raw_spinlock_t i8253_lock;
+extern spinlock_t i8253_lock;
extern struct clock_event_device *global_clock_event;
diff --git a/trunk/arch/x86/include/asm/insn.h b/trunk/arch/x86/include/asm/insn.h
index 88c765e16410..96c2e0ad04ca 100644
--- a/trunk/arch/x86/include/asm/insn.h
+++ b/trunk/arch/x86/include/asm/insn.h
@@ -68,8 +68,6 @@ struct insn {
const insn_byte_t *next_byte;
};
-#define MAX_INSN_SIZE 16
-
#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6)
#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3)
#define X86_MODRM_RM(modrm) ((modrm) & 0x07)
diff --git a/trunk/arch/x86/include/asm/io.h b/trunk/arch/x86/include/asm/io.h
index 30a3e9776123..a1dcfa3ab17d 100644
--- a/trunk/arch/x86/include/asm/io.h
+++ b/trunk/arch/x86/include/asm/io.h
@@ -347,7 +347,6 @@ extern void __iomem *early_ioremap(resource_size_t phys_addr,
extern void __iomem *early_memremap(resource_size_t phys_addr,
unsigned long size);
extern void early_iounmap(void __iomem *addr, unsigned long size);
-extern void fixup_early_ioremap(void);
#define IO_SPACE_LIMIT 0xffff
diff --git a/trunk/arch/x86/include/asm/io_apic.h b/trunk/arch/x86/include/asm/io_apic.h
index 63cb4096c3dc..35832a03a515 100644
--- a/trunk/arch/x86/include/asm/io_apic.h
+++ b/trunk/arch/x86/include/asm/io_apic.h
@@ -159,6 +159,7 @@ struct io_apic_irq_attr;
extern int io_apic_set_pci_routing(struct device *dev, int irq,
struct io_apic_irq_attr *irq_attr);
void setup_IO_APIC_irq_extra(u32 gsi);
+extern int (*ioapic_renumber_irq)(int ioapic, int irq);
extern void ioapic_init_mappings(void);
extern void ioapic_insert_resources(void);
@@ -179,13 +180,12 @@ extern void ioapic_write_entry(int apic, int pin,
extern void setup_ioapic_ids_from_mpc(void);
struct mp_ioapic_gsi{
- u32 gsi_base;
- u32 gsi_end;
+ int gsi_base;
+ int gsi_end;
};
extern struct mp_ioapic_gsi mp_gsi_routing[];
-extern u32 gsi_end;
-int mp_find_ioapic(u32 gsi);
-int mp_find_ioapic_pin(int ioapic, u32 gsi);
+int mp_find_ioapic(int gsi);
+int mp_find_ioapic_pin(int ioapic, int gsi);
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
extern void __init pre_init_apic_IRQ0(void);
@@ -197,8 +197,7 @@ static const int timer_through_8259 = 0;
static inline void ioapic_init_mappings(void) { }
static inline void ioapic_insert_resources(void) { }
static inline void probe_nr_irqs_gsi(void) { }
-#define gsi_end (NR_IRQS_LEGACY - 1)
-static inline int mp_find_ioapic(u32 gsi) { return 0; }
+static inline int mp_find_ioapic(int gsi) { return 0; }
struct io_apic_irq_attr;
static inline int io_apic_set_pci_routing(struct device *dev, int irq,
diff --git a/trunk/arch/x86/include/asm/k8.h b/trunk/arch/x86/include/asm/k8.h
index af00bd1d2089..f70e60071fe8 100644
--- a/trunk/arch/x86/include/asm/k8.h
+++ b/trunk/arch/x86/include/asm/k8.h
@@ -16,16 +16,11 @@ extern int k8_numa_init(unsigned long start_pfn, unsigned long end_pfn);
extern int k8_scan_nodes(void);
#ifdef CONFIG_K8_NB
-extern int num_k8_northbridges;
-
static inline struct pci_dev *node_to_k8_nb_misc(int node)
{
return (node < num_k8_northbridges) ? k8_northbridges[node] : NULL;
}
-
#else
-#define num_k8_northbridges 0
-
static inline struct pci_dev *node_to_k8_nb_misc(int node)
{
return NULL;
diff --git a/trunk/arch/x86/include/asm/kprobes.h b/trunk/arch/x86/include/asm/kprobes.h
index 547882539157..4ffa345a8ccb 100644
--- a/trunk/arch/x86/include/asm/kprobes.h
+++ b/trunk/arch/x86/include/asm/kprobes.h
@@ -24,7 +24,6 @@
#include
#include
#include
-#include
#define __ARCH_WANT_KPROBES_INSN_SLOT
@@ -37,6 +36,7 @@ typedef u8 kprobe_opcode_t;
#define RELATIVEJUMP_SIZE 5
#define RELATIVECALL_OPCODE 0xe8
#define RELATIVE_ADDR_SIZE 4
+#define MAX_INSN_SIZE 16
#define MAX_STACK_SIZE 64
#define MIN_STACK_SIZE(ADDR) \
(((MAX_STACK_SIZE) < (((unsigned long)current_thread_info()) + \
diff --git a/trunk/arch/x86/include/asm/mpspec.h b/trunk/arch/x86/include/asm/mpspec.h
index c82868e9f905..d8bf23a88d05 100644
--- a/trunk/arch/x86/include/asm/mpspec.h
+++ b/trunk/arch/x86/include/asm/mpspec.h
@@ -105,6 +105,16 @@ extern void mp_config_acpi_legacy_irqs(void);
struct device;
extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
int active_high_low);
+extern int acpi_probe_gsi(void);
+#ifdef CONFIG_X86_IO_APIC
+extern int mp_find_ioapic(int gsi);
+extern int mp_find_ioapic_pin(int ioapic, int gsi);
+#endif
+#else /* !CONFIG_ACPI: */
+static inline int acpi_probe_gsi(void)
+{
+ return 0;
+}
#endif /* CONFIG_ACPI */
#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
diff --git a/trunk/arch/x86/include/asm/mshyperv.h b/trunk/arch/x86/include/asm/mshyperv.h
deleted file mode 100644
index 79ce5685ab64..000000000000
--- a/trunk/arch/x86/include/asm/mshyperv.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _ASM_X86_MSHYPER_H
-#define _ASM_X86_MSHYPER_H
-
-#include
-#include
-
-struct ms_hyperv_info {
- u32 features;
- u32 hints;
-};
-
-extern struct ms_hyperv_info ms_hyperv;
-
-#endif
diff --git a/trunk/arch/x86/include/asm/msr-index.h b/trunk/arch/x86/include/asm/msr-index.h
index bc473acfa7f9..4604e6a54d36 100644
--- a/trunk/arch/x86/include/asm/msr-index.h
+++ b/trunk/arch/x86/include/asm/msr-index.h
@@ -71,14 +71,11 @@
#define MSR_IA32_LASTINTTOIP 0x000001de
/* DEBUGCTLMSR bits (others vary by model): */
-#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */
-#define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */
-#define DEBUGCTLMSR_TR (1UL << 6)
-#define DEBUGCTLMSR_BTS (1UL << 7)
-#define DEBUGCTLMSR_BTINT (1UL << 8)
-#define DEBUGCTLMSR_BTS_OFF_OS (1UL << 9)
-#define DEBUGCTLMSR_BTS_OFF_USR (1UL << 10)
-#define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11)
+#define _DEBUGCTLMSR_LBR 0 /* last branch recording */
+#define _DEBUGCTLMSR_BTF 1 /* single-step on branches */
+
+#define DEBUGCTLMSR_LBR (1UL << _DEBUGCTLMSR_LBR)
+#define DEBUGCTLMSR_BTF (1UL << _DEBUGCTLMSR_BTF)
#define MSR_IA32_MC0_CTL 0x00000400
#define MSR_IA32_MC0_STATUS 0x00000401
@@ -362,8 +359,6 @@
#define MSR_P4_U2L_ESCR0 0x000003b0
#define MSR_P4_U2L_ESCR1 0x000003b1
-#define MSR_P4_PEBS_MATRIX_VERT 0x000003f2
-
/* Intel Core-based CPU performance counters */
#define MSR_CORE_PERF_FIXED_CTR0 0x00000309
#define MSR_CORE_PERF_FIXED_CTR1 0x0000030a
diff --git a/trunk/arch/x86/include/asm/percpu.h b/trunk/arch/x86/include/asm/percpu.h
index 0ec6d12d84e6..66a272dfd8b8 100644
--- a/trunk/arch/x86/include/asm/percpu.h
+++ b/trunk/arch/x86/include/asm/percpu.h
@@ -190,29 +190,6 @@ do { \
pfo_ret__; \
})
-#define percpu_unary_op(op, var) \
-({ \
- switch (sizeof(var)) { \
- case 1: \
- asm(op "b "__percpu_arg(0) \
- : "+m" (var)); \
- break; \
- case 2: \
- asm(op "w "__percpu_arg(0) \
- : "+m" (var)); \
- break; \
- case 4: \
- asm(op "l "__percpu_arg(0) \
- : "+m" (var)); \
- break; \
- case 8: \
- asm(op "q "__percpu_arg(0) \
- : "+m" (var)); \
- break; \
- default: __bad_percpu_size(); \
- } \
-})
-
/*
* percpu_read() makes gcc load the percpu variable every time it is
* accessed while percpu_read_stable() allows the value to be cached.
@@ -230,7 +207,6 @@ do { \
#define percpu_and(var, val) percpu_to_op("and", var, val)
#define percpu_or(var, val) percpu_to_op("or", var, val)
#define percpu_xor(var, val) percpu_to_op("xor", var, val)
-#define percpu_inc(var) percpu_unary_op("inc", var)
#define __this_cpu_read_1(pcp) percpu_from_op("mov", (pcp), "m"(pcp))
#define __this_cpu_read_2(pcp) percpu_from_op("mov", (pcp), "m"(pcp))
diff --git a/trunk/arch/x86/include/asm/perf_event.h b/trunk/arch/x86/include/asm/perf_event.h
index 254883d0c7e0..db6109a885a7 100644
--- a/trunk/arch/x86/include/asm/perf_event.h
+++ b/trunk/arch/x86/include/asm/perf_event.h
@@ -5,7 +5,7 @@
* Performance event hw details:
*/
-#define X86_PMC_MAX_GENERIC 32
+#define X86_PMC_MAX_GENERIC 8
#define X86_PMC_MAX_FIXED 3
#define X86_PMC_IDX_GENERIC 0
@@ -18,31 +18,39 @@
#define MSR_ARCH_PERFMON_EVENTSEL0 0x186
#define MSR_ARCH_PERFMON_EVENTSEL1 0x187
-#define ARCH_PERFMON_EVENTSEL_EVENT 0x000000FFULL
-#define ARCH_PERFMON_EVENTSEL_UMASK 0x0000FF00ULL
-#define ARCH_PERFMON_EVENTSEL_USR (1ULL << 16)
-#define ARCH_PERFMON_EVENTSEL_OS (1ULL << 17)
-#define ARCH_PERFMON_EVENTSEL_EDGE (1ULL << 18)
-#define ARCH_PERFMON_EVENTSEL_INT (1ULL << 20)
-#define ARCH_PERFMON_EVENTSEL_ANY (1ULL << 21)
-#define ARCH_PERFMON_EVENTSEL_ENABLE (1ULL << 22)
-#define ARCH_PERFMON_EVENTSEL_INV (1ULL << 23)
-#define ARCH_PERFMON_EVENTSEL_CMASK 0xFF000000ULL
-
-#define AMD64_EVENTSEL_EVENT \
- (ARCH_PERFMON_EVENTSEL_EVENT | (0x0FULL << 32))
-#define INTEL_ARCH_EVENT_MASK \
- (ARCH_PERFMON_EVENTSEL_UMASK | ARCH_PERFMON_EVENTSEL_EVENT)
-
-#define X86_RAW_EVENT_MASK \
- (ARCH_PERFMON_EVENTSEL_EVENT | \
- ARCH_PERFMON_EVENTSEL_UMASK | \
- ARCH_PERFMON_EVENTSEL_EDGE | \
- ARCH_PERFMON_EVENTSEL_INV | \
- ARCH_PERFMON_EVENTSEL_CMASK)
-#define AMD64_RAW_EVENT_MASK \
- (X86_RAW_EVENT_MASK | \
- AMD64_EVENTSEL_EVENT)
+#define ARCH_PERFMON_EVENTSEL_ENABLE (1 << 22)
+#define ARCH_PERFMON_EVENTSEL_ANY (1 << 21)
+#define ARCH_PERFMON_EVENTSEL_INT (1 << 20)
+#define ARCH_PERFMON_EVENTSEL_OS (1 << 17)
+#define ARCH_PERFMON_EVENTSEL_USR (1 << 16)
+
+/*
+ * Includes eventsel and unit mask as well:
+ */
+
+
+#define INTEL_ARCH_EVTSEL_MASK 0x000000FFULL
+#define INTEL_ARCH_UNIT_MASK 0x0000FF00ULL
+#define INTEL_ARCH_EDGE_MASK 0x00040000ULL
+#define INTEL_ARCH_INV_MASK 0x00800000ULL
+#define INTEL_ARCH_CNT_MASK 0xFF000000ULL
+#define INTEL_ARCH_EVENT_MASK (INTEL_ARCH_UNIT_MASK|INTEL_ARCH_EVTSEL_MASK)
+
+/*
+ * filter mask to validate fixed counter events.
+ * the following filters disqualify for fixed counters:
+ * - inv
+ * - edge
+ * - cnt-mask
+ * The other filters are supported by fixed counters.
+ * The any-thread option is supported starting with v3.
+ */
+#define INTEL_ARCH_FIXED_MASK \
+ (INTEL_ARCH_CNT_MASK| \
+ INTEL_ARCH_INV_MASK| \
+ INTEL_ARCH_EDGE_MASK|\
+ INTEL_ARCH_UNIT_MASK|\
+ INTEL_ARCH_EVENT_MASK)
#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c
#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8)
@@ -59,7 +67,7 @@
union cpuid10_eax {
struct {
unsigned int version_id:8;
- unsigned int num_counters:8;
+ unsigned int num_events:8;
unsigned int bit_width:8;
unsigned int mask_length:8;
} split;
@@ -68,7 +76,7 @@ union cpuid10_eax {
union cpuid10_edx {
struct {
- unsigned int num_counters_fixed:4;
+ unsigned int num_events_fixed:4;
unsigned int reserved:28;
} split;
unsigned int full;
@@ -128,18 +136,6 @@ extern void perf_events_lapic_init(void);
#define PERF_EVENT_INDEX_OFFSET 0
-/*
- * Abuse bit 3 of the cpu eflags register to indicate proper PEBS IP fixups.
- * This flag is otherwise unused and ABI specified to be 0, so nobody should
- * care what we do with it.
- */
-#define PERF_EFLAGS_EXACT (1UL << 3)
-
-struct pt_regs;
-extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
-extern unsigned long perf_misc_flags(struct pt_regs *regs);
-#define perf_misc_flags(regs) perf_misc_flags(regs)
-
#else
static inline void init_hw_perf_events(void) { }
static inline void perf_events_lapic_init(void) { }
diff --git a/trunk/arch/x86/include/asm/perf_event_p4.h b/trunk/arch/x86/include/asm/perf_event_p4.h
deleted file mode 100644
index 64a8ebff06fc..000000000000
--- a/trunk/arch/x86/include/asm/perf_event_p4.h
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- * Netburst Perfomance Events (P4, old Xeon)
- */
-
-#ifndef PERF_EVENT_P4_H
-#define PERF_EVENT_P4_H
-
-#include
-#include
-
-/*
- * NetBurst has perfomance MSRs shared between
- * threads if HT is turned on, ie for both logical
- * processors (mem: in turn in Atom with HT support
- * perf-MSRs are not shared and every thread has its
- * own perf-MSRs set)
- */
-#define ARCH_P4_TOTAL_ESCR (46)
-#define ARCH_P4_RESERVED_ESCR (2) /* IQ_ESCR(0,1) not always present */
-#define ARCH_P4_MAX_ESCR (ARCH_P4_TOTAL_ESCR - ARCH_P4_RESERVED_ESCR)
-#define ARCH_P4_MAX_CCCR (18)
-#define ARCH_P4_MAX_COUNTER (ARCH_P4_MAX_CCCR / 2)
-
-#define P4_ESCR_EVENT_MASK 0x7e000000U
-#define P4_ESCR_EVENT_SHIFT 25
-#define P4_ESCR_EVENTMASK_MASK 0x01fffe00U
-#define P4_ESCR_EVENTMASK_SHIFT 9
-#define P4_ESCR_TAG_MASK 0x000001e0U
-#define P4_ESCR_TAG_SHIFT 5
-#define P4_ESCR_TAG_ENABLE 0x00000010U
-#define P4_ESCR_T0_OS 0x00000008U
-#define P4_ESCR_T0_USR 0x00000004U
-#define P4_ESCR_T1_OS 0x00000002U
-#define P4_ESCR_T1_USR 0x00000001U
-
-#define P4_ESCR_EVENT(v) ((v) << P4_ESCR_EVENT_SHIFT)
-#define P4_ESCR_EMASK(v) ((v) << P4_ESCR_EVENTMASK_SHIFT)
-#define P4_ESCR_TAG(v) ((v) << P4_ESCR_TAG_SHIFT)
-
-/* Non HT mask */
-#define P4_ESCR_MASK \
- (P4_ESCR_EVENT_MASK | \
- P4_ESCR_EVENTMASK_MASK | \
- P4_ESCR_TAG_MASK | \
- P4_ESCR_TAG_ENABLE | \
- P4_ESCR_T0_OS | \
- P4_ESCR_T0_USR)
-
-/* HT mask */
-#define P4_ESCR_MASK_HT \
- (P4_ESCR_MASK | P4_ESCR_T1_OS | P4_ESCR_T1_USR)
-
-#define P4_CCCR_OVF 0x80000000U
-#define P4_CCCR_CASCADE 0x40000000U
-#define P4_CCCR_OVF_PMI_T0 0x04000000U
-#define P4_CCCR_OVF_PMI_T1 0x08000000U
-#define P4_CCCR_FORCE_OVF 0x02000000U
-#define P4_CCCR_EDGE 0x01000000U
-#define P4_CCCR_THRESHOLD_MASK 0x00f00000U
-#define P4_CCCR_THRESHOLD_SHIFT 20
-#define P4_CCCR_COMPLEMENT 0x00080000U
-#define P4_CCCR_COMPARE 0x00040000U
-#define P4_CCCR_ESCR_SELECT_MASK 0x0000e000U
-#define P4_CCCR_ESCR_SELECT_SHIFT 13
-#define P4_CCCR_ENABLE 0x00001000U
-#define P4_CCCR_THREAD_SINGLE 0x00010000U
-#define P4_CCCR_THREAD_BOTH 0x00020000U
-#define P4_CCCR_THREAD_ANY 0x00030000U
-#define P4_CCCR_RESERVED 0x00000fffU
-
-#define P4_CCCR_THRESHOLD(v) ((v) << P4_CCCR_THRESHOLD_SHIFT)
-#define P4_CCCR_ESEL(v) ((v) << P4_CCCR_ESCR_SELECT_SHIFT)
-
-/* Custom bits in reerved CCCR area */
-#define P4_CCCR_CACHE_OPS_MASK 0x0000003fU
-
-
-/* Non HT mask */
-#define P4_CCCR_MASK \
- (P4_CCCR_OVF | \
- P4_CCCR_CASCADE | \
- P4_CCCR_OVF_PMI_T0 | \
- P4_CCCR_FORCE_OVF | \
- P4_CCCR_EDGE | \
- P4_CCCR_THRESHOLD_MASK | \
- P4_CCCR_COMPLEMENT | \
- P4_CCCR_COMPARE | \
- P4_CCCR_ESCR_SELECT_MASK | \
- P4_CCCR_ENABLE)
-
-/* HT mask */
-#define P4_CCCR_MASK_HT \
- (P4_CCCR_MASK | P4_CCCR_OVF_PMI_T1 | P4_CCCR_THREAD_ANY)
-
-#define P4_GEN_ESCR_EMASK(class, name, bit) \
- class##__##name = ((1 << bit) << P4_ESCR_EVENTMASK_SHIFT)
-#define P4_ESCR_EMASK_BIT(class, name) class##__##name
-
-/*
- * config field is 64bit width and consists of
- * HT << 63 | ESCR << 32 | CCCR
- * where HT is HyperThreading bit (since ESCR
- * has it reserved we may use it for own purpose)
- *
- * note that this is NOT the addresses of respective
- * ESCR and CCCR but rather an only packed value should
- * be unpacked and written to a proper addresses
- *
- * the base idea is to pack as much info as
- * possible
- */
-#define p4_config_pack_escr(v) (((u64)(v)) << 32)
-#define p4_config_pack_cccr(v) (((u64)(v)) & 0xffffffffULL)
-#define p4_config_unpack_escr(v) (((u64)(v)) >> 32)
-#define p4_config_unpack_cccr(v) (((u64)(v)) & 0xffffffffULL)
-
-#define p4_config_unpack_emask(v) \
- ({ \
- u32 t = p4_config_unpack_escr((v)); \
- t = t & P4_ESCR_EVENTMASK_MASK; \
- t = t >> P4_ESCR_EVENTMASK_SHIFT; \
- t; \
- })
-
-#define p4_config_unpack_event(v) \
- ({ \
- u32 t = p4_config_unpack_escr((v)); \
- t = t & P4_ESCR_EVENT_MASK; \
- t = t >> P4_ESCR_EVENT_SHIFT; \
- t; \
- })
-
-#define p4_config_unpack_cache_event(v) (((u64)(v)) & P4_CCCR_CACHE_OPS_MASK)
-
-#define P4_CONFIG_HT_SHIFT 63
-#define P4_CONFIG_HT (1ULL << P4_CONFIG_HT_SHIFT)
-
-static inline bool p4_is_event_cascaded(u64 config)
-{
- u32 cccr = p4_config_unpack_cccr(config);
- return !!(cccr & P4_CCCR_CASCADE);
-}
-
-static inline int p4_ht_config_thread(u64 config)
-{
- return !!(config & P4_CONFIG_HT);
-}
-
-static inline u64 p4_set_ht_bit(u64 config)
-{
- return config | P4_CONFIG_HT;
-}
-
-static inline u64 p4_clear_ht_bit(u64 config)
-{
- return config & ~P4_CONFIG_HT;
-}
-
-static inline int p4_ht_active(void)
-{
-#ifdef CONFIG_SMP
- return smp_num_siblings > 1;
-#endif
- return 0;
-}
-
-static inline int p4_ht_thread(int cpu)
-{
-#ifdef CONFIG_SMP
- if (smp_num_siblings == 2)
- return cpu != cpumask_first(__get_cpu_var(cpu_sibling_map));
-#endif
- return 0;
-}
-
-static inline int p4_should_swap_ts(u64 config, int cpu)
-{
- return p4_ht_config_thread(config) ^ p4_ht_thread(cpu);
-}
-
-static inline u32 p4_default_cccr_conf(int cpu)
-{
- /*
- * Note that P4_CCCR_THREAD_ANY is "required" on
- * non-HT machines (on HT machines we count TS events
- * regardless the state of second logical processor
- */
- u32 cccr = P4_CCCR_THREAD_ANY;
-
- if (!p4_ht_thread(cpu))
- cccr |= P4_CCCR_OVF_PMI_T0;
- else
- cccr |= P4_CCCR_OVF_PMI_T1;
-
- return cccr;
-}
-
-static inline u32 p4_default_escr_conf(int cpu, int exclude_os, int exclude_usr)
-{
- u32 escr = 0;
-
- if (!p4_ht_thread(cpu)) {
- if (!exclude_os)
- escr |= P4_ESCR_T0_OS;
- if (!exclude_usr)
- escr |= P4_ESCR_T0_USR;
- } else {
- if (!exclude_os)
- escr |= P4_ESCR_T1_OS;
- if (!exclude_usr)
- escr |= P4_ESCR_T1_USR;
- }
-
- return escr;
-}
-
-enum P4_EVENTS {
- P4_EVENT_TC_DELIVER_MODE,
- P4_EVENT_BPU_FETCH_REQUEST,
- P4_EVENT_ITLB_REFERENCE,
- P4_EVENT_MEMORY_CANCEL,
- P4_EVENT_MEMORY_COMPLETE,
- P4_EVENT_LOAD_PORT_REPLAY,
- P4_EVENT_STORE_PORT_REPLAY,
- P4_EVENT_MOB_LOAD_REPLAY,
- P4_EVENT_PAGE_WALK_TYPE,
- P4_EVENT_BSQ_CACHE_REFERENCE,
- P4_EVENT_IOQ_ALLOCATION,
- P4_EVENT_IOQ_ACTIVE_ENTRIES,
- P4_EVENT_FSB_DATA_ACTIVITY,
- P4_EVENT_BSQ_ALLOCATION,
- P4_EVENT_BSQ_ACTIVE_ENTRIES,
- P4_EVENT_SSE_INPUT_ASSIST,
- P4_EVENT_PACKED_SP_UOP,
- P4_EVENT_PACKED_DP_UOP,
- P4_EVENT_SCALAR_SP_UOP,
- P4_EVENT_SCALAR_DP_UOP,
- P4_EVENT_64BIT_MMX_UOP,
- P4_EVENT_128BIT_MMX_UOP,
- P4_EVENT_X87_FP_UOP,
- P4_EVENT_TC_MISC,
- P4_EVENT_GLOBAL_POWER_EVENTS,
- P4_EVENT_TC_MS_XFER,
- P4_EVENT_UOP_QUEUE_WRITES,
- P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE,
- P4_EVENT_RETIRED_BRANCH_TYPE,
- P4_EVENT_RESOURCE_STALL,
- P4_EVENT_WC_BUFFER,
- P4_EVENT_B2B_CYCLES,
- P4_EVENT_BNR,
- P4_EVENT_SNOOP,
- P4_EVENT_RESPONSE,
- P4_EVENT_FRONT_END_EVENT,
- P4_EVENT_EXECUTION_EVENT,
- P4_EVENT_REPLAY_EVENT,
- P4_EVENT_INSTR_RETIRED,
- P4_EVENT_UOPS_RETIRED,
- P4_EVENT_UOP_TYPE,
- P4_EVENT_BRANCH_RETIRED,
- P4_EVENT_MISPRED_BRANCH_RETIRED,
- P4_EVENT_X87_ASSIST,
- P4_EVENT_MACHINE_CLEAR,
- P4_EVENT_INSTR_COMPLETED,
-};
-
-#define P4_OPCODE(event) event##_OPCODE
-#define P4_OPCODE_ESEL(opcode) ((opcode & 0x00ff) >> 0)
-#define P4_OPCODE_EVNT(opcode) ((opcode & 0xff00) >> 8)
-#define P4_OPCODE_PACK(event, sel) (((event) << 8) | sel)
-
-/*
- * Comments below the event represent ESCR restriction
- * for this event and counter index per ESCR
- *
- * MSR_P4_IQ_ESCR0 and MSR_P4_IQ_ESCR1 are available only on early
- * processor builds (family 0FH, models 01H-02H). These MSRs
- * are not available on later versions, so that we don't use
- * them completely
- *
- * Also note that CCCR1 do not have P4_CCCR_ENABLE bit properly
- * working so that we should not use this CCCR and respective
- * counter as result
- */
-enum P4_EVENT_OPCODES {
- P4_OPCODE(P4_EVENT_TC_DELIVER_MODE) = P4_OPCODE_PACK(0x01, 0x01),
- /*
- * MSR_P4_TC_ESCR0: 4, 5
- * MSR_P4_TC_ESCR1: 6, 7
- */
-
- P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST) = P4_OPCODE_PACK(0x03, 0x00),
- /*
- * MSR_P4_BPU_ESCR0: 0, 1
- * MSR_P4_BPU_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_ITLB_REFERENCE) = P4_OPCODE_PACK(0x18, 0x03),
- /*
- * MSR_P4_ITLB_ESCR0: 0, 1
- * MSR_P4_ITLB_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_MEMORY_CANCEL) = P4_OPCODE_PACK(0x02, 0x05),
- /*
- * MSR_P4_DAC_ESCR0: 8, 9
- * MSR_P4_DAC_ESCR1: 10, 11
- */
-
- P4_OPCODE(P4_EVENT_MEMORY_COMPLETE) = P4_OPCODE_PACK(0x08, 0x02),
- /*
- * MSR_P4_SAAT_ESCR0: 8, 9
- * MSR_P4_SAAT_ESCR1: 10, 11
- */
-
- P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY) = P4_OPCODE_PACK(0x04, 0x02),
- /*
- * MSR_P4_SAAT_ESCR0: 8, 9
- * MSR_P4_SAAT_ESCR1: 10, 11
- */
-
- P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY) = P4_OPCODE_PACK(0x05, 0x02),
- /*
- * MSR_P4_SAAT_ESCR0: 8, 9
- * MSR_P4_SAAT_ESCR1: 10, 11
- */
-
- P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY) = P4_OPCODE_PACK(0x03, 0x02),
- /*
- * MSR_P4_MOB_ESCR0: 0, 1
- * MSR_P4_MOB_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE) = P4_OPCODE_PACK(0x01, 0x04),
- /*
- * MSR_P4_PMH_ESCR0: 0, 1
- * MSR_P4_PMH_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE) = P4_OPCODE_PACK(0x0c, 0x07),
- /*
- * MSR_P4_BSU_ESCR0: 0, 1
- * MSR_P4_BSU_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_IOQ_ALLOCATION) = P4_OPCODE_PACK(0x03, 0x06),
- /*
- * MSR_P4_FSB_ESCR0: 0, 1
- * MSR_P4_FSB_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES) = P4_OPCODE_PACK(0x1a, 0x06),
- /*
- * MSR_P4_FSB_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY) = P4_OPCODE_PACK(0x17, 0x06),
- /*
- * MSR_P4_FSB_ESCR0: 0, 1
- * MSR_P4_FSB_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_BSQ_ALLOCATION) = P4_OPCODE_PACK(0x05, 0x07),
- /*
- * MSR_P4_BSU_ESCR0: 0, 1
- */
-
- P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES) = P4_OPCODE_PACK(0x06, 0x07),
- /*
- * NOTE: no ESCR name in docs, it's guessed
- * MSR_P4_BSU_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST) = P4_OPCODE_PACK(0x34, 0x01),
- /*
- * MSR_P4_FIRM_ESCR0: 8, 9
- * MSR_P4_FIRM_ESCR1: 10, 11
- */
-
- P4_OPCODE(P4_EVENT_PACKED_SP_UOP) = P4_OPCODE_PACK(0x08, 0x01),
- /*
- * MSR_P4_FIRM_ESCR0: 8, 9
- * MSR_P4_FIRM_ESCR1: 10, 11
- */
-
- P4_OPCODE(P4_EVENT_PACKED_DP_UOP) = P4_OPCODE_PACK(0x0c, 0x01),
- /*
- * MSR_P4_FIRM_ESCR0: 8, 9
- * MSR_P4_FIRM_ESCR1: 10, 11
- */
-
- P4_OPCODE(P4_EVENT_SCALAR_SP_UOP) = P4_OPCODE_PACK(0x0a, 0x01),
- /*
- * MSR_P4_FIRM_ESCR0: 8, 9
- * MSR_P4_FIRM_ESCR1: 10, 11
- */
-
- P4_OPCODE(P4_EVENT_SCALAR_DP_UOP) = P4_OPCODE_PACK(0x0e, 0x01),
- /*
- * MSR_P4_FIRM_ESCR0: 8, 9
- * MSR_P4_FIRM_ESCR1: 10, 11
- */
-
- P4_OPCODE(P4_EVENT_64BIT_MMX_UOP) = P4_OPCODE_PACK(0x02, 0x01),
- /*
- * MSR_P4_FIRM_ESCR0: 8, 9
- * MSR_P4_FIRM_ESCR1: 10, 11
- */
-
- P4_OPCODE(P4_EVENT_128BIT_MMX_UOP) = P4_OPCODE_PACK(0x1a, 0x01),
- /*
- * MSR_P4_FIRM_ESCR0: 8, 9
- * MSR_P4_FIRM_ESCR1: 10, 11
- */
-
- P4_OPCODE(P4_EVENT_X87_FP_UOP) = P4_OPCODE_PACK(0x04, 0x01),
- /*
- * MSR_P4_FIRM_ESCR0: 8, 9
- * MSR_P4_FIRM_ESCR1: 10, 11
- */
-
- P4_OPCODE(P4_EVENT_TC_MISC) = P4_OPCODE_PACK(0x06, 0x01),
- /*
- * MSR_P4_TC_ESCR0: 4, 5
- * MSR_P4_TC_ESCR1: 6, 7
- */
-
- P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS) = P4_OPCODE_PACK(0x13, 0x06),
- /*
- * MSR_P4_FSB_ESCR0: 0, 1
- * MSR_P4_FSB_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_TC_MS_XFER) = P4_OPCODE_PACK(0x05, 0x00),
- /*
- * MSR_P4_MS_ESCR0: 4, 5
- * MSR_P4_MS_ESCR1: 6, 7
- */
-
- P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES) = P4_OPCODE_PACK(0x09, 0x00),
- /*
- * MSR_P4_MS_ESCR0: 4, 5
- * MSR_P4_MS_ESCR1: 6, 7
- */
-
- P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE) = P4_OPCODE_PACK(0x05, 0x02),
- /*
- * MSR_P4_TBPU_ESCR0: 4, 5
- * MSR_P4_TBPU_ESCR1: 6, 7
- */
-
- P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE) = P4_OPCODE_PACK(0x04, 0x02),
- /*
- * MSR_P4_TBPU_ESCR0: 4, 5
- * MSR_P4_TBPU_ESCR1: 6, 7
- */
-
- P4_OPCODE(P4_EVENT_RESOURCE_STALL) = P4_OPCODE_PACK(0x01, 0x01),
- /*
- * MSR_P4_ALF_ESCR0: 12, 13, 16
- * MSR_P4_ALF_ESCR1: 14, 15, 17
- */
-
- P4_OPCODE(P4_EVENT_WC_BUFFER) = P4_OPCODE_PACK(0x05, 0x05),
- /*
- * MSR_P4_DAC_ESCR0: 8, 9
- * MSR_P4_DAC_ESCR1: 10, 11
- */
-
- P4_OPCODE(P4_EVENT_B2B_CYCLES) = P4_OPCODE_PACK(0x16, 0x03),
- /*
- * MSR_P4_FSB_ESCR0: 0, 1
- * MSR_P4_FSB_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_BNR) = P4_OPCODE_PACK(0x08, 0x03),
- /*
- * MSR_P4_FSB_ESCR0: 0, 1
- * MSR_P4_FSB_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_SNOOP) = P4_OPCODE_PACK(0x06, 0x03),
- /*
- * MSR_P4_FSB_ESCR0: 0, 1
- * MSR_P4_FSB_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_RESPONSE) = P4_OPCODE_PACK(0x04, 0x03),
- /*
- * MSR_P4_FSB_ESCR0: 0, 1
- * MSR_P4_FSB_ESCR1: 2, 3
- */
-
- P4_OPCODE(P4_EVENT_FRONT_END_EVENT) = P4_OPCODE_PACK(0x08, 0x05),
- /*
- * MSR_P4_CRU_ESCR2: 12, 13, 16
- * MSR_P4_CRU_ESCR3: 14, 15, 17
- */
-
- P4_OPCODE(P4_EVENT_EXECUTION_EVENT) = P4_OPCODE_PACK(0x0c, 0x05),
- /*
- * MSR_P4_CRU_ESCR2: 12, 13, 16
- * MSR_P4_CRU_ESCR3: 14, 15, 17
- */
-
- P4_OPCODE(P4_EVENT_REPLAY_EVENT) = P4_OPCODE_PACK(0x09, 0x05),
- /*
- * MSR_P4_CRU_ESCR2: 12, 13, 16
- * MSR_P4_CRU_ESCR3: 14, 15, 17
- */
-
- P4_OPCODE(P4_EVENT_INSTR_RETIRED) = P4_OPCODE_PACK(0x02, 0x04),
- /*
- * MSR_P4_CRU_ESCR0: 12, 13, 16
- * MSR_P4_CRU_ESCR1: 14, 15, 17
- */
-
- P4_OPCODE(P4_EVENT_UOPS_RETIRED) = P4_OPCODE_PACK(0x01, 0x04),
- /*
- * MSR_P4_CRU_ESCR0: 12, 13, 16
- * MSR_P4_CRU_ESCR1: 14, 15, 17
- */
-
- P4_OPCODE(P4_EVENT_UOP_TYPE) = P4_OPCODE_PACK(0x02, 0x02),
- /*
- * MSR_P4_RAT_ESCR0: 12, 13, 16
- * MSR_P4_RAT_ESCR1: 14, 15, 17
- */
-
- P4_OPCODE(P4_EVENT_BRANCH_RETIRED) = P4_OPCODE_PACK(0x06, 0x05),
- /*
- * MSR_P4_CRU_ESCR2: 12, 13, 16
- * MSR_P4_CRU_ESCR3: 14, 15, 17
- */
-
- P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED) = P4_OPCODE_PACK(0x03, 0x04),
- /*
- * MSR_P4_CRU_ESCR0: 12, 13, 16
- * MSR_P4_CRU_ESCR1: 14, 15, 17
- */
-
- P4_OPCODE(P4_EVENT_X87_ASSIST) = P4_OPCODE_PACK(0x03, 0x05),
- /*
- * MSR_P4_CRU_ESCR2: 12, 13, 16
- * MSR_P4_CRU_ESCR3: 14, 15, 17
- */
-
- P4_OPCODE(P4_EVENT_MACHINE_CLEAR) = P4_OPCODE_PACK(0x02, 0x05),
- /*
- * MSR_P4_CRU_ESCR2: 12, 13, 16
- * MSR_P4_CRU_ESCR3: 14, 15, 17
- */
-
- P4_OPCODE(P4_EVENT_INSTR_COMPLETED) = P4_OPCODE_PACK(0x07, 0x04),
- /*
- * MSR_P4_CRU_ESCR0: 12, 13, 16
- * MSR_P4_CRU_ESCR1: 14, 15, 17
- */
-};
-
-/*
- * a caller should use P4_ESCR_EMASK_NAME helper to
- * pick the EventMask needed, for example
- *
- * P4_ESCR_EMASK_NAME(P4_EVENT_TC_DELIVER_MODE, DD)
- */
-enum P4_ESCR_EMASKS {
- P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DD, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DB, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DI, 2),
- P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, BD, 3),
- P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, BB, 4),
- P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, BI, 5),
- P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, ID, 6),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_BPU_FETCH_REQUEST, TCMISS, 0),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_ITLB_REFERENCE, HIT, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_ITLB_REFERENCE, MISS, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_ITLB_REFERENCE, HIT_UK, 2),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_CANCEL, ST_RB_FULL, 2),
- P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_CANCEL, 64K_CONF, 3),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_COMPLETE, LSC, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_COMPLETE, SSC, 1),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_LOAD_PORT_REPLAY, SPLIT_LD, 1),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_STORE_PORT_REPLAY, SPLIT_ST, 1),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, NO_STA, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, NO_STD, 3),
- P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, PARTIAL_DATA, 4),
- P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, UNALGN_ADDR, 5),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_PAGE_WALK_TYPE, DTMISS, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_PAGE_WALK_TYPE, ITMISS, 1),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM, 2),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS, 3),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE, 4),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM, 5),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS, 8),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS, 9),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS, 10),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, DEFAULT, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, ALL_READ, 5),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, ALL_WRITE, 6),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_UC, 7),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WC, 8),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WT, 9),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WP, 10),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WB, 11),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, OWN, 13),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, OTHER, 14),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, PREFETCH, 15),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, DEFAULT, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_READ, 5),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_WRITE, 6),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_UC, 7),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WC, 8),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WT, 9),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WP, 10),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WB, 11),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, OWN, 13),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, OTHER, 14),
- P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, PREFETCH, 15),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OTHER, 2),
- P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_DRV, 3),
- P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OWN, 4),
- P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OTHER, 5),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE0, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE1, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_LEN0, 2),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_LEN1, 3),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_IO_TYPE, 5),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_LOCK_TYPE, 6),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_CACHE_TYPE, 7),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_SPLIT_TYPE, 8),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_DEM_TYPE, 9),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_ORD_TYPE, 10),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE0, 11),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE1, 12),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE2, 13),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE0, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE1, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN0, 2),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN1, 3),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_IO_TYPE, 5),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LOCK_TYPE, 6),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_CACHE_TYPE, 7),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_SPLIT_TYPE, 8),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_DEM_TYPE, 9),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_ORD_TYPE, 10),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE0, 11),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE1, 12),
- P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE2, 13),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_SSE_INPUT_ASSIST, ALL, 15),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_PACKED_SP_UOP, ALL, 15),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_PACKED_DP_UOP, ALL, 15),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_SCALAR_SP_UOP, ALL, 15),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_SCALAR_DP_UOP, ALL, 15),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_64BIT_MMX_UOP, ALL, 15),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_128BIT_MMX_UOP, ALL, 15),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_X87_FP_UOP, ALL, 15),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_TC_MISC, FLUSH, 4),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING, 0),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_TC_MS_XFER, CISC, 0),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_BUILD, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_DELIVER, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_UOP_QUEUE_WRITES, FROM_ROM, 2),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CONDITIONAL, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CALL, 2),
- P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, RETURN, 3),
- P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, INDIRECT, 4),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, CALL, 2),
- P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN, 3),
- P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT, 4),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_RESOURCE_STALL, SBFULL, 5),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_WC_BUFFER, WCB_EVICTS, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_WC_BUFFER, WCB_FULL_EVICTS, 1),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_FRONT_END_EVENT, NBOGUS, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_FRONT_END_EVENT, BOGUS, 1),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS0, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS1, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS2, 2),
- P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS3, 3),
- P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS0, 4),
- P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS1, 5),
- P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS2, 6),
- P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS3, 7),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_REPLAY_EVENT, NBOGUS, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_REPLAY_EVENT, BOGUS, 1),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, NBOGUSTAG, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, BOGUSNTAG, 2),
- P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, BOGUSTAG, 3),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_UOPS_RETIRED, NBOGUS, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_UOPS_RETIRED, BOGUS, 1),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_UOP_TYPE, TAGLOADS, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_UOP_TYPE, TAGSTORES, 2),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMNP, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMNM, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMTP, 2),
- P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMTM, 3),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS, 0),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, FPSU, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, FPSO, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, POAO, 2),
- P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, POAU, 3),
- P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, PREA, 4),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_MACHINE_CLEAR, CLEAR, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_MACHINE_CLEAR, MOCLEAR, 1),
- P4_GEN_ESCR_EMASK(P4_EVENT_MACHINE_CLEAR, SMCLEAR, 2),
-
- P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_COMPLETED, NBOGUS, 0),
- P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_COMPLETED, BOGUS, 1),
-};
-
-/* P4 PEBS: stale for a while */
-#define P4_PEBS_METRIC_MASK 0x00001fffU
-#define P4_PEBS_UOB_TAG 0x01000000U
-#define P4_PEBS_ENABLE 0x02000000U
-
-/* Replay metrics for MSR_IA32_PEBS_ENABLE and MSR_P4_PEBS_MATRIX_VERT */
-#define P4_PEBS__1stl_cache_load_miss_retired 0x3000001
-#define P4_PEBS__2ndl_cache_load_miss_retired 0x3000002
-#define P4_PEBS__dtlb_load_miss_retired 0x3000004
-#define P4_PEBS__dtlb_store_miss_retired 0x3000004
-#define P4_PEBS__dtlb_all_miss_retired 0x3000004
-#define P4_PEBS__tagged_mispred_branch 0x3018000
-#define P4_PEBS__mob_load_replay_retired 0x3000200
-#define P4_PEBS__split_load_retired 0x3000400
-#define P4_PEBS__split_store_retired 0x3000400
-
-#define P4_VERT__1stl_cache_load_miss_retired 0x0000001
-#define P4_VERT__2ndl_cache_load_miss_retired 0x0000001
-#define P4_VERT__dtlb_load_miss_retired 0x0000001
-#define P4_VERT__dtlb_store_miss_retired 0x0000002
-#define P4_VERT__dtlb_all_miss_retired 0x0000003
-#define P4_VERT__tagged_mispred_branch 0x0000010
-#define P4_VERT__mob_load_replay_retired 0x0000001
-#define P4_VERT__split_load_retired 0x0000001
-#define P4_VERT__split_store_retired 0x0000002
-
-enum P4_CACHE_EVENTS {
- P4_CACHE__NONE,
-
- P4_CACHE__1stl_cache_load_miss_retired,
- P4_CACHE__2ndl_cache_load_miss_retired,
- P4_CACHE__dtlb_load_miss_retired,
- P4_CACHE__dtlb_store_miss_retired,
- P4_CACHE__itlb_reference_hit,
- P4_CACHE__itlb_reference_miss,
-
- P4_CACHE__MAX
-};
-
-#endif /* PERF_EVENT_P4_H */
diff --git a/trunk/arch/x86/include/asm/processor.h b/trunk/arch/x86/include/asm/processor.h
index 5a51379dcbe4..b753ea59703a 100644
--- a/trunk/arch/x86/include/asm/processor.h
+++ b/trunk/arch/x86/include/asm/processor.h
@@ -21,6 +21,7 @@ struct mm_struct;
#include
#include
#include
+#include
#include
#include
@@ -28,7 +29,6 @@ struct mm_struct;
#include
#include
#include
-#include
#define HBP_NUM 4
/*
@@ -113,6 +113,7 @@ struct cpuinfo_x86 {
/* Index into per_cpu list: */
u16 cpu_index;
#endif
+ unsigned int x86_hyper_vendor;
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
#define X86_VENDOR_INTEL 0
@@ -126,6 +127,9 @@ struct cpuinfo_x86 {
#define X86_VENDOR_UNKNOWN 0xff
+#define X86_HYPER_VENDOR_NONE 0
+#define X86_HYPER_VENDOR_VMWARE 1
+
/*
* capabilities of CPUs
*/
@@ -376,10 +380,6 @@ union thread_xstate {
struct xsave_struct xsave;
};
-struct fpu {
- union thread_xstate *state;
-};
-
#ifdef CONFIG_X86_64
DECLARE_PER_CPU(struct orig_ist, orig_ist);
@@ -457,7 +457,7 @@ struct thread_struct {
unsigned long trap_no;
unsigned long error_code;
/* floating point and extended processor state */
- struct fpu fpu;
+ union thread_xstate *xstate;
#ifdef CONFIG_X86_32
/* Virtual 86 mode info */
struct vm86_struct __user *vm86_info;
@@ -473,6 +473,10 @@ struct thread_struct {
unsigned long iopl;
/* Max allowed port in the bitmap, in bytes: */
unsigned io_bitmap_max;
+/* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set. */
+ unsigned long debugctlmsr;
+ /* Debug Store context; see asm/ds.h */
+ struct ds_context *ds_ctx;
};
static inline unsigned long native_get_debugreg(int regno)
@@ -799,7 +803,7 @@ extern void cpu_init(void);
static inline unsigned long get_debugctlmsr(void)
{
- unsigned long debugctlmsr = 0;
+ unsigned long debugctlmsr = 0;
#ifndef CONFIG_X86_DEBUGCTLMSR
if (boot_cpu_data.x86 < 6)
@@ -807,6 +811,21 @@ static inline unsigned long get_debugctlmsr(void)
#endif
rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
+ return debugctlmsr;
+}
+
+static inline unsigned long get_debugctlmsr_on_cpu(int cpu)
+{
+ u64 debugctlmsr = 0;
+ u32 val1, val2;
+
+#ifndef CONFIG_X86_DEBUGCTLMSR
+ if (boot_cpu_data.x86 < 6)
+ return 0;
+#endif
+ rdmsr_on_cpu(cpu, MSR_IA32_DEBUGCTLMSR, &val1, &val2);
+ debugctlmsr = val1 | ((u64)val2 << 32);
+
return debugctlmsr;
}
@@ -819,6 +838,18 @@ static inline void update_debugctlmsr(unsigned long debugctlmsr)
wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
}
+static inline void update_debugctlmsr_on_cpu(int cpu,
+ unsigned long debugctlmsr)
+{
+#ifndef CONFIG_X86_DEBUGCTLMSR
+ if (boot_cpu_data.x86 < 6)
+ return;
+#endif
+ wrmsr_on_cpu(cpu, MSR_IA32_DEBUGCTLMSR,
+ (u32)((u64)debugctlmsr),
+ (u32)((u64)debugctlmsr >> 32));
+}
+
/*
* from system description table in BIOS. Mostly for MCA use, but
* others may find it useful:
diff --git a/trunk/arch/x86/include/asm/ptrace-abi.h b/trunk/arch/x86/include/asm/ptrace-abi.h
index 52b098a6eebb..86723035a515 100644
--- a/trunk/arch/x86/include/asm/ptrace-abi.h
+++ b/trunk/arch/x86/include/asm/ptrace-abi.h
@@ -82,6 +82,61 @@
#ifndef __ASSEMBLY__
#include
-#endif
+
+/* configuration/status structure used in PTRACE_BTS_CONFIG and
+ PTRACE_BTS_STATUS commands.
+*/
+struct ptrace_bts_config {
+ /* requested or actual size of BTS buffer in bytes */
+ __u32 size;
+ /* bitmask of below flags */
+ __u32 flags;
+ /* buffer overflow signal */
+ __u32 signal;
+ /* actual size of bts_struct in bytes */
+ __u32 bts_size;
+};
+#endif /* __ASSEMBLY__ */
+
+#define PTRACE_BTS_O_TRACE 0x1 /* branch trace */
+#define PTRACE_BTS_O_SCHED 0x2 /* scheduling events w/ jiffies */
+#define PTRACE_BTS_O_SIGNAL 0x4 /* send SIG on buffer overflow
+ instead of wrapping around */
+#define PTRACE_BTS_O_ALLOC 0x8 /* (re)allocate buffer */
+
+#define PTRACE_BTS_CONFIG 40
+/* Configure branch trace recording.
+ ADDR points to a struct ptrace_bts_config.
+ DATA gives the size of that buffer.
+ A new buffer is allocated, if requested in the flags.
+ An overflow signal may only be requested for new buffers.
+ Returns the number of bytes read.
+*/
+#define PTRACE_BTS_STATUS 41
+/* Return the current configuration in a struct ptrace_bts_config
+ pointed to by ADDR; DATA gives the size of that buffer.
+ Returns the number of bytes written.
+*/
+#define PTRACE_BTS_SIZE 42
+/* Return the number of available BTS records for draining.
+ DATA and ADDR are ignored.
+*/
+#define PTRACE_BTS_GET 43
+/* Get a single BTS record.
+ DATA defines the index into the BTS array, where 0 is the newest
+ entry, and higher indices refer to older entries.
+ ADDR is pointing to struct bts_struct (see asm/ds.h).
+*/
+#define PTRACE_BTS_CLEAR 44
+/* Clear the BTS buffer.
+ DATA and ADDR are ignored.
+*/
+#define PTRACE_BTS_DRAIN 45
+/* Read all available BTS records and clear the buffer.
+ ADDR points to an array of struct bts_struct.
+ DATA gives the size of that buffer.
+ BTS records are read from oldest to newest.
+ Returns number of BTS records drained.
+*/
#endif /* _ASM_X86_PTRACE_ABI_H */
diff --git a/trunk/arch/x86/include/asm/ptrace.h b/trunk/arch/x86/include/asm/ptrace.h
index 78cd1ea94500..69a686a7dff0 100644
--- a/trunk/arch/x86/include/asm/ptrace.h
+++ b/trunk/arch/x86/include/asm/ptrace.h
@@ -289,6 +289,12 @@ extern int do_get_thread_area(struct task_struct *p, int idx,
extern int do_set_thread_area(struct task_struct *p, int idx,
struct user_desc __user *info, int can_allocate);
+#ifdef CONFIG_X86_PTRACE_BTS
+extern void ptrace_bts_untrace(struct task_struct *tsk);
+
+#define arch_ptrace_untrace(tsk) ptrace_bts_untrace(tsk)
+#endif /* CONFIG_X86_PTRACE_BTS */
+
#endif /* __KERNEL__ */
#endif /* !__ASSEMBLY__ */
diff --git a/trunk/arch/x86/include/asm/thread_info.h b/trunk/arch/x86/include/asm/thread_info.h
index d4092fac226b..e0d28901e969 100644
--- a/trunk/arch/x86/include/asm/thread_info.h
+++ b/trunk/arch/x86/include/asm/thread_info.h
@@ -92,7 +92,8 @@ struct thread_info {
#define TIF_IO_BITMAP 22 /* uses I/O bitmap */
#define TIF_FREEZE 23 /* is freezing for suspend */
#define TIF_FORCED_TF 24 /* true if TF in eflags artificially */
-#define TIF_BLOCKSTEP 25 /* set when we want DEBUGCTLMSR_BTF */
+#define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */
+#define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */
#define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */
#define TIF_SYSCALL_TRACEPOINT 28 /* syscall tracepoint instrumentation */
@@ -114,7 +115,8 @@ struct thread_info {
#define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP)
#define _TIF_FREEZE (1 << TIF_FREEZE)
#define _TIF_FORCED_TF (1 << TIF_FORCED_TF)
-#define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP)
+#define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR)
+#define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR)
#define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES)
#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
@@ -145,7 +147,7 @@ struct thread_info {
/* flags to check in __switch_to() */
#define _TIF_WORK_CTXSW \
- (_TIF_IO_BITMAP|_TIF_NOTSC|_TIF_BLOCKSTEP)
+ (_TIF_IO_BITMAP|_TIF_DEBUGCTLMSR|_TIF_DS_AREA_MSR|_TIF_NOTSC)
#define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY)
#define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW|_TIF_DEBUG)
@@ -242,6 +244,7 @@ static inline struct thread_info *current_thread_info(void)
#define TS_POLLING 0x0004 /* true if in idle loop
and not sleeping */
#define TS_RESTORE_SIGMASK 0x0008 /* restore signal mask in do_signal() */
+#define TS_XSAVE 0x0010 /* Use xsave/xrstor */
#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
diff --git a/trunk/arch/x86/include/asm/traps.h b/trunk/arch/x86/include/asm/traps.h
index f66cda56781d..4da91ad69e0d 100644
--- a/trunk/arch/x86/include/asm/traps.h
+++ b/trunk/arch/x86/include/asm/traps.h
@@ -79,7 +79,7 @@ static inline int get_si_code(unsigned long condition)
extern int panic_on_unrecovered_nmi;
-void math_error(struct pt_regs *, int, int);
+void math_error(void __user *);
void math_emulate(struct math_emu_info *);
#ifndef CONFIG_X86_32
asmlinkage void smp_thermal_interrupt(void);
diff --git a/trunk/arch/x86/include/asm/uv/uv_bau.h b/trunk/arch/x86/include/asm/uv/uv_bau.h
index aa558ac0306e..b414d2b401f6 100644
--- a/trunk/arch/x86/include/asm/uv/uv_bau.h
+++ b/trunk/arch/x86/include/asm/uv/uv_bau.h
@@ -27,14 +27,13 @@
* set 2 is at BASE + 2*512, set 3 at BASE + 3*512, and so on.
*
* We will use 31 sets, one for sending BAU messages from each of the 32
- * cpu's on the uvhub.
+ * cpu's on the node.
*
* TLB shootdown will use the first of the 8 descriptors of each set.
* Each of the descriptors is 64 bytes in size (8*64 = 512 bytes in a set).
*/
#define UV_ITEMS_PER_DESCRIPTOR 8
-#define MAX_BAU_CONCURRENT 3
#define UV_CPUS_PER_ACT_STATUS 32
#define UV_ACT_STATUS_MASK 0x3
#define UV_ACT_STATUS_SIZE 2
@@ -46,9 +45,6 @@
#define UV_PAYLOADQ_PNODE_SHIFT 49
#define UV_PTC_BASENAME "sgi_uv/ptc_statistics"
#define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask))
-#define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15
-#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16
-#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL
/*
* bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1
@@ -59,29 +55,15 @@
#define DESC_STATUS_SOURCE_TIMEOUT 3
/*
- * source side threshholds at which message retries print a warning
+ * source side thresholds at which message retries print a warning
*/
#define SOURCE_TIMEOUT_LIMIT 20
#define DESTINATION_TIMEOUT_LIMIT 20
-/*
- * misc. delays, in microseconds
- */
-#define THROTTLE_DELAY 10
-#define TIMEOUT_DELAY 10
-#define BIOS_TO 1000
-/* BIOS is assumed to set the destination timeout to 1003520 nanoseconds */
-
-/*
- * threshholds at which to use IPI to free resources
- */
-#define PLUGSB4RESET 100
-#define TIMEOUTSB4RESET 100
-
/*
* number of entries in the destination side payload queue
*/
-#define DEST_Q_SIZE 20
+#define DEST_Q_SIZE 17
/*
* number of destination side software ack resources
*/
@@ -90,10 +72,9 @@
/*
* completion statuses for sending a TLB flush message
*/
-#define FLUSH_RETRY_PLUGGED 1
-#define FLUSH_RETRY_TIMEOUT 2
-#define FLUSH_GIVEUP 3
-#define FLUSH_COMPLETE 4
+#define FLUSH_RETRY 1
+#define FLUSH_GIVEUP 2
+#define FLUSH_COMPLETE 3
/*
* Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor)
@@ -105,14 +86,14 @@
* 'base_dest_nodeid' field of the header corresponds to the
* destination nodeID associated with that specified bit.
*/
-struct bau_target_uvhubmask {
- unsigned long bits[BITS_TO_LONGS(UV_DISTRIBUTION_SIZE)];
+struct bau_target_nodemask {
+ unsigned long bits[BITS_TO_LONGS(256)];
};
/*
- * mask of cpu's on a uvhub
+ * mask of cpu's on a node
* (during initialization we need to check that unsigned long has
- * enough bits for max. cpu's per uvhub)
+ * enough bits for max. cpu's per node)
*/
struct bau_local_cpumask {
unsigned long bits;
@@ -154,8 +135,8 @@ struct bau_msg_payload {
struct bau_msg_header {
unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */
/* bits 5:0 */
- unsigned int base_dest_nodeid:15; /* nasid (pnode<<1) of */
- /* bits 20:6 */ /* first bit in uvhub map */
+ unsigned int base_dest_nodeid:15; /* nasid>>1 (pnode) of */
+ /* bits 20:6 */ /* first bit in node_map */
unsigned int command:8; /* message type */
/* bits 28:21 */
/* 0x38: SN3net EndPoint Message */
@@ -165,38 +146,26 @@ struct bau_msg_header {
unsigned int rsvd_2:9; /* must be zero */
/* bits 40:32 */
/* Suppl_A is 56-41 */
- unsigned int sequence:16;/* message sequence number */
- /* bits 56:41 */ /* becomes bytes 16-17 of msg */
+ unsigned int payload_2a:8;/* becomes byte 16 of msg */
+ /* bits 48:41 */ /* not currently using */
+ unsigned int payload_2b:8;/* becomes byte 17 of msg */
+ /* bits 56:49 */ /* not currently using */
/* Address field (96:57) is never used as an
address (these are address bits 42:3) */
-
unsigned int rsvd_3:1; /* must be zero */
/* bit 57 */
/* address bits 27:4 are payload */
- /* these next 24 (58-81) bits become bytes 12-14 of msg */
-
- /* bits 65:58 land in byte 12 */
+ /* these 24 bits become bytes 12-14 of msg */
unsigned int replied_to:1;/* sent as 0 by the source to byte 12 */
/* bit 58 */
- unsigned int msg_type:3; /* software type of the message*/
- /* bits 61:59 */
- unsigned int canceled:1; /* message canceled, resource to be freed*/
- /* bit 62 */
- unsigned int payload_1a:1;/* not currently used */
- /* bit 63 */
- unsigned int payload_1b:2;/* not currently used */
- /* bits 65:64 */
-
- /* bits 73:66 land in byte 13 */
- unsigned int payload_1ca:6;/* not currently used */
- /* bits 71:66 */
- unsigned int payload_1c:2;/* not currently used */
- /* bits 73:72 */
-
- /* bits 81:74 land in byte 14 */
- unsigned int payload_1d:6;/* not currently used */
- /* bits 79:74 */
- unsigned int payload_1e:2;/* not currently used */
+
+ unsigned int payload_1a:5;/* not currently used */
+ /* bits 63:59 */
+ unsigned int payload_1b:8;/* not currently used */
+ /* bits 71:64 */
+ unsigned int payload_1c:8;/* not currently used */
+ /* bits 79:72 */
+ unsigned int payload_1d:2;/* not currently used */
/* bits 81:80 */
unsigned int rsvd_4:7; /* must be zero */
@@ -209,7 +178,7 @@ struct bau_msg_header {
/* bits 95:90 */
unsigned int rsvd_6:5; /* must be zero */
/* bits 100:96 */
- unsigned int int_both:1;/* if 1, interrupt both sockets on the uvhub */
+ unsigned int int_both:1;/* if 1, interrupt both sockets on the blade */
/* bit 101*/
unsigned int fairness:3;/* usually zero */
/* bits 104:102 */
@@ -222,18 +191,13 @@ struct bau_msg_header {
/* bits 127:107 */
};
-/* see msg_type: */
-#define MSG_NOOP 0
-#define MSG_REGULAR 1
-#define MSG_RETRY 2
-
/*
* The activation descriptor:
* The format of the message to send, plus all accompanying control
* Should be 64 bytes
*/
struct bau_desc {
- struct bau_target_uvhubmask distribution;
+ struct bau_target_nodemask distribution;
/*
* message template, consisting of header and payload:
*/
@@ -273,25 +237,19 @@ struct bau_payload_queue_entry {
unsigned short acknowledge_count; /* filled in by destination */
/* 16 bits, bytes 10-11 */
- /* these next 3 bytes come from bits 58-81 of the message header */
- unsigned short replied_to:1; /* sent as 0 by the source */
- unsigned short msg_type:3; /* software message type */
- unsigned short canceled:1; /* sent as 0 by the source */
- unsigned short unused1:3; /* not currently using */
- /* byte 12 */
+ unsigned short replied_to:1; /* sent as 0 by the source */
+ /* 1 bit */
+ unsigned short unused1:7; /* not currently using */
+ /* 7 bits: byte 12) */
- unsigned char unused2a; /* not currently using */
- /* byte 13 */
- unsigned char unused2; /* not currently using */
- /* byte 14 */
+ unsigned char unused2[2]; /* not currently using */
+ /* bytes 13-14 */
unsigned char sw_ack_vector; /* filled in by the hardware */
/* byte 15 (bits 127:120) */
- unsigned short sequence; /* message sequence number */
- /* bytes 16-17 */
- unsigned char unused4[2]; /* not currently using bytes 18-19 */
- /* bytes 18-19 */
+ unsigned char unused4[3]; /* not currently using bytes 17-19 */
+ /* bytes 17-19 */
int number_of_cpus; /* filled in at destination */
/* 32 bits, bytes 20-23 (aligned) */
@@ -301,93 +259,63 @@ struct bau_payload_queue_entry {
};
/*
- * one per-cpu; to locate the software tables
+ * one for every slot in the destination payload queue
+ */
+struct bau_msg_status {
+ struct bau_local_cpumask seen_by; /* map of cpu's */
+};
+
+/*
+ * one for every slot in the destination software ack resources
+ */
+struct bau_sw_ack_status {
+ struct bau_payload_queue_entry *msg; /* associated message */
+ int watcher; /* cpu monitoring, or -1 */
+};
+
+/*
+ * one on every node and per-cpu; to locate the software tables
*/
struct bau_control {
struct bau_desc *descriptor_base;
+ struct bau_payload_queue_entry *bau_msg_head;
struct bau_payload_queue_entry *va_queue_first;
struct bau_payload_queue_entry *va_queue_last;
- struct bau_payload_queue_entry *bau_msg_head;
- struct bau_control *uvhub_master;
- struct bau_control *socket_master;
- unsigned long timeout_interval;
- atomic_t active_descriptor_count;
- int max_concurrent;
- int max_concurrent_constant;
- int retry_message_scans;
- int plugged_tries;
- int timeout_tries;
- int ipi_attempts;
- int conseccompletes;
- short cpu;
- short uvhub_cpu;
- short uvhub;
- short cpus_in_socket;
- short cpus_in_uvhub;
- unsigned short message_number;
- unsigned short uvhub_quiesce;
- short socket_acknowledge_count[DEST_Q_SIZE];
- cycles_t send_message;
- spinlock_t masks_lock;
- spinlock_t uvhub_lock;
- spinlock_t queue_lock;
+ struct bau_msg_status *msg_statuses;
+ int *watching; /* pointer to array */
};
/*
* This structure is allocated per_cpu for UV TLB shootdown statistics.
*/
struct ptc_stats {
- /* sender statistics */
- unsigned long s_giveup; /* number of fall backs to IPI-style flushes */
- unsigned long s_requestor; /* number of shootdown requests */
- unsigned long s_stimeout; /* source side timeouts */
- unsigned long s_dtimeout; /* destination side timeouts */
- unsigned long s_time; /* time spent in sending side */
- unsigned long s_retriesok; /* successful retries */
- unsigned long s_ntargcpu; /* number of cpus targeted */
- unsigned long s_ntarguvhub; /* number of uvhubs targeted */
- unsigned long s_ntarguvhub16; /* number of times >= 16 target hubs */
- unsigned long s_ntarguvhub8; /* number of times >= 8 target hubs */
- unsigned long s_ntarguvhub4; /* number of times >= 4 target hubs */
- unsigned long s_ntarguvhub2; /* number of times >= 2 target hubs */
- unsigned long s_ntarguvhub1; /* number of times == 1 target hub */
- unsigned long s_resets_plug; /* ipi-style resets from plug state */
- unsigned long s_resets_timeout; /* ipi-style resets from timeouts */
- unsigned long s_busy; /* status stayed busy past s/w timer */
- unsigned long s_throttles; /* waits in throttle */
- unsigned long s_retry_messages; /* retry broadcasts */
- /* destination statistics */
- unsigned long d_alltlb; /* times all tlb's on this cpu were flushed */
- unsigned long d_onetlb; /* times just one tlb on this cpu was flushed */
- unsigned long d_multmsg; /* interrupts with multiple messages */
- unsigned long d_nomsg; /* interrupts with no message */
- unsigned long d_time; /* time spent on destination side */
- unsigned long d_requestee; /* number of messages processed */
- unsigned long d_retries; /* number of retry messages processed */
- unsigned long d_canceled; /* number of messages canceled by retries */
- unsigned long d_nocanceled; /* retries that found nothing to cancel */
- unsigned long d_resets; /* number of ipi-style requests processed */
- unsigned long d_rcanceled; /* number of messages canceled by resets */
+ unsigned long ptc_i; /* number of IPI-style flushes */
+ unsigned long requestor; /* number of nodes this cpu sent to */
+ unsigned long requestee; /* times cpu was remotely requested */
+ unsigned long alltlb; /* times all tlb's on this cpu were flushed */
+ unsigned long onetlb; /* times just one tlb on this cpu was flushed */
+ unsigned long s_retry; /* retries on source side timeouts */
+ unsigned long d_retry; /* retries on destination side timeouts */
+ unsigned long sflush; /* cycles spent in uv_flush_tlb_others */
+ unsigned long dflush; /* cycles spent on destination side */
+ unsigned long retriesok; /* successes on retries */
+ unsigned long nomsg; /* interrupts with no message */
+ unsigned long multmsg; /* interrupts with multiple messages */
+ unsigned long ntargeted;/* nodes targeted */
};
-static inline int bau_uvhub_isset(int uvhub, struct bau_target_uvhubmask *dstp)
+static inline int bau_node_isset(int node, struct bau_target_nodemask *dstp)
{
- return constant_test_bit(uvhub, &dstp->bits[0]);
+ return constant_test_bit(node, &dstp->bits[0]);
}
-static inline void bau_uvhub_set(int uvhub, struct bau_target_uvhubmask *dstp)
+static inline void bau_node_set(int node, struct bau_target_nodemask *dstp)
{
- __set_bit(uvhub, &dstp->bits[0]);
+ __set_bit(node, &dstp->bits[0]);
}
-static inline void bau_uvhubs_clear(struct bau_target_uvhubmask *dstp,
- int nbits)
+static inline void bau_nodes_clear(struct bau_target_nodemask *dstp, int nbits)
{
bitmap_zero(&dstp->bits[0], nbits);
}
-static inline int bau_uvhub_weight(struct bau_target_uvhubmask *dstp)
-{
- return bitmap_weight((unsigned long *)&dstp->bits[0],
- UV_DISTRIBUTION_SIZE);
-}
static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits)
{
@@ -400,35 +328,4 @@ static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits)
extern void uv_bau_message_intr1(void);
extern void uv_bau_timeout_intr1(void);
-struct atomic_short {
- short counter;
-};
-
-/**
- * atomic_read_short - read a short atomic variable
- * @v: pointer of type atomic_short
- *
- * Atomically reads the value of @v.
- */
-static inline int atomic_read_short(const struct atomic_short *v)
-{
- return v->counter;
-}
-
-/**
- * atomic_add_short_return - add and return a short int
- * @i: short value to add
- * @v: pointer of type atomic_short
- *
- * Atomically adds @i to @v and returns @i + @v
- */
-static inline int atomic_add_short_return(short i, struct atomic_short *v)
-{
- short __i = i;
- asm volatile(LOCK_PREFIX "xaddw %0, %1"
- : "+r" (i), "+m" (v->counter)
- : : "memory");
- return i + __i;
-}
-
#endif /* _ASM_X86_UV_UV_BAU_H */
diff --git a/trunk/arch/x86/include/asm/uv/uv_hub.h b/trunk/arch/x86/include/asm/uv/uv_hub.h
index bf6b88ef8eeb..14cc74ba5d23 100644
--- a/trunk/arch/x86/include/asm/uv/uv_hub.h
+++ b/trunk/arch/x86/include/asm/uv/uv_hub.h
@@ -307,7 +307,7 @@ static inline unsigned long uv_read_global_mmr32(int pnode, unsigned long offset
* Access Global MMR space using the MMR space located at the top of physical
* memory.
*/
-static inline volatile void __iomem *uv_global_mmr64_address(int pnode, unsigned long offset)
+static inline unsigned long *uv_global_mmr64_address(int pnode, unsigned long offset)
{
return __va(UV_GLOBAL_MMR64_BASE |
UV_GLOBAL_MMR64_PNODE_BITS(pnode) | offset);
diff --git a/trunk/arch/x86/include/asm/uv/uv_mmrs.h b/trunk/arch/x86/include/asm/uv/uv_mmrs.h
index b2f2d2e05cec..2cae46c7c8a2 100644
--- a/trunk/arch/x86/include/asm/uv/uv_mmrs.h
+++ b/trunk/arch/x86/include/asm/uv/uv_mmrs.h
@@ -1,3 +1,4 @@
+
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -13,26 +14,14 @@
#define UV_MMR_ENABLE (1UL << 63)
-/* ========================================================================= */
-/* UVH_BAU_DATA_BROADCAST */
-/* ========================================================================= */
-#define UVH_BAU_DATA_BROADCAST 0x61688UL
-#define UVH_BAU_DATA_BROADCAST_32 0x0440
-
-#define UVH_BAU_DATA_BROADCAST_ENABLE_SHFT 0
-#define UVH_BAU_DATA_BROADCAST_ENABLE_MASK 0x0000000000000001UL
-
-union uvh_bau_data_broadcast_u {
- unsigned long v;
- struct uvh_bau_data_broadcast_s {
- unsigned long enable : 1; /* RW */
- unsigned long rsvd_1_63: 63; /* */
- } s;
-};
-
/* ========================================================================= */
/* UVH_BAU_DATA_CONFIG */
/* ========================================================================= */
+#define UVH_LB_BAU_MISC_CONTROL 0x320170UL
+#define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15
+#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16
+#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL
+/* 1011 timebase 7 (168millisec) * 3 ticks -> 500ms */
#define UVH_BAU_DATA_CONFIG 0x61680UL
#define UVH_BAU_DATA_CONFIG_32 0x0438
@@ -614,68 +603,6 @@ union uvh_lb_bau_intd_software_acknowledge_u {
#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS 0x0000000000320088UL
#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS_32 0x0a70
-/* ========================================================================= */
-/* UVH_LB_BAU_MISC_CONTROL */
-/* ========================================================================= */
-#define UVH_LB_BAU_MISC_CONTROL 0x320170UL
-#define UVH_LB_BAU_MISC_CONTROL_32 0x00a10
-
-#define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0
-#define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL
-#define UVH_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8
-#define UVH_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL
-#define UVH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9
-#define UVH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL
-#define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10
-#define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL
-#define UVH_LB_BAU_MISC_CONTROL_CSI_AGENT_PRESENCE_VECTOR_SHFT 11
-#define UVH_LB_BAU_MISC_CONTROL_CSI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL
-#define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14
-#define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL
-#define UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15
-#define UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK 0x0000000000008000UL
-#define UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT 16
-#define UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK 0x00000000000f0000UL
-#define UVH_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20
-#define UVH_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL
-#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21
-#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL
-#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22
-#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL
-#define UVH_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23
-#define UVH_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL
-#define UVH_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24
-#define UVH_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL
-#define UVH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27
-#define UVH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL
-#define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28
-#define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL
-#define UVH_LB_BAU_MISC_CONTROL_FUN_SHFT 48
-#define UVH_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL
-
-union uvh_lb_bau_misc_control_u {
- unsigned long v;
- struct uvh_lb_bau_misc_control_s {
- unsigned long rejection_delay : 8; /* RW */
- unsigned long apic_mode : 1; /* RW */
- unsigned long force_broadcast : 1; /* RW */
- unsigned long force_lock_nop : 1; /* RW */
- unsigned long csi_agent_presence_vector : 3; /* RW */
- unsigned long descriptor_fetch_mode : 1; /* RW */
- unsigned long enable_intd_soft_ack_mode : 1; /* RW */
- unsigned long intd_soft_ack_timeout_period : 4; /* RW */
- unsigned long enable_dual_mapping_mode : 1; /* RW */
- unsigned long vga_io_port_decode_enable : 1; /* RW */
- unsigned long vga_io_port_16_bit_decode : 1; /* RW */
- unsigned long suppress_dest_registration : 1; /* RW */
- unsigned long programmed_initial_priority : 3; /* RW */
- unsigned long use_incoming_priority : 1; /* RW */
- unsigned long enable_programmed_initial_priority : 1; /* RW */
- unsigned long rsvd_29_47 : 19; /* */
- unsigned long fun : 16; /* RW */
- } s;
-};
-
/* ========================================================================= */
/* UVH_LB_BAU_SB_ACTIVATION_CONTROL */
/* ========================================================================= */
@@ -753,6 +680,334 @@ union uvh_lb_bau_sb_descriptor_base_u {
} s;
};
+/* ========================================================================= */
+/* UVH_LB_MCAST_AOERR0_RPT_ENABLE */
+/* ========================================================================= */
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE 0x50b20UL
+
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_OBESE_MSG_SHFT 0
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_OBESE_MSG_MASK 0x0000000000000001UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_DATA_SB_ERR_SHFT 1
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_DATA_SB_ERR_MASK 0x0000000000000002UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_NACK_BUFF_PARITY_SHFT 2
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_NACK_BUFF_PARITY_MASK 0x0000000000000004UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_TIMEOUT_SHFT 3
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_TIMEOUT_MASK 0x0000000000000008UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_INACTIVE_REPLY_SHFT 4
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_INACTIVE_REPLY_MASK 0x0000000000000010UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_UPGRADE_ERROR_SHFT 5
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_UPGRADE_ERROR_MASK 0x0000000000000020UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_REG_COUNT_UNDERFLOW_SHFT 6
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_REG_COUNT_UNDERFLOW_MASK 0x0000000000000040UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_REP_OBESE_MSG_SHFT 7
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_REP_OBESE_MSG_MASK 0x0000000000000080UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_RUNT_MSG_SHFT 8
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_RUNT_MSG_MASK 0x0000000000000100UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_OBESE_MSG_SHFT 9
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_OBESE_MSG_MASK 0x0000000000000200UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_DATA_SB_ERR_SHFT 10
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_DATA_SB_ERR_MASK 0x0000000000000400UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_RUNT_MSG_SHFT 11
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_RUNT_MSG_MASK 0x0000000000000800UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_OBESE_MSG_SHFT 12
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_OBESE_MSG_MASK 0x0000000000001000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_DATA_SB_ERR_SHFT 13
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_DATA_SB_ERR_MASK 0x0000000000002000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_COMMAND_ERR_SHFT 14
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_COMMAND_ERR_MASK 0x0000000000004000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_PEND_TIMEOUT_SHFT 15
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_PEND_TIMEOUT_MASK 0x0000000000008000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_RUNT_MSG_SHFT 16
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_RUNT_MSG_MASK 0x0000000000010000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_OBESE_MSG_SHFT 17
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_OBESE_MSG_MASK 0x0000000000020000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_DATA_SB_ERR_SHFT 18
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_DATA_SB_ERR_MASK 0x0000000000040000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_RUNT_MSG_SHFT 19
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_RUNT_MSG_MASK 0x0000000000080000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_OBESE_MSG_SHFT 20
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_OBESE_MSG_MASK 0x0000000000100000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_DATA_SB_ERR_SHFT 21
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_DATA_SB_ERR_MASK 0x0000000000200000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_AMO_TIMEOUT_SHFT 22
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_AMO_TIMEOUT_MASK 0x0000000000400000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_PUT_TIMEOUT_SHFT 23
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_PUT_TIMEOUT_MASK 0x0000000000800000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_SPURIOUS_EVENT_SHFT 24
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_SPURIOUS_EVENT_MASK 0x0000000001000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IOH_DESTINATION_TABLE_PARITY_SHFT 25
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IOH_DESTINATION_TABLE_PARITY_MASK 0x0000000002000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_HAD_ERROR_REPLY_SHFT 26
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_HAD_ERROR_REPLY_MASK 0x0000000004000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_TIMEOUT_SHFT 27
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_TIMEOUT_MASK 0x0000000008000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_LOCK_MANAGER_HAD_ERROR_REPLY_SHFT 28
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_LOCK_MANAGER_HAD_ERROR_REPLY_MASK 0x0000000010000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_HAD_ERROR_REPLY_SHFT 29
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_HAD_ERROR_REPLY_MASK 0x0000000020000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_TIMEOUT_SHFT 30
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_TIMEOUT_MASK 0x0000000040000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SB_ACTIVATION_OVERRUN_SHFT 31
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SB_ACTIVATION_OVERRUN_MASK 0x0000000080000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_HAD_ERROR_REPLY_SHFT 32
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_HAD_ERROR_REPLY_MASK 0x0000000100000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_TIMEOUT_SHFT 33
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_TIMEOUT_MASK 0x0000000200000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_0_PARITY_SHFT 34
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_0_PARITY_MASK 0x0000000400000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_1_PARITY_SHFT 35
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_1_PARITY_MASK 0x0000000800000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SOCKET_DESTINATION_TABLE_PARITY_SHFT 36
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SOCKET_DESTINATION_TABLE_PARITY_MASK 0x0000001000000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_BAU_REPLY_PAYLOAD_CORRUPTION_SHFT 37
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_BAU_REPLY_PAYLOAD_CORRUPTION_MASK 0x0000002000000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IO_PORT_DESTINATION_TABLE_PARITY_SHFT 38
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IO_PORT_DESTINATION_TABLE_PARITY_MASK 0x0000004000000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INTD_SOFT_ACK_TIMEOUT_SHFT 39
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INTD_SOFT_ACK_TIMEOUT_MASK 0x0000008000000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_OBESE_MSG_SHFT 40
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_OBESE_MSG_MASK 0x0000010000000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_COMMAND_ERR_SHFT 41
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_COMMAND_ERR_MASK 0x0000020000000000UL
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_TIMEOUT_SHFT 42
+#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_TIMEOUT_MASK 0x0000040000000000UL
+
+union uvh_lb_mcast_aoerr0_rpt_enable_u {
+ unsigned long v;
+ struct uvh_lb_mcast_aoerr0_rpt_enable_s {
+ unsigned long mcast_obese_msg : 1; /* RW */
+ unsigned long mcast_data_sb_err : 1; /* RW */
+ unsigned long mcast_nack_buff_parity : 1; /* RW */
+ unsigned long mcast_timeout : 1; /* RW */
+ unsigned long mcast_inactive_reply : 1; /* RW */
+ unsigned long mcast_upgrade_error : 1; /* RW */
+ unsigned long mcast_reg_count_underflow : 1; /* RW */
+ unsigned long mcast_rep_obese_msg : 1; /* RW */
+ unsigned long ucache_req_runt_msg : 1; /* RW */
+ unsigned long ucache_req_obese_msg : 1; /* RW */
+ unsigned long ucache_req_data_sb_err : 1; /* RW */
+ unsigned long ucache_rep_runt_msg : 1; /* RW */
+ unsigned long ucache_rep_obese_msg : 1; /* RW */
+ unsigned long ucache_rep_data_sb_err : 1; /* RW */
+ unsigned long ucache_rep_command_err : 1; /* RW */
+ unsigned long ucache_pend_timeout : 1; /* RW */
+ unsigned long macc_req_runt_msg : 1; /* RW */
+ unsigned long macc_req_obese_msg : 1; /* RW */
+ unsigned long macc_req_data_sb_err : 1; /* RW */
+ unsigned long macc_rep_runt_msg : 1; /* RW */
+ unsigned long macc_rep_obese_msg : 1; /* RW */
+ unsigned long macc_rep_data_sb_err : 1; /* RW */
+ unsigned long macc_amo_timeout : 1; /* RW */
+ unsigned long macc_put_timeout : 1; /* RW */
+ unsigned long macc_spurious_event : 1; /* RW */
+ unsigned long ioh_destination_table_parity : 1; /* RW */
+ unsigned long get_had_error_reply : 1; /* RW */
+ unsigned long get_timeout : 1; /* RW */
+ unsigned long lock_manager_had_error_reply : 1; /* RW */
+ unsigned long put_had_error_reply : 1; /* RW */
+ unsigned long put_timeout : 1; /* RW */
+ unsigned long sb_activation_overrun : 1; /* RW */
+ unsigned long completed_gb_activation_had_error_reply : 1; /* RW */
+ unsigned long completed_gb_activation_timeout : 1; /* RW */
+ unsigned long descriptor_buffer_0_parity : 1; /* RW */
+ unsigned long descriptor_buffer_1_parity : 1; /* RW */
+ unsigned long socket_destination_table_parity : 1; /* RW */
+ unsigned long bau_reply_payload_corruption : 1; /* RW */
+ unsigned long io_port_destination_table_parity : 1; /* RW */
+ unsigned long intd_soft_ack_timeout : 1; /* RW */
+ unsigned long int_rep_obese_msg : 1; /* RW */
+ unsigned long int_rep_command_err : 1; /* RW */
+ unsigned long int_timeout : 1; /* RW */
+ unsigned long rsvd_43_63 : 21; /* */
+ } s;
+};
+
+/* ========================================================================= */
+/* UVH_LOCAL_INT0_CONFIG */
+/* ========================================================================= */
+#define UVH_LOCAL_INT0_CONFIG 0x61000UL
+
+#define UVH_LOCAL_INT0_CONFIG_VECTOR_SHFT 0
+#define UVH_LOCAL_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_LOCAL_INT0_CONFIG_DM_SHFT 8
+#define UVH_LOCAL_INT0_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_LOCAL_INT0_CONFIG_DESTMODE_SHFT 11
+#define UVH_LOCAL_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_LOCAL_INT0_CONFIG_STATUS_SHFT 12
+#define UVH_LOCAL_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_LOCAL_INT0_CONFIG_P_SHFT 13
+#define UVH_LOCAL_INT0_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_LOCAL_INT0_CONFIG_T_SHFT 15
+#define UVH_LOCAL_INT0_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_LOCAL_INT0_CONFIG_M_SHFT 16
+#define UVH_LOCAL_INT0_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_LOCAL_INT0_CONFIG_APIC_ID_SHFT 32
+#define UVH_LOCAL_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_local_int0_config_u {
+ unsigned long v;
+ struct uvh_local_int0_config_s {
+ unsigned long vector_ : 8; /* RW */
+ unsigned long dm : 3; /* RW */
+ unsigned long destmode : 1; /* RW */
+ unsigned long status : 1; /* RO */
+ unsigned long p : 1; /* RO */
+ unsigned long rsvd_14 : 1; /* */
+ unsigned long t : 1; /* RO */
+ unsigned long m : 1; /* RW */
+ unsigned long rsvd_17_31: 15; /* */
+ unsigned long apic_id : 32; /* RW */
+ } s;
+};
+
+/* ========================================================================= */
+/* UVH_LOCAL_INT0_ENABLE */
+/* ========================================================================= */
+#define UVH_LOCAL_INT0_ENABLE 0x65000UL
+
+#define UVH_LOCAL_INT0_ENABLE_LB_HCERR_SHFT 0
+#define UVH_LOCAL_INT0_ENABLE_LB_HCERR_MASK 0x0000000000000001UL
+#define UVH_LOCAL_INT0_ENABLE_GR0_HCERR_SHFT 1
+#define UVH_LOCAL_INT0_ENABLE_GR0_HCERR_MASK 0x0000000000000002UL
+#define UVH_LOCAL_INT0_ENABLE_GR1_HCERR_SHFT 2
+#define UVH_LOCAL_INT0_ENABLE_GR1_HCERR_MASK 0x0000000000000004UL
+#define UVH_LOCAL_INT0_ENABLE_LH_HCERR_SHFT 3
+#define UVH_LOCAL_INT0_ENABLE_LH_HCERR_MASK 0x0000000000000008UL
+#define UVH_LOCAL_INT0_ENABLE_RH_HCERR_SHFT 4
+#define UVH_LOCAL_INT0_ENABLE_RH_HCERR_MASK 0x0000000000000010UL
+#define UVH_LOCAL_INT0_ENABLE_XN_HCERR_SHFT 5
+#define UVH_LOCAL_INT0_ENABLE_XN_HCERR_MASK 0x0000000000000020UL
+#define UVH_LOCAL_INT0_ENABLE_SI_HCERR_SHFT 6
+#define UVH_LOCAL_INT0_ENABLE_SI_HCERR_MASK 0x0000000000000040UL
+#define UVH_LOCAL_INT0_ENABLE_LB_AOERR0_SHFT 7
+#define UVH_LOCAL_INT0_ENABLE_LB_AOERR0_MASK 0x0000000000000080UL
+#define UVH_LOCAL_INT0_ENABLE_GR0_AOERR0_SHFT 8
+#define UVH_LOCAL_INT0_ENABLE_GR0_AOERR0_MASK 0x0000000000000100UL
+#define UVH_LOCAL_INT0_ENABLE_GR1_AOERR0_SHFT 9
+#define UVH_LOCAL_INT0_ENABLE_GR1_AOERR0_MASK 0x0000000000000200UL
+#define UVH_LOCAL_INT0_ENABLE_LH_AOERR0_SHFT 10
+#define UVH_LOCAL_INT0_ENABLE_LH_AOERR0_MASK 0x0000000000000400UL
+#define UVH_LOCAL_INT0_ENABLE_RH_AOERR0_SHFT 11
+#define UVH_LOCAL_INT0_ENABLE_RH_AOERR0_MASK 0x0000000000000800UL
+#define UVH_LOCAL_INT0_ENABLE_XN_AOERR0_SHFT 12
+#define UVH_LOCAL_INT0_ENABLE_XN_AOERR0_MASK 0x0000000000001000UL
+#define UVH_LOCAL_INT0_ENABLE_SI_AOERR0_SHFT 13
+#define UVH_LOCAL_INT0_ENABLE_SI_AOERR0_MASK 0x0000000000002000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_AOERR1_SHFT 14
+#define UVH_LOCAL_INT0_ENABLE_LB_AOERR1_MASK 0x0000000000004000UL
+#define UVH_LOCAL_INT0_ENABLE_GR0_AOERR1_SHFT 15
+#define UVH_LOCAL_INT0_ENABLE_GR0_AOERR1_MASK 0x0000000000008000UL
+#define UVH_LOCAL_INT0_ENABLE_GR1_AOERR1_SHFT 16
+#define UVH_LOCAL_INT0_ENABLE_GR1_AOERR1_MASK 0x0000000000010000UL
+#define UVH_LOCAL_INT0_ENABLE_LH_AOERR1_SHFT 17
+#define UVH_LOCAL_INT0_ENABLE_LH_AOERR1_MASK 0x0000000000020000UL
+#define UVH_LOCAL_INT0_ENABLE_RH_AOERR1_SHFT 18
+#define UVH_LOCAL_INT0_ENABLE_RH_AOERR1_MASK 0x0000000000040000UL
+#define UVH_LOCAL_INT0_ENABLE_XN_AOERR1_SHFT 19
+#define UVH_LOCAL_INT0_ENABLE_XN_AOERR1_MASK 0x0000000000080000UL
+#define UVH_LOCAL_INT0_ENABLE_SI_AOERR1_SHFT 20
+#define UVH_LOCAL_INT0_ENABLE_SI_AOERR1_MASK 0x0000000000100000UL
+#define UVH_LOCAL_INT0_ENABLE_RH_VPI_INT_SHFT 21
+#define UVH_LOCAL_INT0_ENABLE_RH_VPI_INT_MASK 0x0000000000200000UL
+#define UVH_LOCAL_INT0_ENABLE_SYSTEM_SHUTDOWN_INT_SHFT 22
+#define UVH_LOCAL_INT0_ENABLE_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000400000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_0_SHFT 23
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_0_MASK 0x0000000000800000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_1_SHFT 24
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_1_MASK 0x0000000001000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_2_SHFT 25
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_2_MASK 0x0000000002000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_3_SHFT 26
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_3_MASK 0x0000000004000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_4_SHFT 27
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_4_MASK 0x0000000008000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_5_SHFT 28
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_5_MASK 0x0000000010000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_6_SHFT 29
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_6_MASK 0x0000000020000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_7_SHFT 30
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_7_MASK 0x0000000040000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_8_SHFT 31
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_8_MASK 0x0000000080000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_9_SHFT 32
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_9_MASK 0x0000000100000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_10_SHFT 33
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_10_MASK 0x0000000200000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_11_SHFT 34
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_11_MASK 0x0000000400000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_12_SHFT 35
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_12_MASK 0x0000000800000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_13_SHFT 36
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_13_MASK 0x0000001000000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_14_SHFT 37
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_14_MASK 0x0000002000000000UL
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_15_SHFT 38
+#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_15_MASK 0x0000004000000000UL
+#define UVH_LOCAL_INT0_ENABLE_L1_NMI_INT_SHFT 39
+#define UVH_LOCAL_INT0_ENABLE_L1_NMI_INT_MASK 0x0000008000000000UL
+#define UVH_LOCAL_INT0_ENABLE_STOP_CLOCK_SHFT 40
+#define UVH_LOCAL_INT0_ENABLE_STOP_CLOCK_MASK 0x0000010000000000UL
+#define UVH_LOCAL_INT0_ENABLE_ASIC_TO_L1_SHFT 41
+#define UVH_LOCAL_INT0_ENABLE_ASIC_TO_L1_MASK 0x0000020000000000UL
+#define UVH_LOCAL_INT0_ENABLE_L1_TO_ASIC_SHFT 42
+#define UVH_LOCAL_INT0_ENABLE_L1_TO_ASIC_MASK 0x0000040000000000UL
+#define UVH_LOCAL_INT0_ENABLE_LTC_INT_SHFT 43
+#define UVH_LOCAL_INT0_ENABLE_LTC_INT_MASK 0x0000080000000000UL
+#define UVH_LOCAL_INT0_ENABLE_LA_SEQ_TRIGGER_SHFT 44
+#define UVH_LOCAL_INT0_ENABLE_LA_SEQ_TRIGGER_MASK 0x0000100000000000UL
+
+union uvh_local_int0_enable_u {
+ unsigned long v;
+ struct uvh_local_int0_enable_s {
+ unsigned long lb_hcerr : 1; /* RW */
+ unsigned long gr0_hcerr : 1; /* RW */
+ unsigned long gr1_hcerr : 1; /* RW */
+ unsigned long lh_hcerr : 1; /* RW */
+ unsigned long rh_hcerr : 1; /* RW */
+ unsigned long xn_hcerr : 1; /* RW */
+ unsigned long si_hcerr : 1; /* RW */
+ unsigned long lb_aoerr0 : 1; /* RW */
+ unsigned long gr0_aoerr0 : 1; /* RW */
+ unsigned long gr1_aoerr0 : 1; /* RW */
+ unsigned long lh_aoerr0 : 1; /* RW */
+ unsigned long rh_aoerr0 : 1; /* RW */
+ unsigned long xn_aoerr0 : 1; /* RW */
+ unsigned long si_aoerr0 : 1; /* RW */
+ unsigned long lb_aoerr1 : 1; /* RW */
+ unsigned long gr0_aoerr1 : 1; /* RW */
+ unsigned long gr1_aoerr1 : 1; /* RW */
+ unsigned long lh_aoerr1 : 1; /* RW */
+ unsigned long rh_aoerr1 : 1; /* RW */
+ unsigned long xn_aoerr1 : 1; /* RW */
+ unsigned long si_aoerr1 : 1; /* RW */
+ unsigned long rh_vpi_int : 1; /* RW */
+ unsigned long system_shutdown_int : 1; /* RW */
+ unsigned long lb_irq_int_0 : 1; /* RW */
+ unsigned long lb_irq_int_1 : 1; /* RW */
+ unsigned long lb_irq_int_2 : 1; /* RW */
+ unsigned long lb_irq_int_3 : 1; /* RW */
+ unsigned long lb_irq_int_4 : 1; /* RW */
+ unsigned long lb_irq_int_5 : 1; /* RW */
+ unsigned long lb_irq_int_6 : 1; /* RW */
+ unsigned long lb_irq_int_7 : 1; /* RW */
+ unsigned long lb_irq_int_8 : 1; /* RW */
+ unsigned long lb_irq_int_9 : 1; /* RW */
+ unsigned long lb_irq_int_10 : 1; /* RW */
+ unsigned long lb_irq_int_11 : 1; /* RW */
+ unsigned long lb_irq_int_12 : 1; /* RW */
+ unsigned long lb_irq_int_13 : 1; /* RW */
+ unsigned long lb_irq_int_14 : 1; /* RW */
+ unsigned long lb_irq_int_15 : 1; /* RW */
+ unsigned long l1_nmi_int : 1; /* RW */
+ unsigned long stop_clock : 1; /* RW */
+ unsigned long asic_to_l1 : 1; /* RW */
+ unsigned long l1_to_asic : 1; /* RW */
+ unsigned long ltc_int : 1; /* RW */
+ unsigned long la_seq_trigger : 1; /* RW */
+ unsigned long rsvd_45_63 : 19; /* */
+ } s;
+};
+
/* ========================================================================= */
/* UVH_NODE_ID */
/* ========================================================================= */
@@ -856,6 +1111,26 @@ union uvh_rh_gam_alias210_redirect_config_2_mmr_u {
} s;
};
+/* ========================================================================= */
+/* UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR */
+/* ========================================================================= */
+#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR 0x1600020UL
+
+#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_SHFT 26
+#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL
+#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
+#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL
+
+union uvh_rh_gam_cfg_overlay_config_mmr_u {
+ unsigned long v;
+ struct uvh_rh_gam_cfg_overlay_config_mmr_s {
+ unsigned long rsvd_0_25: 26; /* */
+ unsigned long base : 20; /* RW */
+ unsigned long rsvd_46_62: 17; /* */
+ unsigned long enable : 1; /* RW */
+ } s;
+};
+
/* ========================================================================= */
/* UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR */
/* ========================================================================= */
@@ -987,6 +1262,101 @@ union uvh_rtc1_int_config_u {
} s;
};
+/* ========================================================================= */
+/* UVH_RTC2_INT_CONFIG */
+/* ========================================================================= */
+#define UVH_RTC2_INT_CONFIG 0x61600UL
+
+#define UVH_RTC2_INT_CONFIG_VECTOR_SHFT 0
+#define UVH_RTC2_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_RTC2_INT_CONFIG_DM_SHFT 8
+#define UVH_RTC2_INT_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_RTC2_INT_CONFIG_DESTMODE_SHFT 11
+#define UVH_RTC2_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_RTC2_INT_CONFIG_STATUS_SHFT 12
+#define UVH_RTC2_INT_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_RTC2_INT_CONFIG_P_SHFT 13
+#define UVH_RTC2_INT_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_RTC2_INT_CONFIG_T_SHFT 15
+#define UVH_RTC2_INT_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_RTC2_INT_CONFIG_M_SHFT 16
+#define UVH_RTC2_INT_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_RTC2_INT_CONFIG_APIC_ID_SHFT 32
+#define UVH_RTC2_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_rtc2_int_config_u {
+ unsigned long v;
+ struct uvh_rtc2_int_config_s {
+ unsigned long vector_ : 8; /* RW */
+ unsigned long dm : 3; /* RW */
+ unsigned long destmode : 1; /* RW */
+ unsigned long status : 1; /* RO */
+ unsigned long p : 1; /* RO */
+ unsigned long rsvd_14 : 1; /* */
+ unsigned long t : 1; /* RO */
+ unsigned long m : 1; /* RW */
+ unsigned long rsvd_17_31: 15; /* */
+ unsigned long apic_id : 32; /* RW */
+ } s;
+};
+
+/* ========================================================================= */
+/* UVH_RTC3_INT_CONFIG */
+/* ========================================================================= */
+#define UVH_RTC3_INT_CONFIG 0x61640UL
+
+#define UVH_RTC3_INT_CONFIG_VECTOR_SHFT 0
+#define UVH_RTC3_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_RTC3_INT_CONFIG_DM_SHFT 8
+#define UVH_RTC3_INT_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_RTC3_INT_CONFIG_DESTMODE_SHFT 11
+#define UVH_RTC3_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_RTC3_INT_CONFIG_STATUS_SHFT 12
+#define UVH_RTC3_INT_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_RTC3_INT_CONFIG_P_SHFT 13
+#define UVH_RTC3_INT_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_RTC3_INT_CONFIG_T_SHFT 15
+#define UVH_RTC3_INT_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_RTC3_INT_CONFIG_M_SHFT 16
+#define UVH_RTC3_INT_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_RTC3_INT_CONFIG_APIC_ID_SHFT 32
+#define UVH_RTC3_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_rtc3_int_config_u {
+ unsigned long v;
+ struct uvh_rtc3_int_config_s {
+ unsigned long vector_ : 8; /* RW */
+ unsigned long dm : 3; /* RW */
+ unsigned long destmode : 1; /* RW */
+ unsigned long status : 1; /* RO */
+ unsigned long p : 1; /* RO */
+ unsigned long rsvd_14 : 1; /* */
+ unsigned long t : 1; /* RO */
+ unsigned long m : 1; /* RW */
+ unsigned long rsvd_17_31: 15; /* */
+ unsigned long apic_id : 32; /* RW */
+ } s;
+};
+
+/* ========================================================================= */
+/* UVH_RTC_INC_RATIO */
+/* ========================================================================= */
+#define UVH_RTC_INC_RATIO 0x350000UL
+
+#define UVH_RTC_INC_RATIO_FRACTION_SHFT 0
+#define UVH_RTC_INC_RATIO_FRACTION_MASK 0x00000000000fffffUL
+#define UVH_RTC_INC_RATIO_RATIO_SHFT 20
+#define UVH_RTC_INC_RATIO_RATIO_MASK 0x0000000000700000UL
+
+union uvh_rtc_inc_ratio_u {
+ unsigned long v;
+ struct uvh_rtc_inc_ratio_s {
+ unsigned long fraction : 20; /* RW */
+ unsigned long ratio : 3; /* RW */
+ unsigned long rsvd_23_63: 41; /* */
+ } s;
+};
+
/* ========================================================================= */
/* UVH_SI_ADDR_MAP_CONFIG */
/* ========================================================================= */
diff --git a/trunk/arch/x86/include/asm/vmware.h b/trunk/arch/x86/include/asm/vmware.h
new file mode 100644
index 000000000000..e49ed6d2fd4e
--- /dev/null
+++ b/trunk/arch/x86/include/asm/vmware.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2008, VMware, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+#ifndef ASM_X86__VMWARE_H
+#define ASM_X86__VMWARE_H
+
+extern void vmware_platform_setup(void);
+extern int vmware_platform(void);
+extern void vmware_set_feature_bits(struct cpuinfo_x86 *c);
+
+#endif
diff --git a/trunk/arch/x86/include/asm/xsave.h b/trunk/arch/x86/include/asm/xsave.h
index 2c4390cae228..ddc04ccad03b 100644
--- a/trunk/arch/x86/include/asm/xsave.h
+++ b/trunk/arch/x86/include/asm/xsave.h
@@ -37,9 +37,8 @@ extern int check_for_xstate(struct i387_fxsave_struct __user *buf,
void __user *fpstate,
struct _fpx_sw_bytes *sw);
-static inline int fpu_xrstor_checking(struct fpu *fpu)
+static inline int xrstor_checking(struct xsave_struct *fx)
{
- struct xsave_struct *fx = &fpu->state->xsave;
int err;
asm volatile("1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n\t"
@@ -111,12 +110,12 @@ static inline void xrstor_state(struct xsave_struct *fx, u64 mask)
: "memory");
}
-static inline void fpu_xsave(struct fpu *fpu)
+static inline void xsave(struct task_struct *tsk)
{
/* This, however, we can work around by forcing the compiler to select
an addressing mode that doesn't require extended registers. */
__asm__ __volatile__(".byte " REX_PREFIX "0x0f,0xae,0x27"
- : : "D" (&(fpu->state->xsave)),
+ : : "D" (&(tsk->thread.xstate->xsave)),
"a" (-1), "d"(-1) : "memory");
}
#endif
diff --git a/trunk/arch/x86/kernel/Makefile b/trunk/arch/x86/kernel/Makefile
index e77b22083721..4c58352209e0 100644
--- a/trunk/arch/x86/kernel/Makefile
+++ b/trunk/arch/x86/kernel/Makefile
@@ -47,6 +47,8 @@ obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
obj-y += process.o
obj-y += i387.o xsave.o
obj-y += ptrace.o
+obj-$(CONFIG_X86_DS) += ds.o
+obj-$(CONFIG_X86_DS_SELFTEST) += ds_selftest.o
obj-$(CONFIG_X86_32) += tls.o
obj-$(CONFIG_IA32_EMULATION) += tls.o
obj-y += step.o
diff --git a/trunk/arch/x86/kernel/acpi/boot.c b/trunk/arch/x86/kernel/acpi/boot.c
index 9a5ed58f09dc..cd40aba6aa95 100644
--- a/trunk/arch/x86/kernel/acpi/boot.c
+++ b/trunk/arch/x86/kernel/acpi/boot.c
@@ -93,53 +93,6 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
-/*
- * ISA irqs by default are the first 16 gsis but can be
- * any gsi as specified by an interrupt source override.
- */
-static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
-};
-
-static unsigned int gsi_to_irq(unsigned int gsi)
-{
- unsigned int irq = gsi + NR_IRQS_LEGACY;
- unsigned int i;
-
- for (i = 0; i < NR_IRQS_LEGACY; i++) {
- if (isa_irq_to_gsi[i] == gsi) {
- return i;
- }
- }
-
- /* Provide an identity mapping of gsi == irq
- * except on truly weird platforms that have
- * non isa irqs in the first 16 gsis.
- */
- if (gsi >= NR_IRQS_LEGACY)
- irq = gsi;
- else
- irq = gsi_end + 1 + gsi;
-
- return irq;
-}
-
-static u32 irq_to_gsi(int irq)
-{
- unsigned int gsi;
-
- if (irq < NR_IRQS_LEGACY)
- gsi = isa_irq_to_gsi[irq];
- else if (irq <= gsi_end)
- gsi = irq;
- else if (irq <= (gsi_end + NR_IRQS_LEGACY))
- gsi = irq - gsi_end;
- else
- gsi = 0xffffffff;
-
- return gsi;
-}
-
/*
* Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
* to map the target physical address. The problem is that set_fixmap()
@@ -360,7 +313,7 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
/*
* Parse Interrupt Source Override for the ACPI SCI
*/
-static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, u32 gsi)
+static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
{
if (trigger == 0) /* compatible SCI trigger is level */
trigger = 3;
@@ -380,7 +333,7 @@ static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger,
* If GSI is < 16, this will update its flags,
* else it will create a new mp_irqs[] entry.
*/
- mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
+ mp_override_legacy_irq(gsi, polarity, trigger, gsi);
/*
* stash over-ride to indicate we've been here
@@ -404,10 +357,9 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
acpi_table_print_madt_entry(header);
if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) {
- acpi_sci_ioapic_setup(intsrc->source_irq,
+ acpi_sci_ioapic_setup(intsrc->global_irq,
intsrc->inti_flags & ACPI_MADT_POLARITY_MASK,
- (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2,
- intsrc->global_irq);
+ (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
return 0;
}
@@ -496,7 +448,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
{
- *irq = gsi_to_irq(gsi);
+ *irq = gsi;
#ifdef CONFIG_X86_IO_APIC
if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
@@ -506,14 +458,6 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
return 0;
}
-int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
-{
- if (isa_irq >= 16)
- return -1;
- *gsi = irq_to_gsi(isa_irq);
- return 0;
-}
-
/*
* success: return IRQ number (>=0)
* failure: return < 0
@@ -538,7 +482,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
}
#endif
- irq = gsi_to_irq(plat_gsi);
+ irq = plat_gsi;
return irq;
}
@@ -923,6 +867,29 @@ static int __init acpi_parse_madt_lapic_entries(void)
extern int es7000_plat;
#endif
+int __init acpi_probe_gsi(void)
+{
+ int idx;
+ int gsi;
+ int max_gsi = 0;
+
+ if (acpi_disabled)
+ return 0;
+
+ if (!acpi_ioapic)
+ return 0;
+
+ max_gsi = 0;
+ for (idx = 0; idx < nr_ioapics; idx++) {
+ gsi = mp_gsi_routing[idx].gsi_end;
+
+ if (gsi > max_gsi)
+ max_gsi = gsi;
+ }
+
+ return max_gsi + 1;
+}
+
static void assign_to_mp_irq(struct mpc_intsrc *m,
struct mpc_intsrc *mp_irq)
{
@@ -980,13 +947,13 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
mp_irq.dstirq = pin; /* INTIN# */
save_mp_irq(&mp_irq);
-
- isa_irq_to_gsi[bus_irq] = gsi;
}
void __init mp_config_acpi_legacy_irqs(void)
{
int i;
+ int ioapic;
+ unsigned int dstapic;
struct mpc_intsrc mp_irq;
#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
@@ -1006,28 +973,20 @@ void __init mp_config_acpi_legacy_irqs(void)
return;
#endif
+ /*
+ * Locate the IOAPIC that manages the ISA IRQs (0-15).
+ */
+ ioapic = mp_find_ioapic(0);
+ if (ioapic < 0)
+ return;
+ dstapic = mp_ioapics[ioapic].apicid;
+
/*
* Use the default configuration for the IRQs 0-15. Unless
* overridden by (MADT) interrupt source override entries.
*/
for (i = 0; i < 16; i++) {
- int ioapic, pin;
- unsigned int dstapic;
int idx;
- u32 gsi;
-
- /* Locate the gsi that irq i maps to. */
- if (acpi_isa_irq_to_gsi(i, &gsi))
- continue;
-
- /*
- * Locate the IOAPIC that manages the ISA IRQ.
- */
- ioapic = mp_find_ioapic(gsi);
- if (ioapic < 0)
- continue;
- pin = mp_find_ioapic_pin(ioapic, gsi);
- dstapic = mp_ioapics[ioapic].apicid;
for (idx = 0; idx < mp_irq_entries; idx++) {
struct mpc_intsrc *irq = mp_irqs + idx;
@@ -1037,7 +996,7 @@ void __init mp_config_acpi_legacy_irqs(void)
break;
/* Do we already have a mapping for this IOAPIC pin */
- if (irq->dstapic == dstapic && irq->dstirq == pin)
+ if (irq->dstapic == dstapic && irq->dstirq == i)
break;
}
@@ -1052,7 +1011,7 @@ void __init mp_config_acpi_legacy_irqs(void)
mp_irq.dstapic = dstapic;
mp_irq.irqtype = mp_INT;
mp_irq.srcbusirq = i; /* Identity mapped */
- mp_irq.dstirq = pin;
+ mp_irq.dstirq = i;
save_mp_irq(&mp_irq);
}
@@ -1117,6 +1076,11 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
ioapic_pin = mp_find_ioapic_pin(ioapic, gsi);
+#ifdef CONFIG_X86_32
+ if (ioapic_renumber_irq)
+ gsi = ioapic_renumber_irq(ioapic, gsi);
+#endif
+
if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
printk(KERN_ERR "Invalid reference to IOAPIC pin "
"%d-%d\n", mp_ioapics[ioapic].apicid,
@@ -1130,7 +1094,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
- io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
+ io_apic_set_pci_routing(dev, gsi, &irq_attr);
return gsi;
}
@@ -1190,8 +1154,7 @@ static int __init acpi_parse_madt_ioapic_entries(void)
* pretend we got one so we can set the SCI flags.
*/
if (!acpi_sci_override_gsi)
- acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0,
- acpi_gbl_FADT.sci_interrupt);
+ acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
/* Fill in identity legacy mappings where no override */
mp_config_acpi_legacy_irqs();
diff --git a/trunk/arch/x86/kernel/alternative.c b/trunk/arch/x86/kernel/alternative.c
index 70237732a6c7..1a160d5d44d0 100644
--- a/trunk/arch/x86/kernel/alternative.c
+++ b/trunk/arch/x86/kernel/alternative.c
@@ -194,7 +194,7 @@ static void __init_or_module add_nops(void *insns, unsigned int len)
}
extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
-extern s32 __smp_locks[], __smp_locks_end[];
+extern u8 *__smp_locks[], *__smp_locks_end[];
static void *text_poke_early(void *addr, const void *opcode, size_t len);
/* Replace instructions with better alternatives for this CPU type.
@@ -235,41 +235,37 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
#ifdef CONFIG_SMP
-static void alternatives_smp_lock(const s32 *start, const s32 *end,
- u8 *text, u8 *text_end)
+static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
{
- const s32 *poff;
+ u8 **ptr;
mutex_lock(&text_mutex);
- for (poff = start; poff < end; poff++) {
- u8 *ptr = (u8 *)poff + *poff;
-
- if (!*poff || ptr < text || ptr >= text_end)
+ for (ptr = start; ptr < end; ptr++) {
+ if (*ptr < text)
+ continue;
+ if (*ptr > text_end)
continue;
/* turn DS segment override prefix into lock prefix */
- if (*ptr == 0x3e)
- text_poke(ptr, ((unsigned char []){0xf0}), 1);
+ text_poke(*ptr, ((unsigned char []){0xf0}), 1);
};
mutex_unlock(&text_mutex);
}
-static void alternatives_smp_unlock(const s32 *start, const s32 *end,
- u8 *text, u8 *text_end)
+static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
{
- const s32 *poff;
+ u8 **ptr;
if (noreplace_smp)
return;
mutex_lock(&text_mutex);
- for (poff = start; poff < end; poff++) {
- u8 *ptr = (u8 *)poff + *poff;
-
- if (!*poff || ptr < text || ptr >= text_end)
+ for (ptr = start; ptr < end; ptr++) {
+ if (*ptr < text)
+ continue;
+ if (*ptr > text_end)
continue;
/* turn lock prefix into DS segment override prefix */
- if (*ptr == 0xf0)
- text_poke(ptr, ((unsigned char []){0x3E}), 1);
+ text_poke(*ptr, ((unsigned char []){0x3E}), 1);
};
mutex_unlock(&text_mutex);
}
@@ -280,8 +276,8 @@ struct smp_alt_module {
char *name;
/* ptrs to lock prefixes */
- const s32 *locks;
- const s32 *locks_end;
+ u8 **locks;
+ u8 **locks_end;
/* .text segment, needed to avoid patching init code ;) */
u8 *text;
@@ -402,19 +398,16 @@ void alternatives_smp_switch(int smp)
int alternatives_text_reserved(void *start, void *end)
{
struct smp_alt_module *mod;
- const s32 *poff;
+ u8 **ptr;
u8 *text_start = start;
u8 *text_end = end;
list_for_each_entry(mod, &smp_alt_modules, next) {
if (mod->text > text_end || mod->text_end < text_start)
continue;
- for (poff = mod->locks; poff < mod->locks_end; poff++) {
- const u8 *ptr = (const u8 *)poff + *poff;
-
- if (text_start <= ptr && text_end > ptr)
+ for (ptr = mod->locks; ptr < mod->locks_end; ptr++)
+ if (text_start <= *ptr && text_end >= *ptr)
return 1;
- }
}
return 0;
diff --git a/trunk/arch/x86/kernel/amd_iommu.c b/trunk/arch/x86/kernel/amd_iommu.c
index fa5a1474cd18..f854d89b7edf 100644
--- a/trunk/arch/x86/kernel/amd_iommu.c
+++ b/trunk/arch/x86/kernel/amd_iommu.c
@@ -731,22 +731,18 @@ static bool increase_address_space(struct protection_domain *domain,
static u64 *alloc_pte(struct protection_domain *domain,
unsigned long address,
- unsigned long page_size,
+ int end_lvl,
u64 **pte_page,
gfp_t gfp)
{
- int level, end_lvl;
u64 *pte, *page;
-
- BUG_ON(!is_power_of_2(page_size));
+ int level;
while (address > PM_LEVEL_SIZE(domain->mode))
increase_address_space(domain, gfp);
- level = domain->mode - 1;
- pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
- address = PAGE_SIZE_ALIGN(address, page_size);
- end_lvl = PAGE_SIZE_LEVEL(page_size);
+ level = domain->mode - 1;
+ pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
while (level > end_lvl) {
if (!IOMMU_PTE_PRESENT(*pte)) {
@@ -756,10 +752,6 @@ static u64 *alloc_pte(struct protection_domain *domain,
*pte = PM_LEVEL_PDE(level, virt_to_phys(page));
}
- /* No level skipping support yet */
- if (PM_PTE_LEVEL(*pte) != level)
- return NULL;
-
level -= 1;
pte = IOMMU_PTE_PAGE(*pte);
@@ -777,47 +769,28 @@ static u64 *alloc_pte(struct protection_domain *domain,
* This function checks if there is a PTE for a given dma address. If
* there is one, it returns the pointer to it.
*/
-static u64 *fetch_pte(struct protection_domain *domain, unsigned long address)
+static u64 *fetch_pte(struct protection_domain *domain,
+ unsigned long address, int map_size)
{
int level;
u64 *pte;
- if (address > PM_LEVEL_SIZE(domain->mode))
- return NULL;
-
- level = domain->mode - 1;
- pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
+ level = domain->mode - 1;
+ pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
- while (level > 0) {
-
- /* Not Present */
+ while (level > map_size) {
if (!IOMMU_PTE_PRESENT(*pte))
return NULL;
- /* Large PTE */
- if (PM_PTE_LEVEL(*pte) == 0x07) {
- unsigned long pte_mask, __pte;
-
- /*
- * If we have a series of large PTEs, make
- * sure to return a pointer to the first one.
- */
- pte_mask = PTE_PAGE_SIZE(*pte);
- pte_mask = ~((PAGE_SIZE_PTE_COUNT(pte_mask) << 3) - 1);
- __pte = ((unsigned long)pte) & pte_mask;
-
- return (u64 *)__pte;
- }
-
- /* No level skipping support yet */
- if (PM_PTE_LEVEL(*pte) != level)
- return NULL;
-
level -= 1;
- /* Walk to the next level */
pte = IOMMU_PTE_PAGE(*pte);
pte = &pte[PM_LEVEL_INDEX(level, address)];
+
+ if ((PM_PTE_LEVEL(*pte) == 0) && level != map_size) {
+ pte = NULL;
+ break;
+ }
}
return pte;
@@ -834,84 +807,44 @@ static int iommu_map_page(struct protection_domain *dom,
unsigned long bus_addr,
unsigned long phys_addr,
int prot,
- unsigned long page_size)
+ int map_size)
{
u64 __pte, *pte;
- int i, count;
-
- if (!(prot & IOMMU_PROT_MASK))
- return -EINVAL;
bus_addr = PAGE_ALIGN(bus_addr);
phys_addr = PAGE_ALIGN(phys_addr);
- count = PAGE_SIZE_PTE_COUNT(page_size);
- pte = alloc_pte(dom, bus_addr, page_size, NULL, GFP_KERNEL);
- for (i = 0; i < count; ++i)
- if (IOMMU_PTE_PRESENT(pte[i]))
- return -EBUSY;
+ BUG_ON(!PM_ALIGNED(map_size, bus_addr));
+ BUG_ON(!PM_ALIGNED(map_size, phys_addr));
- if (page_size > PAGE_SIZE) {
- __pte = PAGE_SIZE_PTE(phys_addr, page_size);
- __pte |= PM_LEVEL_ENC(7) | IOMMU_PTE_P | IOMMU_PTE_FC;
- } else
- __pte = phys_addr | IOMMU_PTE_P | IOMMU_PTE_FC;
+ if (!(prot & IOMMU_PROT_MASK))
+ return -EINVAL;
+ pte = alloc_pte(dom, bus_addr, map_size, NULL, GFP_KERNEL);
+
+ if (IOMMU_PTE_PRESENT(*pte))
+ return -EBUSY;
+
+ __pte = phys_addr | IOMMU_PTE_P;
if (prot & IOMMU_PROT_IR)
__pte |= IOMMU_PTE_IR;
if (prot & IOMMU_PROT_IW)
__pte |= IOMMU_PTE_IW;
- for (i = 0; i < count; ++i)
- pte[i] = __pte;
+ *pte = __pte;
update_domain(dom);
return 0;
}
-static unsigned long iommu_unmap_page(struct protection_domain *dom,
- unsigned long bus_addr,
- unsigned long page_size)
+static void iommu_unmap_page(struct protection_domain *dom,
+ unsigned long bus_addr, int map_size)
{
- unsigned long long unmap_size, unmapped;
- u64 *pte;
-
- BUG_ON(!is_power_of_2(page_size));
-
- unmapped = 0;
+ u64 *pte = fetch_pte(dom, bus_addr, map_size);
- while (unmapped < page_size) {
-
- pte = fetch_pte(dom, bus_addr);
-
- if (!pte) {
- /*
- * No PTE for this address
- * move forward in 4kb steps
- */
- unmap_size = PAGE_SIZE;
- } else if (PM_PTE_LEVEL(*pte) == 0) {
- /* 4kb PTE found for this address */
- unmap_size = PAGE_SIZE;
- *pte = 0ULL;
- } else {
- int count, i;
-
- /* Large PTE found which maps this address */
- unmap_size = PTE_PAGE_SIZE(*pte);
- count = PAGE_SIZE_PTE_COUNT(unmap_size);
- for (i = 0; i < count; i++)
- pte[i] = 0ULL;
- }
-
- bus_addr = (bus_addr & ~(unmap_size - 1)) + unmap_size;
- unmapped += unmap_size;
- }
-
- BUG_ON(!is_power_of_2(unmapped));
-
- return unmapped;
+ if (pte)
+ *pte = 0;
}
/*
@@ -945,7 +878,7 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
for (addr = e->address_start; addr < e->address_end;
addr += PAGE_SIZE) {
ret = iommu_map_page(&dma_dom->domain, addr, addr, e->prot,
- PAGE_SIZE);
+ PM_MAP_4k);
if (ret)
return ret;
/*
@@ -1073,7 +1006,7 @@ static int alloc_new_range(struct dma_ops_domain *dma_dom,
u64 *pte, *pte_page;
for (i = 0; i < num_ptes; ++i) {
- pte = alloc_pte(&dma_dom->domain, address, PAGE_SIZE,
+ pte = alloc_pte(&dma_dom->domain, address, PM_MAP_4k,
&pte_page, gfp);
if (!pte)
goto out_free;
@@ -1109,7 +1042,7 @@ static int alloc_new_range(struct dma_ops_domain *dma_dom,
for (i = dma_dom->aperture[index]->offset;
i < dma_dom->aperture_size;
i += PAGE_SIZE) {
- u64 *pte = fetch_pte(&dma_dom->domain, i);
+ u64 *pte = fetch_pte(&dma_dom->domain, i, PM_MAP_4k);
if (!pte || !IOMMU_PTE_PRESENT(*pte))
continue;
@@ -1779,7 +1712,7 @@ static u64* dma_ops_get_pte(struct dma_ops_domain *dom,
pte = aperture->pte_pages[APERTURE_PAGE_INDEX(address)];
if (!pte) {
- pte = alloc_pte(&dom->domain, address, PAGE_SIZE, &pte_page,
+ pte = alloc_pte(&dom->domain, address, PM_MAP_4k, &pte_page,
GFP_ATOMIC);
aperture->pte_pages[APERTURE_PAGE_INDEX(address)] = pte_page;
} else
@@ -2506,11 +2439,12 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
return ret;
}
-static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,
- phys_addr_t paddr, int gfp_order, int iommu_prot)
+static int amd_iommu_map_range(struct iommu_domain *dom,
+ unsigned long iova, phys_addr_t paddr,
+ size_t size, int iommu_prot)
{
- unsigned long page_size = 0x1000UL << gfp_order;
struct protection_domain *domain = dom->priv;
+ unsigned long i, npages = iommu_num_pages(paddr, size, PAGE_SIZE);
int prot = 0;
int ret;
@@ -2519,50 +2453,61 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,
if (iommu_prot & IOMMU_WRITE)
prot |= IOMMU_PROT_IW;
+ iova &= PAGE_MASK;
+ paddr &= PAGE_MASK;
+
mutex_lock(&domain->api_lock);
- ret = iommu_map_page(domain, iova, paddr, prot, page_size);
+
+ for (i = 0; i < npages; ++i) {
+ ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k);
+ if (ret)
+ return ret;
+
+ iova += PAGE_SIZE;
+ paddr += PAGE_SIZE;
+ }
+
mutex_unlock(&domain->api_lock);
- return ret;
+ return 0;
}
-static int amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,
- int gfp_order)
+static void amd_iommu_unmap_range(struct iommu_domain *dom,
+ unsigned long iova, size_t size)
{
+
struct protection_domain *domain = dom->priv;
- unsigned long page_size, unmap_size;
+ unsigned long i, npages = iommu_num_pages(iova, size, PAGE_SIZE);
- page_size = 0x1000UL << gfp_order;
+ iova &= PAGE_MASK;
mutex_lock(&domain->api_lock);
- unmap_size = iommu_unmap_page(domain, iova, page_size);
- mutex_unlock(&domain->api_lock);
+
+ for (i = 0; i < npages; ++i) {
+ iommu_unmap_page(domain, iova, PM_MAP_4k);
+ iova += PAGE_SIZE;
+ }
iommu_flush_tlb_pde(domain);
- return get_order(unmap_size);
+ mutex_unlock(&domain->api_lock);
}
static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
unsigned long iova)
{
struct protection_domain *domain = dom->priv;
- unsigned long offset_mask;
+ unsigned long offset = iova & ~PAGE_MASK;
phys_addr_t paddr;
- u64 *pte, __pte;
+ u64 *pte;
- pte = fetch_pte(domain, iova);
+ pte = fetch_pte(domain, iova, PM_MAP_4k);
if (!pte || !IOMMU_PTE_PRESENT(*pte))
return 0;
- if (PM_PTE_LEVEL(*pte) == 0)
- offset_mask = PAGE_SIZE - 1;
- else
- offset_mask = PTE_PAGE_SIZE(*pte) - 1;
-
- __pte = *pte & PM_ADDR_MASK;
- paddr = (__pte & ~offset_mask) | (iova & offset_mask);
+ paddr = *pte & IOMMU_PAGE_MASK;
+ paddr |= offset;
return paddr;
}
@@ -2578,8 +2523,8 @@ static struct iommu_ops amd_iommu_ops = {
.domain_destroy = amd_iommu_domain_destroy,
.attach_dev = amd_iommu_attach_device,
.detach_dev = amd_iommu_detach_device,
- .map = amd_iommu_map,
- .unmap = amd_iommu_unmap,
+ .map = amd_iommu_map_range,
+ .unmap = amd_iommu_unmap_range,
.iova_to_phys = amd_iommu_iova_to_phys,
.domain_has_cap = amd_iommu_domain_has_cap,
};
diff --git a/trunk/arch/x86/kernel/amd_iommu_init.c b/trunk/arch/x86/kernel/amd_iommu_init.c
index 3bacb4d0844c..6360abf993d4 100644
--- a/trunk/arch/x86/kernel/amd_iommu_init.c
+++ b/trunk/arch/x86/kernel/amd_iommu_init.c
@@ -120,7 +120,6 @@ struct ivmd_header {
bool amd_iommu_dump;
static int __initdata amd_iommu_detected;
-static bool __initdata amd_iommu_disabled;
u16 amd_iommu_last_bdf; /* largest PCI device id we have
to handle */
@@ -1373,9 +1372,6 @@ void __init amd_iommu_detect(void)
if (no_iommu || (iommu_detected && !gart_iommu_aperture))
return;
- if (amd_iommu_disabled)
- return;
-
if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) {
iommu_detected = 1;
amd_iommu_detected = 1;
@@ -1405,8 +1401,6 @@ static int __init parse_amd_iommu_options(char *str)
for (; *str; ++str) {
if (strncmp(str, "fullflush", 9) == 0)
amd_iommu_unmap_flush = true;
- if (strncmp(str, "off", 3) == 0)
- amd_iommu_disabled = true;
}
return 1;
diff --git a/trunk/arch/x86/kernel/apic/es7000_32.c b/trunk/arch/x86/kernel/apic/es7000_32.c
index 425e53a87feb..03ba1b895f5e 100644
--- a/trunk/arch/x86/kernel/apic/es7000_32.c
+++ b/trunk/arch/x86/kernel/apic/es7000_32.c
@@ -131,6 +131,24 @@ int es7000_plat;
static unsigned int base;
+static int
+es7000_rename_gsi(int ioapic, int gsi)
+{
+ if (es7000_plat == ES7000_ZORRO)
+ return gsi;
+
+ if (!base) {
+ int i;
+ for (i = 0; i < nr_ioapics; i++)
+ base += nr_ioapic_registers[i];
+ }
+
+ if (!ioapic && (gsi < 16))
+ gsi += base;
+
+ return gsi;
+}
+
static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
{
unsigned long vect = 0, psaival = 0;
@@ -172,6 +190,7 @@ static void setup_unisys(void)
es7000_plat = ES7000_ZORRO;
else
es7000_plat = ES7000_CLASSIC;
+ ioapic_renumber_irq = es7000_rename_gsi;
}
/*
diff --git a/trunk/arch/x86/kernel/apic/io_apic.c b/trunk/arch/x86/kernel/apic/io_apic.c
index 33f3563a2a52..127b8718abfb 100644
--- a/trunk/arch/x86/kernel/apic/io_apic.c
+++ b/trunk/arch/x86/kernel/apic/io_apic.c
@@ -89,9 +89,6 @@ int nr_ioapics;
/* IO APIC gsi routing info */
struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS];
-/* The last gsi number used */
-u32 gsi_end;
-
/* MP IRQ source entries */
struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
@@ -1016,9 +1013,10 @@ static inline int irq_trigger(int idx)
return MPBIOS_trigger(idx);
}
+int (*ioapic_renumber_irq)(int ioapic, int irq);
static int pin_2_irq(int idx, int apic, int pin)
{
- int irq;
+ int irq, i;
int bus = mp_irqs[idx].srcbus;
/*
@@ -1030,12 +1028,18 @@ static int pin_2_irq(int idx, int apic, int pin)
if (test_bit(bus, mp_bus_not_pci)) {
irq = mp_irqs[idx].srcbusirq;
} else {
- u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
-
- if (gsi >= NR_IRQS_LEGACY)
- irq = gsi;
- else
- irq = gsi_end + 1 + gsi;
+ /*
+ * PCI IRQs are mapped in order
+ */
+ i = irq = 0;
+ while (i < apic)
+ irq += nr_ioapic_registers[i++];
+ irq += pin;
+ /*
+ * For MPS mode, so far only needed by ES7000 platform
+ */
+ if (ioapic_renumber_irq)
+ irq = ioapic_renumber_irq(apic, irq);
}
#ifdef CONFIG_X86_32
@@ -1946,8 +1950,20 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
void __init enable_IO_APIC(void)
{
+ union IO_APIC_reg_01 reg_01;
int i8259_apic, i8259_pin;
int apic;
+ unsigned long flags;
+
+ /*
+ * The number of IO-APIC IRQ registers (== #pins):
+ */
+ for (apic = 0; apic < nr_ioapics; apic++) {
+ raw_spin_lock_irqsave(&ioapic_lock, flags);
+ reg_01.raw = io_apic_read(apic, 1);
+ raw_spin_unlock_irqrestore(&ioapic_lock, flags);
+ nr_ioapic_registers[apic] = reg_01.bits.entries+1;
+ }
if (!legacy_pic->nr_legacy_irqs)
return;
@@ -2529,9 +2545,6 @@ void irq_force_complete_move(int irq)
struct irq_desc *desc = irq_to_desc(irq);
struct irq_cfg *cfg = desc->chip_data;
- if (!cfg)
- return;
-
__irq_complete_move(&desc, cfg->vector);
}
#else
@@ -3842,20 +3855,27 @@ int __init io_apic_get_redir_entries (int ioapic)
reg_01.raw = io_apic_read(ioapic, 1);
raw_spin_unlock_irqrestore(&ioapic_lock, flags);
- /* The register returns the maximum index redir index
- * supported, which is one less than the total number of redir
- * entries.
- */
- return reg_01.bits.entries + 1;
+ return reg_01.bits.entries;
}
void __init probe_nr_irqs_gsi(void)
{
- int nr;
+ int nr = 0;
- nr = gsi_end + 1 + NR_IRQS_LEGACY;
- if (nr > nr_irqs_gsi)
+ nr = acpi_probe_gsi();
+ if (nr > nr_irqs_gsi) {
nr_irqs_gsi = nr;
+ } else {
+ /* for acpi=off or acpi is not compiled in */
+ int idx;
+
+ nr = 0;
+ for (idx = 0; idx < nr_ioapics; idx++)
+ nr += io_apic_get_redir_entries(idx) + 1;
+
+ if (nr > nr_irqs_gsi)
+ nr_irqs_gsi = nr;
+ }
printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
}
@@ -4062,27 +4082,22 @@ int __init io_apic_get_version(int ioapic)
return reg_01.bits.version;
}
-int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity)
+int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
{
- int ioapic, pin, idx;
+ int i;
if (skip_ioapic_setup)
return -1;
- ioapic = mp_find_ioapic(gsi);
- if (ioapic < 0)
- return -1;
-
- pin = mp_find_ioapic_pin(ioapic, gsi);
- if (pin < 0)
- return -1;
-
- idx = find_irq_entry(ioapic, pin, mp_INT);
- if (idx < 0)
+ for (i = 0; i < mp_irq_entries; i++)
+ if (mp_irqs[i].irqtype == mp_INT &&
+ mp_irqs[i].srcbusirq == bus_irq)
+ break;
+ if (i >= mp_irq_entries)
return -1;
- *trigger = irq_trigger(idx);
- *polarity = irq_polarity(idx);
+ *trigger = irq_trigger(i);
+ *polarity = irq_polarity(i);
return 0;
}
@@ -4223,7 +4238,7 @@ void __init ioapic_insert_resources(void)
}
}
-int mp_find_ioapic(u32 gsi)
+int mp_find_ioapic(int gsi)
{
int i = 0;
@@ -4238,7 +4253,7 @@ int mp_find_ioapic(u32 gsi)
return -1;
}
-int mp_find_ioapic_pin(int ioapic, u32 gsi)
+int mp_find_ioapic_pin(int ioapic, int gsi)
{
if (WARN_ON(ioapic == -1))
return -1;
@@ -4266,7 +4281,6 @@ static int bad_ioapic(unsigned long address)
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
{
int idx = 0;
- int entries;
if (bad_ioapic(address))
return;
@@ -4285,17 +4299,9 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
* Build basic GSI lookup table to facilitate gsi->io_apic lookups
* and to prevent reprogramming of IOAPIC pins (PCI GSIs).
*/
- entries = io_apic_get_redir_entries(idx);
mp_gsi_routing[idx].gsi_base = gsi_base;
- mp_gsi_routing[idx].gsi_end = gsi_base + entries - 1;
-
- /*
- * The number of IO-APIC IRQ registers (== #pins):
- */
- nr_ioapic_registers[idx] = entries;
-
- if (mp_gsi_routing[idx].gsi_end > gsi_end)
- gsi_end = mp_gsi_routing[idx].gsi_end;
+ mp_gsi_routing[idx].gsi_end = gsi_base +
+ io_apic_get_redir_entries(idx);
printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
"GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
diff --git a/trunk/arch/x86/kernel/apic/x2apic_uv_x.c b/trunk/arch/x86/kernel/apic/x2apic_uv_x.c
index e46f98f36e31..c085d52dbaf2 100644
--- a/trunk/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/trunk/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -735,6 +735,9 @@ void __init uv_system_init(void)
uv_node_to_blade[nid] = blade;
uv_cpu_to_blade[cpu] = blade;
max_pnode = max(pnode, max_pnode);
+
+ printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n",
+ cpu, apicid, pnode, nid, lcpu, blade);
}
/* Add blade/pnode info for nodes without cpus */
diff --git a/trunk/arch/x86/kernel/apm_32.c b/trunk/arch/x86/kernel/apm_32.c
index c4f9182ca3ac..031aa887b0eb 100644
--- a/trunk/arch/x86/kernel/apm_32.c
+++ b/trunk/arch/x86/kernel/apm_32.c
@@ -1224,7 +1224,7 @@ static void reinit_timer(void)
#ifdef INIT_TIMER_AFTER_SUSPEND
unsigned long flags;
- raw_spin_lock_irqsave(&i8253_lock, flags);
+ spin_lock_irqsave(&i8253_lock, flags);
/* set the clock to HZ */
outb_pit(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */
udelay(10);
@@ -1232,7 +1232,7 @@ static void reinit_timer(void)
udelay(10);
outb_pit(LATCH >> 8, PIT_CH0); /* MSB */
udelay(10);
- raw_spin_unlock_irqrestore(&i8253_lock, flags);
+ spin_unlock_irqrestore(&i8253_lock, flags);
#endif
}
diff --git a/trunk/arch/x86/kernel/cpu/Makefile b/trunk/arch/x86/kernel/cpu/Makefile
index 3a785da34b6f..c202b62f3671 100644
--- a/trunk/arch/x86/kernel/cpu/Makefile
+++ b/trunk/arch/x86/kernel/cpu/Makefile
@@ -14,7 +14,7 @@ CFLAGS_common.o := $(nostackp)
obj-y := intel_cacheinfo.o addon_cpuid_features.o
obj-y += proc.o capflags.o powerflags.o common.o
-obj-y += vmware.o hypervisor.o sched.o mshyperv.o
+obj-y += vmware.o hypervisor.o sched.o
obj-$(CONFIG_X86_32) += bugs.o cmpxchg.o
obj-$(CONFIG_X86_64) += bugs_64.o
diff --git a/trunk/arch/x86/kernel/cpu/addon_cpuid_features.c b/trunk/arch/x86/kernel/cpu/addon_cpuid_features.c
index 10fa5684a662..97ad79cdf688 100644
--- a/trunk/arch/x86/kernel/cpu/addon_cpuid_features.c
+++ b/trunk/arch/x86/kernel/cpu/addon_cpuid_features.c
@@ -30,14 +30,12 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
const struct cpuid_bit *cb;
static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
- { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
- { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 },
- { X86_FEATURE_APERFMPERF, CR_ECX, 0, 0x00000006 },
- { X86_FEATURE_CPB, CR_EDX, 9, 0x80000007 },
- { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a },
- { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a },
- { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a },
- { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a },
+ { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
+ { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 },
+ { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a },
+ { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a },
+ { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a },
+ { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a },
{ 0, 0, 0, 0 }
};
diff --git a/trunk/arch/x86/kernel/cpu/bugs.c b/trunk/arch/x86/kernel/cpu/bugs.c
index c39576cb3018..01a265212395 100644
--- a/trunk/arch/x86/kernel/cpu/bugs.c
+++ b/trunk/arch/x86/kernel/cpu/bugs.c
@@ -86,7 +86,7 @@ static void __init check_fpu(void)
static void __init check_hlt(void)
{
- if (boot_cpu_data.x86 >= 5 || paravirt_enabled())
+ if (paravirt_enabled())
return;
printk(KERN_INFO "Checking 'hlt' instruction... ");
diff --git a/trunk/arch/x86/kernel/cpu/common.c b/trunk/arch/x86/kernel/cpu/common.c
index c1c00d0b1692..4868e4a951ee 100644
--- a/trunk/arch/x86/kernel/cpu/common.c
+++ b/trunk/arch/x86/kernel/cpu/common.c
@@ -1243,7 +1243,10 @@ void __cpuinit cpu_init(void)
/*
* Force FPU initialization:
*/
- current_thread_info()->status = 0;
+ if (cpu_has_xsave)
+ current_thread_info()->status = TS_XSAVE;
+ else
+ current_thread_info()->status = 0;
clear_used_math();
mxcsr_feature_mask_init();
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/Makefile b/trunk/arch/x86/kernel/cpu/cpufreq/Makefile
index bd54bf67e6fb..1840c0a5170b 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/Makefile
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/Makefile
@@ -2,8 +2,8 @@
# K8 systems. ACPI is preferred to all other hardware-specific drivers.
# speedstep-* is preferred over p4-clockmod.
-obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o mperf.o
-obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o mperf.o
+obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
+obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o
obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 1d3cddaa40ee..459168083b77 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -46,7 +46,6 @@
#include
#include
#include
-#include "mperf.h"
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
"acpi-cpufreq", msg)
@@ -72,6 +71,8 @@ struct acpi_cpufreq_data {
static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data);
+static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf);
+
/* acpi_perf_data is a pointer to percpu data. */
static struct acpi_processor_performance *acpi_perf_data;
@@ -239,6 +240,45 @@ static u32 get_cur_val(const struct cpumask *mask)
return cmd.val;
}
+/* Called via smp_call_function_single(), on the target CPU */
+static void read_measured_perf_ctrs(void *_cur)
+{
+ struct aperfmperf *am = _cur;
+
+ get_aperfmperf(am);
+}
+
+/*
+ * Return the measured active (C0) frequency on this CPU since last call
+ * to this function.
+ * Input: cpu number
+ * Return: Average CPU frequency in terms of max frequency (zero on error)
+ *
+ * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance
+ * over a period of time, while CPU is in C0 state.
+ * IA32_MPERF counts at the rate of max advertised frequency
+ * IA32_APERF counts at the rate of actual CPU frequency
+ * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
+ * no meaning should be associated with absolute values of these MSRs.
+ */
+static unsigned int get_measured_perf(struct cpufreq_policy *policy,
+ unsigned int cpu)
+{
+ struct aperfmperf perf;
+ unsigned long ratio;
+ unsigned int retval;
+
+ if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1))
+ return 0;
+
+ ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf);
+ per_cpu(acfreq_old_perf, cpu) = perf;
+
+ retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT;
+
+ return retval;
+}
+
static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
{
struct acpi_cpufreq_data *data = per_cpu(acfreq_data, cpu);
@@ -662,7 +702,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
/* Check for APERF/MPERF support in hardware */
if (cpu_has(c, X86_FEATURE_APERFMPERF))
- acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf;
+ acpi_cpufreq_driver.getavg = get_measured_perf;
dprintk("CPU%u - ACPI performance management activated.\n", cpu);
for (i = 0; i < perf->state_count; i++)
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/mperf.c b/trunk/arch/x86/kernel/cpu/cpufreq/mperf.c
deleted file mode 100644
index 911e193018ae..000000000000
--- a/trunk/arch/x86/kernel/cpu/cpufreq/mperf.c
+++ /dev/null
@@ -1,51 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "mperf.h"
-
-static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf);
-
-/* Called via smp_call_function_single(), on the target CPU */
-static void read_measured_perf_ctrs(void *_cur)
-{
- struct aperfmperf *am = _cur;
-
- get_aperfmperf(am);
-}
-
-/*
- * Return the measured active (C0) frequency on this CPU since last call
- * to this function.
- * Input: cpu number
- * Return: Average CPU frequency in terms of max frequency (zero on error)
- *
- * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance
- * over a period of time, while CPU is in C0 state.
- * IA32_MPERF counts at the rate of max advertised frequency
- * IA32_APERF counts at the rate of actual CPU frequency
- * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
- * no meaning should be associated with absolute values of these MSRs.
- */
-unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy,
- unsigned int cpu)
-{
- struct aperfmperf perf;
- unsigned long ratio;
- unsigned int retval;
-
- if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1))
- return 0;
-
- ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf);
- per_cpu(acfreq_old_perf, cpu) = perf;
-
- retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT;
-
- return retval;
-}
-EXPORT_SYMBOL_GPL(cpufreq_get_measured_perf);
-MODULE_LICENSE("GPL");
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/mperf.h b/trunk/arch/x86/kernel/cpu/cpufreq/mperf.h
deleted file mode 100644
index 5dbf2950dc22..000000000000
--- a/trunk/arch/x86/kernel/cpu/cpufreq/mperf.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * (c) 2010 Advanced Micro Devices, Inc.
- * Your use of this code is subject to the terms and conditions of the
- * GNU general public license version 2. See "COPYING" or
- * http://www.gnu.org/licenses/gpl.html
- */
-
-unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy,
- unsigned int cpu);
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index 6f3dc8fbbfdc..d360b56e9825 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -1,5 +1,6 @@
+
/*
- * (c) 2003-2010 Advanced Micro Devices, Inc.
+ * (c) 2003-2006 Advanced Micro Devices, Inc.
* Your use of this code is subject to the terms and conditions of the
* GNU general public license version 2. See "COPYING" or
* http://www.gnu.org/licenses/gpl.html
@@ -45,7 +46,6 @@
#define PFX "powernow-k8: "
#define VERSION "version 2.20.00"
#include "powernow-k8.h"
-#include "mperf.h"
/* serialize freq changes */
static DEFINE_MUTEX(fidvid_mutex);
@@ -54,12 +54,6 @@ static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data);
static int cpu_family = CPU_OPTERON;
-/* core performance boost */
-static bool cpb_capable, cpb_enabled;
-static struct msr __percpu *msrs;
-
-static struct cpufreq_driver cpufreq_amd64_driver;
-
#ifndef CONFIG_SMP
static inline const struct cpumask *cpu_core_mask(int cpu)
{
@@ -935,8 +929,7 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data,
powernow_table[i].index = index;
/* Frequency may be rounded for these */
- if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
- || boot_cpu_data.x86 == 0x11) {
+ if (boot_cpu_data.x86 == 0x10 || boot_cpu_data.x86 == 0x11) {
powernow_table[i].frequency =
freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7);
} else
@@ -1255,7 +1248,6 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
struct powernow_k8_data *data;
struct init_on_cpu init_on_cpu;
int rc;
- struct cpuinfo_x86 *c = &cpu_data(pol->cpu);
if (!cpu_online(pol->cpu))
return -ENODEV;
@@ -1330,10 +1322,6 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
return -EINVAL;
}
- /* Check for APERF/MPERF support in hardware */
- if (cpu_has(c, X86_FEATURE_APERFMPERF))
- cpufreq_amd64_driver.getavg = cpufreq_get_measured_perf;
-
cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
if (cpu_family == CPU_HW_PSTATE)
@@ -1405,77 +1393,8 @@ static unsigned int powernowk8_get(unsigned int cpu)
return khz;
}
-static void _cpb_toggle_msrs(bool t)
-{
- int cpu;
-
- get_online_cpus();
-
- rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
-
- for_each_cpu(cpu, cpu_online_mask) {
- struct msr *reg = per_cpu_ptr(msrs, cpu);
- if (t)
- reg->l &= ~BIT(25);
- else
- reg->l |= BIT(25);
- }
- wrmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
-
- put_online_cpus();
-}
-
-/*
- * Switch on/off core performance boosting.
- *
- * 0=disable
- * 1=enable.
- */
-static void cpb_toggle(bool t)
-{
- if (!cpb_capable)
- return;
-
- if (t && !cpb_enabled) {
- cpb_enabled = true;
- _cpb_toggle_msrs(t);
- printk(KERN_INFO PFX "Core Boosting enabled.\n");
- } else if (!t && cpb_enabled) {
- cpb_enabled = false;
- _cpb_toggle_msrs(t);
- printk(KERN_INFO PFX "Core Boosting disabled.\n");
- }
-}
-
-static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf,
- size_t count)
-{
- int ret = -EINVAL;
- unsigned long val = 0;
-
- ret = strict_strtoul(buf, 10, &val);
- if (!ret && (val == 0 || val == 1) && cpb_capable)
- cpb_toggle(val);
- else
- return -EINVAL;
-
- return count;
-}
-
-static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf)
-{
- return sprintf(buf, "%u\n", cpb_enabled);
-}
-
-#define define_one_rw(_name) \
-static struct freq_attr _name = \
-__ATTR(_name, 0644, show_##_name, store_##_name)
-
-define_one_rw(cpb);
-
static struct freq_attr *powernow_k8_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
- &cpb,
NULL,
};
@@ -1491,51 +1410,10 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
.attr = powernow_k8_attr,
};
-/*
- * Clear the boost-disable flag on the CPU_DOWN path so that this cpu
- * cannot block the remaining ones from boosting. On the CPU_UP path we
- * simply keep the boost-disable flag in sync with the current global
- * state.
- */
-static int __cpuinit cpb_notify(struct notifier_block *nb, unsigned long action,
- void *hcpu)
-{
- unsigned cpu = (long)hcpu;
- u32 lo, hi;
-
- switch (action) {
- case CPU_UP_PREPARE:
- case CPU_UP_PREPARE_FROZEN:
-
- if (!cpb_enabled) {
- rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
- lo |= BIT(25);
- wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
- }
- break;
-
- case CPU_DOWN_PREPARE:
- case CPU_DOWN_PREPARE_FROZEN:
- rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
- lo &= ~BIT(25);
- wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
- break;
-
- default:
- break;
- }
-
- return NOTIFY_OK;
-}
-
-static struct notifier_block __cpuinitdata cpb_nb = {
- .notifier_call = cpb_notify,
-};
-
/* driver entry point for init */
static int __cpuinit powernowk8_init(void)
{
- unsigned int i, supported_cpus = 0, cpu;
+ unsigned int i, supported_cpus = 0;
for_each_online_cpu(i) {
int rc;
@@ -1544,36 +1422,15 @@ static int __cpuinit powernowk8_init(void)
supported_cpus++;
}
- if (supported_cpus != num_online_cpus())
- return -ENODEV;
-
- printk(KERN_INFO PFX "Found %d %s (%d cpu cores) (" VERSION ")\n",
- num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus);
-
- if (boot_cpu_has(X86_FEATURE_CPB)) {
-
- cpb_capable = true;
-
- register_cpu_notifier(&cpb_nb);
-
- msrs = msrs_alloc();
- if (!msrs) {
- printk(KERN_ERR "%s: Error allocating msrs!\n", __func__);
- return -ENOMEM;
- }
-
- rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
-
- for_each_cpu(cpu, cpu_online_mask) {
- struct msr *reg = per_cpu_ptr(msrs, cpu);
- cpb_enabled |= !(!!(reg->l & BIT(25)));
- }
-
- printk(KERN_INFO PFX "Core Performance Boosting: %s.\n",
- (cpb_enabled ? "on" : "off"));
+ if (supported_cpus == num_online_cpus()) {
+ printk(KERN_INFO PFX "Found %d %s "
+ "processors (%d cpu cores) (" VERSION ")\n",
+ num_online_nodes(),
+ boot_cpu_data.x86_model_id, supported_cpus);
+ return cpufreq_register_driver(&cpufreq_amd64_driver);
}
- return cpufreq_register_driver(&cpufreq_amd64_driver);
+ return -ENODEV;
}
/* driver entry point for term */
@@ -1581,13 +1438,6 @@ static void __exit powernowk8_exit(void)
{
dprintk("exit\n");
- if (boot_cpu_has(X86_FEATURE_CPB)) {
- msrs_free(msrs);
- msrs = NULL;
-
- unregister_cpu_notifier(&cpb_nb);
- }
-
cpufreq_unregister_driver(&cpufreq_amd64_driver);
}
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
index df3529b1c02d..02ce824073cb 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
@@ -5,6 +5,7 @@
* http://www.gnu.org/licenses/gpl.html
*/
+
enum pstate {
HW_PSTATE_INVALID = 0xff,
HW_PSTATE_0 = 0,
@@ -54,6 +55,7 @@ struct powernow_k8_data {
struct cpumask *available_cores;
};
+
/* processor's cpuid instruction support */
#define CPUID_PROCESSOR_SIGNATURE 1 /* function 1 */
#define CPUID_XFAM 0x0ff00000 /* extended family */
diff --git a/trunk/arch/x86/kernel/cpu/hypervisor.c b/trunk/arch/x86/kernel/cpu/hypervisor.c
index dd531cc56a8f..08be922de33a 100644
--- a/trunk/arch/x86/kernel/cpu/hypervisor.c
+++ b/trunk/arch/x86/kernel/cpu/hypervisor.c
@@ -21,55 +21,37 @@
*
*/
-#include
#include
+#include
#include
-/*
- * Hypervisor detect order. This is specified explicitly here because
- * some hypervisors might implement compatibility modes for other
- * hypervisors and therefore need to be detected in specific sequence.
- */
-static const __initconst struct hypervisor_x86 * const hypervisors[] =
+static inline void __cpuinit
+detect_hypervisor_vendor(struct cpuinfo_x86 *c)
{
- &x86_hyper_vmware,
- &x86_hyper_ms_hyperv,
-};
-
-const struct hypervisor_x86 *x86_hyper;
-EXPORT_SYMBOL(x86_hyper);
+ if (vmware_platform())
+ c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE;
+ else
+ c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE;
+}
-static inline void __init
-detect_hypervisor_vendor(void)
+static inline void __cpuinit
+hypervisor_set_feature_bits(struct cpuinfo_x86 *c)
{
- const struct hypervisor_x86 *h, * const *p;
-
- for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) {
- h = *p;
- if (h->detect()) {
- x86_hyper = h;
- printk(KERN_INFO "Hypervisor detected: %s\n", h->name);
- break;
- }
+ if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) {
+ vmware_set_feature_bits(c);
+ return;
}
}
void __cpuinit init_hypervisor(struct cpuinfo_x86 *c)
{
- if (x86_hyper && x86_hyper->set_cpu_features)
- x86_hyper->set_cpu_features(c);
+ detect_hypervisor_vendor(c);
+ hypervisor_set_feature_bits(c);
}
void __init init_hypervisor_platform(void)
{
-
- detect_hypervisor_vendor();
-
- if (!x86_hyper)
- return;
-
init_hypervisor(&boot_cpu_data);
-
- if (x86_hyper->init_platform)
- x86_hyper->init_platform();
+ if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
+ vmware_platform_setup();
}
diff --git a/trunk/arch/x86/kernel/cpu/intel.c b/trunk/arch/x86/kernel/cpu/intel.c
index 85f69cdeae10..1366c7cfd483 100644
--- a/trunk/arch/x86/kernel/cpu/intel.c
+++ b/trunk/arch/x86/kernel/cpu/intel.c
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
@@ -372,6 +373,12 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON);
}
+ if (c->cpuid_level > 6) {
+ unsigned ecx = cpuid_ecx(6);
+ if (ecx & 0x01)
+ set_cpu_cap(c, X86_FEATURE_APERFMPERF);
+ }
+
if (cpu_has_xmm2)
set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
if (cpu_has_ds) {
@@ -381,6 +388,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
set_cpu_cap(c, X86_FEATURE_BTS);
if (!(l1 & (1<<12)))
set_cpu_cap(c, X86_FEATURE_PEBS);
+ ds_init_intel(c);
}
if (c->x86 == 6 && c->x86_model == 29 && cpu_has_clflush)
diff --git a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c
index 33eae2062cf5..b3eeb66c0a51 100644
--- a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -148,19 +148,13 @@ union _cpuid4_leaf_ecx {
u32 full;
};
-struct amd_l3_cache {
- struct pci_dev *dev;
- bool can_disable;
- unsigned indices;
- u8 subcaches[4];
-};
-
struct _cpuid4_info {
union _cpuid4_leaf_eax eax;
union _cpuid4_leaf_ebx ebx;
union _cpuid4_leaf_ecx ecx;
unsigned long size;
- struct amd_l3_cache *l3;
+ bool can_disable;
+ unsigned int l3_indices;
DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
};
@@ -170,7 +164,8 @@ struct _cpuid4_info_regs {
union _cpuid4_leaf_ebx ebx;
union _cpuid4_leaf_ecx ecx;
unsigned long size;
- struct amd_l3_cache *l3;
+ bool can_disable;
+ unsigned int l3_indices;
};
unsigned short num_cache_leaves;
@@ -307,163 +302,87 @@ struct _cache_attr {
};
#ifdef CONFIG_CPU_SUP_AMD
-
-/*
- * L3 cache descriptors
- */
-static struct amd_l3_cache **__cpuinitdata l3_caches;
-
-static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3)
+static unsigned int __cpuinit amd_calc_l3_indices(void)
{
+ /*
+ * We're called over smp_call_function_single() and therefore
+ * are on the correct cpu.
+ */
+ int cpu = smp_processor_id();
+ int node = cpu_to_node(cpu);
+ struct pci_dev *dev = node_to_k8_nb_misc(node);
unsigned int sc0, sc1, sc2, sc3;
u32 val = 0;
- pci_read_config_dword(l3->dev, 0x1C4, &val);
+ pci_read_config_dword(dev, 0x1C4, &val);
/* calculate subcache sizes */
- l3->subcaches[0] = sc0 = !(val & BIT(0));
- l3->subcaches[1] = sc1 = !(val & BIT(4));
- l3->subcaches[2] = sc2 = !(val & BIT(8)) + !(val & BIT(9));
- l3->subcaches[3] = sc3 = !(val & BIT(12)) + !(val & BIT(13));
+ sc0 = !(val & BIT(0));
+ sc1 = !(val & BIT(4));
+ sc2 = !(val & BIT(8)) + !(val & BIT(9));
+ sc3 = !(val & BIT(12)) + !(val & BIT(13));
- l3->indices = (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
-}
-
-static struct amd_l3_cache * __cpuinit amd_init_l3_cache(int node)
-{
- struct amd_l3_cache *l3;
- struct pci_dev *dev = node_to_k8_nb_misc(node);
-
- l3 = kzalloc(sizeof(struct amd_l3_cache), GFP_ATOMIC);
- if (!l3) {
- printk(KERN_WARNING "Error allocating L3 struct\n");
- return NULL;
- }
-
- l3->dev = dev;
-
- amd_calc_l3_indices(l3);
-
- return l3;
+ return (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
}
static void __cpuinit
amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
{
- int node;
-
- if (boot_cpu_data.x86 != 0x10)
- return;
-
if (index < 3)
return;
- /* see errata #382 and #388 */
- if (boot_cpu_data.x86_model < 0x8)
+ if (boot_cpu_data.x86 == 0x11)
return;
- if ((boot_cpu_data.x86_model == 0x8 ||
- boot_cpu_data.x86_model == 0x9)
- &&
- boot_cpu_data.x86_mask < 0x1)
- return;
-
- /* not in virtualized environments */
- if (num_k8_northbridges == 0)
+ /* see errata #382 and #388 */
+ if ((boot_cpu_data.x86 == 0x10) &&
+ ((boot_cpu_data.x86_model < 0x8) ||
+ (boot_cpu_data.x86_mask < 0x1)))
return;
- /*
- * Strictly speaking, the amount in @size below is leaked since it is
- * never freed but this is done only on shutdown so it doesn't matter.
- */
- if (!l3_caches) {
- int size = num_k8_northbridges * sizeof(struct amd_l3_cache *);
-
- l3_caches = kzalloc(size, GFP_ATOMIC);
- if (!l3_caches)
- return;
- }
-
- node = amd_get_nb_id(smp_processor_id());
-
- if (!l3_caches[node]) {
- l3_caches[node] = amd_init_l3_cache(node);
- l3_caches[node]->can_disable = true;
- }
-
- WARN_ON(!l3_caches[node]);
-
- this_leaf->l3 = l3_caches[node];
+ this_leaf->can_disable = true;
+ this_leaf->l3_indices = amd_calc_l3_indices();
}
static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
- unsigned int slot)
+ unsigned int index)
{
- struct pci_dev *dev = this_leaf->l3->dev;
+ int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
+ int node = amd_get_nb_id(cpu);
+ struct pci_dev *dev = node_to_k8_nb_misc(node);
unsigned int reg = 0;
- if (!this_leaf->l3 || !this_leaf->l3->can_disable)
+ if (!this_leaf->can_disable)
return -EINVAL;
if (!dev)
return -EINVAL;
- pci_read_config_dword(dev, 0x1BC + slot * 4, ®);
+ pci_read_config_dword(dev, 0x1BC + index * 4, ®);
return sprintf(buf, "0x%08x\n", reg);
}
-#define SHOW_CACHE_DISABLE(slot) \
+#define SHOW_CACHE_DISABLE(index) \
static ssize_t \
-show_cache_disable_##slot(struct _cpuid4_info *this_leaf, char *buf) \
+show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \
{ \
- return show_cache_disable(this_leaf, buf, slot); \
+ return show_cache_disable(this_leaf, buf, index); \
}
SHOW_CACHE_DISABLE(0)
SHOW_CACHE_DISABLE(1)
-static void amd_l3_disable_index(struct amd_l3_cache *l3, int cpu,
- unsigned slot, unsigned long idx)
-{
- int i;
-
- idx |= BIT(30);
-
- /*
- * disable index in all 4 subcaches
- */
- for (i = 0; i < 4; i++) {
- u32 reg = idx | (i << 20);
-
- if (!l3->subcaches[i])
- continue;
-
- pci_write_config_dword(l3->dev, 0x1BC + slot * 4, reg);
-
- /*
- * We need to WBINVD on a core on the node containing the L3
- * cache which indices we disable therefore a simple wbinvd()
- * is not sufficient.
- */
- wbinvd_on_cpu(cpu);
-
- reg |= BIT(31);
- pci_write_config_dword(l3->dev, 0x1BC + slot * 4, reg);
- }
-}
-
-
static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
- const char *buf, size_t count,
- unsigned int slot)
+ const char *buf, size_t count, unsigned int index)
{
- struct pci_dev *dev = this_leaf->l3->dev;
int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
+ int node = amd_get_nb_id(cpu);
+ struct pci_dev *dev = node_to_k8_nb_misc(node);
unsigned long val = 0;
#define SUBCACHE_MASK (3UL << 20)
#define SUBCACHE_INDEX 0xfff
- if (!this_leaf->l3 || !this_leaf->l3->can_disable)
+ if (!this_leaf->can_disable)
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
@@ -477,20 +396,26 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
/* do not allow writes outside of allowed bits */
if ((val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) ||
- ((val & SUBCACHE_INDEX) > this_leaf->l3->indices))
+ ((val & SUBCACHE_INDEX) > this_leaf->l3_indices))
return -EINVAL;
- amd_l3_disable_index(this_leaf->l3, cpu, slot, val);
-
+ val |= BIT(30);
+ pci_write_config_dword(dev, 0x1BC + index * 4, val);
+ /*
+ * We need to WBINVD on a core on the node containing the L3 cache which
+ * indices we disable therefore a simple wbinvd() is not sufficient.
+ */
+ wbinvd_on_cpu(cpu);
+ pci_write_config_dword(dev, 0x1BC + index * 4, val | BIT(31));
return count;
}
-#define STORE_CACHE_DISABLE(slot) \
+#define STORE_CACHE_DISABLE(index) \
static ssize_t \
-store_cache_disable_##slot(struct _cpuid4_info *this_leaf, \
+store_cache_disable_##index(struct _cpuid4_info *this_leaf, \
const char *buf, size_t count) \
{ \
- return store_cache_disable(this_leaf, buf, count, slot); \
+ return store_cache_disable(this_leaf, buf, count, index); \
}
STORE_CACHE_DISABLE(0)
STORE_CACHE_DISABLE(1)
@@ -518,7 +443,8 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
amd_cpuid4(index, &eax, &ebx, &ecx);
- amd_check_l3_disable(index, this_leaf);
+ if (boot_cpu_data.x86 >= 0x10)
+ amd_check_l3_disable(index, this_leaf);
} else {
cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
}
@@ -775,7 +701,6 @@ static void __cpuinit free_cache_attributes(unsigned int cpu)
for (i = 0; i < num_cache_leaves; i++)
cache_remove_shared_cpu_map(cpu, i);
- kfree(per_cpu(ici_cpuid4_info, cpu)->l3);
kfree(per_cpu(ici_cpuid4_info, cpu));
per_cpu(ici_cpuid4_info, cpu) = NULL;
}
@@ -1060,7 +985,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
this_leaf = CPUID4_INFO_IDX(cpu, i);
- if (this_leaf->l3 && this_leaf->l3->can_disable)
+ if (this_leaf->can_disable)
ktype_cache.default_attrs = default_l3_attrs;
else
ktype_cache.default_attrs = default_attrs;
diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce.c b/trunk/arch/x86/kernel/cpu/mcheck/mce.c
index 7a355ddcc64b..8a6f0afa767e 100644
--- a/trunk/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/trunk/arch/x86/kernel/cpu/mcheck/mce.c
@@ -539,7 +539,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
struct mce m;
int i;
- percpu_inc(mce_poll_count);
+ __get_cpu_var(mce_poll_count)++;
mce_setup(&m);
@@ -934,7 +934,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
atomic_inc(&mce_entry);
- percpu_inc(mce_exception_count);
+ __get_cpu_var(mce_exception_count)++;
if (notify_die(DIE_NMI, "machine check", regs, error_code,
18, SIGKILL) == NOTIFY_STOP)
diff --git a/trunk/arch/x86/kernel/cpu/mshyperv.c b/trunk/arch/x86/kernel/cpu/mshyperv.c
deleted file mode 100644
index 16f41bbe46b6..000000000000
--- a/trunk/arch/x86/kernel/cpu/mshyperv.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * HyperV Detection code.
- *
- * Copyright (C) 2010, Novell, Inc.
- * Author : K. Y. Srinivasan
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-struct ms_hyperv_info ms_hyperv;
-
-static bool __init ms_hyperv_platform(void)
-{
- u32 eax;
- u32 hyp_signature[3];
-
- if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
- return false;
-
- cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS,
- &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]);
-
- return eax >= HYPERV_CPUID_MIN &&
- eax <= HYPERV_CPUID_MAX &&
- !memcmp("Microsoft Hv", hyp_signature, 12);
-}
-
-static void __init ms_hyperv_init_platform(void)
-{
- /*
- * Extract the features and hints
- */
- ms_hyperv.features = cpuid_eax(HYPERV_CPUID_FEATURES);
- ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
-
- printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n",
- ms_hyperv.features, ms_hyperv.hints);
-}
-
-const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
- .name = "Microsoft HyperV",
- .detect = ms_hyperv_platform,
- .init_platform = ms_hyperv_init_platform,
-};
-EXPORT_SYMBOL(x86_hyper_ms_hyperv);
diff --git a/trunk/arch/x86/kernel/cpu/perf_event.c b/trunk/arch/x86/kernel/cpu/perf_event.c
index fd4db0db3708..db5bdc8addf8 100644
--- a/trunk/arch/x86/kernel/cpu/perf_event.c
+++ b/trunk/arch/x86/kernel/cpu/perf_event.c
@@ -31,51 +31,46 @@
#include
#include
-#if 0
-#undef wrmsrl
-#define wrmsrl(msr, val) \
-do { \
- trace_printk("wrmsrl(%lx, %lx)\n", (unsigned long)(msr),\
- (unsigned long)(val)); \
- native_write_msr((msr), (u32)((u64)(val)), \
- (u32)((u64)(val) >> 32)); \
-} while (0)
-#endif
+static u64 perf_event_mask __read_mostly;
-/*
- * best effort, GUP based copy_from_user() that assumes IRQ or NMI context
- */
-static unsigned long
-copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
-{
- unsigned long offset, addr = (unsigned long)from;
- int type = in_nmi() ? KM_NMI : KM_IRQ0;
- unsigned long size, len = 0;
- struct page *page;
- void *map;
- int ret;
+/* The maximal number of PEBS events: */
+#define MAX_PEBS_EVENTS 4
- do {
- ret = __get_user_pages_fast(addr, 1, 0, &page);
- if (!ret)
- break;
+/* The size of a BTS record in bytes: */
+#define BTS_RECORD_SIZE 24
- offset = addr & (PAGE_SIZE - 1);
- size = min(PAGE_SIZE - offset, n - len);
+/* The size of a per-cpu BTS buffer in bytes: */
+#define BTS_BUFFER_SIZE (BTS_RECORD_SIZE * 2048)
- map = kmap_atomic(page, type);
- memcpy(to, map+offset, size);
- kunmap_atomic(map, type);
- put_page(page);
+/* The BTS overflow threshold in bytes from the end of the buffer: */
+#define BTS_OVFL_TH (BTS_RECORD_SIZE * 128)
- len += size;
- to += size;
- addr += size;
- } while (len < n);
+/*
+ * Bits in the debugctlmsr controlling branch tracing.
+ */
+#define X86_DEBUGCTL_TR (1 << 6)
+#define X86_DEBUGCTL_BTS (1 << 7)
+#define X86_DEBUGCTL_BTINT (1 << 8)
+#define X86_DEBUGCTL_BTS_OFF_OS (1 << 9)
+#define X86_DEBUGCTL_BTS_OFF_USR (1 << 10)
- return len;
-}
+/*
+ * A debug store configuration.
+ *
+ * We only support architectures that use 64bit fields.
+ */
+struct debug_store {
+ u64 bts_buffer_base;
+ u64 bts_index;
+ u64 bts_absolute_maximum;
+ u64 bts_interrupt_threshold;
+ u64 pebs_buffer_base;
+ u64 pebs_index;
+ u64 pebs_absolute_maximum;
+ u64 pebs_interrupt_threshold;
+ u64 pebs_event_reset[MAX_PEBS_EVENTS];
+};
struct event_constraint {
union {
@@ -94,41 +89,18 @@ struct amd_nb {
struct event_constraint event_constraints[X86_PMC_IDX_MAX];
};
-#define MAX_LBR_ENTRIES 16
-
struct cpu_hw_events {
- /*
- * Generic x86 PMC bits
- */
struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */
unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+ unsigned long interrupts;
int enabled;
+ struct debug_store *ds;
int n_events;
int n_added;
int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
u64 tags[X86_PMC_IDX_MAX];
struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */
-
- unsigned int group_flag;
-
- /*
- * Intel DebugStore bits
- */
- struct debug_store *ds;
- u64 pebs_enabled;
-
- /*
- * Intel LBR bits
- */
- int lbr_users;
- void *lbr_context;
- struct perf_branch_stack lbr_stack;
- struct perf_branch_entry lbr_entries[MAX_LBR_ENTRIES];
-
- /*
- * AMD specific bits
- */
struct amd_nb *amd_nb;
};
@@ -142,75 +114,44 @@ struct cpu_hw_events {
#define EVENT_CONSTRAINT(c, n, m) \
__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n))
-/*
- * Constraint on the Event code.
- */
#define INTEL_EVENT_CONSTRAINT(c, n) \
- EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)
+ EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVTSEL_MASK)
-/*
- * Constraint on the Event code + UMask + fixed-mask
- *
- * filter mask to validate fixed counter events.
- * the following filters disqualify for fixed counters:
- * - inv
- * - edge
- * - cnt-mask
- * The other filters are supported by fixed counters.
- * The any-thread option is supported starting with v3.
- */
#define FIXED_EVENT_CONSTRAINT(c, n) \
- EVENT_CONSTRAINT(c, (1ULL << (32+n)), X86_RAW_EVENT_MASK)
-
-/*
- * Constraint on the Event code + UMask
- */
-#define PEBS_EVENT_CONSTRAINT(c, n) \
- EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
+ EVENT_CONSTRAINT(c, (1ULL << (32+n)), INTEL_ARCH_FIXED_MASK)
#define EVENT_CONSTRAINT_END \
EVENT_CONSTRAINT(0, 0, 0)
#define for_each_event_constraint(e, c) \
- for ((e) = (c); (e)->weight; (e)++)
-
-union perf_capabilities {
- struct {
- u64 lbr_format : 6;
- u64 pebs_trap : 1;
- u64 pebs_arch_reg : 1;
- u64 pebs_format : 4;
- u64 smm_freeze : 1;
- };
- u64 capabilities;
-};
+ for ((e) = (c); (e)->cmask; (e)++)
/*
* struct x86_pmu - generic x86 pmu
*/
struct x86_pmu {
- /*
- * Generic x86 PMC bits
- */
const char *name;
int version;
int (*handle_irq)(struct pt_regs *);
void (*disable_all)(void);
- void (*enable_all)(int added);
+ void (*enable_all)(void);
void (*enable)(struct perf_event *);
void (*disable)(struct perf_event *);
- int (*hw_config)(struct perf_event *event);
- int (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign);
unsigned eventsel;
unsigned perfctr;
u64 (*event_map)(int);
+ u64 (*raw_event)(u64);
int max_events;
- int num_counters;
- int num_counters_fixed;
- int cntval_bits;
- u64 cntval_mask;
+ int num_events;
+ int num_events_fixed;
+ int event_bits;
+ u64 event_mask;
int apic;
u64 max_period;
+ u64 intel_ctrl;
+ void (*enable_bts)(u64 config);
+ void (*disable_bts)(void);
+
struct event_constraint *
(*get_event_constraints)(struct cpu_hw_events *cpuc,
struct perf_event *event);
@@ -218,32 +159,11 @@ struct x86_pmu {
void (*put_event_constraints)(struct cpu_hw_events *cpuc,
struct perf_event *event);
struct event_constraint *event_constraints;
- void (*quirks)(void);
int (*cpu_prepare)(int cpu);
void (*cpu_starting)(int cpu);
void (*cpu_dying)(int cpu);
void (*cpu_dead)(int cpu);
-
- /*
- * Intel Arch Perfmon v2+
- */
- u64 intel_ctrl;
- union perf_capabilities intel_cap;
-
- /*
- * Intel DebugStore bits
- */
- int bts, pebs;
- int pebs_record_size;
- void (*drain_pebs)(struct pt_regs *regs);
- struct event_constraint *pebs_constraints;
-
- /*
- * Intel LBR
- */
- unsigned long lbr_tos, lbr_from, lbr_to; /* MSR base regs */
- int lbr_nr; /* hardware stack size */
};
static struct x86_pmu x86_pmu __read_mostly;
@@ -278,7 +198,7 @@ static u64
x86_perf_event_update(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
- int shift = 64 - x86_pmu.cntval_bits;
+ int shift = 64 - x86_pmu.event_bits;
u64 prev_raw_count, new_raw_count;
int idx = hwc->idx;
s64 delta;
@@ -321,32 +241,33 @@ x86_perf_event_update(struct perf_event *event)
static atomic_t active_events;
static DEFINE_MUTEX(pmc_reserve_mutex);
-#ifdef CONFIG_X86_LOCAL_APIC
-
static bool reserve_pmc_hardware(void)
{
+#ifdef CONFIG_X86_LOCAL_APIC
int i;
if (nmi_watchdog == NMI_LOCAL_APIC)
disable_lapic_nmi_watchdog();
- for (i = 0; i < x86_pmu.num_counters; i++) {
+ for (i = 0; i < x86_pmu.num_events; i++) {
if (!reserve_perfctr_nmi(x86_pmu.perfctr + i))
goto perfctr_fail;
}
- for (i = 0; i < x86_pmu.num_counters; i++) {
+ for (i = 0; i < x86_pmu.num_events; i++) {
if (!reserve_evntsel_nmi(x86_pmu.eventsel + i))
goto eventsel_fail;
}
+#endif
return true;
+#ifdef CONFIG_X86_LOCAL_APIC
eventsel_fail:
for (i--; i >= 0; i--)
release_evntsel_nmi(x86_pmu.eventsel + i);
- i = x86_pmu.num_counters;
+ i = x86_pmu.num_events;
perfctr_fail:
for (i--; i >= 0; i--)
@@ -356,36 +277,128 @@ static bool reserve_pmc_hardware(void)
enable_lapic_nmi_watchdog();
return false;
+#endif
}
static void release_pmc_hardware(void)
{
+#ifdef CONFIG_X86_LOCAL_APIC
int i;
- for (i = 0; i < x86_pmu.num_counters; i++) {
+ for (i = 0; i < x86_pmu.num_events; i++) {
release_perfctr_nmi(x86_pmu.perfctr + i);
release_evntsel_nmi(x86_pmu.eventsel + i);
}
if (nmi_watchdog == NMI_LOCAL_APIC)
enable_lapic_nmi_watchdog();
+#endif
}
-#else
+static inline bool bts_available(void)
+{
+ return x86_pmu.enable_bts != NULL;
+}
-static bool reserve_pmc_hardware(void) { return true; }
-static void release_pmc_hardware(void) {}
+static void init_debug_store_on_cpu(int cpu)
+{
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-#endif
+ if (!ds)
+ return;
+
+ wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
+ (u32)((u64)(unsigned long)ds),
+ (u32)((u64)(unsigned long)ds >> 32));
+}
-static int reserve_ds_buffers(void);
-static void release_ds_buffers(void);
+static void fini_debug_store_on_cpu(int cpu)
+{
+ if (!per_cpu(cpu_hw_events, cpu).ds)
+ return;
+
+ wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
+}
+
+static void release_bts_hardware(void)
+{
+ int cpu;
+
+ if (!bts_available())
+ return;
+
+ get_online_cpus();
+
+ for_each_online_cpu(cpu)
+ fini_debug_store_on_cpu(cpu);
+
+ for_each_possible_cpu(cpu) {
+ struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+ if (!ds)
+ continue;
+
+ per_cpu(cpu_hw_events, cpu).ds = NULL;
+
+ kfree((void *)(unsigned long)ds->bts_buffer_base);
+ kfree(ds);
+ }
+
+ put_online_cpus();
+}
+
+static int reserve_bts_hardware(void)
+{
+ int cpu, err = 0;
+
+ if (!bts_available())
+ return 0;
+
+ get_online_cpus();
+
+ for_each_possible_cpu(cpu) {
+ struct debug_store *ds;
+ void *buffer;
+
+ err = -ENOMEM;
+ buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
+ if (unlikely(!buffer))
+ break;
+
+ ds = kzalloc(sizeof(*ds), GFP_KERNEL);
+ if (unlikely(!ds)) {
+ kfree(buffer);
+ break;
+ }
+
+ ds->bts_buffer_base = (u64)(unsigned long)buffer;
+ ds->bts_index = ds->bts_buffer_base;
+ ds->bts_absolute_maximum =
+ ds->bts_buffer_base + BTS_BUFFER_SIZE;
+ ds->bts_interrupt_threshold =
+ ds->bts_absolute_maximum - BTS_OVFL_TH;
+
+ per_cpu(cpu_hw_events, cpu).ds = ds;
+ err = 0;
+ }
+
+ if (err)
+ release_bts_hardware();
+ else {
+ for_each_online_cpu(cpu)
+ init_debug_store_on_cpu(cpu);
+ }
+
+ put_online_cpus();
+
+ return err;
+}
static void hw_perf_event_destroy(struct perf_event *event)
{
if (atomic_dec_and_mutex_lock(&active_events, &pmc_reserve_mutex)) {
release_pmc_hardware();
- release_ds_buffers();
+ release_bts_hardware();
mutex_unlock(&pmc_reserve_mutex);
}
}
@@ -428,11 +441,54 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event_attr *attr)
return 0;
}
-static int x86_setup_perfctr(struct perf_event *event)
+/*
+ * Setup the hardware configuration for a given attr_type
+ */
+static int __hw_perf_event_init(struct perf_event *event)
{
struct perf_event_attr *attr = &event->attr;
struct hw_perf_event *hwc = &event->hw;
u64 config;
+ int err;
+
+ if (!x86_pmu_initialized())
+ return -ENODEV;
+
+ err = 0;
+ if (!atomic_inc_not_zero(&active_events)) {
+ mutex_lock(&pmc_reserve_mutex);
+ if (atomic_read(&active_events) == 0) {
+ if (!reserve_pmc_hardware())
+ err = -EBUSY;
+ else
+ err = reserve_bts_hardware();
+ }
+ if (!err)
+ atomic_inc(&active_events);
+ mutex_unlock(&pmc_reserve_mutex);
+ }
+ if (err)
+ return err;
+
+ event->destroy = hw_perf_event_destroy;
+
+ /*
+ * Generate PMC IRQs:
+ * (keep 'enabled' bit clear for now)
+ */
+ hwc->config = ARCH_PERFMON_EVENTSEL_INT;
+
+ hwc->idx = -1;
+ hwc->last_cpu = -1;
+ hwc->last_tag = ~0ULL;
+
+ /*
+ * Count user and OS events unless requested not to.
+ */
+ if (!attr->exclude_user)
+ hwc->config |= ARCH_PERFMON_EVENTSEL_USR;
+ if (!attr->exclude_kernel)
+ hwc->config |= ARCH_PERFMON_EVENTSEL_OS;
if (!hwc->sample_period) {
hwc->sample_period = x86_pmu.max_period;
@@ -449,8 +505,16 @@ static int x86_setup_perfctr(struct perf_event *event)
return -EOPNOTSUPP;
}
- if (attr->type == PERF_TYPE_RAW)
+ /*
+ * Raw hw_event type provide the config in the hw_event structure
+ */
+ if (attr->type == PERF_TYPE_RAW) {
+ hwc->config |= x86_pmu.raw_event(attr->config);
+ if ((hwc->config & ARCH_PERFMON_EVENTSEL_ANY) &&
+ perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
+ return -EACCES;
return 0;
+ }
if (attr->type == PERF_TYPE_HW_CACHE)
return set_ext_hw_attr(hwc, attr);
@@ -475,11 +539,11 @@ static int x86_setup_perfctr(struct perf_event *event)
if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
(hwc->sample_period == 1)) {
/* BTS is not supported by this architecture. */
- if (!x86_pmu.bts)
+ if (!bts_available())
return -EOPNOTSUPP;
/* BTS is currently only allowed for user-mode. */
- if (!attr->exclude_kernel)
+ if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
return -EOPNOTSUPP;
}
@@ -488,87 +552,12 @@ static int x86_setup_perfctr(struct perf_event *event)
return 0;
}
-static int x86_pmu_hw_config(struct perf_event *event)
-{
- if (event->attr.precise_ip) {
- int precise = 0;
-
- /* Support for constant skid */
- if (x86_pmu.pebs)
- precise++;
-
- /* Support for IP fixup */
- if (x86_pmu.lbr_nr)
- precise++;
-
- if (event->attr.precise_ip > precise)
- return -EOPNOTSUPP;
- }
-
- /*
- * Generate PMC IRQs:
- * (keep 'enabled' bit clear for now)
- */
- event->hw.config = ARCH_PERFMON_EVENTSEL_INT;
-
- /*
- * Count user and OS events unless requested not to
- */
- if (!event->attr.exclude_user)
- event->hw.config |= ARCH_PERFMON_EVENTSEL_USR;
- if (!event->attr.exclude_kernel)
- event->hw.config |= ARCH_PERFMON_EVENTSEL_OS;
-
- if (event->attr.type == PERF_TYPE_RAW)
- event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK;
-
- return x86_setup_perfctr(event);
-}
-
-/*
- * Setup the hardware configuration for a given attr_type
- */
-static int __hw_perf_event_init(struct perf_event *event)
-{
- int err;
-
- if (!x86_pmu_initialized())
- return -ENODEV;
-
- err = 0;
- if (!atomic_inc_not_zero(&active_events)) {
- mutex_lock(&pmc_reserve_mutex);
- if (atomic_read(&active_events) == 0) {
- if (!reserve_pmc_hardware())
- err = -EBUSY;
- else {
- err = reserve_ds_buffers();
- if (err)
- release_pmc_hardware();
- }
- }
- if (!err)
- atomic_inc(&active_events);
- mutex_unlock(&pmc_reserve_mutex);
- }
- if (err)
- return err;
-
- event->destroy = hw_perf_event_destroy;
-
- event->hw.idx = -1;
- event->hw.last_cpu = -1;
- event->hw.last_tag = ~0ULL;
-
- return x86_pmu.hw_config(event);
-}
-
static void x86_pmu_disable_all(void)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
int idx;
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for (idx = 0; idx < x86_pmu.num_events; idx++) {
u64 val;
if (!test_bit(idx, cpuc->active_mask))
@@ -598,12 +587,12 @@ void hw_perf_disable(void)
x86_pmu.disable_all();
}
-static void x86_pmu_enable_all(int added)
+static void x86_pmu_enable_all(void)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
int idx;
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for (idx = 0; idx < x86_pmu.num_events; idx++) {
struct perf_event *event = cpuc->events[idx];
u64 val;
@@ -678,14 +667,14 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
* assign events to counters starting with most
* constrained events.
*/
- wmax = x86_pmu.num_counters;
+ wmax = x86_pmu.num_events;
/*
* when fixed event counters are present,
* wmax is incremented by 1 to account
* for one more choice
*/
- if (x86_pmu.num_counters_fixed)
+ if (x86_pmu.num_events_fixed)
wmax++;
for (w = 1, num = n; num && w <= wmax; w++) {
@@ -735,7 +724,7 @@ static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader,
struct perf_event *event;
int n, max_count;
- max_count = x86_pmu.num_counters + x86_pmu.num_counters_fixed;
+ max_count = x86_pmu.num_events + x86_pmu.num_events_fixed;
/* current number of events already accepted */
n = cpuc->n_events;
@@ -806,7 +795,7 @@ void hw_perf_enable(void)
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct perf_event *event;
struct hw_perf_event *hwc;
- int i, added = cpuc->n_added;
+ int i;
if (!x86_pmu_initialized())
return;
@@ -858,20 +847,19 @@ void hw_perf_enable(void)
cpuc->enabled = 1;
barrier();
- x86_pmu.enable_all(added);
+ x86_pmu.enable_all();
}
-static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc,
- u64 enable_mask)
+static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc)
{
- wrmsrl(hwc->config_base + hwc->idx, hwc->config | enable_mask);
+ (void)checking_wrmsrl(hwc->config_base + hwc->idx,
+ hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE);
}
static inline void x86_pmu_disable_event(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
-
- wrmsrl(hwc->config_base + hwc->idx, hwc->config);
+ (void)checking_wrmsrl(hwc->config_base + hwc->idx, hwc->config);
}
static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
@@ -886,7 +874,7 @@ x86_perf_event_set_period(struct perf_event *event)
struct hw_perf_event *hwc = &event->hw;
s64 left = atomic64_read(&hwc->period_left);
s64 period = hwc->sample_period;
- int ret = 0, idx = hwc->idx;
+ int err, ret = 0, idx = hwc->idx;
if (idx == X86_PMC_IDX_FIXED_BTS)
return 0;
@@ -924,8 +912,8 @@ x86_perf_event_set_period(struct perf_event *event)
*/
atomic64_set(&hwc->prev_count, (u64)-left);
- wrmsrl(hwc->event_base + idx,
- (u64)(-left) & x86_pmu.cntval_mask);
+ err = checking_wrmsrl(hwc->event_base + idx,
+ (u64)(-left) & x86_pmu.event_mask);
perf_event_update_userpage(event);
@@ -936,8 +924,7 @@ static void x86_pmu_enable_event(struct perf_event *event)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
if (cpuc->enabled)
- __x86_pmu_enable_event(&event->hw,
- ARCH_PERFMON_EVENTSEL_ENABLE);
+ __x86_pmu_enable_event(&event->hw);
}
/*
@@ -963,15 +950,7 @@ static int x86_pmu_enable(struct perf_event *event)
if (n < 0)
return n;
- /*
- * If group events scheduling transaction was started,
- * skip the schedulability test here, it will be peformed
- * at commit time(->commit_txn) as a whole
- */
- if (cpuc->group_flag & PERF_EVENT_TXN_STARTED)
- goto out;
-
- ret = x86_pmu.schedule_events(cpuc, n, assign);
+ ret = x86_schedule_events(cpuc, n, assign);
if (ret)
return ret;
/*
@@ -980,7 +959,6 @@ static int x86_pmu_enable(struct perf_event *event)
*/
memcpy(cpuc->assign, assign, n*sizeof(int));
-out:
cpuc->n_events = n;
cpuc->n_added += n - n0;
@@ -1013,12 +991,11 @@ static void x86_pmu_unthrottle(struct perf_event *event)
void perf_event_print_debug(void)
{
u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left, fixed;
- u64 pebs;
struct cpu_hw_events *cpuc;
unsigned long flags;
int cpu, idx;
- if (!x86_pmu.num_counters)
+ if (!x86_pmu.num_events)
return;
local_irq_save(flags);
@@ -1031,18 +1008,16 @@ void perf_event_print_debug(void)
rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow);
rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed);
- rdmsrl(MSR_IA32_PEBS_ENABLE, pebs);
pr_info("\n");
pr_info("CPU#%d: ctrl: %016llx\n", cpu, ctrl);
pr_info("CPU#%d: status: %016llx\n", cpu, status);
pr_info("CPU#%d: overflow: %016llx\n", cpu, overflow);
pr_info("CPU#%d: fixed: %016llx\n", cpu, fixed);
- pr_info("CPU#%d: pebs: %016llx\n", cpu, pebs);
}
- pr_info("CPU#%d: active: %016llx\n", cpu, *(u64 *)cpuc->active_mask);
+ pr_info("CPU#%d: active: %016llx\n", cpu, *(u64 *)cpuc->active_mask);
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for (idx = 0; idx < x86_pmu.num_events; idx++) {
rdmsrl(x86_pmu.eventsel + idx, pmc_ctrl);
rdmsrl(x86_pmu.perfctr + idx, pmc_count);
@@ -1055,7 +1030,7 @@ void perf_event_print_debug(void)
pr_info("CPU#%d: gen-PMC%d left: %016llx\n",
cpu, idx, prev_left);
}
- for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) {
+ for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) {
rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count);
pr_info("CPU#%d: fixed-PMC%d count: %016llx\n",
@@ -1120,7 +1095,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
cpuc = &__get_cpu_var(cpu_hw_events);
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for (idx = 0; idx < x86_pmu.num_events; idx++) {
if (!test_bit(idx, cpuc->active_mask))
continue;
@@ -1128,7 +1103,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
hwc = &event->hw;
val = x86_perf_event_update(event);
- if (val & (1ULL << (x86_pmu.cntval_bits - 1)))
+ if (val & (1ULL << (x86_pmu.event_bits - 1)))
continue;
/*
@@ -1171,6 +1146,7 @@ void set_perf_event_pending(void)
void perf_events_lapic_init(void)
{
+#ifdef CONFIG_X86_LOCAL_APIC
if (!x86_pmu.apic || !x86_pmu_initialized())
return;
@@ -1178,6 +1154,7 @@ void perf_events_lapic_init(void)
* Always use NMI for PMU
*/
apic_write(APIC_LVTPC, APIC_DM_NMI);
+#endif
}
static int __kprobes
@@ -1201,7 +1178,9 @@ perf_event_nmi_handler(struct notifier_block *self,
regs = args->regs;
+#ifdef CONFIG_X86_LOCAL_APIC
apic_write(APIC_LVTPC, APIC_DM_NMI);
+#endif
/*
* Can't rely on the handled return value to say it was our NMI, two
* events could trigger 'simultaneously' raising two back-to-back NMIs.
@@ -1238,11 +1217,118 @@ x86_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
return &unconstrained;
}
+static int x86_event_sched_in(struct perf_event *event,
+ struct perf_cpu_context *cpuctx)
+{
+ int ret = 0;
+
+ event->state = PERF_EVENT_STATE_ACTIVE;
+ event->oncpu = smp_processor_id();
+ event->tstamp_running += event->ctx->time - event->tstamp_stopped;
+
+ if (!is_x86_event(event))
+ ret = event->pmu->enable(event);
+
+ if (!ret && !is_software_event(event))
+ cpuctx->active_oncpu++;
+
+ if (!ret && event->attr.exclusive)
+ cpuctx->exclusive = 1;
+
+ return ret;
+}
+
+static void x86_event_sched_out(struct perf_event *event,
+ struct perf_cpu_context *cpuctx)
+{
+ event->state = PERF_EVENT_STATE_INACTIVE;
+ event->oncpu = -1;
+
+ if (!is_x86_event(event))
+ event->pmu->disable(event);
+
+ event->tstamp_running -= event->ctx->time - event->tstamp_stopped;
+
+ if (!is_software_event(event))
+ cpuctx->active_oncpu--;
+
+ if (event->attr.exclusive || !cpuctx->active_oncpu)
+ cpuctx->exclusive = 0;
+}
+
+/*
+ * Called to enable a whole group of events.
+ * Returns 1 if the group was enabled, or -EAGAIN if it could not be.
+ * Assumes the caller has disabled interrupts and has
+ * frozen the PMU with hw_perf_save_disable.
+ *
+ * called with PMU disabled. If successful and return value 1,
+ * then guaranteed to call perf_enable() and hw_perf_enable()
+ */
+int hw_perf_group_sched_in(struct perf_event *leader,
+ struct perf_cpu_context *cpuctx,
+ struct perf_event_context *ctx)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct perf_event *sub;
+ int assign[X86_PMC_IDX_MAX];
+ int n0, n1, ret;
+
+ /* n0 = total number of events */
+ n0 = collect_events(cpuc, leader, true);
+ if (n0 < 0)
+ return n0;
+
+ ret = x86_schedule_events(cpuc, n0, assign);
+ if (ret)
+ return ret;
+
+ ret = x86_event_sched_in(leader, cpuctx);
+ if (ret)
+ return ret;
+
+ n1 = 1;
+ list_for_each_entry(sub, &leader->sibling_list, group_entry) {
+ if (sub->state > PERF_EVENT_STATE_OFF) {
+ ret = x86_event_sched_in(sub, cpuctx);
+ if (ret)
+ goto undo;
+ ++n1;
+ }
+ }
+ /*
+ * copy new assignment, now we know it is possible
+ * will be used by hw_perf_enable()
+ */
+ memcpy(cpuc->assign, assign, n0*sizeof(int));
+
+ cpuc->n_events = n0;
+ cpuc->n_added += n1;
+ ctx->nr_active += n1;
+
+ /*
+ * 1 means successful and events are active
+ * This is not quite true because we defer
+ * actual activation until hw_perf_enable() but
+ * this way we* ensure caller won't try to enable
+ * individual events
+ */
+ return 1;
+undo:
+ x86_event_sched_out(leader, cpuctx);
+ n0 = 1;
+ list_for_each_entry(sub, &leader->sibling_list, group_entry) {
+ if (sub->state == PERF_EVENT_STATE_ACTIVE) {
+ x86_event_sched_out(sub, cpuctx);
+ if (++n0 == n1)
+ break;
+ }
+ }
+ return ret;
+}
+
#include "perf_event_amd.c"
#include "perf_event_p6.c"
-#include "perf_event_p4.c"
-#include "perf_event_intel_lbr.c"
-#include "perf_event_intel_ds.c"
#include "perf_event_intel.c"
static int __cpuinit
@@ -1316,50 +1402,48 @@ void __init init_hw_perf_events(void)
pr_cont("%s PMU driver.\n", x86_pmu.name);
- if (x86_pmu.quirks)
- x86_pmu.quirks();
-
- if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) {
+ if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) {
WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
- x86_pmu.num_counters, X86_PMC_MAX_GENERIC);
- x86_pmu.num_counters = X86_PMC_MAX_GENERIC;
+ x86_pmu.num_events, X86_PMC_MAX_GENERIC);
+ x86_pmu.num_events = X86_PMC_MAX_GENERIC;
}
- x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
- perf_max_events = x86_pmu.num_counters;
+ perf_event_mask = (1 << x86_pmu.num_events) - 1;
+ perf_max_events = x86_pmu.num_events;
- if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) {
+ if (x86_pmu.num_events_fixed > X86_PMC_MAX_FIXED) {
WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
- x86_pmu.num_counters_fixed, X86_PMC_MAX_FIXED);
- x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED;
+ x86_pmu.num_events_fixed, X86_PMC_MAX_FIXED);
+ x86_pmu.num_events_fixed = X86_PMC_MAX_FIXED;
}
- x86_pmu.intel_ctrl |=
- ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED;
+ perf_event_mask |=
+ ((1LL << x86_pmu.num_events_fixed)-1) << X86_PMC_IDX_FIXED;
+ x86_pmu.intel_ctrl = perf_event_mask;
perf_events_lapic_init();
register_die_notifier(&perf_event_nmi_notifier);
unconstrained = (struct event_constraint)
- __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,
- 0, x86_pmu.num_counters);
+ __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_events) - 1,
+ 0, x86_pmu.num_events);
if (x86_pmu.event_constraints) {
for_each_event_constraint(c, x86_pmu.event_constraints) {
- if (c->cmask != X86_RAW_EVENT_MASK)
+ if (c->cmask != INTEL_ARCH_FIXED_MASK)
continue;
- c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
- c->weight += x86_pmu.num_counters;
+ c->idxmsk64 |= (1ULL << x86_pmu.num_events) - 1;
+ c->weight += x86_pmu.num_events;
}
}
pr_info("... version: %d\n", x86_pmu.version);
- pr_info("... bit width: %d\n", x86_pmu.cntval_bits);
- pr_info("... generic registers: %d\n", x86_pmu.num_counters);
- pr_info("... value mask: %016Lx\n", x86_pmu.cntval_mask);
+ pr_info("... bit width: %d\n", x86_pmu.event_bits);
+ pr_info("... generic registers: %d\n", x86_pmu.num_events);
+ pr_info("... value mask: %016Lx\n", x86_pmu.event_mask);
pr_info("... max period: %016Lx\n", x86_pmu.max_period);
- pr_info("... fixed-purpose events: %d\n", x86_pmu.num_counters_fixed);
- pr_info("... event mask: %016Lx\n", x86_pmu.intel_ctrl);
+ pr_info("... fixed-purpose events: %d\n", x86_pmu.num_events_fixed);
+ pr_info("... event mask: %016Lx\n", perf_event_mask);
perf_cpu_notifier(x86_pmu_notifier);
}
@@ -1369,59 +1453,6 @@ static inline void x86_pmu_read(struct perf_event *event)
x86_perf_event_update(event);
}
-/*
- * Start group events scheduling transaction
- * Set the flag to make pmu::enable() not perform the
- * schedulability test, it will be performed at commit time
- */
-static void x86_pmu_start_txn(const struct pmu *pmu)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-
- cpuc->group_flag |= PERF_EVENT_TXN_STARTED;
-}
-
-/*
- * Stop group events scheduling transaction
- * Clear the flag and pmu::enable() will perform the
- * schedulability test.
- */
-static void x86_pmu_cancel_txn(const struct pmu *pmu)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-
- cpuc->group_flag &= ~PERF_EVENT_TXN_STARTED;
-}
-
-/*
- * Commit group events scheduling transaction
- * Perform the group schedulability test as a whole
- * Return 0 if success
- */
-static int x86_pmu_commit_txn(const struct pmu *pmu)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- int assign[X86_PMC_IDX_MAX];
- int n, ret;
-
- n = cpuc->n_events;
-
- if (!x86_pmu_initialized())
- return -EAGAIN;
-
- ret = x86_pmu.schedule_events(cpuc, n, assign);
- if (ret)
- return ret;
-
- /*
- * copy new assignment, now we know it is possible
- * will be used by hw_perf_enable()
- */
- memcpy(cpuc->assign, assign, n*sizeof(int));
-
- return 0;
-}
-
static const struct pmu pmu = {
.enable = x86_pmu_enable,
.disable = x86_pmu_disable,
@@ -1429,37 +1460,8 @@ static const struct pmu pmu = {
.stop = x86_pmu_stop,
.read = x86_pmu_read,
.unthrottle = x86_pmu_unthrottle,
- .start_txn = x86_pmu_start_txn,
- .cancel_txn = x86_pmu_cancel_txn,
- .commit_txn = x86_pmu_commit_txn,
};
-/*
- * validate that we can schedule this event
- */
-static int validate_event(struct perf_event *event)
-{
- struct cpu_hw_events *fake_cpuc;
- struct event_constraint *c;
- int ret = 0;
-
- fake_cpuc = kmalloc(sizeof(*fake_cpuc), GFP_KERNEL | __GFP_ZERO);
- if (!fake_cpuc)
- return -ENOMEM;
-
- c = x86_pmu.get_event_constraints(fake_cpuc, event);
-
- if (!c || !c->weight)
- ret = -ENOSPC;
-
- if (x86_pmu.put_event_constraints)
- x86_pmu.put_event_constraints(fake_cpuc, event);
-
- kfree(fake_cpuc);
-
- return ret;
-}
-
/*
* validate a single event group
*
@@ -1500,7 +1502,7 @@ static int validate_group(struct perf_event *event)
fake_cpuc->n_events = n;
- ret = x86_pmu.schedule_events(fake_cpuc, n, NULL);
+ ret = x86_schedule_events(fake_cpuc, n, NULL);
out_free:
kfree(fake_cpuc);
@@ -1525,8 +1527,6 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
if (event->group_leader != event)
err = validate_group(event);
- else
- err = validate_event(event);
event->pmu = tmp;
}
@@ -1574,7 +1574,8 @@ static void backtrace_address(void *data, unsigned long addr, int reliable)
{
struct perf_callchain_entry *entry = data;
- callchain_store(entry, addr);
+ if (reliable)
+ callchain_store(entry, addr);
}
static const struct stacktrace_ops backtrace_ops = {
@@ -1596,6 +1597,41 @@ perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)
dump_trace(NULL, regs, NULL, regs->bp, &backtrace_ops, entry);
}
+/*
+ * best effort, GUP based copy_from_user() that assumes IRQ or NMI context
+ */
+static unsigned long
+copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
+{
+ unsigned long offset, addr = (unsigned long)from;
+ int type = in_nmi() ? KM_NMI : KM_IRQ0;
+ unsigned long size, len = 0;
+ struct page *page;
+ void *map;
+ int ret;
+
+ do {
+ ret = __get_user_pages_fast(addr, 1, 0, &page);
+ if (!ret)
+ break;
+
+ offset = addr & (PAGE_SIZE - 1);
+ size = min(PAGE_SIZE - offset, n - len);
+
+ map = kmap_atomic(page, type);
+ memcpy(to, map+offset, size);
+ kunmap_atomic(map, type);
+ put_page(page);
+
+ len += size;
+ to += size;
+ addr += size;
+
+ } while (len < n);
+
+ return len;
+}
+
#ifdef CONFIG_COMPAT
static inline int
perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
@@ -1691,11 +1727,6 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
{
struct perf_callchain_entry *entry;
- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
- /* TODO: We don't support guest os callchain now */
- return NULL;
- }
-
if (in_nmi())
entry = &__get_cpu_var(pmc_nmi_entry);
else
@@ -1719,37 +1750,3 @@ void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int ski
regs->cs = __KERNEL_CS;
local_save_flags(regs->flags);
}
-
-unsigned long perf_instruction_pointer(struct pt_regs *regs)
-{
- unsigned long ip;
-
- if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
- ip = perf_guest_cbs->get_guest_ip();
- else
- ip = instruction_pointer(regs);
-
- return ip;
-}
-
-unsigned long perf_misc_flags(struct pt_regs *regs)
-{
- int misc = 0;
-
- if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
- if (perf_guest_cbs->is_user_mode())
- misc |= PERF_RECORD_MISC_GUEST_USER;
- else
- misc |= PERF_RECORD_MISC_GUEST_KERNEL;
- } else {
- if (user_mode(regs))
- misc |= PERF_RECORD_MISC_USER;
- else
- misc |= PERF_RECORD_MISC_KERNEL;
- }
-
- if (regs->flags & PERF_EFLAGS_EXACT)
- misc |= PERF_RECORD_MISC_EXACT_IP;
-
- return misc;
-}
diff --git a/trunk/arch/x86/kernel/cpu/perf_event_amd.c b/trunk/arch/x86/kernel/cpu/perf_event_amd.c
index 611df11ba15e..db6f7d4056e1 100644
--- a/trunk/arch/x86/kernel/cpu/perf_event_amd.c
+++ b/trunk/arch/x86/kernel/cpu/perf_event_amd.c
@@ -2,7 +2,7 @@
static DEFINE_RAW_SPINLOCK(amd_nb_lock);
-static __initconst const u64 amd_hw_cache_event_ids
+static __initconst u64 amd_hw_cache_event_ids
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -111,19 +111,22 @@ static u64 amd_pmu_event_map(int hw_event)
return amd_perfmon_event_map[hw_event];
}
-static int amd_pmu_hw_config(struct perf_event *event)
+static u64 amd_pmu_raw_event(u64 hw_event)
{
- int ret = x86_pmu_hw_config(event);
-
- if (ret)
- return ret;
-
- if (event->attr.type != PERF_TYPE_RAW)
- return 0;
-
- event->hw.config |= event->attr.config & AMD64_RAW_EVENT_MASK;
-
- return 0;
+#define K7_EVNTSEL_EVENT_MASK 0xF000000FFULL
+#define K7_EVNTSEL_UNIT_MASK 0x00000FF00ULL
+#define K7_EVNTSEL_EDGE_MASK 0x000040000ULL
+#define K7_EVNTSEL_INV_MASK 0x000800000ULL
+#define K7_EVNTSEL_REG_MASK 0x0FF000000ULL
+
+#define K7_EVNTSEL_MASK \
+ (K7_EVNTSEL_EVENT_MASK | \
+ K7_EVNTSEL_UNIT_MASK | \
+ K7_EVNTSEL_EDGE_MASK | \
+ K7_EVNTSEL_INV_MASK | \
+ K7_EVNTSEL_REG_MASK)
+
+ return hw_event & K7_EVNTSEL_MASK;
}
/*
@@ -162,7 +165,7 @@ static void amd_put_event_constraints(struct cpu_hw_events *cpuc,
* be removed on one CPU at a time AND PMU is disabled
* when we come here
*/
- for (i = 0; i < x86_pmu.num_counters; i++) {
+ for (i = 0; i < x86_pmu.num_events; i++) {
if (nb->owners[i] == event) {
cmpxchg(nb->owners+i, event, NULL);
break;
@@ -212,7 +215,7 @@ amd_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
struct hw_perf_event *hwc = &event->hw;
struct amd_nb *nb = cpuc->amd_nb;
struct perf_event *old = NULL;
- int max = x86_pmu.num_counters;
+ int max = x86_pmu.num_events;
int i, j, k = -1;
/*
@@ -290,7 +293,7 @@ static struct amd_nb *amd_alloc_nb(int cpu, int nb_id)
/*
* initialize all possible NB constraints
*/
- for (i = 0; i < x86_pmu.num_counters; i++) {
+ for (i = 0; i < x86_pmu.num_events; i++) {
__set_bit(i, nb->event_constraints[i].idxmsk);
nb->event_constraints[i].weight = 1;
}
@@ -368,22 +371,21 @@ static void amd_pmu_cpu_dead(int cpu)
raw_spin_unlock(&amd_nb_lock);
}
-static __initconst const struct x86_pmu amd_pmu = {
+static __initconst struct x86_pmu amd_pmu = {
.name = "AMD",
.handle_irq = x86_pmu_handle_irq,
.disable_all = x86_pmu_disable_all,
.enable_all = x86_pmu_enable_all,
.enable = x86_pmu_enable_event,
.disable = x86_pmu_disable_event,
- .hw_config = amd_pmu_hw_config,
- .schedule_events = x86_schedule_events,
.eventsel = MSR_K7_EVNTSEL0,
.perfctr = MSR_K7_PERFCTR0,
.event_map = amd_pmu_event_map,
+ .raw_event = amd_pmu_raw_event,
.max_events = ARRAY_SIZE(amd_perfmon_event_map),
- .num_counters = 4,
- .cntval_bits = 48,
- .cntval_mask = (1ULL << 48) - 1,
+ .num_events = 4,
+ .event_bits = 48,
+ .event_mask = (1ULL << 48) - 1,
.apic = 1,
/* use highest bit to detect overflow */
.max_period = (1ULL << 47) - 1,
diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel.c b/trunk/arch/x86/kernel/cpu/perf_event_intel.c
index fdbc652d3feb..9c794ac87837 100644
--- a/trunk/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/trunk/arch/x86/kernel/cpu/perf_event_intel.c
@@ -88,7 +88,7 @@ static u64 intel_pmu_event_map(int hw_event)
return intel_perfmon_event_map[hw_event];
}
-static __initconst const u64 westmere_hw_cache_event_ids
+static __initconst u64 westmere_hw_cache_event_ids
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -179,7 +179,7 @@ static __initconst const u64 westmere_hw_cache_event_ids
},
};
-static __initconst const u64 nehalem_hw_cache_event_ids
+static __initconst u64 nehalem_hw_cache_event_ids
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -270,7 +270,7 @@ static __initconst const u64 nehalem_hw_cache_event_ids
},
};
-static __initconst const u64 core2_hw_cache_event_ids
+static __initconst u64 core2_hw_cache_event_ids
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -361,7 +361,7 @@ static __initconst const u64 core2_hw_cache_event_ids
},
};
-static __initconst const u64 atom_hw_cache_event_ids
+static __initconst u64 atom_hw_cache_event_ids
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -452,6 +452,60 @@ static __initconst const u64 atom_hw_cache_event_ids
},
};
+static u64 intel_pmu_raw_event(u64 hw_event)
+{
+#define CORE_EVNTSEL_EVENT_MASK 0x000000FFULL
+#define CORE_EVNTSEL_UNIT_MASK 0x0000FF00ULL
+#define CORE_EVNTSEL_EDGE_MASK 0x00040000ULL
+#define CORE_EVNTSEL_INV_MASK 0x00800000ULL
+#define CORE_EVNTSEL_REG_MASK 0xFF000000ULL
+
+#define CORE_EVNTSEL_MASK \
+ (INTEL_ARCH_EVTSEL_MASK | \
+ INTEL_ARCH_UNIT_MASK | \
+ INTEL_ARCH_EDGE_MASK | \
+ INTEL_ARCH_INV_MASK | \
+ INTEL_ARCH_CNT_MASK)
+
+ return hw_event & CORE_EVNTSEL_MASK;
+}
+
+static void intel_pmu_enable_bts(u64 config)
+{
+ unsigned long debugctlmsr;
+
+ debugctlmsr = get_debugctlmsr();
+
+ debugctlmsr |= X86_DEBUGCTL_TR;
+ debugctlmsr |= X86_DEBUGCTL_BTS;
+ debugctlmsr |= X86_DEBUGCTL_BTINT;
+
+ if (!(config & ARCH_PERFMON_EVENTSEL_OS))
+ debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS;
+
+ if (!(config & ARCH_PERFMON_EVENTSEL_USR))
+ debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR;
+
+ update_debugctlmsr(debugctlmsr);
+}
+
+static void intel_pmu_disable_bts(void)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ unsigned long debugctlmsr;
+
+ if (!cpuc->ds)
+ return;
+
+ debugctlmsr = get_debugctlmsr();
+
+ debugctlmsr &=
+ ~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT |
+ X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR);
+
+ update_debugctlmsr(debugctlmsr);
+}
+
static void intel_pmu_disable_all(void)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
@@ -460,17 +514,12 @@ static void intel_pmu_disable_all(void)
if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask))
intel_pmu_disable_bts();
-
- intel_pmu_pebs_disable_all();
- intel_pmu_lbr_disable_all();
}
-static void intel_pmu_enable_all(int added)
+static void intel_pmu_enable_all(void)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- intel_pmu_pebs_enable_all();
- intel_pmu_lbr_enable_all();
wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
@@ -484,42 +533,6 @@ static void intel_pmu_enable_all(int added)
}
}
-/*
- * Workaround for:
- * Intel Errata AAK100 (model 26)
- * Intel Errata AAP53 (model 30)
- * Intel Errata BD53 (model 44)
- *
- * These chips need to be 'reset' when adding counters by programming
- * the magic three (non counting) events 0x4300D2, 0x4300B1 and 0x4300B5
- * either in sequence on the same PMC or on different PMCs.
- */
-static void intel_pmu_nhm_enable_all(int added)
-{
- if (added) {
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- int i;
-
- wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 0, 0x4300D2);
- wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 1, 0x4300B1);
- wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 2, 0x4300B5);
-
- wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x3);
- wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0);
-
- for (i = 0; i < 3; i++) {
- struct perf_event *event = cpuc->events[i];
-
- if (!event)
- continue;
-
- __x86_pmu_enable_event(&event->hw,
- ARCH_PERFMON_EVENTSEL_ENABLE);
- }
- }
- intel_pmu_enable_all(added);
-}
-
static inline u64 intel_pmu_get_status(void)
{
u64 status;
@@ -534,7 +547,8 @@ static inline void intel_pmu_ack_status(u64 ack)
wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
}
-static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
+static inline void
+intel_pmu_disable_fixed(struct hw_perf_event *hwc)
{
int idx = hwc->idx - X86_PMC_IDX_FIXED;
u64 ctrl_val, mask;
@@ -543,10 +557,71 @@ static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
rdmsrl(hwc->config_base, ctrl_val);
ctrl_val &= ~mask;
- wrmsrl(hwc->config_base, ctrl_val);
+ (void)checking_wrmsrl(hwc->config_base, ctrl_val);
+}
+
+static void intel_pmu_drain_bts_buffer(void)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct debug_store *ds = cpuc->ds;
+ struct bts_record {
+ u64 from;
+ u64 to;
+ u64 flags;
+ };
+ struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS];
+ struct bts_record *at, *top;
+ struct perf_output_handle handle;
+ struct perf_event_header header;
+ struct perf_sample_data data;
+ struct pt_regs regs;
+
+ if (!event)
+ return;
+
+ if (!ds)
+ return;
+
+ at = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
+ top = (struct bts_record *)(unsigned long)ds->bts_index;
+
+ if (top <= at)
+ return;
+
+ ds->bts_index = ds->bts_buffer_base;
+
+ perf_sample_data_init(&data, 0);
+
+ data.period = event->hw.last_period;
+ regs.ip = 0;
+
+ /*
+ * Prepare a generic sample, i.e. fill in the invariant fields.
+ * We will overwrite the from and to address before we output
+ * the sample.
+ */
+ perf_prepare_sample(&header, &data, event, ®s);
+
+ if (perf_output_begin(&handle, event,
+ header.size * (top - at), 1, 1))
+ return;
+
+ for (; at < top; at++) {
+ data.ip = at->from;
+ data.addr = at->to;
+
+ perf_output_sample(&handle, &header, &data, event);
+ }
+
+ perf_output_end(&handle);
+
+ /* There's new data available. */
+ event->hw.interrupts++;
+ event->pending_kill = POLL_IN;
}
-static void intel_pmu_disable_event(struct perf_event *event)
+static inline void
+intel_pmu_disable_event(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
@@ -562,15 +637,14 @@ static void intel_pmu_disable_event(struct perf_event *event)
}
x86_pmu_disable_event(event);
-
- if (unlikely(event->attr.precise_ip))
- intel_pmu_pebs_disable(event);
}
-static void intel_pmu_enable_fixed(struct hw_perf_event *hwc)
+static inline void
+intel_pmu_enable_fixed(struct hw_perf_event *hwc)
{
int idx = hwc->idx - X86_PMC_IDX_FIXED;
u64 ctrl_val, bits, mask;
+ int err;
/*
* Enable IRQ generation (0x8),
@@ -595,7 +669,7 @@ static void intel_pmu_enable_fixed(struct hw_perf_event *hwc)
rdmsrl(hwc->config_base, ctrl_val);
ctrl_val &= ~mask;
ctrl_val |= bits;
- wrmsrl(hwc->config_base, ctrl_val);
+ err = checking_wrmsrl(hwc->config_base, ctrl_val);
}
static void intel_pmu_enable_event(struct perf_event *event)
@@ -615,10 +689,7 @@ static void intel_pmu_enable_event(struct perf_event *event)
return;
}
- if (unlikely(event->attr.precise_ip))
- intel_pmu_pebs_enable(event);
-
- __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
+ __x86_pmu_enable_event(hwc);
}
/*
@@ -637,20 +708,20 @@ static void intel_pmu_reset(void)
unsigned long flags;
int idx;
- if (!x86_pmu.num_counters)
+ if (!x86_pmu.num_events)
return;
local_irq_save(flags);
printk("clearing PMU state on CPU#%d\n", smp_processor_id());
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+ for (idx = 0; idx < x86_pmu.num_events; idx++) {
checking_wrmsrl(x86_pmu.eventsel + idx, 0ull);
checking_wrmsrl(x86_pmu.perfctr + idx, 0ull);
}
- for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++)
+ for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) {
checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
-
+ }
if (ds)
ds->bts_index = ds->bts_buffer_base;
@@ -676,7 +747,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
intel_pmu_drain_bts_buffer();
status = intel_pmu_get_status();
if (!status) {
- intel_pmu_enable_all(0);
+ intel_pmu_enable_all();
return 0;
}
@@ -691,15 +762,6 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
inc_irq_stat(apic_perf_irqs);
ack = status;
-
- intel_pmu_lbr_read();
-
- /*
- * PEBS overflow sets bit 62 in the global status register
- */
- if (__test_and_clear_bit(62, (unsigned long *)&status))
- x86_pmu.drain_pebs(regs);
-
for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
struct perf_event *event = cpuc->events[bit];
@@ -725,22 +787,26 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
goto again;
done:
- intel_pmu_enable_all(0);
+ intel_pmu_enable_all();
return 1;
}
+static struct event_constraint bts_constraint =
+ EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0);
+
static struct event_constraint *
-intel_bts_constraints(struct perf_event *event)
+intel_special_constraints(struct perf_event *event)
{
- struct hw_perf_event *hwc = &event->hw;
- unsigned int hw_event, bts_event;
+ unsigned int hw_event;
- hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
- bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
+ hw_event = event->hw.config & INTEL_ARCH_EVENT_MASK;
- if (unlikely(hw_event == bts_event && hwc->sample_period == 1))
- return &bts_constraint;
+ if (unlikely((hw_event ==
+ x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS)) &&
+ (event->hw.sample_period == 1))) {
+ return &bts_constraint;
+ }
return NULL;
}
@@ -749,53 +815,24 @@ intel_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event
{
struct event_constraint *c;
- c = intel_bts_constraints(event);
- if (c)
- return c;
-
- c = intel_pebs_constraints(event);
+ c = intel_special_constraints(event);
if (c)
return c;
return x86_get_event_constraints(cpuc, event);
}
-static int intel_pmu_hw_config(struct perf_event *event)
-{
- int ret = x86_pmu_hw_config(event);
-
- if (ret)
- return ret;
-
- if (event->attr.type != PERF_TYPE_RAW)
- return 0;
-
- if (!(event->attr.config & ARCH_PERFMON_EVENTSEL_ANY))
- return 0;
-
- if (x86_pmu.version < 3)
- return -EINVAL;
-
- if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
- return -EACCES;
-
- event->hw.config |= ARCH_PERFMON_EVENTSEL_ANY;
-
- return 0;
-}
-
-static __initconst const struct x86_pmu core_pmu = {
+static __initconst struct x86_pmu core_pmu = {
.name = "core",
.handle_irq = x86_pmu_handle_irq,
.disable_all = x86_pmu_disable_all,
.enable_all = x86_pmu_enable_all,
.enable = x86_pmu_enable_event,
.disable = x86_pmu_disable_event,
- .hw_config = x86_pmu_hw_config,
- .schedule_events = x86_schedule_events,
.eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
.perfctr = MSR_ARCH_PERFMON_PERFCTR0,
.event_map = intel_pmu_event_map,
+ .raw_event = intel_pmu_raw_event,
.max_events = ARRAY_SIZE(intel_perfmon_event_map),
.apic = 1,
/*
@@ -808,32 +845,17 @@ static __initconst const struct x86_pmu core_pmu = {
.event_constraints = intel_core_event_constraints,
};
-static void intel_pmu_cpu_starting(int cpu)
-{
- init_debug_store_on_cpu(cpu);
- /*
- * Deal with CPUs that don't clear their LBRs on power-up.
- */
- intel_pmu_lbr_reset();
-}
-
-static void intel_pmu_cpu_dying(int cpu)
-{
- fini_debug_store_on_cpu(cpu);
-}
-
-static __initconst const struct x86_pmu intel_pmu = {
+static __initconst struct x86_pmu intel_pmu = {
.name = "Intel",
.handle_irq = intel_pmu_handle_irq,
.disable_all = intel_pmu_disable_all,
.enable_all = intel_pmu_enable_all,
.enable = intel_pmu_enable_event,
.disable = intel_pmu_disable_event,
- .hw_config = intel_pmu_hw_config,
- .schedule_events = x86_schedule_events,
.eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
.perfctr = MSR_ARCH_PERFMON_PERFCTR0,
.event_map = intel_pmu_event_map,
+ .raw_event = intel_pmu_raw_event,
.max_events = ARRAY_SIZE(intel_perfmon_event_map),
.apic = 1,
/*
@@ -842,38 +864,14 @@ static __initconst const struct x86_pmu intel_pmu = {
* the generic event period:
*/
.max_period = (1ULL << 31) - 1,
+ .enable_bts = intel_pmu_enable_bts,
+ .disable_bts = intel_pmu_disable_bts,
.get_event_constraints = intel_get_event_constraints,
- .cpu_starting = intel_pmu_cpu_starting,
- .cpu_dying = intel_pmu_cpu_dying,
+ .cpu_starting = init_debug_store_on_cpu,
+ .cpu_dying = fini_debug_store_on_cpu,
};
-static void intel_clovertown_quirks(void)
-{
- /*
- * PEBS is unreliable due to:
- *
- * AJ67 - PEBS may experience CPL leaks
- * AJ68 - PEBS PMI may be delayed by one event
- * AJ69 - GLOBAL_STATUS[62] will only be set when DEBUGCTL[12]
- * AJ106 - FREEZE_LBRS_ON_PMI doesn't work in combination with PEBS
- *
- * AJ67 could be worked around by restricting the OS/USR flags.
- * AJ69 could be worked around by setting PMU_FREEZE_ON_PMI.
- *
- * AJ106 could possibly be worked around by not allowing LBR
- * usage from PEBS, including the fixup.
- * AJ68 could possibly be worked around by always programming
- * a pebs_event_reset[0] value and coping with the lost events.
- *
- * But taken together it might just make sense to not enable PEBS on
- * these chips.
- */
- printk(KERN_WARNING "PEBS disabled due to CPU errata.\n");
- x86_pmu.pebs = 0;
- x86_pmu.pebs_constraints = NULL;
-}
-
static __init int intel_pmu_init(void)
{
union cpuid10_edx edx;
@@ -883,13 +881,12 @@ static __init int intel_pmu_init(void)
int version;
if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
- switch (boot_cpu_data.x86) {
- case 0x6:
- return p6_pmu_init();
- case 0xf:
- return p4_pmu_init();
- }
+ /* check for P6 processor family */
+ if (boot_cpu_data.x86 == 6) {
+ return p6_pmu_init();
+ } else {
return -ENODEV;
+ }
}
/*
@@ -907,28 +904,16 @@ static __init int intel_pmu_init(void)
x86_pmu = intel_pmu;
x86_pmu.version = version;
- x86_pmu.num_counters = eax.split.num_counters;
- x86_pmu.cntval_bits = eax.split.bit_width;
- x86_pmu.cntval_mask = (1ULL << eax.split.bit_width) - 1;
+ x86_pmu.num_events = eax.split.num_events;
+ x86_pmu.event_bits = eax.split.bit_width;
+ x86_pmu.event_mask = (1ULL << eax.split.bit_width) - 1;
/*
* Quirk: v2 perfmon does not report fixed-purpose events, so
* assume at least 3 events:
*/
if (version > 1)
- x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3);
-
- /*
- * v2 and above have a perf capabilities MSR
- */
- if (version > 1) {
- u64 capabilities;
-
- rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities);
- x86_pmu.intel_cap.capabilities = capabilities;
- }
-
- intel_ds_init();
+ x86_pmu.num_events_fixed = max((int)edx.split.num_events_fixed, 3);
/*
* Install the hw-cache-events table:
@@ -939,15 +924,12 @@ static __init int intel_pmu_init(void)
break;
case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
- x86_pmu.quirks = intel_clovertown_quirks;
case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
case 29: /* six-core 45 nm xeon "Dunnington" */
memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
- intel_pmu_lbr_init_core();
-
x86_pmu.event_constraints = intel_core2_event_constraints;
pr_cont("Core2 events, ");
break;
@@ -958,19 +940,13 @@ static __init int intel_pmu_init(void)
memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
- intel_pmu_lbr_init_nhm();
-
x86_pmu.event_constraints = intel_nehalem_event_constraints;
- x86_pmu.enable_all = intel_pmu_nhm_enable_all;
- pr_cont("Nehalem events, ");
+ pr_cont("Nehalem/Corei7 events, ");
break;
-
case 28: /* Atom */
memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
- intel_pmu_lbr_init_atom();
-
x86_pmu.event_constraints = intel_gen_event_constraints;
pr_cont("Atom events, ");
break;
@@ -980,10 +956,7 @@ static __init int intel_pmu_init(void)
memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
- intel_pmu_lbr_init_nhm();
-
x86_pmu.event_constraints = intel_westmere_event_constraints;
- x86_pmu.enable_all = intel_pmu_nhm_enable_all;
pr_cont("Westmere events, ");
break;
diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c
deleted file mode 100644
index 18018d1311cd..000000000000
--- a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ /dev/null
@@ -1,641 +0,0 @@
-#ifdef CONFIG_CPU_SUP_INTEL
-
-/* The maximal number of PEBS events: */
-#define MAX_PEBS_EVENTS 4
-
-/* The size of a BTS record in bytes: */
-#define BTS_RECORD_SIZE 24
-
-#define BTS_BUFFER_SIZE (PAGE_SIZE << 4)
-#define PEBS_BUFFER_SIZE PAGE_SIZE
-
-/*
- * pebs_record_32 for p4 and core not supported
-
-struct pebs_record_32 {
- u32 flags, ip;
- u32 ax, bc, cx, dx;
- u32 si, di, bp, sp;
-};
-
- */
-
-struct pebs_record_core {
- u64 flags, ip;
- u64 ax, bx, cx, dx;
- u64 si, di, bp, sp;
- u64 r8, r9, r10, r11;
- u64 r12, r13, r14, r15;
-};
-
-struct pebs_record_nhm {
- u64 flags, ip;
- u64 ax, bx, cx, dx;
- u64 si, di, bp, sp;
- u64 r8, r9, r10, r11;
- u64 r12, r13, r14, r15;
- u64 status, dla, dse, lat;
-};
-
-/*
- * A debug store configuration.
- *
- * We only support architectures that use 64bit fields.
- */
-struct debug_store {
- u64 bts_buffer_base;
- u64 bts_index;
- u64 bts_absolute_maximum;
- u64 bts_interrupt_threshold;
- u64 pebs_buffer_base;
- u64 pebs_index;
- u64 pebs_absolute_maximum;
- u64 pebs_interrupt_threshold;
- u64 pebs_event_reset[MAX_PEBS_EVENTS];
-};
-
-static void init_debug_store_on_cpu(int cpu)
-{
- struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
- if (!ds)
- return;
-
- wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
- (u32)((u64)(unsigned long)ds),
- (u32)((u64)(unsigned long)ds >> 32));
-}
-
-static void fini_debug_store_on_cpu(int cpu)
-{
- if (!per_cpu(cpu_hw_events, cpu).ds)
- return;
-
- wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
-}
-
-static void release_ds_buffers(void)
-{
- int cpu;
-
- if (!x86_pmu.bts && !x86_pmu.pebs)
- return;
-
- get_online_cpus();
-
- for_each_online_cpu(cpu)
- fini_debug_store_on_cpu(cpu);
-
- for_each_possible_cpu(cpu) {
- struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
- if (!ds)
- continue;
-
- per_cpu(cpu_hw_events, cpu).ds = NULL;
-
- kfree((void *)(unsigned long)ds->pebs_buffer_base);
- kfree((void *)(unsigned long)ds->bts_buffer_base);
- kfree(ds);
- }
-
- put_online_cpus();
-}
-
-static int reserve_ds_buffers(void)
-{
- int cpu, err = 0;
-
- if (!x86_pmu.bts && !x86_pmu.pebs)
- return 0;
-
- get_online_cpus();
-
- for_each_possible_cpu(cpu) {
- struct debug_store *ds;
- void *buffer;
- int max, thresh;
-
- err = -ENOMEM;
- ds = kzalloc(sizeof(*ds), GFP_KERNEL);
- if (unlikely(!ds))
- break;
- per_cpu(cpu_hw_events, cpu).ds = ds;
-
- if (x86_pmu.bts) {
- buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
- if (unlikely(!buffer))
- break;
-
- max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE;
- thresh = max / 16;
-
- ds->bts_buffer_base = (u64)(unsigned long)buffer;
- ds->bts_index = ds->bts_buffer_base;
- ds->bts_absolute_maximum = ds->bts_buffer_base +
- max * BTS_RECORD_SIZE;
- ds->bts_interrupt_threshold = ds->bts_absolute_maximum -
- thresh * BTS_RECORD_SIZE;
- }
-
- if (x86_pmu.pebs) {
- buffer = kzalloc(PEBS_BUFFER_SIZE, GFP_KERNEL);
- if (unlikely(!buffer))
- break;
-
- max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size;
-
- ds->pebs_buffer_base = (u64)(unsigned long)buffer;
- ds->pebs_index = ds->pebs_buffer_base;
- ds->pebs_absolute_maximum = ds->pebs_buffer_base +
- max * x86_pmu.pebs_record_size;
- /*
- * Always use single record PEBS
- */
- ds->pebs_interrupt_threshold = ds->pebs_buffer_base +
- x86_pmu.pebs_record_size;
- }
-
- err = 0;
- }
-
- if (err)
- release_ds_buffers();
- else {
- for_each_online_cpu(cpu)
- init_debug_store_on_cpu(cpu);
- }
-
- put_online_cpus();
-
- return err;
-}
-
-/*
- * BTS
- */
-
-static struct event_constraint bts_constraint =
- EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0);
-
-static void intel_pmu_enable_bts(u64 config)
-{
- unsigned long debugctlmsr;
-
- debugctlmsr = get_debugctlmsr();
-
- debugctlmsr |= DEBUGCTLMSR_TR;
- debugctlmsr |= DEBUGCTLMSR_BTS;
- debugctlmsr |= DEBUGCTLMSR_BTINT;
-
- if (!(config & ARCH_PERFMON_EVENTSEL_OS))
- debugctlmsr |= DEBUGCTLMSR_BTS_OFF_OS;
-
- if (!(config & ARCH_PERFMON_EVENTSEL_USR))
- debugctlmsr |= DEBUGCTLMSR_BTS_OFF_USR;
-
- update_debugctlmsr(debugctlmsr);
-}
-
-static void intel_pmu_disable_bts(void)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- unsigned long debugctlmsr;
-
- if (!cpuc->ds)
- return;
-
- debugctlmsr = get_debugctlmsr();
-
- debugctlmsr &=
- ~(DEBUGCTLMSR_TR | DEBUGCTLMSR_BTS | DEBUGCTLMSR_BTINT |
- DEBUGCTLMSR_BTS_OFF_OS | DEBUGCTLMSR_BTS_OFF_USR);
-
- update_debugctlmsr(debugctlmsr);
-}
-
-static void intel_pmu_drain_bts_buffer(void)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- struct debug_store *ds = cpuc->ds;
- struct bts_record {
- u64 from;
- u64 to;
- u64 flags;
- };
- struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS];
- struct bts_record *at, *top;
- struct perf_output_handle handle;
- struct perf_event_header header;
- struct perf_sample_data data;
- struct pt_regs regs;
-
- if (!event)
- return;
-
- if (!ds)
- return;
-
- at = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
- top = (struct bts_record *)(unsigned long)ds->bts_index;
-
- if (top <= at)
- return;
-
- ds->bts_index = ds->bts_buffer_base;
-
- perf_sample_data_init(&data, 0);
- data.period = event->hw.last_period;
- regs.ip = 0;
-
- /*
- * Prepare a generic sample, i.e. fill in the invariant fields.
- * We will overwrite the from and to address before we output
- * the sample.
- */
- perf_prepare_sample(&header, &data, event, ®s);
-
- if (perf_output_begin(&handle, event, header.size * (top - at), 1, 1))
- return;
-
- for (; at < top; at++) {
- data.ip = at->from;
- data.addr = at->to;
-
- perf_output_sample(&handle, &header, &data, event);
- }
-
- perf_output_end(&handle);
-
- /* There's new data available. */
- event->hw.interrupts++;
- event->pending_kill = POLL_IN;
-}
-
-/*
- * PEBS
- */
-
-static struct event_constraint intel_core_pebs_events[] = {
- PEBS_EVENT_CONSTRAINT(0x00c0, 0x1), /* INSTR_RETIRED.ANY */
- PEBS_EVENT_CONSTRAINT(0xfec1, 0x1), /* X87_OPS_RETIRED.ANY */
- PEBS_EVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_RETIRED.MISPRED */
- PEBS_EVENT_CONSTRAINT(0x1fc7, 0x1), /* SIMD_INST_RETURED.ANY */
- PEBS_EVENT_CONSTRAINT(0x01cb, 0x1), /* MEM_LOAD_RETIRED.L1D_MISS */
- PEBS_EVENT_CONSTRAINT(0x02cb, 0x1), /* MEM_LOAD_RETIRED.L1D_LINE_MISS */
- PEBS_EVENT_CONSTRAINT(0x04cb, 0x1), /* MEM_LOAD_RETIRED.L2_MISS */
- PEBS_EVENT_CONSTRAINT(0x08cb, 0x1), /* MEM_LOAD_RETIRED.L2_LINE_MISS */
- PEBS_EVENT_CONSTRAINT(0x10cb, 0x1), /* MEM_LOAD_RETIRED.DTLB_MISS */
- EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint intel_nehalem_pebs_events[] = {
- PEBS_EVENT_CONSTRAINT(0x00c0, 0xf), /* INSTR_RETIRED.ANY */
- PEBS_EVENT_CONSTRAINT(0xfec1, 0xf), /* X87_OPS_RETIRED.ANY */
- PEBS_EVENT_CONSTRAINT(0x00c5, 0xf), /* BR_INST_RETIRED.MISPRED */
- PEBS_EVENT_CONSTRAINT(0x1fc7, 0xf), /* SIMD_INST_RETURED.ANY */
- PEBS_EVENT_CONSTRAINT(0x01cb, 0xf), /* MEM_LOAD_RETIRED.L1D_MISS */
- PEBS_EVENT_CONSTRAINT(0x02cb, 0xf), /* MEM_LOAD_RETIRED.L1D_LINE_MISS */
- PEBS_EVENT_CONSTRAINT(0x04cb, 0xf), /* MEM_LOAD_RETIRED.L2_MISS */
- PEBS_EVENT_CONSTRAINT(0x08cb, 0xf), /* MEM_LOAD_RETIRED.L2_LINE_MISS */
- PEBS_EVENT_CONSTRAINT(0x10cb, 0xf), /* MEM_LOAD_RETIRED.DTLB_MISS */
- EVENT_CONSTRAINT_END
-};
-
-static struct event_constraint *
-intel_pebs_constraints(struct perf_event *event)
-{
- struct event_constraint *c;
-
- if (!event->attr.precise_ip)
- return NULL;
-
- if (x86_pmu.pebs_constraints) {
- for_each_event_constraint(c, x86_pmu.pebs_constraints) {
- if ((event->hw.config & c->cmask) == c->code)
- return c;
- }
- }
-
- return &emptyconstraint;
-}
-
-static void intel_pmu_pebs_enable(struct perf_event *event)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- struct hw_perf_event *hwc = &event->hw;
-
- hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
-
- cpuc->pebs_enabled |= 1ULL << hwc->idx;
- WARN_ON_ONCE(cpuc->enabled);
-
- if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1)
- intel_pmu_lbr_enable(event);
-}
-
-static void intel_pmu_pebs_disable(struct perf_event *event)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- struct hw_perf_event *hwc = &event->hw;
-
- cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
- if (cpuc->enabled)
- wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
-
- hwc->config |= ARCH_PERFMON_EVENTSEL_INT;
-
- if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1)
- intel_pmu_lbr_disable(event);
-}
-
-static void intel_pmu_pebs_enable_all(void)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-
- if (cpuc->pebs_enabled)
- wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
-}
-
-static void intel_pmu_pebs_disable_all(void)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-
- if (cpuc->pebs_enabled)
- wrmsrl(MSR_IA32_PEBS_ENABLE, 0);
-}
-
-#include
-
-static inline bool kernel_ip(unsigned long ip)
-{
-#ifdef CONFIG_X86_32
- return ip > PAGE_OFFSET;
-#else
- return (long)ip < 0;
-#endif
-}
-
-static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- unsigned long from = cpuc->lbr_entries[0].from;
- unsigned long old_to, to = cpuc->lbr_entries[0].to;
- unsigned long ip = regs->ip;
-
- /*
- * We don't need to fixup if the PEBS assist is fault like
- */
- if (!x86_pmu.intel_cap.pebs_trap)
- return 1;
-
- /*
- * No LBR entry, no basic block, no rewinding
- */
- if (!cpuc->lbr_stack.nr || !from || !to)
- return 0;
-
- /*
- * Basic blocks should never cross user/kernel boundaries
- */
- if (kernel_ip(ip) != kernel_ip(to))
- return 0;
-
- /*
- * unsigned math, either ip is before the start (impossible) or
- * the basic block is larger than 1 page (sanity)
- */
- if ((ip - to) > PAGE_SIZE)
- return 0;
-
- /*
- * We sampled a branch insn, rewind using the LBR stack
- */
- if (ip == to) {
- regs->ip = from;
- return 1;
- }
-
- do {
- struct insn insn;
- u8 buf[MAX_INSN_SIZE];
- void *kaddr;
-
- old_to = to;
- if (!kernel_ip(ip)) {
- int bytes, size = MAX_INSN_SIZE;
-
- bytes = copy_from_user_nmi(buf, (void __user *)to, size);
- if (bytes != size)
- return 0;
-
- kaddr = buf;
- } else
- kaddr = (void *)to;
-
- kernel_insn_init(&insn, kaddr);
- insn_get_length(&insn);
- to += insn.length;
- } while (to < ip);
-
- if (to == ip) {
- regs->ip = old_to;
- return 1;
- }
-
- /*
- * Even though we decoded the basic block, the instruction stream
- * never matched the given IP, either the TO or the IP got corrupted.
- */
- return 0;
-}
-
-static int intel_pmu_save_and_restart(struct perf_event *event);
-
-static void __intel_pmu_pebs_event(struct perf_event *event,
- struct pt_regs *iregs, void *__pebs)
-{
- /*
- * We cast to pebs_record_core since that is a subset of
- * both formats and we don't use the other fields in this
- * routine.
- */
- struct pebs_record_core *pebs = __pebs;
- struct perf_sample_data data;
- struct pt_regs regs;
-
- if (!intel_pmu_save_and_restart(event))
- return;
-
- perf_sample_data_init(&data, 0);
- data.period = event->hw.last_period;
-
- /*
- * We use the interrupt regs as a base because the PEBS record
- * does not contain a full regs set, specifically it seems to
- * lack segment descriptors, which get used by things like
- * user_mode().
- *
- * In the simple case fix up only the IP and BP,SP regs, for
- * PERF_SAMPLE_IP and PERF_SAMPLE_CALLCHAIN to function properly.
- * A possible PERF_SAMPLE_REGS will have to transfer all regs.
- */
- regs = *iregs;
- regs.ip = pebs->ip;
- regs.bp = pebs->bp;
- regs.sp = pebs->sp;
-
- if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(®s))
- regs.flags |= PERF_EFLAGS_EXACT;
- else
- regs.flags &= ~PERF_EFLAGS_EXACT;
-
- if (perf_event_overflow(event, 1, &data, ®s))
- x86_pmu_stop(event);
-}
-
-static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- struct debug_store *ds = cpuc->ds;
- struct perf_event *event = cpuc->events[0]; /* PMC0 only */
- struct pebs_record_core *at, *top;
- int n;
-
- if (!ds || !x86_pmu.pebs)
- return;
-
- at = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base;
- top = (struct pebs_record_core *)(unsigned long)ds->pebs_index;
-
- /*
- * Whatever else happens, drain the thing
- */
- ds->pebs_index = ds->pebs_buffer_base;
-
- if (!test_bit(0, cpuc->active_mask))
- return;
-
- WARN_ON_ONCE(!event);
-
- if (!event->attr.precise_ip)
- return;
-
- n = top - at;
- if (n <= 0)
- return;
-
- /*
- * Should not happen, we program the threshold at 1 and do not
- * set a reset value.
- */
- WARN_ON_ONCE(n > 1);
- at += n - 1;
-
- __intel_pmu_pebs_event(event, iregs, at);
-}
-
-static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- struct debug_store *ds = cpuc->ds;
- struct pebs_record_nhm *at, *top;
- struct perf_event *event = NULL;
- u64 status = 0;
- int bit, n;
-
- if (!ds || !x86_pmu.pebs)
- return;
-
- at = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
- top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
-
- ds->pebs_index = ds->pebs_buffer_base;
-
- n = top - at;
- if (n <= 0)
- return;
-
- /*
- * Should not happen, we program the threshold at 1 and do not
- * set a reset value.
- */
- WARN_ON_ONCE(n > MAX_PEBS_EVENTS);
-
- for ( ; at < top; at++) {
- for_each_set_bit(bit, (unsigned long *)&at->status, MAX_PEBS_EVENTS) {
- event = cpuc->events[bit];
- if (!test_bit(bit, cpuc->active_mask))
- continue;
-
- WARN_ON_ONCE(!event);
-
- if (!event->attr.precise_ip)
- continue;
-
- if (__test_and_set_bit(bit, (unsigned long *)&status))
- continue;
-
- break;
- }
-
- if (!event || bit >= MAX_PEBS_EVENTS)
- continue;
-
- __intel_pmu_pebs_event(event, iregs, at);
- }
-}
-
-/*
- * BTS, PEBS probe and setup
- */
-
-static void intel_ds_init(void)
-{
- /*
- * No support for 32bit formats
- */
- if (!boot_cpu_has(X86_FEATURE_DTES64))
- return;
-
- x86_pmu.bts = boot_cpu_has(X86_FEATURE_BTS);
- x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS);
- if (x86_pmu.pebs) {
- char pebs_type = x86_pmu.intel_cap.pebs_trap ? '+' : '-';
- int format = x86_pmu.intel_cap.pebs_format;
-
- switch (format) {
- case 0:
- printk(KERN_CONT "PEBS fmt0%c, ", pebs_type);
- x86_pmu.pebs_record_size = sizeof(struct pebs_record_core);
- x86_pmu.drain_pebs = intel_pmu_drain_pebs_core;
- x86_pmu.pebs_constraints = intel_core_pebs_events;
- break;
-
- case 1:
- printk(KERN_CONT "PEBS fmt1%c, ", pebs_type);
- x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm);
- x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
- x86_pmu.pebs_constraints = intel_nehalem_pebs_events;
- break;
-
- default:
- printk(KERN_CONT "no PEBS fmt%d%c, ", format, pebs_type);
- x86_pmu.pebs = 0;
- break;
- }
- }
-}
-
-#else /* CONFIG_CPU_SUP_INTEL */
-
-static int reserve_ds_buffers(void)
-{
- return 0;
-}
-
-static void release_ds_buffers(void)
-{
-}
-
-#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/trunk/arch/x86/kernel/cpu/perf_event_intel_lbr.c
deleted file mode 100644
index d202c1bece1a..000000000000
--- a/trunk/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ /dev/null
@@ -1,218 +0,0 @@
-#ifdef CONFIG_CPU_SUP_INTEL
-
-enum {
- LBR_FORMAT_32 = 0x00,
- LBR_FORMAT_LIP = 0x01,
- LBR_FORMAT_EIP = 0x02,
- LBR_FORMAT_EIP_FLAGS = 0x03,
-};
-
-/*
- * We only support LBR implementations that have FREEZE_LBRS_ON_PMI
- * otherwise it becomes near impossible to get a reliable stack.
- */
-
-static void __intel_pmu_lbr_enable(void)
-{
- u64 debugctl;
-
- rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
- debugctl |= (DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
- wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
-}
-
-static void __intel_pmu_lbr_disable(void)
-{
- u64 debugctl;
-
- rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
- debugctl &= ~(DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
- wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
-}
-
-static void intel_pmu_lbr_reset_32(void)
-{
- int i;
-
- for (i = 0; i < x86_pmu.lbr_nr; i++)
- wrmsrl(x86_pmu.lbr_from + i, 0);
-}
-
-static void intel_pmu_lbr_reset_64(void)
-{
- int i;
-
- for (i = 0; i < x86_pmu.lbr_nr; i++) {
- wrmsrl(x86_pmu.lbr_from + i, 0);
- wrmsrl(x86_pmu.lbr_to + i, 0);
- }
-}
-
-static void intel_pmu_lbr_reset(void)
-{
- if (!x86_pmu.lbr_nr)
- return;
-
- if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
- intel_pmu_lbr_reset_32();
- else
- intel_pmu_lbr_reset_64();
-}
-
-static void intel_pmu_lbr_enable(struct perf_event *event)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-
- if (!x86_pmu.lbr_nr)
- return;
-
- WARN_ON_ONCE(cpuc->enabled);
-
- /*
- * Reset the LBR stack if we changed task context to
- * avoid data leaks.
- */
-
- if (event->ctx->task && cpuc->lbr_context != event->ctx) {
- intel_pmu_lbr_reset();
- cpuc->lbr_context = event->ctx;
- }
-
- cpuc->lbr_users++;
-}
-
-static void intel_pmu_lbr_disable(struct perf_event *event)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-
- if (!x86_pmu.lbr_nr)
- return;
-
- cpuc->lbr_users--;
- WARN_ON_ONCE(cpuc->lbr_users < 0);
-
- if (cpuc->enabled && !cpuc->lbr_users)
- __intel_pmu_lbr_disable();
-}
-
-static void intel_pmu_lbr_enable_all(void)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-
- if (cpuc->lbr_users)
- __intel_pmu_lbr_enable();
-}
-
-static void intel_pmu_lbr_disable_all(void)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-
- if (cpuc->lbr_users)
- __intel_pmu_lbr_disable();
-}
-
-static inline u64 intel_pmu_lbr_tos(void)
-{
- u64 tos;
-
- rdmsrl(x86_pmu.lbr_tos, tos);
-
- return tos;
-}
-
-static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
-{
- unsigned long mask = x86_pmu.lbr_nr - 1;
- u64 tos = intel_pmu_lbr_tos();
- int i;
-
- for (i = 0; i < x86_pmu.lbr_nr; i++) {
- unsigned long lbr_idx = (tos - i) & mask;
- union {
- struct {
- u32 from;
- u32 to;
- };
- u64 lbr;
- } msr_lastbranch;
-
- rdmsrl(x86_pmu.lbr_from + lbr_idx, msr_lastbranch.lbr);
-
- cpuc->lbr_entries[i].from = msr_lastbranch.from;
- cpuc->lbr_entries[i].to = msr_lastbranch.to;
- cpuc->lbr_entries[i].flags = 0;
- }
- cpuc->lbr_stack.nr = i;
-}
-
-#define LBR_FROM_FLAG_MISPRED (1ULL << 63)
-
-/*
- * Due to lack of segmentation in Linux the effective address (offset)
- * is the same as the linear address, allowing us to merge the LIP and EIP
- * LBR formats.
- */
-static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
-{
- unsigned long mask = x86_pmu.lbr_nr - 1;
- int lbr_format = x86_pmu.intel_cap.lbr_format;
- u64 tos = intel_pmu_lbr_tos();
- int i;
-
- for (i = 0; i < x86_pmu.lbr_nr; i++) {
- unsigned long lbr_idx = (tos - i) & mask;
- u64 from, to, flags = 0;
-
- rdmsrl(x86_pmu.lbr_from + lbr_idx, from);
- rdmsrl(x86_pmu.lbr_to + lbr_idx, to);
-
- if (lbr_format == LBR_FORMAT_EIP_FLAGS) {
- flags = !!(from & LBR_FROM_FLAG_MISPRED);
- from = (u64)((((s64)from) << 1) >> 1);
- }
-
- cpuc->lbr_entries[i].from = from;
- cpuc->lbr_entries[i].to = to;
- cpuc->lbr_entries[i].flags = flags;
- }
- cpuc->lbr_stack.nr = i;
-}
-
-static void intel_pmu_lbr_read(void)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-
- if (!cpuc->lbr_users)
- return;
-
- if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
- intel_pmu_lbr_read_32(cpuc);
- else
- intel_pmu_lbr_read_64(cpuc);
-}
-
-static void intel_pmu_lbr_init_core(void)
-{
- x86_pmu.lbr_nr = 4;
- x86_pmu.lbr_tos = 0x01c9;
- x86_pmu.lbr_from = 0x40;
- x86_pmu.lbr_to = 0x60;
-}
-
-static void intel_pmu_lbr_init_nhm(void)
-{
- x86_pmu.lbr_nr = 16;
- x86_pmu.lbr_tos = 0x01c9;
- x86_pmu.lbr_from = 0x680;
- x86_pmu.lbr_to = 0x6c0;
-}
-
-static void intel_pmu_lbr_init_atom(void)
-{
- x86_pmu.lbr_nr = 8;
- x86_pmu.lbr_tos = 0x01c9;
- x86_pmu.lbr_from = 0x40;
- x86_pmu.lbr_to = 0x60;
-}
-
-#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/trunk/arch/x86/kernel/cpu/perf_event_p4.c b/trunk/arch/x86/kernel/cpu/perf_event_p4.c
deleted file mode 100644
index ae85d69644d1..000000000000
--- a/trunk/arch/x86/kernel/cpu/perf_event_p4.c
+++ /dev/null
@@ -1,858 +0,0 @@
-/*
- * Netburst Perfomance Events (P4, old Xeon)
- *
- * Copyright (C) 2010 Parallels, Inc., Cyrill Gorcunov
- * Copyright (C) 2010 Intel Corporation, Lin Ming
- *
- * For licencing details see kernel-base/COPYING
- */
-
-#ifdef CONFIG_CPU_SUP_INTEL
-
-#include
-
-#define P4_CNTR_LIMIT 3
-/*
- * array indices: 0,1 - HT threads, used with HT enabled cpu
- */
-struct p4_event_bind {
- unsigned int opcode; /* Event code and ESCR selector */
- unsigned int escr_msr[2]; /* ESCR MSR for this event */
- char cntr[2][P4_CNTR_LIMIT]; /* counter index (offset), -1 on abscence */
-};
-
-struct p4_cache_event_bind {
- unsigned int metric_pebs;
- unsigned int metric_vert;
-};
-
-#define P4_GEN_CACHE_EVENT_BIND(name) \
- [P4_CACHE__##name] = { \
- .metric_pebs = P4_PEBS__##name, \
- .metric_vert = P4_VERT__##name, \
- }
-
-static struct p4_cache_event_bind p4_cache_event_bind_map[] = {
- P4_GEN_CACHE_EVENT_BIND(1stl_cache_load_miss_retired),
- P4_GEN_CACHE_EVENT_BIND(2ndl_cache_load_miss_retired),
- P4_GEN_CACHE_EVENT_BIND(dtlb_load_miss_retired),
- P4_GEN_CACHE_EVENT_BIND(dtlb_store_miss_retired),
-};
-
-/*
- * Note that we don't use CCCR1 here, there is an
- * exception for P4_BSQ_ALLOCATION but we just have
- * no workaround
- *
- * consider this binding as resources which particular
- * event may borrow, it doesn't contain EventMask,
- * Tags and friends -- they are left to a caller
- */
-static struct p4_event_bind p4_event_bind_map[] = {
- [P4_EVENT_TC_DELIVER_MODE] = {
- .opcode = P4_OPCODE(P4_EVENT_TC_DELIVER_MODE),
- .escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
- .cntr = { {4, 5, -1}, {6, 7, -1} },
- },
- [P4_EVENT_BPU_FETCH_REQUEST] = {
- .opcode = P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST),
- .escr_msr = { MSR_P4_BPU_ESCR0, MSR_P4_BPU_ESCR1 },
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_ITLB_REFERENCE] = {
- .opcode = P4_OPCODE(P4_EVENT_ITLB_REFERENCE),
- .escr_msr = { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 },
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_MEMORY_CANCEL] = {
- .opcode = P4_OPCODE(P4_EVENT_MEMORY_CANCEL),
- .escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_MEMORY_COMPLETE] = {
- .opcode = P4_OPCODE(P4_EVENT_MEMORY_COMPLETE),
- .escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 },
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_LOAD_PORT_REPLAY] = {
- .opcode = P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY),
- .escr_msr = { MSR_P4_SAAT_ESCR0, MSR_P4_SAAT_ESCR1 },
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_STORE_PORT_REPLAY] = {
- .opcode = P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY),
- .escr_msr = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 },
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_MOB_LOAD_REPLAY] = {
- .opcode = P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY),
- .escr_msr = { MSR_P4_MOB_ESCR0, MSR_P4_MOB_ESCR1 },
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_PAGE_WALK_TYPE] = {
- .opcode = P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE),
- .escr_msr = { MSR_P4_PMH_ESCR0, MSR_P4_PMH_ESCR1 },
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_BSQ_CACHE_REFERENCE] = {
- .opcode = P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE),
- .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 },
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_IOQ_ALLOCATION] = {
- .opcode = P4_OPCODE(P4_EVENT_IOQ_ALLOCATION),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_IOQ_ACTIVE_ENTRIES] = { /* shared ESCR */
- .opcode = P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES),
- .escr_msr = { MSR_P4_FSB_ESCR1, MSR_P4_FSB_ESCR1 },
- .cntr = { {2, -1, -1}, {3, -1, -1} },
- },
- [P4_EVENT_FSB_DATA_ACTIVITY] = {
- .opcode = P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_BSQ_ALLOCATION] = { /* shared ESCR, broken CCCR1 */
- .opcode = P4_OPCODE(P4_EVENT_BSQ_ALLOCATION),
- .escr_msr = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR0 },
- .cntr = { {0, -1, -1}, {1, -1, -1} },
- },
- [P4_EVENT_BSQ_ACTIVE_ENTRIES] = { /* shared ESCR */
- .opcode = P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES),
- .escr_msr = { MSR_P4_BSU_ESCR1 , MSR_P4_BSU_ESCR1 },
- .cntr = { {2, -1, -1}, {3, -1, -1} },
- },
- [P4_EVENT_SSE_INPUT_ASSIST] = {
- .opcode = P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_PACKED_SP_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_PACKED_SP_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_PACKED_DP_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_PACKED_DP_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_SCALAR_SP_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_SCALAR_SP_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_SCALAR_DP_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_SCALAR_DP_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_64BIT_MMX_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_64BIT_MMX_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_128BIT_MMX_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_128BIT_MMX_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_X87_FP_UOP] = {
- .opcode = P4_OPCODE(P4_EVENT_X87_FP_UOP),
- .escr_msr = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_TC_MISC] = {
- .opcode = P4_OPCODE(P4_EVENT_TC_MISC),
- .escr_msr = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
- .cntr = { {4, 5, -1}, {6, 7, -1} },
- },
- [P4_EVENT_GLOBAL_POWER_EVENTS] = {
- .opcode = P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_TC_MS_XFER] = {
- .opcode = P4_OPCODE(P4_EVENT_TC_MS_XFER),
- .escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
- .cntr = { {4, 5, -1}, {6, 7, -1} },
- },
- [P4_EVENT_UOP_QUEUE_WRITES] = {
- .opcode = P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES),
- .escr_msr = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
- .cntr = { {4, 5, -1}, {6, 7, -1} },
- },
- [P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE] = {
- .opcode = P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE),
- .escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR0 },
- .cntr = { {4, 5, -1}, {6, 7, -1} },
- },
- [P4_EVENT_RETIRED_BRANCH_TYPE] = {
- .opcode = P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE),
- .escr_msr = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR1 },
- .cntr = { {4, 5, -1}, {6, 7, -1} },
- },
- [P4_EVENT_RESOURCE_STALL] = {
- .opcode = P4_OPCODE(P4_EVENT_RESOURCE_STALL),
- .escr_msr = { MSR_P4_ALF_ESCR0, MSR_P4_ALF_ESCR1 },
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_WC_BUFFER] = {
- .opcode = P4_OPCODE(P4_EVENT_WC_BUFFER),
- .escr_msr = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
- .cntr = { {8, 9, -1}, {10, 11, -1} },
- },
- [P4_EVENT_B2B_CYCLES] = {
- .opcode = P4_OPCODE(P4_EVENT_B2B_CYCLES),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_BNR] = {
- .opcode = P4_OPCODE(P4_EVENT_BNR),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_SNOOP] = {
- .opcode = P4_OPCODE(P4_EVENT_SNOOP),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_RESPONSE] = {
- .opcode = P4_OPCODE(P4_EVENT_RESPONSE),
- .escr_msr = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
- .cntr = { {0, -1, -1}, {2, -1, -1} },
- },
- [P4_EVENT_FRONT_END_EVENT] = {
- .opcode = P4_OPCODE(P4_EVENT_FRONT_END_EVENT),
- .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_EXECUTION_EVENT] = {
- .opcode = P4_OPCODE(P4_EVENT_EXECUTION_EVENT),
- .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_REPLAY_EVENT] = {
- .opcode = P4_OPCODE(P4_EVENT_REPLAY_EVENT),
- .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_INSTR_RETIRED] = {
- .opcode = P4_OPCODE(P4_EVENT_INSTR_RETIRED),
- .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_UOPS_RETIRED] = {
- .opcode = P4_OPCODE(P4_EVENT_UOPS_RETIRED),
- .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_UOP_TYPE] = {
- .opcode = P4_OPCODE(P4_EVENT_UOP_TYPE),
- .escr_msr = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 },
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_BRANCH_RETIRED] = {
- .opcode = P4_OPCODE(P4_EVENT_BRANCH_RETIRED),
- .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_MISPRED_BRANCH_RETIRED] = {
- .opcode = P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED),
- .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_X87_ASSIST] = {
- .opcode = P4_OPCODE(P4_EVENT_X87_ASSIST),
- .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_MACHINE_CLEAR] = {
- .opcode = P4_OPCODE(P4_EVENT_MACHINE_CLEAR),
- .escr_msr = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
- [P4_EVENT_INSTR_COMPLETED] = {
- .opcode = P4_OPCODE(P4_EVENT_INSTR_COMPLETED),
- .escr_msr = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
- .cntr = { {12, 13, 16}, {14, 15, 17} },
- },
-};
-
-#define P4_GEN_CACHE_EVENT(event, bit, cache_event) \
- p4_config_pack_escr(P4_ESCR_EVENT(event) | \
- P4_ESCR_EMASK_BIT(event, bit)) | \
- p4_config_pack_cccr(cache_event | \
- P4_CCCR_ESEL(P4_OPCODE_ESEL(P4_OPCODE(event))))
-
-static __initconst const u64 p4_hw_cache_event_ids
- [PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
- P4_CACHE__1stl_cache_load_miss_retired),
- },
- },
- [ C(LL ) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
- P4_CACHE__2ndl_cache_load_miss_retired),
- },
-},
- [ C(DTLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
- P4_CACHE__dtlb_load_miss_retired),
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = 0x0,
- [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
- P4_CACHE__dtlb_store_miss_retired),
- },
- },
- [ C(ITLB) ] = {
- [ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, HIT,
- P4_CACHE__itlb_reference_hit),
- [ C(RESULT_MISS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, MISS,
- P4_CACHE__itlb_reference_miss),
- },
- [ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- [ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
- },
- },
-};
-
-static u64 p4_general_events[PERF_COUNT_HW_MAX] = {
- /* non-halted CPU clocks */
- [PERF_COUNT_HW_CPU_CYCLES] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_GLOBAL_POWER_EVENTS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING)),
-
- /*
- * retired instructions
- * in a sake of simplicity we don't use the FSB tagging
- */
- [PERF_COUNT_HW_INSTRUCTIONS] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_INSTR_RETIRED) |
- P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG) |
- P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG)),
-
- /* cache hits */
- [PERF_COUNT_HW_CACHE_REFERENCES] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM)),
-
- /* cache misses */
- [PERF_COUNT_HW_CACHE_MISSES] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS) |
- P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS)),
-
- /* branch instructions retired */
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_RETIRED_BRANCH_TYPE) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN) |
- P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT)),
-
- /* mispredicted branches retired */
- [PERF_COUNT_HW_BRANCH_MISSES] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_MISPRED_BRANCH_RETIRED) |
- P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS)),
-
- /* bus ready clocks (cpu is driving #DRDY_DRV\#DRDY_OWN): */
- [PERF_COUNT_HW_BUS_CYCLES] =
- p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_FSB_DATA_ACTIVITY) |
- P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV) |
- P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN)) |
- p4_config_pack_cccr(P4_CCCR_EDGE | P4_CCCR_COMPARE),
-};
-
-static struct p4_event_bind *p4_config_get_bind(u64 config)
-{
- unsigned int evnt = p4_config_unpack_event(config);
- struct p4_event_bind *bind = NULL;
-
- if (evnt < ARRAY_SIZE(p4_event_bind_map))
- bind = &p4_event_bind_map[evnt];
-
- return bind;
-}
-
-static u64 p4_pmu_event_map(int hw_event)
-{
- struct p4_event_bind *bind;
- unsigned int esel;
- u64 config;
-
- config = p4_general_events[hw_event];
- bind = p4_config_get_bind(config);
- esel = P4_OPCODE_ESEL(bind->opcode);
- config |= p4_config_pack_cccr(P4_CCCR_ESEL(esel));
-
- return config;
-}
-
-static int p4_hw_config(struct perf_event *event)
-{
- int cpu = get_cpu();
- int rc = 0;
- unsigned int evnt;
- u32 escr, cccr;
-
- /*
- * the reason we use cpu that early is that: if we get scheduled
- * first time on the same cpu -- we will not need swap thread
- * specific flags in config (and will save some cpu cycles)
- */
-
- cccr = p4_default_cccr_conf(cpu);
- escr = p4_default_escr_conf(cpu, event->attr.exclude_kernel,
- event->attr.exclude_user);
- event->hw.config = p4_config_pack_escr(escr) |
- p4_config_pack_cccr(cccr);
-
- if (p4_ht_active() && p4_ht_thread(cpu))
- event->hw.config = p4_set_ht_bit(event->hw.config);
-
- if (event->attr.type == PERF_TYPE_RAW) {
-
- /* user data may have out-of-bound event index */
- evnt = p4_config_unpack_event(event->attr.config);
- if (evnt >= ARRAY_SIZE(p4_event_bind_map)) {
- rc = -EINVAL;
- goto out;
- }
-
- /*
- * We don't control raw events so it's up to the caller
- * to pass sane values (and we don't count the thread number
- * on HT machine but allow HT-compatible specifics to be
- * passed on)
- *
- * XXX: HT wide things should check perf_paranoid_cpu() &&
- * CAP_SYS_ADMIN
- */
- event->hw.config |= event->attr.config &
- (p4_config_pack_escr(P4_ESCR_MASK_HT) |
- p4_config_pack_cccr(P4_CCCR_MASK_HT));
- }
-
- rc = x86_setup_perfctr(event);
-out:
- put_cpu();
- return rc;
-}
-
-static inline int p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc)
-{
- int overflow = 0;
- u32 low, high;
-
- rdmsr(hwc->config_base + hwc->idx, low, high);
-
- /* we need to check high bit for unflagged overflows */
- if ((low & P4_CCCR_OVF) || !(high & (1 << 31))) {
- overflow = 1;
- (void)checking_wrmsrl(hwc->config_base + hwc->idx,
- ((u64)low) & ~P4_CCCR_OVF);
- }
-
- return overflow;
-}
-
-static inline void p4_pmu_disable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
-
- /*
- * If event gets disabled while counter is in overflowed
- * state we need to clear P4_CCCR_OVF, otherwise interrupt get
- * asserted again and again
- */
- (void)checking_wrmsrl(hwc->config_base + hwc->idx,
- (u64)(p4_config_unpack_cccr(hwc->config)) &
- ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED);
-}
-
-static void p4_pmu_disable_all(void)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- int idx;
-
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
- struct perf_event *event = cpuc->events[idx];
- if (!test_bit(idx, cpuc->active_mask))
- continue;
- p4_pmu_disable_event(event);
- }
-}
-
-static void p4_pmu_enable_event(struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- int thread = p4_ht_config_thread(hwc->config);
- u64 escr_conf = p4_config_unpack_escr(p4_clear_ht_bit(hwc->config));
- unsigned int idx = p4_config_unpack_event(hwc->config);
- unsigned int idx_cache = p4_config_unpack_cache_event(hwc->config);
- struct p4_event_bind *bind;
- struct p4_cache_event_bind *bind_cache;
- u64 escr_addr, cccr;
-
- bind = &p4_event_bind_map[idx];
- escr_addr = (u64)bind->escr_msr[thread];
-
- /*
- * - we dont support cascaded counters yet
- * - and counter 1 is broken (erratum)
- */
- WARN_ON_ONCE(p4_is_event_cascaded(hwc->config));
- WARN_ON_ONCE(hwc->idx == 1);
-
- /* we need a real Event value */
- escr_conf &= ~P4_ESCR_EVENT_MASK;
- escr_conf |= P4_ESCR_EVENT(P4_OPCODE_EVNT(bind->opcode));
-
- cccr = p4_config_unpack_cccr(hwc->config);
-
- /*
- * it could be Cache event so that we need to
- * set metrics into additional MSRs
- */
- BUILD_BUG_ON(P4_CACHE__MAX > P4_CCCR_CACHE_OPS_MASK);
- if (idx_cache > P4_CACHE__NONE &&
- idx_cache < ARRAY_SIZE(p4_cache_event_bind_map)) {
- bind_cache = &p4_cache_event_bind_map[idx_cache];
- (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)bind_cache->metric_pebs);
- (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)bind_cache->metric_vert);
- }
-
- (void)checking_wrmsrl(escr_addr, escr_conf);
- (void)checking_wrmsrl(hwc->config_base + hwc->idx,
- (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE);
-}
-
-static void p4_pmu_enable_all(int added)
-{
- struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
- int idx;
-
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
- struct perf_event *event = cpuc->events[idx];
- if (!test_bit(idx, cpuc->active_mask))
- continue;
- p4_pmu_enable_event(event);
- }
-}
-
-static int p4_pmu_handle_irq(struct pt_regs *regs)
-{
- struct perf_sample_data data;
- struct cpu_hw_events *cpuc;
- struct perf_event *event;
- struct hw_perf_event *hwc;
- int idx, handled = 0;
- u64 val;
-
- data.addr = 0;
- data.raw = NULL;
-
- cpuc = &__get_cpu_var(cpu_hw_events);
-
- for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-
- if (!test_bit(idx, cpuc->active_mask))
- continue;
-
- event = cpuc->events[idx];
- hwc = &event->hw;
-
- WARN_ON_ONCE(hwc->idx != idx);
-
- /* it might be unflagged overflow */
- handled = p4_pmu_clear_cccr_ovf(hwc);
-
- val = x86_perf_event_update(event);
- if (!handled && (val & (1ULL << (x86_pmu.cntval_bits - 1))))
- continue;
-
- /* event overflow for sure */
- data.period = event->hw.last_period;
-
- if (!x86_perf_event_set_period(event))
- continue;
- if (perf_event_overflow(event, 1, &data, regs))
- p4_pmu_disable_event(event);
- }
-
- if (handled) {
- /* p4 quirk: unmask it again */
- apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);
- inc_irq_stat(apic_perf_irqs);
- }
-
- return handled;
-}
-
-/*
- * swap thread specific fields according to a thread
- * we are going to run on
- */
-static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu)
-{
- u32 escr, cccr;
-
- /*
- * we either lucky and continue on same cpu or no HT support
- */
- if (!p4_should_swap_ts(hwc->config, cpu))
- return;
-
- /*
- * the event is migrated from an another logical
- * cpu, so we need to swap thread specific flags
- */
-
- escr = p4_config_unpack_escr(hwc->config);
- cccr = p4_config_unpack_cccr(hwc->config);
-
- if (p4_ht_thread(cpu)) {
- cccr &= ~P4_CCCR_OVF_PMI_T0;
- cccr |= P4_CCCR_OVF_PMI_T1;
- if (escr & P4_ESCR_T0_OS) {
- escr &= ~P4_ESCR_T0_OS;
- escr |= P4_ESCR_T1_OS;
- }
- if (escr & P4_ESCR_T0_USR) {
- escr &= ~P4_ESCR_T0_USR;
- escr |= P4_ESCR_T1_USR;
- }
- hwc->config = p4_config_pack_escr(escr);
- hwc->config |= p4_config_pack_cccr(cccr);
- hwc->config |= P4_CONFIG_HT;
- } else {
- cccr &= ~P4_CCCR_OVF_PMI_T1;
- cccr |= P4_CCCR_OVF_PMI_T0;
- if (escr & P4_ESCR_T1_OS) {
- escr &= ~P4_ESCR_T1_OS;
- escr |= P4_ESCR_T0_OS;
- }
- if (escr & P4_ESCR_T1_USR) {
- escr &= ~P4_ESCR_T1_USR;
- escr |= P4_ESCR_T0_USR;
- }
- hwc->config = p4_config_pack_escr(escr);
- hwc->config |= p4_config_pack_cccr(cccr);
- hwc->config &= ~P4_CONFIG_HT;
- }
-}
-
-/*
- * ESCR address hashing is tricky, ESCRs are not sequential
- * in memory but all starts from MSR_P4_BSU_ESCR0 (0x03a0) and
- * the metric between any ESCRs is laid in range [0xa0,0xe1]
- *
- * so we make ~70% filled hashtable
- */
-
-#define P4_ESCR_MSR_BASE 0x000003a0
-#define P4_ESCR_MSR_MAX 0x000003e1
-#define P4_ESCR_MSR_TABLE_SIZE (P4_ESCR_MSR_MAX - P4_ESCR_MSR_BASE + 1)
-#define P4_ESCR_MSR_IDX(msr) (msr - P4_ESCR_MSR_BASE)
-#define P4_ESCR_MSR_TABLE_ENTRY(msr) [P4_ESCR_MSR_IDX(msr)] = msr
-
-static const unsigned int p4_escr_table[P4_ESCR_MSR_TABLE_SIZE] = {
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR2),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR3),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR4),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR5),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR1),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR0),
- P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR1),
-};
-
-static int p4_get_escr_idx(unsigned int addr)
-{
- unsigned int idx = P4_ESCR_MSR_IDX(addr);
-
- if (unlikely(idx >= P4_ESCR_MSR_TABLE_SIZE ||
- !p4_escr_table[idx] ||
- p4_escr_table[idx] != addr)) {
- WARN_ONCE(1, "P4 PMU: Wrong address passed: %x\n", addr);
- return -1;
- }
-
- return idx;
-}
-
-static int p4_next_cntr(int thread, unsigned long *used_mask,
- struct p4_event_bind *bind)
-{
- int i, j;
-
- for (i = 0; i < P4_CNTR_LIMIT; i++) {
- j = bind->cntr[thread][i];
- if (j != -1 && !test_bit(j, used_mask))
- return j;
- }
-
- return -1;
-}
-
-static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
-{
- unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
- unsigned long escr_mask[BITS_TO_LONGS(P4_ESCR_MSR_TABLE_SIZE)];
- int cpu = smp_processor_id();
- struct hw_perf_event *hwc;
- struct p4_event_bind *bind;
- unsigned int i, thread, num;
- int cntr_idx, escr_idx;
-
- bitmap_zero(used_mask, X86_PMC_IDX_MAX);
- bitmap_zero(escr_mask, P4_ESCR_MSR_TABLE_SIZE);
-
- for (i = 0, num = n; i < n; i++, num--) {
-
- hwc = &cpuc->event_list[i]->hw;
- thread = p4_ht_thread(cpu);
- bind = p4_config_get_bind(hwc->config);
- escr_idx = p4_get_escr_idx(bind->escr_msr[thread]);
- if (unlikely(escr_idx == -1))
- goto done;
-
- if (hwc->idx != -1 && !p4_should_swap_ts(hwc->config, cpu)) {
- cntr_idx = hwc->idx;
- if (assign)
- assign[i] = hwc->idx;
- goto reserve;
- }
-
- cntr_idx = p4_next_cntr(thread, used_mask, bind);
- if (cntr_idx == -1 || test_bit(escr_idx, escr_mask))
- goto done;
-
- p4_pmu_swap_config_ts(hwc, cpu);
- if (assign)
- assign[i] = cntr_idx;
-reserve:
- set_bit(cntr_idx, used_mask);
- set_bit(escr_idx, escr_mask);
- }
-
-done:
- return num ? -ENOSPC : 0;
-}
-
-static __initconst const struct x86_pmu p4_pmu = {
- .name = "Netburst P4/Xeon",
- .handle_irq = p4_pmu_handle_irq,
- .disable_all = p4_pmu_disable_all,
- .enable_all = p4_pmu_enable_all,
- .enable = p4_pmu_enable_event,
- .disable = p4_pmu_disable_event,
- .eventsel = MSR_P4_BPU_CCCR0,
- .perfctr = MSR_P4_BPU_PERFCTR0,
- .event_map = p4_pmu_event_map,
- .max_events = ARRAY_SIZE(p4_general_events),
- .get_event_constraints = x86_get_event_constraints,
- /*
- * IF HT disabled we may need to use all
- * ARCH_P4_MAX_CCCR counters simulaneously
- * though leave it restricted at moment assuming
- * HT is on
- */
- .num_counters = ARCH_P4_MAX_CCCR,
- .apic = 1,
- .cntval_bits = 40,
- .cntval_mask = (1ULL << 40) - 1,
- .max_period = (1ULL << 39) - 1,
- .hw_config = p4_hw_config,
- .schedule_events = p4_pmu_schedule_events,
-};
-
-static __init int p4_pmu_init(void)
-{
- unsigned int low, high;
-
- /* If we get stripped -- indexig fails */
- BUILD_BUG_ON(ARCH_P4_MAX_CCCR > X86_PMC_MAX_GENERIC);
-
- rdmsr(MSR_IA32_MISC_ENABLE, low, high);
- if (!(low & (1 << 7))) {
- pr_cont("unsupported Netburst CPU model %d ",
- boot_cpu_data.x86_model);
- return -ENODEV;
- }
-
- memcpy(hw_cache_event_ids, p4_hw_cache_event_ids,
- sizeof(hw_cache_event_ids));
-
- pr_cont("Netburst events, ");
-
- x86_pmu = p4_pmu;
-
- return 0;
-}
-
-#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/trunk/arch/x86/kernel/cpu/perf_event_p6.c b/trunk/arch/x86/kernel/cpu/perf_event_p6.c
index 34ba07be2cda..a330485d14da 100644
--- a/trunk/arch/x86/kernel/cpu/perf_event_p6.c
+++ b/trunk/arch/x86/kernel/cpu/perf_event_p6.c
@@ -27,6 +27,24 @@ static u64 p6_pmu_event_map(int hw_event)
*/
#define P6_NOP_EVENT 0x0000002EULL
+static u64 p6_pmu_raw_event(u64 hw_event)
+{
+#define P6_EVNTSEL_EVENT_MASK 0x000000FFULL
+#define P6_EVNTSEL_UNIT_MASK 0x0000FF00ULL
+#define P6_EVNTSEL_EDGE_MASK 0x00040000ULL
+#define P6_EVNTSEL_INV_MASK 0x00800000ULL
+#define P6_EVNTSEL_REG_MASK 0xFF000000ULL
+
+#define P6_EVNTSEL_MASK \
+ (P6_EVNTSEL_EVENT_MASK | \
+ P6_EVNTSEL_UNIT_MASK | \
+ P6_EVNTSEL_EDGE_MASK | \
+ P6_EVNTSEL_INV_MASK | \
+ P6_EVNTSEL_REG_MASK)
+
+ return hw_event & P6_EVNTSEL_MASK;
+}
+
static struct event_constraint p6_event_constraints[] =
{
INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FLOPS */
@@ -48,7 +66,7 @@ static void p6_pmu_disable_all(void)
wrmsrl(MSR_P6_EVNTSEL0, val);
}
-static void p6_pmu_enable_all(int added)
+static void p6_pmu_enable_all(void)
{
unsigned long val;
@@ -84,23 +102,22 @@ static void p6_pmu_enable_event(struct perf_event *event)
(void)checking_wrmsrl(hwc->config_base + hwc->idx, val);
}
-static __initconst const struct x86_pmu p6_pmu = {
+static __initconst struct x86_pmu p6_pmu = {
.name = "p6",
.handle_irq = x86_pmu_handle_irq,
.disable_all = p6_pmu_disable_all,
.enable_all = p6_pmu_enable_all,
.enable = p6_pmu_enable_event,
.disable = p6_pmu_disable_event,
- .hw_config = x86_pmu_hw_config,
- .schedule_events = x86_schedule_events,
.eventsel = MSR_P6_EVNTSEL0,
.perfctr = MSR_P6_PERFCTR0,
.event_map = p6_pmu_event_map,
+ .raw_event = p6_pmu_raw_event,
.max_events = ARRAY_SIZE(p6_perfmon_event_map),
.apic = 1,
.max_period = (1ULL << 31) - 1,
.version = 0,
- .num_counters = 2,
+ .num_events = 2,
/*
* Events have 40 bits implemented. However they are designed such
* that bits [32-39] are sign extensions of bit 31. As such the
@@ -108,8 +125,8 @@ static __initconst const struct x86_pmu p6_pmu = {
*
* See IA-32 Intel Architecture Software developer manual Vol 3B
*/
- .cntval_bits = 32,
- .cntval_mask = (1ULL << 32) - 1,
+ .event_bits = 32,
+ .event_mask = (1ULL << 32) - 1,
.get_event_constraints = x86_get_event_constraints,
.event_constraints = p6_event_constraints,
};
diff --git a/trunk/arch/x86/kernel/cpu/vmware.c b/trunk/arch/x86/kernel/cpu/vmware.c
index b9d1ff588445..dfdb4dba2320 100644
--- a/trunk/arch/x86/kernel/cpu/vmware.c
+++ b/trunk/arch/x86/kernel/cpu/vmware.c
@@ -24,8 +24,8 @@
#include
#include
#include
+#include
#include
-#include
#define CPUID_VMWARE_INFO_LEAF 0x40000000
#define VMWARE_HYPERVISOR_MAGIC 0x564D5868
@@ -65,7 +65,7 @@ static unsigned long vmware_get_tsc_khz(void)
return tsc_hz;
}
-static void __init vmware_platform_setup(void)
+void __init vmware_platform_setup(void)
{
uint32_t eax, ebx, ecx, edx;
@@ -83,22 +83,26 @@ static void __init vmware_platform_setup(void)
* serial key should be enough, as this will always have a VMware
* specific string when running under VMware hypervisor.
*/
-static bool __init vmware_platform(void)
+int vmware_platform(void)
{
if (cpu_has_hypervisor) {
- unsigned int eax;
- unsigned int hyper_vendor_id[3];
-
- cpuid(CPUID_VMWARE_INFO_LEAF, &eax, &hyper_vendor_id[0],
- &hyper_vendor_id[1], &hyper_vendor_id[2]);
- if (!memcmp(hyper_vendor_id, "VMwareVMware", 12))
- return true;
+ unsigned int eax, ebx, ecx, edx;
+ char hyper_vendor_id[13];
+
+ cpuid(CPUID_VMWARE_INFO_LEAF, &eax, &ebx, &ecx, &edx);
+ memcpy(hyper_vendor_id + 0, &ebx, 4);
+ memcpy(hyper_vendor_id + 4, &ecx, 4);
+ memcpy(hyper_vendor_id + 8, &edx, 4);
+ hyper_vendor_id[12] = '\0';
+ if (!strcmp(hyper_vendor_id, "VMwareVMware"))
+ return 1;
} else if (dmi_available && dmi_name_in_serial("VMware") &&
__vmware_platform())
- return true;
+ return 1;
- return false;
+ return 0;
}
+EXPORT_SYMBOL(vmware_platform);
/*
* VMware hypervisor takes care of exporting a reliable TSC to the guest.
@@ -112,16 +116,8 @@ static bool __init vmware_platform(void)
* so that the kernel could just trust the hypervisor with providing a
* reliable virtual TSC that is suitable for timekeeping.
*/
-static void __cpuinit vmware_set_cpu_features(struct cpuinfo_x86 *c)
+void __cpuinit vmware_set_feature_bits(struct cpuinfo_x86 *c)
{
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE);
}
-
-const __refconst struct hypervisor_x86 x86_hyper_vmware = {
- .name = "VMware",
- .detect = vmware_platform,
- .set_cpu_features = vmware_set_cpu_features,
- .init_platform = vmware_platform_setup,
-};
-EXPORT_SYMBOL(x86_hyper_vmware);
diff --git a/trunk/arch/x86/kernel/ds.c b/trunk/arch/x86/kernel/ds.c
new file mode 100644
index 000000000000..1c47390dd0e5
--- /dev/null
+++ b/trunk/arch/x86/kernel/ds.c
@@ -0,0 +1,1437 @@
+/*
+ * Debug Store support
+ *
+ * This provides a low-level interface to the hardware's Debug Store
+ * feature that is used for branch trace store (BTS) and
+ * precise-event based sampling (PEBS).
+ *
+ * It manages:
+ * - DS and BTS hardware configuration
+ * - buffer overflow handling (to be done)
+ * - buffer access
+ *
+ * It does not do:
+ * - security checking (is the caller allowed to trace the task)
+ * - buffer allocation (memory accounting)
+ *
+ *
+ * Copyright (C) 2007-2009 Intel Corporation.
+ * Markus Metzger , 2007-2009
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "ds_selftest.h"
+
+/*
+ * The configuration for a particular DS hardware implementation:
+ */
+struct ds_configuration {
+ /* The name of the configuration: */
+ const char *name;
+
+ /* The size of pointer-typed fields in DS, BTS, and PEBS: */
+ unsigned char sizeof_ptr_field;
+
+ /* The size of a BTS/PEBS record in bytes: */
+ unsigned char sizeof_rec[2];
+
+ /* The number of pebs counter reset values in the DS structure. */
+ unsigned char nr_counter_reset;
+
+ /* Control bit-masks indexed by enum ds_feature: */
+ unsigned long ctl[dsf_ctl_max];
+};
+static struct ds_configuration ds_cfg __read_mostly;
+
+
+/* Maximal size of a DS configuration: */
+#define MAX_SIZEOF_DS 0x80
+
+/* Maximal size of a BTS record: */
+#define MAX_SIZEOF_BTS (3 * 8)
+
+/* BTS and PEBS buffer alignment: */
+#define DS_ALIGNMENT (1 << 3)
+
+/* Number of buffer pointers in DS: */
+#define NUM_DS_PTR_FIELDS 8
+
+/* Size of a pebs reset value in DS: */
+#define PEBS_RESET_FIELD_SIZE 8
+
+/* Mask of control bits in the DS MSR register: */
+#define BTS_CONTROL \
+ ( ds_cfg.ctl[dsf_bts] | \
+ ds_cfg.ctl[dsf_bts_kernel] | \
+ ds_cfg.ctl[dsf_bts_user] | \
+ ds_cfg.ctl[dsf_bts_overflow] )
+
+/*
+ * A BTS or PEBS tracer.
+ *
+ * This holds the configuration of the tracer and serves as a handle
+ * to identify tracers.
+ */
+struct ds_tracer {
+ /* The DS context (partially) owned by this tracer. */
+ struct ds_context *context;
+ /* The buffer provided on ds_request() and its size in bytes. */
+ void *buffer;
+ size_t size;
+};
+
+struct bts_tracer {
+ /* The common DS part: */
+ struct ds_tracer ds;
+
+ /* The trace including the DS configuration: */
+ struct bts_trace trace;
+
+ /* Buffer overflow notification function: */
+ bts_ovfl_callback_t ovfl;
+
+ /* Active flags affecting trace collection. */
+ unsigned int flags;
+};
+
+struct pebs_tracer {
+ /* The common DS part: */
+ struct ds_tracer ds;
+
+ /* The trace including the DS configuration: */
+ struct pebs_trace trace;
+
+ /* Buffer overflow notification function: */
+ pebs_ovfl_callback_t ovfl;
+};
+
+/*
+ * Debug Store (DS) save area configuration (see Intel64 and IA32
+ * Architectures Software Developer's Manual, section 18.5)
+ *
+ * The DS configuration consists of the following fields; different
+ * architetures vary in the size of those fields.
+ *
+ * - double-word aligned base linear address of the BTS buffer
+ * - write pointer into the BTS buffer
+ * - end linear address of the BTS buffer (one byte beyond the end of
+ * the buffer)
+ * - interrupt pointer into BTS buffer
+ * (interrupt occurs when write pointer passes interrupt pointer)
+ * - double-word aligned base linear address of the PEBS buffer
+ * - write pointer into the PEBS buffer
+ * - end linear address of the PEBS buffer (one byte beyond the end of
+ * the buffer)
+ * - interrupt pointer into PEBS buffer
+ * (interrupt occurs when write pointer passes interrupt pointer)
+ * - value to which counter is reset following counter overflow
+ *
+ * Later architectures use 64bit pointers throughout, whereas earlier
+ * architectures use 32bit pointers in 32bit mode.
+ *
+ *
+ * We compute the base address for the first 8 fields based on:
+ * - the field size stored in the DS configuration
+ * - the relative field position
+ * - an offset giving the start of the respective region
+ *
+ * This offset is further used to index various arrays holding
+ * information for BTS and PEBS at the respective index.
+ *
+ * On later 32bit processors, we only access the lower 32bit of the
+ * 64bit pointer fields. The upper halves will be zeroed out.
+ */
+
+enum ds_field {
+ ds_buffer_base = 0,
+ ds_index,
+ ds_absolute_maximum,
+ ds_interrupt_threshold,
+};
+
+enum ds_qualifier {
+ ds_bts = 0,
+ ds_pebs
+};
+
+static inline unsigned long
+ds_get(const unsigned char *base, enum ds_qualifier qual, enum ds_field field)
+{
+ base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
+ return *(unsigned long *)base;
+}
+
+static inline void
+ds_set(unsigned char *base, enum ds_qualifier qual, enum ds_field field,
+ unsigned long value)
+{
+ base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
+ (*(unsigned long *)base) = value;
+}
+
+
+/*
+ * Locking is done only for allocating BTS or PEBS resources.
+ */
+static DEFINE_SPINLOCK(ds_lock);
+
+/*
+ * We either support (system-wide) per-cpu or per-thread allocation.
+ * We distinguish the two based on the task_struct pointer, where a
+ * NULL pointer indicates per-cpu allocation for the current cpu.
+ *
+ * Allocations are use-counted. As soon as resources are allocated,
+ * further allocations must be of the same type (per-cpu or
+ * per-thread). We model this by counting allocations (i.e. the number
+ * of tracers of a certain type) for one type negatively:
+ * =0 no tracers
+ * >0 number of per-thread tracers
+ * <0 number of per-cpu tracers
+ *
+ * Tracers essentially gives the number of ds contexts for a certain
+ * type of allocation.
+ */
+static atomic_t tracers = ATOMIC_INIT(0);
+
+static inline int get_tracer(struct task_struct *task)
+{
+ int error;
+
+ spin_lock_irq(&ds_lock);
+
+ if (task) {
+ error = -EPERM;
+ if (atomic_read(&tracers) < 0)
+ goto out;
+ atomic_inc(&tracers);
+ } else {
+ error = -EPERM;
+ if (atomic_read(&tracers) > 0)
+ goto out;
+ atomic_dec(&tracers);
+ }
+
+ error = 0;
+out:
+ spin_unlock_irq(&ds_lock);
+ return error;
+}
+
+static inline void put_tracer(struct task_struct *task)
+{
+ if (task)
+ atomic_dec(&tracers);
+ else
+ atomic_inc(&tracers);
+}
+
+/*
+ * The DS context is either attached to a thread or to a cpu:
+ * - in the former case, the thread_struct contains a pointer to the
+ * attached context.
+ * - in the latter case, we use a static array of per-cpu context
+ * pointers.
+ *
+ * Contexts are use-counted. They are allocated on first access and
+ * deallocated when the last user puts the context.
+ */
+struct ds_context {
+ /* The DS configuration; goes into MSR_IA32_DS_AREA: */
+ unsigned char ds[MAX_SIZEOF_DS];
+
+ /* The owner of the BTS and PEBS configuration, respectively: */
+ struct bts_tracer *bts_master;
+ struct pebs_tracer *pebs_master;
+
+ /* Use count: */
+ unsigned long count;
+
+ /* Pointer to the context pointer field: */
+ struct ds_context **this;
+
+ /* The traced task; NULL for cpu tracing: */
+ struct task_struct *task;
+
+ /* The traced cpu; only valid if task is NULL: */
+ int cpu;
+};
+
+static DEFINE_PER_CPU(struct ds_context *, cpu_ds_context);
+
+
+static struct ds_context *ds_get_context(struct task_struct *task, int cpu)
+{
+ struct ds_context **p_context =
+ (task ? &task->thread.ds_ctx : &per_cpu(cpu_ds_context, cpu));
+ struct ds_context *context = NULL;
+ struct ds_context *new_context = NULL;
+
+ /* Chances are small that we already have a context. */
+ new_context = kzalloc(sizeof(*new_context), GFP_KERNEL);
+ if (!new_context)
+ return NULL;
+
+ spin_lock_irq(&ds_lock);
+
+ context = *p_context;
+ if (likely(!context)) {
+ context = new_context;
+
+ context->this = p_context;
+ context->task = task;
+ context->cpu = cpu;
+ context->count = 0;
+
+ *p_context = context;
+ }
+
+ context->count++;
+
+ spin_unlock_irq(&ds_lock);
+
+ if (context != new_context)
+ kfree(new_context);
+
+ return context;
+}
+
+static void ds_put_context(struct ds_context *context)
+{
+ struct task_struct *task;
+ unsigned long irq;
+
+ if (!context)
+ return;
+
+ spin_lock_irqsave(&ds_lock, irq);
+
+ if (--context->count) {
+ spin_unlock_irqrestore(&ds_lock, irq);
+ return;
+ }
+
+ *(context->this) = NULL;
+
+ task = context->task;
+
+ if (task)
+ clear_tsk_thread_flag(task, TIF_DS_AREA_MSR);
+
+ /*
+ * We leave the (now dangling) pointer to the DS configuration in
+ * the DS_AREA msr. This is as good or as bad as replacing it with
+ * NULL - the hardware would crash if we enabled tracing.
+ *
+ * This saves us some problems with having to write an msr on a
+ * different cpu while preventing others from doing the same for the
+ * next context for that same cpu.
+ */
+
+ spin_unlock_irqrestore(&ds_lock, irq);
+
+ /* The context might still be in use for context switching. */
+ if (task && (task != current))
+ wait_task_context_switch(task);
+
+ kfree(context);
+}
+
+static void ds_install_ds_area(struct ds_context *context)
+{
+ unsigned long ds;
+
+ ds = (unsigned long)context->ds;
+
+ /*
+ * There is a race between the bts master and the pebs master.
+ *
+ * The thread/cpu access is synchronized via get/put_cpu() for
+ * task tracing and via wrmsr_on_cpu for cpu tracing.
+ *
+ * If bts and pebs are collected for the same task or same cpu,
+ * the same confiuration is written twice.
+ */
+ if (context->task) {
+ get_cpu();
+ if (context->task == current)
+ wrmsrl(MSR_IA32_DS_AREA, ds);
+ set_tsk_thread_flag(context->task, TIF_DS_AREA_MSR);
+ put_cpu();
+ } else
+ wrmsr_on_cpu(context->cpu, MSR_IA32_DS_AREA,
+ (u32)((u64)ds), (u32)((u64)ds >> 32));
+}
+
+/*
+ * Call the tracer's callback on a buffer overflow.
+ *
+ * context: the ds context
+ * qual: the buffer type
+ */
+static void ds_overflow(struct ds_context *context, enum ds_qualifier qual)
+{
+ switch (qual) {
+ case ds_bts:
+ if (context->bts_master &&
+ context->bts_master->ovfl)
+ context->bts_master->ovfl(context->bts_master);
+ break;
+ case ds_pebs:
+ if (context->pebs_master &&
+ context->pebs_master->ovfl)
+ context->pebs_master->ovfl(context->pebs_master);
+ break;
+ }
+}
+
+
+/*
+ * Write raw data into the BTS or PEBS buffer.
+ *
+ * The remainder of any partially written record is zeroed out.
+ *
+ * context: the DS context
+ * qual: the buffer type
+ * record: the data to write
+ * size: the size of the data
+ */
+static int ds_write(struct ds_context *context, enum ds_qualifier qual,
+ const void *record, size_t size)
+{
+ int bytes_written = 0;
+
+ if (!record)
+ return -EINVAL;
+
+ while (size) {
+ unsigned long base, index, end, write_end, int_th;
+ unsigned long write_size, adj_write_size;
+
+ /*
+ * Write as much as possible without producing an
+ * overflow interrupt.
+ *
+ * Interrupt_threshold must either be
+ * - bigger than absolute_maximum or
+ * - point to a record between buffer_base and absolute_maximum
+ *
+ * Index points to a valid record.
+ */
+ base = ds_get(context->ds, qual, ds_buffer_base);
+ index = ds_get(context->ds, qual, ds_index);
+ end = ds_get(context->ds, qual, ds_absolute_maximum);
+ int_th = ds_get(context->ds, qual, ds_interrupt_threshold);
+
+ write_end = min(end, int_th);
+
+ /*
+ * If we are already beyond the interrupt threshold,
+ * we fill the entire buffer.
+ */
+ if (write_end <= index)
+ write_end = end;
+
+ if (write_end <= index)
+ break;
+
+ write_size = min((unsigned long) size, write_end - index);
+ memcpy((void *)index, record, write_size);
+
+ record = (const char *)record + write_size;
+ size -= write_size;
+ bytes_written += write_size;
+
+ adj_write_size = write_size / ds_cfg.sizeof_rec[qual];
+ adj_write_size *= ds_cfg.sizeof_rec[qual];
+
+ /* Zero out trailing bytes. */
+ memset((char *)index + write_size, 0,
+ adj_write_size - write_size);
+ index += adj_write_size;
+
+ if (index >= end)
+ index = base;
+ ds_set(context->ds, qual, ds_index, index);
+
+ if (index >= int_th)
+ ds_overflow(context, qual);
+ }
+
+ return bytes_written;
+}
+
+
+/*
+ * Branch Trace Store (BTS) uses the following format. Different
+ * architectures vary in the size of those fields.
+ * - source linear address
+ * - destination linear address
+ * - flags
+ *
+ * Later architectures use 64bit pointers throughout, whereas earlier
+ * architectures use 32bit pointers in 32bit mode.
+ *
+ * We compute the base address for the fields based on:
+ * - the field size stored in the DS configuration
+ * - the relative field position
+ *
+ * In order to store additional information in the BTS buffer, we use
+ * a special source address to indicate that the record requires
+ * special interpretation.
+ *
+ * Netburst indicated via a bit in the flags field whether the branch
+ * was predicted; this is ignored.
+ *
+ * We use two levels of abstraction:
+ * - the raw data level defined here
+ * - an arch-independent level defined in ds.h
+ */
+
+enum bts_field {
+ bts_from,
+ bts_to,
+ bts_flags,
+
+ bts_qual = bts_from,
+ bts_clock = bts_to,
+ bts_pid = bts_flags,
+
+ bts_qual_mask = (bts_qual_max - 1),
+ bts_escape = ((unsigned long)-1 & ~bts_qual_mask)
+};
+
+static inline unsigned long bts_get(const char *base, unsigned long field)
+{
+ base += (ds_cfg.sizeof_ptr_field * field);
+ return *(unsigned long *)base;
+}
+
+static inline void bts_set(char *base, unsigned long field, unsigned long val)
+{
+ base += (ds_cfg.sizeof_ptr_field * field);
+ (*(unsigned long *)base) = val;
+}
+
+
+/*
+ * The raw BTS data is architecture dependent.
+ *
+ * For higher-level users, we give an arch-independent view.
+ * - ds.h defines struct bts_struct
+ * - bts_read translates one raw bts record into a bts_struct
+ * - bts_write translates one bts_struct into the raw format and
+ * writes it into the top of the parameter tracer's buffer.
+ *
+ * return: bytes read/written on success; -Eerrno, otherwise
+ */
+static int
+bts_read(struct bts_tracer *tracer, const void *at, struct bts_struct *out)
+{
+ if (!tracer)
+ return -EINVAL;
+
+ if (at < tracer->trace.ds.begin)
+ return -EINVAL;
+
+ if (tracer->trace.ds.end < (at + tracer->trace.ds.size))
+ return -EINVAL;
+
+ memset(out, 0, sizeof(*out));
+ if ((bts_get(at, bts_qual) & ~bts_qual_mask) == bts_escape) {
+ out->qualifier = (bts_get(at, bts_qual) & bts_qual_mask);
+ out->variant.event.clock = bts_get(at, bts_clock);
+ out->variant.event.pid = bts_get(at, bts_pid);
+ } else {
+ out->qualifier = bts_branch;
+ out->variant.lbr.from = bts_get(at, bts_from);
+ out->variant.lbr.to = bts_get(at, bts_to);
+
+ if (!out->variant.lbr.from && !out->variant.lbr.to)
+ out->qualifier = bts_invalid;
+ }
+
+ return ds_cfg.sizeof_rec[ds_bts];
+}
+
+static int bts_write(struct bts_tracer *tracer, const struct bts_struct *in)
+{
+ unsigned char raw[MAX_SIZEOF_BTS];
+
+ if (!tracer)
+ return -EINVAL;
+
+ if (MAX_SIZEOF_BTS < ds_cfg.sizeof_rec[ds_bts])
+ return -EOVERFLOW;
+
+ switch (in->qualifier) {
+ case bts_invalid:
+ bts_set(raw, bts_from, 0);
+ bts_set(raw, bts_to, 0);
+ bts_set(raw, bts_flags, 0);
+ break;
+ case bts_branch:
+ bts_set(raw, bts_from, in->variant.lbr.from);
+ bts_set(raw, bts_to, in->variant.lbr.to);
+ bts_set(raw, bts_flags, 0);
+ break;
+ case bts_task_arrives:
+ case bts_task_departs:
+ bts_set(raw, bts_qual, (bts_escape | in->qualifier));
+ bts_set(raw, bts_clock, in->variant.event.clock);
+ bts_set(raw, bts_pid, in->variant.event.pid);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ds_write(tracer->ds.context, ds_bts, raw,
+ ds_cfg.sizeof_rec[ds_bts]);
+}
+
+
+static void ds_write_config(struct ds_context *context,
+ struct ds_trace *cfg, enum ds_qualifier qual)
+{
+ unsigned char *ds = context->ds;
+
+ ds_set(ds, qual, ds_buffer_base, (unsigned long)cfg->begin);
+ ds_set(ds, qual, ds_index, (unsigned long)cfg->top);
+ ds_set(ds, qual, ds_absolute_maximum, (unsigned long)cfg->end);
+ ds_set(ds, qual, ds_interrupt_threshold, (unsigned long)cfg->ith);
+}
+
+static void ds_read_config(struct ds_context *context,
+ struct ds_trace *cfg, enum ds_qualifier qual)
+{
+ unsigned char *ds = context->ds;
+
+ cfg->begin = (void *)ds_get(ds, qual, ds_buffer_base);
+ cfg->top = (void *)ds_get(ds, qual, ds_index);
+ cfg->end = (void *)ds_get(ds, qual, ds_absolute_maximum);
+ cfg->ith = (void *)ds_get(ds, qual, ds_interrupt_threshold);
+}
+
+static void ds_init_ds_trace(struct ds_trace *trace, enum ds_qualifier qual,
+ void *base, size_t size, size_t ith,
+ unsigned int flags) {
+ unsigned long buffer, adj;
+
+ /*
+ * Adjust the buffer address and size to meet alignment
+ * constraints:
+ * - buffer is double-word aligned
+ * - size is multiple of record size
+ *
+ * We checked the size at the very beginning; we have enough
+ * space to do the adjustment.
+ */
+ buffer = (unsigned long)base;
+
+ adj = ALIGN(buffer, DS_ALIGNMENT) - buffer;
+ buffer += adj;
+ size -= adj;
+
+ trace->n = size / ds_cfg.sizeof_rec[qual];
+ trace->size = ds_cfg.sizeof_rec[qual];
+
+ size = (trace->n * trace->size);
+
+ trace->begin = (void *)buffer;
+ trace->top = trace->begin;
+ trace->end = (void *)(buffer + size);
+ /*
+ * The value for 'no threshold' is -1, which will set the
+ * threshold outside of the buffer, just like we want it.
+ */
+ ith *= ds_cfg.sizeof_rec[qual];
+ trace->ith = (void *)(buffer + size - ith);
+
+ trace->flags = flags;
+}
+
+
+static int ds_request(struct ds_tracer *tracer, struct ds_trace *trace,
+ enum ds_qualifier qual, struct task_struct *task,
+ int cpu, void *base, size_t size, size_t th)
+{
+ struct ds_context *context;
+ int error;
+ size_t req_size;
+
+ error = -EOPNOTSUPP;
+ if (!ds_cfg.sizeof_rec[qual])
+ goto out;
+
+ error = -EINVAL;
+ if (!base)
+ goto out;
+
+ req_size = ds_cfg.sizeof_rec[qual];
+ /* We might need space for alignment adjustments. */
+ if (!IS_ALIGNED((unsigned long)base, DS_ALIGNMENT))
+ req_size += DS_ALIGNMENT;
+
+ error = -EINVAL;
+ if (size < req_size)
+ goto out;
+
+ if (th != (size_t)-1) {
+ th *= ds_cfg.sizeof_rec[qual];
+
+ error = -EINVAL;
+ if (size <= th)
+ goto out;
+ }
+
+ tracer->buffer = base;
+ tracer->size = size;
+
+ error = -ENOMEM;
+ context = ds_get_context(task, cpu);
+ if (!context)
+ goto out;
+ tracer->context = context;
+
+ /*
+ * Defer any tracer-specific initialization work for the context until
+ * context ownership has been clarified.
+ */
+
+ error = 0;
+ out:
+ return error;
+}
+
+static struct bts_tracer *ds_request_bts(struct task_struct *task, int cpu,
+ void *base, size_t size,
+ bts_ovfl_callback_t ovfl, size_t th,
+ unsigned int flags)
+{
+ struct bts_tracer *tracer;
+ int error;
+
+ /* Buffer overflow notification is not yet implemented. */
+ error = -EOPNOTSUPP;
+ if (ovfl)
+ goto out;
+
+ error = get_tracer(task);
+ if (error < 0)
+ goto out;
+
+ error = -ENOMEM;
+ tracer = kzalloc(sizeof(*tracer), GFP_KERNEL);
+ if (!tracer)
+ goto out_put_tracer;
+ tracer->ovfl = ovfl;
+
+ /* Do some more error checking and acquire a tracing context. */
+ error = ds_request(&tracer->ds, &tracer->trace.ds,
+ ds_bts, task, cpu, base, size, th);
+ if (error < 0)
+ goto out_tracer;
+
+ /* Claim the bts part of the tracing context we acquired above. */
+ spin_lock_irq(&ds_lock);
+
+ error = -EPERM;
+ if (tracer->ds.context->bts_master)
+ goto out_unlock;
+ tracer->ds.context->bts_master = tracer;
+
+ spin_unlock_irq(&ds_lock);
+
+ /*
+ * Now that we own the bts part of the context, let's complete the
+ * initialization for that part.
+ */
+ ds_init_ds_trace(&tracer->trace.ds, ds_bts, base, size, th, flags);
+ ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_bts);
+ ds_install_ds_area(tracer->ds.context);
+
+ tracer->trace.read = bts_read;
+ tracer->trace.write = bts_write;
+
+ /* Start tracing. */
+ ds_resume_bts(tracer);
+
+ return tracer;
+
+ out_unlock:
+ spin_unlock_irq(&ds_lock);
+ ds_put_context(tracer->ds.context);
+ out_tracer:
+ kfree(tracer);
+ out_put_tracer:
+ put_tracer(task);
+ out:
+ return ERR_PTR(error);
+}
+
+struct bts_tracer *ds_request_bts_task(struct task_struct *task,
+ void *base, size_t size,
+ bts_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags)
+{
+ return ds_request_bts(task, 0, base, size, ovfl, th, flags);
+}
+
+struct bts_tracer *ds_request_bts_cpu(int cpu, void *base, size_t size,
+ bts_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags)
+{
+ return ds_request_bts(NULL, cpu, base, size, ovfl, th, flags);
+}
+
+static struct pebs_tracer *ds_request_pebs(struct task_struct *task, int cpu,
+ void *base, size_t size,
+ pebs_ovfl_callback_t ovfl, size_t th,
+ unsigned int flags)
+{
+ struct pebs_tracer *tracer;
+ int error;
+
+ /* Buffer overflow notification is not yet implemented. */
+ error = -EOPNOTSUPP;
+ if (ovfl)
+ goto out;
+
+ error = get_tracer(task);
+ if (error < 0)
+ goto out;
+
+ error = -ENOMEM;
+ tracer = kzalloc(sizeof(*tracer), GFP_KERNEL);
+ if (!tracer)
+ goto out_put_tracer;
+ tracer->ovfl = ovfl;
+
+ /* Do some more error checking and acquire a tracing context. */
+ error = ds_request(&tracer->ds, &tracer->trace.ds,
+ ds_pebs, task, cpu, base, size, th);
+ if (error < 0)
+ goto out_tracer;
+
+ /* Claim the pebs part of the tracing context we acquired above. */
+ spin_lock_irq(&ds_lock);
+
+ error = -EPERM;
+ if (tracer->ds.context->pebs_master)
+ goto out_unlock;
+ tracer->ds.context->pebs_master = tracer;
+
+ spin_unlock_irq(&ds_lock);
+
+ /*
+ * Now that we own the pebs part of the context, let's complete the
+ * initialization for that part.
+ */
+ ds_init_ds_trace(&tracer->trace.ds, ds_pebs, base, size, th, flags);
+ ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_pebs);
+ ds_install_ds_area(tracer->ds.context);
+
+ /* Start tracing. */
+ ds_resume_pebs(tracer);
+
+ return tracer;
+
+ out_unlock:
+ spin_unlock_irq(&ds_lock);
+ ds_put_context(tracer->ds.context);
+ out_tracer:
+ kfree(tracer);
+ out_put_tracer:
+ put_tracer(task);
+ out:
+ return ERR_PTR(error);
+}
+
+struct pebs_tracer *ds_request_pebs_task(struct task_struct *task,
+ void *base, size_t size,
+ pebs_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags)
+{
+ return ds_request_pebs(task, 0, base, size, ovfl, th, flags);
+}
+
+struct pebs_tracer *ds_request_pebs_cpu(int cpu, void *base, size_t size,
+ pebs_ovfl_callback_t ovfl,
+ size_t th, unsigned int flags)
+{
+ return ds_request_pebs(NULL, cpu, base, size, ovfl, th, flags);
+}
+
+static void ds_free_bts(struct bts_tracer *tracer)
+{
+ struct task_struct *task;
+
+ task = tracer->ds.context->task;
+
+ WARN_ON_ONCE(tracer->ds.context->bts_master != tracer);
+ tracer->ds.context->bts_master = NULL;
+
+ /* Make sure tracing stopped and the tracer is not in use. */
+ if (task && (task != current))
+ wait_task_context_switch(task);
+
+ ds_put_context(tracer->ds.context);
+ put_tracer(task);
+
+ kfree(tracer);
+}
+
+void ds_release_bts(struct bts_tracer *tracer)
+{
+ might_sleep();
+
+ if (!tracer)
+ return;
+
+ ds_suspend_bts(tracer);
+ ds_free_bts(tracer);
+}
+
+int ds_release_bts_noirq(struct bts_tracer *tracer)
+{
+ struct task_struct *task;
+ unsigned long irq;
+ int error;
+
+ if (!tracer)
+ return 0;
+
+ task = tracer->ds.context->task;
+
+ local_irq_save(irq);
+
+ error = -EPERM;
+ if (!task &&
+ (tracer->ds.context->cpu != smp_processor_id()))
+ goto out;
+
+ error = -EPERM;
+ if (task && (task != current))
+ goto out;
+
+ ds_suspend_bts_noirq(tracer);
+ ds_free_bts(tracer);
+
+ error = 0;
+ out:
+ local_irq_restore(irq);
+ return error;
+}
+
+static void update_task_debugctlmsr(struct task_struct *task,
+ unsigned long debugctlmsr)
+{
+ task->thread.debugctlmsr = debugctlmsr;
+
+ get_cpu();
+ if (task == current)
+ update_debugctlmsr(debugctlmsr);
+ put_cpu();
+}
+
+void ds_suspend_bts(struct bts_tracer *tracer)
+{
+ struct task_struct *task;
+ unsigned long debugctlmsr;
+ int cpu;
+
+ if (!tracer)
+ return;
+
+ tracer->flags = 0;
+
+ task = tracer->ds.context->task;
+ cpu = tracer->ds.context->cpu;
+
+ WARN_ON(!task && irqs_disabled());
+
+ debugctlmsr = (task ?
+ task->thread.debugctlmsr :
+ get_debugctlmsr_on_cpu(cpu));
+ debugctlmsr &= ~BTS_CONTROL;
+
+ if (task)
+ update_task_debugctlmsr(task, debugctlmsr);
+ else
+ update_debugctlmsr_on_cpu(cpu, debugctlmsr);
+}
+
+int ds_suspend_bts_noirq(struct bts_tracer *tracer)
+{
+ struct task_struct *task;
+ unsigned long debugctlmsr, irq;
+ int cpu, error = 0;
+
+ if (!tracer)
+ return 0;
+
+ tracer->flags = 0;
+
+ task = tracer->ds.context->task;
+ cpu = tracer->ds.context->cpu;
+
+ local_irq_save(irq);
+
+ error = -EPERM;
+ if (!task && (cpu != smp_processor_id()))
+ goto out;
+
+ debugctlmsr = (task ?
+ task->thread.debugctlmsr :
+ get_debugctlmsr());
+ debugctlmsr &= ~BTS_CONTROL;
+
+ if (task)
+ update_task_debugctlmsr(task, debugctlmsr);
+ else
+ update_debugctlmsr(debugctlmsr);
+
+ error = 0;
+ out:
+ local_irq_restore(irq);
+ return error;
+}
+
+static unsigned long ds_bts_control(struct bts_tracer *tracer)
+{
+ unsigned long control;
+
+ control = ds_cfg.ctl[dsf_bts];
+ if (!(tracer->trace.ds.flags & BTS_KERNEL))
+ control |= ds_cfg.ctl[dsf_bts_kernel];
+ if (!(tracer->trace.ds.flags & BTS_USER))
+ control |= ds_cfg.ctl[dsf_bts_user];
+
+ return control;
+}
+
+void ds_resume_bts(struct bts_tracer *tracer)
+{
+ struct task_struct *task;
+ unsigned long debugctlmsr;
+ int cpu;
+
+ if (!tracer)
+ return;
+
+ tracer->flags = tracer->trace.ds.flags;
+
+ task = tracer->ds.context->task;
+ cpu = tracer->ds.context->cpu;
+
+ WARN_ON(!task && irqs_disabled());
+
+ debugctlmsr = (task ?
+ task->thread.debugctlmsr :
+ get_debugctlmsr_on_cpu(cpu));
+ debugctlmsr |= ds_bts_control(tracer);
+
+ if (task)
+ update_task_debugctlmsr(task, debugctlmsr);
+ else
+ update_debugctlmsr_on_cpu(cpu, debugctlmsr);
+}
+
+int ds_resume_bts_noirq(struct bts_tracer *tracer)
+{
+ struct task_struct *task;
+ unsigned long debugctlmsr, irq;
+ int cpu, error = 0;
+
+ if (!tracer)
+ return 0;
+
+ tracer->flags = tracer->trace.ds.flags;
+
+ task = tracer->ds.context->task;
+ cpu = tracer->ds.context->cpu;
+
+ local_irq_save(irq);
+
+ error = -EPERM;
+ if (!task && (cpu != smp_processor_id()))
+ goto out;
+
+ debugctlmsr = (task ?
+ task->thread.debugctlmsr :
+ get_debugctlmsr());
+ debugctlmsr |= ds_bts_control(tracer);
+
+ if (task)
+ update_task_debugctlmsr(task, debugctlmsr);
+ else
+ update_debugctlmsr(debugctlmsr);
+
+ error = 0;
+ out:
+ local_irq_restore(irq);
+ return error;
+}
+
+static void ds_free_pebs(struct pebs_tracer *tracer)
+{
+ struct task_struct *task;
+
+ task = tracer->ds.context->task;
+
+ WARN_ON_ONCE(tracer->ds.context->pebs_master != tracer);
+ tracer->ds.context->pebs_master = NULL;
+
+ ds_put_context(tracer->ds.context);
+ put_tracer(task);
+
+ kfree(tracer);
+}
+
+void ds_release_pebs(struct pebs_tracer *tracer)
+{
+ might_sleep();
+
+ if (!tracer)
+ return;
+
+ ds_suspend_pebs(tracer);
+ ds_free_pebs(tracer);
+}
+
+int ds_release_pebs_noirq(struct pebs_tracer *tracer)
+{
+ struct task_struct *task;
+ unsigned long irq;
+ int error;
+
+ if (!tracer)
+ return 0;
+
+ task = tracer->ds.context->task;
+
+ local_irq_save(irq);
+
+ error = -EPERM;
+ if (!task &&
+ (tracer->ds.context->cpu != smp_processor_id()))
+ goto out;
+
+ error = -EPERM;
+ if (task && (task != current))
+ goto out;
+
+ ds_suspend_pebs_noirq(tracer);
+ ds_free_pebs(tracer);
+
+ error = 0;
+ out:
+ local_irq_restore(irq);
+ return error;
+}
+
+void ds_suspend_pebs(struct pebs_tracer *tracer)
+{
+
+}
+
+int ds_suspend_pebs_noirq(struct pebs_tracer *tracer)
+{
+ return 0;
+}
+
+void ds_resume_pebs(struct pebs_tracer *tracer)
+{
+
+}
+
+int ds_resume_pebs_noirq(struct pebs_tracer *tracer)
+{
+ return 0;
+}
+
+const struct bts_trace *ds_read_bts(struct bts_tracer *tracer)
+{
+ if (!tracer)
+ return NULL;
+
+ ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_bts);
+ return &tracer->trace;
+}
+
+const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer)
+{
+ if (!tracer)
+ return NULL;
+
+ ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_pebs);
+
+ tracer->trace.counters = ds_cfg.nr_counter_reset;
+ memcpy(tracer->trace.counter_reset,
+ tracer->ds.context->ds +
+ (NUM_DS_PTR_FIELDS * ds_cfg.sizeof_ptr_field),
+ ds_cfg.nr_counter_reset * PEBS_RESET_FIELD_SIZE);
+
+ return &tracer->trace;
+}
+
+int ds_reset_bts(struct bts_tracer *tracer)
+{
+ if (!tracer)
+ return -EINVAL;
+
+ tracer->trace.ds.top = tracer->trace.ds.begin;
+
+ ds_set(tracer->ds.context->ds, ds_bts, ds_index,
+ (unsigned long)tracer->trace.ds.top);
+
+ return 0;
+}
+
+int ds_reset_pebs(struct pebs_tracer *tracer)
+{
+ if (!tracer)
+ return -EINVAL;
+
+ tracer->trace.ds.top = tracer->trace.ds.begin;
+
+ ds_set(tracer->ds.context->ds, ds_pebs, ds_index,
+ (unsigned long)tracer->trace.ds.top);
+
+ return 0;
+}
+
+int ds_set_pebs_reset(struct pebs_tracer *tracer,
+ unsigned int counter, u64 value)
+{
+ if (!tracer)
+ return -EINVAL;
+
+ if (ds_cfg.nr_counter_reset < counter)
+ return -EINVAL;
+
+ *(u64 *)(tracer->ds.context->ds +
+ (NUM_DS_PTR_FIELDS * ds_cfg.sizeof_ptr_field) +
+ (counter * PEBS_RESET_FIELD_SIZE)) = value;
+
+ return 0;
+}
+
+static const struct ds_configuration ds_cfg_netburst = {
+ .name = "Netburst",
+ .ctl[dsf_bts] = (1 << 2) | (1 << 3),
+ .ctl[dsf_bts_kernel] = (1 << 5),
+ .ctl[dsf_bts_user] = (1 << 6),
+ .nr_counter_reset = 1,
+};
+static const struct ds_configuration ds_cfg_pentium_m = {
+ .name = "Pentium M",
+ .ctl[dsf_bts] = (1 << 6) | (1 << 7),
+ .nr_counter_reset = 1,
+};
+static const struct ds_configuration ds_cfg_core2_atom = {
+ .name = "Core 2/Atom",
+ .ctl[dsf_bts] = (1 << 6) | (1 << 7),
+ .ctl[dsf_bts_kernel] = (1 << 9),
+ .ctl[dsf_bts_user] = (1 << 10),
+ .nr_counter_reset = 1,
+};
+static const struct ds_configuration ds_cfg_core_i7 = {
+ .name = "Core i7",
+ .ctl[dsf_bts] = (1 << 6) | (1 << 7),
+ .ctl[dsf_bts_kernel] = (1 << 9),
+ .ctl[dsf_bts_user] = (1 << 10),
+ .nr_counter_reset = 4,
+};
+
+static void
+ds_configure(const struct ds_configuration *cfg,
+ struct cpuinfo_x86 *cpu)
+{
+ unsigned long nr_pebs_fields = 0;
+
+ printk(KERN_INFO "[ds] using %s configuration\n", cfg->name);
+
+#ifdef __i386__
+ nr_pebs_fields = 10;
+#else
+ nr_pebs_fields = 18;
+#endif
+
+ /*
+ * Starting with version 2, architectural performance
+ * monitoring supports a format specifier.
+ */
+ if ((cpuid_eax(0xa) & 0xff) > 1) {
+ unsigned long perf_capabilities, format;
+
+ rdmsrl(MSR_IA32_PERF_CAPABILITIES, perf_capabilities);
+
+ format = (perf_capabilities >> 8) & 0xf;
+
+ switch (format) {
+ case 0:
+ nr_pebs_fields = 18;
+ break;
+ case 1:
+ nr_pebs_fields = 22;
+ break;
+ default:
+ printk(KERN_INFO
+ "[ds] unknown PEBS format: %lu\n", format);
+ nr_pebs_fields = 0;
+ break;
+ }
+ }
+
+ memset(&ds_cfg, 0, sizeof(ds_cfg));
+ ds_cfg = *cfg;
+
+ ds_cfg.sizeof_ptr_field =
+ (cpu_has(cpu, X86_FEATURE_DTES64) ? 8 : 4);
+
+ ds_cfg.sizeof_rec[ds_bts] = ds_cfg.sizeof_ptr_field * 3;
+ ds_cfg.sizeof_rec[ds_pebs] = ds_cfg.sizeof_ptr_field * nr_pebs_fields;
+
+ if (!cpu_has(cpu, X86_FEATURE_BTS)) {
+ ds_cfg.sizeof_rec[ds_bts] = 0;
+ printk(KERN_INFO "[ds] bts not available\n");
+ }
+ if (!cpu_has(cpu, X86_FEATURE_PEBS)) {
+ ds_cfg.sizeof_rec[ds_pebs] = 0;
+ printk(KERN_INFO "[ds] pebs not available\n");
+ }
+
+ printk(KERN_INFO "[ds] sizes: address: %u bit, ",
+ 8 * ds_cfg.sizeof_ptr_field);
+ printk("bts/pebs record: %u/%u bytes\n",
+ ds_cfg.sizeof_rec[ds_bts], ds_cfg.sizeof_rec[ds_pebs]);
+
+ WARN_ON_ONCE(MAX_PEBS_COUNTERS < ds_cfg.nr_counter_reset);
+}
+
+void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
+{
+ /* Only configure the first cpu. Others are identical. */
+ if (ds_cfg.name)
+ return;
+
+ switch (c->x86) {
+ case 0x6:
+ switch (c->x86_model) {
+ case 0x9:
+ case 0xd: /* Pentium M */
+ ds_configure(&ds_cfg_pentium_m, c);
+ break;
+ case 0xf:
+ case 0x17: /* Core2 */
+ case 0x1c: /* Atom */
+ ds_configure(&ds_cfg_core2_atom, c);
+ break;
+ case 0x1a: /* Core i7 */
+ ds_configure(&ds_cfg_core_i7, c);
+ break;
+ default:
+ /* Sorry, don't know about them. */
+ break;
+ }
+ break;
+ case 0xf:
+ switch (c->x86_model) {
+ case 0x0:
+ case 0x1:
+ case 0x2: /* Netburst */
+ ds_configure(&ds_cfg_netburst, c);
+ break;
+ default:
+ /* Sorry, don't know about them. */
+ break;
+ }
+ break;
+ default:
+ /* Sorry, don't know about them. */
+ break;
+ }
+}
+
+static inline void ds_take_timestamp(struct ds_context *context,
+ enum bts_qualifier qualifier,
+ struct task_struct *task)
+{
+ struct bts_tracer *tracer = context->bts_master;
+ struct bts_struct ts;
+
+ /* Prevent compilers from reading the tracer pointer twice. */
+ barrier();
+
+ if (!tracer || !(tracer->flags & BTS_TIMESTAMPS))
+ return;
+
+ memset(&ts, 0, sizeof(ts));
+ ts.qualifier = qualifier;
+ ts.variant.event.clock = trace_clock_global();
+ ts.variant.event.pid = task->pid;
+
+ bts_write(tracer, &ts);
+}
+
+/*
+ * Change the DS configuration from tracing prev to tracing next.
+ */
+void ds_switch_to(struct task_struct *prev, struct task_struct *next)
+{
+ struct ds_context *prev_ctx = prev->thread.ds_ctx;
+ struct ds_context *next_ctx = next->thread.ds_ctx;
+ unsigned long debugctlmsr = next->thread.debugctlmsr;
+
+ /* Make sure all data is read before we start. */
+ barrier();
+
+ if (prev_ctx) {
+ update_debugctlmsr(0);
+
+ ds_take_timestamp(prev_ctx, bts_task_departs, prev);
+ }
+
+ if (next_ctx) {
+ ds_take_timestamp(next_ctx, bts_task_arrives, next);
+
+ wrmsrl(MSR_IA32_DS_AREA, (unsigned long)next_ctx->ds);
+ }
+
+ update_debugctlmsr(debugctlmsr);
+}
+
+static __init int ds_selftest(void)
+{
+ if (ds_cfg.sizeof_rec[ds_bts]) {
+ int error;
+
+ error = ds_selftest_bts();
+ if (error) {
+ WARN(1, "[ds] selftest failed. disabling bts.\n");
+ ds_cfg.sizeof_rec[ds_bts] = 0;
+ }
+ }
+
+ if (ds_cfg.sizeof_rec[ds_pebs]) {
+ int error;
+
+ error = ds_selftest_pebs();
+ if (error) {
+ WARN(1, "[ds] selftest failed. disabling pebs.\n");
+ ds_cfg.sizeof_rec[ds_pebs] = 0;
+ }
+ }
+
+ return 0;
+}
+device_initcall(ds_selftest);
diff --git a/trunk/arch/x86/kernel/ds_selftest.c b/trunk/arch/x86/kernel/ds_selftest.c
new file mode 100644
index 000000000000..6bc7c199ab99
--- /dev/null
+++ b/trunk/arch/x86/kernel/ds_selftest.c
@@ -0,0 +1,408 @@
+/*
+ * Debug Store support - selftest
+ *
+ *
+ * Copyright (C) 2009 Intel Corporation.
+ * Markus Metzger , 2009
+ */
+
+#include "ds_selftest.h"
+
+#include
+#include
+#include
+#include
+
+#include
+
+
+#define BUFFER_SIZE 521 /* Intentionally chose an odd size. */
+#define SMALL_BUFFER_SIZE 24 /* A single bts entry. */
+
+struct ds_selftest_bts_conf {
+ struct bts_tracer *tracer;
+ int error;
+ int (*suspend)(struct bts_tracer *);
+ int (*resume)(struct bts_tracer *);
+};
+
+static int ds_selftest_bts_consistency(const struct bts_trace *trace)
+{
+ int error = 0;
+
+ if (!trace) {
+ printk(KERN_CONT "failed to access trace...");
+ /* Bail out. Other tests are pointless. */
+ return -1;
+ }
+
+ if (!trace->read) {
+ printk(KERN_CONT "bts read not available...");
+ error = -1;
+ }
+
+ /* Do some sanity checks on the trace configuration. */
+ if (!trace->ds.n) {
+ printk(KERN_CONT "empty bts buffer...");
+ error = -1;
+ }
+ if (!trace->ds.size) {
+ printk(KERN_CONT "bad bts trace setup...");
+ error = -1;
+ }
+ if (trace->ds.end !=
+ (char *)trace->ds.begin + (trace->ds.n * trace->ds.size)) {
+ printk(KERN_CONT "bad bts buffer setup...");
+ error = -1;
+ }
+ /*
+ * We allow top in [begin; end], since its not clear when the
+ * overflow adjustment happens: after the increment or before the
+ * write.
+ */
+ if ((trace->ds.top < trace->ds.begin) ||
+ (trace->ds.end < trace->ds.top)) {
+ printk(KERN_CONT "bts top out of bounds...");
+ error = -1;
+ }
+
+ return error;
+}
+
+static int ds_selftest_bts_read(struct bts_tracer *tracer,
+ const struct bts_trace *trace,
+ const void *from, const void *to)
+{
+ const unsigned char *at;
+
+ /*
+ * Check a few things which do not belong to this test.
+ * They should be covered by other tests.
+ */
+ if (!trace)
+ return -1;
+
+ if (!trace->read)
+ return -1;
+
+ if (to < from)
+ return -1;
+
+ if (from < trace->ds.begin)
+ return -1;
+
+ if (trace->ds.end < to)
+ return -1;
+
+ if (!trace->ds.size)
+ return -1;
+
+ /* Now to the test itself. */
+ for (at = from; (void *)at < to; at += trace->ds.size) {
+ struct bts_struct bts;
+ unsigned long index;
+ int error;
+
+ if (((void *)at - trace->ds.begin) % trace->ds.size) {
+ printk(KERN_CONT
+ "read from non-integer index...");
+ return -1;
+ }
+ index = ((void *)at - trace->ds.begin) / trace->ds.size;
+
+ memset(&bts, 0, sizeof(bts));
+ error = trace->read(tracer, at, &bts);
+ if (error < 0) {
+ printk(KERN_CONT
+ "error reading bts trace at [%lu] (0x%p)...",
+ index, at);
+ return error;
+ }
+
+ switch (bts.qualifier) {
+ case BTS_BRANCH:
+ break;
+ default:
+ printk(KERN_CONT
+ "unexpected bts entry %llu at [%lu] (0x%p)...",
+ bts.qualifier, index, at);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void ds_selftest_bts_cpu(void *arg)
+{
+ struct ds_selftest_bts_conf *conf = arg;
+ const struct bts_trace *trace;
+ void *top;
+
+ if (IS_ERR(conf->tracer)) {
+ conf->error = PTR_ERR(conf->tracer);
+ conf->tracer = NULL;
+
+ printk(KERN_CONT
+ "initialization failed (err: %d)...", conf->error);
+ return;
+ }
+
+ /* We should meanwhile have enough trace. */
+ conf->error = conf->suspend(conf->tracer);
+ if (conf->error < 0)
+ return;
+
+ /* Let's see if we can access the trace. */
+ trace = ds_read_bts(conf->tracer);
+
+ conf->error = ds_selftest_bts_consistency(trace);
+ if (conf->error < 0)
+ return;
+
+ /* If everything went well, we should have a few trace entries. */
+ if (trace->ds.top == trace->ds.begin) {
+ /*
+ * It is possible but highly unlikely that we got a
+ * buffer overflow and end up at exactly the same
+ * position we started from.
+ * Let's issue a warning, but continue.
+ */
+ printk(KERN_CONT "no trace/overflow...");
+ }
+
+ /* Let's try to read the trace we collected. */
+ conf->error =
+ ds_selftest_bts_read(conf->tracer, trace,
+ trace->ds.begin, trace->ds.top);
+ if (conf->error < 0)
+ return;
+
+ /*
+ * Let's read the trace again.
+ * Since we suspended tracing, we should get the same result.
+ */
+ top = trace->ds.top;
+
+ trace = ds_read_bts(conf->tracer);
+ conf->error = ds_selftest_bts_consistency(trace);
+ if (conf->error < 0)
+ return;
+
+ if (top != trace->ds.top) {
+ printk(KERN_CONT "suspend not working...");
+ conf->error = -1;
+ return;
+ }
+
+ /* Let's collect some more trace - see if resume is working. */
+ conf->error = conf->resume(conf->tracer);
+ if (conf->error < 0)
+ return;
+
+ conf->error = conf->suspend(conf->tracer);
+ if (conf->error < 0)
+ return;
+
+ trace = ds_read_bts(conf->tracer);
+
+ conf->error = ds_selftest_bts_consistency(trace);
+ if (conf->error < 0)
+ return;
+
+ if (trace->ds.top == top) {
+ /*
+ * It is possible but highly unlikely that we got a
+ * buffer overflow and end up at exactly the same
+ * position we started from.
+ * Let's issue a warning and check the full trace.
+ */
+ printk(KERN_CONT
+ "no resume progress/overflow...");
+
+ conf->error =
+ ds_selftest_bts_read(conf->tracer, trace,
+ trace->ds.begin, trace->ds.end);
+ } else if (trace->ds.top < top) {
+ /*
+ * We had a buffer overflow - the entire buffer should
+ * contain trace records.
+ */
+ conf->error =
+ ds_selftest_bts_read(conf->tracer, trace,
+ trace->ds.begin, trace->ds.end);
+ } else {
+ /*
+ * It is quite likely that the buffer did not overflow.
+ * Let's just check the delta trace.
+ */
+ conf->error =
+ ds_selftest_bts_read(conf->tracer, trace, top,
+ trace->ds.top);
+ }
+ if (conf->error < 0)
+ return;
+
+ conf->error = 0;
+}
+
+static int ds_suspend_bts_wrap(struct bts_tracer *tracer)
+{
+ ds_suspend_bts(tracer);
+ return 0;
+}
+
+static int ds_resume_bts_wrap(struct bts_tracer *tracer)
+{
+ ds_resume_bts(tracer);
+ return 0;
+}
+
+static void ds_release_bts_noirq_wrap(void *tracer)
+{
+ (void)ds_release_bts_noirq(tracer);
+}
+
+static int ds_selftest_bts_bad_release_noirq(int cpu,
+ struct bts_tracer *tracer)
+{
+ int error = -EPERM;
+
+ /* Try to release the tracer on the wrong cpu. */
+ get_cpu();
+ if (cpu != smp_processor_id()) {
+ error = ds_release_bts_noirq(tracer);
+ if (error != -EPERM)
+ printk(KERN_CONT "release on wrong cpu...");
+ }
+ put_cpu();
+
+ return error ? 0 : -1;
+}
+
+static int ds_selftest_bts_bad_request_cpu(int cpu, void *buffer)
+{
+ struct bts_tracer *tracer;
+ int error;
+
+ /* Try to request cpu tracing while task tracing is active. */
+ tracer = ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE, NULL,
+ (size_t)-1, BTS_KERNEL);
+ error = PTR_ERR(tracer);
+ if (!IS_ERR(tracer)) {
+ ds_release_bts(tracer);
+ error = 0;
+ }
+
+ if (error != -EPERM)
+ printk(KERN_CONT "cpu/task tracing overlap...");
+
+ return error ? 0 : -1;
+}
+
+static int ds_selftest_bts_bad_request_task(void *buffer)
+{
+ struct bts_tracer *tracer;
+ int error;
+
+ /* Try to request cpu tracing while task tracing is active. */
+ tracer = ds_request_bts_task(current, buffer, BUFFER_SIZE, NULL,
+ (size_t)-1, BTS_KERNEL);
+ error = PTR_ERR(tracer);
+ if (!IS_ERR(tracer)) {
+ error = 0;
+ ds_release_bts(tracer);
+ }
+
+ if (error != -EPERM)
+ printk(KERN_CONT "task/cpu tracing overlap...");
+
+ return error ? 0 : -1;
+}
+
+int ds_selftest_bts(void)
+{
+ struct ds_selftest_bts_conf conf;
+ unsigned char buffer[BUFFER_SIZE], *small_buffer;
+ unsigned long irq;
+ int cpu;
+
+ printk(KERN_INFO "[ds] bts selftest...");
+ conf.error = 0;
+
+ small_buffer = (unsigned char *)ALIGN((unsigned long)buffer, 8) + 8;
+
+ get_online_cpus();
+ for_each_online_cpu(cpu) {
+ conf.suspend = ds_suspend_bts_wrap;
+ conf.resume = ds_resume_bts_wrap;
+ conf.tracer =
+ ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE,
+ NULL, (size_t)-1, BTS_KERNEL);
+ ds_selftest_bts_cpu(&conf);
+ if (conf.error >= 0)
+ conf.error = ds_selftest_bts_bad_request_task(buffer);
+ ds_release_bts(conf.tracer);
+ if (conf.error < 0)
+ goto out;
+
+ conf.suspend = ds_suspend_bts_noirq;
+ conf.resume = ds_resume_bts_noirq;
+ conf.tracer =
+ ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE,
+ NULL, (size_t)-1, BTS_KERNEL);
+ smp_call_function_single(cpu, ds_selftest_bts_cpu, &conf, 1);
+ if (conf.error >= 0) {
+ conf.error =
+ ds_selftest_bts_bad_release_noirq(cpu,
+ conf.tracer);
+ /* We must not release the tracer twice. */
+ if (conf.error < 0)
+ conf.tracer = NULL;
+ }
+ if (conf.error >= 0)
+ conf.error = ds_selftest_bts_bad_request_task(buffer);
+ smp_call_function_single(cpu, ds_release_bts_noirq_wrap,
+ conf.tracer, 1);
+ if (conf.error < 0)
+ goto out;
+ }
+
+ conf.suspend = ds_suspend_bts_wrap;
+ conf.resume = ds_resume_bts_wrap;
+ conf.tracer =
+ ds_request_bts_task(current, buffer, BUFFER_SIZE,
+ NULL, (size_t)-1, BTS_KERNEL);
+ ds_selftest_bts_cpu(&conf);
+ if (conf.error >= 0)
+ conf.error = ds_selftest_bts_bad_request_cpu(0, buffer);
+ ds_release_bts(conf.tracer);
+ if (conf.error < 0)
+ goto out;
+
+ conf.suspend = ds_suspend_bts_noirq;
+ conf.resume = ds_resume_bts_noirq;
+ conf.tracer =
+ ds_request_bts_task(current, small_buffer, SMALL_BUFFER_SIZE,
+ NULL, (size_t)-1, BTS_KERNEL);
+ local_irq_save(irq);
+ ds_selftest_bts_cpu(&conf);
+ if (conf.error >= 0)
+ conf.error = ds_selftest_bts_bad_request_cpu(0, buffer);
+ ds_release_bts_noirq(conf.tracer);
+ local_irq_restore(irq);
+ if (conf.error < 0)
+ goto out;
+
+ conf.error = 0;
+ out:
+ put_online_cpus();
+ printk(KERN_CONT "%s.\n", (conf.error ? "failed" : "passed"));
+
+ return conf.error;
+}
+
+int ds_selftest_pebs(void)
+{
+ return 0;
+}
diff --git a/trunk/arch/x86/kernel/ds_selftest.h b/trunk/arch/x86/kernel/ds_selftest.h
new file mode 100644
index 000000000000..2ba8745c6663
--- /dev/null
+++ b/trunk/arch/x86/kernel/ds_selftest.h
@@ -0,0 +1,15 @@
+/*
+ * Debug Store support - selftest
+ *
+ *
+ * Copyright (C) 2009 Intel Corporation.
+ * Markus Metzger , 2009
+ */
+
+#ifdef CONFIG_X86_DS_SELFTEST
+extern int ds_selftest_bts(void);
+extern int ds_selftest_pebs(void);
+#else
+static inline int ds_selftest_bts(void) { return 0; }
+static inline int ds_selftest_pebs(void) { return 0; }
+#endif
diff --git a/trunk/arch/x86/kernel/dumpstack.c b/trunk/arch/x86/kernel/dumpstack.c
index c89a386930b7..6d817554780a 100644
--- a/trunk/arch/x86/kernel/dumpstack.c
+++ b/trunk/arch/x86/kernel/dumpstack.c
@@ -224,6 +224,11 @@ unsigned __kprobes long oops_begin(void)
int cpu;
unsigned long flags;
+ /* notify the hw-branch tracer so it may disable tracing and
+ add the last trace to the trace buffer -
+ the earlier this happens, the more useful the trace. */
+ trace_hw_branch_oops();
+
oops_enter();
/* racy, but better than risking deadlock. */
diff --git a/trunk/arch/x86/kernel/entry_32.S b/trunk/arch/x86/kernel/entry_32.S
index cd49141cf153..44a8e0dc6737 100644
--- a/trunk/arch/x86/kernel/entry_32.S
+++ b/trunk/arch/x86/kernel/entry_32.S
@@ -53,7 +53,6 @@
#include
#include
#include
-#include
/* Avoid __ASSEMBLER__'ifying just for this. */
#include
@@ -906,25 +905,7 @@ ENTRY(simd_coprocessor_error)
RING0_INT_FRAME
pushl $0
CFI_ADJUST_CFA_OFFSET 4
-#ifdef CONFIG_X86_INVD_BUG
- /* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */
-661: pushl $do_general_protection
-662:
-.section .altinstructions,"a"
- .balign 4
- .long 661b
- .long 663f
- .byte X86_FEATURE_XMM
- .byte 662b-661b
- .byte 664f-663f
-.previous
-.section .altinstr_replacement,"ax"
-663: pushl $do_simd_coprocessor_error
-664:
-.previous
-#else
pushl $do_simd_coprocessor_error
-#endif
CFI_ADJUST_CFA_OFFSET 4
jmp error_code
CFI_ENDPROC
diff --git a/trunk/arch/x86/kernel/hw_breakpoint.c b/trunk/arch/x86/kernel/hw_breakpoint.c
index a8f1b803d2fd..d6cc065f519f 100644
--- a/trunk/arch/x86/kernel/hw_breakpoint.c
+++ b/trunk/arch/x86/kernel/hw_breakpoint.c
@@ -188,17 +188,26 @@ static int get_hbp_len(u8 hbp_len)
return len_in_bytes;
}
+/*
+ * Check for virtual address in user space.
+ */
+int arch_check_va_in_userspace(unsigned long va, u8 hbp_len)
+{
+ unsigned int len;
+
+ len = get_hbp_len(hbp_len);
+
+ return (va <= TASK_SIZE - len);
+}
+
/*
* Check for virtual address in kernel space.
*/
-int arch_check_bp_in_kernelspace(struct perf_event *bp)
+static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
{
unsigned int len;
- unsigned long va;
- struct arch_hw_breakpoint *info = counter_arch_bp(bp);
- va = info->address;
- len = get_hbp_len(info->len);
+ len = get_hbp_len(hbp_len);
return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
}
@@ -291,7 +300,8 @@ static int arch_build_bp_info(struct perf_event *bp)
/*
* Validate the arch-specific HW Breakpoint register settings
*/
-int arch_validate_hwbkpt_settings(struct perf_event *bp)
+int arch_validate_hwbkpt_settings(struct perf_event *bp,
+ struct task_struct *tsk)
{
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
unsigned int align;
@@ -304,6 +314,16 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
ret = -EINVAL;
+ if (info->type == X86_BREAKPOINT_EXECUTE)
+ /*
+ * Ptrace-refactoring code
+ * For now, we'll allow instruction breakpoint only for user-space
+ * addresses
+ */
+ if ((!arch_check_va_in_userspace(info->address, info->len)) &&
+ info->len != X86_BREAKPOINT_EXECUTE)
+ return ret;
+
switch (info->len) {
case X86_BREAKPOINT_LEN_1:
align = 0;
@@ -330,6 +350,15 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
if (info->address & align)
return -EINVAL;
+ /* Check that the virtual address is in the proper range */
+ if (tsk) {
+ if (!arch_check_va_in_userspace(info->address, info->len))
+ return -EFAULT;
+ } else {
+ if (!arch_check_va_in_kernelspace(info->address, info->len))
+ return -EFAULT;
+ }
+
return 0;
}
diff --git a/trunk/arch/x86/kernel/i387.c b/trunk/arch/x86/kernel/i387.c
index 86cef6b32253..54c31c285488 100644
--- a/trunk/arch/x86/kernel/i387.c
+++ b/trunk/arch/x86/kernel/i387.c
@@ -102,62 +102,65 @@ void __cpuinit fpu_init(void)
mxcsr_feature_mask_init();
/* clean state in init */
- current_thread_info()->status = 0;
+ if (cpu_has_xsave)
+ current_thread_info()->status = TS_XSAVE;
+ else
+ current_thread_info()->status = 0;
clear_used_math();
}
#endif /* CONFIG_X86_64 */
-static void fpu_finit(struct fpu *fpu)
+/*
+ * The _current_ task is using the FPU for the first time
+ * so initialize it and set the mxcsr to its default
+ * value at reset if we support XMM instructions and then
+ * remeber the current task has used the FPU.
+ */
+int init_fpu(struct task_struct *tsk)
{
+ if (tsk_used_math(tsk)) {
+ if (HAVE_HWFP && tsk == current)
+ unlazy_fpu(tsk);
+ return 0;
+ }
+
+ /*
+ * Memory allocation at the first usage of the FPU and other state.
+ */
+ if (!tsk->thread.xstate) {
+ tsk->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
+ GFP_KERNEL);
+ if (!tsk->thread.xstate)
+ return -ENOMEM;
+ }
+
#ifdef CONFIG_X86_32
if (!HAVE_HWFP) {
- finit_soft_fpu(&fpu->state->soft);
- return;
+ memset(tsk->thread.xstate, 0, xstate_size);
+ finit_task(tsk);
+ set_stopped_child_used_math(tsk);
+ return 0;
}
#endif
if (cpu_has_fxsr) {
- struct i387_fxsave_struct *fx = &fpu->state->fxsave;
+ struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
memset(fx, 0, xstate_size);
fx->cwd = 0x37f;
if (cpu_has_xmm)
fx->mxcsr = MXCSR_DEFAULT;
} else {
- struct i387_fsave_struct *fp = &fpu->state->fsave;
+ struct i387_fsave_struct *fp = &tsk->thread.xstate->fsave;
memset(fp, 0, xstate_size);
fp->cwd = 0xffff037fu;
fp->swd = 0xffff0000u;
fp->twd = 0xffffffffu;
fp->fos = 0xffff0000u;
}
-}
-
-/*
- * The _current_ task is using the FPU for the first time
- * so initialize it and set the mxcsr to its default
- * value at reset if we support XMM instructions and then
- * remeber the current task has used the FPU.
- */
-int init_fpu(struct task_struct *tsk)
-{
- int ret;
-
- if (tsk_used_math(tsk)) {
- if (HAVE_HWFP && tsk == current)
- unlazy_fpu(tsk);
- return 0;
- }
-
/*
- * Memory allocation at the first usage of the FPU and other state.
+ * Only the device not available exception or ptrace can call init_fpu.
*/
- ret = fpu_alloc(&tsk->thread.fpu);
- if (ret)
- return ret;
-
- fpu_finit(&tsk->thread.fpu);
-
set_stopped_child_used_math(tsk);
return 0;
}
@@ -191,7 +194,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset,
return ret;
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpu.state->fxsave, 0, -1);
+ &target->thread.xstate->fxsave, 0, -1);
}
int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
@@ -208,19 +211,19 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
return ret;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpu.state->fxsave, 0, -1);
+ &target->thread.xstate->fxsave, 0, -1);
/*
* mxcsr reserved bits must be masked to zero for security reasons.
*/
- target->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask;
+ target->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask;
/*
* update the header bits in the xsave header, indicating the
* presence of FP and SSE state.
*/
if (cpu_has_xsave)
- target->thread.fpu.state->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;
+ target->thread.xstate->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;
return ret;
}
@@ -243,14 +246,14 @@ int xstateregs_get(struct task_struct *target, const struct user_regset *regset,
* memory layout in the thread struct, so that we can copy the entire
* xstateregs to the user using one user_regset_copyout().
*/
- memcpy(&target->thread.fpu.state->fxsave.sw_reserved,
+ memcpy(&target->thread.xstate->fxsave.sw_reserved,
xstate_fx_sw_bytes, sizeof(xstate_fx_sw_bytes));
/*
* Copy the xstate memory layout.
*/
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpu.state->xsave, 0, -1);
+ &target->thread.xstate->xsave, 0, -1);
return ret;
}
@@ -269,14 +272,14 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
return ret;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpu.state->xsave, 0, -1);
+ &target->thread.xstate->xsave, 0, -1);
/*
* mxcsr reserved bits must be masked to zero for security reasons.
*/
- target->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask;
+ target->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask;
- xsave_hdr = &target->thread.fpu.state->xsave.xsave_hdr;
+ xsave_hdr = &target->thread.xstate->xsave.xsave_hdr;
xsave_hdr->xstate_bv &= pcntxt_mask;
/*
@@ -362,7 +365,7 @@ static inline u32 twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
static void
convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)
{
- struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state->fxsave;
+ struct i387_fxsave_struct *fxsave = &tsk->thread.xstate->fxsave;
struct _fpreg *to = (struct _fpreg *) &env->st_space[0];
struct _fpxreg *from = (struct _fpxreg *) &fxsave->st_space[0];
int i;
@@ -402,7 +405,7 @@ static void convert_to_fxsr(struct task_struct *tsk,
const struct user_i387_ia32_struct *env)
{
- struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state->fxsave;
+ struct i387_fxsave_struct *fxsave = &tsk->thread.xstate->fxsave;
struct _fpreg *from = (struct _fpreg *) &env->st_space[0];
struct _fpxreg *to = (struct _fpxreg *) &fxsave->st_space[0];
int i;
@@ -442,7 +445,7 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset,
if (!cpu_has_fxsr) {
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpu.state->fsave, 0,
+ &target->thread.xstate->fsave, 0,
-1);
}
@@ -472,7 +475,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
if (!cpu_has_fxsr) {
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &target->thread.fpu.state->fsave, 0, -1);
+ &target->thread.xstate->fsave, 0, -1);
}
if (pos > 0 || count < sizeof(env))
@@ -487,7 +490,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
* presence of FP.
*/
if (cpu_has_xsave)
- target->thread.fpu.state->xsave.xsave_hdr.xstate_bv |= XSTATE_FP;
+ target->thread.xstate->xsave.xsave_hdr.xstate_bv |= XSTATE_FP;
return ret;
}
@@ -498,7 +501,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf)
{
struct task_struct *tsk = current;
- struct i387_fsave_struct *fp = &tsk->thread.fpu.state->fsave;
+ struct i387_fsave_struct *fp = &tsk->thread.xstate->fsave;
fp->status = fp->swd;
if (__copy_to_user(buf, fp, sizeof(struct i387_fsave_struct)))
@@ -509,7 +512,7 @@ static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf)
static int save_i387_fxsave(struct _fpstate_ia32 __user *buf)
{
struct task_struct *tsk = current;
- struct i387_fxsave_struct *fx = &tsk->thread.fpu.state->fxsave;
+ struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
struct user_i387_ia32_struct env;
int err = 0;
@@ -544,7 +547,7 @@ static int save_i387_xsave(void __user *buf)
* header as well as change any contents in the memory layout.
* xrestore as part of sigreturn will capture all the changes.
*/
- tsk->thread.fpu.state->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;
+ tsk->thread.xstate->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;
if (save_i387_fxsave(fx) < 0)
return -1;
@@ -596,7 +599,7 @@ static inline int restore_i387_fsave(struct _fpstate_ia32 __user *buf)
{
struct task_struct *tsk = current;
- return __copy_from_user(&tsk->thread.fpu.state->fsave, buf,
+ return __copy_from_user(&tsk->thread.xstate->fsave, buf,
sizeof(struct i387_fsave_struct));
}
@@ -607,10 +610,10 @@ static int restore_i387_fxsave(struct _fpstate_ia32 __user *buf,
struct user_i387_ia32_struct env;
int err;
- err = __copy_from_user(&tsk->thread.fpu.state->fxsave, &buf->_fxsr_env[0],
+ err = __copy_from_user(&tsk->thread.xstate->fxsave, &buf->_fxsr_env[0],
size);
/* mxcsr reserved bits must be masked to zero for security reasons */
- tsk->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask;
+ tsk->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask;
if (err || __copy_from_user(&env, buf, sizeof(env)))
return 1;
convert_to_fxsr(tsk, &env);
@@ -626,7 +629,7 @@ static int restore_i387_xsave(void __user *buf)
struct i387_fxsave_struct __user *fx =
(struct i387_fxsave_struct __user *) &fx_user->_fxsr_env[0];
struct xsave_hdr_struct *xsave_hdr =
- ¤t->thread.fpu.state->xsave.xsave_hdr;
+ ¤t->thread.xstate->xsave.xsave_hdr;
u64 mask;
int err;
diff --git a/trunk/arch/x86/kernel/i8253.c b/trunk/arch/x86/kernel/i8253.c
index 2dfd31597443..23c167925a5c 100644
--- a/trunk/arch/x86/kernel/i8253.c
+++ b/trunk/arch/x86/kernel/i8253.c
@@ -16,7 +16,7 @@
#include
#include
-DEFINE_RAW_SPINLOCK(i8253_lock);
+DEFINE_SPINLOCK(i8253_lock);
EXPORT_SYMBOL(i8253_lock);
/*
@@ -33,7 +33,7 @@ struct clock_event_device *global_clock_event;
static void init_pit_timer(enum clock_event_mode mode,
struct clock_event_device *evt)
{
- raw_spin_lock(&i8253_lock);
+ spin_lock(&i8253_lock);
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
@@ -62,7 +62,7 @@ static void init_pit_timer(enum clock_event_mode mode,
/* Nothing to do here */
break;
}
- raw_spin_unlock(&i8253_lock);
+ spin_unlock(&i8253_lock);
}
/*
@@ -72,10 +72,10 @@ static void init_pit_timer(enum clock_event_mode mode,
*/
static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
{
- raw_spin_lock(&i8253_lock);
+ spin_lock(&i8253_lock);
outb_pit(delta & 0xff , PIT_CH0); /* LSB */
outb_pit(delta >> 8 , PIT_CH0); /* MSB */
- raw_spin_unlock(&i8253_lock);
+ spin_unlock(&i8253_lock);
return 0;
}
@@ -130,7 +130,7 @@ static cycle_t pit_read(struct clocksource *cs)
int count;
u32 jifs;
- raw_spin_lock_irqsave(&i8253_lock, flags);
+ spin_lock_irqsave(&i8253_lock, flags);
/*
* Although our caller may have the read side of xtime_lock,
* this is now a seqlock, and we are cheating in this routine
@@ -176,7 +176,7 @@ static cycle_t pit_read(struct clocksource *cs)
old_count = count;
old_jifs = jifs;
- raw_spin_unlock_irqrestore(&i8253_lock, flags);
+ spin_unlock_irqrestore(&i8253_lock, flags);
count = (LATCH - 1) - count;
diff --git a/trunk/arch/x86/kernel/irqinit.c b/trunk/arch/x86/kernel/irqinit.c
index 990ae7cfc578..0ed2d300cd46 100644
--- a/trunk/arch/x86/kernel/irqinit.c
+++ b/trunk/arch/x86/kernel/irqinit.c
@@ -60,7 +60,7 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id)
outb(0, 0xF0);
if (ignore_fpu_irq || !boot_cpu_data.hard_math)
return IRQ_NONE;
- math_error(get_irq_regs(), 0, 16);
+ math_error((void __user *)get_irq_regs()->ip);
return IRQ_HANDLED;
}
diff --git a/trunk/arch/x86/kernel/kprobes.c b/trunk/arch/x86/kernel/kprobes.c
index 345a4b1fe144..b43bbaebe2c0 100644
--- a/trunk/arch/x86/kernel/kprobes.c
+++ b/trunk/arch/x86/kernel/kprobes.c
@@ -422,22 +422,14 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
static void __kprobes clear_btf(void)
{
- if (test_thread_flag(TIF_BLOCKSTEP)) {
- unsigned long debugctl = get_debugctlmsr();
-
- debugctl &= ~DEBUGCTLMSR_BTF;
- update_debugctlmsr(debugctl);
- }
+ if (test_thread_flag(TIF_DEBUGCTLMSR))
+ update_debugctlmsr(0);
}
static void __kprobes restore_btf(void)
{
- if (test_thread_flag(TIF_BLOCKSTEP)) {
- unsigned long debugctl = get_debugctlmsr();
-
- debugctl |= DEBUGCTLMSR_BTF;
- update_debugctlmsr(debugctl);
- }
+ if (test_thread_flag(TIF_DEBUGCTLMSR))
+ update_debugctlmsr(current->thread.debugctlmsr);
}
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
@@ -542,6 +534,20 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
struct kprobe_ctlblk *kcb;
addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
+ if (*addr != BREAKPOINT_INSTRUCTION) {
+ /*
+ * The breakpoint instruction was removed right
+ * after we hit it. Another cpu has removed
+ * either a probepoint or a debugger breakpoint
+ * at this address. In either case, no further
+ * handling of this interrupt is appropriate.
+ * Back up over the (now missing) int3 and run
+ * the original instruction.
+ */
+ regs->ip = (unsigned long)addr;
+ return 1;
+ }
+
/*
* We don't want to be preempted for the entire
* duration of kprobe processing. We conditionally
@@ -573,19 +579,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
setup_singlestep(p, regs, kcb, 0);
return 1;
}
- } else if (*addr != BREAKPOINT_INSTRUCTION) {
- /*
- * The breakpoint instruction was removed right
- * after we hit it. Another cpu has removed
- * either a probepoint or a debugger breakpoint
- * at this address. In either case, no further
- * handling of this interrupt is appropriate.
- * Back up over the (now missing) int3 and run
- * the original instruction.
- */
- regs->ip = (unsigned long)addr;
- preempt_enable_no_resched();
- return 1;
} else if (kprobe_running()) {
p = __get_cpu_var(current_kprobe);
if (p->break_handler && p->break_handler(p, regs)) {
diff --git a/trunk/arch/x86/kernel/microcode_core.c b/trunk/arch/x86/kernel/microcode_core.c
index 2cd8c544e41a..cceb5bc3c3c2 100644
--- a/trunk/arch/x86/kernel/microcode_core.c
+++ b/trunk/arch/x86/kernel/microcode_core.c
@@ -201,9 +201,9 @@ static int do_microcode_update(const void __user *buf, size_t size)
return error;
}
-static int microcode_open(struct inode *inode, struct file *file)
+static int microcode_open(struct inode *unused1, struct file *unused2)
{
- return capable(CAP_SYS_RAWIO) ? nonseekable_open(inode, file) : -EPERM;
+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
}
static ssize_t microcode_write(struct file *file, const char __user *buf,
diff --git a/trunk/arch/x86/kernel/microcode_intel.c b/trunk/arch/x86/kernel/microcode_intel.c
index 356170262a93..85a343e28937 100644
--- a/trunk/arch/x86/kernel/microcode_intel.c
+++ b/trunk/arch/x86/kernel/microcode_intel.c
@@ -343,11 +343,10 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
int (*get_ucode_data)(void *, const void *, size_t))
{
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
- u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL;
+ u8 *ucode_ptr = data, *new_mc = NULL, *mc;
int new_rev = uci->cpu_sig.rev;
unsigned int leftover = size;
enum ucode_state state = UCODE_OK;
- unsigned int curr_mc_size = 0;
while (leftover) {
struct microcode_header_intel mc_header;
@@ -362,15 +361,9 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
break;
}
- /* For performance reasons, reuse mc area when possible */
- if (!mc || mc_size > curr_mc_size) {
- if (mc)
- vfree(mc);
- mc = vmalloc(mc_size);
- if (!mc)
- break;
- curr_mc_size = mc_size;
- }
+ mc = vmalloc(mc_size);
+ if (!mc)
+ break;
if (get_ucode_data(mc, ucode_ptr, mc_size) ||
microcode_sanity_check(mc) < 0) {
@@ -383,16 +376,13 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
vfree(new_mc);
new_rev = mc_header.rev;
new_mc = mc;
- mc = NULL; /* trigger new vmalloc */
- }
+ } else
+ vfree(mc);
ucode_ptr += mc_size;
leftover -= mc_size;
}
- if (mc)
- vfree(mc);
-
if (leftover) {
if (new_mc)
vfree(new_mc);
diff --git a/trunk/arch/x86/kernel/mpparse.c b/trunk/arch/x86/kernel/mpparse.c
index 5ae5d2426edf..e81030f71a8f 100644
--- a/trunk/arch/x86/kernel/mpparse.c
+++ b/trunk/arch/x86/kernel/mpparse.c
@@ -115,6 +115,21 @@ static void __init MP_bus_info(struct mpc_bus *m)
printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
}
+static int bad_ioapic(unsigned long address)
+{
+ if (nr_ioapics >= MAX_IO_APICS) {
+ printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
+ "(found %d)\n", MAX_IO_APICS, nr_ioapics);
+ panic("Recompile kernel with bigger MAX_IO_APICS!\n");
+ }
+ if (!address) {
+ printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
+ " found in table, skipping!\n");
+ return 1;
+ }
+ return 0;
+}
+
static void __init MP_ioapic_info(struct mpc_ioapic *m)
{
if (!(m->flags & MPC_APIC_USABLE))
@@ -123,7 +138,15 @@ static void __init MP_ioapic_info(struct mpc_ioapic *m)
printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n",
m->apicid, m->apicver, m->apicaddr);
- mp_register_ioapic(m->apicid, m->apicaddr, gsi_end + 1);
+ if (bad_ioapic(m->apicaddr))
+ return;
+
+ mp_ioapics[nr_ioapics].apicaddr = m->apicaddr;
+ mp_ioapics[nr_ioapics].apicid = m->apicid;
+ mp_ioapics[nr_ioapics].type = m->type;
+ mp_ioapics[nr_ioapics].apicver = m->apicver;
+ mp_ioapics[nr_ioapics].flags = m->flags;
+ nr_ioapics++;
}
static void print_MP_intsrc_info(struct mpc_intsrc *m)
diff --git a/trunk/arch/x86/kernel/mrst.c b/trunk/arch/x86/kernel/mrst.c
index e796448f0eb5..0aad8670858e 100644
--- a/trunk/arch/x86/kernel/mrst.c
+++ b/trunk/arch/x86/kernel/mrst.c
@@ -237,9 +237,4 @@ void __init x86_mrst_early_setup(void)
x86_init.pci.fixup_irqs = x86_init_noop;
legacy_pic = &null_legacy_pic;
-
- /* Avoid searching for BIOS MP tables */
- x86_init.mpparse.find_smp_config = x86_init_noop;
- x86_init.mpparse.get_smp_config = x86_init_uint_noop;
-
}
diff --git a/trunk/arch/x86/kernel/process.c b/trunk/arch/x86/kernel/process.c
index e7e35219b32f..28ad9f4d8b94 100644
--- a/trunk/arch/x86/kernel/process.c
+++ b/trunk/arch/x86/kernel/process.c
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include
unsigned long idle_halt;
@@ -31,22 +32,26 @@ struct kmem_cache *task_xstate_cachep;
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
{
- int ret;
-
*dst = *src;
- if (fpu_allocated(&src->thread.fpu)) {
- memset(&dst->thread.fpu, 0, sizeof(dst->thread.fpu));
- ret = fpu_alloc(&dst->thread.fpu);
- if (ret)
- return ret;
- fpu_copy(&dst->thread.fpu, &src->thread.fpu);
+ if (src->thread.xstate) {
+ dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
+ GFP_KERNEL);
+ if (!dst->thread.xstate)
+ return -ENOMEM;
+ WARN_ON((unsigned long)dst->thread.xstate & 15);
+ memcpy(dst->thread.xstate, src->thread.xstate, xstate_size);
}
return 0;
}
void free_thread_xstate(struct task_struct *tsk)
{
- fpu_free(&tsk->thread.fpu);
+ if (tsk->thread.xstate) {
+ kmem_cache_free(task_xstate_cachep, tsk->thread.xstate);
+ tsk->thread.xstate = NULL;
+ }
+
+ WARN(tsk->thread.ds_ctx, "leaking DS context\n");
}
void free_thread_info(struct thread_info *ti)
@@ -193,16 +198,11 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
prev = &prev_p->thread;
next = &next_p->thread;
- if (test_tsk_thread_flag(prev_p, TIF_BLOCKSTEP) ^
- test_tsk_thread_flag(next_p, TIF_BLOCKSTEP)) {
- unsigned long debugctl = get_debugctlmsr();
-
- debugctl &= ~DEBUGCTLMSR_BTF;
- if (test_tsk_thread_flag(next_p, TIF_BLOCKSTEP))
- debugctl |= DEBUGCTLMSR_BTF;
-
- update_debugctlmsr(debugctl);
- }
+ if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) ||
+ test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR))
+ ds_switch_to(prev_p, next_p);
+ else if (next->debugctlmsr != prev->debugctlmsr)
+ update_debugctlmsr(next->debugctlmsr);
if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^
test_tsk_thread_flag(next_p, TIF_NOTSC)) {
@@ -546,13 +546,11 @@ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
* check OSVW bit for CPUs that are not affected
* by erratum #400
*/
- if (cpu_has(c, X86_FEATURE_OSVW)) {
- rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val);
- if (val >= 2) {
- rdmsrl(MSR_AMD64_OSVW_STATUS, val);
- if (!(val & BIT(1)))
- goto no_c1e_idle;
- }
+ rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val);
+ if (val >= 2) {
+ rdmsrl(MSR_AMD64_OSVW_STATUS, val);
+ if (!(val & BIT(1)))
+ goto no_c1e_idle;
}
return 1;
}
diff --git a/trunk/arch/x86/kernel/process_32.c b/trunk/arch/x86/kernel/process_32.c
index 8d128783af47..f6c62667e30c 100644
--- a/trunk/arch/x86/kernel/process_32.c
+++ b/trunk/arch/x86/kernel/process_32.c
@@ -55,6 +55,7 @@
#include
#include
#include
+#include
#include
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
@@ -237,6 +238,13 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
kfree(p->thread.io_bitmap_ptr);
p->thread.io_bitmap_max = 0;
}
+
+ clear_tsk_thread_flag(p, TIF_DS_AREA_MSR);
+ p->thread.ds_ctx = NULL;
+
+ clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR);
+ p->thread.debugctlmsr = 0;
+
return err;
}
@@ -309,7 +317,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
/* we're going to use this soon, after a few expensive things */
if (preload_fpu)
- prefetch(next->fpu.state);
+ prefetch(next->xstate);
/*
* Reload esp0.
diff --git a/trunk/arch/x86/kernel/process_64.c b/trunk/arch/x86/kernel/process_64.c
index 3c2422a99f1f..17cb3295cbf7 100644
--- a/trunk/arch/x86/kernel/process_64.c
+++ b/trunk/arch/x86/kernel/process_64.c
@@ -49,6 +49,7 @@
#include
#include
#include
+#include
#include
asmlinkage extern void ret_from_fork(void);
@@ -312,6 +313,13 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
if (err)
goto out;
}
+
+ clear_tsk_thread_flag(p, TIF_DS_AREA_MSR);
+ p->thread.ds_ctx = NULL;
+
+ clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR);
+ p->thread.debugctlmsr = 0;
+
err = 0;
out:
if (err && p->thread.io_bitmap_ptr) {
@@ -388,7 +396,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
/* we're going to use this soon, after a few expensive things */
if (preload_fpu)
- prefetch(next->fpu.state);
+ prefetch(next->xstate);
/*
* Reload esp0, LDT and the page table pointer:
diff --git a/trunk/arch/x86/kernel/ptrace.c b/trunk/arch/x86/kernel/ptrace.c
index 70c4872cd8aa..2e9b55027b7e 100644
--- a/trunk/arch/x86/kernel/ptrace.c
+++ b/trunk/arch/x86/kernel/ptrace.c
@@ -2,6 +2,9 @@
/*
* Pentium III FXSR, SSE support
* Gareth Hughes , May 2000
+ *
+ * BTS tracing
+ * Markus Metzger , Dec 2007
*/
#include
@@ -19,6 +22,7 @@
#include
#include
#include
+#include
#include
#include
@@ -32,6 +36,7 @@
#include
#include
#include
+#include
#include
#include "tls.h"
@@ -688,7 +693,7 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
struct perf_event_attr attr;
if (!t->ptrace_bps[nr]) {
- ptrace_breakpoint_init(&attr);
+ hw_breakpoint_init(&attr);
/*
* Put stub len and type to register (reserve) an inactive but
* correct bp
@@ -784,6 +789,342 @@ static int ioperm_get(struct task_struct *target,
0, IO_BITMAP_BYTES);
}
+#ifdef CONFIG_X86_PTRACE_BTS
+/*
+ * A branch trace store context.
+ *
+ * Contexts may only be installed by ptrace_bts_config() and only for
+ * ptraced tasks.
+ *
+ * Contexts are destroyed when the tracee is detached from the tracer.
+ * The actual destruction work requires interrupts enabled, so the
+ * work is deferred and will be scheduled during __ptrace_unlink().
+ *
+ * Contexts hold an additional task_struct reference on the traced
+ * task, as well as a reference on the tracer's mm.
+ *
+ * Ptrace already holds a task_struct for the duration of ptrace operations,
+ * but since destruction is deferred, it may be executed after both
+ * tracer and tracee exited.
+ */
+struct bts_context {
+ /* The branch trace handle. */
+ struct bts_tracer *tracer;
+
+ /* The buffer used to store the branch trace and its size. */
+ void *buffer;
+ unsigned int size;
+
+ /* The mm that paid for the above buffer. */
+ struct mm_struct *mm;
+
+ /* The task this context belongs to. */
+ struct task_struct *task;
+
+ /* The signal to send on a bts buffer overflow. */
+ unsigned int bts_ovfl_signal;
+
+ /* The work struct to destroy a context. */
+ struct work_struct work;
+};
+
+static int alloc_bts_buffer(struct bts_context *context, unsigned int size)
+{
+ void *buffer = NULL;
+ int err = -ENOMEM;
+
+ err = account_locked_memory(current->mm, current->signal->rlim, size);
+ if (err < 0)
+ return err;
+
+ buffer = kzalloc(size, GFP_KERNEL);
+ if (!buffer)
+ goto out_refund;
+
+ context->buffer = buffer;
+ context->size = size;
+ context->mm = get_task_mm(current);
+
+ return 0;
+
+ out_refund:
+ refund_locked_memory(current->mm, size);
+ return err;
+}
+
+static inline void free_bts_buffer(struct bts_context *context)
+{
+ if (!context->buffer)
+ return;
+
+ kfree(context->buffer);
+ context->buffer = NULL;
+
+ refund_locked_memory(context->mm, context->size);
+ context->size = 0;
+
+ mmput(context->mm);
+ context->mm = NULL;
+}
+
+static void free_bts_context_work(struct work_struct *w)
+{
+ struct bts_context *context;
+
+ context = container_of(w, struct bts_context, work);
+
+ ds_release_bts(context->tracer);
+ put_task_struct(context->task);
+ free_bts_buffer(context);
+ kfree(context);
+}
+
+static inline void free_bts_context(struct bts_context *context)
+{
+ INIT_WORK(&context->work, free_bts_context_work);
+ schedule_work(&context->work);
+}
+
+static inline struct bts_context *alloc_bts_context(struct task_struct *task)
+{
+ struct bts_context *context = kzalloc(sizeof(*context), GFP_KERNEL);
+ if (context) {
+ context->task = task;
+ task->bts = context;
+
+ get_task_struct(task);
+ }
+
+ return context;
+}
+
+static int ptrace_bts_read_record(struct task_struct *child, size_t index,
+ struct bts_struct __user *out)
+{
+ struct bts_context *context;
+ const struct bts_trace *trace;
+ struct bts_struct bts;
+ const unsigned char *at;
+ int error;
+
+ context = child->bts;
+ if (!context)
+ return -ESRCH;
+
+ trace = ds_read_bts(context->tracer);
+ if (!trace)
+ return -ESRCH;
+
+ at = trace->ds.top - ((index + 1) * trace->ds.size);
+ if ((void *)at < trace->ds.begin)
+ at += (trace->ds.n * trace->ds.size);
+
+ if (!trace->read)
+ return -EOPNOTSUPP;
+
+ error = trace->read(context->tracer, at, &bts);
+ if (error < 0)
+ return error;
+
+ if (copy_to_user(out, &bts, sizeof(bts)))
+ return -EFAULT;
+
+ return sizeof(bts);
+}
+
+static int ptrace_bts_drain(struct task_struct *child,
+ long size,
+ struct bts_struct __user *out)
+{
+ struct bts_context *context;
+ const struct bts_trace *trace;
+ const unsigned char *at;
+ int error, drained = 0;
+
+ context = child->bts;
+ if (!context)
+ return -ESRCH;
+
+ trace = ds_read_bts(context->tracer);
+ if (!trace)
+ return -ESRCH;
+
+ if (!trace->read)
+ return -EOPNOTSUPP;
+
+ if (size < (trace->ds.top - trace->ds.begin))
+ return -EIO;
+
+ for (at = trace->ds.begin; (void *)at < trace->ds.top;
+ out++, drained++, at += trace->ds.size) {
+ struct bts_struct bts;
+
+ error = trace->read(context->tracer, at, &bts);
+ if (error < 0)
+ return error;
+
+ if (copy_to_user(out, &bts, sizeof(bts)))
+ return -EFAULT;
+ }
+
+ memset(trace->ds.begin, 0, trace->ds.n * trace->ds.size);
+
+ error = ds_reset_bts(context->tracer);
+ if (error < 0)
+ return error;
+
+ return drained;
+}
+
+static int ptrace_bts_config(struct task_struct *child,
+ long cfg_size,
+ const struct ptrace_bts_config __user *ucfg)
+{
+ struct bts_context *context;
+ struct ptrace_bts_config cfg;
+ unsigned int flags = 0;
+
+ if (cfg_size < sizeof(cfg))
+ return -EIO;
+
+ if (copy_from_user(&cfg, ucfg, sizeof(cfg)))
+ return -EFAULT;
+
+ context = child->bts;
+ if (!context)
+ context = alloc_bts_context(child);
+ if (!context)
+ return -ENOMEM;
+
+ if (cfg.flags & PTRACE_BTS_O_SIGNAL) {
+ if (!cfg.signal)
+ return -EINVAL;
+
+ return -EOPNOTSUPP;
+ context->bts_ovfl_signal = cfg.signal;
+ }
+
+ ds_release_bts(context->tracer);
+ context->tracer = NULL;
+
+ if ((cfg.flags & PTRACE_BTS_O_ALLOC) && (cfg.size != context->size)) {
+ int err;
+
+ free_bts_buffer(context);
+ if (!cfg.size)
+ return 0;
+
+ err = alloc_bts_buffer(context, cfg.size);
+ if (err < 0)
+ return err;
+ }
+
+ if (cfg.flags & PTRACE_BTS_O_TRACE)
+ flags |= BTS_USER;
+
+ if (cfg.flags & PTRACE_BTS_O_SCHED)
+ flags |= BTS_TIMESTAMPS;
+
+ context->tracer =
+ ds_request_bts_task(child, context->buffer, context->size,
+ NULL, (size_t)-1, flags);
+ if (unlikely(IS_ERR(context->tracer))) {
+ int error = PTR_ERR(context->tracer);
+
+ free_bts_buffer(context);
+ context->tracer = NULL;
+ return error;
+ }
+
+ return sizeof(cfg);
+}
+
+static int ptrace_bts_status(struct task_struct *child,
+ long cfg_size,
+ struct ptrace_bts_config __user *ucfg)
+{
+ struct bts_context *context;
+ const struct bts_trace *trace;
+ struct ptrace_bts_config cfg;
+
+ context = child->bts;
+ if (!context)
+ return -ESRCH;
+
+ if (cfg_size < sizeof(cfg))
+ return -EIO;
+
+ trace = ds_read_bts(context->tracer);
+ if (!trace)
+ return -ESRCH;
+
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.size = trace->ds.end - trace->ds.begin;
+ cfg.signal = context->bts_ovfl_signal;
+ cfg.bts_size = sizeof(struct bts_struct);
+
+ if (cfg.signal)
+ cfg.flags |= PTRACE_BTS_O_SIGNAL;
+
+ if (trace->ds.flags & BTS_USER)
+ cfg.flags |= PTRACE_BTS_O_TRACE;
+
+ if (trace->ds.flags & BTS_TIMESTAMPS)
+ cfg.flags |= PTRACE_BTS_O_SCHED;
+
+ if (copy_to_user(ucfg, &cfg, sizeof(cfg)))
+ return -EFAULT;
+
+ return sizeof(cfg);
+}
+
+static int ptrace_bts_clear(struct task_struct *child)
+{
+ struct bts_context *context;
+ const struct bts_trace *trace;
+
+ context = child->bts;
+ if (!context)
+ return -ESRCH;
+
+ trace = ds_read_bts(context->tracer);
+ if (!trace)
+ return -ESRCH;
+
+ memset(trace->ds.begin, 0, trace->ds.n * trace->ds.size);
+
+ return ds_reset_bts(context->tracer);
+}
+
+static int ptrace_bts_size(struct task_struct *child)
+{
+ struct bts_context *context;
+ const struct bts_trace *trace;
+
+ context = child->bts;
+ if (!context)
+ return -ESRCH;
+
+ trace = ds_read_bts(context->tracer);
+ if (!trace)
+ return -ESRCH;
+
+ return (trace->ds.top - trace->ds.begin) / trace->ds.size;
+}
+
+/*
+ * Called from __ptrace_unlink() after the child has been moved back
+ * to its original parent.
+ */
+void ptrace_bts_untrace(struct task_struct *child)
+{
+ if (unlikely(child->bts)) {
+ free_bts_context(child->bts);
+ child->bts = NULL;
+ }
+}
+#endif /* CONFIG_X86_PTRACE_BTS */
+
/*
* Called by kernel/ptrace.c when detaching..
*
@@ -911,6 +1252,39 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
#endif
+ /*
+ * These bits need more cooking - not enabled yet:
+ */
+#ifdef CONFIG_X86_PTRACE_BTS
+ case PTRACE_BTS_CONFIG:
+ ret = ptrace_bts_config
+ (child, data, (struct ptrace_bts_config __user *)addr);
+ break;
+
+ case PTRACE_BTS_STATUS:
+ ret = ptrace_bts_status
+ (child, data, (struct ptrace_bts_config __user *)addr);
+ break;
+
+ case PTRACE_BTS_SIZE:
+ ret = ptrace_bts_size(child);
+ break;
+
+ case PTRACE_BTS_GET:
+ ret = ptrace_bts_read_record
+ (child, data, (struct bts_struct __user *) addr);
+ break;
+
+ case PTRACE_BTS_CLEAR:
+ ret = ptrace_bts_clear(child);
+ break;
+
+ case PTRACE_BTS_DRAIN:
+ ret = ptrace_bts_drain
+ (child, data, (struct bts_struct __user *) addr);
+ break;
+#endif /* CONFIG_X86_PTRACE_BTS */
+
default:
ret = ptrace_request(child, request, addr, data);
break;
@@ -1170,6 +1544,14 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
case PTRACE_GET_THREAD_AREA:
case PTRACE_SET_THREAD_AREA:
+#ifdef CONFIG_X86_PTRACE_BTS
+ case PTRACE_BTS_CONFIG:
+ case PTRACE_BTS_STATUS:
+ case PTRACE_BTS_SIZE:
+ case PTRACE_BTS_GET:
+ case PTRACE_BTS_CLEAR:
+ case PTRACE_BTS_DRAIN:
+#endif /* CONFIG_X86_PTRACE_BTS */
return arch_ptrace(child, request, addr, data);
default:
diff --git a/trunk/arch/x86/kernel/sfi.c b/trunk/arch/x86/kernel/sfi.c
index 7ded57896c0a..34e099382651 100644
--- a/trunk/arch/x86/kernel/sfi.c
+++ b/trunk/arch/x86/kernel/sfi.c
@@ -81,6 +81,7 @@ static int __init sfi_parse_cpus(struct sfi_table_header *table)
#endif /* CONFIG_X86_LOCAL_APIC */
#ifdef CONFIG_X86_IO_APIC
+static u32 gsi_base;
static int __init sfi_parse_ioapic(struct sfi_table_header *table)
{
@@ -93,7 +94,8 @@ static int __init sfi_parse_ioapic(struct sfi_table_header *table)
pentry = (struct sfi_apic_table_entry *)sb->pentry;
for (i = 0; i < num; i++) {
- mp_register_ioapic(i, pentry->phys_addr, gsi_end + 1);
+ mp_register_ioapic(i, pentry->phys_addr, gsi_base);
+ gsi_base += io_apic_get_redir_entries(i);
pentry++;
}
diff --git a/trunk/arch/x86/kernel/step.c b/trunk/arch/x86/kernel/step.c
index 58de45ee08b6..3149032ff107 100644
--- a/trunk/arch/x86/kernel/step.c
+++ b/trunk/arch/x86/kernel/step.c
@@ -157,6 +157,22 @@ static int enable_single_step(struct task_struct *child)
return 1;
}
+/*
+ * Install this value in MSR_IA32_DEBUGCTLMSR whenever child is running.
+ */
+static void write_debugctlmsr(struct task_struct *child, unsigned long val)
+{
+ if (child->thread.debugctlmsr == val)
+ return;
+
+ child->thread.debugctlmsr = val;
+
+ if (child != current)
+ return;
+
+ update_debugctlmsr(val);
+}
+
/*
* Enable single or block step.
*/
@@ -170,17 +186,15 @@ static void enable_step(struct task_struct *child, bool block)
* that uses user-mode single stepping itself.
*/
if (enable_single_step(child) && block) {
- unsigned long debugctl = get_debugctlmsr();
-
- debugctl |= DEBUGCTLMSR_BTF;
- update_debugctlmsr(debugctl);
- set_tsk_thread_flag(child, TIF_BLOCKSTEP);
- } else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) {
- unsigned long debugctl = get_debugctlmsr();
-
- debugctl &= ~DEBUGCTLMSR_BTF;
- update_debugctlmsr(debugctl);
- clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
+ set_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
+ write_debugctlmsr(child,
+ child->thread.debugctlmsr | DEBUGCTLMSR_BTF);
+ } else {
+ write_debugctlmsr(child,
+ child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF);
+
+ if (!child->thread.debugctlmsr)
+ clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
}
}
@@ -199,13 +213,11 @@ void user_disable_single_step(struct task_struct *child)
/*
* Make sure block stepping (BTF) is disabled.
*/
- if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) {
- unsigned long debugctl = get_debugctlmsr();
+ write_debugctlmsr(child,
+ child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF);
- debugctl &= ~DEBUGCTLMSR_BTF;
- update_debugctlmsr(debugctl);
- clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
- }
+ if (!child->thread.debugctlmsr)
+ clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
/* Always clear TIF_SINGLESTEP... */
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
diff --git a/trunk/arch/x86/kernel/tboot.c b/trunk/arch/x86/kernel/tboot.c
index cc2c60474fd0..86c9f91b48ae 100644
--- a/trunk/arch/x86/kernel/tboot.c
+++ b/trunk/arch/x86/kernel/tboot.c
@@ -175,9 +175,6 @@ static void add_mac_region(phys_addr_t start, unsigned long size)
struct tboot_mac_region *mr;
phys_addr_t end = start + size;
- if (tboot->num_mac_regions >= MAX_TB_MAC_REGIONS)
- panic("tboot: Too many MAC regions\n");
-
if (start && size) {
mr = &tboot->mac_regions[tboot->num_mac_regions++];
mr->start = round_down(start, PAGE_SIZE);
@@ -187,17 +184,18 @@ static void add_mac_region(phys_addr_t start, unsigned long size)
static int tboot_setup_sleep(void)
{
- int i;
-
tboot->num_mac_regions = 0;
- for (i = 0; i < e820.nr_map; i++) {
- if ((e820.map[i].type != E820_RAM)
- && (e820.map[i].type != E820_RESERVED_KERN))
- continue;
+ /* S3 resume code */
+ add_mac_region(acpi_wakeup_address, WAKEUP_SIZE);
- add_mac_region(e820.map[i].addr, e820.map[i].size);
- }
+#ifdef CONFIG_X86_TRAMPOLINE
+ /* AP trampoline code */
+ add_mac_region(virt_to_phys(trampoline_base), TRAMPOLINE_SIZE);
+#endif
+
+ /* kernel code + data + bss */
+ add_mac_region(virt_to_phys(_text), _end - _text);
tboot->acpi_sinfo.kernel_s3_resume_vector = acpi_wakeup_address;
diff --git a/trunk/arch/x86/kernel/tlb_uv.c b/trunk/arch/x86/kernel/tlb_uv.c
index 7fea555929e2..17b03dd3a6b5 100644
--- a/trunk/arch/x86/kernel/tlb_uv.c
+++ b/trunk/arch/x86/kernel/tlb_uv.c
@@ -1,7 +1,7 @@
/*
* SGI UltraViolet TLB flush routines.
*
- * (c) 2008-2010 Cliff Wickman , SGI.
+ * (c) 2008 Cliff Wickman , SGI.
*
* This code is released under the GNU General Public License version 2 or
* later.
@@ -20,67 +20,42 @@
#include
#include
#include
-#include
-struct msg_desc {
- struct bau_payload_queue_entry *msg;
- int msg_slot;
- int sw_ack_slot;
- struct bau_payload_queue_entry *va_queue_first;
- struct bau_payload_queue_entry *va_queue_last;
-};
-
-#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL
-
-static int uv_bau_max_concurrent __read_mostly;
-
-static int nobau;
-static int __init setup_nobau(char *arg)
-{
- nobau = 1;
- return 0;
-}
-early_param("nobau", setup_nobau);
+static struct bau_control **uv_bau_table_bases __read_mostly;
+static int uv_bau_retry_limit __read_mostly;
/* base pnode in this partition */
-static int uv_partition_base_pnode __read_mostly;
-/* position of pnode (which is nasid>>1): */
-static int uv_nshift __read_mostly;
-static unsigned long uv_mmask __read_mostly;
+static int uv_partition_base_pnode __read_mostly;
+
+static unsigned long uv_mmask __read_mostly;
static DEFINE_PER_CPU(struct ptc_stats, ptcstats);
static DEFINE_PER_CPU(struct bau_control, bau_control);
-static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask);
-
-struct reset_args {
- int sender;
-};
/*
- * Determine the first node on a uvhub. 'Nodes' are used for kernel
- * memory allocation.
+ * Determine the first node on a blade.
*/
-static int __init uvhub_to_first_node(int uvhub)
+static int __init blade_to_first_node(int blade)
{
int node, b;
for_each_online_node(node) {
b = uv_node_to_blade_id(node);
- if (uvhub == b)
+ if (blade == b)
return node;
}
- return -1;
+ return -1; /* shouldn't happen */
}
/*
- * Determine the apicid of the first cpu on a uvhub.
+ * Determine the apicid of the first cpu on a blade.
*/
-static int __init uvhub_to_first_apicid(int uvhub)
+static int __init blade_to_first_apicid(int blade)
{
int cpu;
for_each_present_cpu(cpu)
- if (uvhub == uv_cpu_to_blade_id(cpu))
+ if (blade == uv_cpu_to_blade_id(cpu))
return per_cpu(x86_cpu_to_apicid, cpu);
return -1;
}
@@ -93,459 +68,195 @@ static int __init uvhub_to_first_apicid(int uvhub)
* clear of the Timeout bit (as well) will free the resource. No reply will
* be sent (the hardware will only do one reply per message).
*/
-static inline void uv_reply_to_message(struct msg_desc *mdp,
- struct bau_control *bcp)
+static void uv_reply_to_message(int resource,
+ struct bau_payload_queue_entry *msg,
+ struct bau_msg_status *msp)
{
unsigned long dw;
- struct bau_payload_queue_entry *msg;
- msg = mdp->msg;
- if (!msg->canceled) {
- dw = (msg->sw_ack_vector << UV_SW_ACK_NPENDING) |
- msg->sw_ack_vector;
- uv_write_local_mmr(
- UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, dw);
- }
+ dw = (1 << (resource + UV_SW_ACK_NPENDING)) | (1 << resource);
msg->replied_to = 1;
msg->sw_ack_vector = 0;
-}
-
-/*
- * Process the receipt of a RETRY message
- */
-static inline void uv_bau_process_retry_msg(struct msg_desc *mdp,
- struct bau_control *bcp)
-{
- int i;
- int cancel_count = 0;
- int slot2;
- unsigned long msg_res;
- unsigned long mmr = 0;
- struct bau_payload_queue_entry *msg;
- struct bau_payload_queue_entry *msg2;
- struct ptc_stats *stat;
-
- msg = mdp->msg;
- stat = &per_cpu(ptcstats, bcp->cpu);
- stat->d_retries++;
- /*
- * cancel any message from msg+1 to the retry itself
- */
- for (msg2 = msg+1, i = 0; i < DEST_Q_SIZE; msg2++, i++) {
- if (msg2 > mdp->va_queue_last)
- msg2 = mdp->va_queue_first;
- if (msg2 == msg)
- break;
-
- /* same conditions for cancellation as uv_do_reset */
- if ((msg2->replied_to == 0) && (msg2->canceled == 0) &&
- (msg2->sw_ack_vector) && ((msg2->sw_ack_vector &
- msg->sw_ack_vector) == 0) &&
- (msg2->sending_cpu == msg->sending_cpu) &&
- (msg2->msg_type != MSG_NOOP)) {
- slot2 = msg2 - mdp->va_queue_first;
- mmr = uv_read_local_mmr
- (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE);
- msg_res = ((msg2->sw_ack_vector << 8) |
- msg2->sw_ack_vector);
- /*
- * This is a message retry; clear the resources held
- * by the previous message only if they timed out.
- * If it has not timed out we have an unexpected
- * situation to report.
- */
- if (mmr & (msg_res << 8)) {
- /*
- * is the resource timed out?
- * make everyone ignore the cancelled message.
- */
- msg2->canceled = 1;
- stat->d_canceled++;
- cancel_count++;
- uv_write_local_mmr(
- UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS,
- (msg_res << 8) | msg_res);
- } else
- printk(KERN_INFO "note bau retry: no effect\n");
- }
- }
- if (!cancel_count)
- stat->d_nocanceled++;
+ if (msp)
+ msp->seen_by.bits = 0;
+ uv_write_local_mmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, dw);
}
/*
* Do all the things a cpu should do for a TLB shootdown message.
* Other cpu's may come here at the same time for this message.
*/
-static void uv_bau_process_message(struct msg_desc *mdp,
- struct bau_control *bcp)
+static void uv_bau_process_message(struct bau_payload_queue_entry *msg,
+ int msg_slot, int sw_ack_slot)
{
- int msg_ack_count;
- short socket_ack_count = 0;
- struct ptc_stats *stat;
- struct bau_payload_queue_entry *msg;
- struct bau_control *smaster = bcp->socket_master;
+ unsigned long this_cpu_mask;
+ struct bau_msg_status *msp;
+ int cpu;
+
+ msp = __get_cpu_var(bau_control).msg_statuses + msg_slot;
+ cpu = uv_blade_processor_id();
+ msg->number_of_cpus =
+ uv_blade_nr_online_cpus(uv_node_to_blade_id(numa_node_id()));
+ this_cpu_mask = 1UL << cpu;
+ if (msp->seen_by.bits & this_cpu_mask)
+ return;
+ atomic_or_long(&msp->seen_by.bits, this_cpu_mask);
+
+ if (msg->replied_to == 1)
+ return;
- /*
- * This must be a normal message, or retry of a normal message
- */
- msg = mdp->msg;
- stat = &per_cpu(ptcstats, bcp->cpu);
if (msg->address == TLB_FLUSH_ALL) {
local_flush_tlb();
- stat->d_alltlb++;
+ __get_cpu_var(ptcstats).alltlb++;
} else {
__flush_tlb_one(msg->address);
- stat->d_onetlb++;
+ __get_cpu_var(ptcstats).onetlb++;
}
- stat->d_requestee++;
-
- /*
- * One cpu on each uvhub has the additional job on a RETRY
- * of releasing the resource held by the message that is
- * being retried. That message is identified by sending
- * cpu number.
- */
- if (msg->msg_type == MSG_RETRY && bcp == bcp->uvhub_master)
- uv_bau_process_retry_msg(mdp, bcp);
- /*
- * This is a sw_ack message, so we have to reply to it.
- * Count each responding cpu on the socket. This avoids
- * pinging the count's cache line back and forth between
- * the sockets.
- */
- socket_ack_count = atomic_add_short_return(1, (struct atomic_short *)
- &smaster->socket_acknowledge_count[mdp->msg_slot]);
- if (socket_ack_count == bcp->cpus_in_socket) {
- /*
- * Both sockets dump their completed count total into
- * the message's count.
- */
- smaster->socket_acknowledge_count[mdp->msg_slot] = 0;
- msg_ack_count = atomic_add_short_return(socket_ack_count,
- (struct atomic_short *)&msg->acknowledge_count);
-
- if (msg_ack_count == bcp->cpus_in_uvhub) {
- /*
- * All cpus in uvhub saw it; reply
- */
- uv_reply_to_message(mdp, bcp);
- }
- }
+ __get_cpu_var(ptcstats).requestee++;
- return;
+ atomic_inc_short(&msg->acknowledge_count);
+ if (msg->number_of_cpus == msg->acknowledge_count)
+ uv_reply_to_message(sw_ack_slot, msg, msp);
}
/*
- * Determine the first cpu on a uvhub.
- */
-static int uvhub_to_first_cpu(int uvhub)
-{
- int cpu;
- for_each_present_cpu(cpu)
- if (uvhub == uv_cpu_to_blade_id(cpu))
- return cpu;
- return -1;
-}
-
-/*
- * Last resort when we get a large number of destination timeouts is
- * to clear resources held by a given cpu.
- * Do this with IPI so that all messages in the BAU message queue
- * can be identified by their nonzero sw_ack_vector field.
+ * Examine the payload queue on one distribution node to see
+ * which messages have not been seen, and which cpu(s) have not seen them.
*
- * This is entered for a single cpu on the uvhub.
- * The sender want's this uvhub to free a specific message's
- * sw_ack resources.
+ * Returns the number of cpu's that have not responded.
*/
-static void
-uv_do_reset(void *ptr)
+static int uv_examine_destination(struct bau_control *bau_tablesp, int sender)
{
- int i;
- int slot;
- int count = 0;
- unsigned long mmr;
- unsigned long msg_res;
- struct bau_control *bcp;
- struct reset_args *rap;
struct bau_payload_queue_entry *msg;
- struct ptc_stats *stat;
-
- bcp = &per_cpu(bau_control, smp_processor_id());
- rap = (struct reset_args *)ptr;
- stat = &per_cpu(ptcstats, bcp->cpu);
- stat->d_resets++;
+ struct bau_msg_status *msp;
+ int count = 0;
+ int i;
+ int j;
- /*
- * We're looking for the given sender, and
- * will free its sw_ack resource.
- * If all cpu's finally responded after the timeout, its
- * message 'replied_to' was set.
- */
- for (msg = bcp->va_queue_first, i = 0; i < DEST_Q_SIZE; msg++, i++) {
- /* uv_do_reset: same conditions for cancellation as
- uv_bau_process_retry_msg() */
- if ((msg->replied_to == 0) &&
- (msg->canceled == 0) &&
- (msg->sending_cpu == rap->sender) &&
- (msg->sw_ack_vector) &&
- (msg->msg_type != MSG_NOOP)) {
- /*
- * make everyone else ignore this message
- */
- msg->canceled = 1;
- slot = msg - bcp->va_queue_first;
- count++;
- /*
- * only reset the resource if it is still pending
- */
- mmr = uv_read_local_mmr
- (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE);
- msg_res = ((msg->sw_ack_vector << 8) |
- msg->sw_ack_vector);
- if (mmr & msg_res) {
- stat->d_rcanceled++;
- uv_write_local_mmr(
- UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS,
- msg_res);
+ for (msg = bau_tablesp->va_queue_first, i = 0; i < DEST_Q_SIZE;
+ msg++, i++) {
+ if ((msg->sending_cpu == sender) && (!msg->replied_to)) {
+ msp = bau_tablesp->msg_statuses + i;
+ printk(KERN_DEBUG
+ "blade %d: address:%#lx %d of %d, not cpu(s): ",
+ i, msg->address, msg->acknowledge_count,
+ msg->number_of_cpus);
+ for (j = 0; j < msg->number_of_cpus; j++) {
+ if (!((1L << j) & msp->seen_by.bits)) {
+ count++;
+ printk("%d ", j);
+ }
}
+ printk("\n");
}
}
- return;
+ return count;
}
/*
- * Use IPI to get all target uvhubs to release resources held by
- * a given sending cpu number.
+ * Examine the payload queue on all the distribution nodes to see
+ * which messages have not been seen, and which cpu(s) have not seen them.
+ *
+ * Returns the number of cpu's that have not responded.
*/
-static void uv_reset_with_ipi(struct bau_target_uvhubmask *distribution,
- int sender)
+static int uv_examine_destinations(struct bau_target_nodemask *distribution)
{
- int uvhub;
- int cpu;
- cpumask_t mask;
- struct reset_args reset_args;
-
- reset_args.sender = sender;
+ int sender;
+ int i;
+ int count = 0;
- cpus_clear(mask);
- /* find a single cpu for each uvhub in this distribution mask */
- for (uvhub = 0;
- uvhub < sizeof(struct bau_target_uvhubmask) * BITSPERBYTE;
- uvhub++) {
- if (!bau_uvhub_isset(uvhub, distribution))
+ sender = smp_processor_id();
+ for (i = 0; i < sizeof(struct bau_target_nodemask) * BITSPERBYTE; i++) {
+ if (!bau_node_isset(i, distribution))
continue;
- /* find a cpu for this uvhub */
- cpu = uvhub_to_first_cpu(uvhub);
- cpu_set(cpu, mask);
+ count += uv_examine_destination(uv_bau_table_bases[i], sender);
}
- /* IPI all cpus; Preemption is already disabled */
- smp_call_function_many(&mask, uv_do_reset, (void *)&reset_args, 1);
- return;
-}
-
-static inline unsigned long
-cycles_2_us(unsigned long long cyc)
-{
- unsigned long long ns;
- unsigned long us;
- ns = (cyc * per_cpu(cyc2ns, smp_processor_id()))
- >> CYC2NS_SCALE_FACTOR;
- us = ns / 1000;
- return us;
-}
-
-/*
- * wait for all cpus on this hub to finish their sends and go quiet
- * leaves uvhub_quiesce set so that no new broadcasts are started by
- * bau_flush_send_and_wait()
- */
-static inline void
-quiesce_local_uvhub(struct bau_control *hmaster)
-{
- atomic_add_short_return(1, (struct atomic_short *)
- &hmaster->uvhub_quiesce);
-}
-
-/*
- * mark this quiet-requestor as done
- */
-static inline void
-end_uvhub_quiesce(struct bau_control *hmaster)
-{
- atomic_add_short_return(-1, (struct atomic_short *)
- &hmaster->uvhub_quiesce);
+ return count;
}
/*
- * Wait for completion of a broadcast software ack message
- * return COMPLETE, RETRY(PLUGGED or TIMEOUT) or GIVEUP
+ * wait for completion of a broadcast message
+ *
+ * return COMPLETE, RETRY or GIVEUP
*/
static int uv_wait_completion(struct bau_desc *bau_desc,
- unsigned long mmr_offset, int right_shift, int this_cpu,
- struct bau_control *bcp, struct bau_control *smaster, long try)
+ unsigned long mmr_offset, int right_shift)
{
- int relaxes = 0;
+ int exams = 0;
+ long destination_timeouts = 0;
+ long source_timeouts = 0;
unsigned long descriptor_status;
- unsigned long mmr;
- unsigned long mask;
- cycles_t ttime;
- cycles_t timeout_time;
- struct ptc_stats *stat = &per_cpu(ptcstats, this_cpu);
- struct bau_control *hmaster;
-
- hmaster = bcp->uvhub_master;
- timeout_time = get_cycles() + bcp->timeout_interval;
- /* spin on the status MMR, waiting for it to go idle */
while ((descriptor_status = (((unsigned long)
uv_read_local_mmr(mmr_offset) >>
right_shift) & UV_ACT_STATUS_MASK)) !=
DESC_STATUS_IDLE) {
+ if (descriptor_status == DESC_STATUS_SOURCE_TIMEOUT) {
+ source_timeouts++;
+ if (source_timeouts > SOURCE_TIMEOUT_LIMIT)
+ source_timeouts = 0;
+ __get_cpu_var(ptcstats).s_retry++;
+ return FLUSH_RETRY;
+ }
/*
- * Our software ack messages may be blocked because there are
- * no swack resources available. As long as none of them
- * has timed out hardware will NACK our message and its
- * state will stay IDLE.
+ * spin here looking for progress at the destinations
*/
- if (descriptor_status == DESC_STATUS_SOURCE_TIMEOUT) {
- stat->s_stimeout++;
- return FLUSH_GIVEUP;
- } else if (descriptor_status ==
- DESC_STATUS_DESTINATION_TIMEOUT) {
- stat->s_dtimeout++;
- ttime = get_cycles();
-
- /*
- * Our retries may be blocked by all destination
- * swack resources being consumed, and a timeout
- * pending. In that case hardware returns the
- * ERROR that looks like a destination timeout.
- */
- if (cycles_2_us(ttime - bcp->send_message) < BIOS_TO) {
- bcp->conseccompletes = 0;
- return FLUSH_RETRY_PLUGGED;
- }
-
- bcp->conseccompletes = 0;
- return FLUSH_RETRY_TIMEOUT;
- } else {
- /*
- * descriptor_status is still BUSY
- */
- cpu_relax();
- relaxes++;
- if (relaxes >= 10000) {
- relaxes = 0;
- if (get_cycles() > timeout_time) {
- quiesce_local_uvhub(hmaster);
-
- /* single-thread the register change */
- spin_lock(&hmaster->masks_lock);
- mmr = uv_read_local_mmr(mmr_offset);
- mask = 0UL;
- mask |= (3UL < right_shift);
- mask = ~mask;
- mmr &= mask;
- uv_write_local_mmr(mmr_offset, mmr);
- spin_unlock(&hmaster->masks_lock);
- end_uvhub_quiesce(hmaster);
- stat->s_busy++;
+ if (descriptor_status == DESC_STATUS_DESTINATION_TIMEOUT) {
+ destination_timeouts++;
+ if (destination_timeouts > DESTINATION_TIMEOUT_LIMIT) {
+ /*
+ * returns number of cpus not responding
+ */
+ if (uv_examine_destinations
+ (&bau_desc->distribution) == 0) {
+ __get_cpu_var(ptcstats).d_retry++;
+ return FLUSH_RETRY;
+ }
+ exams++;
+ if (exams >= uv_bau_retry_limit) {
+ printk(KERN_DEBUG
+ "uv_flush_tlb_others");
+ printk("giving up on cpu %d\n",
+ smp_processor_id());
return FLUSH_GIVEUP;
}
+ /*
+ * delays can hang the simulator
+ udelay(1000);
+ */
+ destination_timeouts = 0;
}
}
+ cpu_relax();
}
- bcp->conseccompletes++;
return FLUSH_COMPLETE;
}
-static inline cycles_t
-sec_2_cycles(unsigned long sec)
-{
- unsigned long ns;
- cycles_t cyc;
-
- ns = sec * 1000000000;
- cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id()));
- return cyc;
-}
-
-/*
- * conditionally add 1 to *v, unless *v is >= u
- * return 0 if we cannot add 1 to *v because it is >= u
- * return 1 if we can add 1 to *v because it is < u
- * the add is atomic
- *
- * This is close to atomic_add_unless(), but this allows the 'u' value
- * to be lowered below the current 'v'. atomic_add_unless can only stop
- * on equal.
- */
-static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u)
-{
- spin_lock(lock);
- if (atomic_read(v) >= u) {
- spin_unlock(lock);
- return 0;
- }
- atomic_inc(v);
- spin_unlock(lock);
- return 1;
-}
-
/**
* uv_flush_send_and_wait
*
- * Send a broadcast and wait for it to complete.
+ * Send a broadcast and wait for a broadcast message to complete.
*
- * The flush_mask contains the cpus the broadcast is to be sent to, plus
- * cpus that are on the local uvhub.
+ * The flush_mask contains the cpus the broadcast was sent to.
*
- * Returns NULL if all flushing represented in the mask was done. The mask
- * is zeroed.
+ * Returns NULL if all remote flushing was done. The mask is zeroed.
* Returns @flush_mask if some remote flushing remains to be done. The
- * mask will have some bits still set, representing any cpus on the local
- * uvhub (not current cpu) and any on remote uvhubs if the broadcast failed.
+ * mask will have some bits still set.
*/
-const struct cpumask *uv_flush_send_and_wait(struct bau_desc *bau_desc,
- struct cpumask *flush_mask,
- struct bau_control *bcp)
+const struct cpumask *uv_flush_send_and_wait(int cpu, int this_pnode,
+ struct bau_desc *bau_desc,
+ struct cpumask *flush_mask)
{
+ int completion_status = 0;
int right_shift;
- int uvhub;
+ int tries = 0;
+ int pnode;
int bit;
- int completion_status = 0;
- int seq_number = 0;
- long try = 0;
- int cpu = bcp->uvhub_cpu;
- int this_cpu = bcp->cpu;
- int this_uvhub = bcp->uvhub;
unsigned long mmr_offset;
unsigned long index;
cycles_t time1;
cycles_t time2;
- struct ptc_stats *stat = &per_cpu(ptcstats, bcp->cpu);
- struct bau_control *smaster = bcp->socket_master;
- struct bau_control *hmaster = bcp->uvhub_master;
-
- /*
- * Spin here while there are hmaster->max_concurrent or more active
- * descriptors. This is the per-uvhub 'throttle'.
- */
- if (!atomic_inc_unless_ge(&hmaster->uvhub_lock,
- &hmaster->active_descriptor_count,
- hmaster->max_concurrent)) {
- stat->s_throttles++;
- do {
- cpu_relax();
- } while (!atomic_inc_unless_ge(&hmaster->uvhub_lock,
- &hmaster->active_descriptor_count,
- hmaster->max_concurrent));
- }
-
- while (hmaster->uvhub_quiesce)
- cpu_relax();
if (cpu < UV_CPUS_PER_ACT_STATUS) {
mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0;
@@ -557,108 +268,24 @@ const struct cpumask *uv_flush_send_and_wait(struct bau_desc *bau_desc,
}
time1 = get_cycles();
do {
- /*
- * Every message from any given cpu gets a unique message
- * sequence number. But retries use that same number.
- * Our message may have timed out at the destination because
- * all sw-ack resources are in use and there is a timeout
- * pending there. In that case, our last send never got
- * placed into the queue and we need to persist until it
- * does.
- *
- * Make any retry a type MSG_RETRY so that the destination will
- * free any resource held by a previous message from this cpu.
- */
- if (try == 0) {
- /* use message type set by the caller the first time */
- seq_number = bcp->message_number++;
- } else {
- /* use RETRY type on all the rest; same sequence */
- bau_desc->header.msg_type = MSG_RETRY;
- stat->s_retry_messages++;
- }
- bau_desc->header.sequence = seq_number;
+ tries++;
index = (1UL << UVH_LB_BAU_SB_ACTIVATION_CONTROL_PUSH_SHFT) |
- bcp->uvhub_cpu;
- bcp->send_message = get_cycles();
-
+ cpu;
uv_write_local_mmr(UVH_LB_BAU_SB_ACTIVATION_CONTROL, index);
-
- try++;
completion_status = uv_wait_completion(bau_desc, mmr_offset,
- right_shift, this_cpu, bcp, smaster, try);
-
- if (completion_status == FLUSH_RETRY_PLUGGED) {
- /*
- * Our retries may be blocked by all destination swack
- * resources being consumed, and a timeout pending. In
- * that case hardware immediately returns the ERROR
- * that looks like a destination timeout.
- */
- udelay(TIMEOUT_DELAY);
- bcp->plugged_tries++;
- if (bcp->plugged_tries >= PLUGSB4RESET) {
- bcp->plugged_tries = 0;
- quiesce_local_uvhub(hmaster);
- spin_lock(&hmaster->queue_lock);
- uv_reset_with_ipi(&bau_desc->distribution,
- this_cpu);
- spin_unlock(&hmaster->queue_lock);
- end_uvhub_quiesce(hmaster);
- bcp->ipi_attempts++;
- stat->s_resets_plug++;
- }
- } else if (completion_status == FLUSH_RETRY_TIMEOUT) {
- hmaster->max_concurrent = 1;
- bcp->timeout_tries++;
- udelay(TIMEOUT_DELAY);
- if (bcp->timeout_tries >= TIMEOUTSB4RESET) {
- bcp->timeout_tries = 0;
- quiesce_local_uvhub(hmaster);
- spin_lock(&hmaster->queue_lock);
- uv_reset_with_ipi(&bau_desc->distribution,
- this_cpu);
- spin_unlock(&hmaster->queue_lock);
- end_uvhub_quiesce(hmaster);
- bcp->ipi_attempts++;
- stat->s_resets_timeout++;
- }
- }
- if (bcp->ipi_attempts >= 3) {
- bcp->ipi_attempts = 0;
- completion_status = FLUSH_GIVEUP;
- break;
- }
- cpu_relax();
- } while ((completion_status == FLUSH_RETRY_PLUGGED) ||
- (completion_status == FLUSH_RETRY_TIMEOUT));
+ right_shift);
+ } while (completion_status == FLUSH_RETRY);
time2 = get_cycles();
+ __get_cpu_var(ptcstats).sflush += (time2 - time1);
+ if (tries > 1)
+ __get_cpu_var(ptcstats).retriesok++;
- if ((completion_status == FLUSH_COMPLETE) && (bcp->conseccompletes > 5)
- && (hmaster->max_concurrent < hmaster->max_concurrent_constant))
- hmaster->max_concurrent++;
-
- /*
- * hold any cpu not timing out here; no other cpu currently held by
- * the 'throttle' should enter the activation code
- */
- while (hmaster->uvhub_quiesce)
- cpu_relax();
- atomic_dec(&hmaster->active_descriptor_count);
-
- /* guard against cycles wrap */
- if (time2 > time1)
- stat->s_time += (time2 - time1);
- else
- stat->s_requestor--; /* don't count this one */
- if (completion_status == FLUSH_COMPLETE && try > 1)
- stat->s_retriesok++;
- else if (completion_status == FLUSH_GIVEUP) {
+ if (completion_status == FLUSH_GIVEUP) {
/*
* Cause the caller to do an IPI-style TLB shootdown on
- * the target cpu's, all of which are still in the mask.
+ * the cpu's, all of which are still in the mask.
*/
- stat->s_giveup++;
+ __get_cpu_var(ptcstats).ptc_i++;
return flush_mask;
}
@@ -667,17 +294,18 @@ const struct cpumask *uv_flush_send_and_wait(struct bau_desc *bau_desc,
* use the IPI method of shootdown on them.
*/
for_each_cpu(bit, flush_mask) {
- uvhub = uv_cpu_to_blade_id(bit);
- if (uvhub == this_uvhub)
+ pnode = uv_cpu_to_pnode(bit);
+ if (pnode == this_pnode)
continue;
cpumask_clear_cpu(bit, flush_mask);
}
if (!cpumask_empty(flush_mask))
return flush_mask;
-
return NULL;
}
+static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask);
+
/**
* uv_flush_tlb_others - globally purge translation cache of a virtual
* address or all TLB's
@@ -694,8 +322,8 @@ const struct cpumask *uv_flush_send_and_wait(struct bau_desc *bau_desc,
* The caller has derived the cpumask from the mm_struct. This function
* is called only if there are bits set in the mask. (e.g. flush_tlb_page())
*
- * The cpumask is converted into a uvhubmask of the uvhubs containing
- * those cpus.
+ * The cpumask is converted into a nodemask of the nodes containing
+ * the cpus.
*
* Note that this function should be called with preemption disabled.
*
@@ -707,82 +335,52 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
struct mm_struct *mm,
unsigned long va, unsigned int cpu)
{
- int remotes;
- int tcpu;
- int uvhub;
+ struct cpumask *flush_mask = __get_cpu_var(uv_flush_tlb_mask);
+ int i;
+ int bit;
+ int pnode;
+ int uv_cpu;
+ int this_pnode;
int locals = 0;
struct bau_desc *bau_desc;
- struct cpumask *flush_mask;
- struct ptc_stats *stat;
- struct bau_control *bcp;
-
- if (nobau)
- return cpumask;
- bcp = &per_cpu(bau_control, cpu);
- /*
- * Each sending cpu has a per-cpu mask which it fills from the caller's
- * cpu mask. Only remote cpus are converted to uvhubs and copied.
- */
- flush_mask = (struct cpumask *)per_cpu(uv_flush_tlb_mask, cpu);
- /*
- * copy cpumask to flush_mask, removing current cpu
- * (current cpu should already have been flushed by the caller and
- * should never be returned if we return flush_mask)
- */
cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu));
- if (cpu_isset(cpu, *cpumask))
- locals++; /* current cpu was targeted */
- bau_desc = bcp->descriptor_base;
- bau_desc += UV_ITEMS_PER_DESCRIPTOR * bcp->uvhub_cpu;
+ uv_cpu = uv_blade_processor_id();
+ this_pnode = uv_hub_info->pnode;
+ bau_desc = __get_cpu_var(bau_control).descriptor_base;
+ bau_desc += UV_ITEMS_PER_DESCRIPTOR * uv_cpu;
+
+ bau_nodes_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE);
- bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE);
- remotes = 0;
- for_each_cpu(tcpu, flush_mask) {
- uvhub = uv_cpu_to_blade_id(tcpu);
- if (uvhub == bcp->uvhub) {
+ i = 0;
+ for_each_cpu(bit, flush_mask) {
+ pnode = uv_cpu_to_pnode(bit);
+ BUG_ON(pnode > (UV_DISTRIBUTION_SIZE - 1));
+ if (pnode == this_pnode) {
locals++;
continue;
}
- bau_uvhub_set(uvhub, &bau_desc->distribution);
- remotes++;
+ bau_node_set(pnode - uv_partition_base_pnode,
+ &bau_desc->distribution);
+ i++;
}
- if (remotes == 0) {
+ if (i == 0) {
/*
- * No off_hub flushing; return status for local hub.
- * Return the caller's mask if all were local (the current
- * cpu may be in that mask).
+ * no off_node flushing; return status for local node
*/
if (locals)
- return cpumask;
+ return flush_mask;
else
return NULL;
}
- stat = &per_cpu(ptcstats, cpu);
- stat->s_requestor++;
- stat->s_ntargcpu += remotes;
- remotes = bau_uvhub_weight(&bau_desc->distribution);
- stat->s_ntarguvhub += remotes;
- if (remotes >= 16)
- stat->s_ntarguvhub16++;
- else if (remotes >= 8)
- stat->s_ntarguvhub8++;
- else if (remotes >= 4)
- stat->s_ntarguvhub4++;
- else if (remotes >= 2)
- stat->s_ntarguvhub2++;
- else
- stat->s_ntarguvhub1++;
+ __get_cpu_var(ptcstats).requestor++;
+ __get_cpu_var(ptcstats).ntargeted += i;
bau_desc->payload.address = va;
bau_desc->payload.sending_cpu = cpu;
- /*
- * uv_flush_send_and_wait returns null if all cpu's were messaged, or
- * the adjusted flush_mask if any cpu's were not messaged.
- */
- return uv_flush_send_and_wait(bau_desc, flush_mask, bcp);
+ return uv_flush_send_and_wait(uv_cpu, this_pnode, bau_desc, flush_mask);
}
/*
@@ -791,70 +389,87 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
*
* We received a broadcast assist message.
*
- * Interrupts are disabled; this interrupt could represent
+ * Interrupts may have been disabled; this interrupt could represent
* the receipt of several messages.
*
- * All cores/threads on this hub get this interrupt.
- * The last one to see it does the software ack.
+ * All cores/threads on this node get this interrupt.
+ * The last one to see it does the s/w ack.
* (the resource will not be freed until noninterruptable cpus see this
- * interrupt; hardware may timeout the s/w ack and reply ERROR)
+ * interrupt; hardware will timeout the s/w ack and reply ERROR)
*/
void uv_bau_message_interrupt(struct pt_regs *regs)
{
- int count = 0;
- cycles_t time_start;
+ struct bau_payload_queue_entry *va_queue_first;
+ struct bau_payload_queue_entry *va_queue_last;
struct bau_payload_queue_entry *msg;
- struct bau_control *bcp;
- struct ptc_stats *stat;
- struct msg_desc msgdesc;
-
- time_start = get_cycles();
- bcp = &per_cpu(bau_control, smp_processor_id());
- stat = &per_cpu(ptcstats, smp_processor_id());
- msgdesc.va_queue_first = bcp->va_queue_first;
- msgdesc.va_queue_last = bcp->va_queue_last;
- msg = bcp->bau_msg_head;
+ struct pt_regs *old_regs = set_irq_regs(regs);
+ cycles_t time1;
+ cycles_t time2;
+ int msg_slot;
+ int sw_ack_slot;
+ int fw;
+ int count = 0;
+ unsigned long local_pnode;
+
+ ack_APIC_irq();
+ exit_idle();
+ irq_enter();
+
+ time1 = get_cycles();
+
+ local_pnode = uv_blade_to_pnode(uv_numa_blade_id());
+
+ va_queue_first = __get_cpu_var(bau_control).va_queue_first;
+ va_queue_last = __get_cpu_var(bau_control).va_queue_last;
+
+ msg = __get_cpu_var(bau_control).bau_msg_head;
while (msg->sw_ack_vector) {
count++;
- msgdesc.msg_slot = msg - msgdesc.va_queue_first;
- msgdesc.sw_ack_slot = ffs(msg->sw_ack_vector) - 1;
- msgdesc.msg = msg;
- uv_bau_process_message(&msgdesc, bcp);
+ fw = msg->sw_ack_vector;
+ msg_slot = msg - va_queue_first;
+ sw_ack_slot = ffs(fw) - 1;
+
+ uv_bau_process_message(msg, msg_slot, sw_ack_slot);
+
msg++;
- if (msg > msgdesc.va_queue_last)
- msg = msgdesc.va_queue_first;
- bcp->bau_msg_head = msg;
+ if (msg > va_queue_last)
+ msg = va_queue_first;
+ __get_cpu_var(bau_control).bau_msg_head = msg;
}
- stat->d_time += (get_cycles() - time_start);
if (!count)
- stat->d_nomsg++;
+ __get_cpu_var(ptcstats).nomsg++;
else if (count > 1)
- stat->d_multmsg++;
- ack_APIC_irq();
+ __get_cpu_var(ptcstats).multmsg++;
+
+ time2 = get_cycles();
+ __get_cpu_var(ptcstats).dflush += (time2 - time1);
+
+ irq_exit();
+ set_irq_regs(old_regs);
}
/*
* uv_enable_timeouts
*
- * Each target uvhub (i.e. a uvhub that has no cpu's) needs to have
+ * Each target blade (i.e. blades that have cpu's) needs to have
* shootdown message timeouts enabled. The timeout does not cause
* an interrupt, but causes an error message to be returned to
* the sender.
*/
static void uv_enable_timeouts(void)
{
- int uvhub;
- int nuvhubs;
+ int blade;
+ int nblades;
int pnode;
unsigned long mmr_image;
- nuvhubs = uv_num_possible_blades();
+ nblades = uv_num_possible_blades();
- for (uvhub = 0; uvhub < nuvhubs; uvhub++) {
- if (!uv_blade_nr_possible_cpus(uvhub))
+ for (blade = 0; blade < nblades; blade++) {
+ if (!uv_blade_nr_possible_cpus(blade))
continue;
- pnode = uv_blade_to_pnode(uvhub);
+ pnode = uv_blade_to_pnode(blade);
mmr_image =
uv_read_global_mmr64(pnode, UVH_LB_BAU_MISC_CONTROL);
/*
@@ -864,16 +479,16 @@ static void uv_enable_timeouts(void)
* To program the period, the SOFT_ACK_MODE must be off.
*/
mmr_image &= ~((unsigned long)1 <<
- UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT);
+ UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT);
uv_write_global_mmr64
(pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image);
/*
* Set the 4-bit period.
*/
mmr_image &= ~((unsigned long)0xf <<
- UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT);
+ UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT);
mmr_image |= (UV_INTD_SOFT_ACK_TIMEOUT_PERIOD <<
- UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT);
+ UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT);
uv_write_global_mmr64
(pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image);
/*
@@ -882,7 +497,7 @@ static void uv_enable_timeouts(void)
* indicated in bits 2:0 (7 causes all of them to timeout).
*/
mmr_image |= ((unsigned long)1 <<
- UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT);
+ UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT);
uv_write_global_mmr64
(pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image);
}
@@ -907,20 +522,9 @@ static void uv_ptc_seq_stop(struct seq_file *file, void *data)
{
}
-static inline unsigned long long
-millisec_2_cycles(unsigned long millisec)
-{
- unsigned long ns;
- unsigned long long cyc;
-
- ns = millisec * 1000;
- cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id()));
- return cyc;
-}
-
/*
- * Display the statistics thru /proc.
- * 'data' points to the cpu number
+ * Display the statistics thru /proc
+ * data points to the cpu number
*/
static int uv_ptc_seq_show(struct seq_file *file, void *data)
{
@@ -931,155 +535,78 @@ static int uv_ptc_seq_show(struct seq_file *file, void *data)
if (!cpu) {
seq_printf(file,
- "# cpu sent stime numuvhubs numuvhubs16 numuvhubs8 ");
+ "# cpu requestor requestee one all sretry dretry ptc_i ");
seq_printf(file,
- "numuvhubs4 numuvhubs2 numuvhubs1 numcpus dto ");
- seq_printf(file,
- "retries rok resetp resett giveup sto bz throt ");
- seq_printf(file,
- "sw_ack recv rtime all ");
- seq_printf(file,
- "one mult none retry canc nocan reset rcan\n");
+ "sw_ack sflush dflush sok dnomsg dmult starget\n");
}
if (cpu < num_possible_cpus() && cpu_online(cpu)) {
stat = &per_cpu(ptcstats, cpu);
- /* source side statistics */
- seq_printf(file,
- "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ",
- cpu, stat->s_requestor, cycles_2_us(stat->s_time),
- stat->s_ntarguvhub, stat->s_ntarguvhub16,
- stat->s_ntarguvhub8, stat->s_ntarguvhub4,
- stat->s_ntarguvhub2, stat->s_ntarguvhub1,
- stat->s_ntargcpu, stat->s_dtimeout);
- seq_printf(file, "%ld %ld %ld %ld %ld %ld %ld %ld ",
- stat->s_retry_messages, stat->s_retriesok,
- stat->s_resets_plug, stat->s_resets_timeout,
- stat->s_giveup, stat->s_stimeout,
- stat->s_busy, stat->s_throttles);
- /* destination side statistics */
- seq_printf(file,
- "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n",
+ seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld ",
+ cpu, stat->requestor,
+ stat->requestee, stat->onetlb, stat->alltlb,
+ stat->s_retry, stat->d_retry, stat->ptc_i);
+ seq_printf(file, "%lx %ld %ld %ld %ld %ld %ld\n",
uv_read_global_mmr64(uv_cpu_to_pnode(cpu),
UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE),
- stat->d_requestee, cycles_2_us(stat->d_time),
- stat->d_alltlb, stat->d_onetlb, stat->d_multmsg,
- stat->d_nomsg, stat->d_retries, stat->d_canceled,
- stat->d_nocanceled, stat->d_resets,
- stat->d_rcanceled);
+ stat->sflush, stat->dflush,
+ stat->retriesok, stat->nomsg,
+ stat->multmsg, stat->ntargeted);
}
return 0;
}
/*
- * -1: resetf the statistics
* 0: display meaning of the statistics
- * >0: maximum concurrent active descriptors per uvhub (throttle)
+ * >0: retry limit
*/
static ssize_t uv_ptc_proc_write(struct file *file, const char __user *user,
size_t count, loff_t *data)
{
- int cpu;
- long input_arg;
+ long newmode;
char optstr[64];
- struct ptc_stats *stat;
- struct bau_control *bcp;
if (count == 0 || count > sizeof(optstr))
return -EINVAL;
if (copy_from_user(optstr, user, count))
return -EFAULT;
optstr[count - 1] = '\0';
- if (strict_strtol(optstr, 10, &input_arg) < 0) {
+ if (strict_strtoul(optstr, 10, &newmode) < 0) {
printk(KERN_DEBUG "%s is invalid\n", optstr);
return -EINVAL;
}
- if (input_arg == 0) {
+ if (newmode == 0) {
printk(KERN_DEBUG "# cpu: cpu number\n");
- printk(KERN_DEBUG "Sender statistics:\n");
- printk(KERN_DEBUG
- "sent: number of shootdown messages sent\n");
- printk(KERN_DEBUG
- "stime: time spent sending messages\n");
- printk(KERN_DEBUG
- "numuvhubs: number of hubs targeted with shootdown\n");
- printk(KERN_DEBUG
- "numuvhubs16: number times 16 or more hubs targeted\n");
- printk(KERN_DEBUG
- "numuvhubs8: number times 8 or more hubs targeted\n");
- printk(KERN_DEBUG
- "numuvhubs4: number times 4 or more hubs targeted\n");
- printk(KERN_DEBUG
- "numuvhubs2: number times 2 or more hubs targeted\n");
- printk(KERN_DEBUG
- "numuvhubs1: number times 1 hub targeted\n");
- printk(KERN_DEBUG
- "numcpus: number of cpus targeted with shootdown\n");
- printk(KERN_DEBUG
- "dto: number of destination timeouts\n");
- printk(KERN_DEBUG
- "retries: destination timeout retries sent\n");
- printk(KERN_DEBUG
- "rok: : destination timeouts successfully retried\n");
- printk(KERN_DEBUG
- "resetp: ipi-style resource resets for plugs\n");
- printk(KERN_DEBUG
- "resett: ipi-style resource resets for timeouts\n");
- printk(KERN_DEBUG
- "giveup: fall-backs to ipi-style shootdowns\n");
- printk(KERN_DEBUG
- "sto: number of source timeouts\n");
- printk(KERN_DEBUG
- "bz: number of stay-busy's\n");
- printk(KERN_DEBUG
- "throt: number times spun in throttle\n");
- printk(KERN_DEBUG "Destination side statistics:\n");
printk(KERN_DEBUG
- "sw_ack: image of UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE\n");
+ "requestor: times this cpu was the flush requestor\n");
printk(KERN_DEBUG
- "recv: shootdown messages received\n");
+ "requestee: times this cpu was requested to flush its TLBs\n");
printk(KERN_DEBUG
- "rtime: time spent processing messages\n");
+ "one: times requested to flush a single address\n");
printk(KERN_DEBUG
- "all: shootdown all-tlb messages\n");
+ "all: times requested to flush all TLB's\n");
printk(KERN_DEBUG
- "one: shootdown one-tlb messages\n");
+ "sretry: number of retries of source-side timeouts\n");
printk(KERN_DEBUG
- "mult: interrupts that found multiple messages\n");
+ "dretry: number of retries of destination-side timeouts\n");
printk(KERN_DEBUG
- "none: interrupts that found no messages\n");
+ "ptc_i: times UV fell through to IPI-style flushes\n");
printk(KERN_DEBUG
- "retry: number of retry messages processed\n");
+ "sw_ack: image of UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE\n");
printk(KERN_DEBUG
- "canc: number messages canceled by retries\n");
+ "sflush_us: cycles spent in uv_flush_tlb_others()\n");
printk(KERN_DEBUG
- "nocan: number retries that found nothing to cancel\n");
+ "dflush_us: cycles spent in handling flush requests\n");
+ printk(KERN_DEBUG "sok: successes on retry\n");
+ printk(KERN_DEBUG "dnomsg: interrupts with no message\n");
printk(KERN_DEBUG
- "reset: number of ipi-style reset requests processed\n");
- printk(KERN_DEBUG
- "rcan: number messages canceled by reset requests\n");
- } else if (input_arg == -1) {
- for_each_present_cpu(cpu) {
- stat = &per_cpu(ptcstats, cpu);
- memset(stat, 0, sizeof(struct ptc_stats));
- }
+ "dmult: interrupts with multiple messages\n");
+ printk(KERN_DEBUG "starget: nodes targeted\n");
} else {
- uv_bau_max_concurrent = input_arg;
- bcp = &per_cpu(bau_control, smp_processor_id());
- if (uv_bau_max_concurrent < 1 ||
- uv_bau_max_concurrent > bcp->cpus_in_uvhub) {
- printk(KERN_DEBUG
- "Error: BAU max concurrent %d; %d is invalid\n",
- bcp->max_concurrent, uv_bau_max_concurrent);
- return -EINVAL;
- }
- printk(KERN_DEBUG "Set BAU max concurrent:%d\n",
- uv_bau_max_concurrent);
- for_each_present_cpu(cpu) {
- bcp = &per_cpu(bau_control, cpu);
- bcp->max_concurrent = uv_bau_max_concurrent;
- }
+ uv_bau_retry_limit = newmode;
+ printk(KERN_DEBUG "timeout retry limit:%d\n",
+ uv_bau_retry_limit);
}
return count;
@@ -1122,31 +649,80 @@ static int __init uv_ptc_init(void)
return 0;
}
+/*
+ * begin the initialization of the per-blade control structures
+ */
+static struct bau_control * __init uv_table_bases_init(int blade, int node)
+{
+ int i;
+ struct bau_msg_status *msp;
+ struct bau_control *bau_tabp;
+
+ bau_tabp =
+ kmalloc_node(sizeof(struct bau_control), GFP_KERNEL, node);
+ BUG_ON(!bau_tabp);
+
+ bau_tabp->msg_statuses =
+ kmalloc_node(sizeof(struct bau_msg_status) *
+ DEST_Q_SIZE, GFP_KERNEL, node);
+ BUG_ON(!bau_tabp->msg_statuses);
+
+ for (i = 0, msp = bau_tabp->msg_statuses; i < DEST_Q_SIZE; i++, msp++)
+ bau_cpubits_clear(&msp->seen_by, (int)
+ uv_blade_nr_possible_cpus(blade));
+
+ uv_bau_table_bases[blade] = bau_tabp;
+
+ return bau_tabp;
+}
+
+/*
+ * finish the initialization of the per-blade control structures
+ */
+static void __init
+uv_table_bases_finish(int blade,
+ struct bau_control *bau_tablesp,
+ struct bau_desc *adp)
+{
+ struct bau_control *bcp;
+ int cpu;
+
+ for_each_present_cpu(cpu) {
+ if (blade != uv_cpu_to_blade_id(cpu))
+ continue;
+
+ bcp = (struct bau_control *)&per_cpu(bau_control, cpu);
+ bcp->bau_msg_head = bau_tablesp->va_queue_first;
+ bcp->va_queue_first = bau_tablesp->va_queue_first;
+ bcp->va_queue_last = bau_tablesp->va_queue_last;
+ bcp->msg_statuses = bau_tablesp->msg_statuses;
+ bcp->descriptor_base = adp;
+ }
+}
+
/*
* initialize the sending side's sending buffers
*/
-static void
+static struct bau_desc * __init
uv_activation_descriptor_init(int node, int pnode)
{
int i;
- int cpu;
unsigned long pa;
unsigned long m;
unsigned long n;
- struct bau_desc *bau_desc;
- struct bau_desc *bd2;
- struct bau_control *bcp;
+ struct bau_desc *adp;
+ struct bau_desc *ad2;
/*
* each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR)
- * per cpu; and up to 32 (UV_ADP_SIZE) cpu's per uvhub
+ * per cpu; and up to 32 (UV_ADP_SIZE) cpu's per blade
*/
- bau_desc = (struct bau_desc *)kmalloc_node(sizeof(struct bau_desc)*
+ adp = (struct bau_desc *)kmalloc_node(sizeof(struct bau_desc)*
UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node);
- BUG_ON(!bau_desc);
+ BUG_ON(!adp);
- pa = uv_gpa(bau_desc); /* need the real nasid*/
- n = pa >> uv_nshift;
+ pa = uv_gpa(adp); /* need the real nasid*/
+ n = uv_gpa_to_pnode(pa);
m = pa & uv_mmask;
uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE,
@@ -1155,188 +731,96 @@ uv_activation_descriptor_init(int node, int pnode)
/*
* initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each
* cpu even though we only use the first one; one descriptor can
- * describe a broadcast to 256 uv hubs.
+ * describe a broadcast to 256 nodes.
*/
- for (i = 0, bd2 = bau_desc; i < (UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR);
- i++, bd2++) {
- memset(bd2, 0, sizeof(struct bau_desc));
- bd2->header.sw_ack_flag = 1;
+ for (i = 0, ad2 = adp; i < (UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR);
+ i++, ad2++) {
+ memset(ad2, 0, sizeof(struct bau_desc));
+ ad2->header.sw_ack_flag = 1;
/*
- * base_dest_nodeid is the nasid (pnode<<1) of the first uvhub
- * in the partition. The bit map will indicate uvhub numbers,
- * which are 0-N in a partition. Pnodes are unique system-wide.
+ * base_dest_nodeid is the first node in the partition, so
+ * the bit map will indicate partition-relative node numbers.
+ * note that base_dest_nodeid is actually a nasid.
*/
- bd2->header.base_dest_nodeid = uv_partition_base_pnode << 1;
- bd2->header.dest_subnodeid = 0x10; /* the LB */
- bd2->header.command = UV_NET_ENDPOINT_INTD;
- bd2->header.int_both = 1;
+ ad2->header.base_dest_nodeid = uv_partition_base_pnode << 1;
+ ad2->header.dest_subnodeid = 0x10; /* the LB */
+ ad2->header.command = UV_NET_ENDPOINT_INTD;
+ ad2->header.int_both = 1;
/*
* all others need to be set to zero:
* fairness chaining multilevel count replied_to
*/
}
- for_each_present_cpu(cpu) {
- if (pnode != uv_blade_to_pnode(uv_cpu_to_blade_id(cpu)))
- continue;
- bcp = &per_cpu(bau_control, cpu);
- bcp->descriptor_base = bau_desc;
- }
+ return adp;
}
/*
* initialize the destination side's receiving buffers
- * entered for each uvhub in the partition
- * - node is first node (kernel memory notion) on the uvhub
- * - pnode is the uvhub's physical identifier
*/
-static void
-uv_payload_queue_init(int node, int pnode)
+static struct bau_payload_queue_entry * __init
+uv_payload_queue_init(int node, int pnode, struct bau_control *bau_tablesp)
{
+ struct bau_payload_queue_entry *pqp;
+ unsigned long pa;
int pn;
- int cpu;
char *cp;
- unsigned long pa;
- struct bau_payload_queue_entry *pqp;
- struct bau_payload_queue_entry *pqp_malloc;
- struct bau_control *bcp;
pqp = (struct bau_payload_queue_entry *) kmalloc_node(
(DEST_Q_SIZE + 1) * sizeof(struct bau_payload_queue_entry),
GFP_KERNEL, node);
BUG_ON(!pqp);
- pqp_malloc = pqp;
cp = (char *)pqp + 31;
pqp = (struct bau_payload_queue_entry *)(((unsigned long)cp >> 5) << 5);
-
- for_each_present_cpu(cpu) {
- if (pnode != uv_cpu_to_pnode(cpu))
- continue;
- /* for every cpu on this pnode: */
- bcp = &per_cpu(bau_control, cpu);
- bcp->va_queue_first = pqp;
- bcp->bau_msg_head = pqp;
- bcp->va_queue_last = pqp + (DEST_Q_SIZE - 1);
- }
+ bau_tablesp->va_queue_first = pqp;
/*
* need the pnode of where the memory was really allocated
*/
pa = uv_gpa(pqp);
- pn = pa >> uv_nshift;
+ pn = uv_gpa_to_pnode(pa);
uv_write_global_mmr64(pnode,
UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST,
((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) |
uv_physnodeaddr(pqp));
uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL,
uv_physnodeaddr(pqp));
+ bau_tablesp->va_queue_last = pqp + (DEST_Q_SIZE - 1);
uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST,
(unsigned long)
- uv_physnodeaddr(pqp + (DEST_Q_SIZE - 1)));
- /* in effect, all msg_type's are set to MSG_NOOP */
+ uv_physnodeaddr(bau_tablesp->va_queue_last));
memset(pqp, 0, sizeof(struct bau_payload_queue_entry) * DEST_Q_SIZE);
+
+ return pqp;
}
/*
- * Initialization of each UV hub's structures
+ * Initialization of each UV blade's structures
*/
-static void __init uv_init_uvhub(int uvhub, int vector)
+static int __init uv_init_blade(int blade)
{
int node;
int pnode;
+ unsigned long pa;
unsigned long apicid;
-
- node = uvhub_to_first_node(uvhub);
- pnode = uv_blade_to_pnode(uvhub);
- uv_activation_descriptor_init(node, pnode);
- uv_payload_queue_init(node, pnode);
+ struct bau_desc *adp;
+ struct bau_payload_queue_entry *pqp;
+ struct bau_control *bau_tablesp;
+
+ node = blade_to_first_node(blade);
+ bau_tablesp = uv_table_bases_init(blade, node);
+ pnode = uv_blade_to_pnode(blade);
+ adp = uv_activation_descriptor_init(node, pnode);
+ pqp = uv_payload_queue_init(node, pnode, bau_tablesp);
+ uv_table_bases_finish(blade, bau_tablesp, adp);
/*
* the below initialization can't be in firmware because the
* messaging IRQ will be determined by the OS
*/
- apicid = uvhub_to_first_apicid(uvhub);
+ apicid = blade_to_first_apicid(blade);
+ pa = uv_read_global_mmr64(pnode, UVH_BAU_DATA_CONFIG);
uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG,
- ((apicid << 32) | vector));
-}
-
-/*
- * initialize the bau_control structure for each cpu
- */
-static void uv_init_per_cpu(int nuvhubs)
-{
- int i, j, k;
- int cpu;
- int pnode;
- int uvhub;
- short socket = 0;
- struct bau_control *bcp;
- struct uvhub_desc *bdp;
- struct socket_desc *sdp;
- struct bau_control *hmaster = NULL;
- struct bau_control *smaster = NULL;
- struct socket_desc {
- short num_cpus;
- short cpu_number[16];
- };
- struct uvhub_desc {
- short num_sockets;
- short num_cpus;
- short uvhub;
- short pnode;
- struct socket_desc socket[2];
- };
- struct uvhub_desc *uvhub_descs;
-
- uvhub_descs = (struct uvhub_desc *)
- kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL);
- memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc));
- for_each_present_cpu(cpu) {
- bcp = &per_cpu(bau_control, cpu);
- memset(bcp, 0, sizeof(struct bau_control));
- spin_lock_init(&bcp->masks_lock);
- bcp->max_concurrent = uv_bau_max_concurrent;
- pnode = uv_cpu_hub_info(cpu)->pnode;
- uvhub = uv_cpu_hub_info(cpu)->numa_blade_id;
- bdp = &uvhub_descs[uvhub];
- bdp->num_cpus++;
- bdp->uvhub = uvhub;
- bdp->pnode = pnode;
- /* time interval to catch a hardware stay-busy bug */
- bcp->timeout_interval = millisec_2_cycles(3);
- /* kludge: assume uv_hub.h is constant */
- socket = (cpu_physical_id(cpu)>>5)&1;
- if (socket >= bdp->num_sockets)
- bdp->num_sockets = socket+1;
- sdp = &bdp->socket[socket];
- sdp->cpu_number[sdp->num_cpus] = cpu;
- sdp->num_cpus++;
- }
- socket = 0;
- for_each_possible_blade(uvhub) {
- bdp = &uvhub_descs[uvhub];
- for (i = 0; i < bdp->num_sockets; i++) {
- sdp = &bdp->socket[i];
- for (j = 0; j < sdp->num_cpus; j++) {
- cpu = sdp->cpu_number[j];
- bcp = &per_cpu(bau_control, cpu);
- bcp->cpu = cpu;
- if (j == 0) {
- smaster = bcp;
- if (i == 0)
- hmaster = bcp;
- }
- bcp->cpus_in_uvhub = bdp->num_cpus;
- bcp->cpus_in_socket = sdp->num_cpus;
- bcp->socket_master = smaster;
- bcp->uvhub_master = hmaster;
- for (k = 0; k < DEST_Q_SIZE; k++)
- bcp->socket_acknowledge_count[k] = 0;
- bcp->uvhub_cpu =
- uv_cpu_hub_info(cpu)->blade_processor_id;
- }
- socket++;
- }
- }
- kfree(uvhub_descs);
+ ((apicid << 32) | UV_BAU_MESSAGE));
+ return 0;
}
/*
@@ -1344,54 +828,38 @@ static void uv_init_per_cpu(int nuvhubs)
*/
static int __init uv_bau_init(void)
{
- int uvhub;
- int pnode;
- int nuvhubs;
+ int blade;
+ int nblades;
int cur_cpu;
- int vector;
- unsigned long mmr;
if (!is_uv_system())
return 0;
- if (nobau)
- return 0;
-
for_each_possible_cpu(cur_cpu)
zalloc_cpumask_var_node(&per_cpu(uv_flush_tlb_mask, cur_cpu),
GFP_KERNEL, cpu_to_node(cur_cpu));
- uv_bau_max_concurrent = MAX_BAU_CONCURRENT;
- uv_nshift = uv_hub_info->m_val;
+ uv_bau_retry_limit = 1;
uv_mmask = (1UL << uv_hub_info->m_val) - 1;
- nuvhubs = uv_num_possible_blades();
+ nblades = uv_num_possible_blades();
- uv_init_per_cpu(nuvhubs);
+ uv_bau_table_bases = (struct bau_control **)
+ kmalloc(nblades * sizeof(struct bau_control *), GFP_KERNEL);
+ BUG_ON(!uv_bau_table_bases);
uv_partition_base_pnode = 0x7fffffff;
- for (uvhub = 0; uvhub < nuvhubs; uvhub++)
- if (uv_blade_nr_possible_cpus(uvhub) &&
- (uv_blade_to_pnode(uvhub) < uv_partition_base_pnode))
- uv_partition_base_pnode = uv_blade_to_pnode(uvhub);
-
- vector = UV_BAU_MESSAGE;
- for_each_possible_blade(uvhub)
- if (uv_blade_nr_possible_cpus(uvhub))
- uv_init_uvhub(uvhub, vector);
-
+ for (blade = 0; blade < nblades; blade++)
+ if (uv_blade_nr_possible_cpus(blade) &&
+ (uv_blade_to_pnode(blade) < uv_partition_base_pnode))
+ uv_partition_base_pnode = uv_blade_to_pnode(blade);
+ for (blade = 0; blade < nblades; blade++)
+ if (uv_blade_nr_possible_cpus(blade))
+ uv_init_blade(blade);
+
+ alloc_intr_gate(UV_BAU_MESSAGE, uv_bau_message_intr1);
uv_enable_timeouts();
- alloc_intr_gate(vector, uv_bau_message_intr1);
-
- for_each_possible_blade(uvhub) {
- pnode = uv_blade_to_pnode(uvhub);
- /* INIT the bau */
- uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_ACTIVATION_CONTROL,
- ((unsigned long)1 << 63));
- mmr = 1; /* should be 1 to broadcast to both sockets */
- uv_write_global_mmr64(pnode, UVH_BAU_DATA_BROADCAST, mmr);
- }
return 0;
}
-core_initcall(uv_bau_init);
-core_initcall(uv_ptc_init);
+__initcall(uv_bau_init);
+__initcall(uv_ptc_init);
diff --git a/trunk/arch/x86/kernel/traps.c b/trunk/arch/x86/kernel/traps.c
index 02cfb9b8f5b1..1168e4454188 100644
--- a/trunk/arch/x86/kernel/traps.c
+++ b/trunk/arch/x86/kernel/traps.c
@@ -108,6 +108,15 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
dec_preempt_count();
}
+#ifdef CONFIG_X86_32
+static inline void
+die_if_kernel(const char *str, struct pt_regs *regs, long err)
+{
+ if (!user_mode_vm(regs))
+ die(str, regs, err);
+}
+#endif
+
static void __kprobes
do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
long error_code, siginfo_t *info)
@@ -534,11 +543,11 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
/* DR6 may or may not be cleared by the CPU */
set_debugreg(0, 6);
-
/*
* The processor cleared BTF, so don't mark that we need it set.
*/
- clear_tsk_thread_flag(tsk, TIF_BLOCKSTEP);
+ clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR);
+ tsk->thread.debugctlmsr = 0;
/* Store the virtualized DR6 value */
tsk->thread.debugreg6 = dr6;
@@ -576,67 +585,55 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
return;
}
+#ifdef CONFIG_X86_64
+static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr)
+{
+ if (fixup_exception(regs))
+ return 1;
+
+ notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE);
+ /* Illegal floating point operation in the kernel */
+ current->thread.trap_no = trapnr;
+ die(str, regs, 0);
+ return 0;
+}
+#endif
+
/*
* Note that we play around with the 'TS' bit in an attempt to get
* the correct behaviour even in the presence of the asynchronous
* IRQ13 behaviour
*/
-void math_error(struct pt_regs *regs, int error_code, int trapnr)
+void math_error(void __user *ip)
{
- struct task_struct *task = current;
+ struct task_struct *task;
siginfo_t info;
- unsigned short err;
- char *str = (trapnr == 16) ? "fpu exception" : "simd exception";
-
- if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP)
- return;
- conditional_sti(regs);
-
- if (!user_mode_vm(regs))
- {
- if (!fixup_exception(regs)) {
- task->thread.error_code = error_code;
- task->thread.trap_no = trapnr;
- die(str, regs, error_code);
- }
- return;
- }
+ unsigned short cwd, swd, err;
/*
* Save the info for the exception handler and clear the error.
*/
+ task = current;
save_init_fpu(task);
- task->thread.trap_no = trapnr;
- task->thread.error_code = error_code;
+ task->thread.trap_no = 16;
+ task->thread.error_code = 0;
info.si_signo = SIGFPE;
info.si_errno = 0;
- info.si_addr = (void __user *)regs->ip;
- if (trapnr == 16) {
- unsigned short cwd, swd;
- /*
- * (~cwd & swd) will mask out exceptions that are not set to unmasked
- * status. 0x3f is the exception bits in these regs, 0x200 is the
- * C1 reg you need in case of a stack fault, 0x040 is the stack
- * fault bit. We should only be taking one exception at a time,
- * so if this combination doesn't produce any single exception,
- * then we have a bad program that isn't synchronizing its FPU usage
- * and it will suffer the consequences since we won't be able to
- * fully reproduce the context of the exception
- */
- cwd = get_fpu_cwd(task);
- swd = get_fpu_swd(task);
+ info.si_addr = ip;
+ /*
+ * (~cwd & swd) will mask out exceptions that are not set to unmasked
+ * status. 0x3f is the exception bits in these regs, 0x200 is the
+ * C1 reg you need in case of a stack fault, 0x040 is the stack
+ * fault bit. We should only be taking one exception at a time,
+ * so if this combination doesn't produce any single exception,
+ * then we have a bad program that isn't synchronizing its FPU usage
+ * and it will suffer the consequences since we won't be able to
+ * fully reproduce the context of the exception
+ */
+ cwd = get_fpu_cwd(task);
+ swd = get_fpu_swd(task);
- err = swd & ~cwd;
- } else {
- /*
- * The SIMD FPU exceptions are handled a little differently, as there
- * is only a single status/control register. Thus, to determine which
- * unmasked exception was caught we must mask the exception mask bits
- * at 0x1f80, and then use these to mask the exception bits at 0x3f.
- */
- unsigned short mxcsr = get_fpu_mxcsr(task);
- err = ~(mxcsr >> 7) & mxcsr;
- }
+ err = swd & ~cwd;
if (err & 0x001) { /* Invalid op */
/*
@@ -665,17 +662,97 @@ void math_error(struct pt_regs *regs, int error_code, int trapnr)
dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
{
+ conditional_sti(regs);
+
#ifdef CONFIG_X86_32
ignore_fpu_irq = 1;
+#else
+ if (!user_mode(regs) &&
+ kernel_math_error(regs, "kernel x87 math error", 16))
+ return;
#endif
- math_error(regs, error_code, 16);
+ math_error((void __user *)regs->ip);
+}
+
+static void simd_math_error(void __user *ip)
+{
+ struct task_struct *task;
+ siginfo_t info;
+ unsigned short mxcsr;
+
+ /*
+ * Save the info for the exception handler and clear the error.
+ */
+ task = current;
+ save_init_fpu(task);
+ task->thread.trap_no = 19;
+ task->thread.error_code = 0;
+ info.si_signo = SIGFPE;
+ info.si_errno = 0;
+ info.si_code = __SI_FAULT;
+ info.si_addr = ip;
+ /*
+ * The SIMD FPU exceptions are handled a little differently, as there
+ * is only a single status/control register. Thus, to determine which
+ * unmasked exception was caught we must mask the exception mask bits
+ * at 0x1f80, and then use these to mask the exception bits at 0x3f.
+ */
+ mxcsr = get_fpu_mxcsr(task);
+ switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
+ case 0x000:
+ default:
+ break;
+ case 0x001: /* Invalid Op */
+ info.si_code = FPE_FLTINV;
+ break;
+ case 0x002: /* Denormalize */
+ case 0x010: /* Underflow */
+ info.si_code = FPE_FLTUND;
+ break;
+ case 0x004: /* Zero Divide */
+ info.si_code = FPE_FLTDIV;
+ break;
+ case 0x008: /* Overflow */
+ info.si_code = FPE_FLTOVF;
+ break;
+ case 0x020: /* Precision */
+ info.si_code = FPE_FLTRES;
+ break;
+ }
+ force_sig_info(SIGFPE, &info, task);
}
dotraplinkage void
do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
{
- math_error(regs, error_code, 19);
+ conditional_sti(regs);
+
+#ifdef CONFIG_X86_32
+ if (cpu_has_xmm) {
+ /* Handle SIMD FPU exceptions on PIII+ processors. */
+ ignore_fpu_irq = 1;
+ simd_math_error((void __user *)regs->ip);
+ return;
+ }
+ /*
+ * Handle strange cache flush from user space exception
+ * in all other cases. This is undocumented behaviour.
+ */
+ if (regs->flags & X86_VM_MASK) {
+ handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
+ return;
+ }
+ current->thread.trap_no = 19;
+ current->thread.error_code = error_code;
+ die_if_kernel("cache flush denied", regs, error_code);
+ force_sig(SIGSEGV, current);
+#else
+ if (!user_mode(regs) &&
+ kernel_math_error(regs, "kernel simd math error", 19))
+ return;
+ simd_math_error((void __user *)regs->ip);
+#endif
}
dotraplinkage void
diff --git a/trunk/arch/x86/kernel/uv_irq.c b/trunk/arch/x86/kernel/uv_irq.c
index 1132129db792..1d40336b030a 100644
--- a/trunk/arch/x86/kernel/uv_irq.c
+++ b/trunk/arch/x86/kernel/uv_irq.c
@@ -44,7 +44,7 @@ static void uv_ack_apic(unsigned int irq)
ack_APIC_irq();
}
-static struct irq_chip uv_irq_chip = {
+struct irq_chip uv_irq_chip = {
.name = "UV-CORE",
.startup = uv_noop_ret,
.shutdown = uv_noop,
@@ -141,7 +141,7 @@ int uv_irq_2_mmr_info(int irq, unsigned long *offset, int *pnode)
*/
static int
arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
- unsigned long mmr_offset, int limit)
+ unsigned long mmr_offset, int restrict)
{
const struct cpumask *eligible_cpu = cpumask_of(cpu);
struct irq_desc *desc = irq_to_desc(irq);
@@ -160,7 +160,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
if (err != 0)
return err;
- if (limit == UV_AFFINITY_CPU)
+ if (restrict == UV_AFFINITY_CPU)
desc->status |= IRQ_NO_BALANCING;
else
desc->status |= IRQ_MOVE_PCNTXT;
@@ -214,7 +214,7 @@ static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask)
unsigned long mmr_value;
struct uv_IO_APIC_route_entry *entry;
unsigned long mmr_offset;
- int mmr_pnode;
+ unsigned mmr_pnode;
if (set_desc_affinity(desc, mask, &dest))
return -1;
@@ -248,7 +248,7 @@ static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask)
* interrupt is raised.
*/
int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
- unsigned long mmr_offset, int limit)
+ unsigned long mmr_offset, int restrict)
{
int irq, ret;
@@ -258,7 +258,7 @@ int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
return -EBUSY;
ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset,
- limit);
+ restrict);
if (ret == irq)
uv_set_irq_2_mmr_info(irq, mmr_offset, mmr_blade);
else
diff --git a/trunk/arch/x86/kernel/x8664_ksyms_64.c b/trunk/arch/x86/kernel/x8664_ksyms_64.c
index 1b950d151e58..693920b22496 100644
--- a/trunk/arch/x86/kernel/x8664_ksyms_64.c
+++ b/trunk/arch/x86/kernel/x8664_ksyms_64.c
@@ -54,6 +54,7 @@ EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(__memcpy);
EXPORT_SYMBOL(empty_zero_page);
+EXPORT_SYMBOL(init_level4_pgt);
#ifndef CONFIG_PARAVIRT
EXPORT_SYMBOL(native_load_gs_index);
#endif
diff --git a/trunk/arch/x86/kernel/xsave.c b/trunk/arch/x86/kernel/xsave.c
index 37e68fc5e24a..782c3a362ec6 100644
--- a/trunk/arch/x86/kernel/xsave.c
+++ b/trunk/arch/x86/kernel/xsave.c
@@ -99,7 +99,7 @@ int save_i387_xstate(void __user *buf)
if (err)
return err;
- if (use_xsave())
+ if (task_thread_info(tsk)->status & TS_XSAVE)
err = xsave_user(buf);
else
err = fxsave_user(buf);
@@ -109,14 +109,14 @@ int save_i387_xstate(void __user *buf)
task_thread_info(tsk)->status &= ~TS_USEDFPU;
stts();
} else {
- if (__copy_to_user(buf, &tsk->thread.fpu.state->fxsave,
+ if (__copy_to_user(buf, &tsk->thread.xstate->fxsave,
xstate_size))
return -1;
}
clear_used_math(); /* trigger finit */
- if (use_xsave()) {
+ if (task_thread_info(tsk)->status & TS_XSAVE) {
struct _fpstate __user *fx = buf;
struct _xstate __user *x = buf;
u64 xstate_bv;
@@ -225,7 +225,7 @@ int restore_i387_xstate(void __user *buf)
clts();
task_thread_info(current)->status |= TS_USEDFPU;
}
- if (use_xsave())
+ if (task_thread_info(tsk)->status & TS_XSAVE)
err = restore_user_xstate(buf);
else
err = fxrstor_checking((__force struct i387_fxsave_struct *)
diff --git a/trunk/arch/x86/kvm/svm.c b/trunk/arch/x86/kvm/svm.c
index 737361fcd503..2ba58206812a 100644
--- a/trunk/arch/x86/kvm/svm.c
+++ b/trunk/arch/x86/kvm/svm.c
@@ -2067,7 +2067,7 @@ static int cpuid_interception(struct vcpu_svm *svm)
static int iret_interception(struct vcpu_svm *svm)
{
++svm->vcpu.stat.nmi_window_exits;
- svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET);
+ svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET);
svm->vcpu.arch.hflags |= HF_IRET_MASK;
return 1;
}
@@ -2479,7 +2479,7 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu)
svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_NMI;
vcpu->arch.hflags |= HF_NMI_MASK;
- svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET);
+ svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET);
++vcpu->stat.nmi_injections;
}
@@ -2539,10 +2539,10 @@ static void svm_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
if (masked) {
svm->vcpu.arch.hflags |= HF_NMI_MASK;
- svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET);
+ svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET);
} else {
svm->vcpu.arch.hflags &= ~HF_NMI_MASK;
- svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET);
+ svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET);
}
}
diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c
index edca080407a5..bc933cfb4e66 100644
--- a/trunk/arch/x86/kvm/vmx.c
+++ b/trunk/arch/x86/kvm/vmx.c
@@ -2703,7 +2703,8 @@ static int vmx_nmi_allowed(struct kvm_vcpu *vcpu)
return 0;
return !(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
- (GUEST_INTR_STATE_MOV_SS | GUEST_INTR_STATE_NMI));
+ (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS |
+ GUEST_INTR_STATE_NMI));
}
static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
@@ -3659,11 +3660,8 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
/* We need to handle NMIs before interrupts are enabled */
if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR &&
- (exit_intr_info & INTR_INFO_VALID_MASK)) {
- kvm_before_handle_nmi(&vmx->vcpu);
+ (exit_intr_info & INTR_INFO_VALID_MASK))
asm("int $2");
- kvm_after_handle_nmi(&vmx->vcpu);
- }
idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c
index dd9bc8fb81ab..3c4ca98ad27f 100644
--- a/trunk/arch/x86/kvm/x86.c
+++ b/trunk/arch/x86/kvm/x86.c
@@ -40,7 +40,6 @@
#include
#include
#include
-#include
#include
#undef TRACE_INCLUDE_FILE
#define CREATE_TRACE_POINTS
@@ -1713,7 +1712,6 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
if (copy_from_user(cpuid_entries, entries,
cpuid->nent * sizeof(struct kvm_cpuid_entry)))
goto out_free;
- vcpu_load(vcpu);
for (i = 0; i < cpuid->nent; i++) {
vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
@@ -1731,7 +1729,6 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
r = 0;
kvm_apic_set_version(vcpu);
kvm_x86_ops->cpuid_update(vcpu);
- vcpu_put(vcpu);
out_free:
vfree(cpuid_entries);
@@ -1752,11 +1749,9 @@ static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
if (copy_from_user(&vcpu->arch.cpuid_entries, entries,
cpuid->nent * sizeof(struct kvm_cpuid_entry2)))
goto out;
- vcpu_load(vcpu);
vcpu->arch.cpuid_nent = cpuid->nent;
kvm_apic_set_version(vcpu);
kvm_x86_ops->cpuid_update(vcpu);
- vcpu_put(vcpu);
return 0;
out:
@@ -3748,51 +3743,6 @@ static void kvm_timer_init(void)
}
}
-static DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu);
-
-static int kvm_is_in_guest(void)
-{
- return percpu_read(current_vcpu) != NULL;
-}
-
-static int kvm_is_user_mode(void)
-{
- int user_mode = 3;
-
- if (percpu_read(current_vcpu))
- user_mode = kvm_x86_ops->get_cpl(percpu_read(current_vcpu));
-
- return user_mode != 0;
-}
-
-static unsigned long kvm_get_guest_ip(void)
-{
- unsigned long ip = 0;
-
- if (percpu_read(current_vcpu))
- ip = kvm_rip_read(percpu_read(current_vcpu));
-
- return ip;
-}
-
-static struct perf_guest_info_callbacks kvm_guest_cbs = {
- .is_in_guest = kvm_is_in_guest,
- .is_user_mode = kvm_is_user_mode,
- .get_guest_ip = kvm_get_guest_ip,
-};
-
-void kvm_before_handle_nmi(struct kvm_vcpu *vcpu)
-{
- percpu_write(current_vcpu, vcpu);
-}
-EXPORT_SYMBOL_GPL(kvm_before_handle_nmi);
-
-void kvm_after_handle_nmi(struct kvm_vcpu *vcpu)
-{
- percpu_write(current_vcpu, NULL);
-}
-EXPORT_SYMBOL_GPL(kvm_after_handle_nmi);
-
int kvm_arch_init(void *opaque)
{
int r;
@@ -3829,8 +3779,6 @@ int kvm_arch_init(void *opaque)
kvm_timer_init();
- perf_register_guest_info_callbacks(&kvm_guest_cbs);
-
return 0;
out:
@@ -3839,8 +3787,6 @@ int kvm_arch_init(void *opaque)
void kvm_arch_exit(void)
{
- perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
-
if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
diff --git a/trunk/arch/x86/kvm/x86.h b/trunk/arch/x86/kvm/x86.h
index b7a404722d2b..2d101639bd8d 100644
--- a/trunk/arch/x86/kvm/x86.h
+++ b/trunk/arch/x86/kvm/x86.h
@@ -65,7 +65,4 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
return kvm_read_cr0_bits(vcpu, X86_CR0_PG);
}
-void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
-void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
-
#endif
diff --git a/trunk/arch/x86/lib/Makefile b/trunk/arch/x86/lib/Makefile
index f871e04b6965..419386c24b82 100644
--- a/trunk/arch/x86/lib/Makefile
+++ b/trunk/arch/x86/lib/Makefile
@@ -20,18 +20,17 @@ lib-y := delay.o
lib-y += thunk_$(BITS).o
lib-y += usercopy_$(BITS).o getuser.o putuser.o
lib-y += memcpy_$(BITS).o
-lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o
+lib-$(CONFIG_KPROBES) += insn.o inat.o
obj-y += msr.o msr-reg.o msr-reg-export.o
ifeq ($(CONFIG_X86_32),y)
obj-y += atomic64_32.o
- lib-y += atomic64_cx8_32.o
lib-y += checksum_32.o
lib-y += strstr_32.o
lib-y += semaphore_32.o string_32.o
ifneq ($(CONFIG_X86_CMPXCHG64),y)
- lib-y += cmpxchg8b_emu.o atomic64_386_32.o
+ lib-y += cmpxchg8b_emu.o
endif
lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o
else
diff --git a/trunk/arch/x86/lib/atomic64_32.c b/trunk/arch/x86/lib/atomic64_32.c
index 540179e8e9fa..824fa0be55a3 100644
--- a/trunk/arch/x86/lib/atomic64_32.c
+++ b/trunk/arch/x86/lib/atomic64_32.c
@@ -6,54 +6,225 @@
#include
#include
-long long atomic64_read_cx8(long long, const atomic64_t *v);
-EXPORT_SYMBOL(atomic64_read_cx8);
-long long atomic64_set_cx8(long long, const atomic64_t *v);
-EXPORT_SYMBOL(atomic64_set_cx8);
-long long atomic64_xchg_cx8(long long, unsigned high);
-EXPORT_SYMBOL(atomic64_xchg_cx8);
-long long atomic64_add_return_cx8(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_add_return_cx8);
-long long atomic64_sub_return_cx8(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_sub_return_cx8);
-long long atomic64_inc_return_cx8(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_inc_return_cx8);
-long long atomic64_dec_return_cx8(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_dec_return_cx8);
-long long atomic64_dec_if_positive_cx8(atomic64_t *v);
-EXPORT_SYMBOL(atomic64_dec_if_positive_cx8);
-int atomic64_inc_not_zero_cx8(atomic64_t *v);
-EXPORT_SYMBOL(atomic64_inc_not_zero_cx8);
-int atomic64_add_unless_cx8(atomic64_t *v, long long a, long long u);
-EXPORT_SYMBOL(atomic64_add_unless_cx8);
-
-#ifndef CONFIG_X86_CMPXCHG64
-long long atomic64_read_386(long long, const atomic64_t *v);
-EXPORT_SYMBOL(atomic64_read_386);
-long long atomic64_set_386(long long, const atomic64_t *v);
-EXPORT_SYMBOL(atomic64_set_386);
-long long atomic64_xchg_386(long long, unsigned high);
-EXPORT_SYMBOL(atomic64_xchg_386);
-long long atomic64_add_return_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_add_return_386);
-long long atomic64_sub_return_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_sub_return_386);
-long long atomic64_inc_return_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_inc_return_386);
-long long atomic64_dec_return_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_dec_return_386);
-long long atomic64_add_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_add_386);
-long long atomic64_sub_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_sub_386);
-long long atomic64_inc_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_inc_386);
-long long atomic64_dec_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_dec_386);
-long long atomic64_dec_if_positive_386(atomic64_t *v);
-EXPORT_SYMBOL(atomic64_dec_if_positive_386);
-int atomic64_inc_not_zero_386(atomic64_t *v);
-EXPORT_SYMBOL(atomic64_inc_not_zero_386);
-int atomic64_add_unless_386(atomic64_t *v, long long a, long long u);
-EXPORT_SYMBOL(atomic64_add_unless_386);
-#endif
+static noinline u64 cmpxchg8b(u64 *ptr, u64 old, u64 new)
+{
+ u32 low = new;
+ u32 high = new >> 32;
+
+ asm volatile(
+ LOCK_PREFIX "cmpxchg8b %1\n"
+ : "+A" (old), "+m" (*ptr)
+ : "b" (low), "c" (high)
+ );
+ return old;
+}
+
+u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val)
+{
+ return cmpxchg8b(&ptr->counter, old_val, new_val);
+}
+EXPORT_SYMBOL(atomic64_cmpxchg);
+
+/**
+ * atomic64_xchg - xchg atomic64 variable
+ * @ptr: pointer to type atomic64_t
+ * @new_val: value to assign
+ *
+ * Atomically xchgs the value of @ptr to @new_val and returns
+ * the old value.
+ */
+u64 atomic64_xchg(atomic64_t *ptr, u64 new_val)
+{
+ /*
+ * Try first with a (possibly incorrect) assumption about
+ * what we have there. We'll do two loops most likely,
+ * but we'll get an ownership MESI transaction straight away
+ * instead of a read transaction followed by a
+ * flush-for-ownership transaction:
+ */
+ u64 old_val, real_val = 0;
+
+ do {
+ old_val = real_val;
+
+ real_val = atomic64_cmpxchg(ptr, old_val, new_val);
+
+ } while (real_val != old_val);
+
+ return old_val;
+}
+EXPORT_SYMBOL(atomic64_xchg);
+
+/**
+ * atomic64_set - set atomic64 variable
+ * @ptr: pointer to type atomic64_t
+ * @new_val: value to assign
+ *
+ * Atomically sets the value of @ptr to @new_val.
+ */
+void atomic64_set(atomic64_t *ptr, u64 new_val)
+{
+ atomic64_xchg(ptr, new_val);
+}
+EXPORT_SYMBOL(atomic64_set);
+
+/**
+EXPORT_SYMBOL(atomic64_read);
+ * atomic64_add_return - add and return
+ * @delta: integer value to add
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically adds @delta to @ptr and returns @delta + *@ptr
+ */
+noinline u64 atomic64_add_return(u64 delta, atomic64_t *ptr)
+{
+ /*
+ * Try first with a (possibly incorrect) assumption about
+ * what we have there. We'll do two loops most likely,
+ * but we'll get an ownership MESI transaction straight away
+ * instead of a read transaction followed by a
+ * flush-for-ownership transaction:
+ */
+ u64 old_val, new_val, real_val = 0;
+
+ do {
+ old_val = real_val;
+ new_val = old_val + delta;
+
+ real_val = atomic64_cmpxchg(ptr, old_val, new_val);
+
+ } while (real_val != old_val);
+
+ return new_val;
+}
+EXPORT_SYMBOL(atomic64_add_return);
+
+u64 atomic64_sub_return(u64 delta, atomic64_t *ptr)
+{
+ return atomic64_add_return(-delta, ptr);
+}
+EXPORT_SYMBOL(atomic64_sub_return);
+
+u64 atomic64_inc_return(atomic64_t *ptr)
+{
+ return atomic64_add_return(1, ptr);
+}
+EXPORT_SYMBOL(atomic64_inc_return);
+
+u64 atomic64_dec_return(atomic64_t *ptr)
+{
+ return atomic64_sub_return(1, ptr);
+}
+EXPORT_SYMBOL(atomic64_dec_return);
+
+/**
+ * atomic64_add - add integer to atomic64 variable
+ * @delta: integer value to add
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically adds @delta to @ptr.
+ */
+void atomic64_add(u64 delta, atomic64_t *ptr)
+{
+ atomic64_add_return(delta, ptr);
+}
+EXPORT_SYMBOL(atomic64_add);
+
+/**
+ * atomic64_sub - subtract the atomic64 variable
+ * @delta: integer value to subtract
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically subtracts @delta from @ptr.
+ */
+void atomic64_sub(u64 delta, atomic64_t *ptr)
+{
+ atomic64_add(-delta, ptr);
+}
+EXPORT_SYMBOL(atomic64_sub);
+
+/**
+ * atomic64_sub_and_test - subtract value from variable and test result
+ * @delta: integer value to subtract
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically subtracts @delta from @ptr and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+int atomic64_sub_and_test(u64 delta, atomic64_t *ptr)
+{
+ u64 new_val = atomic64_sub_return(delta, ptr);
+
+ return new_val == 0;
+}
+EXPORT_SYMBOL(atomic64_sub_and_test);
+
+/**
+ * atomic64_inc - increment atomic64 variable
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically increments @ptr by 1.
+ */
+void atomic64_inc(atomic64_t *ptr)
+{
+ atomic64_add(1, ptr);
+}
+EXPORT_SYMBOL(atomic64_inc);
+
+/**
+ * atomic64_dec - decrement atomic64 variable
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically decrements @ptr by 1.
+ */
+void atomic64_dec(atomic64_t *ptr)
+{
+ atomic64_sub(1, ptr);
+}
+EXPORT_SYMBOL(atomic64_dec);
+
+/**
+ * atomic64_dec_and_test - decrement and test
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically decrements @ptr by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+int atomic64_dec_and_test(atomic64_t *ptr)
+{
+ return atomic64_sub_and_test(1, ptr);
+}
+EXPORT_SYMBOL(atomic64_dec_and_test);
+
+/**
+ * atomic64_inc_and_test - increment and test
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically increments @ptr by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+int atomic64_inc_and_test(atomic64_t *ptr)
+{
+ return atomic64_sub_and_test(-1, ptr);
+}
+EXPORT_SYMBOL(atomic64_inc_and_test);
+
+/**
+ * atomic64_add_negative - add and test if negative
+ * @delta: integer value to add
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically adds @delta to @ptr and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+int atomic64_add_negative(u64 delta, atomic64_t *ptr)
+{
+ s64 new_val = atomic64_add_return(delta, ptr);
+
+ return new_val < 0;
+}
+EXPORT_SYMBOL(atomic64_add_negative);
diff --git a/trunk/arch/x86/lib/atomic64_386_32.S b/trunk/arch/x86/lib/atomic64_386_32.S
deleted file mode 100644
index 4a5979aa6883..000000000000
--- a/trunk/arch/x86/lib/atomic64_386_32.S
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * atomic64_t for 386/486
- *
- * Copyright © 2010 Luca Barbieri
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include
-#include
-#include
-
-/* if you want SMP support, implement these with real spinlocks */
-.macro LOCK reg
- pushfl
- CFI_ADJUST_CFA_OFFSET 4
- cli
-.endm
-
-.macro UNLOCK reg
- popfl
- CFI_ADJUST_CFA_OFFSET -4
-.endm
-
-.macro BEGIN func reg
-$v = \reg
-
-ENTRY(atomic64_\func\()_386)
- CFI_STARTPROC
- LOCK $v
-
-.macro RETURN
- UNLOCK $v
- ret
-.endm
-
-.macro END_
- CFI_ENDPROC
-ENDPROC(atomic64_\func\()_386)
-.purgem RETURN
-.purgem END_
-.purgem END
-.endm
-
-.macro END
-RETURN
-END_
-.endm
-.endm
-
-BEGIN read %ecx
- movl ($v), %eax
- movl 4($v), %edx
-END
-
-BEGIN set %esi
- movl %ebx, ($v)
- movl %ecx, 4($v)
-END
-
-BEGIN xchg %esi
- movl ($v), %eax
- movl 4($v), %edx
- movl %ebx, ($v)
- movl %ecx, 4($v)
-END
-
-BEGIN add %ecx
- addl %eax, ($v)
- adcl %edx, 4($v)
-END
-
-BEGIN add_return %ecx
- addl ($v), %eax
- adcl 4($v), %edx
- movl %eax, ($v)
- movl %edx, 4($v)
-END
-
-BEGIN sub %ecx
- subl %eax, ($v)
- sbbl %edx, 4($v)
-END
-
-BEGIN sub_return %ecx
- negl %edx
- negl %eax
- sbbl $0, %edx
- addl ($v), %eax
- adcl 4($v), %edx
- movl %eax, ($v)
- movl %edx, 4($v)
-END
-
-BEGIN inc %esi
- addl $1, ($v)
- adcl $0, 4($v)
-END
-
-BEGIN inc_return %esi
- movl ($v), %eax
- movl 4($v), %edx
- addl $1, %eax
- adcl $0, %edx
- movl %eax, ($v)
- movl %edx, 4($v)
-END
-
-BEGIN dec %esi
- subl $1, ($v)
- sbbl $0, 4($v)
-END
-
-BEGIN dec_return %esi
- movl ($v), %eax
- movl 4($v), %edx
- subl $1, %eax
- sbbl $0, %edx
- movl %eax, ($v)
- movl %edx, 4($v)
-END
-
-BEGIN add_unless %ecx
- addl %eax, %esi
- adcl %edx, %edi
- addl ($v), %eax
- adcl 4($v), %edx
- cmpl %eax, %esi
- je 3f
-1:
- movl %eax, ($v)
- movl %edx, 4($v)
- movl $1, %eax
-2:
-RETURN
-3:
- cmpl %edx, %edi
- jne 1b
- xorl %eax, %eax
- jmp 2b
-END_
-
-BEGIN inc_not_zero %esi
- movl ($v), %eax
- movl 4($v), %edx
- testl %eax, %eax
- je 3f
-1:
- addl $1, %eax
- adcl $0, %edx
- movl %eax, ($v)
- movl %edx, 4($v)
- movl $1, %eax
-2:
-RETURN
-3:
- testl %edx, %edx
- jne 1b
- jmp 2b
-END_
-
-BEGIN dec_if_positive %esi
- movl ($v), %eax
- movl 4($v), %edx
- subl $1, %eax
- sbbl $0, %edx
- js 1f
- movl %eax, ($v)
- movl %edx, 4($v)
-1:
-END
diff --git a/trunk/arch/x86/lib/atomic64_cx8_32.S b/trunk/arch/x86/lib/atomic64_cx8_32.S
deleted file mode 100644
index 71e080de3352..000000000000
--- a/trunk/arch/x86/lib/atomic64_cx8_32.S
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * atomic64_t for 586+
- *
- * Copyright © 2010 Luca Barbieri
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include